From 4471418df1822e2e30eb81419e2e10d822f49b85 Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Fri, 31 Oct 2025 10:03:38 -0300 Subject: [PATCH] driver: adc_esp32: protect the adc reading against core migration. On dual core esp32 the either the interrupts and the FoC task may migrate to a different core, making the ADC registers subject to corruption if the other core tries to manage the ADC while current core owns it, so add a spinlock around the ADC to avoid that. On single core devices this is call is a NOOP. Signed-off-by: Felipe Neves --- .../hardware_specific/esp32/esp32_adc_driver.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/current_sense/hardware_specific/esp32/esp32_adc_driver.cpp b/src/current_sense/hardware_specific/esp32/esp32_adc_driver.cpp index 4c0fa8dc..0ed21131 100644 --- a/src/current_sense/hardware_specific/esp32/esp32_adc_driver.cpp +++ b/src/current_sense/hardware_specific/esp32/esp32_adc_driver.cpp @@ -6,6 +6,7 @@ #define SIMPLEFOC_ADC_ATTEN ADC_11db #define SIMPLEFOC_ADC_RES 12 +static portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; #if CONFIG_IDF_TARGET_ESP32 // if esp32 variant @@ -38,6 +39,7 @@ void IRAM_ATTR __configFastADCs(){ SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S); SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S); while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_MEAS_STATUS_S) != 0); //wait det_fsm== + } @@ -56,6 +58,10 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin) // variable to hold the ADC value uint16_t value = 0; + + //Protects against core migration, on single core chips this is noop. + portENTER_CRITICAL(&spinlock); + // do the ADC conversion switch(adc_num){ case 1: @@ -82,6 +88,8 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin) break; } + portEXIT_CRITICAL(&spinlock); + // return value return value; } @@ -128,6 +136,10 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin) // variable to hold the ADC value uint16_t value = 0; + + //Protects against core migration, on single core chips this is noop. + portENTER_CRITICAL(&spinlock); + // do the ADC conversion switch(adc_num){ case 1: @@ -154,6 +166,8 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin) break; } + portEXIT_CRITICAL(&spinlock); + return value; }