ADC conversions to memory via DMA

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

ADC conversions to memory via DMA

2,077 Views
dp05
Contributor II

I've gone through a few provided sample code examples in addition to the Peripherals Manual, but I've been unable to set up a baremetal example with the an ADC triggering a DMA request after each conversion and putting the 16-bit sample into a 128-byte circular buffer. Currently, it transfers the first sample and then stops. Do the channel registers need to be reinitialized after each transfer in an interrupt? The idea is to fill the buffer in VLPS mode and then wake up the core for analysis. Below is the initial register setup (using Device Initialization to generate init() code):

/* SIM_SCGC7: DMA=1 */

  SIM_SCGC7 |= (uint32_t)0x0100UL;                      

  /* SIM_SCGC6: DMAMUX=1 */

  SIM_SCGC6 |= (uint32_t)0x02UL;                      

  /* DMAMUX0_CHCFG0: ENBL=0,TRIG=0,SOURCE=0 */

  DMAMUX0_CHCFG0 = (uint8_t)0x00U;                         

  /* DMAMUX0_CHCFG1: ENBL=0,TRIG=0,SOURCE=0 */

  DMAMUX0_CHCFG1 = (uint8_t)0x00U;                         

  /* DMAMUX0_CHCFG2: ENBL=0,TRIG=0,SOURCE=0 */

  DMAMUX0_CHCFG2 = (uint8_t)0x00U;                         

  /* DMAMUX0_CHCFG3: ENBL=0,TRIG=0,SOURCE=0 */

  DMAMUX0_CHCFG3 = (uint8_t)0x00U;                         

  /* DMA_DSR_BCR0: DONE=1 */

  DMA_DSR_BCR0 |= (uint32_t)0x01000000UL;                      

  DMA_SAR0 = ((uint32_t)&ADC0_RA);

  DMA_DAR0 = ((uint32_t)&MyStaticArray);

  /* DMA_DSR_BCR0: CE=0,BES=0,BED=0,REQ=0,BSY=0,DONE=0,BCR=2 */

  DMA_DSR_BCR0 = (uint32_t)0x02UL;                 

  /* DMA_DCR0: EINT=1,ERQ=1,CS=1,AA=0,EADREQ=1,SINC=0,SSIZE=2,DINC=1,DSIZE=2,START=0,SMOD=0,DMOD=4,D_REQ=0,LINKCC=0,LCH1=0,LCH2=0 */

  DMA_DCR0 = (uint32_t)0xE0AC0400UL;                 

  /* DMAMUX0_CHCFG0: ENBL=1,TRIG=0,SOURCE=0x28 */

  DMAMUX0_CHCFG0 = (uint8_t)0xA8U;

Labels (1)
Tags (3)
0 Kudos
Reply
3 Replies

1,360 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

I checked your code DMA_DSR_BCRn register [BCR] bits is 2 bytes, that's why after the first transfer DMA will generate the interrupt to wake up the core from VLPS mode.

You need to modify [BCR] btis value to 0x80.

Please try to modify the below code :

from

/* DMA_DSR_BCR0: CE=0,BES=0,BED=0,REQ=0,BSY=0,DONE=0,BCR=2 */  

DMA_DSR_BCR0 = (uint32_t)0x02UL;

to

DMA_DSR_BCR0 = (uint32_t)0x80UL;

Wish it helps.

0 Kudos
Reply

1,360 Views
dp05
Contributor II

Thanks for pointing that out. With that update I do now get more samples filling the buffer and an interrupt triggering at the end of all the transfers. However I'm experiencing some strange behavior where the first 46 elements of the array are filled and then the DAR jumps to a pointer in a memory space just prior to the array, so I'm losing those last 18 elements and corrupting memory.

In terms of resetting the DMA in the ISR, what needs to be done to set up the next block of transfers? Using the sample code I was writing '1' to the DONE bit in DSR0, but that didn't help. Thinking that the registers need to be reconfigured I rewrote DSR_BCR0 to 0x80, reset DAR0 to the array pointer, and re-enabled DMAMUX0_CHCFG0[ENBL] and SOURCE (0x28). I am now getting behavior that returns to the head of the array after each interrupt. Are any of these actually needed, or are others needed?

Thanks again for your help!

0 Kudos
Reply

1,360 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

About how to resetting the DMA in the ISR, it need to write 1 to clear DMA_DSR_BCRn [DONE] bit and it also need to rewrite [BCR] bits with 0x80 value. There is no need to rewrite DAR0 and DMAMUX0_CHCFG0 registers, which register value does not modified.

About the abnormal issue (DAR jumps to a  pointer in a memory space just prior to the array), customer need to check the code if there exists another place with code to modify the DMA_DAR0 register.

Wish it helps.

0 Kudos
Reply