Showing results for 
Search instead for 
Did you mean: 

PSoC 5, 3 & 1 MCU

New Contributor II

Hello, I've run into a bit of behavior I am struggling to figure out. I am using a SPI master in full duplex mode using only the hardware FIFO (no interrupts) to communicate with an external chip. I can write just fine via SPI to the device. I can also see that the device is responding correctly to my SPI master commands in that the anticipated data are returned as seen by a logic analyzer. That being said, the SPIM_ReadRxData from the Creator API does not behave as expected. This is because the SPIM_GetRxBufferSize() is returning an incorrect number of bytes.


If I transmit 3 bytes of data through SPIM, I should receive 3 bytes of data (even if it's garbage) because it is shift-register based and sync'd with the master clock. Well, I get sometimes one, but usually zero bytes. So, I'm confused. Here is the snippet of code. Does anyone have any thoughts on the matter?

static BOOL_t AFE4300_read( uint8_t address, uint16_t *pdata ) /****************************************************************************** * Description: This performs the 24-bit read from the AFE. The 3-byte write * is defined by the hardware of the AFE and cannot be changed. The first byte * is always the register to which the data are to be read from. The next 16-bit * transfer is the data. All registers EXCEPT for the data register must be re- * written once they've been read. ******************************************************************************/ {     uint8_t highByte;     uint8_t lowByte;     BOOL_t success = FALSE;     uint8_t temp;            SPIM_ClearFIFO();          SPIM_WriteTxData(address | ADDRESS_READ_ENABLE); // see p18 of data sheet about bit 21     SPIM_WriteTxData(0x00); // send dummy data to shift high byte out of device     SPIM_WriteTxData(0x00); // send dummy data to shift low byte out of device          temp = SPIM_GetRxBufferSize();     if(temp >= 3)     {         SPIM_ReadRxData(); // ignore byte shifted out as address went in         highByte = SPIM_ReadRxData();         lowByte = SPIM_ReadRxData();              *pdata = ((uint16_t)highByte << 😎 | (uint16_t)lowByte;          // write rx'd data back to device unless it is the ADC register         if( ADC_DATA_REG_ADDR != address )         {             // re-write data back to register             SPIM_WriteTxData(address | ADDRESS_WRITE_ENABLE);             SPIM_WriteTxData(highByte);             SPIM_WriteTxData(lowByte);         }         success = TRUE;     }     /* NOTE: if success is FALSE, the AFE is in an unknown state and will need      to be reset */     return( success ); }

I am attaching a PNG of the master clocking data out of the slave. The master writes a 0x21 to get data from the slave followed by two dummy bytes. The dummy bytes are correctly verified to contain 0x81 and 0xC3. The PSoC does not received these bytes for some reason.




Thank you.

3 Replies
Expert II

Can you please post your complete project, so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.





Honored Contributor II

_WriteTxData() just places the value in the TX FIFO. It doesn't wait until the data is send. So you are checking for the RX buffer size too early. Check the SPI status and wait until all bytes have been send.

New Contributor II

You are correct. There were two parts of the problem. The first was that checking the rx buffer function doesn't work if you aren't using the software buffer. So I had to increase the buffer size to above 4 bytes for the software buffer to be enabled. Then I could wait for the SPIM transmit to complete and check for data. Of course if I transmit 3 bytes, the rx FIFO should have 3 bytes in it as well, so checking the rx buffer size is not necessary.