stm32h7: Fix race condition in ADC interrupt handling
This commit is contained in:
parent
a5b5c963c7
commit
d808ed450c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user