1 /*
2 * SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /*----------------------------------------------------------------------------------
8 This file contains ESP32 and ESP32S2 Depricated ADC APIs and functions
9 -----------------------------------------------------------------------------------*/
10
11 #include "sdkconfig.h"
12 #include "esp_types.h"
13 #include "esp_log.h"
14 #include "esp_intr_alloc.h"
15 #include "driver/rtc_io.h"
16 #include "hal/adc_hal.h"
17 #include "hal/adc_ll.h"
18 #include "hal/adc_types.h"
19 #ifdef CONFIG_PM_ENABLE
20 #include "esp_pm.h"
21 #endif
22 #include "freertos/FreeRTOS.h"
23
24 #include "driver/adc_i2s_legacy.h"
25 #include "driver/adc_types_legacy.h"
26
27 static __attribute__((unused)) const char *ADC_TAG = "ADC";
28
29 #define ADC_CHECK_RET(fun_ret) ({ \
30 if (fun_ret != ESP_OK) { \
31 ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__); \
32 return ESP_FAIL; \
33 } \
34 })
35
36 #define ADC_CHECK(a, str, ret_val) ({ \
37 if (!(a)) { \
38 ESP_LOGE(ADC_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
39 return (ret_val); \
40 } \
41 })
42
43 #define ADC_CHANNEL_CHECK(periph, channel) ADC_CHECK(channel < SOC_ADC_CHANNEL_NUM(periph), "ADC"#periph" channel error", ESP_ERR_INVALID_ARG)
44 #define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
45
46 extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
47 #define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
48 #define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
49
50 #ifdef CONFIG_PM_ENABLE
51 esp_pm_lock_handle_t adc_digi_arbiter_lock = NULL;
52 #endif //CONFIG_PM_ENABLE
53
54
55 #if CONFIG_IDF_TARGET_ESP32
56 /*---------------------------------------------------------------
57 ESP32 Depricated ADC APIs and functions
58 ---------------------------------------------------------------*/
59 #define DIG_ADC_OUTPUT_FORMAT_DEFUALT (ADC_DIGI_FORMAT_12BIT)
60 #define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_11)
61 #define DIG_ADC_BIT_WIDTH_DEFUALT (3) //3 for ADC_WIDTH_BIT_12
62
63 /**
64 * @brief ADC digital controller (DMA mode) conversion rules setting.
65 */
66 typedef struct {
67 union {
68 struct {
69 uint8_t atten: 2; /*!< ADC sampling voltage attenuation configuration. Modification of attenuation affects the range of measurements.
70 0: measurement range 0 - 800mV,
71 1: measurement range 0 - 1100mV,
72 2: measurement range 0 - 1350mV,
73 3: measurement range 0 - 2600mV. */
74 uint8_t bit_width: 2; /*!< ADC resolution.
75 - 0: 9 bit;
76 - 1: 10 bit;
77 - 2: 11 bit;
78 - 3: 12 bit. */
79 int8_t channel: 4; /*!< ADC channel index. */
80 };
81 uint8_t val; /*!<Raw data value */
82 };
83 } adc_digi_pattern_table_t;
84
85 /**
86 * @brief ADC digital controller (DMA mode) output data format option.
87 */
88 typedef enum {
89 ADC_DIGI_FORMAT_12BIT, /*!<ADC to DMA data format, [15:12]-channel, [11: 0]-12 bits ADC data (`adc_digi_output_data_t`). Note: For single convert mode. */
90 ADC_DIGI_FORMAT_11BIT, /*!<ADC to DMA data format, [15]-adc unit, [14:11]-channel, [10: 0]-11 bits ADC data (`adc_digi_output_data_t`). Note: For multi or alter convert mode. */
91 ADC_DIGI_FORMAT_MAX,
92 } adc_digi_format_t;
93
94 /**
95 * Explanation of the relationship between `conv_limit_num`, `dma_eof_num` and the number of DMA outputs:
96 *
97 * +---------------------+--------+--------+--------+
98 * | conv_mode | single | both | alter |
99 * +---------------------+--------+--------+--------+
100 * | trigger meas times | 1 | 1 | 1 |
101 * +---------------------+--------+--------+--------+
102 * | conv_limit_num | +1 | +1 | +1 |
103 * | dma_eof_num | +1 | +2 | +1 |
104 * | dma output (byte) | +2 | +4 | +2 |
105 * +---------------------+--------+--------+--------+
106 */
107 typedef struct {
108 uint32_t adc1_pattern_len; /*!<Pattern table length for digital controller. Range: 0 ~ 16 (0: Don't change the pattern table setting).
109 The pattern table that defines the conversion rules for each SAR ADC. Each table has 16 items, in which channel selection,
110 resolution and attenuation are stored. When the conversion is started, the controller reads conversion rules from the
111 pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. */
112 uint32_t adc2_pattern_len; /*!<Refer to ``adc1_pattern_len`` */
113 adc_digi_pattern_table_t *adc1_pattern; /*!<Pointer to pattern table for digital controller. The table size defined by `adc1_pattern_len`. */
114 adc_digi_pattern_table_t *adc2_pattern; /*!<Refer to `adc1_pattern` */
115 adc_digi_convert_mode_t conv_mode; /*!<ADC conversion mode for digital controller. See ``adc_digi_convert_mode_t``. */
116 adc_digi_format_t format; /*!<ADC output data format for digital controller. See ``adc_digi_format_t``. */
117 } adc_digi_config_t;
118
119 /**
120 * Set adc output 16-bit-data format from digital controller.
121 *
122 * @param data_sel 1: [15] unit, [14:11] channel, [10:0] data, 11-bit-width at most. Only work under `ADC_LL_DIGI_CONV_BOTH_UNIT` or `ADC_LL_DIGI_CONV_ALTER_UNIT` mode.
123 * 0: [15:12] channel, [11:0] data, 12-bit-width at most. Only work under `ADC_LL_DIGI_CONV_ONLY_ADC1` or `ADC_LL_DIGI_CONV_ONLY_ADC2` mode
124 * @note see `adc_ll_digi_pattern_table_t` for more detail of data bit width
125 */
adc_ll_digi_set_output_format(bool data_sel)126 static inline void adc_ll_digi_set_output_format(bool data_sel)
127 {
128 SYSCON.saradc_ctrl.data_sar_sel = data_sel;
129 }
130
adc_ll_digi_prepare_pattern_table(adc_unit_t adc_n,uint32_t pattern_index,adc_digi_pattern_table_t pattern)131 static inline void adc_ll_digi_prepare_pattern_table(adc_unit_t adc_n, uint32_t pattern_index, adc_digi_pattern_table_t pattern)
132 {
133 uint32_t tab;
134 uint8_t index = pattern_index / 4;
135 uint8_t offset = (pattern_index % 4) * 8;
136 if (adc_n == ADC_UNIT_1) {
137 tab = SYSCON.saradc_sar1_patt_tab[index]; // Read old register value
138 tab &= (~(0xFF000000 >> offset)); // clear old data
139 tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
140 SYSCON.saradc_sar1_patt_tab[index] = tab; // Write back
141 } else { // adc_n == ADC_UNIT_2
142 tab = SYSCON.saradc_sar2_patt_tab[index]; // Read old register value
143 tab &= (~(0xFF000000 >> offset)); // clear old data
144 tab |= ((uint32_t)pattern.val << 24) >> offset; // Fill in the new data
145 SYSCON.saradc_sar2_patt_tab[index] = tab; // Write back
146 }
147 }
148
adc_digi_controller_reg_set(const adc_digi_config_t * cfg)149 static void adc_digi_controller_reg_set(const adc_digi_config_t *cfg)
150 {
151 /* On ESP32, only support ADC1 */
152 switch (cfg->conv_mode) {
153 case ADC_CONV_SINGLE_UNIT_1:
154 adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ONLY_ADC1);
155 break;
156 case ADC_CONV_SINGLE_UNIT_2:
157 adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ONLY_ADC2);
158 break;
159 case ADC_CONV_BOTH_UNIT:
160 adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_BOTH_UNIT);
161 break;
162 case ADC_CONV_ALTER_UNIT:
163 adc_ll_digi_set_convert_mode(ADC_LL_DIGI_CONV_ALTER_UNIT);
164 break;
165 default:
166 abort();
167 }
168
169 if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
170 adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_DIG);
171 if (cfg->adc1_pattern_len) {
172 adc_ll_digi_clear_pattern_table(ADC_UNIT_1);
173 adc_ll_digi_set_pattern_table_len(ADC_UNIT_1, cfg->adc1_pattern_len);
174 for (uint32_t i = 0; i < cfg->adc1_pattern_len; i++) {
175 adc_ll_digi_prepare_pattern_table(ADC_UNIT_1, i, cfg->adc1_pattern[i]);
176 }
177 }
178 }
179 if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
180 adc_ll_set_controller(ADC_UNIT_2, ADC_LL_CTRL_DIG);
181 if (cfg->adc2_pattern_len) {
182 adc_ll_digi_clear_pattern_table(ADC_UNIT_2);
183 adc_ll_digi_set_pattern_table_len(ADC_UNIT_2, cfg->adc2_pattern_len);
184 for (uint32_t i = 0; i < cfg->adc2_pattern_len; i++) {
185 adc_ll_digi_prepare_pattern_table(ADC_UNIT_2, i, cfg->adc2_pattern[i]);
186 }
187 }
188 }
189 adc_ll_digi_set_output_format(cfg->format);
190 adc_ll_digi_convert_limit_enable(ADC_LL_DEFAULT_CONV_LIMIT_EN);
191 adc_ll_digi_set_convert_limit_num(ADC_LL_DEFAULT_CONV_LIMIT_NUM);
192 adc_ll_digi_set_data_source(ADC_I2S_DATA_SRC_ADC);
193 }
194
adc_set_i2s_data_source(adc_i2s_source_t src)195 esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src)
196 {
197 ADC_CHECK((src == ADC_I2S_DATA_SRC_IO_SIG || src == ADC_I2S_DATA_SRC_ADC), "ADC i2s data source error", ESP_ERR_INVALID_ARG);
198 ADC_ENTER_CRITICAL();
199 adc_ll_digi_set_data_source(src);
200 ADC_EXIT_CRITICAL();
201 return ESP_OK;
202 }
203
204 extern esp_err_t adc_common_gpio_init(adc_unit_t adc_unit, adc_channel_t channel);
adc_i2s_mode_init(adc_unit_t adc_unit,adc_channel_t channel)205 esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel)
206 {
207 if (adc_unit == ADC_UNIT_1) {
208 ADC_CHANNEL_CHECK(ADC_UNIT_1, channel);
209 } else if (adc_unit == ADC_UNIT_2) {
210 //ADC2 does not support DMA mode
211 ADC_CHECK(false, "ADC2 not support DMA for now.", ESP_ERR_INVALID_ARG);
212 ADC_CHANNEL_CHECK(ADC_UNIT_2, channel);
213 }
214
215 adc_digi_pattern_table_t adc1_pattern[1];
216 adc_digi_pattern_table_t adc2_pattern[1];
217 adc_digi_config_t dig_cfg = {
218 .format = DIG_ADC_OUTPUT_FORMAT_DEFUALT,
219 .conv_mode = ADC_CONV_SINGLE_UNIT_1,
220 };
221
222 if (adc_unit == ADC_UNIT_1) {
223 adc1_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT;
224 adc1_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT;
225 adc1_pattern[0].channel = channel;
226 dig_cfg.adc1_pattern_len = 1;
227 dig_cfg.adc1_pattern = adc1_pattern;
228 } else if (adc_unit == ADC_UNIT_2) {
229 adc2_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT;
230 adc2_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT;
231 adc2_pattern[0].channel = channel;
232 dig_cfg.adc2_pattern_len = 1;
233 dig_cfg.adc2_pattern = adc2_pattern;
234 }
235 adc_common_gpio_init(adc_unit, channel);
236 ADC_ENTER_CRITICAL();
237 adc_ll_digi_set_fsm_time(ADC_LL_FSM_RSTB_WAIT_DEFAULT, ADC_LL_FSM_START_WAIT_DEFAULT,
238 ADC_LL_FSM_STANDBY_WAIT_DEFAULT);
239 adc_ll_set_sample_cycle(ADC_LL_SAMPLE_CYCLE_DEFAULT);
240 adc_hal_pwdet_set_cct(ADC_LL_PWDET_CCT_DEFAULT);
241 adc_ll_digi_output_invert(ADC_UNIT_1, ADC_LL_DIGI_DATA_INVERT_DEFAULT(ADC_UNIT_1));
242 adc_ll_digi_output_invert(ADC_UNIT_2, ADC_LL_DIGI_DATA_INVERT_DEFAULT(ADC_UNIT_2));
243 adc_ll_digi_set_clk_div(ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT);
244 adc_digi_controller_reg_set(&dig_cfg);
245 ADC_EXIT_CRITICAL();
246
247 return ESP_OK;
248 }
249
250 #endif //#if CONFIG_IDF_TARGET_ESP32
251