• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016-2018 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/soc_pins.h"
22 #include "esp_osal/esp_osal.h"
23 #include "esp_osal/semphr.h"
24 #include "esp_osal/timers.h"
25 #include "esp_intr_alloc.h"
26 #include "driver/rtc_io.h"
27 #include "driver/touch_pad.h"
28 #include "driver/rtc_cntl.h"
29 #include "driver/gpio.h"
30 #include "hal/touch_sensor_types.h"
31 #include "hal/touch_sensor_hal.h"
32 
33 static const char *TOUCH_TAG = "TOUCH_SENSOR";
34 #define TOUCH_CHECK(a, str, ret_val) ({                                             \
35     if (!(a)) {                                                                     \
36         ESP_LOGE(TOUCH_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str);              \
37         return (ret_val);                                                           \
38     }                                                                               \
39 })
40 #ifdef CONFIG_IDF_TARGET_ESP32
41 #define TOUCH_CHANNEL_CHECK(channel) do { \
42         TOUCH_CHECK(channel < SOC_TOUCH_SENSOR_NUM && channel >= 0, "Touch channel error", ESP_ERR_INVALID_ARG); \
43     } while (0);
44 #else // !CONFIG_IDF_TARGET_ESP32
45 #define TOUCH_CHANNEL_CHECK(channel) do { \
46         TOUCH_CHECK(channel < SOC_TOUCH_SENSOR_NUM && channel >= 0, "Touch channel error", ESP_ERR_INVALID_ARG); \
47         TOUCH_CHECK(channel != SOC_TOUCH_DENOISE_CHANNEL, "TOUCH0 is internal denoise channel", ESP_ERR_INVALID_ARG); \
48     } while (0);
49 #endif // CONFIG_IDF_TARGET_ESP32
50 
51 #define TOUCH_GET_IO_NUM(channel) (touch_sensor_channel_io_map[channel])
52 
53 _Static_assert(TOUCH_PAD_MAX == SOC_TOUCH_SENSOR_NUM, "Touch sensor channel number not equal to chip capabilities");
54 
55 extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
56 #define TOUCH_ENTER_CRITICAL()  portENTER_CRITICAL(&rtc_spinlock)
57 #define TOUCH_EXIT_CRITICAL()  portEXIT_CRITICAL(&rtc_spinlock)
58 
touch_pad_isr_deregister(intr_handler_t fn,void * arg)59 esp_err_t touch_pad_isr_deregister(intr_handler_t fn, void *arg)
60 {
61     return rtc_isr_deregister(fn, arg);
62 }
63 
touch_pad_set_voltage(touch_high_volt_t refh,touch_low_volt_t refl,touch_volt_atten_t atten)64 esp_err_t touch_pad_set_voltage(touch_high_volt_t refh, touch_low_volt_t refl, touch_volt_atten_t atten)
65 {
66     TOUCH_CHECK(((refh < TOUCH_HVOLT_MAX) && (refh >= (int )TOUCH_HVOLT_KEEP)), "touch refh error",
67                 ESP_ERR_INVALID_ARG);
68     TOUCH_CHECK(((refl < TOUCH_LVOLT_MAX) && (refh >= (int )TOUCH_LVOLT_KEEP)), "touch refl error",
69                 ESP_ERR_INVALID_ARG);
70     TOUCH_CHECK(((atten < TOUCH_HVOLT_ATTEN_MAX) && (refh >= (int )TOUCH_HVOLT_ATTEN_KEEP)), "touch atten error",
71                 ESP_ERR_INVALID_ARG);
72 
73     const touch_hal_volt_t volt = {
74         .refh = refh,
75         .refl = refl,
76         .atten = atten,
77     };
78     TOUCH_ENTER_CRITICAL();
79     touch_hal_set_voltage(&volt);
80     TOUCH_EXIT_CRITICAL();
81 
82     return ESP_OK;
83 }
84 
touch_pad_get_voltage(touch_high_volt_t * refh,touch_low_volt_t * refl,touch_volt_atten_t * atten)85 esp_err_t touch_pad_get_voltage(touch_high_volt_t *refh, touch_low_volt_t *refl, touch_volt_atten_t *atten)
86 {
87     touch_hal_volt_t volt = {0};
88     TOUCH_ENTER_CRITICAL();
89     touch_hal_get_voltage(&volt);
90     TOUCH_EXIT_CRITICAL();
91     *refh = volt.refh;
92     *refl = volt.refl;
93     *atten = volt.atten;
94 
95     return ESP_OK;
96 }
97 
touch_pad_set_cnt_mode(touch_pad_t touch_num,touch_cnt_slope_t slope,touch_tie_opt_t opt)98 esp_err_t touch_pad_set_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t slope, touch_tie_opt_t opt)
99 {
100     TOUCH_CHECK(touch_num < SOC_TOUCH_SENSOR_NUM, "Touch channel error", ESP_ERR_INVALID_ARG);
101     TOUCH_CHECK(slope < TOUCH_PAD_SLOPE_MAX, "touch slope error", ESP_ERR_INVALID_ARG);
102     TOUCH_CHECK(opt < TOUCH_PAD_TIE_OPT_MAX, "touch opt error", ESP_ERR_INVALID_ARG);
103 
104     const touch_hal_meas_mode_t meas = {
105         .slope = slope,
106         .tie_opt = opt,
107     };
108     TOUCH_ENTER_CRITICAL();
109     touch_hal_set_meas_mode(touch_num, &meas);
110     TOUCH_EXIT_CRITICAL();
111 
112     return ESP_OK;
113 }
114 
touch_pad_get_cnt_mode(touch_pad_t touch_num,touch_cnt_slope_t * slope,touch_tie_opt_t * opt)115 esp_err_t touch_pad_get_cnt_mode(touch_pad_t touch_num, touch_cnt_slope_t *slope, touch_tie_opt_t *opt)
116 {
117     TOUCH_CHECK(touch_num < SOC_TOUCH_SENSOR_NUM, "Touch channel error", ESP_ERR_INVALID_ARG);
118 
119     touch_hal_meas_mode_t meas = {0};
120     TOUCH_ENTER_CRITICAL();
121     touch_hal_get_meas_mode(touch_num, &meas);
122     TOUCH_EXIT_CRITICAL();
123     *slope = meas.slope;
124     *opt = meas.tie_opt;
125 
126     return ESP_OK;
127 }
128 
touch_pad_io_init(touch_pad_t touch_num)129 esp_err_t touch_pad_io_init(touch_pad_t touch_num)
130 {
131     TOUCH_CHANNEL_CHECK(touch_num);
132     gpio_num_t gpio_num = TOUCH_GET_IO_NUM(touch_num);
133     rtc_gpio_init(gpio_num);
134     rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED);
135     rtc_gpio_pulldown_dis(gpio_num);
136     rtc_gpio_pullup_dis(gpio_num);
137     return ESP_OK;
138 }
139 
touch_pad_fsm_start(void)140 esp_err_t touch_pad_fsm_start(void)
141 {
142     TOUCH_ENTER_CRITICAL();
143     touch_hal_start_fsm();
144     TOUCH_EXIT_CRITICAL();
145     return ESP_OK;
146 }
147 
touch_pad_fsm_stop(void)148 esp_err_t touch_pad_fsm_stop(void)
149 {
150     TOUCH_ENTER_CRITICAL();
151     touch_hal_stop_fsm();
152     TOUCH_EXIT_CRITICAL();
153     return ESP_OK;
154 }
155 
touch_pad_set_fsm_mode(touch_fsm_mode_t mode)156 esp_err_t touch_pad_set_fsm_mode(touch_fsm_mode_t mode)
157 {
158     TOUCH_CHECK((mode < TOUCH_FSM_MODE_MAX), "touch fsm mode error", ESP_ERR_INVALID_ARG);
159 
160     TOUCH_ENTER_CRITICAL();
161     touch_hal_set_fsm_mode(mode);
162     TOUCH_EXIT_CRITICAL();
163 #ifdef CONFIG_IDF_TARGET_ESP32
164     if (mode == TOUCH_FSM_MODE_TIMER) {
165         touch_pad_fsm_start();
166     } else {
167         touch_pad_fsm_stop();
168     }
169 #endif
170     return ESP_OK;
171 }
172 
touch_pad_get_fsm_mode(touch_fsm_mode_t * mode)173 esp_err_t touch_pad_get_fsm_mode(touch_fsm_mode_t *mode)
174 {
175     touch_hal_get_fsm_mode(mode);
176     return ESP_OK;
177 }
178 
touch_pad_sw_start(void)179 esp_err_t touch_pad_sw_start(void)
180 {
181     TOUCH_ENTER_CRITICAL();
182     touch_hal_start_sw_meas();
183     TOUCH_EXIT_CRITICAL();
184     return ESP_OK;
185 }
186 
187 #ifdef CONFIG_IDF_TARGET_ESP32
touch_pad_set_thresh(touch_pad_t touch_num,uint16_t threshold)188 esp_err_t touch_pad_set_thresh(touch_pad_t touch_num, uint16_t threshold)
189 {
190     TOUCH_CHANNEL_CHECK(touch_num);
191     TOUCH_ENTER_CRITICAL();
192     touch_hal_set_threshold(touch_num, threshold);
193     TOUCH_EXIT_CRITICAL();
194     return ESP_OK;
195 }
196 #else // !CONFIG_IDF_TARGET_ESP32
touch_pad_set_thresh(touch_pad_t touch_num,uint32_t threshold)197 esp_err_t touch_pad_set_thresh(touch_pad_t touch_num, uint32_t threshold)
198 {
199     TOUCH_CHANNEL_CHECK(touch_num);
200     TOUCH_CHECK(touch_num != SOC_TOUCH_DENOISE_CHANNEL,
201                 "TOUCH0 is internal denoise channel", ESP_ERR_INVALID_ARG);
202     TOUCH_ENTER_CRITICAL();
203     touch_hal_set_threshold(touch_num, threshold);
204     TOUCH_EXIT_CRITICAL();
205     return ESP_OK;
206 }
207 #endif // CONFIG_IDF_TARGET_ESP32
208 
209 #ifdef CONFIG_IDF_TARGET_ESP32
touch_pad_get_thresh(touch_pad_t touch_num,uint16_t * threshold)210 esp_err_t touch_pad_get_thresh(touch_pad_t touch_num, uint16_t *threshold)
211 {
212     TOUCH_CHANNEL_CHECK(touch_num);
213     touch_hal_get_threshold(touch_num, threshold);
214     return ESP_OK;
215 }
216 #else // !CONFIG_IDF_TARGET_ESP32
touch_pad_get_thresh(touch_pad_t touch_num,uint32_t * threshold)217 esp_err_t touch_pad_get_thresh(touch_pad_t touch_num, uint32_t *threshold)
218 {
219     TOUCH_CHANNEL_CHECK(touch_num);
220     TOUCH_CHECK(touch_num != SOC_TOUCH_DENOISE_CHANNEL,
221                 "TOUCH0 is internal denoise channel", ESP_ERR_INVALID_ARG);
222     touch_hal_get_threshold(touch_num, threshold);
223     return ESP_OK;
224 }
225 #endif // CONFIG_IDF_TARGET_ESP32
226 
touch_pad_get_wakeup_status(touch_pad_t * pad_num)227 esp_err_t touch_pad_get_wakeup_status(touch_pad_t *pad_num)
228 {
229     touch_hal_get_wakeup_status(pad_num);
230     TOUCH_CHANNEL_CHECK(*pad_num);
231     return ESP_OK;
232 }
233 
touch_pad_get_status(void)234 uint32_t IRAM_ATTR touch_pad_get_status(void)
235 {
236     uint32_t status = 0;
237     touch_hal_read_trigger_status_mask(&status);
238     return status;
239 }
240 
touch_pad_clear_status(void)241 esp_err_t IRAM_ATTR touch_pad_clear_status(void)
242 {
243     touch_hal_clear_trigger_status_mask();
244     return ESP_OK;
245 }
246