Skip to main content
Visitor II
March 24, 2023
Question

STM8L DMA and ADC out of sync?

  • March 24, 2023
  • 3 replies
  • 1427 views

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?

    This topic has been closed for replies.

    3 replies

    rmatveevAuthor
    Visitor II
    March 26, 2023

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

    rmatveevAuthor
    Visitor II
    March 31, 2023

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

    Any thought can be very helpful

    Visitor II
    March 31, 2023

    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.