5 Replies Latest reply on May 8, 2016 8:55 PM by user_365962704

    DMA + SPI, TD run-time configuration

    user_365962704

      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 :D

        • 1. Re: DMA + SPI, TD run-time configuration
          user_1377889

                  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

          • 2. Re: DMA + SPI, TD run-time configuration
            user_365962704

            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 :D

               

            Carlos

               

            • 3. Re: DMA + SPI, TD run-time configuration
              user_1377889

              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

              • 4. Re: DMA + SPI, TD run-time configuration
                user_365962704

                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

                • 5. Re: DMA + SPI, TD run-time configuration
                  user_1377889

                  You are always welcome, Carlos!

                     

                   

                     

                  Bob