DMA + SPI, TD run-time configuration

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

cross mob
lock attach
Attachments are accessible only for community members.
cadi_1014291
Level 6
Level 6
25 likes received 10 likes received 10 likes given

Hi, hope all is good.

   

I have been trying to make DMA and SPI work together for at least two weeks, and i think i have something usefull, the end application of this is drive the nRF24 chip with DMA on the PSoC 5LP.

   

I have some doubts and hope somebody can help me, or suggest me a more efficient way to do it.

   

SPI FIFO is 4 bytes deep so i send 1 byte each time using the Tx FIFO not Full signal, if i try to send more bytes al goes crazy, same i get 1 byte on the receiver buffer with help of the Rx FIFO Not Empty signal.

   

nRF24 chip have several registers, most of them are 1 byte size, and few others are 32 bytes long, so to be able to read or write to them i need to send a read/write command byte + all the bytes of data, for this i was tinking on have 1 TD to send the command + 1 TD to send the data on the Tx side, and 1 TD for the received data. I did this on a function (DMATransfer on the attached project) but i do not know if i have to allocate the TD on the beggining of the function and then free the TD when i'm finishing the function, all this because i'm changing the TD transfer size parameter each time i call the function.

   

And also i would like to know if there's a way to avoid this:

   

while(0u == (SPI_TX_STATUS_REG & SPI_STS_SPI_DONE));

   

i have to do it because if i don't do it the /SS line never goes 'high' when i'm done sending the number of bytes i pass as parameter.

   

 

   

Attached the most recent project. Thanks in advance

   

Carlos

   

PS: I'm bad explaining, so any doubts pls let me know 😄

0 Likes
5 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

        DMATransfer(0xFF, txBuffer, rxBuffer, sizeof(rxBuffer));
        
        while (0u == (SPI_ReadTxStatus() & SPI_STS_SPI_DONE))    // <- Forgotten semicolon here???
            
        memset(rxBuffer, 0, sizeof(rxBuffer));    // <- otherwise receive buffer gets overwritten!

   

 

   

You could use an interrupt that indicates a finished DMA, but when the ss line has to go high again you will have to wait for a finished SPI transfer.

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
cadi_1014291
Level 6
Level 6
25 likes received 10 likes received 10 likes given

Hi Bob

   

Yes i forgot to write the semicolon because i was cleaning the code of the project :D.

   

I used memset function to fill the array with zeroes after the transfer, i think now it's working, but i was trying to avoid wait the SPI to finish the transfer inside the interrupt routine.

   

Maybe if i wait for the interrupt of the Rx DMA channel i do not wait to much, it's asserted finishing the 0x05 byte on the image.

   

   

Also on the beginning of the program i read the free TDs with CyDmaTdFreeCount() and i get 0x68 (104 decimal), where can be the rest of the TDs?

   

Thanks for the help 😄

   

Carlos

   

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

The TDs are a property of the DMA-controller. What you receive when allocating a TD is an index-numberinto the controller's array of TDs

   

i was trying to avoid wait the SPI to finish the transfer inside the interrupt routine. Not a bad idea!!! I would suggest to set a flag within the handler and wait for the flag in the main-loop.

   

Just my 2ct:

   

SPI is (as all serial connections)  comparably slow (when compared to CPU speed)  and usually does not need a fast reaction. DMA is able to shovel amounts of data  A simple SPIM_PutArray() is a "fire -and-forget-it" function, all will be handled internally and at need I can control the state of transmission. I usually use DMA to transfer data from fast devices (ADC, SAR) where the response time is short and the available amount of statements to execute is restricted .

   

 

   

Bob

0 Likes

Thanks for the feedback, and yes, i did compare the usual API vs. the DMA transfers and there are almost no differences on matter of time, the unique one i found is i do not have to control the /SS line.

   

 

   

Always thanks for the tips Bob, those are really helpfull

   

Carlos

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You are always welcome, Carlos!

   

 

   

Bob

0 Likes