diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index 5e9748cd82..f1de2eb0a4 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -238,6 +238,7 @@ static IRAM_ATTR void adc_dma_intr(void *arg) s_adc_digi_ctx->hal_dma_config.desc_cnt = 0; //start next turns of dma operation + adc_hal_digi_dma_multi_descriptor(&s_adc_digi_ctx->hal_dma_config, s_adc_digi_ctx->rx_dma_buf, s_adc_digi_ctx->bytes_between_intr, s_adc_digi_ctx->hal_dma_config.desc_max_num); adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config); } @@ -326,7 +327,7 @@ esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_l data = xRingbufferReceiveUpTo(s_adc_digi_ctx->ringbuf_hdl, &size, ticks_to_wait, length_max); if (!data) { - ESP_LOGW(ADC_DMA_TAG, "No data, increase timeout or reduce conv_num_each_intr"); + ESP_LOGV(ADC_DMA_TAG, "No data, increase timeout or reduce conv_num_each_intr"); ret = ESP_ERR_TIMEOUT; *out_length = 0; return ret; @@ -340,6 +341,7 @@ esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_l if (s_adc_digi_ctx->ringbuf_overflow_flag) { ret = ESP_ERR_INVALID_STATE; } + return ret; } @@ -382,8 +384,8 @@ static adc_atten_t s_atten2_single[ADC2_CHANNEL_MAX]; //Array saving attenuat esp_err_t adc1_config_width(adc_bits_width_t width_bit) { - //On ESP32C3, the data width is always 13-bits. - if (width_bit != ADC_WIDTH_BIT_13) { + //On ESP32C3, the data width is always 12-bits. + if (width_bit != ADC_WIDTH_BIT_12) { return ESP_ERR_INVALID_ARG; } @@ -404,40 +406,41 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten) int adc1_get_raw(adc1_channel_t channel) { - int result = 0; + int raw_out = 0; adc_digi_config_t dig_cfg = { .conv_limit_en = 0, .conv_limit_num = 250, .interval = 40, .dig_clk.use_apll = 0, - .dig_clk.div_num = 1, + .dig_clk.div_num = 15, .dig_clk.div_a = 0, .dig_clk.div_b = 1, }; ADC_DIGI_LOCK_ACQUIRE(); + periph_module_enable(PERIPH_SARADC_MODULE); adc_hal_digi_controller_config(&dig_cfg); adc_hal_intr_clear(ADC_EVENT_ADC1_DONE); - adc_hal_onetime_channel(ADC_NUM_1, channel); adc_hal_set_onetime_atten(s_atten1_single[channel]); - adc_hal_adc1_onetime_sample_enable(true); //Trigger single read. + adc_hal_adc1_onetime_sample_enable(true); adc_hal_onetime_start(&dig_cfg); while (!adc_hal_intr_get_raw(ADC_EVENT_ADC1_DONE)); adc_hal_intr_clear(ADC_EVENT_ADC1_DONE); adc_hal_adc1_onetime_sample_enable(false); - result = adc_hal_adc1_read(); + adc_hal_single_read(ADC_NUM_1, &raw_out); adc_hal_digi_deinit(); + periph_module_disable(PERIPH_SARADC_MODULE); ADC_DIGI_LOCK_RELEASE(); - return result; + return raw_out; } esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) @@ -454,17 +457,18 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out) { - //On ESP32C3, the data width is always 13-bits. - if (width_bit != ADC_WIDTH_BIT_13) { + //On ESP32C3, the data width is always 12-bits. + if (width_bit != ADC_WIDTH_BIT_12) { return ESP_ERR_INVALID_ARG; } + esp_err_t ret = ESP_OK; adc_digi_config_t dig_cfg = { .conv_limit_en = 0, .conv_limit_num = 250, .interval = 40, .dig_clk.use_apll = 0, - .dig_clk.div_num = 1, + .dig_clk.div_num = 15, .dig_clk.div_a = 0, .dig_clk.div_b = 1, }; @@ -472,23 +476,27 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * SAC_ADC2_LOCK_ACQUIRE(); ADC_DIGI_LOCK_ACQUIRE(); + periph_module_enable(PERIPH_SARADC_MODULE); adc_hal_digi_controller_config(&dig_cfg); adc_hal_intr_clear(ADC_EVENT_ADC2_DONE); - adc_hal_onetime_channel(ADC_NUM_2, channel); adc_hal_set_onetime_atten(s_atten2_single[channel]); - adc_hal_adc2_onetime_sample_enable(true); //Trigger single read. + adc_hal_adc2_onetime_sample_enable(true); adc_hal_onetime_start(&dig_cfg); while (!adc_hal_intr_get_raw(ADC_EVENT_ADC2_DONE)); adc_hal_intr_clear(ADC_EVENT_ADC2_DONE); adc_hal_adc2_onetime_sample_enable(false); - *raw_out = adc_hal_adc2_read(); + ret = adc_hal_single_read(ADC_NUM_2, raw_out); + if (ret != ESP_OK) { + return ret; + } adc_hal_digi_deinit(); + periph_module_disable(PERIPH_SARADC_MODULE); ADC_DIGI_LOCK_RELEASE(); SAC_ADC2_LOCK_RELEASE(); @@ -547,12 +555,12 @@ esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config) * @note For ADC1, Controller access is mutually exclusive. * * @param adc_unit ADC unit. - * @param ctrl ADC controller, Refer to `adc_ll_controller_t`. + * @param ctrl ADC controller, Refer to `adc_controller_t`. * * @return * - ESP_OK Success */ -esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_ll_controller_t ctrl) +esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_controller_t ctrl) { adc_arbiter_t config = {0}; adc_arbiter_t cfg = ADC_ARBITER_CONFIG_DEFAULT(); @@ -611,22 +619,54 @@ esp_err_t adc_digi_reset(void) esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx) { - abort(); // TODO ESP32-C3 IDF-2528 + ADC_ENTER_CRITICAL(); + if (idx == ADC_DIGI_FILTER_IDX0) { + adc_hal_digi_filter_reset(ADC_NUM_1); + } else if (idx == ADC_DIGI_FILTER_IDX1) { + adc_hal_digi_filter_reset(ADC_NUM_2); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; } esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config) { - abort(); // TODO ESP32-C3 IDF-2528 + ADC_ENTER_CRITICAL(); + if (idx == ADC_DIGI_FILTER_IDX0) { + adc_hal_digi_filter_set_factor(ADC_NUM_1, config->mode); + } else if (idx == ADC_DIGI_FILTER_IDX1) { + adc_hal_digi_filter_set_factor(ADC_NUM_2, config->mode); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; } esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config) { - abort(); // TODO ESP32-C3 IDF-2528 + ADC_ENTER_CRITICAL(); + if (idx == ADC_DIGI_FILTER_IDX0) { + config->adc_unit = ADC_UNIT_1; + config->channel = ADC_CHANNEL_MAX; + adc_hal_digi_filter_get_factor(ADC_NUM_1, &config->mode); + } else if (idx == ADC_DIGI_FILTER_IDX1) { + config->adc_unit = ADC_UNIT_2; + config->channel = ADC_CHANNEL_MAX; + adc_hal_digi_filter_get_factor(ADC_NUM_2, &config->mode); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; } esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable) { - abort(); // TODO ESP32-C3 IDF-2528 + ADC_ENTER_CRITICAL(); + if (idx == ADC_DIGI_FILTER_IDX0) { + adc_hal_digi_filter_enable(ADC_NUM_1, enable); + } else if (idx == ADC_DIGI_FILTER_IDX1) { + adc_hal_digi_filter_enable(ADC_NUM_2, enable); + } + ADC_EXIT_CRITICAL(); + return ESP_OK; } /** @@ -638,7 +678,13 @@ esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable) */ int adc_digi_filter_read_data(adc_digi_filter_idx_t idx) { - abort(); // TODO ESP32-C3 IDF-2528 + if (idx == ADC_DIGI_FILTER_IDX0) { + return adc_hal_digi_filter_read_data(ADC_NUM_1); + } else if (idx == ADC_DIGI_FILTER_IDX1) { + return adc_hal_digi_filter_read_data(ADC_NUM_2); + } else { + return -1; + } } /**************************************/ diff --git a/components/driver/esp32c3/include/driver/adc.h b/components/driver/esp32c3/include/driver/adc.h index 463778a3a9..fc8b59412d 100644 --- a/components/driver/esp32c3/include/driver/adc.h +++ b/components/driver/esp32c3/include/driver/adc.h @@ -186,6 +186,39 @@ esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_fl */ esp_err_t adc_digi_isr_deregister(void); +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ + +/*--------------------------------------------------------------- + Deprecated API +---------------------------------------------------------------*/ +/** + * @brief Set I2S data source + * + * @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC. + * + * @deprecated The ESP32C3 doesn't use I2S DMA. Call ``adc_digi_controller_config`` instead. + * + * @return + * - ESP_OK success + */ +esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src) __attribute__((deprecated)); + +/** + * @brief Initialize I2S ADC mode + * + * @param adc_unit ADC unit index + * @param channel ADC channel index + * + * @deprecated The ESP32C3 doesn't use I2S DMA. Call ``adc_digi_controller_config`` instead. + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel) __attribute__((deprecated)); + #ifdef __cplusplus } #endif diff --git a/components/driver/include/driver/adc_common.h b/components/driver/include/driver/adc_common.h index cbdd377b66..5eafc8d508 100644 --- a/components/driver/include/driver/adc_common.h +++ b/components/driver/include/driver/adc_common.h @@ -37,7 +37,8 @@ typedef enum { ADC1_CHANNEL_7, /*!< ADC1 channel 7 is GPIO35 */ ADC1_CHANNEL_MAX, } adc1_channel_t; -#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 // TODO ESP32-S3 channels are wrong IDF-1776 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +//S3 is not sure. Need to be checked when bringing up S3 /**** `adc1_channel_t` will be deprecated functions, combine into `adc_channel_t` ********/ typedef enum { ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO1 */ @@ -62,9 +63,10 @@ typedef enum { ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO34 */ ADC1_CHANNEL_MAX, } adc1_channel_t; -#endif // CONFIG_IDF_TARGET_* +#endif -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 // TODO ESP32-S3 channels are wrong IDF-1776 +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +//S3 is not sure. Need to be checked when bringing up S3 /**** `adc2_channel_t` will be deprecated functions, combine into `adc_channel_t` ********/ typedef enum { ADC2_CHANNEL_0 = 0, /*!< ADC2 channel 0 is GPIO4 (ESP32), GPIO11 (ESP32-S2) */ @@ -141,32 +143,14 @@ typedef struct adc_digi_init_config_s { /** * @brief Enable ADC power - * @deprecated Use adc_power_acquire and adc_power_release instead. */ -void adc_power_on(void) __attribute__((deprecated)); +void adc_power_on(void); /** * @brief Power off SAR ADC - * @deprecated Use adc_power_acquire and adc_power_release instead. - * This function will force power down for ADC. - * This function is deprecated because forcing power ADC power off may - * disrupt operation of other components which may be using the ADC. + * This function will force power down for ADC */ -void adc_power_off(void) __attribute__((deprecated)); - -/** - * @brief Increment the usage counter for ADC module. - * ADC will stay powered on while the counter is greater than 0. - * Call adc_power_release when done using the ADC. - */ -void adc_power_acquire(void); - -/** - * @brief Decrement the usage counter for ADC module. - * ADC will stay powered on while the counter is greater than 0. - * Call this function when done using the ADC. - */ -void adc_power_release(void); +void adc_power_off(void); /** * @brief Initialize ADC pad @@ -258,8 +242,6 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit); * the input of GPIO36 and GPIO39 will be pulled down for about 80ns. * When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39. * Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue. - * As a workaround, call adc_power_acquire() in the app. This will result in higher power consumption (by ~1mA), - * but will remove the glitches on GPIO36 and GPIO39. * * @note Call ``adc1_config_width()`` before the first time this * function is called. @@ -385,9 +367,6 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten); * the input of GPIO36 and GPIO39 will be pulled down for about 80ns. * When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39. * Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue. - * As a workaround, call adc_power_acquire() in the app. This will result in higher power consumption (by ~1mA), - * but will remove the glitches on GPIO36 and GPIO39. - * * * @note ESP32: * For a given channel, ``adc2_config_channel_atten()`` diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 68e3cbfac6..b3b5b2305a 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -30,11 +30,11 @@ if(NOT BOOTLOADER_BUILD) "sha_hal.c" "aes_hal.c" "twai_hal.c" - "twai_hal_iram.c") + "twai_hal_iram.c" + "adc_hal.c") if(${target} STREQUAL "esp32") list(APPEND srcs - "adc_hal.c" "dac_hal.c" "mcpwm_hal.c" "pcnt_hal.c" @@ -52,7 +52,6 @@ if(NOT BOOTLOADER_BUILD) if(${target} STREQUAL "esp32s2") list(APPEND srcs - "adc_hal.c" "dac_hal.c" "pcnt_hal.c" "spi_flash_hal_gpspi.c" @@ -70,7 +69,6 @@ if(NOT BOOTLOADER_BUILD) if(${target} STREQUAL "esp32s3") list(APPEND srcs - "adc_hal.c" "dac_hal.c" "gdma_hal.c" "pcnt_hal.c" diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 787bc71039..00647c2fb9 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -15,6 +15,7 @@ #include "hal/adc_hal.h" #include "hal/adc_hal_conf.h" + #if CONFIG_IDF_TARGET_ESP32C3 #include "soc/soc.h" #include "esp_rom_sys.h" @@ -123,7 +124,7 @@ void adc_hal_digi_init(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t adc_dma_ctx->dev = &GDMA; gdma_ll_enable_clock(adc_dma_ctx->dev, true); gdma_ll_clear_interrupt_status(adc_dma_ctx->dev, dma_config->dma_chan, UINT32_MAX); - gdma_ll_rx_connect_to_periph(adc_dma_ctx->dev, dma_config->dma_chan, SOC_GDMA_TRIG_PERIPH_ADC0); + gdma_ll_rx_connect_to_periph(adc_dma_ctx->dev, dma_config->dma_chan, GDMA_LL_TRIG_SRC_ADC_DAC); } /*--------------------------------------------------------------- @@ -183,14 +184,17 @@ void adc_hal_set_onetime_atten(adc_atten_t atten) adc_ll_onetime_set_atten(atten); } -uint32_t adc_hal_adc1_read(void) +esp_err_t adc_hal_single_read(adc_ll_num_t unit, int *out_raw) { - return adc_ll_adc1_read(); -} - -uint32_t adc_hal_adc2_read(void) -{ - return adc_ll_adc2_read(); + if (unit == ADC_NUM_1) { + *out_raw = adc_ll_adc1_read(); + } else if (unit == ADC_NUM_2) { + *out_raw = adc_ll_adc2_read(); + if (adc_ll_rtc_analysis_raw_data(unit, *out_raw)) { + return ESP_ERR_INVALID_STATE; + } + } + return ESP_OK; } //--------------------INTR------------------------------- diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index 4e923babb5..9ccbc355c5 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -20,8 +20,6 @@ #include "soc/apb_saradc_struct.h" #include "soc/apb_saradc_reg.h" #include "soc/rtc_cntl_struct.h" -#include "soc/rtc_cntl_reg.h" -#include "regi2c_ctrl.h" #include "esp_attr.h" @@ -29,6 +27,8 @@ extern "C" { #endif +#define ADC_LL_ADC2_CHANNEL_MAX 1 + typedef enum { ADC_NUM_1 = 0, /*!< SAR ADC 1 */ ADC_NUM_2 = 1, /*!< SAR ADC 2 */ @@ -75,7 +75,7 @@ typedef struct { }; uint16_t val; }; -} adc_ll_rtc_output_data_t; +} adc_rtc_output_data_t; #ifdef _MSC_VER #pragma pack(pop) @@ -95,7 +95,7 @@ typedef enum { ADC2_CTRL_FORCE_PWDET = 3, /*!> 13) >= ADC_LL_ADC2_CHANNEL_MAX) { + return ADC_RTC_DATA_FAIL; + } + + return ADC_RTC_DATA_OK; } /*--------------------------------------------------------------- @@ -720,7 +863,18 @@ static inline void adc_ll_set_power_manage(adc_ll_power_t manage) */ static inline adc_ll_power_t adc_ll_get_power_manage(void) { - abort(); // TODO ESP32-C3 IDF-2094 + /* Bit1 0:Fsm 1: SW mode + Bit0 0:SW mode power down 1: SW mode power on */ + // adc_ll_power_t manage; + // if (SENS.sar_power_xpd_sar.force_xpd_sar == SENS_FORCE_XPD_SAR_PU) { + // manage = ADC_POWER_SW_ON; + // } else if (SENS.sar_power_xpd_sar.force_xpd_sar == SENS_FORCE_XPD_SAR_PD) { + // manage = ADC_POWER_SW_OFF; + // } else { + // manage = ADC_POWER_BY_FSM; + // } + // return manage; + return 0; } /** @@ -730,7 +884,11 @@ static inline adc_ll_power_t adc_ll_get_power_manage(void) */ static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div) { - abort(); // TODO ESP32-C3 IDF-2094 + // if (adc_n == ADC_NUM_1) { + // SENS.sar_reader1_ctrl.sar1_clk_div = div; + // } else { // adc_n == ADC_NUM_2 + // SENS.sar_reader2_ctrl.sar2_clk_div = div; + // } } /** @@ -768,7 +926,11 @@ static inline void adc_ll_set_sar_clk_div(adc_ll_num_t adc_n, uint32_t div) */ static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten) { - abort(); // TODO ESP32-C3 IDF-2094 + // if (adc_n == ADC_NUM_1) { + // SENS.sar_atten1 = ( SENS.sar_atten1 & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2)); + // } else { // adc_n == ADC_NUM_2 + // SENS.sar_atten2 = ( SENS.sar_atten2 & ~(0x3 << (channel * 2)) ) | ((atten & 0x3) << (channel * 2)); + // } } /** @@ -780,7 +942,12 @@ static inline void adc_ll_set_atten(adc_ll_num_t adc_n, adc_channel_t channel, a */ static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t channel) { - abort(); // TODO ESP32-C3 IDF-2094 + abort(); // FIXME + // if (adc_n == ADC_NUM_1) { + // return (adc_atten_t)((SENS.sar_atten1 >> (channel * 2)) & 0x3); + // } else { + // return (adc_atten_t)((SENS.sar_atten2 >> (channel * 2)) & 0x3); + // } } /** @@ -793,9 +960,43 @@ static inline adc_atten_t adc_ll_get_atten(adc_ll_num_t adc_n, adc_channel_t cha * @param adc_n ADC unit. * @param ctrl ADC controller. */ -static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t ctrl) +static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_controller_t ctrl) { - abort(); // TODO ESP32-C3 IDF-2094 + //NOTE: ULP is removed on C3, please remove ULP related (if there still are any) code and this comment + + // if (adc_n == ADC_NUM_1) { + // switch ( ctrl ) { + // case ADC_CTRL_RTC: + // SENS.sar_meas1_mux.sar1_dig_force = 0; // 1: Select digital control; 0: Select RTC control. + // SENS.sar_meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + // SENS.sar_meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + // break; + // case ADC_CTRL_DIG: + // SENS.sar_meas1_mux.sar1_dig_force = 1; // 1: Select digital control; 0: Select RTC control. + // SENS.sar_meas1_ctrl2.meas1_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + // SENS.sar_meas1_ctrl2.sar1_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + // break; + // default: + // break; + // } + // } else { // adc_n == ADC_NUM_2 + // switch ( ctrl ) { + // case ADC_CTRL_RTC: + // SENS.sar_meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + // SENS.sar_meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + // break; + // case ADC_CTRL_DIG: + // SENS.sar_meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + // SENS.sar_meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + // break; + // case ADC2_CTRL_PWDET: // currently only used by Wi-Fi + // SENS.sar_meas2_ctrl2.meas2_start_force = 1; // 1: SW control RTC ADC start; 0: ULP control RTC ADC start. + // SENS.sar_meas2_ctrl2.sar2_en_pad_force = 1; // 1: SW control RTC ADC bit map; 0: ULP control RTC ADC bit map; + // break; + // default: + // break; + // } + // } } /** @@ -877,7 +1078,7 @@ static inline void adc_ll_set_arbiter_priority(uint8_t pri_rtc, uint8_t pri_dig, */ static inline void adc_ll_enable_sleep_controller(void) { - abort(); // TODO ESP32-C3 IDF-2094 + // SENS.sar_meas2_mux.sar2_rtc_force = 1; } /** @@ -891,10 +1092,51 @@ static inline void adc_ll_enable_sleep_controller(void) */ static inline void adc_ll_disable_sleep_controller(void) { - abort(); // TODO ESP32-C3 IDF-2094 + // SENS.sar_meas2_mux.sar2_rtc_force = 0; } /* ADC calibration code. */ +#include "soc/rtc_cntl_reg.h" +#include "regi2c_ctrl.h" + +#define I2C_ADC 0X69 +#define I2C_ADC_HOSTID 0 + +#define ANA_CONFIG2_REG 0x6000E048 +#define ANA_CONFIG2_M (BIT(18)) + +#define SAR1_ENCAL_GND_ADDR 0x7 +#define SAR1_ENCAL_GND_ADDR_MSB 5 +#define SAR1_ENCAL_GND_ADDR_LSB 5 + +#define SAR2_ENCAL_GND_ADDR 0x7 +#define SAR2_ENCAL_GND_ADDR_MSB 7 +#define SAR2_ENCAL_GND_ADDR_LSB 7 + +#define SAR1_INITIAL_CODE_HIGH_ADDR 0x1 +#define SAR1_INITIAL_CODE_HIGH_ADDR_MSB 0x3 +#define SAR1_INITIAL_CODE_HIGH_ADDR_LSB 0x0 + +#define SAR1_INITIAL_CODE_LOW_ADDR 0x0 +#define SAR1_INITIAL_CODE_LOW_ADDR_MSB 0x7 +#define SAR1_INITIAL_CODE_LOW_ADDR_LSB 0x0 + +#define SAR2_INITIAL_CODE_HIGH_ADDR 0x4 +#define SAR2_INITIAL_CODE_HIGH_ADDR_MSB 0x3 +#define SAR2_INITIAL_CODE_HIGH_ADDR_LSB 0x0 + +#define SAR2_INITIAL_CODE_LOW_ADDR 0x3 +#define SAR2_INITIAL_CODE_LOW_ADDR_MSB 0x7 +#define SAR2_INITIAL_CODE_LOW_ADDR_LSB 0x0 + +#define SAR1_DREF_ADDR 0x2 +#define SAR1_DREF_ADDR_MSB 0x6 +#define SAR1_DREF_ADDR_LSB 0x4 + +#define SAR2_DREF_ADDR 0x5 +#define SAR2_DREF_ADDR_MSB 0x6 +#define SAR2_DREF_ADDR_LSB 0x4 + #define ADC_HAL_CAL_OFFSET_RANGE (4096) #define ADC_HAL_CAL_TIMES (10) @@ -910,7 +1152,30 @@ static inline void adc_ll_disable_sleep_controller(void) */ static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t channel, bool internal_gnd) { - abort(); // TODO ESP32-C3 IDF-2526 + // /* Enable i2s_write_reg function. */ + // void phy_get_romfunc_addr(void); + // phy_get_romfunc_addr(); + // //CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M); + // //SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M); + // CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18)); + // SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16)); + + // /* Enable/disable internal connect GND (for calibration). */ + // if (adc_n == ADC_NUM_1) { + // REGI2C_WRITE_MASK(I2C_ADC, SAR1_DREF_ADDR, 4); + // if (internal_gnd) { + // REGI2C_WRITE_MASK(I2C_ADC, SAR1_ENCAL_GND_ADDR, 1); + // } else { + // REGI2C_WRITE_MASK(I2C_ADC, SAR1_ENCAL_GND_ADDR, 0); + // } + // } else { + // REGI2C_WRITE_MASK(I2C_ADC, SAR2_DREF_ADDR, 4); + // if (internal_gnd) { + // REGI2C_WRITE_MASK(I2C_ADC, SAR2_ENCAL_GND_ADDR, 1); + // } else { + // REGI2C_WRITE_MASK(I2C_ADC, SAR2_ENCAL_GND_ADDR, 0); + // } + // } } /** @@ -920,7 +1185,11 @@ static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t */ static inline void adc_ll_calibration_finish(adc_ll_num_t adc_n) { - abort(); // TODO ESP32-C3 IDF-2526 + // if (adc_n == ADC_NUM_1) { + // REGI2C_WRITE_MASK(I2C_ADC, SAR1_ENCAL_GND_ADDR, 0); + // } else { + // REGI2C_WRITE_MASK(I2C_ADC, SAR2_ENCAL_GND_ADDR, 0); + // } } /** @@ -932,8 +1201,24 @@ static inline void adc_ll_calibration_finish(adc_ll_num_t adc_n) */ static inline void adc_ll_set_calibration_param(adc_ll_num_t adc_n, uint32_t param) { - abort(); // TODO ESP32-C3 IDF-2526 + // uint8_t msb = param >> 8; + // uint8_t lsb = param & 0xFF; + // /* Enable i2s_write_reg function. */ + // void phy_get_romfunc_addr(void); + // phy_get_romfunc_addr(); + // //SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M); + // CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, BIT(18)); + // SET_PERI_REG_MASK(ANA_CONFIG2_REG, BIT(16)); + + // if (adc_n == ADC_NUM_1) { + // REGI2C_WRITE_MASK(I2C_ADC, SAR1_INITIAL_CODE_HIGH_ADDR, msb); + // REGI2C_WRITE_MASK(I2C_ADC, SAR1_INITIAL_CODE_LOW_ADDR, lsb); + // } else { + // REGI2C_WRITE_MASK(I2C_ADC, SAR2_INITIAL_CODE_HIGH_ADDR, msb); + // REGI2C_WRITE_MASK(I2C_ADC, SAR2_INITIAL_CODE_LOW_ADDR, lsb); + // } } +/* Temp code end. */ /*--------------------------------------------------------------- Single Read @@ -998,7 +1283,8 @@ static inline void adc_ll_adc1_onetime_sample_dis(void) static inline uint32_t adc_ll_adc1_read(void) { - return APB_SARADC.apb_saradc1_data_status.adc1_data; + //On ESP32C3, valid data width is 12-bit + return (APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff); } //--------------------------------adc2------------------------------// @@ -1014,8 +1300,10 @@ static inline void adc_ll_adc2_onetime_sample_dis(void) static inline uint32_t adc_ll_adc2_read(void) { - return APB_SARADC.apb_saradc2_data_status.adc2_data; + //On ESP32C3, valid data width is 12-bit + return (APB_SARADC.apb_saradc2_data_status.adc2_data & 0xfff); } + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c3/include/hal/clk_gate_ll.h b/components/hal/esp32c3/include/hal/clk_gate_ll.h index f7382650d5..7af8ed61ba 100644 --- a/components/hal/esp32c3/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c3/include/hal/clk_gate_ll.h @@ -172,6 +172,7 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) case PERIPH_SHA_MODULE: case PERIPH_GDMA_MODULE: return SYSTEM_PERIP_CLK_EN1_REG; + case PERIPH_SARADC_MODULE: default: return SYSTEM_PERIP_CLK_EN0_REG; } @@ -195,6 +196,7 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) case PERIPH_SHA_MODULE: case PERIPH_GDMA_MODULE: return SYSTEM_PERIP_RST_EN1_REG; + case PERIPH_SARADC_MODULE: default: return SYSTEM_PERIP_RST_EN0_REG; } diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index ea952b6472..3ac94b26b9 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -213,6 +213,7 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg); #include "hal/dma_types.h" #include "hal/adc_ll.h" #include "hal/dma_types.h" +#include "esp_err.h" typedef struct adc_dma_hal_context_t { gdma_dev_t *dev; //address of the general DMA @@ -259,9 +260,7 @@ void adc_hal_onetime_channel(adc_ll_num_t unit, adc_channel_t channel); void adc_hal_set_onetime_atten(adc_atten_t atten); -uint32_t adc_hal_adc1_read(void); - -uint32_t adc_hal_adc2_read(void); +esp_err_t adc_hal_single_read(adc_ll_num_t unit, int *out_raw); void adc_hal_intr_enable(adc_event_t event); diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index dea8ab0ec1..eddf6a96c5 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -88,8 +88,10 @@ typedef enum { ADC_WIDTH_BIT_10 = 1, /*!< ADC capture width is 10Bit. */ ADC_WIDTH_BIT_11 = 2, /*!< ADC capture width is 11Bit. */ ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit. */ -#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 ADC_WIDTH_BIT_13 = 4, /*!< ADC capture width is 13Bit. */ +#elif CONFIG_IDF_TARGET_ESP32C3 + ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit. */ #endif ADC_WIDTH_MAX, } adc_bits_width_t; @@ -139,7 +141,7 @@ typedef struct { uint8_t reserved: 2; /*!< reserved0 */ #endif }; - uint8_t val; /*! ADC_CHANNEL_MAX), The data is invalid. */ - uint32_t unit: 1; /*! ADC_CHANNEL_MAX), The data is invalid. */ + uint32_t unit: 1; /*!) +``` +[0_1_54e](4e 25 00 00) +[0_1_548](48 25 00 00) +[0_1_556](56 25 00 00) +``` + +## Troubleshooting + +* program upload failure + + * Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs. + * The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again. + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/peripherals/adc_dma_demo/main/CMakeLists.txt b/examples/peripherals/adc_dma_demo/main/CMakeLists.txt new file mode 100644 index 0000000000..72b0d08bf0 --- /dev/null +++ b/examples/peripherals/adc_dma_demo/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "adc_dma_example_main.c" + INCLUDE_DIRS ".") diff --git a/examples/peripherals/adc_dma_demo/main/adc_dma_example_main.c b/examples/peripherals/adc_dma_demo/main/adc_dma_example_main.c new file mode 100644 index 0000000000..6bbf9655ef --- /dev/null +++ b/examples/peripherals/adc_dma_demo/main/adc_dma_example_main.c @@ -0,0 +1,117 @@ +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "driver/adc.h" + +#define TIMES 256 +#define DMA_CHANNEL 0 + +static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask, adc_channel_t *channel, uint8_t channel_num) +{ + esp_err_t ret = ESP_OK; + assert(ret == ESP_OK); + + adc_digi_init_config_t adc_dma_config = { + .max_store_buf_size = 1024, + .conv_num_each_intr = 256, + .dma_chan = SOC_GDMA_ADC_DMA_CHANNEL, + .adc1_chan_mask = adc1_chan_mask, + .adc2_chan_mask = adc2_chan_mask, + }; + ret = adc_digi_initialize(&adc_dma_config); + assert(ret == ESP_OK); + + adc_digi_pattern_table_t adc_pattern[10]; + adc_digi_config_t dig_cfg = { + .conv_limit_en = 0, + .conv_limit_num = 250, + .interval = 40, + .dig_clk.use_apll = 0, + .dig_clk.div_num = 15, + .dig_clk.div_a = 0, + .dig_clk.div_b = 1, + }; + + dig_cfg.adc_pattern_len = channel_num; + for (int i = 0; i < channel_num; i++) { + uint8_t unit = ((channel[i] >> 3) & 0x1); + uint8_t ch = channel[i] & 0x7; + adc_pattern[i].atten = ADC_ATTEN_DB_0; + adc_pattern[i].channel = ch; + adc_pattern[i].unit = unit; + } + dig_cfg.adc_pattern = adc_pattern; + ret = adc_digi_controller_config(&dig_cfg); + assert(ret == ESP_OK); +} + +static void continuous_read_demo(void *arg) +{ + esp_err_t ret; + uint32_t ret_num = 0; + uint8_t result[TIMES] = {0}; + memset(result, 0xcc, TIMES); + + uint16_t adc1_chan_mask = BIT(ADC1_CHANNEL_0) | BIT(ADC1_CHANNEL_1); + uint16_t adc2_chan_mask = BIT(ADC2_CHANNEL_0); + adc_channel_t channel[3] = {ADC1_CHANNEL_0, ADC1_CHANNEL_1, (ADC2_CHANNEL_0 | 1 << 3)}; + + continuous_adc_init(adc1_chan_mask, adc2_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t)); + adc_digi_start(); + + int n = 20; + while(n--) { + ret = adc_digi_read_bytes(result, TIMES, &ret_num, ADC_MAX_DELAY); + for (int i = 0; i < ret_num; i+=4) { + uint32_t temp = (result[i+3] << 24) | (result[i+2] << 16) | (result[i+1] << 8) | (result[i+0]); + adc_digi_output_data_t *p = (void*)&temp; + printf("[%d_%d_%x](%02x %02x %02x %02x) \n", p->type2.unit, p->type2.channel, p->type2.data, + result[i], + result[i + 1], + result[i + 2], + result[i + 3]); + } + // If you see task WDT in this task, it means the conversion is too fast for the task to handle + } + + adc_digi_stop(); + ret = adc_digi_deinitialize(); + assert(ret == ESP_OK); +} + +static void single_read_demo(void *arg) +{ + esp_err_t ret; + int adc1_reading[3] = {0xcc}; + int adc2_reading[1] = {0xcc}; + + adc1_config_width(ADC_WIDTH_BIT_12); + adc1_config_channel_atten(ADC1_CHANNEL_2, ADC_ATTEN_DB_0); + adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6); + adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0); + adc2_config_channel_atten(ADC2_CHANNEL_0, ADC_ATTEN_DB_0); + + int n = 20; + while (n--) { + + adc1_reading[0] = adc1_get_raw(ADC1_CHANNEL_2); + adc1_reading[1] = adc1_get_raw(ADC1_CHANNEL_3); + adc1_reading[2] = adc1_get_raw(ADC1_CHANNEL_4); + + for (int i = 0; i < 3; i++) { + printf("[%x]\n", adc1_reading[i]); + } + + ret = adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_BIT_12, &adc2_reading[0]); + assert(ret == ESP_OK); + printf("[%x]\n", adc2_reading[0]); + } +} + +void app_main() +{ + single_read_demo(NULL); + continuous_read_demo(NULL); +}