From 8256b5f32b039e8114275140fb4c2c692a227bc3 Mon Sep 17 00:00:00 2001 From: fuzhibo Date: Wed, 8 Apr 2020 21:56:14 +0800 Subject: [PATCH] driver(adc): fix adc io init bug; add unit test to check; --- components/driver/adc_common.c | 6 +- components/driver/test/CMakeLists.txt | 2 +- .../driver/test/adc_dma_test/test_esp32s2.c | 294 ++++++++++++++---- components/driver/test/component.mk | 2 +- components/driver/test/test_adc_common.c | 89 ++++++ .../{ => include}/touch_scope.h | 0 .../soc/soc/esp32s2/include/soc/adc_caps.h | 2 +- .../soc/src/esp32s2/include/hal/adc_hal.h | 4 +- 8 files changed, 333 insertions(+), 66 deletions(-) rename components/driver/test/touch_sensor_test/{ => include}/touch_scope.h (100%) diff --git a/components/driver/adc_common.c b/components/driver/adc_common.c index 3e7331015..e2fb84c98 100644 --- a/components/driver/adc_common.c +++ b/components/driver/adc_common.c @@ -161,7 +161,8 @@ esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel) } ADC_CHECK_RET(rtc_gpio_init(gpio_num)); ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); - ADC_CHECK_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING)); + ADC_CHECK_RET(rtc_gpio_pulldown_dis(gpio_num)); + ADC_CHECK_RET(rtc_gpio_pullup_dis(gpio_num)); return ESP_OK; } @@ -397,7 +398,8 @@ static esp_err_t adc2_pad_init(adc2_channel_t channel) ADC_CHECK_RET(adc2_pad_get_io_num(channel, &gpio_num)); ADC_CHECK_RET(rtc_gpio_init(gpio_num)); ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); - ADC_CHECK_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING)); + ADC_CHECK_RET(rtc_gpio_pulldown_dis(gpio_num)); + ADC_CHECK_RET(rtc_gpio_pullup_dis(gpio_num)); return ESP_OK; } diff --git a/components/driver/test/CMakeLists.txt b/components/driver/test/CMakeLists.txt index f099b0b6b..f79ac921c 100644 --- a/components/driver/test/CMakeLists.txt +++ b/components/driver/test/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRC_DIRS . param_test touch_sensor_test adc_dma_test dac_dma_test - PRIV_INCLUDE_DIRS include param_test/include + PRIV_INCLUDE_DIRS include param_test/include touch_sensor_test/include PRIV_REQUIRES unity test_utils driver nvs_flash esp_serial_slave_link infrared_tools) \ No newline at end of file diff --git a/components/driver/test/adc_dma_test/test_esp32s2.c b/components/driver/test/adc_dma_test/test_esp32s2.c index 14787d819..cacb54af6 100644 --- a/components/driver/test/adc_dma_test/test_esp32s2.c +++ b/components/driver/test/adc_dma_test/test_esp32s2.c @@ -62,7 +62,9 @@ static void test_pxp_deinit_io(void) TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(SENS_SARDATE_REG, SENS_SAR_DATE), SENS.sardate.sar_date); \ TEST_ASSERT_EQUAL_UINT32(REG_GET_FIELD(RTC_IO_DATE_REG, RTC_IO_IO_DATE), RTCIO.date.date); \ }) -#define TEST_ADC_TRIGGER_INTERVAL_DEFAULT (40) +/** Sample rate = APB_CLK(80 MHz) / CLK_DIV / TRIGGER_INTERVAL */ +#define TEST_ADC_TRIGGER_INTERVAL_DEFAULT (80) +#define TEST_ADC_DIGI_CLK_DIV_DEFAULT (40) #define TEST_ADC_COUNT_NUM (10) #define TEST_ADC_CHANNEL (10) static adc_channel_t adc_list[TEST_ADC_CHANNEL] = { @@ -78,13 +80,7 @@ static adc_channel_t adc_list[TEST_ADC_CHANNEL] = { ADC_CHANNEL_9, }; /* For ESP32S2, it should use same atten, or, it will have error. */ -// #define TEST_ADC_ATTEN_DEFAULT (ADC_ATTEN_11db) -static adc_atten_t adc_atten[ADC_ATTEN_MAX] = { - ADC_ATTEN_DB_0, - ADC_ATTEN_DB_2_5, - ADC_ATTEN_DB_6, - ADC_ATTEN_DB_11 -}; +#define TEST_ADC_ATTEN_DEFAULT (ADC_ATTEN_11db) /*******************************************/ /** SPI DMA INIT CODE */ /*******************************************/ @@ -102,12 +98,12 @@ typedef struct dma_link { struct dma_link *pnext; //point to the next dma linker, if this link is the last one, set it NULL. } dma_link_t; /* Work mode. - * sigle: eof_num; + * single: eof_num; * double: SAR_EOF_NUMBER/2; * alter: eof_num; * */ -#define SAR_SIMPLE_NUM 64 -#define SAR_DMA_DATA_SIZE(unit, sample_num) (SAR_EOF_NUMBER(unit, sample_num) * 2) // 1 adc -> 2 byte +#define SAR_SIMPLE_NUM 64 // Set sample number of enabled unit. +#define SAR_DMA_DATA_SIZE(unit, sample_num) (SAR_EOF_NUMBER(unit, sample_num)) // 1 adc -> 2 byte data -> 2 link buf #define SAR_EOF_NUMBER(unit, sample_num) ((sample_num) * (unit)) #define SAR_MEAS_LIMIT_NUM(unit, sample_num) (SAR_EOF_NUMBER(unit, sample_num) / unit) @@ -124,11 +120,12 @@ static void dma_linker_init(adc_unit_t adc, bool is_loop) dma1.des.length = 0; //For input buffer, this field is no use. dma1.buf = &link_buf[0][0]; - dma2.des.eof = 1; dma2.des.owner = 1; if (is_loop) { + dma2.des.eof = 0; dma2.pnext = &dma1; } else { + dma2.des.eof = 1; dma2.pnext = NULL; } dma2.des.size = SAR_DMA_DATA_SIZE((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM); @@ -142,8 +139,10 @@ static void dma_linker_init(adc_unit_t adc, bool is_loop) REG_CLR_BIT(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST_M); uint32_t dma_pointer = (uint32_t)&dma1; SET_PERI_REG_BITS(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_ADDR, dma_pointer, 0); - REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START); + REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP); + REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START); REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP); + REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START); REG_SET_BIT(SPI_DMA_INT_ENA_REG(3), SPI_IN_SUC_EOF_INT_ENA); printf("reg addr 0x%08x 0x%08x \n", SPI_DMA_IN_LINK_REG(3), dma_pointer); } @@ -152,10 +151,8 @@ static void dma_linker_restart(void) { REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP); REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START); - REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_RESTART_M); - REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_RESTART_M); - REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START); REG_CLR_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_STOP); + REG_SET_BIT(SPI_DMA_IN_LINK_REG(3), SPI_INLINK_START); adc_digi_reset(); } @@ -176,6 +173,7 @@ static void adc_fake_tie_middle(adc_unit_t adc) adc_gpio_init(ADC_UNIT_1, adc_list[i]); TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(0, adc_list[i]))); TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(0, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_set_direction(ADC_GET_IO_NUM(0, adc_list[i]), RTC_GPIO_MODE_INPUT_ONLY)); } } if (adc & ADC_UNIT_2) { @@ -183,6 +181,7 @@ static void adc_fake_tie_middle(adc_unit_t adc) adc_gpio_init(ADC_UNIT_2, adc_list[i]); TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(1, adc_list[i]))); TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(1, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_set_direction(ADC_GET_IO_NUM(1, adc_list[i]), RTC_GPIO_MODE_INPUT_ONLY)); } } vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO. @@ -195,6 +194,8 @@ static void adc_fake_tie_high(adc_unit_t adc) adc_gpio_init(ADC_UNIT_1, adc_list[i]); TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(0, adc_list[i]))); TEST_ESP_OK(rtc_gpio_pulldown_dis(ADC_GET_IO_NUM(0, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_set_direction(ADC_GET_IO_NUM(0, adc_list[i]), RTC_GPIO_MODE_OUTPUT_ONLY)); + TEST_ESP_OK(rtc_gpio_set_level(ADC_GET_IO_NUM(0, adc_list[i]), 1)); } } if (adc & ADC_UNIT_2) { @@ -202,6 +203,8 @@ static void adc_fake_tie_high(adc_unit_t adc) adc_gpio_init(ADC_UNIT_2, adc_list[i]); TEST_ESP_OK(rtc_gpio_pullup_en(ADC_GET_IO_NUM(1, adc_list[i]))); TEST_ESP_OK(rtc_gpio_pulldown_dis(ADC_GET_IO_NUM(1, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_set_direction(ADC_GET_IO_NUM(1, adc_list[i]), RTC_GPIO_MODE_OUTPUT_ONLY)); + TEST_ESP_OK(rtc_gpio_set_level(ADC_GET_IO_NUM(1, adc_list[i]), 1)); } } vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO. @@ -214,6 +217,8 @@ static void adc_fake_tie_low(adc_unit_t adc) adc_gpio_init(ADC_UNIT_1, adc_list[i]); TEST_ESP_OK(rtc_gpio_pullup_dis(ADC_GET_IO_NUM(0, adc_list[i]))); TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(0, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_set_direction(ADC_GET_IO_NUM(0, adc_list[i]), RTC_GPIO_MODE_OUTPUT_ONLY)); + TEST_ESP_OK(rtc_gpio_set_level(ADC_GET_IO_NUM(0, adc_list[i]), 0)); } } if (adc & ADC_UNIT_2) { @@ -221,6 +226,8 @@ static void adc_fake_tie_low(adc_unit_t adc) adc_gpio_init(ADC_UNIT_2, adc_list[i]); TEST_ESP_OK(rtc_gpio_pullup_dis(ADC_GET_IO_NUM(1, adc_list[i]))); TEST_ESP_OK(rtc_gpio_pulldown_en(ADC_GET_IO_NUM(1, adc_list[i]))); + TEST_ESP_OK(rtc_gpio_set_direction(ADC_GET_IO_NUM(1, adc_list[i]), RTC_GPIO_MODE_OUTPUT_ONLY)); + TEST_ESP_OK(rtc_gpio_set_level(ADC_GET_IO_NUM(1, adc_list[i]), 0)); } } vTaskDelay(10 / portTICK_RATE_MS); // To wait stable of IO. @@ -243,7 +250,7 @@ static void adc_io_normal(adc_unit_t adc) #define DEBUG_CHECK_ENABLE 0 #define DEBUG_PRINT_ENABLE 1 -#define DEBUG_CHECK_ERROR 100 +#define DEBUG_CHECK_ERROR 10 static esp_err_t adc_dma_data_check(adc_unit_t adc, int ideal_level) { @@ -253,8 +260,8 @@ static esp_err_t adc_dma_data_check(adc_unit_t adc, int ideal_level) #endif for (int cnt = 0; cnt < 2; cnt++) { ets_printf("\n[%s] link_buf[%d]: \n", __func__, cnt % 2); - for (int i = 0; i < SAR_DMA_DATA_SIZE((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM); i++, i++) { - uint16_t h = link_buf[cnt % 2][i + 1], l = link_buf[cnt % 2][i]; + for (int i = 0; i < SAR_DMA_DATA_SIZE((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM); i += 2) { + uint8_t h = link_buf[cnt % 2][i + 1], l = link_buf[cnt % 2][i]; uint16_t temp = (h << 8 | l); adc_digi_output_data_t *data = (adc_digi_output_data_t *)&temp; @@ -266,21 +273,26 @@ static esp_err_t adc_dma_data_check(adc_unit_t adc, int ideal_level) ets_printf("[%d_%d_%04x] ", data->type2.unit, data->type2.channel, data->type2.data); #endif #if DEBUG_CHECK_ENABLE - TEST_ASSERT_NOT_EQUAL(unit_old, data->type2.unit); - unit_old = data->type2.unit; - if (data->type2.channel > ADC_CHANNEL_MAX) { - printf("Data invalid [%d]\n", data->type2.channel); - continue; + if (ideal_level >= 0) { + TEST_ASSERT_NOT_EQUAL(unit_old, data->type2.unit); + unit_old = data->type2.unit; + if (data->type2.channel > ADC_CHANNEL_MAX) { + printf("Data invalid [%d]\n", data->type2.channel); + continue; + } + int cur_ch = ((ch_cnt++ / 2) % TEST_ADC_CHANNEL); + TEST_ASSERT_EQUAL( data->type2.channel, adc_list[cur_ch] ); } - int cur_ch = ((ch_cnt++ / 2) % TEST_ADC_CHANNEL); - TEST_ASSERT_EQUAL( data->type2.channel, adc_list[cur_ch] ); /*Check data channel unit*/ - if (ideal_level == 1) { + if (ideal_level == 1) { // high level TEST_ASSERT_INT_WITHIN( DEBUG_CHECK_ERROR, 0x7FF, data->type2.data ); - } else if (ideal_level == 0) { + } else if (ideal_level == 0) { // low level TEST_ASSERT_INT_WITHIN( DEBUG_CHECK_ERROR, 0, data->type2.data ); + } else if (ideal_level == 2) { // middle level + TEST_ASSERT_INT_WITHIN( 300, 1100, data->type1.data ); + } else if (ideal_level == 3) { // normal level } else { - // middle vol + // no check } #endif } else { //ADC_ENCODE_12BIT @@ -292,22 +304,19 @@ static esp_err_t adc_dma_data_check(adc_unit_t adc, int ideal_level) #endif #if DEBUG_CHECK_ENABLE /*Check data channel */ - if (ideal_level == 1) { - if (data->type1.data != 0XFFF) { - return ESP_FAIL; - } - } else if (ideal_level == 0) { - if (data->type1.data != 0) { - return ESP_FAIL; - } + if (ideal_level == 1) { // high level + TEST_ASSERT_INT_WITHIN( DEBUG_CHECK_ERROR, 0XFFF, data->type1.data ); + } else if (ideal_level == 0) { // low level + TEST_ASSERT_INT_WITHIN( DEBUG_CHECK_ERROR, 0, data->type1.data ); + } else if (ideal_level == 2) { // middle level + TEST_ASSERT_INT_WITHIN( 300, 2200, data->type1.data ); + } else if (ideal_level == 3) { // normal level } else { - if (data->type1.data == 0 || data->type1.data == 0XFFF) { - return ESP_FAIL; - } + // no check } - int cur_ch = ((i / 2) % TEST_ADC_CHANNEL); - if (data->type1.channel != adc_list[cur_ch] ) { - return ESP_FAIL; + if (ideal_level >= 0) { + int cur_ch = ((ch_cnt++) % TEST_ADC_CHANNEL); + TEST_ASSERT_EQUAL( adc_list[cur_ch], data->type1.channel ); } #endif } @@ -323,41 +332,37 @@ static esp_err_t adc_dma_data_multi_st_check(adc_unit_t adc) { ESP_LOGI(TAG, "adc IO fake tie low, test ..."); adc_fake_tie_low(adc); - TEST_ESP_OK( adc_digi_stop() ); dma_linker_restart(); - REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); TEST_ESP_OK( adc_digi_start() ); - while (0 == REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST)) {}; + while (REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST) == 0) {}; REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); - if ( ESP_OK != adc_dma_data_check(adc, 0)) { + TEST_ESP_OK( adc_digi_stop() ); + if ( adc_dma_data_check(adc, 0) != ESP_OK ) { return ESP_FAIL; } ESP_LOGI(TAG, "adc IO fake tie high, test ..."); adc_fake_tie_high(adc); - TEST_ESP_OK( adc_digi_stop() ); dma_linker_restart(); - REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); TEST_ESP_OK( adc_digi_start() ); - while (0 == REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST)) {}; + while (REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST) == 0) {}; REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); - if ( ESP_OK != adc_dma_data_check(adc, 1)) { + TEST_ESP_OK( adc_digi_stop() ); + if ( adc_dma_data_check(adc, 1) != ESP_OK ) { return ESP_FAIL; } ESP_LOGI(TAG, "adc IO fake tie middle, test ..."); adc_fake_tie_middle(adc); - TEST_ESP_OK( adc_digi_stop() ); dma_linker_restart(); - REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); TEST_ESP_OK( adc_digi_start() ); - while (0 == REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST)) {}; + while (REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST) == 0) {}; REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); - if ( ESP_OK != adc_dma_data_check(adc, 2)) { + TEST_ESP_OK( adc_digi_stop() ); + if ( adc_dma_data_check(adc, 2) != ESP_OK ) { return ESP_FAIL; } - TEST_ESP_OK( adc_digi_stop() ); adc_io_normal(adc); return ESP_OK; @@ -429,7 +434,7 @@ int test_adc_dig_dma_single_unit(adc_unit_t adc) .conv_limit_num = 0, .interval = TEST_ADC_TRIGGER_INTERVAL_DEFAULT, .dig_clk.use_apll = 0, // APB clk - .dig_clk.div_num = 2, // 80 MHz / 160 = 500 KHz + .dig_clk.div_num = TEST_ADC_DIGI_CLK_DIV_DEFAULT, // 80 MHz / 2 = 40 MHz .dig_clk.div_b = 1, .dig_clk.div_a = 1, .dma_eof_num = SAR_EOF_NUMBER((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM), @@ -441,7 +446,7 @@ int test_adc_dig_dma_single_unit(adc_unit_t adc) config.adc1_pattern_len = TEST_ADC_CHANNEL; config.adc1_pattern = adc1_patt; for (int i = 0; i < TEST_ADC_CHANNEL; i++) { - adc1_patt[i].atten = adc_atten[i%ADC_ATTEN_MAX]; + adc1_patt[i].atten = TEST_ADC_ATTEN_DEFAULT; adc1_patt[i].channel = adc_list[i]; adc_gpio_init(ADC_UNIT_1, adc_list[i]); } @@ -450,7 +455,7 @@ int test_adc_dig_dma_single_unit(adc_unit_t adc) config.adc2_pattern_len = TEST_ADC_CHANNEL; config.adc2_pattern = adc2_patt; for (int i = 0; i < TEST_ADC_CHANNEL; i++) { - adc2_patt[i].atten = adc_atten[i%ADC_ATTEN_MAX]; + adc2_patt[i].atten = TEST_ADC_ATTEN_DEFAULT; adc2_patt[i].channel = adc_list[i]; adc_gpio_init(ADC_UNIT_2, adc_list[i]); } @@ -473,10 +478,19 @@ int test_adc_dig_dma_single_unit(adc_unit_t adc) dma_linker_init(adc, false); TEST_ESP_OK( adc_check_patt_table(adc, TEST_ADC_CHANNEL, adc_list[TEST_ADC_CHANNEL - 1]) ); + ESP_LOGI(TAG, "adc IO normal, test ..."); + dma_linker_restart(); TEST_ESP_OK( adc_digi_start() ); + while (REG_GET_BIT(SPI_DMA_INT_ST_REG(3), SPI_IN_SUC_EOF_INT_ST) == 0) {}; + REG_SET_BIT(SPI_DMA_INT_CLR_REG(3), SPI_IN_SUC_EOF_INT_CLR); + TEST_ESP_OK( adc_digi_stop() ); + if ( adc_dma_data_check(adc, -1) != ESP_OK ) { + return ESP_FAIL; + } adc_dma_data_multi_st_check(adc); + TEST_ESP_OK( adc_digi_deinit() ); return 0; } @@ -491,4 +505,166 @@ TEST_CASE("ADC DMA single read", "[ADC]") test_adc_dig_dma_single_unit(ADC_UNIT_2); } +#include "touch_scope.h" +/** + * 0: ADC1 channels raw data debug. + * 1: ADC2 channels raw data debug. + */ +#define SCOPE_DEBUG_TYPE 0 +#define SCOPE_DEBUG_CHANNEL_MAX (10) +#define SCOPE_DEBUG_ENABLE (0) +#define SCOPE_UART_BUADRATE (256000) +#define SCOPE_DEBUG_FREQ_MS (50) +#define SCOPE_OUTPUT_UART (0) + +int test_adc_dig_scope_debug_unit(adc_unit_t adc) +{ + ESP_LOGI(TAG, " >> %s << ", __func__); + ESP_LOGI(TAG, " >> adc unit: %x << ", adc); + + TEST_ESP_OK( adc_digi_init() ); + /* arbiter config */ + adc_arbiter_t arb_cfg = { + .mode = ADC_ARB_MODE_FIX, + .dig_pri = 0, + .pwdet_pri = 2, + .rtc_pri = 1, + }; + TEST_ESP_OK( adc_arbiter_config(ADC_UNIT_2, &arb_cfg) ); // If you want use force + + adc_digi_config_t config = { + .conv_limit_en = false, + .conv_limit_num = 0, + .interval = TEST_ADC_TRIGGER_INTERVAL_DEFAULT, + .dig_clk.use_apll = 0, // APB clk + .dig_clk.div_num = TEST_ADC_DIGI_CLK_DIV_DEFAULT, // 80 MHz / 80 = 1 MHz + .dig_clk.div_b = 1, + .dig_clk.div_a = 1, + .dma_eof_num = SAR_EOF_NUMBER((adc > 2) ? 2 : 1, SAR_SIMPLE_NUM), + }; + /* Config pattern table */ + adc_digi_pattern_table_t adc1_patt[TEST_ADC_CHANNEL] = {0}; + adc_digi_pattern_table_t adc2_patt[TEST_ADC_CHANNEL] = {0}; + if (adc & ADC_UNIT_1) { + config.adc1_pattern_len = TEST_ADC_CHANNEL; + config.adc1_pattern = adc1_patt; + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc1_patt[i].atten = TEST_ADC_ATTEN_DEFAULT; + adc1_patt[i].channel = adc_list[i]; + adc_gpio_init(ADC_UNIT_1, adc_list[i]); + } + } + if (adc & ADC_UNIT_2) { + config.adc2_pattern_len = TEST_ADC_CHANNEL; + config.adc2_pattern = adc2_patt; + for (int i = 0; i < TEST_ADC_CHANNEL; i++) { + adc2_patt[i].atten = TEST_ADC_ATTEN_DEFAULT; + adc2_patt[i].channel = adc_list[i]; + adc_gpio_init(ADC_UNIT_2, adc_list[i]); + } + } + if (adc == ADC_UNIT_1) { + config.conv_mode = ADC_CONV_SINGLE_UNIT_1; + config.format = ADC_DIGI_FORMAT_12BIT; + } else if (adc == ADC_UNIT_2) { + config.conv_mode = ADC_CONV_SINGLE_UNIT_2; + config.format = ADC_DIGI_FORMAT_12BIT; + } else if (adc == ADC_UNIT_BOTH) { + config.conv_mode = ADC_CONV_BOTH_UNIT; + config.format = ADC_DIGI_FORMAT_11BIT; + } else if (adc == ADC_UNIT_ALTER) { + config.conv_mode = ADC_CONV_ALTER_UNIT; + config.format = ADC_DIGI_FORMAT_11BIT; + } + TEST_ESP_OK( adc_digi_controller_config(&config) ); + + dma_linker_init(adc, false); + TEST_ESP_OK( adc_check_patt_table(adc, TEST_ADC_CHANNEL, adc_list[TEST_ADC_CHANNEL - 1]) ); + + ESP_LOGI(TAG, "adc IO fake tie middle, test ..."); + adc_fake_tie_middle(adc); + + TEST_ESP_OK( adc_digi_start() ); + + return 0; +} + +static void scope_output(int adc_num, int channel, int data) +{ + static float scope_temp[TEST_ADC_CHANNEL] = {0}; // max scope channel is 10. + static int scope_cnt = 0; + /** can replace by uart log.*/ +#if SCOPE_OUTPUT_UART + static int i = 0; + if (i++ % 8 == 0) { + ets_printf("\n"); + } + ets_printf("[%d_%d_%04x] ", adc_num, channel, data); + return; +#endif +#if SCOPE_DEBUG_TYPE == 0 + if (adc_num != 0) { + return; + } +#elif SCOPE_DEBUG_TYPE == 1 + if (adc_num != 1) { + return; + } +#endif + /* adc Read */ + if (adc_num == 0) { + scope_temp[channel] = data; + if (++scope_cnt >= TEST_ADC_CHANNEL) { + scope_cnt = 0; + test_tp_print_to_scope(scope_temp, TEST_ADC_CHANNEL); + vTaskDelay(SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); + for (int i=0; i 2) ? 2 : 1, SAR_SIMPLE_NUM); i += 2) { + uint8_t h = link_buf[cnt % 2][i + 1], l = link_buf[cnt % 2][i]; + uint16_t temp = (h << 8 | l); + adc_digi_output_data_t *data = (adc_digi_output_data_t *)&temp; + if (adc > ADC_UNIT_2) { //ADC_ENCODE_11BIT + scope_output(data->type2.unit, data->type2.channel, data->type2.data); + } else { //ADC_ENCODE_12BIT + if (adc == ADC_UNIT_1) { + scope_output(0, data->type1.channel, data->type1.data); + } else if (adc == ADC_UNIT_2) { + scope_output(1, data->type1.channel, data->type1.data); + } + } + link_buf[cnt % 2][i] = 0; + link_buf[cnt % 2][i + 1] = 0; + } + } + } +} + #endif // !DISABLED_FOR_TARGETS(ESP8266, ESP32) \ No newline at end of file diff --git a/components/driver/test/component.mk b/components/driver/test/component.mk index 4ad0b5cee..a50df0f37 100644 --- a/components/driver/test/component.mk +++ b/components/driver/test/component.mk @@ -3,6 +3,6 @@ # COMPONENT_SRCDIRS += param_test touch_sensor_test adc_test -COMPONENT_PRIV_INCLUDEDIRS += param_test/include +COMPONENT_PRIV_INCLUDEDIRS += param_test/include touch_sensor_test/include COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/driver/test/test_adc_common.c b/components/driver/test/test_adc_common.c index 29122b15b..adc916000 100644 --- a/components/driver/test/test_adc_common.c +++ b/components/driver/test/test_adc_common.c @@ -28,7 +28,11 @@ static const char *TAG = "test_adc"; #define ADC1_TEST_ATTEN ADC_ATTEN_DB_11 #define ADC2_TEST_ATTEN ADC_ATTEN_DB_11 +#if CONFIG_IDF_TARGET_ESP32 #define ADC1_TEST_CHANNEL_NUM 8 +#elif CONFIG_IDF_TARGET_ESP32S2 +#define ADC1_TEST_CHANNEL_NUM 10 +#endif #define ADC2_TEST_CHANNEL_NUM 6 static const int adc1_ch[ADC1_TEST_CHANNEL_NUM] = { @@ -40,6 +44,10 @@ static const int adc1_ch[ADC1_TEST_CHANNEL_NUM] = { ADC1_CHANNEL_5, ADC1_CHANNEL_6, ADC1_CHANNEL_7, +#if CONFIG_IDF_TARGET_ESP32S2 + ADC1_CHANNEL_8, + ADC1_CHANNEL_9, +#endif }; static const int adc2_ch[ADC2_TEST_CHANNEL_NUM] = { @@ -65,6 +73,7 @@ static void adc_fake_tie_middle(adc_unit_t adc_unit, adc_channel_t channel) TEST_ESP_OK(rtc_gpio_pullup_en(gpio_num)); TEST_ESP_OK(rtc_gpio_pulldown_en(gpio_num)); TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLUP_PULLDOWN)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); } static void adc_fake_tie_high(adc_unit_t adc_unit, adc_channel_t channel) @@ -79,6 +88,8 @@ static void adc_fake_tie_high(adc_unit_t adc_unit, adc_channel_t channel) TEST_ESP_OK(rtc_gpio_pullup_en(gpio_num)); TEST_ESP_OK(rtc_gpio_pulldown_dis(gpio_num)); TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLUP_ONLY)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_OUTPUT_ONLY)); + TEST_ESP_OK(rtc_gpio_set_level(gpio_num, 1)); } static void adc_fake_tie_low(adc_unit_t adc_unit, adc_channel_t channel) @@ -93,6 +104,8 @@ static void adc_fake_tie_low(adc_unit_t adc_unit, adc_channel_t channel) TEST_ESP_OK(rtc_gpio_pullup_dis(gpio_num)); TEST_ESP_OK(rtc_gpio_pulldown_en(gpio_num)); TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_PULLDOWN_ONLY)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_OUTPUT_ONLY)); + TEST_ESP_OK(rtc_gpio_set_level(gpio_num, 0)); } static void adc_io_normal(adc_unit_t adc_unit, adc_channel_t channel) @@ -107,6 +120,7 @@ static void adc_io_normal(adc_unit_t adc_unit, adc_channel_t channel) TEST_ESP_OK(rtc_gpio_pullup_dis(gpio_num)); TEST_ESP_OK(rtc_gpio_pulldown_dis(gpio_num)); TEST_ESP_OK(gpio_set_pull_mode(gpio_num, GPIO_FLOATING)); + TEST_ESP_OK(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED)); } TEST_CASE("ADC1 rtc read", "[adc1]") @@ -177,6 +191,7 @@ TEST_CASE("ADC1 rtc read", "[adc1]") adc1_val[i] = adc1_get_raw((adc1_channel_t)adc1_ch[i]); printf("CH%d-%d ", adc1_ch[i], adc1_val[i]); #ifdef CONFIG_IDF_TARGET_ESP32S2 + TEST_ASSERT_NOT_EQUAL( adc1_val[i], 0x1fff ); TEST_ASSERT_NOT_EQUAL( adc1_val[i], 0 ); #endif } @@ -264,3 +279,77 @@ TEST_CASE("ADC2 rtc read", "[adc2]") adc_io_normal(ADC_UNIT_1, adc1_ch[i]); } } + +#include "touch_scope.h" +/** + * 0: ADC1 channels raw data debug. + * 1: ADC2 channels raw data debug. + */ +#define SCOPE_DEBUG_TYPE 1 +#define SCOPE_DEBUG_CHANNEL_MAX (10) +#define SCOPE_DEBUG_ENABLE (0) +#define SCOPE_UART_BUADRATE (256000) +#define SCOPE_DEBUG_FREQ_MS (50) + +/** + * Manual test: Capture ADC-DMA data and display it on the serial oscilloscope. Used to observe the stability of the data. + * Use step: + * 1. Call this function in `esp-idf/tools/unit-test-app/main/app_main.c`. + * 2. Use `ESP-Tuning Tool`(download from `www.espressif.com`) to capture. + * 3. The readings of multiple channels will be displayed on the tool. + */ +void test_adc_slope_debug(void) +{ + float scope_temp[SCOPE_DEBUG_CHANNEL_MAX] = {0}; // max scope channel is 10. + test_tp_scope_debug_init(0, -1, -1, SCOPE_UART_BUADRATE); + +#if SCOPE_DEBUG_TYPE == 0 + /* adc1 Configure */ + adc1_config_width(ADC1_TEST_WIDTH); + ESP_LOGI(TAG, "ADC1 [CH - GPIO] atten %d:", ADC1_TEST_ATTEN); + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + TEST_ESP_OK( adc1_config_channel_atten(adc1_ch[i], ADC1_TEST_ATTEN) ); + ESP_LOGI(TAG, "[CH%d - IO%d]", adc1_ch[i], ADC_GET_IO_NUM(0, adc1_ch[i])); + } + /* tie midedle */ + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + adc_fake_tie_middle(ADC_UNIT_1, adc1_ch[i]); + } + vTaskDelay(10 / portTICK_RATE_MS); + + while (1) { + /* adc Read */ + for (int i = 0; i < ADC1_TEST_CHANNEL_NUM; i++) { + scope_temp[i] = adc1_get_raw((adc1_channel_t)adc1_ch[i]); + } + test_tp_print_to_scope(scope_temp, ADC1_TEST_CHANNEL_NUM); + vTaskDelay(SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); + } +#elif SCOPE_DEBUG_TYPE == 1 + int adc2_val[ADC2_TEST_CHANNEL_NUM] = {0}; + + /* adc2 Configure */ + ESP_LOGI(TAG, "ADC2 [CH - GPIO] atten %d:", ADC2_TEST_ATTEN); + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + TEST_ESP_OK( adc2_config_channel_atten(adc2_ch[i], ADC2_TEST_ATTEN) ); + ESP_LOGI(TAG, "[CH%d - IO%d]:", adc2_ch[i], ADC_GET_IO_NUM(1, adc2_ch[i])); + } + /* tie midedle */ + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + adc_fake_tie_middle(ADC_UNIT_2, adc2_ch[i]); + } + vTaskDelay(10 / portTICK_RATE_MS); + + while (1) { + /* adc Read */ + printf("ADC2: "); + for (int i = 0; i < ADC2_TEST_CHANNEL_NUM; i++) { + adc2_get_raw((adc2_channel_t)adc2_ch[i], ADC2_TEST_WIDTH, &adc2_val[i]); + scope_temp[i] = adc2_val[i]; + } + + test_tp_print_to_scope(scope_temp, ADC2_TEST_CHANNEL_NUM); + vTaskDelay(SCOPE_DEBUG_FREQ_MS / portTICK_RATE_MS); + } +#endif +} \ No newline at end of file diff --git a/components/driver/test/touch_sensor_test/touch_scope.h b/components/driver/test/touch_sensor_test/include/touch_scope.h similarity index 100% rename from components/driver/test/touch_sensor_test/touch_scope.h rename to components/driver/test/touch_sensor_test/include/touch_scope.h diff --git a/components/soc/soc/esp32s2/include/soc/adc_caps.h b/components/soc/soc/esp32s2/include/soc/adc_caps.h index f22567223..ad7325333 100644 --- a/components/soc/soc/esp32s2/include/soc/adc_caps.h +++ b/components/soc/soc/esp32s2/include/soc/adc_caps.h @@ -28,4 +28,4 @@ #define SOC_ADC_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) ((PERIPH_NUM==0)? 2 : 1) -#define SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT (1) \ No newline at end of file +#define SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT (2) \ No newline at end of file diff --git a/components/soc/src/esp32s2/include/hal/adc_hal.h b/components/soc/src/esp32s2/include/hal/adc_hal.h index e05c936be..76ab02ea0 100644 --- a/components/soc/src/esp32s2/include/hal/adc_hal.h +++ b/components/soc/src/esp32s2/include/hal/adc_hal.h @@ -240,8 +240,8 @@ void adc_hal_arbiter_config(adc_arbiter_t *config); * @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. - * @param force_cal true: Do not use the results that have already been verified, and perform the verification again. It will take a long time. - * false: Use the result of the last calibration. + * @param force_cal true: Do not use the results that have already been verified, and perform the verification again. It will take a long time(~40us). + * false: Use the result of the last calibration. Return immediately. * * @return * - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set.