cancel
Showing results for 
Search instead for 
Did you mean: 

STM8L DMA and ADC out of sync?

rmatveev
Associate II

I have STM8LDiscovery (with STM8L152C6T6 CPU). I need to continuously read 2 ADC channels with writing the data to the memory.

I'm doing my project in IAR EW for STM8 v. 3.11.4.

I run into the problem: channels data (ADC_DATA) continuously exchanging their places, so ADC_IN0 can be writen to either ADC_DATA[0] or to ADC_DATA[1] and vice versa for ADC_IN1. Moreover: ADC overrun error (ADC1_SR.OVER) is apearing right after the start of the application and never go away.

Looks like ADC and DMA works not in the sync. As there is overrun error in the ADC status register I assume that DMA works slower than ADC producing the conversion data.

DMA writes exactly 2 words of memory. I already have tested it by increasing the ADC_DATA array size.

My ADC and DMA configuration looks like this:

unsigned int ADC_DATA[10];

// ADC1 clock enable

CLK_PCKENR2_bit.PCKEN20 = 1;

// DMA1 clock enable

CLK_PCKENR2_bit.PCKEN24 = 1;

// ADC1_IN0 (PA5): Input, No pull-up, Interrupt disable

PA_DDR_bit.DDR5 = 0;

PA_CR1_bit.C15 = 0;

PA_CR2_bit.C25 = 0;

// ADC1_IN1 (PA6): Input, No pull-up, Interrupt disable

PA_DDR_bit.DDR6 = 0;

PA_CR1_bit.C16 = 0;

PA_CR2_bit.C26 = 0;

// ADC1 conversion complete interrupt disabled

ADC1_CR1_bit.EOCIE = 0;

// ADC1 continuous conversion mode enabled

ADC1_CR1_bit.CONT = 1;

// ADC1 clock prescale 1:2

ADC1_CR2_bit.PRESC = 1;

// ADC1 sequence selection

// PA6, PA5

ADC1_SQR1 = 0x00;

ADC1_SQR2 = 0x00;

ADC1_SQR3 = 0x00;

ADC1_SQR4 = 0x03;

// DMA channel 0 in increment mode

DMA1_C0CR_bit.MINCDEC = 1;

// DMA channel 0 in circular mode

DMA1_C0CR_bit.CIRC = 1;

// DMA channel 0 in direction: peripheral to memory

DMA1_C0CR_bit.DIR = 0;

// DMA channel 0 interrupt disabled

DMA1_C0CR_bit.TCIE = 0;

// DMA channel 0 priority LOW

DMA1_C0SPR_bit.PL0= 0;

DMA1_C0SPR_bit.PL1= 0;

// DMA channel 0 16-bit mode

DMA1_C0SPR_bit.TSIZE= 1;

// DMA number af words to transfer

DMA1_C0NDTR = 2;

// DMA channel 0 peripipheral address

DMA1_C0PARH = 0x53;

DMA1_C0PARL = 0x44;

// DMA channel 0 memory address

DMA1_C0M0ARH = (unsigned char)(((unsigned int)(&ADC_DATA[0])) / 256);

DMA1_C0M0ARL = (unsigned char)(((unsigned int)(&ADC_DATA[0])) % 256);

// DMA enabled

DMA1_GCSR_bit.GEN = 1;

// DMA channel 0 enabled

DMA1_C0CR_bit.EN = 1;

// ADC1 ON

ADC1_CR1_bit.ADON = 1;

// ADC1 start conversion

ADC1_CR1_bit.START = 1;

What could be wrong with my code?

3 REPLIES 3
rmatveev
Associate II

I have already tested to trigger ADC with timer. However - same thing happened

rmatveev
Associate II

Friends, I still desperately need some help. STM8 appears to have very small community.

Any thought can be very helpful

AA1
Senior III

Read RM0031 with attention.

Maybe there are other problems but power-on ADC should be first step and set DMA GEN bit should be last step.