diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 51ea19c312..22dce0b6b5 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -25,7 +25,7 @@ endif() if(CONFIG_SOC_ADC_SUPPORTED) list(APPEND srcs - "adc_common.c" + "adc_single.c" "adc.c") endif() diff --git a/components/driver/adc.c b/components/driver/adc.c index dd1c377116..850089dc2f 100644 --- a/components/driver/adc.c +++ b/components/driver/adc.c @@ -102,7 +102,7 @@ extern esp_pm_lock_handle_t adc_digi_arbiter_lock; #endif //CONFIG_PM_ENABLE #if SOC_ADC_CALIBRATION_V1_SUPPORTED -uint32_t adc_get_calibration_offset(adc_unit_t adc_n, adc_channel_t chan, adc_atten_t atten); +uint32_t adc_get_calibration_offset(adc_unit_t adc_n, adc_atten_t atten); #endif /*--------------------------------------------------------------- @@ -385,11 +385,11 @@ esp_err_t adc_digi_start(void) #if SOC_ADC_CALIBRATION_V1_SUPPORTED if (s_adc_digi_ctx->use_adc1) { - uint32_t cal_val = adc_get_calibration_offset(ADC_UNIT_1, ADC_CHANNEL_MAX, s_adc_digi_ctx->adc1_atten); + uint32_t cal_val = adc_get_calibration_offset(ADC_UNIT_1, s_adc_digi_ctx->adc1_atten); adc_hal_set_calibration_param(ADC_UNIT_1, cal_val); } if (s_adc_digi_ctx->use_adc2) { - uint32_t cal_val = adc_get_calibration_offset(ADC_UNIT_2, ADC_CHANNEL_MAX, s_adc_digi_ctx->adc2_atten); + uint32_t cal_val = adc_get_calibration_offset(ADC_UNIT_2, s_adc_digi_ctx->adc2_atten); adc_hal_set_calibration_param(ADC_UNIT_2, cal_val); } #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED @@ -679,7 +679,7 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit) esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten) { ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_1), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC1 channel error"); - ESP_RETURN_ON_FALSE((atten < ADC_ATTEN_MAX), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC Atten Err"); + ESP_RETURN_ON_FALSE((atten < SOC_ADC_ATTEN_NUM), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC Atten Err"); esp_err_t ret = ESP_OK; s_atten1_single[channel] = atten; @@ -700,11 +700,11 @@ int adc1_get_raw(adc1_channel_t channel) SAR_ADC1_LOCK_ACQUIRE(); adc_atten_t atten = s_atten1_single[channel]; - uint32_t cal_val = adc_get_calibration_offset(ADC_UNIT_1, channel, atten); + uint32_t cal_val = adc_get_calibration_offset(ADC_UNIT_1, atten); adc_hal_set_calibration_param(ADC_UNIT_1, cal_val); ADC_REG_LOCK_ENTER(); - adc_hal_set_atten(ADC_UNIT_2, channel, atten); + adc_oneshot_ll_set_atten(ADC_UNIT_2, channel, atten); adc_hal_convert(ADC_UNIT_1, channel, &raw_out); ADC_REG_LOCK_EXIT(); @@ -748,11 +748,11 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * adc_hal_arbiter_config(&config); adc_atten_t atten = s_atten2_single[channel]; - uint32_t cal_val = adc_get_calibration_offset(ADC_UNIT_2, channel, atten); + uint32_t cal_val = adc_get_calibration_offset(ADC_UNIT_2, atten); adc_hal_set_calibration_param(ADC_UNIT_2, cal_val); ADC_REG_LOCK_ENTER(); - adc_hal_set_atten(ADC_UNIT_2, channel, atten); + adc_oneshot_ll_set_atten(ADC_UNIT_2, channel, atten); ret = adc_hal_convert(ADC_UNIT_2, channel, raw_out); ADC_REG_LOCK_EXIT(); @@ -837,13 +837,13 @@ static inline uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t a } #endif -static uint16_t s_adc_cali_param[SOC_ADC_PERIPH_NUM][ADC_ATTEN_MAX] = {}; +static uint16_t s_adc_cali_param[SOC_ADC_PERIPH_NUM][SOC_ADC_ATTEN_NUM] = {}; //NOTE: according to calibration version, different types of lock may be taken during the process: // 1. Semaphore when reading efuse // 2. Lock (Spinlock, or Mutex) if we actually do ADC calibration in the future //This function shoudn't be called inside critical section or ISR -uint32_t adc_get_calibration_offset(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) +uint32_t adc_get_calibration_offset(adc_unit_t adc_n, adc_atten_t atten) { if (s_adc_cali_param[adc_n][atten]) { ESP_LOGV(ADC_TAG, "Use calibrated val ADC%d atten=%d: %04X", adc_n, atten, s_adc_cali_param[adc_n][atten]); @@ -863,7 +863,7 @@ uint32_t adc_get_calibration_offset(adc_unit_t adc_n, adc_channel_t channel, adc adc_power_acquire(); ADC_ENTER_CRITICAL(); const bool internal_gnd = true; - init_code = adc_hal_self_calibration(adc_n, channel, atten, internal_gnd); + init_code = adc_hal_self_calibration(adc_n, atten, internal_gnd); ADC_EXIT_CRITICAL(); adc_power_release(); } @@ -875,10 +875,10 @@ uint32_t adc_get_calibration_offset(adc_unit_t adc_n, adc_channel_t channel, adc } // Internal function to calibrate PWDET for WiFi -esp_err_t adc_cal_offset(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) +esp_err_t adc_cal_offset(adc_unit_t adc_n, adc_atten_t atten) { adc_hal_calibration_init(adc_n); - uint32_t cal_val = adc_get_calibration_offset(adc_n, channel, atten); + uint32_t cal_val = adc_get_calibration_offset(adc_n, atten); ADC_ENTER_CRITICAL(); adc_hal_set_calibration_param(adc_n, cal_val); ADC_EXIT_CRITICAL(); diff --git a/components/driver/adc_deprecated.c b/components/driver/adc_deprecated.c index 8cf2247a5c..3f27a0c1ba 100644 --- a/components/driver/adc_deprecated.c +++ b/components/driver/adc_deprecated.c @@ -591,12 +591,12 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config) if (config->conv_mode & ADC_CONV_SINGLE_UNIT_1) { for (int i = 0; i < config->adc1_pattern_len; i++) { - adc_cal_offset(ADC_UNIT_1, config->adc1_pattern[i].channel, config->adc1_pattern[i].atten); + adc_cal_offset(ADC_UNIT_1, config->adc1_pattern[i].atten); } } if (config->conv_mode & ADC_CONV_SINGLE_UNIT_2) { for (int i = 0; i < config->adc2_pattern_len; i++) { - adc_cal_offset(ADC_UNIT_2, config->adc2_pattern[i].channel, config->adc2_pattern[i].atten); + adc_cal_offset(ADC_UNIT_2, config->adc2_pattern[i].atten); } } diff --git a/components/driver/adc_common.c b/components/driver/adc_single.c similarity index 86% rename from components/driver/adc_common.c rename to components/driver/adc_single.c index 7e2cd4d297..9673dc2758 100644 --- a/components/driver/adc_common.c +++ b/components/driver/adc_single.c @@ -228,9 +228,9 @@ esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num) static uint32_t get_calibration_offset(adc_unit_t adc_n, adc_channel_t chan) { adc_atten_t atten = adc_ll_get_atten(adc_n, chan); - extern uint32_t adc_get_calibration_offset(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten); + extern uint32_t adc_get_calibration_offset(adc_unit_t adc_n, adc_atten_t atten); - return adc_get_calibration_offset(adc_n, chan, atten); + return adc_get_calibration_offset(adc_n, atten); } #endif //SOC_ADC_CALIBRATION_V1_SUPPORTED @@ -250,7 +250,7 @@ static void adc_rtc_chan_init(adc_unit_t adc_unit) #if SOC_DAC_SUPPORTED dac_hal_rtc_sync_by_adc(false); #endif - adc_hal_rtc_output_invert(ADC_UNIT_1, ADC_HAL_DATA_INVERT_DEFAULT(ADC_UNIT_1)); + adc_oneshot_ll_output_invert(ADC_UNIT_1, ADC_HAL_DATA_INVERT_DEFAULT(ADC_UNIT_1)); adc_ll_set_sar_clk_div(ADC_UNIT_1, ADC_HAL_SAR_CLK_DIV_DEFAULT(ADC_UNIT_1)); #ifdef CONFIG_IDF_TARGET_ESP32 adc_ll_hall_disable(); //Disable other peripherals. @@ -259,7 +259,7 @@ static void adc_rtc_chan_init(adc_unit_t adc_unit) } if (adc_unit == ADC_UNIT_2) { adc_hal_pwdet_set_cct(ADC_HAL_PWDET_CCT_DEFAULT); - adc_hal_rtc_output_invert(ADC_UNIT_2, ADC_HAL_DATA_INVERT_DEFAULT(ADC_UNIT_2)); + adc_oneshot_ll_output_invert(ADC_UNIT_2, ADC_HAL_DATA_INVERT_DEFAULT(ADC_UNIT_2)); adc_ll_set_sar_clk_div(ADC_UNIT_2, ADC_HAL_SAR_CLK_DIV_DEFAULT(ADC_UNIT_2)); } } @@ -297,12 +297,12 @@ esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en) { if (adc_unit == ADC_UNIT_1) { SARADC1_ENTER(); - adc_hal_rtc_output_invert(ADC_UNIT_1, inv_en); + adc_oneshot_ll_output_invert(ADC_UNIT_1, inv_en); SARADC1_EXIT(); } if (adc_unit == ADC_UNIT_2) { SARADC2_ENTER(); - adc_hal_rtc_output_invert(ADC_UNIT_2, inv_en); + adc_oneshot_ll_output_invert(ADC_UNIT_2, inv_en); SARADC2_EXIT(); } @@ -311,20 +311,39 @@ esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en) esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit) { + ADC_CHECK(width_bit < ADC_WIDTH_MAX, "unsupported bit width", ESP_ERR_INVALID_ARG); + adc_bitwidth_t bitwidth = 0; #if CONFIG_IDF_TARGET_ESP32 - ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG); -#else - ADC_CHECK(width_bit == ADC_WIDTH_MAX - 1, "WIDTH ERR: see `adc_bits_width_t` for supported bit width", ESP_ERR_INVALID_ARG); + switch(width_bit) { + case ADC_WIDTH_BIT_9: + bitwidth = ADC_BITWIDTH_9; + break; + case ADC_WIDTH_BIT_10: + bitwidth = ADC_BITWIDTH_10; + break; + case ADC_WIDTH_BIT_11: + bitwidth = ADC_BITWIDTH_11; + break; + case ADC_WIDTH_BIT_12: + bitwidth = ADC_BITWIDTH_12; + break; + default: + abort(); + } +#elif CONFIG_IDF_TARGET_ESP32S2 + bitwidth = ADC_BITWIDTH_13; +#else //esp32s3 + bitwidth = ADC_BITWIDTH_12; #endif if (adc_unit == ADC_UNIT_1) { SARADC1_ENTER(); - adc_hal_rtc_set_output_format(ADC_UNIT_1, width_bit); + adc_oneshot_ll_set_output_bits(ADC_UNIT_1, bitwidth); SARADC1_EXIT(); } if (adc_unit == ADC_UNIT_2) { SARADC2_ENTER(); - adc_hal_rtc_set_output_format(ADC_UNIT_2, width_bit); + adc_oneshot_ll_set_output_bits(ADC_UNIT_2, bitwidth); SARADC2_EXIT(); } @@ -353,12 +372,12 @@ esp_err_t adc_rtc_reset(void) esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten) { ADC_CHANNEL_CHECK(ADC_UNIT_1, channel); - ADC_CHECK(atten < ADC_ATTEN_MAX, "ADC Atten Err", ESP_ERR_INVALID_ARG); + ADC_CHECK(atten < SOC_ADC_ATTEN_NUM, "ADC Atten Err", ESP_ERR_INVALID_ARG); adc_common_gpio_init(ADC_UNIT_1, channel); SARADC1_ENTER(); adc_rtc_chan_init(ADC_UNIT_1); - adc_hal_set_atten(ADC_UNIT_1, channel, atten); + adc_oneshot_ll_set_atten(ADC_UNIT_1, channel, atten); SARADC1_EXIT(); #if SOC_ADC_CALIBRATION_V1_SUPPORTED @@ -370,14 +389,33 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten) esp_err_t adc1_config_width(adc_bits_width_t width_bit) { + ADC_CHECK(width_bit < ADC_WIDTH_MAX, "unsupported bit width", ESP_ERR_INVALID_ARG); + adc_bitwidth_t bitwidth = 0; #if CONFIG_IDF_TARGET_ESP32 - ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG); -#else - ADC_CHECK(width_bit == ADC_WIDTH_MAX - 1, "WIDTH ERR: see `adc_bits_width_t` for supported bit width", ESP_ERR_INVALID_ARG); + switch(width_bit) { + case ADC_WIDTH_BIT_9: + bitwidth = ADC_BITWIDTH_9; + break; + case ADC_WIDTH_BIT_10: + bitwidth = ADC_BITWIDTH_10; + break; + case ADC_WIDTH_BIT_11: + bitwidth = ADC_BITWIDTH_11; + break; + case ADC_WIDTH_BIT_12: + bitwidth = ADC_BITWIDTH_12; + break; + default: + abort(); + } +#elif CONFIG_IDF_TARGET_ESP32S2 + bitwidth = ADC_BITWIDTH_13; +#else //esp32s3 + bitwidth = ADC_BITWIDTH_12; #endif SARADC1_ENTER(); - adc_hal_rtc_set_output_format(ADC_UNIT_1, width_bit); + adc_oneshot_ll_set_output_bits(ADC_UNIT_1, bitwidth); SARADC1_EXIT(); return ESP_OK; @@ -443,6 +481,7 @@ int adc1_get_raw(adc1_channel_t channel) adc_ll_amp_disable(); //Currently the LNA is not open, close it by default. #endif adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_RTC); //Set controller + adc_oneshot_ll_set_channel(ADC_UNIT_1, channel); adc_hal_convert(ADC_UNIT_1, channel, &adc_value); //Start conversion, For ADC1, the data always valid. #if !CONFIG_IDF_TARGET_ESP32 adc_ll_rtc_reset(); //Reset FSM of rtc controller @@ -500,7 +539,7 @@ esp_err_t adc2_wifi_release(void) esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) { ADC_CHANNEL_CHECK(ADC_UNIT_2, channel); - ADC_CHECK(atten <= ADC_ATTEN_11db, "ADC2 Atten Err", ESP_ERR_INVALID_ARG); + ADC_CHECK(atten <= SOC_ADC_ATTEN_NUM, "ADC2 Atten Err", ESP_ERR_INVALID_ARG); adc_common_gpio_init(ADC_UNIT_2, channel); @@ -512,7 +551,7 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) //avoid collision with other tasks SARADC2_ENTER(); adc_rtc_chan_init(ADC_UNIT_2); - adc_hal_set_atten(ADC_UNIT_2, channel, atten); + adc_oneshot_ll_set_atten(ADC_UNIT_2, channel, atten); SARADC2_EXIT(); SARADC2_RELEASE(); @@ -565,13 +604,32 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * { esp_err_t ret = ESP_OK; int adc_value = 0; + adc_bitwidth_t bitwidth = 0; ADC_CHECK(raw_out != NULL, "ADC out value err", ESP_ERR_INVALID_ARG); ADC_CHECK(channel < ADC2_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG); + ADC_CHECK(width_bit < ADC_WIDTH_MAX, "unsupported bit width", ESP_ERR_INVALID_ARG); #if CONFIG_IDF_TARGET_ESP32 - ADC_CHECK(width_bit < ADC_WIDTH_MAX, "WIDTH ERR: ESP32 support 9 ~ 12 bit width", ESP_ERR_INVALID_ARG); -#else - ADC_CHECK(width_bit == ADC_WIDTH_MAX - 1, "WIDTH ERR: see `adc_bits_width_t` for supported bit width", ESP_ERR_INVALID_ARG); + switch(width_bit) { + case ADC_WIDTH_BIT_9: + bitwidth = ADC_BITWIDTH_9; + break; + case ADC_WIDTH_BIT_10: + bitwidth = ADC_BITWIDTH_10; + break; + case ADC_WIDTH_BIT_11: + bitwidth = ADC_BITWIDTH_11; + break; + case ADC_WIDTH_BIT_12: + bitwidth = ADC_BITWIDTH_12; + break; + default: + abort(); + } +#elif CONFIG_IDF_TARGET_ESP32S2 + bitwidth = ADC_BITWIDTH_13; +#else //esp32s3 + bitwidth = ADC_BITWIDTH_12; #endif #if SOC_ADC_CALIBRATION_V1_SUPPORTED @@ -598,7 +656,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * #ifdef CONFIG_ADC_DISABLE_DAC adc2_dac_disable(channel); //disable other peripherals #endif - adc_hal_rtc_set_output_format(ADC_UNIT_2, width_bit); + adc_oneshot_ll_set_output_bits(ADC_UNIT_2, bitwidth); #if CONFIG_IDF_TARGET_ESP32 adc_ll_set_controller(ADC_UNIT_2, ADC_LL_CTRL_RTC);// set controller @@ -614,6 +672,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * #endif //CONFIG_PM_ENABLE #endif //CONFIG_IDF_TARGET_ESP32 + adc_oneshot_ll_set_channel(ADC_UNIT_2, channel); ret = adc_hal_convert(ADC_UNIT_2, channel, &adc_value); if (ret != ESP_OK) { adc_value = -1; diff --git a/components/driver/esp32c3/adc2_init_cal.c b/components/driver/esp32c3/adc2_init_cal.c index 7051c36593..f774d7b8bc 100644 --- a/components/driver/esp32c3/adc2_init_cal.c +++ b/components/driver/esp32c3/adc2_init_cal.c @@ -20,8 +20,7 @@ static __attribute__((constructor)) void adc2_init_code_calibration(void) { const adc_unit_t adc_n = ADC_UNIT_2; const adc_atten_t atten = ADC_ATTEN_DB_11; - const adc_channel_t channel = 0; - adc_cal_offset(adc_n, channel, atten); + adc_cal_offset(adc_n, atten); } /** Don't call `adc2_cal_include` in user code. */ diff --git a/components/driver/esp32s2/adc.c b/components/driver/esp32s2/adc.c index 4dee66d278..2cc086a203 100644 --- a/components/driver/esp32s2/adc.c +++ b/components/driver/esp32s2/adc.c @@ -64,11 +64,11 @@ esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_ ADC_ENTER_CRITICAL(); if (idx == ADC_DIGI_FILTER_IDX0) { config->adc_unit = ADC_UNIT_1; - config->channel = ADC_CHANNEL_MAX; + config->channel = SOC_ADC_CHANNEL_NUM(0); adc_ll_digi_filter_get_factor(ADC_UNIT_1, &config->mode); } else if (idx == ADC_DIGI_FILTER_IDX1) { config->adc_unit = ADC_UNIT_2; - config->channel = ADC_CHANNEL_MAX; + config->channel = SOC_ADC_CHANNEL_NUM(1); adc_ll_digi_filter_get_factor(ADC_UNIT_2, &config->mode); } ADC_EXIT_CRITICAL(); diff --git a/components/driver/esp32s2/adc2_init_cal.c b/components/driver/esp32s2/adc2_init_cal.c index 7051c36593..f774d7b8bc 100644 --- a/components/driver/esp32s2/adc2_init_cal.c +++ b/components/driver/esp32s2/adc2_init_cal.c @@ -20,8 +20,7 @@ static __attribute__((constructor)) void adc2_init_code_calibration(void) { const adc_unit_t adc_n = ADC_UNIT_2; const adc_atten_t atten = ADC_ATTEN_DB_11; - const adc_channel_t channel = 0; - adc_cal_offset(adc_n, channel, atten); + adc_cal_offset(adc_n, atten); } /** Don't call `adc2_cal_include` in user code. */ diff --git a/components/driver/include/driver/adc.h b/components/driver/include/driver/adc.h index cabbc50b88..dfbf82e3d8 100644 --- a/components/driver/include/driver/adc.h +++ b/components/driver/include/driver/adc.h @@ -93,7 +93,7 @@ typedef enum { /** * The default (max) bit width of the ADC of current version. You can also get the maximum bitwidth - * by `SOC_ADC_MAX_BITWIDTH` defined in soc_caps.h. + * by `SOC_ADC_RTC_MAX_BITWIDTH` defined in soc_caps.h. */ #define ADC_WIDTH_BIT_DEFAULT (ADC_WIDTH_MAX-1) diff --git a/components/driver/include/esp_private/adc_cali.h b/components/driver/include/esp_private/adc_cali.h index 78b78051a0..428e0f5cb4 100644 --- a/components/driver/include/esp_private/adc_cali.h +++ b/components/driver/include/esp_private/adc_cali.h @@ -20,11 +20,10 @@ extern "C" { * @brief Calibrate the offset of ADC. (Based on the pre-stored efuse or actual calibration) * * @param adc_n ADC unit to calibrate - * @param channel Target channel if really do calibration * @param atten Attenuation to use * @return Always ESP_OK */ -extern esp_err_t adc_cal_offset(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten); +extern esp_err_t adc_cal_offset(adc_unit_t adc_n, adc_atten_t atten); #endif diff --git a/components/esp_adc_cal/esp32s3/esp_adc_cal.c b/components/esp_adc_cal/esp32s3/esp_adc_cal.c index e2b748bb50..ccd39d683b 100644 --- a/components/esp_adc_cal/esp32s3/esp_adc_cal.c +++ b/components/esp_adc_cal/esp32s3/esp_adc_cal.c @@ -134,7 +134,7 @@ esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, // Check parameters ESP_RETURN_ON_FALSE(adc_num == ADC_UNIT_1 || adc_num == ADC_UNIT_2, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Invalid unit num"); ESP_RETURN_ON_FALSE(chars != NULL, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Ivalid characteristic"); - ESP_RETURN_ON_FALSE(atten < ADC_ATTEN_MAX, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Invalid attenuation"); + ESP_RETURN_ON_FALSE(atten < SOC_ADC_ATTEN_NUM, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "Invalid attenuation"); int version_num = esp_efuse_rtc_calib_get_ver(); ESP_RETURN_ON_FALSE(version_num == 1, ESP_ADC_CAL_VAL_NOT_SUPPORTED, LOG_TAG, "No calibration efuse burnt"); diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 7f0980792b..903952646a 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -46,6 +46,7 @@ if(NOT BOOTLOADER_BUILD) "soc_hal.c" "interrupt_controller_hal.c" "sha_hal.c" + "adc_hal_common.c" "adc_hal.c") if(CONFIG_SOC_SYSTIMER_SUPPORTED) diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 00a8612f12..9af9079a76 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -33,11 +33,6 @@ * For chips without RTC controller, Digital controller is used to trigger an ADC single read. */ #include "esp_rom_sys.h" - -typedef enum { - ADC_EVENT_ADC1_DONE = BIT(0), - ADC_EVENT_ADC2_DONE = BIT(1), -} adc_hal_event_t; #endif //SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED /*--------------------------------------------------------------- @@ -107,13 +102,6 @@ typedef enum { #endif -#if SOC_ADC_ARBITER_SUPPORTED -void adc_hal_arbiter_config(adc_arbiter_t *config) -{ - adc_ll_set_arbiter_work_mode(config->mode); - adc_ll_set_arbiter_priority(config->rtc_pri, config->dig_pri, config->pwdet_pri); -} -#endif // #if SOC_ADC_ARBITER_SUPPORTED void adc_hal_dma_ctx_config(adc_hal_dma_ctx_t *hal, const adc_hal_dma_config_t *config) { @@ -144,10 +132,8 @@ void adc_hal_digi_init(adc_hal_dma_ctx_t *hal) i2s_ll_rx_force_enable_fifo_mod(hal->dev, 1); i2s_ll_enable_builtin_adc(hal->dev, 1); #endif -#if CONFIG_IDF_TARGET_ESP32C3 - adc_ll_onetime_sample_enable(ADC_UNIT_1, false); - adc_ll_onetime_sample_enable(ADC_UNIT_2, false); -#endif + + adc_oneshot_ll_disable_all_unit(); } void adc_hal_digi_deinit(adc_hal_dma_ctx_t *hal) @@ -160,57 +146,6 @@ void adc_hal_digi_deinit(adc_hal_dma_ctx_t *hal) adc_ll_digi_controller_clk_disable(); } -/*--------------------------------------------------------------- - Controller Setting ----------------------------------------------------------------*/ -static adc_ll_controller_t get_controller(adc_unit_t unit, adc_hal_work_mode_t work_mode) -{ - if (unit == ADC_UNIT_1) { - switch (work_mode) { -#if SOC_ULP_SUPPORTED - case ADC_HAL_ULP_MODE: - return ADC_LL_CTRL_ULP; -#endif - case ADC_HAL_SINGLE_READ_MODE: -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - return ADC_LL_CTRL_DIG; -#elif SOC_ADC_RTC_CTRL_SUPPORTED - return ADC_LL_CTRL_RTC; -#endif - case ADC_HAL_CONTINUOUS_READ_MODE: - return ADC_LL_CTRL_DIG; - default: - abort(); - } - } else { - switch (work_mode) { -#if SOC_ULP_SUPPORTED - case ADC_HAL_ULP_MODE: - return ADC_LL_CTRL_ULP; -#endif -#if !SOC_ADC_ARBITER_SUPPORTED //No ADC2 arbiter on ESP32 - case ADC_HAL_SINGLE_READ_MODE: - return ADC_LL_CTRL_RTC; - case ADC_HAL_CONTINUOUS_READ_MODE: - return ADC_LL_CTRL_DIG; - case ADC_HAL_PWDET_MODE: - return ADC_LL_CTRL_PWDET; - default: - abort(); -#else - default: - return ADC_LL_CTRL_ARB; -#endif - } - } -} - -void adc_hal_set_controller(adc_unit_t unit, adc_hal_work_mode_t work_mode) -{ - adc_ll_controller_t ctrlr = get_controller(unit, work_mode); - adc_ll_set_controller(unit, ctrlr); -} - /*--------------------------------------------------------------- DMA read ---------------------------------------------------------------*/ @@ -400,7 +335,7 @@ void adc_hal_digi_stop(adc_hal_dma_ctx_t *hal) adc_ll_digi_dma_disable(); } -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED + /*--------------------------------------------------------------- Single Read ---------------------------------------------------------------*/ @@ -408,33 +343,11 @@ void adc_hal_digi_stop(adc_hal_dma_ctx_t *hal) * For chips without RTC controller, Digital controller is used to trigger an ADC single read. */ -//--------------------INTR-------------------------------// -static adc_ll_intr_t get_event_intr(adc_hal_event_t event) -{ - adc_ll_intr_t intr_mask = 0; - if (event & ADC_EVENT_ADC1_DONE) { - intr_mask |= ADC_LL_INTR_ADC1_DONE; - } - if (event & ADC_EVENT_ADC2_DONE) { - intr_mask |= ADC_LL_INTR_ADC2_DONE; - } - return intr_mask; -} - -static void adc_hal_intr_clear(adc_hal_event_t event) -{ - adc_ll_intr_clear(get_event_intr(event)); -} - -static bool adc_hal_intr_get_raw(adc_hal_event_t event) -{ - return adc_ll_intr_get_raw(get_event_intr(event)); -} - - //--------------------Single Read-------------------------------// -static void adc_hal_onetime_start(void) +static void adc_hal_onetime_start(adc_unit_t adc_n) { +#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED + (void)adc_n; /** * There is a hardware limitation. If the APB clock frequency is high, the step of this reg signal: ``onetime_start`` may not be captured by the * ADC digital controller (when its clock frequency is too slow). A rough estimate for this step should be at least 3 ADC digital controller @@ -453,208 +366,35 @@ static void adc_hal_onetime_start(void) delay = 0; } - adc_ll_onetime_start(false); + adc_oneshot_ll_start(false); esp_rom_delay_us(delay); - adc_ll_onetime_start(true); + adc_oneshot_ll_start(true); //No need to delay here. Becuase if the start signal is not seen, there won't be a done intr. -} - -static esp_err_t adc_hal_single_read(adc_unit_t adc_n, int *out_raw) -{ - if (adc_n == ADC_UNIT_1) { - *out_raw = adc_ll_adc1_read(); - } else if (adc_n == ADC_UNIT_2) { - *out_raw = adc_ll_adc2_read(); - if (adc_ll_analysis_raw_data(adc_n, *out_raw)) { - return ESP_ERR_INVALID_STATE; - } - } - return ESP_OK; +#else + adc_oneshot_ll_start(adc_n); +#endif } esp_err_t adc_hal_convert(adc_unit_t adc_n, int channel, int *out_raw) { - esp_err_t ret; - adc_hal_event_t event; + uint32_t event = (adc_n == ADC_UNIT_1) ? ADC_LL_EVENT_ADC1_ONESHOT_DONE : ADC_LL_EVENT_ADC2_ONESHOT_DONE; + adc_oneshot_ll_clear_event(event); + adc_oneshot_ll_disable_all_unit(); + adc_oneshot_ll_enable(adc_n); + adc_oneshot_ll_set_channel(adc_n, channel); - if (adc_n == ADC_UNIT_1) { - event = ADC_EVENT_ADC1_DONE; - } else { - event = ADC_EVENT_ADC2_DONE; + adc_hal_onetime_start(adc_n); + while (adc_oneshot_ll_get_event(event) != true) { + ; } - - adc_hal_intr_clear(event); - adc_ll_onetime_sample_enable(ADC_UNIT_1, false); - adc_ll_onetime_sample_enable(ADC_UNIT_2, false); - adc_ll_onetime_sample_enable(adc_n, true); - adc_ll_onetime_set_channel(adc_n, channel); - - //Trigger single read. - adc_hal_onetime_start(); - while (!adc_hal_intr_get_raw(event)); - ret = adc_hal_single_read(adc_n, out_raw); - //HW workaround: when enabling periph clock, this should be false - adc_ll_onetime_sample_enable(adc_n, false); - - return ret; -} - -#else // #if SOC_ADC_RTC_CTRL_SUPPORTED -esp_err_t adc_hal_convert(adc_unit_t adc_n, int channel, int *out_raw) -{ - adc_ll_rtc_enable_channel(adc_n, channel); - adc_ll_rtc_start_convert(adc_n, channel); - while (adc_ll_rtc_convert_is_done(adc_n) != true); - *out_raw = adc_ll_rtc_get_convert_value(adc_n); - - if ((int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*out_raw))) { + *out_raw = adc_oneshot_ll_get_raw_result(adc_n); + if (adc_oneshot_ll_raw_check_valid(adc_n, *out_raw) == false) { return ESP_ERR_INVALID_STATE; } + //HW workaround: when enabling periph clock, this should be false + adc_oneshot_ll_disable_all_unit(); + return ESP_OK; } -#endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - - -/*--------------------------------------------------------------- - ADC calibration setting ----------------------------------------------------------------*/ -#if SOC_ADC_CALIBRATION_V1_SUPPORTED -void adc_hal_calibration_init(adc_unit_t adc_n) -{ - adc_ll_calibration_init(adc_n); -} - -static uint32_t s_previous_init_code[SOC_ADC_PERIPH_NUM] = {-1, -1}; - -void adc_hal_set_calibration_param(adc_unit_t adc_n, uint32_t param) -{ - if (param != s_previous_init_code[adc_n]) { - adc_ll_set_calibration_param(adc_n, param); - s_previous_init_code[adc_n] = param; - } -} - -#if SOC_ADC_RTC_CTRL_SUPPORTED -static void cal_setup(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd) -{ - adc_hal_set_controller(adc_n, ADC_HAL_SINGLE_READ_MODE); //Set controller - - /* Enable/disable internal connect GND (for calibration). */ - if (internal_gnd) { - adc_ll_rtc_disable_channel(adc_n); - adc_ll_set_atten(adc_n, 0, atten); // Note: when disable all channel, HW auto select channel0 atten param. - } else { - adc_ll_rtc_enable_channel(adc_n, channel); - adc_ll_set_atten(adc_n, channel, atten); - } -} - -static uint32_t read_cal_channel(adc_unit_t adc_n, int channel) -{ - adc_ll_rtc_start_convert(adc_n, channel); - while (adc_ll_rtc_convert_is_done(adc_n) != true); - return (uint32_t)adc_ll_rtc_get_convert_value(adc_n); -} - -//For those RTC controller not supported chips, they use digital controller to do the single read. e.g.: esp32c3 -#elif SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED -static void cal_setup(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd) -{ - adc_ll_onetime_sample_enable(ADC_UNIT_1, false); - adc_ll_onetime_sample_enable(ADC_UNIT_2, false); - /* Enable/disable internal connect GND (for calibration). */ - if (internal_gnd) { - const int esp32c3_invalid_chan = (adc_n == ADC_UNIT_1)? 0xF: 0x1; - adc_ll_onetime_set_channel(adc_n, esp32c3_invalid_chan); - } else { - adc_ll_onetime_set_channel(adc_n, channel); - } - adc_ll_onetime_set_atten(atten); - adc_ll_onetime_sample_enable(adc_n, true); -} - -static uint32_t read_cal_channel(adc_unit_t adc_n, int channel) -{ - adc_ll_intr_clear(ADC_LL_INTR_ADC1_DONE | ADC_LL_INTR_ADC2_DONE); - adc_ll_onetime_start(false); - esp_rom_delay_us(5); - adc_ll_onetime_start(true); - - while(!adc_ll_intr_get_raw(ADC_LL_INTR_ADC1_DONE | ADC_LL_INTR_ADC2_DONE)); - - uint32_t read_val = -1; - if (adc_n == ADC_UNIT_1) { - read_val = adc_ll_adc1_read(); - } else if (adc_n == ADC_UNIT_2) { - read_val = adc_ll_adc2_read(); - if (adc_ll_analysis_raw_data(adc_n, read_val)) { - return -1; - } - } - return read_val; -} -#endif //Do single read via DIGI controller or RTC controller - -#define ADC_HAL_CAL_TIMES (10) -#define ADC_HAL_CAL_OFFSET_RANGE (4096) - -uint32_t adc_hal_self_calibration(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd) -{ - if (adc_n == ADC_UNIT_2) { - adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); - adc_hal_arbiter_config(&config); - } - - cal_setup(adc_n, channel, atten, internal_gnd); - - adc_ll_calibration_prepare(adc_n, channel, internal_gnd); - - uint32_t code_list[ADC_HAL_CAL_TIMES] = {0}; - uint32_t code_sum = 0; - uint32_t code_h = 0; - uint32_t code_l = 0; - uint32_t chk_code = 0; - - for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) { - code_h = ADC_HAL_CAL_OFFSET_RANGE; - code_l = 0; - chk_code = (code_h + code_l) / 2; - adc_ll_set_calibration_param(adc_n, chk_code); - uint32_t self_cal = read_cal_channel(adc_n, channel); - while (code_h - code_l > 1) { - if (self_cal == 0) { - code_h = chk_code; - } else { - code_l = chk_code; - } - chk_code = (code_h + code_l) / 2; - adc_ll_set_calibration_param(adc_n, chk_code); - self_cal = read_cal_channel(adc_n, channel); - if ((code_h - code_l == 1)) { - chk_code += 1; - adc_ll_set_calibration_param(adc_n, chk_code); - self_cal = read_cal_channel(adc_n, channel); - } - } - code_list[rpt] = chk_code; - code_sum += chk_code; - } - - code_l = code_list[0]; - code_h = code_list[0]; - for (uint8_t i = 0 ; i < ADC_HAL_CAL_TIMES ; i++) { - code_l = MIN(code_l, code_list[i]); - code_h = MAX(code_h, code_list[i]); - } - - chk_code = code_h + code_l; - uint32_t ret = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4) - ? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) - : (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1; - - adc_ll_calibration_finish(adc_n); - return ret; -} -#endif //SOC_ADC_CALIBRATION_V1_SUPPORTED diff --git a/components/hal/adc_hal_common.c b/components/hal/adc_hal_common.c new file mode 100644 index 0000000000..f4d4053273 --- /dev/null +++ b/components/hal/adc_hal_common.c @@ -0,0 +1,199 @@ +/* + * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "soc/soc_caps.h" +#include "hal/adc_hal_common.h" +#include "hal/adc_ll.h" +#include "hal/assert.h" + +/*--------------------------------------------------------------- + Controller Setting +---------------------------------------------------------------*/ +static adc_ll_controller_t get_controller(adc_unit_t unit, adc_hal_work_mode_t work_mode) +{ + if (unit == ADC_UNIT_1) { + switch (work_mode) { +#if SOC_ULP_SUPPORTED + case ADC_HAL_ULP_MODE: + return ADC_LL_CTRL_ULP; +#endif + case ADC_HAL_SINGLE_READ_MODE: +#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED + return ADC_LL_CTRL_DIG; +#elif SOC_ADC_RTC_CTRL_SUPPORTED + return ADC_LL_CTRL_RTC; +#endif + case ADC_HAL_CONTINUOUS_READ_MODE: + return ADC_LL_CTRL_DIG; + default: + abort(); + } + } else { + switch (work_mode) { +#if SOC_ULP_SUPPORTED + case ADC_HAL_ULP_MODE: + return ADC_LL_CTRL_ULP; +#endif +#if !SOC_ADC_ARBITER_SUPPORTED //No ADC2 arbiter on ESP32 + case ADC_HAL_SINGLE_READ_MODE: + return ADC_LL_CTRL_RTC; + case ADC_HAL_CONTINUOUS_READ_MODE: + return ADC_LL_CTRL_DIG; + case ADC_HAL_PWDET_MODE: + return ADC_LL_CTRL_PWDET; + default: + abort(); +#else + default: + return ADC_LL_CTRL_ARB; +#endif + } + } +} + +void adc_hal_set_controller(adc_unit_t unit, adc_hal_work_mode_t work_mode) +{ + adc_ll_controller_t ctrlr = get_controller(unit, work_mode); + adc_ll_set_controller(unit, ctrlr); +} + + +/*--------------------------------------------------------------- + Arbiter +---------------------------------------------------------------*/ +#if SOC_ADC_ARBITER_SUPPORTED +void adc_hal_arbiter_config(adc_arbiter_t *config) +{ + adc_ll_set_arbiter_work_mode(config->mode); + adc_ll_set_arbiter_priority(config->rtc_pri, config->dig_pri, config->pwdet_pri); +} +#endif // #if SOC_ADC_ARBITER_SUPPORTED + + +/*--------------------------------------------------------------- + ADC calibration setting +---------------------------------------------------------------*/ +#if SOC_ADC_CALIBRATION_V1_SUPPORTED +//For chips without RTC controller, Digital controller is used to trigger an ADC single read. +#include "esp_rom_sys.h" + +void adc_hal_calibration_init(adc_unit_t adc_n) +{ + adc_ll_calibration_init(adc_n); +} + +static uint32_t s_previous_init_code[SOC_ADC_PERIPH_NUM] = {-1, -1}; + +void adc_hal_set_calibration_param(adc_unit_t adc_n, uint32_t param) +{ + if (param != s_previous_init_code[adc_n]) { + adc_ll_set_calibration_param(adc_n, param); + s_previous_init_code[adc_n] = param; + } +} + +static void cal_setup(adc_unit_t adc_n, adc_atten_t atten) +{ + adc_hal_set_controller(adc_n, ADC_HAL_SINGLE_READ_MODE); + adc_oneshot_ll_disable_all_unit(); + // Enableinternal connect GND (for calibration). + adc_oneshot_ll_disable_channel(adc_n); + /** + * Note: + * When controlled by RTC controller, when all channels are disabled, HW auto selects channel0 atten param. + * When controlled by DIG controller, unit and channel are not related to attenuation + */ + adc_oneshot_ll_set_atten(adc_n, 0, atten); + adc_oneshot_ll_enable(adc_n); +} + +static uint32_t read_cal_channel(adc_unit_t adc_n) +{ + uint32_t event = (adc_n == ADC_UNIT_1) ? ADC_LL_EVENT_ADC1_ONESHOT_DONE : ADC_LL_EVENT_ADC2_ONESHOT_DONE; + adc_oneshot_ll_clear_event(event); + +#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED + adc_oneshot_ll_start(false); + esp_rom_delay_us(5); + adc_oneshot_ll_start(true); +#else + adc_oneshot_ll_start(adc_n); +#endif + + while(!adc_oneshot_ll_get_event(event)); + + uint32_t read_val = -1; + read_val = adc_oneshot_ll_get_raw_result(adc_n); + if (adc_oneshot_ll_raw_check_valid(adc_n, read_val) == false) { + return -1; + } + return read_val; +} + +#define ADC_HAL_CAL_TIMES (10) +#define ADC_HAL_CAL_OFFSET_RANGE (4096) + +uint32_t adc_hal_self_calibration(adc_unit_t adc_n, adc_atten_t atten, bool internal_gnd) +{ + if (adc_n == ADC_UNIT_2) { + adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); + adc_hal_arbiter_config(&config); + } + + cal_setup(adc_n, atten); + + adc_ll_calibration_prepare(adc_n, internal_gnd); + + uint32_t code_list[ADC_HAL_CAL_TIMES] = {0}; + uint32_t code_sum = 0; + uint32_t code_h = 0; + uint32_t code_l = 0; + uint32_t chk_code = 0; + + for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) { + code_h = ADC_HAL_CAL_OFFSET_RANGE; + code_l = 0; + chk_code = (code_h + code_l) / 2; + adc_ll_set_calibration_param(adc_n, chk_code); + uint32_t self_cal = read_cal_channel(adc_n); + while (code_h - code_l > 1) { + if (self_cal == 0) { + code_h = chk_code; + } else { + code_l = chk_code; + } + chk_code = (code_h + code_l) / 2; + adc_ll_set_calibration_param(adc_n, chk_code); + self_cal = read_cal_channel(adc_n); + if ((code_h - code_l == 1)) { + chk_code += 1; + adc_ll_set_calibration_param(adc_n, chk_code); + self_cal = read_cal_channel(adc_n); + } + } + code_list[rpt] = chk_code; + code_sum += chk_code; + } + + code_l = code_list[0]; + code_h = code_list[0]; + for (uint8_t i = 0 ; i < ADC_HAL_CAL_TIMES ; i++) { + code_l = MIN(code_l, code_list[i]); + code_h = MAX(code_h, code_list[i]); + } + + chk_code = code_h + code_l; + uint32_t ret = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4) + ? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + : (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1; + + adc_ll_calibration_finish(adc_n); + return ret; + return 0; +} +#endif //SOC_ADC_CALIBRATION_V1_SUPPORTED diff --git a/components/hal/esp32/include/hal/adc_ll.h b/components/hal/esp32/include/hal/adc_ll.h index a8287becfa..0da20a58c2 100644 --- a/components/hal/esp32/include/hal/adc_ll.h +++ b/components/hal/esp32/include/hal/adc_ll.h @@ -6,19 +6,22 @@ #pragma once -#include "soc/adc_periph.h" +#include #include "hal/adc_types.h" +#include "hal/misc.h" +#include "hal/assert.h" +#include "soc/adc_periph.h" #include "soc/rtc_io_struct.h" #include "soc/sens_struct.h" #include "soc/syscon_struct.h" #include "soc/rtc_cntl_struct.h" -#include -#include "hal/misc.h" #ifdef __cplusplus extern "C" { #endif +#define ADC_LL_EVENT_ADC1_ONESHOT_DONE (1 << 0) +#define ADC_LL_EVENT_ADC2_ONESHOT_DONE (1 << 1) typedef enum { ADC_POWER_BY_FSM, /*!< ADC XPD controlled by FSM. Used for polling mode */ @@ -338,14 +341,31 @@ static inline void adc_ll_set_sar_clk_div(adc_unit_t adc_n, uint32_t div) * @param adc_n ADC unit. * @param bits Output data bits width option, see ``adc_bits_width_t``. */ -static inline void adc_ll_rtc_set_output_format(adc_unit_t adc_n, adc_bits_width_t bits) +static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits) { + uint32_t reg_val = 0; + switch (bits) { + case ADC_BITWIDTH_9: + reg_val = 0; + break; + case ADC_BITWIDTH_10: + reg_val = 1; + break; + case ADC_BITWIDTH_11: + reg_val = 2; + break; + case ADC_BITWIDTH_12: + reg_val = 3; + break; + default: + HAL_ASSERT(false); + } if (adc_n == ADC_UNIT_1) { - SENS.sar_start_force.sar1_bit_width = bits; - SENS.sar_read_ctrl.sar1_sample_bit = bits; + SENS.sar_start_force.sar1_bit_width = reg_val; + SENS.sar_read_ctrl.sar1_sample_bit = reg_val; } else { // adc_n == ADC_UNIT_2 - SENS.sar_start_force.sar2_bit_width = bits; - SENS.sar_read_ctrl2.sar2_sample_bit = bits; + SENS.sar_start_force.sar2_bit_width = reg_val; + SENS.sar_read_ctrl2.sar2_sample_bit = reg_val; } } @@ -357,7 +377,7 @@ static inline void adc_ll_rtc_set_output_format(adc_unit_t adc_n, adc_bits_width * @param adc_n ADC unit. * @param channel ADC channel number for each ADCn. */ -static inline void adc_ll_rtc_enable_channel(adc_unit_t adc_n, int channel) +static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, int channel) { if (adc_n == ADC_UNIT_1) { SENS.sar_meas_start1.sar1_en_pad = (1 << channel); //only one channel is selected. @@ -373,7 +393,7 @@ static inline void adc_ll_rtc_enable_channel(adc_unit_t adc_n, int channel) * * @param adc_n ADC unit. */ -static inline void adc_ll_rtc_disable_channel(adc_unit_t adc_n) +static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n) { if (adc_n == ADC_UNIT_1) { SENS.sar_meas_start1.sar1_en_pad = 0; //only one channel is selected. @@ -388,9 +408,8 @@ static inline void adc_ll_rtc_disable_channel(adc_unit_t adc_n) * @note It may be block to wait conversion idle for ADC1. * * @param adc_n ADC unit. - * @param channel ADC channel number for each ADCn. */ -static inline void adc_ll_rtc_start_convert(adc_unit_t adc_n, int channel) +static inline void adc_oneshot_ll_start(adc_unit_t adc_n) { if (adc_n == ADC_UNIT_1) { while (HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_slave_addr1, meas_status) != 0) {} @@ -403,20 +422,33 @@ static inline void adc_ll_rtc_start_convert(adc_unit_t adc_n, int channel) } /** - * Check the conversion done flag for each ADCn for RTC controller. + * Clear the event for each ADCn for Oneshot mode + * + * @param event ADC event + */ +static inline void adc_oneshot_ll_clear_event(uint32_t event) +{ + //For compatibility +} + +/** + * Check the event for each ADCn for Oneshot mode + * + * @param event ADC event * - * @param adc_n ADC unit. * @return * -true : The conversion process is finish. * -false : The conversion process is not finish. */ -static inline bool adc_ll_rtc_convert_is_done(adc_unit_t adc_n) +static inline bool adc_oneshot_ll_get_event(uint32_t event) { bool ret = true; - if (adc_n == ADC_UNIT_1) { + if (event == ADC_LL_EVENT_ADC1_ONESHOT_DONE) { ret = (bool)SENS.sar_meas_start1.meas1_done_sar; - } else { // adc_n == ADC_UNIT_2 + } else if (event == ADC_LL_EVENT_ADC2_ONESHOT_DONE) { ret = (bool)SENS.sar_meas_start2.meas2_done_sar; + } else { + HAL_ASSERT(false); } return ret; } @@ -428,9 +460,9 @@ static inline bool adc_ll_rtc_convert_is_done(adc_unit_t adc_n) * @return * - Converted value. */ -static inline int adc_ll_rtc_get_convert_value(adc_unit_t adc_n) +static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n) { - int ret_val = 0; + uint32_t ret_val = 0; if (adc_n == ADC_UNIT_1) { ret_val = HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_meas_start1, meas1_data_sar); } else { // adc_n == ADC_UNIT_2 @@ -444,7 +476,7 @@ static inline int adc_ll_rtc_get_convert_value(adc_unit_t adc_n) * * @param adc_n ADC unit. */ -static inline void adc_ll_rtc_output_invert(adc_unit_t adc_n, bool inv_en) +static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en) { if (adc_n == ADC_UNIT_1) { SENS.sar_read_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert @@ -457,20 +489,20 @@ static inline void adc_ll_rtc_output_invert(adc_unit_t adc_n, bool inv_en) * Analyze whether the obtained raw data is correct. * * @param adc_n ADC unit. - * @param raw_data ADC raw data input (convert value). + * @param raw ADC raw data input (convert value). * @return - * - 0: The data is correct to use. + * - true: raw data is valid */ -static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_unit_t adc_n, uint16_t raw_data) +static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw) { - /* ADC1 don't need check data */ - return ADC_RTC_DATA_OK; + /* No arbiter, don't need check data */ + return true; } /** * Set the attenuation of a particular channel on ADCn. */ -static inline void adc_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) +static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) { if (adc_n == ADC_UNIT_1) { SENS.sar_atten1 = ( SENS.sar_atten1 & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2)); @@ -495,6 +527,25 @@ static inline adc_atten_t adc_ll_get_atten(adc_unit_t adc_n, adc_channel_t chann } } +/** + * Enable oneshot conversion trigger + * + * @param adc_n Not used, for compatibility + */ +static inline void adc_oneshot_ll_enable(adc_unit_t adc_n) +{ + (void)adc_n; + //For compatibility +} + +/** + * Disable oneshot conversion trigger for all the ADC units + */ +static inline void adc_oneshot_ll_disable_all_unit(void) +{ + //For compatibility +} + /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ diff --git a/components/hal/esp32c2/include/hal/adc_ll.h b/components/hal/esp32c2/include/hal/adc_ll.h index 176bf77a42..3fcef891ed 100644 --- a/components/hal/esp32c2/include/hal/adc_ll.h +++ b/components/hal/esp32c2/include/hal/adc_ll.h @@ -16,6 +16,7 @@ #include "soc/rtc_cntl_reg.h" #include "hal/misc.h" #include "hal/adc_types.h" +#include "hal/adc_types_private.h" #include "esp_private/regi2c_ctrl.h" #include "regi2c_saradc.h" @@ -28,6 +29,8 @@ extern "C" { #define ADC_LL_CLKM_DIV_B_DEFAULT 1 #define ADC_LL_CLKM_DIV_A_DEFAULT 0 +#define ADC_LL_EVENT_ADC1_ONESHOT_DONE BIT(31) +#define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30) typedef enum { ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ @@ -767,82 +770,188 @@ static inline void adc_ll_vref_output(adc_unit_t adc, adc_channel_t channel, boo Single Read ---------------------------------------------------------------*/ /** - * Trigger single read + * Set adc output data format for oneshot mode + * + * @note ESP32C3 Oneshot mode only supports 12bit. + * @param adc_n ADC unit. + * @param bits Output data bits width option. + */ +static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits) +{ + abort(); //TODO IDF-3908 + // //ESP32C3 only supports 12bit, leave here for compatibility + // HAL_ASSERT(bits == ADC_BITWIDTH_12); +} + +/** + * Enable adc channel to start convert. + * + * @note Only one channel can be selected for measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel) +{ + abort(); //TODO IDF-3908 + // APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | channel); +} + +/** + * Disable adc channel to start convert. + * + * @note Only one channel can be selected in once measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n) +{ + abort(); //TODO IDF-3908 + // if (adc_n == ADC_UNIT_1) { + // APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | 0xF); + // } else { // adc_n == ADC_UNIT_2 + // APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | 0x1); + // } +} + +/** + * Start oneshot conversion by software * * @param val Usage: set to 1 to start the ADC conversion. The step signal should at least keep 3 ADC digital controller clock cycle, * otherwise the step signal may not be captured by the ADC digital controller when its frequency is slow. * This hardware limitation will be removed in future versions. */ -static inline void adc_ll_onetime_start(bool val) +static inline void adc_oneshot_ll_start(bool val) { abort(); //TODO IDF-3908 // APB_SARADC.onetime_sample.onetime_start = val; } -static inline void adc_ll_onetime_set_channel(adc_unit_t unit, adc_channel_t channel) +/** + * Clear the event for each ADCn for Oneshot mode + * + * @param event ADC event + */ +static inline void adc_oneshot_ll_clear_event(uint32_t event_mask) { abort(); //TODO IDF-3908 - // APB_SARADC.onetime_sample.onetime_channel = ((unit << 3) | channel); + // APB_SARADC.int_clr.val |= event_mask; } -static inline void adc_ll_onetime_set_atten(adc_atten_t atten) +/** + * Check the event for each ADCn for Oneshot mode + * + * @param event ADC event + * + * @return + * -true : The conversion process is finish. + * -false : The conversion process is not finish. + */ +static inline bool adc_oneshot_ll_get_event(uint32_t event_mask) { abort(); //TODO IDF-3908 - // APB_SARADC.onetime_sample.onetime_atten = atten; + // return (APB_SARADC.int_raw.val & event_mask); } -static inline void adc_ll_intr_enable(adc_ll_intr_t mask) +/** + * Get the converted value for each ADCn for RTC controller. + * + * @param adc_n ADC unit. + * @return + * - Converted value. + */ +static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n) { abort(); //TODO IDF-3908 - // APB_SARADC.int_ena.val |= mask; + // uint32_t ret_val = 0; + // if (adc_n == ADC_UNIT_1) { + // ret_val = APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff; + // } else { // adc_n == ADC_UNIT_2 + // ret_val = APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff; + // } + // return ret_val; } -static inline void adc_ll_intr_disable(adc_ll_intr_t mask) -{ - abort(); //TODO IDF-3908 - // APB_SARADC.int_ena.val &= ~mask; -} - -static inline void adc_ll_intr_clear(adc_ll_intr_t mask) -{ - abort(); //TODO IDF-3908 - // APB_SARADC.int_clr.val |= mask; -} - -static inline bool adc_ll_intr_get_raw(adc_ll_intr_t mask) -{ - abort(); //TODO IDF-3908 - // return (APB_SARADC.int_raw.val & mask); -} - -static inline bool adc_ll_intr_get_status(adc_ll_intr_t mask) -{ - abort(); //TODO IDF-3908 - // return (APB_SARADC.int_st.val & mask); -} - -static inline void adc_ll_onetime_sample_enable(adc_unit_t adc_n, bool enable) +/** + * Analyze whether the obtained raw data is correct. + * ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data. + * + * @param adc_n ADC unit. + * @param raw_data ADC raw data input (convert value). + * @return + * - 1: The data is correct to use. + * - 0: The data is invalid. + */ +static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw_data) { abort(); //TODO IDF-3908 // if (adc_n == ADC_UNIT_1) { - // APB_SARADC.onetime_sample.adc1_onetime_sample = enable; + // return true; + // } + + // //The raw data API returns value without channel information. Read value directly from the register + // if (((APB_SARADC.apb_saradc2_data_status.adc2_data >> 13) & 0xF) > 9) { + // return false; + // } + + // return true; +} + +/** + * ADC module RTC output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en) +{ + abort(); //TODO IDF-3908 + // (void)adc_n; + // (void)inv_en; + // //For compatibility +} + +/** + * Enable oneshot conversion trigger + * + * @param adc_n ADC unit + */ +static inline void adc_oneshot_ll_enable(adc_unit_t adc_n) +{ + abort(); //TODO IDF-3908 + // if (adc_n == ADC_UNIT_1) { + // APB_SARADC.onetime_sample.adc1_onetime_sample = 1; // } else { - // APB_SARADC.onetime_sample.adc2_onetime_sample = enable; + // APB_SARADC.onetime_sample.adc2_onetime_sample = 1; // } } -static inline uint32_t adc_ll_adc1_read(void) +/** + * Disable oneshot conversion trigger for all the ADC units + */ +static inline void adc_oneshot_ll_disable_all_unit(void) { abort(); //TODO IDF-3908 - // //On ESP32-C2, valid data width is 12-bit - // return (APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff); + // APB_SARADC.onetime_sample.adc1_onetime_sample = 0; + // APB_SARADC.onetime_sample.adc2_onetime_sample = 0; } -static inline uint32_t adc_ll_adc2_read(void) +/** + * Set attenuation + * + * @note Attenuation is for all channels + * + * @param adc_n ADC unit + * @param channel ADC channel + * @param atten ADC attenuation + */ +static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) { abort(); //TODO IDF-3908 - // //On ESP32-C2, valid data width is 12-bit - // return (APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff); + // (void)adc_n; + // (void)channel; + // // Attenuation is for all channels, unit and channel are for compatibility + // APB_SARADC.onetime_sample.onetime_atten = atten; } #ifdef __cplusplus diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index d6500b2b8d..81c190b447 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -15,7 +15,9 @@ #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" #include "hal/misc.h" +#include "hal/assert.h" #include "hal/adc_types.h" +#include "hal/adc_types_private.h" #include "esp_private/regi2c_ctrl.h" #include "regi2c_saradc.h" @@ -28,6 +30,13 @@ extern "C" { #define ADC_LL_CLKM_DIV_B_DEFAULT 1 #define ADC_LL_CLKM_DIV_A_DEFAULT 0 +#define ADC_LL_EVENT_ADC1_ONESHOT_DONE BIT(31) +#define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30) +#define ADC_LL_EVENT_THRES0_HIGH BIT(29) +#define ADC_LL_event_THRES1_HIGH BIT(28) +#define ADC_LL_event_THRES0_LOW BIT(27) +#define ADC_LL_EVENT_THRES1_LOW BIT(26) + typedef enum { ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ ADC_POWER_SW_ON, /*!< ADC XPD controled by SW. power on. Used for DMA mode */ @@ -58,17 +67,6 @@ typedef enum { ADC_LL_DIGI_CONV_ALTER_UNIT = 0, // Use both ADC1 and ADC2 for conversion by turn. e.g. ADC1 -> ADC2 -> ADC1 -> ADC2 ..... } adc_ll_digi_convert_mode_t; -//These values should be set according to the HW -typedef enum { - ADC_LL_INTR_THRES1_LOW = BIT(26), - ADC_LL_INTR_THRES0_LOW = BIT(27), - ADC_LL_INTR_THRES1_HIGH = BIT(28), - ADC_LL_INTR_THRES0_HIGH = BIT(29), - ADC_LL_INTR_ADC2_DONE = BIT(30), - ADC_LL_INTR_ADC1_DONE = BIT(31), -} adc_ll_intr_t; -FLAG_ATTR(adc_ll_intr_t) - typedef struct { union { struct { @@ -474,30 +472,6 @@ static inline uint32_t adc_ll_pwdet_get_cct(void) return RTCCNTL.sensor_ctrl.sar2_pwdet_cct; } -/** - * Analyze whether the obtained raw data is correct. - * ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data. - * - * @param adc_n ADC unit. - * @param raw_data ADC raw data input (convert value). - * @return - * - 0: The data is correct to use. - * - -1: The data is invalid. - */ -static inline adc_ll_rtc_raw_data_t adc_ll_analysis_raw_data(adc_unit_t adc_n, int raw_data) -{ - if (adc_n == ADC_UNIT_1) { - return ADC_RTC_DATA_OK; - } - - //The raw data API returns value without channel information. Read value directly from the register - if (((APB_SARADC.apb_saradc2_data_status.adc2_data >> 13) & 0xF) > 9) { - return ADC_RTC_DATA_FAIL; - } - - return ADC_RTC_DATA_OK; -} - /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ @@ -613,11 +587,10 @@ static inline void adc_ll_calibration_init(adc_unit_t adc_n) * @note Different ADC units and different attenuation options use different calibration data (initial data). * * @param adc_n ADC index number. - * @param channel adc channel number. * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. * false: Use IO external voltage as calibration voltage. */ -static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, adc_channel_t channel, bool internal_gnd) +static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gnd) { /* Enable/disable internal connect GND (for calibration). */ if (adc_n == ADC_UNIT_1) { @@ -725,74 +698,179 @@ static inline void adc_ll_vref_output(adc_unit_t adc, adc_channel_t channel, boo } /*--------------------------------------------------------------- - Single Read + Oneshot Read ---------------------------------------------------------------*/ /** - * Trigger single read + * Set adc output data format for oneshot mode + * + * @note ESP32C3 Oneshot mode only supports 12bit. + * @param adc_n ADC unit. + * @param bits Output data bits width option. + */ +static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits) +{ + //ESP32C3 only supports 12bit, leave here for compatibility + HAL_ASSERT(bits == ADC_BITWIDTH_12); +} + +/** + * Enable adc channel to start convert. + * + * @note Only one channel can be selected for measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel) +{ + APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | channel); +} + +/** + * Disable adc channel to start convert. + * + * @note Only one channel can be selected in once measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n) +{ + if (adc_n == ADC_UNIT_1) { + APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | 0xF); + } else { // adc_n == ADC_UNIT_2 + APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | 0x1); + } +} + +/** + * Start oneshot conversion by software * * @param val Usage: set to 1 to start the ADC conversion. The step signal should at least keep 3 ADC digital controller clock cycle, * otherwise the step signal may not be captured by the ADC digital controller when its frequency is slow. * This hardware limitation will be removed in future versions. */ -static inline void adc_ll_onetime_start(bool val) +static inline void adc_oneshot_ll_start(bool val) { APB_SARADC.onetime_sample.onetime_start = val; } -static inline void adc_ll_onetime_set_channel(adc_unit_t unit, adc_channel_t channel) +/** + * Clear the event for each ADCn for Oneshot mode + * + * @param event ADC event + */ +static inline void adc_oneshot_ll_clear_event(uint32_t event_mask) { - APB_SARADC.onetime_sample.onetime_channel = ((unit << 3) | channel); + APB_SARADC.int_clr.val |= event_mask; } -static inline void adc_ll_onetime_set_atten(adc_atten_t atten) +/** + * Check the event for each ADCn for Oneshot mode + * + * @param event ADC event + * + * @return + * -true : The conversion process is finish. + * -false : The conversion process is not finish. + */ +static inline bool adc_oneshot_ll_get_event(uint32_t event_mask) { - APB_SARADC.onetime_sample.onetime_atten = atten; + return (APB_SARADC.int_raw.val & event_mask); } -static inline void adc_ll_intr_enable(adc_ll_intr_t mask) +/** + * Get the converted value for each ADCn for RTC controller. + * + * @param adc_n ADC unit. + * @return + * - Converted value. + */ +static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n) { - APB_SARADC.int_ena.val |= mask; + uint32_t ret_val = 0; + if (adc_n == ADC_UNIT_1) { + ret_val = APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff; + } else { // adc_n == ADC_UNIT_2 + ret_val = APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff; + } + return ret_val; } -static inline void adc_ll_intr_disable(adc_ll_intr_t mask) -{ - APB_SARADC.int_ena.val &= ~mask; -} - -static inline void adc_ll_intr_clear(adc_ll_intr_t mask) -{ - APB_SARADC.int_clr.val |= mask; -} - -static inline bool adc_ll_intr_get_raw(adc_ll_intr_t mask) -{ - return (APB_SARADC.int_raw.val & mask); -} - -static inline bool adc_ll_intr_get_status(adc_ll_intr_t mask) -{ - return (APB_SARADC.int_st.val & mask); -} - -static inline void adc_ll_onetime_sample_enable(adc_unit_t adc_n, bool enable) +/** + * Analyze whether the obtained raw data is correct. + * ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data. + * + * @param adc_n ADC unit. + * @param raw_data ADC raw data input (convert value). + * @return + * - 1: The data is correct to use. + * - 0: The data is invalid. + */ +static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw_data) { if (adc_n == ADC_UNIT_1) { - APB_SARADC.onetime_sample.adc1_onetime_sample = enable; + return true; + } + + //The raw data API returns value without channel information. Read value directly from the register + if (((APB_SARADC.apb_saradc2_data_status.adc2_data >> 13) & 0xF) > 9) { + return false; + } + + return true; +} + +/** + * ADC module RTC output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en) +{ + (void)adc_n; + (void)inv_en; + //For compatibility +} + +/** + * Enable oneshot conversion trigger + * + * @param adc_n ADC unit + */ +static inline void adc_oneshot_ll_enable(adc_unit_t adc_n) +{ + if (adc_n == ADC_UNIT_1) { + APB_SARADC.onetime_sample.adc1_onetime_sample = 1; } else { - APB_SARADC.onetime_sample.adc2_onetime_sample = enable; + APB_SARADC.onetime_sample.adc2_onetime_sample = 1; } } -static inline uint32_t adc_ll_adc1_read(void) +/** + * Disable oneshot conversion trigger for all the ADC units + */ +static inline void adc_oneshot_ll_disable_all_unit(void) { - //On ESP32C3, valid data width is 12-bit - return (APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff); + APB_SARADC.onetime_sample.adc1_onetime_sample = 0; + APB_SARADC.onetime_sample.adc2_onetime_sample = 0; } -static inline uint32_t adc_ll_adc2_read(void) +/** + * Set attenuation + * + * @note Attenuation is for all channels + * + * @param adc_n ADC unit + * @param channel ADC channel + * @param atten ADC attenuation + */ +static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) { - //On ESP32C3, valid data width is 12-bit - return (APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff); + (void)adc_n; + (void)channel; + // Attenuation is for all channels, unit and channel are for compatibility + APB_SARADC.onetime_sample.onetime_atten = atten; } #ifdef __cplusplus diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index eeabbad3ab..92ffa39052 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -11,6 +11,7 @@ #include "soc/adc_periph.h" #include "hal/adc_types.h" +#include "hal/adc_types_private.h" #include "soc/apb_saradc_struct.h" #include "soc/apb_saradc_reg.h" #include "soc/rtc_cntl_struct.h" @@ -28,6 +29,9 @@ extern "C" { #define ADC_LL_CLKM_DIV_B_DEFAULT 1 #define ADC_LL_CLKM_DIV_A_DEFAULT 0 +#define ADC_LL_EVENT_ADC1_ONESHOT_DONE BIT(31) +#define ADC_LL_EVENT_ADC2_ONESHOT_DONE BIT(30) + typedef enum { ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ ADC_POWER_SW_ON, /*!< ADC XPD controled by SW. power on. Used for DMA mode */ @@ -690,73 +694,189 @@ static inline void adc_ll_vref_output(adc_unit_t adc, adc_channel_t channel, boo Single Read ---------------------------------------------------------------*/ /** - * Trigger single read + * Set adc output data format for oneshot mode + * + * @note ESP32C3 Oneshot mode only supports 12bit. + * @param adc_n ADC unit. + * @param bits Output data bits width option. + */ +static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits) +{ + abort(); //TODO IDF-3908 + // //ESP32C3 only supports 12bit, leave here for compatibility + // HAL_ASSERT(bits == ADC_BITWIDTH_12); +} + +/** + * Enable adc channel to start convert. + * + * @note Only one channel can be selected for measurement. + * + * @param adc_n ADC unit. + * @param channel ADC channel number for each ADCn. + */ +static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel) +{ + abort(); //TODO IDF-3908 + // APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | channel); +} + +/** + * Disable adc channel to start convert. + * + * @note Only one channel can be selected in once measurement. + * + * @param adc_n ADC unit. + */ +static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n) +{ + abort(); //TODO IDF-3908 + // if (adc_n == ADC_UNIT_1) { + // APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | 0xF); + // } else { // adc_n == ADC_UNIT_2 + // APB_SARADC.onetime_sample.onetime_channel = ((adc_n << 3) | 0x1); + // } +} + +/** + * Start oneshot conversion by software * * @param val Usage: set to 1 to start the ADC conversion. The step signal should at least keep 3 ADC digital controller clock cycle, * otherwise the step signal may not be captured by the ADC digital controller when its frequency is slow. * This hardware limitation will be removed in future versions. */ -static inline void adc_ll_onetime_start(bool val) +static inline void adc_oneshot_ll_start(bool val) { - APB_SARADC.onetime_sample.onetime_start = val; + abort(); //TODO IDF-3908 + // APB_SARADC.onetime_sample.onetime_start = val; } -static inline void adc_ll_onetime_set_channel(adc_unit_t unit, adc_channel_t channel) +/** + * Clear the event for each ADCn for Oneshot mode + * + * @param event ADC event + */ +static inline void adc_oneshot_ll_clear_event(uint32_t event_mask) { - APB_SARADC.onetime_sample.onetime_channel = ((unit << 3) | channel); + abort(); //TODO IDF-3908 + // APB_SARADC.int_clr.val |= event_mask; } -static inline void adc_ll_onetime_set_atten(adc_atten_t atten) +/** + * Check the event for each ADCn for Oneshot mode + * + * @param event ADC event + * + * @return + * -true : The conversion process is finish. + * -false : The conversion process is not finish. + */ +static inline bool adc_oneshot_ll_get_event(uint32_t event_mask) { - APB_SARADC.onetime_sample.onetime_atten = atten; + abort(); //TODO IDF-3908 + // return (APB_SARADC.int_raw.val & event_mask); } -static inline void adc_ll_intr_enable(adc_ll_intr_t mask) +/** + * Get the converted value for each ADCn for RTC controller. + * + * @param adc_n ADC unit. + * @return + * - Converted value. + */ +static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n) { - APB_SARADC.int_ena.val |= mask; + abort(); //TODO IDF-3908 + // uint32_t ret_val = 0; + // if (adc_n == ADC_UNIT_1) { + // ret_val = APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff; + // } else { // adc_n == ADC_UNIT_2 + // ret_val = APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff; + // } + // return ret_val; } -static inline void adc_ll_intr_disable(adc_ll_intr_t mask) +/** + * Analyze whether the obtained raw data is correct. + * ADC2 can use arbiter. The arbitration result is stored in the channel information of the returned data. + * + * @param adc_n ADC unit. + * @param raw_data ADC raw data input (convert value). + * @return + * - 1: The data is correct to use. + * - 0: The data is invalid. + */ +static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw_data) { - APB_SARADC.int_ena.val &= ~mask; + abort(); //TODO IDF-3908 + // if (adc_n == ADC_UNIT_1) { + // return true; + // } + + // //The raw data API returns value without channel information. Read value directly from the register + // if (((APB_SARADC.apb_saradc2_data_status.adc2_data >> 13) & 0xF) > 9) { + // return false; + // } + + // return true; } -static inline void adc_ll_intr_clear(adc_ll_intr_t mask) +/** + * ADC module RTC output data invert or not. + * + * @param adc_n ADC unit. + * @param inv_en data invert or not. + */ +static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en) { - APB_SARADC.int_clr.val |= mask; + abort(); //TODO IDF-3908 + // (void)adc_n; + // (void)inv_en; + // //For compatibility } -static inline bool adc_ll_intr_get_raw(adc_ll_intr_t mask) +/** + * Enable oneshot conversion trigger + * + * @param adc_n ADC unit + */ +static inline void adc_oneshot_ll_enable(adc_unit_t adc_n) { - return (APB_SARADC.int_raw.val & mask); + abort(); //TODO IDF-3908 + // if (adc_n == ADC_UNIT_1) { + // APB_SARADC.onetime_sample.adc1_onetime_sample = 1; + // } else { + // APB_SARADC.onetime_sample.adc2_onetime_sample = 1; + // } } -static inline bool adc_ll_intr_get_status(adc_ll_intr_t mask) +/** + * Disable oneshot conversion trigger for all the ADC units + */ +static inline void adc_oneshot_ll_disable_all_unit(void) { - return (APB_SARADC.int_st.val & mask); + abort(); //TODO IDF-3908 + // APB_SARADC.onetime_sample.adc1_onetime_sample = 0; + // APB_SARADC.onetime_sample.adc2_onetime_sample = 0; } -static inline void adc_ll_onetime_sample_enable(adc_unit_t adc_n, bool enable) +/** + * Set attenuation + * + * @note Attenuation is for all channels + * + * @param adc_n ADC unit + * @param channel ADC channel + * @param atten ADC attenuation + */ +static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) { - if (adc_n == ADC_UNIT_1) { - APB_SARADC.onetime_sample.adc1_onetime_sample = enable; - } else { - APB_SARADC.onetime_sample.adc2_onetime_sample = enable; - } + abort(); //TODO IDF-3908 + // (void)adc_n; + // (void)channel; + // // Attenuation is for all channels, unit and channel are for compatibility + // APB_SARADC.onetime_sample.onetime_atten = atten; } - -static inline uint32_t adc_ll_adc1_read(void) -{ - //On ESP32H2, valid data width is 12-bit - return (APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff); -} - -static inline uint32_t adc_ll_adc2_read(void) -{ - //On ESP32H2, valid data width is 12-bit - return (APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff); -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index f3d0bae551..2f0ccad38a 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -10,6 +10,8 @@ #include "hal/misc.h" #include "soc/adc_periph.h" #include "hal/adc_types.h" +#include "hal/adc_types_private.h" +#include "hal/assert.h" #include "soc/apb_saradc_struct.h" #include "soc/sens_struct.h" #include "soc/apb_saradc_reg.h" @@ -22,10 +24,12 @@ extern "C" { #endif -//To be checked if ESP32S2 has the 5M freq limit -#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15 -#define ADC_LL_CLKM_DIV_B_DEFAULT 1 -#define ADC_LL_CLKM_DIV_A_DEFAULT 0 +#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15 +#define ADC_LL_CLKM_DIV_B_DEFAULT 1 +#define ADC_LL_CLKM_DIV_A_DEFAULT 0 + +#define ADC_LL_EVENT_ADC1_ONESHOT_DONE (1 << 0) +#define ADC_LL_EVENT_ADC2_ONESHOT_DONE (1 << 1) typedef enum { ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ @@ -588,9 +592,10 @@ static inline void adc_ll_set_sar_clk_div(adc_unit_t adc_n, uint32_t div) * @prarm adc_n ADC unit. * @prarm bits Output data bits width option. */ -static inline void adc_ll_rtc_set_output_format(adc_unit_t adc_n, adc_bits_width_t bits) +static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits) { - return; + //ESP32S2 only supports 13bit, leave here for compatibility + HAL_ASSERT(bits == ADC_BITWIDTH_13); } /** @@ -601,7 +606,7 @@ static inline void adc_ll_rtc_set_output_format(adc_unit_t adc_n, adc_bits_width * @param adc_n ADC unit. * @param channel ADC channel number for each ADCn. */ -static inline void adc_ll_rtc_enable_channel(adc_unit_t adc_n, int channel) +static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, int channel) { if (adc_n == ADC_UNIT_1) { SENS.sar_meas1_ctrl2.sar1_en_pad = (1 << channel); //only one channel is selected. @@ -618,7 +623,7 @@ static inline void adc_ll_rtc_enable_channel(adc_unit_t adc_n, int channel) * @param adc_n ADC unit. * @param channel ADC channel number for each ADCn. */ -static inline void adc_ll_rtc_disable_channel(adc_unit_t adc_n) +static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n) { if (adc_n == ADC_UNIT_1) { SENS.sar_meas1_ctrl2.sar1_en_pad = 0; //only one channel is selected. @@ -633,9 +638,8 @@ static inline void adc_ll_rtc_disable_channel(adc_unit_t adc_n) * @note It may be block to wait conversion idle for ADC1. * * @param adc_n ADC unit. - * @param channel ADC channel number for each ADCn. */ -static inline void adc_ll_rtc_start_convert(adc_unit_t adc_n, int channel) +static inline void adc_oneshot_ll_start(adc_unit_t adc_n) { if (adc_n == ADC_UNIT_1) { while (HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_slave_addr1, meas_status) != 0) {} @@ -648,20 +652,33 @@ static inline void adc_ll_rtc_start_convert(adc_unit_t adc_n, int channel) } /** - * Check the conversion done flag for each ADCn for RTC controller. + * Clear the event for each ADCn for Oneshot mode + * + * @param event ADC event + */ +static inline void adc_oneshot_ll_clear_event(uint32_t event) +{ + //For compatibility +} + +/** + * Check the event for each ADCn for Oneshot mode + * + * @param event ADC event * - * @param adc_n ADC unit. * @return * -true : The conversion process is finish. * -false : The conversion process is not finish. */ -static inline bool adc_ll_rtc_convert_is_done(adc_unit_t adc_n) +static inline bool adc_oneshot_ll_get_event(uint32_t event) { bool ret = true; - if (adc_n == ADC_UNIT_1) { + if (event == ADC_LL_EVENT_ADC1_ONESHOT_DONE) { ret = (bool)SENS.sar_meas1_ctrl2.meas1_done_sar; - } else { // adc_n == ADC_UNIT_2 + } else if (event == ADC_LL_EVENT_ADC2_ONESHOT_DONE) { ret = (bool)SENS.sar_meas2_ctrl2.meas2_done_sar; + } else { + HAL_ASSERT(false); } return ret; } @@ -673,9 +690,9 @@ static inline bool adc_ll_rtc_convert_is_done(adc_unit_t adc_n) * @return * - Converted value. */ -static inline int adc_ll_rtc_get_convert_value(adc_unit_t adc_n) +static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n) { - int ret_val = 0; + uint32_t ret_val = 0; if (adc_n == ADC_UNIT_1) { ret_val = HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_meas1_ctrl2, meas1_data_sar); } else { // adc_n == ADC_UNIT_2 @@ -684,13 +701,37 @@ static inline int adc_ll_rtc_get_convert_value(adc_unit_t adc_n) return ret_val; } +/** + * Analyze whether the obtained raw data is correct. + * ADC2 can use arbiter. The arbitration result can be judged by the flag bit in the original data. + * + * @param adc_n ADC unit. + * @param raw ADC raw data input (convert value). + * @return + * - true: raw data is valid + * - false: raw data is invalid + */ +static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw) +{ + if (adc_n == ADC_UNIT_1) { + return true; + } + adc_ll_rtc_output_data_t *temp = (adc_ll_rtc_output_data_t *)&raw; + if (temp->flag == 0) { + return true; + } else { + //Could be ADC_LL_RTC_CTRL_UNSELECTED, ADC_LL_RTC_CTRL_BREAK or ADC_LL_RTC_DATA_FAIL + return false; + } +} + /** * ADC module RTC output data invert or not. * * @param adc_n ADC unit. * @param inv_en data invert or not. */ -static inline void adc_ll_rtc_output_invert(adc_unit_t adc_n, bool inv_en) +static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en) { if (adc_n == ADC_UNIT_1) { SENS.sar_reader1_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert @@ -751,36 +792,6 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) SENS.sar_reader2_ctrl.sar2_wait_arb_cycle = cycle; } -/** - * Analyze whether the obtained raw data is correct. - * ADC2 can use arbiter. The arbitration result can be judged by the flag bit in the original data. - * - * @param adc_n ADC unit. - * @param raw_data ADC raw data input (convert value). - * @return - * - 0: The data is correct to use. - * - 1: The data is invalid. The current controller is not enabled by the arbiter. - * - 2: The data is invalid. The current controller process was interrupted by a higher priority controller. - * - -1: The data is error. - */ -static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_unit_t adc_n, uint16_t raw_data) -{ - /* ADC1 don't need check data */ - if (adc_n == ADC_UNIT_1) { - return ADC_RTC_DATA_OK; - } - adc_ll_rtc_output_data_t *temp = (adc_ll_rtc_output_data_t *)&raw_data; - if (temp->flag == 0) { - return ADC_RTC_DATA_OK; - } else if (temp->flag == 1) { - return ADC_RTC_CTRL_UNSELECTED; - } else if (temp->flag == 2) { - return ADC_RTC_CTRL_BREAK; - } else { - return ADC_RTC_DATA_FAIL; - } -} - /** * Set the attenuation of a particular channel on ADCn. * @@ -814,7 +825,7 @@ static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_unit_t adc_ * @param channel ADCn channel number. * @param atten The attenuation option. */ -static inline void adc_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) +static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) { if (adc_n == ADC_UNIT_1) { SENS.sar_atten1 = ( SENS.sar_atten1 & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2)); @@ -839,6 +850,25 @@ static inline adc_atten_t adc_ll_get_atten(adc_unit_t adc_n, adc_channel_t chann } } +/** + * Enable oneshot conversion trigger + * + * @param adc_n Not used, for compatibility + */ +static inline void adc_oneshot_ll_enable(adc_unit_t adc_n) +{ + (void)adc_n; + //For compatibility +} + +/** + * Disable oneshot conversion trigger for all the ADC units + */ +static inline void adc_oneshot_ll_disable_all_unit(void) +{ + //For compatibility +} + /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ @@ -1027,11 +1057,10 @@ static inline void adc_ll_calibration_init(adc_unit_t adc_n) * @note Different ADC units and different attenuation options use different calibration data (initial data). * * @param adc_n ADC index number. - * @param channel adc channel number. * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. * false: Use IO external voltage as calibration voltage. */ -static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, adc_channel_t channel, bool internal_gnd) +static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gnd) { /* Should be called before writing I2C registers. */ CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M); diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index cac222ff64..6374030f7c 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -10,12 +10,14 @@ #include "soc/adc_periph.h" #include "hal/adc_types.h" +#include "hal/adc_types_private.h" +#include "hal/assert.h" +#include "hal/misc.h" #include "soc/apb_saradc_struct.h" #include "soc/sens_struct.h" #include "soc/apb_saradc_reg.h" #include "soc/rtc_cntl_struct.h" #include "soc/rtc_cntl_reg.h" -#include "hal/misc.h" #include "esp_private/regi2c_ctrl.h" #include "regi2c_saradc.h" @@ -24,9 +26,12 @@ extern "C" { #endif -#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15 -#define ADC_LL_CLKM_DIV_B_DEFAULT 1 -#define ADC_LL_CLKM_DIV_A_DEFAULT 0 +#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15 +#define ADC_LL_CLKM_DIV_B_DEFAULT 1 +#define ADC_LL_CLKM_DIV_A_DEFAULT 0 + +#define ADC_LL_EVENT_ADC1_ONESHOT_DONE (1 << 0) +#define ADC_LL_EVENT_ADC2_ONESHOT_DONE (1 << 1) typedef enum { ADC_POWER_BY_FSM, /*!< ADC XPD controled by FSM. Used for polling mode */ @@ -36,10 +41,10 @@ typedef enum { } adc_ll_power_t; typedef enum { - ADC_RTC_DATA_OK = 0, - ADC_RTC_CTRL_UNSELECTED = 1, - ADC_RTC_CTRL_BREAK = 2, - ADC_RTC_DATA_FAIL = -1, + ADC_LL_RTC_DATA_OK = 0, + ADC_LL_RTC_CTRL_UNSELECTED = 1, ///< The current controller is not enabled by the arbiter. + ADC_LL_RTC_CTRL_BREAK = 2, ///< The current controller process was interrupted by a higher priority controller. + ADC_LL_RTC_DATA_FAIL = -1, ///< The data is wrong } adc_ll_rtc_raw_data_t; typedef enum { @@ -702,11 +707,10 @@ static inline void adc_ll_calibration_init(adc_unit_t adc_n) * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration. * * @param adc_n ADC index number. - * @param channel Not used. * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. * false: Use IO external voltage as calibration voltage. */ -static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, adc_channel_t channel, bool internal_gnd) +static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gnd) { /* Should be called before writing I2C registers. */ SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M); @@ -800,12 +804,13 @@ static inline void adc_ll_set_sar_clk_div(adc_unit_t adc_n, uint32_t div) * Set adc output data format for RTC controller. * * @note ESP32S3 RTC controller only support 12bit. - * @prarm adc_n ADC unit. - * @prarm bits Output data bits width option. + * @param adc_n ADC unit. + * @param bits Output data bits width option. */ -static inline void adc_ll_rtc_set_output_format(adc_unit_t adc_n, adc_bits_width_t bits) +static inline void adc_oneshot_ll_set_output_bits(adc_unit_t adc_n, adc_bitwidth_t bits) { //ESP32S3 only supports 12bit, leave here for compatibility + HAL_ASSERT(bits == ADC_BITWIDTH_12); } /** @@ -816,7 +821,7 @@ static inline void adc_ll_rtc_set_output_format(adc_unit_t adc_n, adc_bits_width * @param adc_n ADC unit. * @param channel ADC channel number for each ADCn. */ -static inline void adc_ll_rtc_enable_channel(adc_unit_t adc_n, int channel) +static inline void adc_oneshot_ll_set_channel(adc_unit_t adc_n, adc_channel_t channel) { if (adc_n == ADC_UNIT_1) { SENS.sar_meas1_ctrl2.sar1_en_pad = (1 << channel); //only one channel is selected. @@ -833,7 +838,7 @@ static inline void adc_ll_rtc_enable_channel(adc_unit_t adc_n, int channel) * @param adc_n ADC unit. * @param channel ADC channel number for each ADCn. */ -static inline void adc_ll_rtc_disable_channel(adc_unit_t adc_n) +static inline void adc_oneshot_ll_disable_channel(adc_unit_t adc_n) { if (adc_n == ADC_UNIT_1) { SENS.sar_meas1_ctrl2.sar1_en_pad = 0; //only one channel is selected. @@ -848,9 +853,8 @@ static inline void adc_ll_rtc_disable_channel(adc_unit_t adc_n) * @note It may be block to wait conversion idle for ADC1. * * @param adc_n ADC unit. - * @param channel ADC channel number for each ADCn. */ -static inline void adc_ll_rtc_start_convert(adc_unit_t adc_n, int channel) +static inline void adc_oneshot_ll_start(adc_unit_t adc_n) { if (adc_n == ADC_UNIT_1) { while (HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_slave_addr1, meas_status) != 0) {} @@ -863,20 +867,33 @@ static inline void adc_ll_rtc_start_convert(adc_unit_t adc_n, int channel) } /** - * Check the conversion done flag for each ADCn for RTC controller. + * Clear the event for each ADCn for Oneshot mode + * + * @param event ADC event + */ +static inline void adc_oneshot_ll_clear_event(uint32_t event) +{ + //For compatibility +} + +/** + * Check the event for each ADCn for Oneshot mode + * + * @param event ADC event * - * @param adc_n ADC unit. * @return * -true : The conversion process is finish. * -false : The conversion process is not finish. */ -static inline bool adc_ll_rtc_convert_is_done(adc_unit_t adc_n) +static inline bool adc_oneshot_ll_get_event(uint32_t event) { bool ret = true; - if (adc_n == ADC_UNIT_1) { + if (event == ADC_LL_EVENT_ADC1_ONESHOT_DONE) { ret = (bool)SENS.sar_meas1_ctrl2.meas1_done_sar; - } else { // adc_n == ADC_UNIT_2 + } else if (event == ADC_LL_EVENT_ADC2_ONESHOT_DONE) { ret = (bool)SENS.sar_meas2_ctrl2.meas2_done_sar; + } else { + HAL_ASSERT(false); } return ret; } @@ -888,9 +905,9 @@ static inline bool adc_ll_rtc_convert_is_done(adc_unit_t adc_n) * @return * - Converted value. */ -static inline int adc_ll_rtc_get_convert_value(adc_unit_t adc_n) +static inline uint32_t adc_oneshot_ll_get_raw_result(adc_unit_t adc_n) { - int ret_val = 0; + uint32_t ret_val = 0; if (adc_n == ADC_UNIT_1) { ret_val = HAL_FORCE_READ_U32_REG_FIELD(SENS.sar_meas1_ctrl2, meas1_data_sar); } else { // adc_n == ADC_UNIT_2 @@ -899,13 +916,37 @@ static inline int adc_ll_rtc_get_convert_value(adc_unit_t adc_n) return ret_val; } +/** + * Analyze whether the obtained raw data is correct. + * ADC2 can use arbiter. The arbitration result can be judged by the flag bit in the original data. + * + * @param adc_n ADC unit. + * @param raw ADC raw data input (convert value). + * @return + * - true: raw data is valid + * - false: raw data is invalid + */ +static inline bool adc_oneshot_ll_raw_check_valid(adc_unit_t adc_n, uint32_t raw) +{ + if (adc_n == ADC_UNIT_1) { + return true; + } + adc_ll_rtc_output_data_t *temp = (adc_ll_rtc_output_data_t *)&raw; + if (temp->flag == 0) { + return true; + } else { + //Could be ADC_LL_RTC_CTRL_UNSELECTED, ADC_LL_RTC_CTRL_BREAK or ADC_LL_RTC_DATA_FAIL + return false; + } +} + /** * ADC module RTC output data invert or not. * * @param adc_n ADC unit. * @param inv_en data invert or not. */ -static inline void adc_ll_rtc_output_invert(adc_unit_t adc_n, bool inv_en) +static inline void adc_oneshot_ll_output_invert(adc_unit_t adc_n, bool inv_en) { if (adc_n == ADC_UNIT_1) { SENS.sar_reader1_ctrl.sar1_data_inv = inv_en; // Enable / Disable ADC data invert @@ -966,36 +1007,6 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) SENS.sar_reader2_ctrl.sar2_wait_arb_cycle = cycle; } -/** - * Analyze whether the obtained raw data is correct. - * ADC2 can use arbiter. The arbitration result can be judged by the flag bit in the original data. - * - * @param adc_n ADC unit. - * @param raw_data ADC raw data input (convert value). - * @return - * - 0: The data is correct to use. - * - 1: The data is invalid. The current controller is not enabled by the arbiter. - * - 2: The data is invalid. The current controller process was interrupted by a higher priority controller. - * - -1: The data is error. - */ -static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_unit_t adc_n, uint16_t raw_data) -{ - /* ADC1 don't need check data */ - if (adc_n == ADC_UNIT_1) { - return ADC_RTC_DATA_OK; - } - adc_ll_rtc_output_data_t *temp = (adc_ll_rtc_output_data_t *)&raw_data; - if (temp->flag == 0) { - return ADC_RTC_DATA_OK; - } else if (temp->flag == 1) { - return ADC_RTC_CTRL_UNSELECTED; - } else if (temp->flag == 2) { - return ADC_RTC_CTRL_BREAK; - } else { - return ADC_RTC_DATA_FAIL; - } -} - /** * Set the attenuation of a particular channel on ADCn. * @@ -1029,7 +1040,7 @@ static inline adc_ll_rtc_raw_data_t adc_ll_rtc_analysis_raw_data(adc_unit_t adc_ * @param channel ADCn channel number. * @param atten The attenuation option. */ -static inline void adc_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) +static inline void adc_oneshot_ll_set_atten(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten) { if (adc_n == ADC_UNIT_1) { SENS.sar_atten1 = ( SENS.sar_atten1 & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2)); @@ -1066,6 +1077,25 @@ static inline uint32_t adc_ll_adc2_read(void) return (APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff); } +/** + * Enable oneshot conversion trigger + * + * @param adc_n Not used, for compatibility + */ +static inline void adc_oneshot_ll_enable(adc_unit_t adc_n) +{ + (void)adc_n; + //For compatibility +} + +/** + * Disable oneshot conversion trigger for all the ADC units + */ +static inline void adc_oneshot_ll_disable_all_unit(void) +{ + //For compatibility +} + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index 258a6e89bd..381b3fb5c6 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -102,22 +102,6 @@ typedef struct adc_hal_digi_ctrlr_cfg_t { */ #define adc_hal_set_power_manage(manage) adc_ll_set_power_manage(manage) -#if SOC_ADC_ARBITER_SUPPORTED -//No ADC2 controller arbiter on ESP32 -/** - * Config ADC2 module arbiter. - * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, - * the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data. - * - * @note Only ADC2 support arbiter. - * @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode. - * @note Default priority: Wi-Fi > RTC > Digital; - * - * @param config Refer to ``adc_arbiter_t``. - */ -void adc_hal_arbiter_config(adc_arbiter_t *config); -#endif //#if SOC_ADC_ARBITER_SUPPORTED - /*--------------------------------------------------------------- PWDET(Power detect) controller setting ---------------------------------------------------------------*/ @@ -251,55 +235,6 @@ void adc_hal_digi_stop(adc_hal_dma_ctx_t *hal); /*--------------------------------------------------------------- ADC Single Read ---------------------------------------------------------------*/ -#if SOC_ADC_RTC_CTRL_SUPPORTED -/** - * Set the attenuation of a particular channel on ADCn. - * - * @note For any given channel, this function must be called before the first time conversion. - * - * The default ADC full-scale voltage is 1.1V. To read higher voltages (up to the pin maximum voltage, - * usually 3.3V) requires setting >0dB signal attenuation for that ADC channel. - * - * When VDD_A is 3.3V: - * - * - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V - * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V - * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V - * - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below) - * - * @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured - * bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.) - * - * @note At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage. - * - * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges: - * - * - 0dB attenuaton (ADC_ATTEN_DB_0) between 100 and 950mV - * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV - * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV - * - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV - * - * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. - * - * @param adc_n ADC unit. - * @param channel ADCn channel number. - * @param atten ADC attenuation. See ``adc_atten_t`` - */ -#define adc_hal_set_atten(adc_n, channel, atten) adc_ll_set_atten(adc_n, channel, atten) - -#else // #if !SOC_ADC_RTC_CTRL_SUPPORTED -/** - * Set the attenuation for ADC to single read - * - * @note All ADC units and channels will share the setting. So PLEASE DO save your attenuations and reset them by calling this API again in your driver - * - * @param adc_n Not used, leave here for chip version compatibility - * @param channel Not used, leave here for chip version compatibility - * @param atten ADC attenuation. See ``adc_atten_t`` - */ -#define adc_hal_set_atten(adc_n, channel, atten) adc_ll_onetime_set_atten(atten) -#endif //#if SOC_ADC_RTC_CTRL_SUPPORTED - /** * Start an ADC conversion and get the converted value. * @@ -315,65 +250,6 @@ void adc_hal_digi_stop(adc_hal_dma_ctx_t *hal); */ esp_err_t adc_hal_convert(adc_unit_t adc_n, int channel, int *out_raw); -/*--------------------------------------------------------------- - ADC calibration setting ----------------------------------------------------------------*/ -#if SOC_ADC_CALIBRATION_V1_SUPPORTED - -/** - * @brief Initialize default parameter for the calibration block. - * - * @param adc_n ADC index numer - */ -void adc_hal_calibration_init(adc_unit_t adc_n); - -/** - * Set the calibration result (initial data) to ADC. - * - * @note Different ADC units and different attenuation options use different calibration data (initial data). - * - * @param adc_n ADC index number. - * @param param the calibration parameter to configure - */ -void adc_hal_set_calibration_param(adc_unit_t adc_n, uint32_t param); - -/** - * Calibrate the ADC using internal connections. - * - * @note Different ADC units and different attenuation options use different calibration data (initial data). - * - * @param adc_n ADC index number. - * @param channel adc channel number. - * @param atten The attenuation for the channel - * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. - * false: Use IO external voltage as calibration voltage. - * - * @return - * - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set. - */ -uint32_t adc_hal_self_calibration(adc_unit_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd); - -#endif //SOC_ADC_CALIBRATION_V1_SUPPORTED - - -/*--------------------------------------------------------------- - RTC controller setting ----------------------------------------------------------------*/ -/** - * Set adc output data format for RTC controller. - * - * @prarm adc_n ADC unit. - * @prarm bits Output data bits width option. - */ -#define adc_hal_rtc_set_output_format(adc_n, bits) adc_ll_rtc_set_output_format(adc_n, bits) - -/** - * ADC module output data invert or not. - * - * @prarm adc_n ADC unit. - */ -#define adc_hal_rtc_output_invert(adc_n, inv_en) adc_ll_rtc_output_invert(adc_n, inv_en) - #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/adc_hal_common.h b/components/hal/include/hal/adc_hal_common.h index 1349662f22..9329220805 100644 --- a/components/hal/include/hal/adc_hal_common.h +++ b/components/hal/include/hal/adc_hal_common.h @@ -6,10 +6,14 @@ #pragma once +#include "hal/adc_types.h" +#include "hal/adc_types_private.h" + #ifdef __cplusplus extern "C" { #endif + /** * This header file is only for hardware abstract concepts and APIs * used by both ADC RTC controller and Digital controller @@ -33,6 +37,62 @@ typedef enum adc_hal_work_mode_t { */ void adc_hal_set_controller(adc_unit_t unit, adc_hal_work_mode_t work_mode); +#if SOC_ADC_ARBITER_SUPPORTED +//No ADC2 controller arbiter on ESP32 +/** + * Config ADC2 module arbiter. + * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, + * the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data. + * + * @note Only ADC2 support arbiter. + * @note The arbiter's working clock is APB_CLK. When the APB_CLK clock drops below 8 MHz, the arbiter must be in shield mode. + * @note Default priority: Wi-Fi > RTC > Digital; + * + * @param config Refer to ``adc_arbiter_t``. + */ +void adc_hal_arbiter_config(adc_arbiter_t *config); +#endif //#if SOC_ADC_ARBITER_SUPPORTED + +/*--------------------------------------------------------------- + ADC calibration setting +---------------------------------------------------------------*/ +#if SOC_ADC_CALIBRATION_V1_SUPPORTED + +/** + * @brief Initialize default parameter for the calibration block. + * + * @param adc_n ADC index numer + */ +void adc_hal_calibration_init(adc_unit_t adc_n); + +/** + * Set the calibration result (initial data) to ADC. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + * @param param the calibration parameter to configure + */ +void adc_hal_set_calibration_param(adc_unit_t adc_n, uint32_t param); + +/** + * Calibrate the ADC using internal connections. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + * @param atten ADC attenuation + * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. + * false: Use IO external voltage as calibration voltage. + * + * @return + * - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set. + */ +uint32_t adc_hal_self_calibration(adc_unit_t adc_n, adc_atten_t atten, bool internal_gnd); + +#endif //SOC_ADC_CALIBRATION_V1_SUPPORTED + + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index 7067ebbfc2..7de8872443 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -12,43 +12,37 @@ #include "esp_attr.h" /** - * @brief ADC unit enumeration. - * - * @note For ADC digital controller (DMA mode), ESP32 doesn't support `ADC_UNIT_2`, `ADC_UNIT_BOTH`, `ADC_UNIT_ALTER`. + * @brief ADC unit */ typedef enum { - ADC_UNIT_1, /*!< SAR ADC 1. */ - ADC_UNIT_2, /*!< SAR ADC 2. */ + ADC_UNIT_1, ///< SAR ADC 1 + ADC_UNIT_2, ///< SAR ADC 2 } adc_unit_t; /** - * @brief ADC channels handle. See ``adc1_channel_t``, ``adc2_channel_t``. - * - * @note For ESP32 ADC1, don't use `ADC_CHANNEL_8`, `ADC_CHANNEL_9`. See ``adc1_channel_t``. + * @brief ADC channels */ typedef enum { - ADC_CHANNEL_0 = 0, /*!< ADC channel */ - ADC_CHANNEL_1, /*!< ADC channel */ - ADC_CHANNEL_2, /*!< ADC channel */ - ADC_CHANNEL_3, /*!< ADC channel */ - ADC_CHANNEL_4, /*!< ADC channel */ - ADC_CHANNEL_5, /*!< ADC channel */ - ADC_CHANNEL_6, /*!< ADC channel */ - ADC_CHANNEL_7, /*!< ADC channel */ - ADC_CHANNEL_8, /*!< ADC channel */ - ADC_CHANNEL_9, /*!< ADC channel */ - ADC_CHANNEL_MAX, + ADC_CHANNEL_0, ///< ADC channel + ADC_CHANNEL_1, ///< ADC channel + ADC_CHANNEL_2, ///< ADC channel + ADC_CHANNEL_3, ///< ADC channel + ADC_CHANNEL_4, ///< ADC channel + ADC_CHANNEL_5, ///< ADC channel + ADC_CHANNEL_6, ///< ADC channel + ADC_CHANNEL_7, ///< ADC channel + ADC_CHANNEL_8, ///< ADC channel + ADC_CHANNEL_9, ///< ADC channel } adc_channel_t; /** * @brief ADC attenuation parameter. Different parameters determine the range of the ADC. See ``adc1_config_channel_atten``. */ typedef enum { - ADC_ATTEN_DB_0 = 0, /*!