- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"&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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would vote for posting final solution, would add to the dialog
here substantially.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);