SPI slave and DMA question

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

I am using PSoC3 at the SPI slave end and SPI master is a ARM9 processor. I need to consistantly exchange block of data to PSoC3 through the SPI, so I set up the DMA on PSoC3 side. In my test program, I find SPI slave return data is shifted by one byte. For example, in PSoC3, I initialize spitxdata = i + 10; but on the SPI master side, at the very first time, it receive data SpiReturn[0] = 0; SpiReturn[1] = 10; SpiReturn[2] = 11......and the next round, it will assign SpiReturn[0] = 49, then SpiReturn[1] = 10.... It seems Spi slave Tx does not put the tx data after receiving the first byte? Any suggestions?

   

Here is some more details about my program. SPIS Rx/Tx buffer size = 4, only selected Interrupt On Tx FIFO Not Full and Interrupt On Rx FIFO Not Empty, rx_interrupt output connects to DMA_RX_S drq and tx_interrupt connects to DMA_TX_S drq, both DMA has hardware request set to level

   

 

   

Attached is the related code.

   

 

   

Thanks in advance for any suggestion!

0 Likes
1 Solution
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored
        After reading deeper into the SPI Slave data sheet, I have an idea what might happen. Basically when you start the TX buffer is empty (nothing is loaded into A0 so there is nothing to transmit). Now when the master starts to write, it asserts SS and starts sending. In that moment, the SPI Slave sees that the TX buffer is empty, creates an IRQ and the the DMA fills in the first byte. But that is then too late to send it out, so it will get send only the second time. You can test that by adding an ISR to the tx_interrupt line. It should fire after the SPI has been initialized, and before the master sends for the first time. If it doesn't, then my idea above is correct. (Or you route it to a pin and check with a logic analyzer when interrupts are generated) If this is what happens, then you would just need to create the first DMA request manually (with CyDMAChSetRequest).   

View solution in original post

0 Likes
14 Replies