cancel
Showing results for 
Search instead for 
Did you mean: 

ADC register ADRDY never sets when I enable the ADC, so it keeps waiting there to start STM32F303RBT6

JMart.13
Senior

Hi all,

I have this problem. I want to start the ADC of my microcontroller, and following the reference manual it says I have to wait until the ADRDY register is set by the hardware to continue and make conversions, but that register never sets. This is my code:

This function enables the DMA fot the ADC

void DMA_Init(ADC_TypeDef * adc, DMA_Channel_TypeDef * dma_ch, std::uint16_t * buffer, std::uint32_t buffer_length,std::uint8_t length){
 
	adc->CFGR |= ADC_CFGR_CONT; 
	adc->CFGR |= ADC_CFGR_DMAEN | ADC_CFGR_DMACFG;
	adc->SMPR1 |= (7U << 3U) | (7U << 6U); //max sampling rate 
	
			
	dma_ch->CPAR = (std::uint32_t)(&adc->DR); 
	dma_ch->CMAR = (std::uint32_t)(buffer); 
	dma_ch->CNDTR = buffer_length; 	
	dma_ch->CCR |= DMA_CCR_EN;				
			
			
	Enable_regulator(adc);
	Enable(adc); 
	Calib(adc); 
	Enable(adc); 
			
}

So these are the enable regulator and enable functions:

void Enable_regulator(ADC_TypeDef * adc){ 
	adc->CR &= ~(ADC_CR_ADVERGEN_CLEAR); 
	adc->CR |= ADC_CR_ADVERGEN_ENABLE; 
	utils::delay::us(30); 
}
 
 
void Enable(ADC_TypeDef * adc){
	adc->CR |= ADC_CR_ADEN; 
	while(!(adc->ISR & ADC_ISR_ADRDY)){}
}

The enable regulator works perfectly. But the enable function keeps waiting forever. Any help would be great.

Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
JMart.13
Senior

OK, i had to configure the ADC12_COMMON_CLOCK with a prescaler of 2 to work:

ADC12_COMMON->CCR |= (1U << 17U);

Thanks for the help!

View solution in original post

11 REPLIES 11
AScha.3
Chief II

did you calibrate ADC ? need it first... see:

0693W00000VORAjQAP.pngso: first calibrate, wait, enable , wait , -> ready. set ADC channel, start ADC.

0693W00000VORAoQAP.png

If you feel a post has answered your question, please click "Accept as Solution".

Read out and check/post ADC registers content.

Did you enable ADC in RCC?

JW

Yes, before calling those methods. I checked in the registers if it was set before calling the methods

Hum whenever I need an operation of waiting for the hardware to set those bits it just freezes :/ since the calibration needs to wait until ADC_CR_ADCAL != 0

void Calib(ADC_TypeDef * adc){
	 
	adc->CR &= ~ADC_CR_ADCALDIF; 
	adc->CR |= ADC_CR_ADCAL; 
			
	while((adc->CR & ADC_CR_ADCAL) != 0){}
}

even disabling the ADC freeze at waiting

AScha.3
Chief II

enable ADC power - ok. and enable clock ?

0693W00000VORDnQAP.png

If you feel a post has answered your question, please click "Accept as Solution".

yep, the clock is configured for the ADC

JMart.13
Senior

OK, i had to configure the ADC12_COMMON_CLOCK with a prescaler of 2 to work:

ADC12_COMMON->CCR |= (1U << 17U);

Thanks for the help!

looking at this i tried to divide by 2 the clock frequency of the ADC and it worked. So thanks a lot!

I had the same problem with the STM32L431RCT6. ADRDY bit in ISR was never set after enabling. This caused the DMA to keep reading zeros from the ADC. It didn't work with prescaler set to 32 or 64, but it did sometimes work with 16. Slightly reordering the code, adding some delays or adding breakpoints at certain places would also affect this issue and either fix it or cause it to happen again. My workaround was to simply keep trying to set ADEN. Not pretty, but it works for all clock settings now!

// doesn't always work directly after calibration, so keep trying
while(LL_ADC_IsActiveFlag_ADRDY(ADC1) == 0) 
{
	LL_ADC_Enable(ADC1);
}

Edit: ST has a define LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES. It doesn't use this delay in generated code. But if you delay this number of ADC cycles after calibration the enable seems to work. But you still need to wait for the active flag to turn high before you can use the ADC. So I kept the code just in case

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.