DMA Channels Problem (Using DMA to Emulate ADC Flexible Scan Mode)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DMA Channels Problem (Using DMA to Emulate ADC Flexible Scan Mode)

1,069 Views
anouarraddaoui
Contributor I

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

165350_165350.pngpastedImage_1.png

and here are the values using channel 0 and 1 :

165351_165351.pngpastedImage_2.png

Original Attachment has been moved to: ADC0_DMA_looking-for-channels.rar

Labels (1)
0 Kudos
2 Replies

753 Views
isaacavila
NXP Employee
NXP Employee

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:

CITER_LINK register.jpg

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

753 Views
anouarraddaoui
Contributor I

Thanks :smileyhappy:

0 Kudos