1 /*
2  * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Unlicense OR CC0-1.0
5  */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "unity.h"
9 #include "esp_log.h"
10 #include "freertos/FreeRTOS.h"
11 #include "freertos/task.h"
12 #include "driver/gpio.h"
13 #include "driver/rtc_io.h"
14 #include "soc/adc_periph.h"
15 #include "test_common_adc.h"
16 
17 __attribute__((unused)) static const char *TAG = "TEST_ADC";
18 
19 /*---------------------------------------------------------------
20         ADC Attenuation
21 ---------------------------------------------------------------*/
22 #if CONFIG_IDF_TARGET_ESP32C2
23 adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_11};
24 #else
25 adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_2_5, ADC_ATTEN_DB_6, ADC_ATTEN_DB_11};
26 #endif
27 
28 #if SOC_ADC_DIG_IIR_FILTER_SUPPORTED
29 adc_digi_iir_filter_coeff_t g_test_filter_coeff[TEST_FILTER_COEFF_NUMS] = {
30     ADC_DIGI_IIR_FILTER_COEFF_2,
31     ADC_DIGI_IIR_FILTER_COEFF_4,
32     ADC_DIGI_IIR_FILTER_COEFF_8,
33     ADC_DIGI_IIR_FILTER_COEFF_16,
34     ADC_DIGI_IIR_FILTER_COEFF_64,
35 };
36 #endif
37 
38 
39 /*---------------------------------------------------------------
40         ADC Calibration
41 ---------------------------------------------------------------*/
test_adc_calibration_init(adc_unit_t unit,adc_channel_t channel,adc_atten_t atten,adc_bitwidth_t bitwidth,adc_cali_handle_t * out_handle)42 bool test_adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_bitwidth_t bitwidth, adc_cali_handle_t *out_handle)
43 {
44     esp_err_t ret = ESP_FAIL;
45     adc_cali_handle_t handle = NULL;
46     bool calibrated = false;
47 
48 #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
49     ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting");
50     adc_cali_curve_fitting_config_t cali_config = {
51         .unit_id = unit,
52         .chan = channel,
53         .atten = atten,
54         .bitwidth = bitwidth,
55     };
56     ret = adc_cali_create_scheme_curve_fitting(&cali_config, &handle);
57 
58 #elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
59     ESP_LOGI(TAG, "calibration scheme version is %s", "Line Fitting");
60     adc_cali_line_fitting_config_t cali_config = {
61         .unit_id = unit,
62         .atten = atten,
63         .bitwidth = bitwidth,
64     };
65     ret = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
66 #endif
67 
68     if (ret == ESP_OK) {
69         calibrated = true;
70     } else if (ret == ESP_ERR_NOT_SUPPORTED) {
71         ESP_LOGW(TAG, "calibration fail due to lack of eFuse bits");
72     } else {
73         TEST_ASSERT(false);
74     }
75 
76     *out_handle = handle;
77 
78     return calibrated;
79 }
80 
test_adc_calibration_deinit(adc_cali_handle_t handle)81 void test_adc_calibration_deinit(adc_cali_handle_t handle)
82 {
83 #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
84     ESP_LOGI(TAG, "deregister %s calibration scheme", "Curve Fitting");
85     TEST_ESP_OK(adc_cali_delete_scheme_curve_fitting(handle));
86 
87 #elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
88     ESP_LOGI(TAG, "deregister %s calibration scheme", "Line Fitting");
89     TEST_ESP_OK(adc_cali_delete_scheme_line_fitting(handle));
90 #endif
91 }
92 
93 
94 /*---------------------------------------------------------------
95         ADC GPIO
96 ---------------------------------------------------------------*/
97 #define ADC_GET_IO_NUM(unit, channel) (adc_channel_io_map[unit][channel])
98 
test_adc_set_io_level(adc_unit_t unit,adc_channel_t channel,bool level)99 void test_adc_set_io_level(adc_unit_t unit, adc_channel_t channel, bool level)
100 {
101     TEST_ASSERT(channel < SOC_ADC_CHANNEL_NUM(unit) && "invalid channel");
102 
103 #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
104     uint32_t io_num = ADC_GET_IO_NUM(unit, channel);
105     TEST_ESP_OK(gpio_set_pull_mode(io_num, (level ? GPIO_PULLUP_ONLY: GPIO_PULLDOWN_ONLY)));
106 #else
107     gpio_num_t io_num = ADC_GET_IO_NUM(unit, channel);
108     if (level) {
109         TEST_ESP_OK(rtc_gpio_pullup_en(io_num));
110         TEST_ESP_OK(rtc_gpio_pulldown_dis(io_num));
111     } else {
112         TEST_ESP_OK(rtc_gpio_pullup_dis(io_num));
113         TEST_ESP_OK(rtc_gpio_pulldown_en(io_num));
114     }
115     TEST_ESP_OK(gpio_set_pull_mode(io_num, (level ? GPIO_PULLUP_ONLY: GPIO_PULLDOWN_ONLY)));
116 #endif
117 }
118 
119 
test_adc_set_io_middle(adc_unit_t unit,adc_channel_t channel)120 void test_adc_set_io_middle(adc_unit_t unit, adc_channel_t channel)
121 {
122     TEST_ASSERT(channel < SOC_ADC_CHANNEL_NUM(unit) && "invalid channel");
123 
124     uint32_t io_num = ADC_GET_IO_NUM(unit, channel);
125 
126 #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
127     TEST_ESP_OK(gpio_set_pull_mode(io_num, GPIO_PULLUP_PULLDOWN));
128 #else
129     TEST_ESP_OK(rtc_gpio_init(io_num));
130     TEST_ESP_OK(rtc_gpio_pullup_en(io_num));
131     TEST_ESP_OK(rtc_gpio_pulldown_en(io_num));
132     TEST_ESP_OK(rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_DISABLED));
133 #endif
134     vTaskDelay(10 / portTICK_PERIOD_MS);
135 }
136