From 74f4582aacfc790ef3c09be8ccb3224cf95ba25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Procha=CC=81zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:32:25 +0100 Subject: [PATCH 1/6] Adc refactored + periman implementation Peripheral manager still needs to be checked if the implementation is right. --- cores/esp32/esp32-hal-adc.c | 447 +++++++++++++++++++++--------------- cores/esp32/esp32-hal-adc.h | 25 +- 2 files changed, 271 insertions(+), 201 deletions(-) diff --git a/cores/esp32/esp32-hal-adc.c b/cores/esp32/esp32-hal-adc.c index 50a3d5e676e..b1d279895b6 100644 --- a/cores/esp32/esp32-hal-adc.c +++ b/cores/esp32/esp32-hal-adc.c @@ -13,129 +13,219 @@ // limitations under the License. #include "esp32-hal-adc.h" -#include "driver/adc.h" -#include "esp_adc_cal.h" -#if SOC_DAC_SUPPORTED //ESP32, ESP32S2 -#include "soc/dac_channel.h" -#include "soc/sens_reg.h" -#include "soc/rtc_io_reg.h" -#endif +#if SOC_ADC_SUPPORTED +#include "esp32-hal.h" +#include "esp32-hal-periman.h" +#include "esp_adc/adc_oneshot.h" +#include "esp_adc/adc_cali_scheme.h" -#define DEFAULT_VREF 1100 +static uint8_t __analogAttenuation = ADC_11db; +static uint8_t __analogWidth = SOC_ADC_RTC_MAX_BITWIDTH; +static uint8_t __analogReturnedWidth = SOC_ADC_RTC_MAX_BITWIDTH; -static uint8_t __analogAttenuation = 3;//11db -static uint8_t __analogWidth = ADC_WIDTH_MAX - 1; //3 for ESP32/ESP32C3; 4 for ESP32S2 -static uint8_t __analogReturnedWidth = SOC_ADC_RTC_MAX_BITWIDTH; //12 for ESP32/ESP32C3; 13 for ESP32S2 -static uint8_t __analogClockDiv = 1; -static adc_attenuation_t __pin_attenuation[SOC_GPIO_PIN_COUNT]; +adc_oneshot_unit_handle_t adc_handle[SOC_ADC_PERIPH_NUM]; +adc_cali_handle_t adc_cali_handle[SOC_ADC_PERIPH_NUM]; -static uint16_t __analogVRef = 0; -#if CONFIG_IDF_TARGET_ESP32 -static uint8_t __analogVRefPin = 0; -#endif +static bool adcDetachBus(void * bus){ + + uint8_t used_channels = 0; + adc_unit_t adc_unit = 0; + + for(int i = 0; i < SOC_ADC_PERIPH_NUM; i++){ + if(adc_handle[i] == bus){ + adc_unit = i; + break; + } + } + + for (uint8_t channel = 0; channel < SOC_ADC_CHANNEL_NUM(adc_unit); channel++){ + int io_pin; + adc_oneshot_channel_to_io(adc_unit, channel, &io_pin); + if(perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_ONESHOT){ + used_channels++; + } + } + + if(used_channels == 1) {//only 1 channel is used + esp_err_t err = adc_oneshot_del_unit((adc_oneshot_unit_handle_t)bus); + if(err != ESP_OK){ + return false; + } + adc_handle[adc_unit] = NULL; + } + return true; +} + +esp_err_t __analogChannelConfig(adc_bitwidth_t width, adc_attenuation_t atten, int8_t pin){ + + esp_err_t err = ESP_OK; + adc_oneshot_chan_cfg_t config = { + .bitwidth = width, + .atten = (atten & 3), + }; + if(pin == -1){ //Reconfigure all used analog pins/channels + for(int adc_unit = 0 ; adc_unit < SOC_ADC_PERIPH_NUM; adc_unit++){ + if(adc_handle[adc_unit] != NULL){ + for (uint8_t channel = 0; channel < SOC_ADC_CHANNEL_NUM(adc_unit); channel++){ + int io_pin; + adc_oneshot_channel_to_io( adc_unit, channel, &io_pin); + if(perimanGetPinBusType(io_pin) == ESP32_BUS_TYPE_ADC_ONESHOT){ + err = adc_oneshot_config_channel(adc_handle[adc_unit], channel, &config); + if(err != ESP_OK){ + log_e("adc_oneshot_config_channel failed with error: %d", err); + return err; + } + } + } + //ADC calibration reconfig only if all channels are updated + if(adc_cali_handle[adc_unit] != NULL){ + #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED + log_d("Deleting ADC_UNIT_%d cali handle",adc_unit); + err = adc_cali_delete_scheme_curve_fitting(adc_cali_handle[adc_unit]); + if(err != ESP_OK){ + log_e("adc_cali_delete_scheme_curve_fitting failed with error: %d", err); + return err; + } + adc_cali_curve_fitting_config_t cali_config = { + .unit_id = adc_unit, + .atten = atten, + .bitwidth = width, + }; + log_d("Creating ADC_UNIT_%d curve cali handle",adc_unit); + err = adc_cali_create_scheme_curve_fitting(&cali_config, &adc_cali_handle[adc_unit]); + if(err != ESP_OK){ + log_e("adc_cali_create_scheme_curve_fitting failed with error: %d", err); + return err; + } + #else if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED + log_d("Deleting ADC_UNIT_%d line cali handle",adc_unit); + err = adc_cali_delete_scheme_line_fitting(adc_cali_handle[adc_unit]); + if(err != ESP_OK){ + log_e("adc_cali_delete_scheme_line_fitting failed with error: %d", err); + return err; + } + adc_cali_line_fitting_config_t cali_config = { + .unit_id = adc_unit, + .atten = atten, + .bitwidth = width, + }; + log_d("Creating ADC_UNIT_%d line cali handle",adc_unit); + err = adc_cali_create_scheme_line_fitting(&cali_config, &adc_cali_handle[adc_unit]); + if(err != ESP_OK){ + log_e("adc_cali_create_scheme_line_fitting failed with error: %d", err); + return err; + } + #endif + } + } + } + + //make it default for next channels + __analogWidth = width; + __analogAttenuation = atten; + } + else{ //Reconfigure single channel + if(perimanGetPinBusType(pin) == ESP32_BUS_TYPE_ADC_ONESHOT){ + adc_channel_t channel; + adc_unit_t adc_unit; + + adc_oneshot_io_to_channel(pin, &adc_unit, &channel); + if(err != ESP_OK){ + log_e("Pin %u is not ADC pin!", pin); + return err; + } + err = adc_oneshot_config_channel(adc_handle[adc_unit], channel, &config); + if(err != ESP_OK){ + log_e("adc_oneshot_config_channel failed with error: %d", err); + return err; + } + } + else { + log_e("Pin is not configured as analog channel"); + } + } + return ESP_OK; +} static inline uint16_t mapResolution(uint16_t value) { - uint8_t from = __analogWidth + 9; - if (from == __analogReturnedWidth) { + uint8_t from = __analogWidth; + if (from == __analogReturnedWidth){ return value; } - if (from > __analogReturnedWidth) { + if (from > __analogReturnedWidth){ return value >> (from - __analogReturnedWidth); } return value << (__analogReturnedWidth - from); } -void __analogSetClockDiv(uint8_t clockDiv){ - if(!clockDiv){ - clockDiv = 1; - } - __analogClockDiv = clockDiv; -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 - adc_set_clk_div(__analogClockDiv); -#endif -} - void __analogSetAttenuation(adc_attenuation_t attenuation) { - __analogAttenuation = attenuation & 3; + if(__analogChannelConfig(__analogWidth, attenuation, -1) != ESP_OK){ + log_e("__analogChannelConfig failed!"); + } } #if CONFIG_IDF_TARGET_ESP32 -void __analogSetWidth(uint8_t bits){ - if(bits < 9){ - bits = 9; - } else if(bits > 12){ - bits = 12; +void __analogSetWidth(uint8_t bits) +{ + if(bits < SOC_ADC_RTC_MIN_BITWIDTH){ + bits = SOC_ADC_RTC_MIN_BITWIDTH; + } + else if(bits > SOC_ADC_RTC_MAX_BITWIDTH){ + bits = SOC_ADC_RTC_MAX_BITWIDTH; + } + if(__analogChannelConfig(bits, __analogAttenuation, -1) != ESP_OK){ + log_e("__analogChannelConfig failed!"); } - __analogWidth = bits - 9; - adc1_config_width(__analogWidth); } #endif -void __analogInit(){ - static bool initialized = false; - if(initialized){ - return; - } - initialized = true; - __analogSetClockDiv(__analogClockDiv); -#if CONFIG_IDF_TARGET_ESP32 - __analogSetWidth(__analogWidth + 9);//in bits -#endif - for(int i=0; i 3){ - return ; + esp_err_t err = ESP_OK; + if(adc_handle[adc_unit] == NULL) { + adc_oneshot_unit_init_cfg_t init_config1 = { + .unit_id = adc_unit, + .ulp_mode = ADC_ULP_MODE_DISABLE, + }; + err = adc_oneshot_new_unit(&init_config1, &adc_handle[adc_unit]); + + if(err != ESP_OK){ + log_e("adc_oneshot_new_unit failed with error: %d", err); + return err; + } } - if(channel > (SOC_ADC_MAX_CHANNEL_NUM - 1)){ - adc2_config_channel_atten(channel - SOC_ADC_MAX_CHANNEL_NUM, attenuation); - } else { - adc1_config_channel_atten(channel, attenuation); + + if(!perimanSetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT, (void *)adc_handle[adc_unit])){ + adcDetachBus((void *)adc_handle[adc_unit]); + return err; } - __analogInit(); - if((__pin_attenuation[pin] != ADC_ATTENDB_MAX) || (attenuation != __analogAttenuation)){ - __pin_attenuation[pin] = attenuation; + + adc_oneshot_chan_cfg_t config = { + .bitwidth = __analogWidth, + .atten = __analogAttenuation, + }; + + err = adc_oneshot_config_channel(adc_handle[adc_unit], channel, &config); + + if(err != ESP_OK){ + log_e("adc_oneshot_config_channel failed with error: %d", err); + return err; } + + perimanSetBusDeinit(ESP32_BUS_TYPE_ADC_ONESHOT, adcDetachBus); + + return ESP_OK; } -bool __adcAttachPin(uint8_t pin){ - int8_t channel = digitalPinToAnalogChannel(pin); - if(channel < 0){ - log_e("Pin %u is not ADC pin!", pin); - return false; - } - __analogInit(); - int8_t pad = digitalPinToTouchChannel(pin); - if(pad >= 0){ -#if CONFIG_IDF_TARGET_ESP32 - uint32_t touch = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG); - if(touch & (1 << pad)){ - touch &= ~((1 << (pad + SENS_TOUCH_PAD_OUTEN2_S)) - | (1 << (pad + SENS_TOUCH_PAD_OUTEN1_S)) - | (1 << (pad + SENS_TOUCH_PAD_WORKEN_S))); - WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, touch); - } -#endif - } -#if SOC_DAC_SUPPORTED - else if(pin == DAC_CHANNEL_1_GPIO_NUM){ - CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE);//stop dac1 - } else if(pin == DAC_CHANNEL_2_GPIO_NUM){ - CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE);//stop dac2 +void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation) +{ + if(__analogChannelConfig(__analogWidth, attenuation, pin) != ESP_OK) + { + log_e("__analogChannelConfig failed!"); } -#endif - - pinMode(pin, ANALOG); - __analogSetPinAttenuation(pin, (__pin_attenuation[pin] != ADC_ATTENDB_MAX)?__pin_attenuation[pin]:__analogAttenuation); - return true; } void __analogReadResolution(uint8_t bits) @@ -144,130 +234,125 @@ void __analogReadResolution(uint8_t bits) return; } __analogReturnedWidth = bits; + #if CONFIG_IDF_TARGET_ESP32 - __analogSetWidth(bits); // hadware from 9 to 12 + __analogSetWidth(bits); // hardware analog resolution from 9 to 12 #endif } uint16_t __analogRead(uint8_t pin) { - int8_t channel = digitalPinToAnalogChannel(pin); int value = 0; - esp_err_t r = ESP_OK; - if(channel < 0){ + adc_channel_t channel; + adc_unit_t adc_unit; + + esp_err_t err = ESP_OK; + adc_oneshot_io_to_channel(pin, &adc_unit, &channel); + if(err != ESP_OK){ log_e("Pin %u is not ADC pin!", pin); return value; } - __adcAttachPin(pin); - if(channel > (SOC_ADC_MAX_CHANNEL_NUM - 1)){ - channel -= SOC_ADC_MAX_CHANNEL_NUM; - r = adc2_get_raw( channel, __analogWidth, &value); - if ( r == ESP_OK ) { - return mapResolution(value); - } else if ( r == ESP_ERR_INVALID_STATE ) { - log_e("GPIO%u: %s: ADC2 not initialized yet.", pin, esp_err_to_name(r)); - } else if ( r == ESP_ERR_TIMEOUT ) { - log_e("GPIO%u: %s: ADC2 is in use by Wi-Fi. Please see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/adc.html#adc-limitations for more info", pin, esp_err_to_name(r)); - } else { - log_e("GPIO%u: %s", pin, esp_err_to_name(r)); + //log_d("adc_unit = %d adc_channel = %d",adc_unit,channel); + + adc_oneshot_unit_handle_t bus = (adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT); + if(bus == NULL){ + //log_d("No BUS - calling __analogInit()"); + + err = __analogInit(pin, channel, adc_unit); + if(err != ESP_OK){ + log_e("Analog initialization failed!"); + return value; } - } else { - value = adc1_get_raw(channel); - return mapResolution(value); } + + + adc_oneshot_read((adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT), channel, &value); return mapResolution(value); + } + uint32_t __analogReadMilliVolts(uint8_t pin){ - int8_t channel = digitalPinToAnalogChannel(pin); - if(channel < 0){ + + int value = 0; + int raw_value = 0; + adc_channel_t channel; + adc_unit_t adc_unit; + esp_err_t err = ESP_OK; + + adc_oneshot_io_to_channel(pin, &adc_unit, &channel); + if(err != ESP_OK){ log_e("Pin %u is not ADC pin!", pin); - return 0; + return value; } - if(!__analogVRef){ - if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) { - log_d("eFuse Two Point: Supported"); - __analogVRef = DEFAULT_VREF; - } - if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) { - log_d("eFuse Vref: Supported"); - __analogVRef = DEFAULT_VREF; - } - if(!__analogVRef){ - __analogVRef = DEFAULT_VREF; - - #if CONFIG_IDF_TARGET_ESP32 - if(__analogVRefPin){ - esp_adc_cal_characteristics_t chars; - if(adc_vref_to_gpio(ADC_UNIT_2, __analogVRefPin) == ESP_OK){ - __analogVRef = __analogRead(__analogVRefPin); - esp_adc_cal_characterize(1, __analogAttenuation, __analogWidth, DEFAULT_VREF, &chars); - __analogVRef = esp_adc_cal_raw_to_voltage(__analogVRef, &chars); - log_d("Vref to GPIO%u: %u", __analogVRefPin, __analogVRef); - } - } - #endif - } - } - uint8_t unit = 1; - if(channel > (SOC_ADC_MAX_CHANNEL_NUM - 1)){ - unit = 2; - } + //log_d("adc_unit = %d adc_channel = %d",adc_unit,channel); - uint16_t adc_reading = __analogRead(pin); + adc_oneshot_unit_handle_t bus = (adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT); + if(bus == NULL){ - uint8_t atten = __analogAttenuation; - if (__pin_attenuation[pin] != ADC_ATTENDB_MAX){ - atten = __pin_attenuation[pin]; - } + //log_d("No BUS - calling __analogInit()"); - esp_adc_cal_characteristics_t chars = {}; - esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, __analogWidth, __analogVRef, &chars); + err = __analogInit(pin, channel, adc_unit); + if(err != ESP_OK){ + log_e("Analog initialization failed!"); + return value; + } + } - static bool print_chars_info = true; - if(print_chars_info) + if(adc_cali_handle[adc_unit] == NULL) { - if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { - log_i("ADC%u: Characterized using Two Point Value: %u\n", unit, chars.vref); - } - else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { - log_i("ADC%u: Characterized using eFuse Vref: %u\n", unit, chars.vref); - } - #if CONFIG_IDF_TARGET_ESP32 - else if(__analogVRef != DEFAULT_VREF){ - log_i("ADC%u: Characterized using Vref to GPIO%u: %u\n", unit, __analogVRefPin, chars.vref); - } + log_d("Creating cali handle for ADC_%d", adc_unit); + #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED + adc_cali_curve_fitting_config_t cali_config = { + .unit_id = adc_unit, + .atten = __analogAttenuation, + .bitwidth = __analogWidth, + }; + err = adc_cali_create_scheme_curve_fitting(&cali_config, &adc_cali_handle[adc_unit]); + #else if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED + adc_cali_line_fitting_config_t cali_config = { + .unit_id = adc_unit, + .bitwidth = __analogWidth, + .atten = __analogAttenuation, + }; + err = adc_cali_create_scheme_line_fitting(&cali_config, &adc_cali_handle[adc_unit]); #endif - else { - log_i("ADC%u: Characterized using Default Vref: %u\n", unit, chars.vref); + if(err != ESP_OK){ + log_e("adc_cali_create_scheme_x failed!"); + return value; } - print_chars_info = false; } - return esp_adc_cal_raw_to_voltage((uint32_t)adc_reading, &chars); -} - -#if CONFIG_IDF_TARGET_ESP32 - -void __analogSetVRefPin(uint8_t pin){ - if(pin <25 || pin > 27){ - pin = 0; + + err = adc_oneshot_get_calibrated_result((adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT), adc_cali_handle[adc_unit], channel, &value); + if(err != ESP_OK){ + log_e("adc_oneshot_get_calibrated_result failed!"); + return 0; } - __analogVRefPin = pin; -} + /* + err = adc_oneshot_read((adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT), channel, &raw_value); + if(err != ESP_OK){ + log_e("adc_oneshot_read failed!"); + return value; + } + adc_cali_raw_to_voltage(adc_cali_handle[adc_unit], raw_value, &value); + if(err != ESP_OK){ + log_e("adc_cali_raw_to_voltage failed!"); + return 0; + } + */ + return value; -#endif +} extern uint16_t analogRead(uint8_t pin) __attribute__ ((weak, alias("__analogRead"))); extern uint32_t analogReadMilliVolts(uint8_t pin) __attribute__ ((weak, alias("__analogReadMilliVolts"))); extern void analogReadResolution(uint8_t bits) __attribute__ ((weak, alias("__analogReadResolution"))); -extern void analogSetClockDiv(uint8_t clockDiv) __attribute__ ((weak, alias("__analogSetClockDiv"))); extern void analogSetAttenuation(adc_attenuation_t attenuation) __attribute__ ((weak, alias("__analogSetAttenuation"))); extern void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation) __attribute__ ((weak, alias("__analogSetPinAttenuation"))); -extern bool adcAttachPin(uint8_t pin) __attribute__ ((weak, alias("__adcAttachPin"))); - #if CONFIG_IDF_TARGET_ESP32 -extern void analogSetVRefPin(uint8_t pin) __attribute__ ((weak, alias("__analogSetVRefPin"))); extern void analogSetWidth(uint8_t bits) __attribute__ ((weak, alias("__analogSetWidth"))); #endif + +#endif diff --git a/cores/esp32/esp32-hal-adc.h b/cores/esp32/esp32-hal-adc.h index c226384a422..f25e1abce41 100644 --- a/cores/esp32/esp32-hal-adc.h +++ b/cores/esp32/esp32-hal-adc.h @@ -17,8 +17,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef MAIN_ESP32_HAL_ADC_H_ -#define MAIN_ESP32_HAL_ADC_H_ +#pragma once + +#include "soc/soc_caps.h" +#if SOC_ADC_SUPPORTED #ifdef __cplusplus extern "C" { @@ -53,13 +55,6 @@ uint32_t analogReadMilliVolts(uint8_t pin); */ void analogReadResolution(uint8_t bits); -/* - * Set the divider for the ADC clock. - * Default is 1 - * Range is 1 - 255 - * */ -void analogSetClockDiv(uint8_t clockDiv); - /* * Set the attenuation for all channels * Default is 11db @@ -72,11 +67,6 @@ void analogSetAttenuation(adc_attenuation_t attenuation); * */ void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation); -/* - * Attach pin to ADC (will also clear any other analog mode that could be on) - * */ -bool adcAttachPin(uint8_t pin); - #if CONFIG_IDF_TARGET_ESP32 /* * Sets the sample bits and read resolution @@ -85,15 +75,10 @@ bool adcAttachPin(uint8_t pin); * */ void analogSetWidth(uint8_t bits); -/* - * Set pin to use for ADC calibration if the esp is not already calibrated (25, 26 or 27) - * */ -void analogSetVRefPin(uint8_t pin); - #endif #ifdef __cplusplus } #endif -#endif /* MAIN_ESP32_HAL_ADC_H_ */ +#endif /* SOC_ADC_SUPPORTED */ From 254c10e093d9b370c3301cf0d9f75d96f7bf8e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Procha=CC=81zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:41:17 +0100 Subject: [PATCH 2/6] switched to working solution for milivolts read --- cores/esp32/esp32-hal-adc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cores/esp32/esp32-hal-adc.c b/cores/esp32/esp32-hal-adc.c index b1d279895b6..95ef01f7b62 100644 --- a/cores/esp32/esp32-hal-adc.c +++ b/cores/esp32/esp32-hal-adc.c @@ -323,13 +323,13 @@ uint32_t __analogReadMilliVolts(uint8_t pin){ return value; } } - + /* err = adc_oneshot_get_calibrated_result((adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT), adc_cali_handle[adc_unit], channel, &value); if(err != ESP_OK){ log_e("adc_oneshot_get_calibrated_result failed!"); return 0; } - /* + */ err = adc_oneshot_read((adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT), channel, &raw_value); if(err != ESP_OK){ log_e("adc_oneshot_read failed!"); @@ -340,7 +340,7 @@ uint32_t __analogReadMilliVolts(uint8_t pin){ log_e("adc_cali_raw_to_voltage failed!"); return 0; } - */ + return value; } From 174903e6b7d33e067a0248d48d05005bec6d84a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Procha=CC=81zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:03:02 +0100 Subject: [PATCH 3/6] Periman detachbus fix --- cores/esp32/esp32-hal-adc.c | 66 ++++++++++--------------------------- 1 file changed, 17 insertions(+), 49 deletions(-) diff --git a/cores/esp32/esp32-hal-adc.c b/cores/esp32/esp32-hal-adc.c index 95ef01f7b62..38bb886ef21 100644 --- a/cores/esp32/esp32-hal-adc.c +++ b/cores/esp32/esp32-hal-adc.c @@ -27,18 +27,13 @@ static uint8_t __analogReturnedWidth = SOC_ADC_RTC_MAX_BITWIDTH; adc_oneshot_unit_handle_t adc_handle[SOC_ADC_PERIPH_NUM]; adc_cali_handle_t adc_cali_handle[SOC_ADC_PERIPH_NUM]; -static bool adcDetachBus(void * bus){ - +static bool adcDetachBus(void * pin){ + adc_channel_t adc_channel; + adc_unit_t adc_unit; + esp_err_t err = ESP_OK; uint8_t used_channels = 0; - adc_unit_t adc_unit = 0; - - for(int i = 0; i < SOC_ADC_PERIPH_NUM; i++){ - if(adc_handle[i] == bus){ - adc_unit = i; - break; - } - } + adc_oneshot_io_to_channel((int)(pin-1), &adc_unit, &adc_channel); for (uint8_t channel = 0; channel < SOC_ADC_CHANNEL_NUM(adc_unit); channel++){ int io_pin; adc_oneshot_channel_to_io(adc_unit, channel, &io_pin); @@ -48,7 +43,7 @@ static bool adcDetachBus(void * bus){ } if(used_channels == 1) {//only 1 channel is used - esp_err_t err = adc_oneshot_del_unit((adc_oneshot_unit_handle_t)bus); + esp_err_t err = adc_oneshot_del_unit(adc_handle[adc_unit]); if(err != ESP_OK){ return false; } @@ -58,7 +53,6 @@ static bool adcDetachBus(void * bus){ } esp_err_t __analogChannelConfig(adc_bitwidth_t width, adc_attenuation_t atten, int8_t pin){ - esp_err_t err = ESP_OK; adc_oneshot_chan_cfg_t config = { .bitwidth = width, @@ -198,8 +192,8 @@ esp_err_t __analogInit(uint8_t pin, adc_channel_t channel, adc_unit_t adc_unit){ } } - if(!perimanSetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT, (void *)adc_handle[adc_unit])){ - adcDetachBus((void *)adc_handle[adc_unit]); + if(!perimanSetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT, (void *)(pin+1))){ + adcDetachBus((void *)(pin+1)); return err; } @@ -209,14 +203,11 @@ esp_err_t __analogInit(uint8_t pin, adc_channel_t channel, adc_unit_t adc_unit){ }; err = adc_oneshot_config_channel(adc_handle[adc_unit], channel, &config); - if(err != ESP_OK){ log_e("adc_oneshot_config_channel failed with error: %d", err); return err; } - perimanSetBusDeinit(ESP32_BUS_TYPE_ADC_ONESHOT, adcDetachBus); - return ESP_OK; } @@ -247,17 +238,15 @@ uint16_t __analogRead(uint8_t pin) adc_unit_t adc_unit; esp_err_t err = ESP_OK; - adc_oneshot_io_to_channel(pin, &adc_unit, &channel); + err = adc_oneshot_io_to_channel(pin, &adc_unit, &channel); if(err != ESP_OK){ log_e("Pin %u is not ADC pin!", pin); return value; } - //log_d("adc_unit = %d adc_channel = %d",adc_unit,channel); - - adc_oneshot_unit_handle_t bus = (adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT); - if(bus == NULL){ - //log_d("No BUS - calling __analogInit()"); + if(perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT) == NULL) + { + log_d("Calling __analogInit! pin = %d", pin); err = __analogInit(pin, channel, adc_unit); if(err != ESP_OK){ log_e("Analog initialization failed!"); @@ -265,13 +254,10 @@ uint16_t __analogRead(uint8_t pin) } } - - adc_oneshot_read((adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT), channel, &value); + adc_oneshot_read(adc_handle[adc_unit], channel, &value); return mapResolution(value); - } - uint32_t __analogReadMilliVolts(uint8_t pin){ int value = 0; @@ -286,13 +272,8 @@ uint32_t __analogReadMilliVolts(uint8_t pin){ return value; } - //log_d("adc_unit = %d adc_channel = %d",adc_unit,channel); - - adc_oneshot_unit_handle_t bus = (adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT); - if(bus == NULL){ - - //log_d("No BUS - calling __analogInit()"); - + if(perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT) == NULL) + { err = __analogInit(pin, channel, adc_unit); if(err != ESP_OK){ log_e("Analog initialization failed!"); @@ -323,26 +304,13 @@ uint32_t __analogReadMilliVolts(uint8_t pin){ return value; } } - /* - err = adc_oneshot_get_calibrated_result((adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT), adc_cali_handle[adc_unit], channel, &value); + + err = adc_oneshot_get_calibrated_result(adc_handle[adc_unit], adc_cali_handle[adc_unit], channel, &value); if(err != ESP_OK){ log_e("adc_oneshot_get_calibrated_result failed!"); return 0; } - */ - err = adc_oneshot_read((adc_oneshot_unit_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT), channel, &raw_value); - if(err != ESP_OK){ - log_e("adc_oneshot_read failed!"); - return value; - } - adc_cali_raw_to_voltage(adc_cali_handle[adc_unit], raw_value, &value); - if(err != ESP_OK){ - log_e("adc_cali_raw_to_voltage failed!"); - return 0; - } - return value; - } extern uint16_t analogRead(uint8_t pin) __attribute__ ((weak, alias("__analogRead"))); From 9cd5a78b6ab8fc1d9fdb0211cf843a4e0cadaac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Procha=CC=81zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:05:14 +0100 Subject: [PATCH 4/6] coding style --- cores/esp32/esp32-hal-adc.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/cores/esp32/esp32-hal-adc.c b/cores/esp32/esp32-hal-adc.c index 38bb886ef21..4abefa9b807 100644 --- a/cores/esp32/esp32-hal-adc.c +++ b/cores/esp32/esp32-hal-adc.c @@ -42,7 +42,7 @@ static bool adcDetachBus(void * pin){ } } - if(used_channels == 1) {//only 1 channel is used + if(used_channels == 1){ //only 1 channel is used esp_err_t err = adc_oneshot_del_unit(adc_handle[adc_unit]); if(err != ESP_OK){ return false; @@ -142,8 +142,7 @@ esp_err_t __analogChannelConfig(adc_bitwidth_t width, adc_attenuation_t atten, i return ESP_OK; } -static inline uint16_t mapResolution(uint16_t value) -{ +static inline uint16_t mapResolution(uint16_t value){ uint8_t from = __analogWidth; if (from == __analogReturnedWidth){ return value; @@ -154,16 +153,14 @@ static inline uint16_t mapResolution(uint16_t value) return value << (__analogReturnedWidth - from); } -void __analogSetAttenuation(adc_attenuation_t attenuation) -{ +void __analogSetAttenuation(adc_attenuation_t attenuation){ if(__analogChannelConfig(__analogWidth, attenuation, -1) != ESP_OK){ log_e("__analogChannelConfig failed!"); } } #if CONFIG_IDF_TARGET_ESP32 -void __analogSetWidth(uint8_t bits) -{ +void __analogSetWidth(uint8_t bits){ if(bits < SOC_ADC_RTC_MIN_BITWIDTH){ bits = SOC_ADC_RTC_MIN_BITWIDTH; } @@ -177,7 +174,6 @@ void __analogSetWidth(uint8_t bits) #endif esp_err_t __analogInit(uint8_t pin, adc_channel_t channel, adc_unit_t adc_unit){ - esp_err_t err = ESP_OK; if(adc_handle[adc_unit] == NULL) { adc_oneshot_unit_init_cfg_t init_config1 = { @@ -211,16 +207,14 @@ esp_err_t __analogInit(uint8_t pin, adc_channel_t channel, adc_unit_t adc_unit){ return ESP_OK; } -void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation) -{ +void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation){ if(__analogChannelConfig(__analogWidth, attenuation, pin) != ESP_OK) { log_e("__analogChannelConfig failed!"); } } -void __analogReadResolution(uint8_t bits) -{ +void __analogReadResolution(uint8_t bits){ if(!bits || bits > 16){ return; } @@ -231,8 +225,7 @@ void __analogReadResolution(uint8_t bits) #endif } -uint16_t __analogRead(uint8_t pin) -{ +uint16_t __analogRead(uint8_t pin){ int value = 0; adc_channel_t channel; adc_unit_t adc_unit; @@ -244,8 +237,7 @@ uint16_t __analogRead(uint8_t pin) return value; } - if(perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT) == NULL) - { + if(perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT) == NULL){ log_d("Calling __analogInit! pin = %d", pin); err = __analogInit(pin, channel, adc_unit); if(err != ESP_OK){ @@ -259,7 +251,6 @@ uint16_t __analogRead(uint8_t pin) } uint32_t __analogReadMilliVolts(uint8_t pin){ - int value = 0; int raw_value = 0; adc_channel_t channel; @@ -272,8 +263,7 @@ uint32_t __analogReadMilliVolts(uint8_t pin){ return value; } - if(perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT) == NULL) - { + if(perimanGetPinBus(pin, ESP32_BUS_TYPE_ADC_ONESHOT) == NULL){ err = __analogInit(pin, channel, adc_unit); if(err != ESP_OK){ log_e("Analog initialization failed!"); @@ -281,8 +271,7 @@ uint32_t __analogReadMilliVolts(uint8_t pin){ } } - if(adc_cali_handle[adc_unit] == NULL) - { + if(adc_cali_handle[adc_unit] == NULL){ log_d("Creating cali handle for ADC_%d", adc_unit); #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED adc_cali_curve_fitting_config_t cali_config = { From f9cbbdd8b80e3651d9e36748e679b32a3e7f6158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Procha=CC=81zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:10:11 +0100 Subject: [PATCH 5/6] fix CI warnings --- cores/esp32/esp32-hal-adc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cores/esp32/esp32-hal-adc.c b/cores/esp32/esp32-hal-adc.c index 4abefa9b807..dc3c1815535 100644 --- a/cores/esp32/esp32-hal-adc.c +++ b/cores/esp32/esp32-hal-adc.c @@ -30,7 +30,6 @@ adc_cali_handle_t adc_cali_handle[SOC_ADC_PERIPH_NUM]; static bool adcDetachBus(void * pin){ adc_channel_t adc_channel; adc_unit_t adc_unit; - esp_err_t err = ESP_OK; uint8_t used_channels = 0; adc_oneshot_io_to_channel((int)(pin-1), &adc_unit, &adc_channel); @@ -92,7 +91,7 @@ esp_err_t __analogChannelConfig(adc_bitwidth_t width, adc_attenuation_t atten, i log_e("adc_cali_create_scheme_curve_fitting failed with error: %d", err); return err; } - #else if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED + #else //ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED log_d("Deleting ADC_UNIT_%d line cali handle",adc_unit); err = adc_cali_delete_scheme_line_fitting(adc_cali_handle[adc_unit]); if(err != ESP_OK){ @@ -252,7 +251,6 @@ uint16_t __analogRead(uint8_t pin){ uint32_t __analogReadMilliVolts(uint8_t pin){ int value = 0; - int raw_value = 0; adc_channel_t channel; adc_unit_t adc_unit; esp_err_t err = ESP_OK; @@ -280,7 +278,7 @@ uint32_t __analogReadMilliVolts(uint8_t pin){ .bitwidth = __analogWidth, }; err = adc_cali_create_scheme_curve_fitting(&cali_config, &adc_cali_handle[adc_unit]); - #else if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED + #else //ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED adc_cali_line_fitting_config_t cali_config = { .unit_id = adc_unit, .bitwidth = __analogWidth, From 08eb54f85dd6757a5a2e98eba5759d25dfcc01c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Procha=CC=81zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:35:05 +0100 Subject: [PATCH 6/6] fix FreeRTOS example --- .../FreeRTOS/BasicMultiThreading/BasicMultiThreading.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/BasicMultiThreading.ino b/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/BasicMultiThreading.ino index 745d5b6a46c..2cfe185a20c 100644 --- a/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/BasicMultiThreading.ino +++ b/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading/BasicMultiThreading.ino @@ -92,7 +92,7 @@ void TaskBlink(void *pvParameters){ // This is a task. void TaskAnalogRead(void *pvParameters){ // This is a task. (void) pvParameters; // Check if the given analog pin is usable - if not - delete this task - if(!adcAttachPin(ANALOG_INPUT_PIN)){ + if(digitalPinToAnalogChannel(ANALOG_INPUT_PIN) == -1){ Serial.printf("TaskAnalogRead cannot work because the given pin %d cannot be used for ADC - the task will delete itself.\n", ANALOG_INPUT_PIN); analog_read_task_handle = NULL; // Prevent calling vTaskDelete on non-existing task vTaskDelete(NULL); // Delete this task