Hello,
I am trying to use 2 DMA channels to read ADC results from 3 different ADC channels and save them in SRAM using DMA.
The code below works just fine if I use the DMA channels 0 and 1. It works also fine with channel 0 and anyone of the rest 15 channels. But for my project, I need channels 0 and 1 for something else. Therefore I need to use DMA channels other than 0 and 1.
I tried several combinations (channel 2 and 3 / 3 and 4 / 6 and 7 ....) but I am always getting false ADC values.
(See the screenshot below: the ADC value I should be getting in the first column is about 45100, which occurs SOMETIMES. When using DMA channels 0 and 1, I am ALWAYS recieving, as expected the right value.)
The code below is written based on the application note : "Using DMA to Emulate ADC Flexible Scan Mode".
Can anyone help figuring out the reason and how to solve it ?
Thank you
and here are the values using channel 0 and 1 :
Original Attachment has been moved to: ADC0_DMA_looking-for-channels.rar
Hello,
There are two types of linking channels: on Minor loop or on Major loop completion.
Basically, for this example, you need to link channels every time that 1 result from ADC is obtained, in this case, channel will be linked to move the next data to be converted, so you will need to user the Minoor Loop linking method.
This linking mode is configured in CITER/BITER registers:
In this case, in your previous example, you were setting ELINK mask but LINKCH was set to zero, so, in every minor loop, you were triggering channel 0. That is why you needed to use channel 0 + other channel to get this example working.
This can be solved by using two MACROs that defines the channels to be used and then write to CITER/BITER registers as follows (pay special attention to LINKCH field):
DMA0->TCD[SECOND_DMA_CHANNEL].CITER_ELINKYES = DMA_CITER_ELINKYES_ELINK_MASK |
DMA_CITER_ELINKYES_LINKCH(FIRST_DMA_CHANNEL) |
DMA_CITER_ELINKYES_CITER(0x0C);
DMA0->TCD[SECOND_DMA_CHANNEL].BITER_ELINKYES = DMA_BITER_ELINKYES_ELINK_MASK |
DMA_BITER_ELINKYES_LINKCH(FIRST_DMA_CHANNEL) |
DMA_BITER_ELINKYES_BITER(0x0C);
I adapted your project to use any DMA channel that is defined in FIRST_DMA_CHANNEL and SECOND_DMA_CHANNEL. I am attaching full dma.c file.
I hope this can help you!
Regards,
Isaac
Thanks :smileyhappy: