This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new b495b7b95c4 arch/arm/stm32h5: Fix hanging ADC enable call.
b495b7b95c4 is described below
commit b495b7b95c4d2d5ed909068fbf2a74b94e78895f
Author: Randy Rossi <[email protected]>
AuthorDate: Sat Oct 18 10:20:58 2025 -0400
arch/arm/stm32h5: Fix hanging ADC enable call.
Posix open() calls to /dev/adc# were hanging often due
to the ready loop check at the end of adc_enable() never
returning. According to ES0565 document, at least 4 ADC
clock cycles must pass between the time we waited for
calibration to end and before we can set ADEN. This will
depend on what clock is set for ADC. So to ensure enough
time passes, we are adding a short delay (so that even a
slow clock will work). Also, we are clearing the ADRDY
flag before hand to ensure we are detecting a fresh event.
The delay to wait for the voltage regulator is also
increased to account for extra time required in
non-ideal conditions.
Signed-off-by: Liam Howatt <[email protected]>
---
arch/arm/src/stm32h5/stm32_adc.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/arm/src/stm32h5/stm32_adc.c b/arch/arm/src/stm32h5/stm32_adc.c
index e38f34e8a70..8e7d31113dd 100644
--- a/arch/arm/src/stm32h5/stm32_adc.c
+++ b/arch/arm/src/stm32h5/stm32_adc.c
@@ -649,7 +649,12 @@ static void adc_enable(struct stm32_dev_s *priv)
/* Wait for voltage regulator to power up */
- up_udelay(20);
+ /* Datasheet recommends a _minimum_ of 20ms but it will depend
+ * on temperature, supply ramp and whether we've recently
+ * powered up ADC. So give a larger delay for safety.
+ */
+
+ up_udelay(50);
/* Perform single-ended and/or differential calibration if necessary */
@@ -680,6 +685,17 @@ static void adc_enable(struct stm32_dev_s *priv)
* ARM instructions.
*/
+ /* ES0565 document (STM32H562/563/573 series) : As noted above, we
+ * can't set ADEN until 4 ADC clock cycles from now. This will depend
+ * on what we use for ADC clock. To ensure we give enough guard time
+ * we are delaying ADEN by at least 1 microsecond. This will ensure
+ * even a slow clock will have enough time before we try to set ADEN.
+ * Also, clear ADRDY to ensure we are waiting for a fresh event.
+ */
+
+ adc_modifyreg(priv, STM32_ADC_ISR_OFFSET, 0, ADC_INT_ADRDY);
+ up_udelay(1);
+
regval = adc_getreg(priv, STM32_ADC_CR_OFFSET);
regval |= ADC_CR_ADEN;
adc_putreg(priv, STM32_ADC_CR_OFFSET, regval);