6 Replies Latest reply on Oct 28, 2015 11:43 AM by user_302397898

    Ping Pong DMA

    aditya.karn

       Hello All,

         

       I am trying to establish a Ping pong DMA to transfer data alternatively from two buffers. Buffer Size is 1000k(1MB). Can anyone give me any idea to perform this task?

         

      Thanks.

        • 1. Re: Ping Pong DMA
          user_1377889

          I think I have red that the maximum amount to transfer with a single TD is limited to 4095 bytes. Have a look into this appnote

             

          Deeper information you will find here.

             

           

             

          Happy coding

             

          Bob

          • 2. Re: Ping Pong DMA
            user_78878863

            Out of curiosity: do you have a secret PSoC device with 1MB RAM? Or do you use external memory?

            • 3. Re: Ping Pong DMA
              user_14586677

              Some ref material -

                 

               

                 

                  

                 

                        

                 

              http://www.cypress.com/?rID=37793     AN52705     Getting Started with DMA

                 

              http://www.cypress.com/?rID=82680     AN84810     PSoC® 3 and PSoC 5LP Advanced DMA Topics

                 

              http://www.cypress.com/?rID=44335     AN61102 PSoC® 3 and PSoC 5LP - ADC Data Buffering Using DMA

                 

              http://video.cypress.com/video-library/search/dma/     Videos on DMA

                 

              https://www.youtube.com/results?search_query=dma+psoc Videos on DMA (some overlap)

                 

               

                 

               

                 

              Regards, Dana.

              • 4. Re: Ping Pong DMA
                aditya.karn

                 Thanks Dana

                • 5. Re: Ping Pong DMA
                  user_14586677

                  You are always welcome!

                     

                   

                     

                  Dana.

                  • 6. Re: Ping Pong DMA
                    user_302397898

                    AdityaK, Bob is right that the maximum transfer is 4095 bytes from a single TD but you can have multiple TDs to transfer the total length you need.  What is the source of your data buffers -- a filter? ADC?  Is your input array the same size as your output array? I have used pointers in each TD to reference a specific offset into the source or destination buffer. Be sure to reinitialize these pointers for each burst. For example:

                       

                    uint16 *pA[4];  // Array of pointers to segments of data array from Filter A

                    void set_pointers()  // Sets the pointers to the output arrays
                    {    
                        uint16 j;
                        for (j = 0; j < SEGMENTS; j++) // and if SEGMENTS is #defined as 4 ...
                        {
                            pA[j] = &(Filter_Ch_A[LENGTH*j]); // pointers to the four segments of Filter A data used in DMA TDs
                        }
                    }

                       

                    Then each TD uses one of the pA pointers. See them used in the last four lines in this code:

                       

                    The following might be the reverse direction of what you are doing but it can be modified for your need.

                       

                    /* DMA Configuration for dma_out_A */
                        /* Create a TD[5] that ENDs to avoid memory corruptions if the main loop is too slow to stop it */    
                        dma_out_A_Chan = dma_out_A_DmaInitialize(dma_out_A_BYTES_PER_BURST, dma_out_A_REQUEST_PER_BURST, 
                            HI16(dma_out_A_SRC_BASE), HI16(dma_out_A_DST_BASE));
                        dma_out_A_TD[0] = CyDmaTdAllocate();
                        dma_out_A_TD[1] = CyDmaTdAllocate();
                        dma_out_A_TD[2] = CyDmaTdAllocate();
                        dma_out_A_TD[3] = CyDmaTdAllocate();
                        dma_out_A_TD[4] = CyDmaTdAllocate();
                        CyDmaTdSetConfiguration(dma_out_A_TD[0], 2*LENGTH, dma_out_A_TD[1], TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
                        CyDmaTdSetConfiguration(dma_out_A_TD[1], 2*LENGTH, dma_out_A_TD[2], TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
                        CyDmaTdSetConfiguration(dma_out_A_TD[2], 2*LENGTH, dma_out_A_TD[3], TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
                        CyDmaTdSetConfiguration(dma_out_A_TD[3], 2*LENGTH, dma_out_A_TD[4], dma_out_A__TD_TERMOUT_EN | TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
                        CyDmaTdSetConfiguration(dma_out_A_TD[4], 32, dma_out_A_TD[0], TD_AUTO_EXEC_NEXT);
                        CyDmaTdSetAddress(dma_out_A_TD[0], LO16((uint32)Filter_HOLDA_PTR), LO16((uint32)pA[0]));
                        CyDmaTdSetAddress(dma_out_A_TD[1], LO16((uint32)Filter_HOLDA_PTR), LO16((uint32)pA[1]));
                        CyDmaTdSetAddress(dma_out_A_TD[2], LO16((uint32)Filter_HOLDA_PTR), LO16((uint32)pA[2]));
                        CyDmaTdSetAddress(dma_out_A_TD[3], LO16((uint32)Filter_HOLDA_PTR), LO16((uint32)pA[3]));
                        CyDmaTdSetAddress(dma_out_A_TD[4], LO16((uint32)Filter_HOLDA_PTR), LO16((uint32)overflow_A));
                        CyDmaChSetInitialTd(dma_out_A_Chan, dma_out_A_TD[0]);
                        CyDmaChEnable(dma_out_A_Chan, 1)