2026-01-29 3:25 AM
Hello,
here the exit of my (extended)initialization prodecure for ADC of STM32U535 running at 3.3v and 160 Mhz. Before setting ADC_CR_ADSTART, without the small delay or with the delay in line 14 and the limit for i smaller "6" like here "5" in the code, ADC_CR_ADSTART stays high and the programm keeps in the while (ADC1->CR & ADC_CR_ADSTART) loop line16/17. __DMB() is not replacement for the delay.
Is the needed delay some artefact of my setup or some requirement that I do not find/oversee in RM0456?
ADC1->CR |= ADC_CR_ADCAL; /*8*/
while (ADC1->CR & ADC_CR_ADCAL) {
__NOP();
}
__DMB();
ADC1->CR &= ~ADC_CR_ADCALLIN;
__DMB();
const uint8_t channel = 19U;
AdcSetRegularSequence(ADC1, 1U, &channel);
ADC1->CR |= ADC_CR_ADEN;
while (!(ADC1->ISR & ADC_ISR_ADRDY)) {
__NOP();
}
for (volatile int i = 0; i < 5; i++) {}
ADC1->CR |= ADC_CR_ADSTART;
while (ADC1->CR & ADC_CR_ADSTART) {
__NOP();
2026-01-29 3:32 AM - edited 2026-01-29 3:34 AM
ADC is dual-clock (if not more), so perhaps you want to add also the clock setup to the minimal example exhibiting the failure.
ST might want to start to meticulously document the exact delays needed and their relationship to the clocks, instead of "oh just throw in a DMB here and there" (it would be even better would there be a foolproof method of setting up things based on readbacks, but I understand that hardware bugs creep in, the hardware complexity shot through the roof long ago, but ST should not resort to handwaving like the far-eastern competition routinely does). The duration of DMB may vary with exact source of execution and maybe other factors, too.
JW
2026-01-29 3:50 AM
Here the ADC clock setting
RCC->CCIPR3 |= RCC_CCIPR3_ADCDACSEL_0;
RCC->AHB2ENR1 |= RCC_AHB2ENR1_ADC12EN;
RCC->AHB2RSTR1 |= RCC_AHB2RSTR1_ADC12RST;
RCC->AHB2RSTR1 = 0;
/* Wake up */
ADC1->CR &= ~ADC_CR_DEEPPWD;
ADC1->ISR = ADC_ISR_LDORDY;
ADC1->CR |= ADC_CR_ADVREGEN;
while ((ADC1->ISR & ADC_ISR_LDORDY) == 0U)
continue;
/* Divide Sysclk by 4 for 40 MHz ADC clock*/
ADC12_COMMON_NS->CCR &= ~ADC_CCR_PRESC_Msk;
ADC12_COMMON_NS->CCR |= ADC_CCR_PRESC_1;
AdcPowerOff(ADC1);