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!

11 REPLIES 11

@Community member​ 

Thanks for reporting this.

Please, in all posts relating to ADC, tell us the STM32 model, as ADC is probably the most varying peripheral across STM32 models.

No related erratum?

> It didn't work with prescaler set to 32 or 64, but it did sometimes work with 16.

So, what was exactly the mcu/APB and ADC clock setting?

It sounds, that this is the key. ST's grip on the cross-clock-domain issues in peripherals is not stellar.

JW

> tell us the STM32 model

Done, I added STM32L431RCT6 to my posts.

> No related erratum?

No. The chapter about ADC had only the following issues:

  1. Writing ADCx_JSQR when JADCSTART and JQDIS are set might lead to incorrect behavior
  2. Wrong ADC result if conversion done late after calibration or previous conversion
  3. Spurious temperature measurement due to spike noise
  4. Selected external ADC inputs unduly clamped to VDD when all analog peripherals are disabled

None of them apply to this situation.

> So, what was exactly the mcu/APB and ADC clock setting?

Currently CPU=80MHz, ADC=1.25MHz. But it works for 2.5MHz and 5MHz as well. I haven't tested other frequencies, but if I go higher I cannot sample the temperature sensor slower than the minimum of 120us from the datasheet.

> It sounds, that this is the key. ST's grip on the cross-clock-domain issues in peripherals is not stellar.

I had my suspicion it was due to synchronization between MCU core and/or DMA with the ADC. I didn't know it was called Clock domain crossing (CDC). It sounds like something very fundamental that a manufacturer of MCUs should know how to avoid! The headerfile does have a define LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES, but it isn't used in any generated code!

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.