PSoC Large DMA Transaction

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

cross mob
Anonymous
Not applicable

Hello,

   

My application has a stream of digital values being captured by a FIFO (http://www.cypress.com/?rID=46730). The number of data points sent by my target is 25,344 bytes. I have been able to estabilish a 2-D array in memory of the PSoC 5 device that works.

   

I am concerned that the DMA might not be able to directly transfer such a large chunk of data. I understand that it has some kind of counter limit?

   

Does anyone have any suggestions on how to go about this?

   

Thanks,

   

DiodeDan

0 Likes
3 Replies
Anonymous
Not applicable

Yes, the DMA has a limitation of (4KB - 1) for each TD because the count is stored in a 12 bit field.  That is only the limitation of the TD, but you can chain multiple TDs together if you want to support a larger transfer.  There are 128 TDs (you can use 104 of them since 24 are reserved for storage of the working status of each DMA channel).  Chaining several of these TDs together shouldn't pose a problem for your application.  With the FIFOIn component that you are using you will be getting a new request in for each byte, so you don't need to have the TD chain move from one TD to the next without a request.  However if for example you wanted to do a large transfer with a single request, that is supported by using the TD_AUTO_EXEC_NEXT option when you set up the TD.  In some cases it is also useful to know how far the DMA has progressed and that can be accomplished by using the DMA__TD_TERMOUT_EN (DMA needs to be replaced with the DMA instance name) option when you setup the TD.  That will cause the nrq output to pulse when that TD finishes.  Typically that is then hooked to an interrupt.

   

Brad Budlong

   

PSoC Sensei

0 Likes
Anonymous
Not applicable

 Brad,

   

Thanks for the quick reply. Also, thanks for the FIFO component. It is really useful.

   

I am looking at two options here:

   

1) Let's say that perhaps I wanted to use the FIFO's ISR instead? I was thinking that I could mask the register to interrupt on FIFO_NOT_FULL and then have the ISR grab one byte and transfer it to memory? The FIFO datasheet does not explain the ISR's triggering conditions though.

   

2) If I were to use DMA to transfer 25,344 bytes that means that I would have to make 7 TD's of 4095 elements right (28665 elements max). However, I am unclear on how to do this, especially with a 2D array. Would it look like this (?):

   

uint8 image[144][176];

   

 

   

uint8 tdArray[7];

   

//Setup the 6 TD's required for this task

   

for(i=0;i<6;i++)

   

     tdArray = CyDmaTdAllocate();

   

//Setup 1st 6 channels

   

for(i=0;i<6;i++)

   

{

   

     //Setup the 1st 6 td's to transfer 2^12-1 bytes to each successive td (except the last one), don't set off term_out

   

     CyDmaTdSetConfiguration(tdArray, 4095, tdArray[i+1],TD_INC_DST_ADR);

   

}

   

//Setup the last channel to transfer the remaining 774 bytes, and loop back to the 1st td, set off the term_out to let us know that whole buffer has been copied 

   

CyDmaTdSetConfiguration(tdArray[6], 774, tdArray[0],TD_INC_DST_ADR|DMA__TD_TERMOUT_EN));

0 Likes
Anonymous
Not applicable

 By the way,

   

I noted that the FIFO's "int" pin does not appear to be working. Have you tested it? I called FIFO_Start() and FIFO_Enable().

   

DiodeDan

0 Likes