1 // Copyright 2016-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <stdlib.h>
16 #include <ctype.h>
17 #include "sdkconfig.h"
18 #include "esp_types.h"
19 #include "esp_log.h"
20 #include "sys/lock.h"
21 #include "soc/rtc.h"
22 #include "soc/periph_defs.h"
23 #include "esp_osal/esp_osal.h"
24 #include "esp_osal/xtensa_api.h"
25 #include "esp_osal/semphr.h"
26 #include "esp_osal/timers.h"
27 #include "esp_intr_alloc.h"
28 #include "driver/rtc_io.h"
29 #include "driver/rtc_cntl.h"
30 #include "driver/gpio.h"
31 #include "driver/adc.h"
32
33 #ifndef NDEBUG
34 // Enable built-in checks in queue.h in debug builds
35 #define INVARIANTS
36 #endif
37 #include "sys/queue.h"
38 #include "hal/adc_types.h"
39 #include "hal/adc_hal.h"
40
41 #define ADC_MAX_MEAS_NUM_DEFAULT (255)
42 #define ADC_MEAS_NUM_LIM_DEFAULT (1)
43
44 #define DIG_ADC_OUTPUT_FORMAT_DEFUALT (ADC_DIGI_FORMAT_12BIT)
45 #define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_11)
46 #define DIG_ADC_BIT_WIDTH_DEFUALT (ADC_WIDTH_BIT_12)
47
48 #define ADC_CHECK_RET(fun_ret) ({ \
49 if (fun_ret != ESP_OK) { \
50 ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__); \
51 return ESP_FAIL; \
52 } \
53 })
54
55 static const char *ADC_TAG = "ADC";
56
57 #define ADC_CHECK(a, str, ret_val) ({ \
58 if (!(a)) { \
59 ESP_LOGE(ADC_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
60 return (ret_val); \
61 } \
62 })
63
64 #define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
65
66 #define ADC_CHANNEL_CHECK(periph, channel) ADC_CHECK(channel < SOC_ADC_CHANNEL_NUM(periph), "ADC"#periph" channel error", ESP_ERR_INVALID_ARG)
67
68 extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
69 #define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
70 #define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
71
72 /*---------------------------------------------------------------
73 Digital controller setting
74 ---------------------------------------------------------------*/
75
adc_set_i2s_data_source(adc_i2s_source_t src)76 esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src)
77 {
78 ADC_CHECK(src < ADC_I2S_DATA_SRC_MAX, "ADC i2s data source error", ESP_ERR_INVALID_ARG);
79 ADC_ENTER_CRITICAL();
80 adc_hal_digi_set_data_source(src);
81 ADC_EXIT_CRITICAL();
82 return ESP_OK;
83 }
84
adc_i2s_mode_init(adc_unit_t adc_unit,adc_channel_t channel)85 esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel)
86 {
87 if (adc_unit & ADC_UNIT_1) {
88 ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_1)), "ADC1 not support DMA for now.", ESP_ERR_INVALID_ARG);
89 ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
90 }
91 if (adc_unit & ADC_UNIT_2) {
92 ADC_CHECK((SOC_ADC_SUPPORT_DMA_MODE(ADC_NUM_2)), "ADC2 not support DMA for now.", ESP_ERR_INVALID_ARG);
93 ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
94 }
95
96 adc_digi_pattern_table_t adc1_pattern[1];
97 adc_digi_pattern_table_t adc2_pattern[1];
98 adc_digi_config_t dig_cfg = {
99 .conv_limit_en = ADC_MEAS_NUM_LIM_DEFAULT,
100 .conv_limit_num = ADC_MAX_MEAS_NUM_DEFAULT,
101 .format = DIG_ADC_OUTPUT_FORMAT_DEFUALT,
102 .conv_mode = (adc_digi_convert_mode_t)adc_unit,
103 };
104
105 if (adc_unit & ADC_UNIT_1) {
106 adc1_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT;
107 adc1_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT;
108 adc1_pattern[0].channel = channel;
109 dig_cfg.adc1_pattern_len = 1;
110 dig_cfg.adc1_pattern = adc1_pattern;
111 }
112 if (adc_unit & ADC_UNIT_2) {
113 adc2_pattern[0].atten = DIG_ADC_ATTEN_DEFUALT;
114 adc2_pattern[0].bit_width = DIG_ADC_BIT_WIDTH_DEFUALT;
115 adc2_pattern[0].channel = channel;
116 dig_cfg.adc2_pattern_len = 1;
117 dig_cfg.adc2_pattern = adc2_pattern;
118 }
119 adc_gpio_init(adc_unit, channel);
120 ADC_ENTER_CRITICAL();
121 adc_hal_init();
122 adc_hal_digi_controller_config(&dig_cfg);
123 ADC_EXIT_CRITICAL();
124
125 return ESP_OK;
126 }
127
adc_digi_init(void)128 esp_err_t adc_digi_init(void)
129 {
130 ADC_ENTER_CRITICAL();
131 adc_hal_init();
132 ADC_EXIT_CRITICAL();
133 return ESP_OK;
134 }
135
adc_digi_deinit(void)136 esp_err_t adc_digi_deinit(void)
137 {
138 adc_power_release();
139 ADC_ENTER_CRITICAL();
140 adc_hal_digi_deinit();
141 ADC_EXIT_CRITICAL();
142 return ESP_OK;
143 }
144
adc_digi_controller_config(const adc_digi_config_t * config)145 esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
146 {
147 /* If enable digital controller, adc xpd should always on. */
148 adc_power_acquire();
149 ADC_ENTER_CRITICAL();
150 adc_hal_digi_controller_config(config);
151 ADC_EXIT_CRITICAL();
152 return ESP_OK;
153 }
154
155 /*---------------------------------------------------------------
156 RTC controller setting
157 ---------------------------------------------------------------*/
158
159 /*---------------------------------------------------------------
160 HALL SENSOR
161 ---------------------------------------------------------------*/
162
hall_sensor_get_value(void)163 static int hall_sensor_get_value(void) //hall sensor without LNA
164 {
165 int hall_value;
166
167 adc_power_acquire();
168
169 ADC_ENTER_CRITICAL();
170 /* disable other peripherals. */
171 adc_hal_amp_disable();
172 adc_hal_hall_enable();
173 // set controller
174 adc_hal_set_controller( ADC_NUM_1, ADC_CTRL_RTC );
175 hall_value = adc_hal_hall_convert();
176 adc_hal_hall_disable();
177 ADC_EXIT_CRITICAL();
178
179 adc_power_release();
180 return hall_value;
181 }
182
hall_sensor_read(void)183 int hall_sensor_read(void)
184 {
185 adc_gpio_init(ADC_UNIT_1, ADC1_CHANNEL_0);
186 adc_gpio_init(ADC_UNIT_1, ADC1_CHANNEL_3);
187 adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0);
188 adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_0);
189 return hall_sensor_get_value();
190 }
191