From a3991ebfc040f0a4c172cf16efcfb2b9e147e08c Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Sun, 12 Oct 2025 17:58:23 -0300 Subject: [PATCH] ESP32: move runtime ADC reading functions to IRAM. * It will improve the execution speed. * It will prevent crashes if the chip disables the ICACHE Signed-off-by: Felipe Neves --- .../esp32/esp32_adc_driver.cpp | 28 +++++++++---------- .../esp32/esp32_mcpwm_mcu.cpp | 6 ++-- .../hardware_specific/esp32/esp32_mcu.cpp | 6 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) 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 5d8d7e79..4c0fa8dc 100644 --- a/src/current_sense/hardware_specific/esp32/esp32_adc_driver.cpp +++ b/src/current_sense/hardware_specific/esp32/esp32_adc_driver.cpp @@ -2,7 +2,7 @@ #include "esp32_mcu.h" #include "esp32_adc_driver.h" -#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) +#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) #define SIMPLEFOC_ADC_ATTEN ADC_11db #define SIMPLEFOC_ADC_RES 12 @@ -12,12 +12,12 @@ #include "soc/sens_reg.h" // configure the ADCs in RTC mode -// saves about 3us per call +// saves about 3us per call // going from 12us to 9us -// +// // TODO: See if we need to configure both ADCs or we can just configure the one we'll use // For the moment we will configure both -void __configFastADCs(){ +void IRAM_ATTR __configFastADCs(){ SIMPLEFOC_ESP32_CS_DEBUG("Configuring fast ADCs"); @@ -46,9 +46,9 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin) int8_t channel = digitalPinToAnalogChannel(pin); if(channel < 0){ SIMPLEFOC_ESP32_CS_DEBUG("ERROR: Not ADC pin: "+String(pin)); - return false; //not adc pin + return false; //not adc pin } - + // channels <= MAX_CHANNEL_NUM belong to ADC1 // channels > MAX_CHANNEL_NUM belong to ADC2 (where the channel number is number-SOC_ADC_MAX_CHANNEL_NUM) uint8_t adc_num = (channel >= SOC_ADC_MAX_CHANNEL_NUM) ? 2 : 1; @@ -65,7 +65,7 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin) SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M); // wait for conversion - while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0); + while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0); // read the value value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S); break; @@ -76,7 +76,7 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin) SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M); // wait for conversion - while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0); + while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0); // read the value value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S); break; @@ -91,10 +91,10 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin) #include "soc/sens_reg.h" -// configure the ADCs in RTC mode +// configure the ADCs in RTC mode // no real gain - see if we do something with it later // void __configFastADCs(){ - + // SET_PERI_REG_MASK(SENS_SAR_READER1_CTRL_REG, SENS_SAR1_DATA_INV); // SET_PERI_REG_MASK(SENS_SAR_READER2_CTRL_REG, SENS_SAR2_DATA_INV); @@ -137,7 +137,7 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin) SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR_M); // wait for conversion - while (GET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DONE_SAR) == 0); + while (GET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DONE_SAR) == 0); // read the value value = GET_PERI_REG_BITS2(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S); break; @@ -148,7 +148,7 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin) SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_SAR_M); // wait for conversion - while (GET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DONE_SAR) == 0); + while (GET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DONE_SAR) == 0); // read the value value = GET_PERI_REG_BITS2(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S); break; @@ -171,7 +171,7 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin){ // configure the ADC for the pin bool IRAM_ATTR adcInit(uint8_t pin){ static bool initialized = false; - + int8_t channel = digitalPinToAnalogChannel(pin); if(channel < 0){ SIMPLEFOC_ESP32_CS_DEBUG("ERROR: Not ADC pin: "+String(pin)); @@ -186,7 +186,7 @@ bool IRAM_ATTR adcInit(uint8_t pin){ if(! initialized){ analogSetAttenuation(SIMPLEFOC_ADC_ATTEN); analogReadResolution(SIMPLEFOC_ADC_RES); - } + } pinMode(pin, ANALOG); analogRead(pin); analogSetPinAttenuation(pin, SIMPLEFOC_ADC_ATTEN); diff --git a/src/current_sense/hardware_specific/esp32/esp32_mcpwm_mcu.cpp b/src/current_sense/hardware_specific/esp32/esp32_mcpwm_mcu.cpp index 1afdd50c..029daa64 100644 --- a/src/current_sense/hardware_specific/esp32/esp32_mcpwm_mcu.cpp +++ b/src/current_sense/hardware_specific/esp32/esp32_mcpwm_mcu.cpp @@ -43,7 +43,7 @@ // function reading an ADC value and returning the read voltage -float _readADCVoltageLowSide(const int pin, const void* cs_params){ +float IRAM_ATTR _readADCVoltageLowSide(const int pin, const void* cs_params){ ESP32CurrentSenseParams* p = (ESP32CurrentSenseParams*)cs_params; int no_channel = 0; for(int i=0; i < 3; i++){ @@ -59,7 +59,7 @@ float _readADCVoltageLowSide(const int pin, const void* cs_params){ // function configuring low-side current sensing -void* _configureADCLowSide(const void* driver_params, const int pinA,const int pinB,const int pinC){ +void* IRAM_ATTR _configureADCLowSide(const void* driver_params, const int pinA,const int pinB,const int pinC){ // check if driver timer is already running // fail if it is // the easiest way that I've found to check if timer is running @@ -116,7 +116,7 @@ static bool IRAM_ATTR _mcpwmTriggerADCCallback(mcpwm_timer_handle_t tim, const m return true; } -void* _driverSyncLowSide(void* driver_params, void* cs_params){ +void* IRAM_ATTR _driverSyncLowSide(void* driver_params, void* cs_params){ #ifdef SIMPLEFOC_ESP32_INTERRUPT_DEBUG pinMode(DEBUGPIN, OUTPUT); #endif diff --git a/src/current_sense/hardware_specific/esp32/esp32_mcu.cpp b/src/current_sense/hardware_specific/esp32/esp32_mcu.cpp index e5ed3fbf..95667069 100644 --- a/src/current_sense/hardware_specific/esp32/esp32_mcu.cpp +++ b/src/current_sense/hardware_specific/esp32/esp32_mcu.cpp @@ -3,16 +3,16 @@ #if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) /** - * Inline adc reading implementation + * Inline adc reading implementation */ // function reading an ADC value and returning the read voltage -float _readADCVoltageInline(const int pinA, const void* cs_params){ +float IRAM_ATTR _readADCVoltageInline(const int pinA, const void* cs_params){ uint32_t raw_adc = adcRead(pinA); return raw_adc * ((ESP32CurrentSenseParams*)cs_params)->adc_voltage_conv; } // function reading an ADC value and returning the read voltage -void* _configureADCInline(const void* driver_params, const int pinA, const int pinB, const int pinC){ +void* IRAM_ATTR _configureADCInline(const void* driver_params, const int pinA, const int pinB, const int pinC){ ESP32CurrentSenseParams* params = new ESP32CurrentSenseParams { .pins = { pinA, pinB, pinC },