Index DMA

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

cross mob
Anonymous
Not applicable

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.

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

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).

   

 

   

Bob

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

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.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

"&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.

0 Likes
Anonymous
Not applicable

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.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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

   

here substantially.

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

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_Chan = DMA_1_DmaInitialize(DMA_F_BYTES_PER_BURST, DMA_F_REQUEST_PER_BURST, HI16(CYDEV_PERIPH_BASE), HI16(DMA_DST_BASE));

   

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  );

   

CyDmaTdSetAddress(DMA_2_TD[0],LO16((uint32)&buff0),LO16((uint32)time0));

   

CyDmaChSetInitialTd(DMA_2_Chan, DMA_2_TD[0]);

   

CyDmaChEnable(DMA_2_Chan, 1);

0 Likes