6 Replies Latest reply on Feb 25, 2015 8:41 AM by userc_41771

    Index DMA

      I am trying to use asynchronous data to fill a buffer using DMA.  I would like to use one dma to determine the destination address for the second DMA (or TD).  I have looked at   AN84810 and other DMA references.


      I want to write a timer value to a, array  buffer and then increment the spot in the array.  I cant use the auto increment in the dma, becasue it (the DMA) will stay open unitl the next data is received, but I have 8 channels in total that I need to process so I cant keep the DMA open and waiting.


      The events come in to fast to process in software.   


      Is this possible to do?


      What I have now that does not work


      CyDmaTdSetAddress(DMA_1_TD[0], LO16((uint32)Counter_1_COUNTER_LSB_PTR), LO16((uint32)&address));




      CyDmaTdSetAddress(DMA_2_TD[0], LO16((uint32)timer_value),address);


      The "CyDMATdSetAddress" function is only called once, so even if the value at address  changes, DMA_@ is not reset to use it.

        • 1. Re: Index DMA

          Probably the  expression "&address" is wrong when "address" is an array.


          All your DMA channels work simultaneously, so I don't see that there is something like "open".


          You wrote "I want to write a timer value to a, array  buffer and then increment the spot in the array", I'm not quite sure what you want to do exactly (probably language problem, I'm not English).





          • 2. Re: Index DMA

            a) why not using 8 DMAs in parallel? They can share the same source and transfer to different target, you just need to trigger them each at the rigft time.


            b) an indexed DMA works by one DMA manipulating the TDs of another DMA. Thats not what I see you doing here. So maybe you need to explain a little more what you actually intend to do, so we understand it.

            • 3. Re: Index DMA

              "&address[ 0 ]" or just "address" works to stipulate the address of the array.




              Is the data coming in sequentially from the channels ? If so you can -








              Regards, Dana.

              • 4. Re: Index DMA

                Appreciate all support.  What i thought was the DMA staying "open" was due to a lack of term out signal on every read (only when total bytes have been transferred, which makes perfect sense.)


                I am building up to try and use 16 channels of DMA one to buffer the four byte counter value, the other to write to the array buffer, but debugging in psoc 5 seems soo much slower than psoc 3.




                since I wanst actually "indexing" using multiple TD's can I change the name of the thread or take it down to not distract people?  I spent a lot of time looking through other peoples DMA posts to no avail.


                Or should I post my final solution?  I would like to be a responsible forum user.  Thanks again.

                • 5. Re: Index DMA

                  I would vote for posting final solution, would add to the dialog


                  here substantially.




                  Regards, Dana.

                  • 6. Re: Index DMA

                    In the end I was able to do what I wanted to do using code similar to what I had originally posted.


                    I had misunderstood how the dma advnaced its index.


                    I can save 8 channels of 4 byte data using two dma's per channel, one set to trigger the next, here is the working code for the first two dma initializations:


                    #define DMA_F_BYTES_PER_BURST 4


                    #define DMA_F_REQUEST_PER_BURST 1


                    #define DMA_S_BYTES_PER_BURST 4


                    #define DMA_S_REQUEST_PER_BURST 1




                    DMA_1_TD[0] = CyDmaTdAllocate();


                    CyDmaTdSetConfiguration(DMA_1_TD[0], 4, DMA_1_TD[0], DMA_1__TD_TERMOUT_EN| TD_INC_SRC_ADR  );


                    CyDmaTdSetAddress(DMA_1_TD[0], LO16((uint32)Main_Counter_COUNTER_LSB_PTR), LO16((uint32)&buff0));


                    CyDmaChSetInitialTd(DMA_1_Chan, DMA_1_TD[0]);


                    CyDmaChEnable(DMA_1_Chan, 1);


                    DMA_2_Chan = DMA_2_DmaInitialize(DMA_F_BYTES_PER_BURST, DMA_F_REQUEST_PER_BURST, HI16(CYDEV_SRAM_BASE), HI16(DMA_DST_BASE));


                    DMA_2_TD[0] = CyDmaTdAllocate();


                    CyDmaTdSetConfiguration(DMA_2_TD[0], MEM_DEPTH*4, DMA_2_TD[0], DMA_2__TD_TERMOUT_EN| TD_INC_DST_ADR  );




                    CyDmaChSetInitialTd(DMA_2_Chan, DMA_2_TD[0]);


                    CyDmaChEnable(DMA_2_Chan, 1);