I have seen an exactly same behavior of SPI Slave in a PSoC 5LP.
At that time, I was explained that because of nature of SPI Slave,
when writing an array to the TxBuffer, the first byte is written as 0
then the data we wanted to write was written from the second byte.
To avoid this they provided an API
which will place the data at the first byte/word.
And I think that for the PSoC 6, they implemented SPI Slave similarly.
But so far, I have not been able to find a counterpart function of SPIS_WriteTxDataZero() for PSOC 6.
May be there is one with different name or may be they decided that the programmer needs to take care of it somehow.
Thanks Motto for your response. It helps to know that someone else has seen something similar.
I had a look through the available PSoC 6 functions and I also could not find anything like the "zero" function you found for PSoC 5.
I hope we get something meaningful from Cypress on this one.
Here is a snip from the PDL documentation:
__STATIC_INLINE uint32_t Cy_SCB_SPI_Write ( CySCB_Type * base, uint32_t data )
Places a single data element in the SPI TX FIFO.
This function does not block. It returns how many data elements were placed in the TX FIFO.
base The pointer to the SPI SCB instance. data Data to put in the TX FIFO. The element size is defined by the data type, which depends on the configured TX data width.
- The number of data elements placed in the TX FIFO: 0 or 1.
- When in the master mode, writing data into the TX FIFO starts an SPI transfer.
- When in the slave mode, writing data into the TX FIFO does not start an SPI transfer. The data is loaded in the TX FIFO and will be sent to the master on its request.
- The SPI interface is full-duplex, therefore reads and writes occur at the same time. Thus, for every data element transferred out of the TX FIFO, one is transferred into the RX FIFO.
It appears it is implied that a Cy_SCB_SPI_Write() places the first data in the shift register from the FIFO.
Hi Len, thanks for the response. I had seen this in the documentation. The data certainly is loaded into the TX FIFO and is being sent to the master - no problem there. The problem is the extra byte at the beginning which is appearing on MISO but was not placed into the FIFO, as you can see in the trace picture I attached.
There is a PSoC6 SPI Master/Slave Example available under PSoC Creator. It's listed as CE221120.
It has four SPI modes
- low-level Polling
- low-level Interrupt
- low-level DMA
The projects all use a SPI master and a SPI slave on the same PSoC and the master needs to be physically connected to the slave.
The SPI slave preloads the first byte into its TxFIFO to acknowledge the status of the previous SPI master command. No one byte delay.
1 of 1 people found this helpful
If you are using the default Mode 0(CPHA=0,CPOL=0) of SPI, then this behavior is probably occurring because the next byte to be sent out by the SPI slave is already loaded on the last clock edge (falling edge) of the previous byte itself. Below is a screenshot of the SPI component timing diagram that shows this:
So, in your case, the data is loaded in the last clock edge when the address byte is transmitted itself.
To overcome this, would it be possible to try:
1) Loading the Tx FIFO with data on or before the address byte(first byte) transmission from the master ?
But if this does not satisfy your application requirement(where the response data is decided only after the first address byte), then can you try:
2) Changing the SPI SCLK mode to Mode 1(CPHA=1,CPOL=0). In this mode, the loading of the shift register seems to happen only the first clock edge of the current byte, as shown in the below screenshot:
But note that the SPI master also has to be changed to this mode.
3) Or (on the SPI master's side) try lifting up the SPI SS after the first address byte, and lowering it before the next response byte (in between which you can load the slave response byte into the Tx FIFO).
Thank you for this very clear and comprehensive response. You are exactly correct. I have done some tests and confirmed it.
Did you find some reference documentation that states when this FIFO-to-shift register action occurs, or did you just figure out? I’ve had a look again through whatever documents I can find but there is no detailed description of this. If you did find something in some document, please would you give me a link to it?
It seems strange to me that the SPI Mode should affect the way the internal FIFO and shift register interact – I have not seen this in any other SPI interface I have dealt with. In fact, it doesn’t make sense because it actually affects the higher-level protocol that is implemented in the slave firmware.
Regarding your suggested work-arounds:
- I can’t do this because, as you say, the response data is determined by the first address byte.
- This is possible, but because of other wider implications in the master and with other slave devices, it’s not ideal.
- This could work, but again has other implications, and the entire frame is defined by the SS pulse.
I’ve decided to leave it as it is and actually use this “extra” byte as a status byte that is independent of the data pointed to by the address byte – which actually has some other advantages. At least now I understand what’s going on, which is a big help.
Thanks again for taking the time to write up this answer for me – very much appreciated.
Glad that this helps to get an understanding of the issue, though not much can be done about it.
I could not find the FIFO to shift-register transfer event mentioned as such in any document. I had only interpreted it based on observed behavior and the data transition indications in the timing diagram, previously on PSoC5LP, and guessed the same might be occurring here.