diff --git a/arch/arm/src/stm32h7/stm32_adc.c b/arch/arm/src/stm32h7/stm32_adc.c index d00e9bd2bb1..e4d608bb689 100644 --- a/arch/arm/src/stm32h7/stm32_adc.c +++ b/arch/arm/src/stm32h7/stm32_adc.c @@ -1253,6 +1253,8 @@ static void adc_enable(struct stm32_dev_s *priv) /* Wait for hardware to be ready for conversions */ while (!(adc_getreg(priv, STM32_ADC_ISR_OFFSET) & ADC_INT_ADRDY)); + + adc_modifyreg(priv, STM32_ADC_ISR_OFFSET, 0, ADC_INT_ADRDY); } /**************************************************************************** @@ -2008,6 +2010,13 @@ static int adc_interrupt(struct adc_dev_s *dev, uint32_t adcisr) /* Stop ADC conversions to avoid continuous interrupts */ adc_startconv(priv, false); + + /* Clear the interrupt. This register only accepts write 1's so its + * safe to only set the 1 bit without regard for the rest of the + * register + */ + + adc_putreg(priv, STM32_ADC_ISR_OFFSET, ADC_INT_AWD1); } /* OVR: Overrun */ @@ -2037,6 +2046,11 @@ static int adc_interrupt(struct adc_dev_s *dev, uint32_t adcisr) priv->cb->au_reset(dev); } + /* Clear the interrupt. This register only accepts write 1's so its + * safe to only set the 1 bit without regard for the rest of the + * register + */ + adc_putreg(priv, STM32_ADC_ISR_OFFSET, ADC_INT_OVR); } @@ -2091,6 +2105,10 @@ static int adc_interrupt(struct adc_dev_s *dev, uint32_t adcisr) } } while ((adc_getreg(priv, STM32_ADC_ISR_OFFSET) & ADC_INT_EOC) != 0); + + /* We dont't add EOC to the bits to clear. It will cause a race + * condition. EOC should only be cleared by reading the ADC_DR + */ } return OK; @@ -2120,10 +2138,6 @@ static int adc12_interrupt(int irq, void *context, void *arg) if (pending != 0) { adc_interrupt(&g_adcdev1, regval); - - /* Clear interrupts */ - - putreg32(regval, STM32_ADC1_ISR); } #endif @@ -2133,10 +2147,6 @@ static int adc12_interrupt(int irq, void *context, void *arg) if (pending != 0) { adc_interrupt(&g_adcdev2, regval); - - /* Clear interrupts */ - - putreg32(regval, STM32_ADC2_ISR); } #endif @@ -2167,10 +2177,6 @@ static int adc3_interrupt(int irq, void *context, void *arg) if (pending != 0) { adc_interrupt(&g_adcdev3, regval); - - /* Clear interrupts */ - - putreg32(regval, STM32_ADC3_ISR); } return OK;