1 /*
2 * SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdlib.h>
8 #include <ctype.h>
9 #include "sdkconfig.h"
10 #include "esp_types.h"
11 #include "esp_log.h"
12 #include "sys/lock.h"
13 #include "soc/rtc.h"
14 #include "soc/periph_defs.h"
15 #include "freertos/FreeRTOS.h"
16 #include "freertos/xtensa_api.h"
17 #include "freertos/semphr.h"
18 #include "freertos/timers.h"
19 #include "esp_intr_alloc.h"
20 #include "driver/rtc_io.h"
21 #include "driver/touch_pad.h"
22 #include "driver/rtc_cntl.h"
23 #include "driver/gpio.h"
24 #include "esp_check.h"
25
26 #ifndef NDEBUG
27 // Enable built-in checks in queue.h in debug builds
28 #define INVARIANTS
29 #endif
30 #include "sys/queue.h"
31 #include "hal/touch_sensor_types.h"
32 #include "hal/touch_sensor_hal.h"
33
34 typedef struct {
35 TimerHandle_t timer;
36 uint16_t filtered_val[TOUCH_PAD_MAX];
37 uint16_t raw_val[TOUCH_PAD_MAX];
38 uint32_t filter_period;
39 uint32_t period;
40 bool enable;
41 } touch_pad_filter_t;
42 static touch_pad_filter_t *s_touch_pad_filter = NULL;
43 // check if touch pad be initialized.
44 static uint16_t s_touch_pad_init_bit = 0x0000;
45 static filter_cb_t s_filter_cb = NULL;
46 static SemaphoreHandle_t rtc_touch_mux = NULL;
47
48 #define TOUCH_PAD_FILTER_FACTOR_DEFAULT (4) // IIR filter coefficient.
49 #define TOUCH_PAD_SHIFT_DEFAULT (4) // Increase computing accuracy.
50 #define TOUCH_PAD_SHIFT_ROUND_DEFAULT (8) // ROUND = 2^(n-1); rounding off for fractional.
51
52 static const char *TOUCH_TAG = "TOUCH_SENSOR";
53
54 #define TOUCH_CHANNEL_CHECK(channel) ESP_RETURN_ON_FALSE(channel < SOC_TOUCH_SENSOR_NUM, ESP_ERR_INVALID_ARG, TOUCH_TAG, "Touch channel error");
55 #define TOUCH_NULL_POINTER_CHECK(p, name) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, TOUCH_TAG, "input param '"name"' is NULL")
56 #define TOUCH_PARAM_CHECK_STR(s) ""s" parameter error"
57
58 extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
59 #define TOUCH_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
60 #define TOUCH_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
61
62 /*---------------------------------------------------------------
63 Touch Pad
64 ---------------------------------------------------------------*/
65 //Some register bits of touch sensor 8 and 9 are mismatched, we need to swap the bits.
66 #define BITSWAP(data, n, m) (((data >> n) & 0x1) == ((data >> m) & 0x1) ? (data) : ((data) ^ ((0x1 <<n) | (0x1 << m))))
67 #define TOUCH_BITS_SWAP(v) BITSWAP(v, TOUCH_PAD_NUM8, TOUCH_PAD_NUM9)
68 static esp_err_t _touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value, touch_fsm_mode_t mode);
69
touch_pad_isr_handler_register(void (* fn)(void *),void * arg,int no_use,intr_handle_t * handle_no_use)70 esp_err_t touch_pad_isr_handler_register(void (*fn)(void *), void *arg, int no_use, intr_handle_t *handle_no_use)
71 {
72 ESP_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TOUCH_TAG, "Touch_Pad ISR null");
73 return rtc_isr_register(fn, arg, RTC_CNTL_TOUCH_INT_ST_M);
74 }
75
touch_pad_isr_register(intr_handler_t fn,void * arg)76 esp_err_t touch_pad_isr_register(intr_handler_t fn, void *arg)
77 {
78 ESP_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TOUCH_TAG, "Touch_Pad ISR null");
79 return rtc_isr_register(fn, arg, RTC_CNTL_TOUCH_INT_ST_M);
80 }
81
_touch_filter_iir(uint32_t in_now,uint32_t out_last,uint32_t k)82 static uint32_t _touch_filter_iir(uint32_t in_now, uint32_t out_last, uint32_t k)
83 {
84 if (k == 0) {
85 return in_now;
86 } else {
87 uint32_t out_now = (in_now + (k - 1) * out_last) / k;
88 return out_now;
89 }
90 }
91
touch_pad_set_filter_read_cb(filter_cb_t read_cb)92 esp_err_t touch_pad_set_filter_read_cb(filter_cb_t read_cb)
93 {
94 s_filter_cb = read_cb;
95 return ESP_OK;
96 }
97
touch_pad_filter_cb(void * arg)98 static void touch_pad_filter_cb(void *arg)
99 {
100 static uint32_t s_filtered_temp[TOUCH_PAD_MAX] = {0};
101
102 if (s_touch_pad_filter == NULL || rtc_touch_mux == NULL) {
103 return;
104 }
105 uint16_t val = 0;
106 touch_fsm_mode_t mode;
107 xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
108 touch_pad_get_fsm_mode(&mode);
109 for (int i = 0; i < TOUCH_PAD_MAX; i++) {
110 if ((s_touch_pad_init_bit >> i) & 0x1) {
111 _touch_pad_read(i, &val, mode);
112 s_touch_pad_filter->raw_val[i] = val;
113 s_filtered_temp[i] = s_filtered_temp[i] == 0 ? ((uint32_t)val << TOUCH_PAD_SHIFT_DEFAULT) : s_filtered_temp[i];
114 s_filtered_temp[i] = _touch_filter_iir((val << TOUCH_PAD_SHIFT_DEFAULT),
115 s_filtered_temp[i], TOUCH_PAD_FILTER_FACTOR_DEFAULT);
116 s_touch_pad_filter->filtered_val[i] = (s_filtered_temp[i] + TOUCH_PAD_SHIFT_ROUND_DEFAULT) >> TOUCH_PAD_SHIFT_DEFAULT;
117 }
118 }
119 xTimerReset(s_touch_pad_filter->timer, portMAX_DELAY);
120 xSemaphoreGive(rtc_touch_mux);
121 if (s_filter_cb) {
122 //return the raw data and filtered data.
123 s_filter_cb(s_touch_pad_filter->raw_val, s_touch_pad_filter->filtered_val);
124 }
125 }
126
touch_pad_set_meas_time(uint16_t sleep_cycle,uint16_t meas_cycle)127 esp_err_t touch_pad_set_meas_time(uint16_t sleep_cycle, uint16_t meas_cycle)
128 {
129 TOUCH_ENTER_CRITICAL();
130 touch_hal_set_meas_time(meas_cycle);
131 touch_hal_set_sleep_time(sleep_cycle);
132 TOUCH_EXIT_CRITICAL();
133
134 return ESP_OK;
135 }
136
touch_pad_get_meas_time(uint16_t * sleep_cycle,uint16_t * meas_cycle)137 esp_err_t touch_pad_get_meas_time(uint16_t *sleep_cycle, uint16_t *meas_cycle)
138 {
139 TOUCH_NULL_POINTER_CHECK(sleep_cycle, "sleep_cycle");
140 TOUCH_NULL_POINTER_CHECK(meas_cycle, "meas_cycle");
141 TOUCH_ENTER_CRITICAL();
142 touch_hal_get_meas_time(meas_cycle);
143 touch_hal_get_sleep_time(sleep_cycle);
144 TOUCH_EXIT_CRITICAL();
145
146 return ESP_OK;
147 }
148
touch_pad_set_trigger_mode(touch_trigger_mode_t mode)149 esp_err_t touch_pad_set_trigger_mode(touch_trigger_mode_t mode)
150 {
151 ESP_RETURN_ON_FALSE((mode < TOUCH_TRIGGER_MAX), ESP_ERR_INVALID_ARG, TOUCH_TAG, TOUCH_PARAM_CHECK_STR("mode"));
152 TOUCH_ENTER_CRITICAL();
153 touch_hal_set_trigger_mode(mode);
154 TOUCH_EXIT_CRITICAL();
155 return ESP_OK;
156 }
157
touch_pad_get_trigger_mode(touch_trigger_mode_t * mode)158 esp_err_t touch_pad_get_trigger_mode(touch_trigger_mode_t *mode)
159 {
160 TOUCH_NULL_POINTER_CHECK(mode, "mode");
161 touch_hal_get_trigger_mode(mode);
162 return ESP_OK;
163 }
164
touch_pad_set_trigger_source(touch_trigger_src_t src)165 esp_err_t touch_pad_set_trigger_source(touch_trigger_src_t src)
166 {
167 ESP_RETURN_ON_FALSE((src < TOUCH_TRIGGER_SOURCE_MAX), ESP_ERR_INVALID_ARG, TOUCH_TAG, TOUCH_PARAM_CHECK_STR("src"));
168 TOUCH_ENTER_CRITICAL();
169 touch_hal_set_trigger_source(src);
170 TOUCH_EXIT_CRITICAL();
171 return ESP_OK;
172 }
173
touch_pad_get_trigger_source(touch_trigger_src_t * src)174 esp_err_t touch_pad_get_trigger_source(touch_trigger_src_t *src)
175 {
176 TOUCH_NULL_POINTER_CHECK(src, "src");
177 touch_hal_get_trigger_source(src);
178 return ESP_OK;
179 }
180
touch_pad_set_group_mask(uint16_t set1_mask,uint16_t set2_mask,uint16_t en_mask)181 esp_err_t touch_pad_set_group_mask(uint16_t set1_mask, uint16_t set2_mask, uint16_t en_mask)
182 {
183 ESP_RETURN_ON_FALSE((set1_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch set1 bitmask error");
184 ESP_RETURN_ON_FALSE((set2_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch set2 bitmask error");
185 ESP_RETURN_ON_FALSE((en_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch work_en bitmask error");
186
187 TOUCH_ENTER_CRITICAL();
188 touch_hal_set_group_mask(set1_mask, set2_mask);
189 touch_hal_set_channel_mask(en_mask);
190 TOUCH_EXIT_CRITICAL();
191
192 return ESP_OK;
193 }
194
touch_pad_get_group_mask(uint16_t * set1_mask,uint16_t * set2_mask,uint16_t * en_mask)195 esp_err_t touch_pad_get_group_mask(uint16_t *set1_mask, uint16_t *set2_mask, uint16_t *en_mask)
196 {
197 TOUCH_NULL_POINTER_CHECK(set1_mask, "set1_mask");
198 TOUCH_NULL_POINTER_CHECK(set2_mask, "set2_mask");
199 TOUCH_NULL_POINTER_CHECK(en_mask, "en_mask");
200 TOUCH_ENTER_CRITICAL();
201 touch_hal_get_channel_mask(en_mask);
202 touch_hal_get_group_mask(set1_mask, set2_mask);
203 TOUCH_EXIT_CRITICAL();
204
205 return ESP_OK;
206 }
207
touch_pad_clear_group_mask(uint16_t set1_mask,uint16_t set2_mask,uint16_t en_mask)208 esp_err_t touch_pad_clear_group_mask(uint16_t set1_mask, uint16_t set2_mask, uint16_t en_mask)
209 {
210 ESP_RETURN_ON_FALSE((set1_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch set1 bitmask error");
211 ESP_RETURN_ON_FALSE((set2_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch set2 bitmask error");
212 ESP_RETURN_ON_FALSE((en_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch work_en bitmask error");
213
214 TOUCH_ENTER_CRITICAL();
215 touch_hal_clear_channel_mask(en_mask);
216 touch_hal_clear_group_mask(set1_mask, set2_mask);
217 TOUCH_EXIT_CRITICAL();
218 return ESP_OK;
219 }
220
touch_pad_intr_enable(void)221 esp_err_t touch_pad_intr_enable(void)
222 {
223 TOUCH_ENTER_CRITICAL();
224 touch_hal_intr_enable();
225 TOUCH_EXIT_CRITICAL();
226 return ESP_OK;
227 }
228
touch_pad_intr_disable(void)229 esp_err_t touch_pad_intr_disable(void)
230 {
231 TOUCH_ENTER_CRITICAL();
232 touch_hal_intr_disable();
233 TOUCH_EXIT_CRITICAL();
234 return ESP_OK;
235 }
236
touch_pad_intr_clear(void)237 esp_err_t touch_pad_intr_clear(void)
238 {
239 TOUCH_ENTER_CRITICAL();
240 touch_hal_intr_clear();
241 TOUCH_EXIT_CRITICAL();
242 return ESP_OK;
243 }
244
touch_pad_meas_is_done(void)245 bool touch_pad_meas_is_done(void)
246 {
247 return touch_hal_meas_is_done();
248 }
249
touch_pad_config(touch_pad_t touch_num,uint16_t threshold)250 esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold)
251 {
252 ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_FAIL, TOUCH_TAG, "Touch pad not initialized");
253 TOUCH_CHANNEL_CHECK(touch_num);
254 touch_fsm_mode_t mode;
255 touch_pad_io_init(touch_num);
256 TOUCH_ENTER_CRITICAL();
257 touch_hal_config(touch_num);
258 touch_hal_set_threshold(touch_num, threshold);
259 TOUCH_EXIT_CRITICAL();
260 touch_pad_get_fsm_mode(&mode);
261 if (TOUCH_FSM_MODE_SW == mode) {
262 touch_pad_clear_group_mask((1 << touch_num), (1 << touch_num), (1 << touch_num));
263 s_touch_pad_init_bit |= (1 << touch_num);
264 } else if (TOUCH_FSM_MODE_TIMER == mode) {
265 uint16_t sleep_time = 0;
266 uint16_t meas_cycle = 0;
267 uint32_t wait_time_ms = 0;
268 uint32_t wait_tick = 0;
269 uint32_t rtc_clk = rtc_clk_slow_freq_get_hz();
270 touch_pad_set_group_mask((1 << touch_num), (1 << touch_num), (1 << touch_num));
271 touch_pad_get_meas_time(&sleep_time, &meas_cycle);
272 //If the FSM mode is 'TOUCH_FSM_MODE_TIMER', The data will be ready after one measurement cycle
273 //after this function is executed, otherwise, the "touch_value" by "touch_pad_read" is 0.
274 wait_time_ms = sleep_time / (rtc_clk / 1000) + meas_cycle / (RTC_FAST_CLK_FREQ_APPROX / 1000);
275 wait_tick = wait_time_ms / portTICK_RATE_MS;
276 vTaskDelay(wait_tick ? wait_tick : 1);
277 s_touch_pad_init_bit |= (1 << touch_num);
278 } else {
279 return ESP_FAIL;
280 }
281 return ESP_OK;
282 }
283
touch_pad_init(void)284 esp_err_t touch_pad_init(void)
285 {
286 #ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2
287 ESP_LOGE(TOUCH_TAG, "Touch Pad can't work because it provides current to external XTAL");
288 return ESP_ERR_NOT_SUPPORTED;
289 #endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2
290 if (rtc_touch_mux == NULL) {
291 rtc_touch_mux = xSemaphoreCreateMutex();
292 }
293 if (rtc_touch_mux == NULL) {
294 return ESP_FAIL;
295 }
296 TOUCH_ENTER_CRITICAL();
297 touch_hal_init();
298 TOUCH_EXIT_CRITICAL();
299 return ESP_OK;
300 }
301
touch_pad_deinit(void)302 esp_err_t touch_pad_deinit(void)
303 {
304 ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_FAIL, TOUCH_TAG, "Touch pad not initialized");
305 if (s_touch_pad_filter) {
306 touch_pad_filter_stop();
307 touch_pad_filter_delete();
308 }
309 xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
310 s_touch_pad_init_bit = 0x0000;
311 TOUCH_ENTER_CRITICAL();
312 touch_hal_deinit();
313 TOUCH_EXIT_CRITICAL();
314 xSemaphoreGive(rtc_touch_mux);
315 vSemaphoreDelete(rtc_touch_mux);
316 rtc_touch_mux = NULL;
317 return ESP_OK;
318 }
319
_touch_pad_read(touch_pad_t touch_num,uint16_t * touch_value,touch_fsm_mode_t mode)320 static esp_err_t _touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value, touch_fsm_mode_t mode)
321 {
322 esp_err_t res = ESP_OK;
323 if (TOUCH_FSM_MODE_SW == mode) {
324 touch_pad_set_group_mask((1 << touch_num), (1 << touch_num), (1 << touch_num));
325 touch_pad_sw_start();
326 while (!touch_hal_meas_is_done()) {};
327 *touch_value = touch_hal_read_raw_data(touch_num);
328 touch_pad_clear_group_mask((1 << touch_num), (1 << touch_num), (1 << touch_num));
329 } else if (TOUCH_FSM_MODE_TIMER == mode) {
330 while (!touch_hal_meas_is_done()) {};
331 *touch_value = touch_hal_read_raw_data(touch_num);
332 } else {
333 res = ESP_FAIL;
334 }
335 if (*touch_value == 0) {
336 res = ESP_ERR_INVALID_STATE;
337 }
338 return res;
339 }
340
touch_pad_read(touch_pad_t touch_num,uint16_t * touch_value)341 esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value)
342 {
343 TOUCH_CHANNEL_CHECK(touch_num);
344 TOUCH_NULL_POINTER_CHECK(touch_value, "touch_value");
345 ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_FAIL, TOUCH_TAG, "Touch pad not initialized");
346
347 esp_err_t res = ESP_OK;
348 touch_fsm_mode_t mode;
349 touch_pad_get_fsm_mode(&mode);
350 xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
351 res = _touch_pad_read(touch_num, touch_value, mode);
352 xSemaphoreGive(rtc_touch_mux);
353 return res;
354 }
355
touch_pad_read_raw_data(touch_pad_t touch_num,uint16_t * touch_value)356 IRAM_ATTR esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint16_t *touch_value)
357 {
358 ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_FAIL, TOUCH_TAG, "Touch pad not initialized");
359 TOUCH_CHANNEL_CHECK(touch_num);
360 TOUCH_NULL_POINTER_CHECK(touch_value, "touch_value");
361 ESP_RETURN_ON_FALSE(s_touch_pad_filter, ESP_FAIL, TOUCH_TAG, "Touch pad filter not initialized");
362 *touch_value = s_touch_pad_filter->raw_val[touch_num];
363 if (*touch_value == 0) {
364 return ESP_ERR_INVALID_STATE;
365 }
366 return ESP_OK;
367 }
368
touch_pad_read_filtered(touch_pad_t touch_num,uint16_t * touch_value)369 IRAM_ATTR esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value)
370 {
371 ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_FAIL, TOUCH_TAG, "Touch pad not initialized");
372 TOUCH_CHANNEL_CHECK(touch_num);
373 TOUCH_NULL_POINTER_CHECK(touch_value, "touch_value");
374 ESP_RETURN_ON_FALSE(s_touch_pad_filter, ESP_FAIL, TOUCH_TAG, "Touch pad filter not initialized");
375 *touch_value = (s_touch_pad_filter->filtered_val[touch_num]);
376 if (*touch_value == 0) {
377 return ESP_ERR_INVALID_STATE;
378 }
379 return ESP_OK;
380 }
381
touch_pad_set_filter_period(uint32_t new_period_ms)382 esp_err_t touch_pad_set_filter_period(uint32_t new_period_ms)
383 {
384 ESP_RETURN_ON_FALSE(s_touch_pad_filter, ESP_ERR_INVALID_STATE, TOUCH_TAG, "Touch pad filter not initialized");
385 ESP_RETURN_ON_FALSE(new_period_ms > 0, ESP_ERR_INVALID_ARG, TOUCH_TAG, "Touch pad filter period error");
386 ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_ERR_INVALID_STATE, TOUCH_TAG, "Touch pad not initialized");
387
388 esp_err_t ret = ESP_OK;
389 xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
390 if (s_touch_pad_filter) {
391 xTimerChangePeriod(s_touch_pad_filter->timer, new_period_ms / portTICK_PERIOD_MS, portMAX_DELAY);
392 s_touch_pad_filter->period = new_period_ms;
393 } else {
394 ESP_LOGE(TOUCH_TAG, "Touch pad filter deleted");
395 ret = ESP_ERR_INVALID_STATE;
396 }
397 xSemaphoreGive(rtc_touch_mux);
398 return ret;
399 }
400
touch_pad_get_filter_period(uint32_t * p_period_ms)401 esp_err_t touch_pad_get_filter_period(uint32_t *p_period_ms)
402 {
403 ESP_RETURN_ON_FALSE(s_touch_pad_filter, ESP_ERR_INVALID_STATE, TOUCH_TAG, "Touch pad filter not initialized");
404 TOUCH_NULL_POINTER_CHECK(p_period_ms, "p_period_ms");
405 ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_ERR_INVALID_STATE, TOUCH_TAG, "Touch pad not initialized");
406
407 esp_err_t ret = ESP_OK;
408 xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
409 if (s_touch_pad_filter) {
410 *p_period_ms = s_touch_pad_filter->period;
411 } else {
412 ESP_LOGE(TOUCH_TAG, "Touch pad filter deleted");
413 ret = ESP_ERR_INVALID_STATE;
414 }
415 xSemaphoreGive(rtc_touch_mux);
416 return ret;
417 }
418
touch_pad_filter_start(uint32_t filter_period_ms)419 esp_err_t touch_pad_filter_start(uint32_t filter_period_ms)
420 {
421 ESP_RETURN_ON_FALSE(filter_period_ms >= portTICK_PERIOD_MS, ESP_ERR_INVALID_ARG, TOUCH_TAG, "Touch pad filter period error");
422 ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_ERR_INVALID_STATE, TOUCH_TAG, "Touch pad not initialized");
423
424 xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
425 if (s_touch_pad_filter == NULL) {
426 s_touch_pad_filter = (touch_pad_filter_t *) calloc(1, sizeof(touch_pad_filter_t));
427 if (s_touch_pad_filter == NULL) {
428 goto err_no_mem;
429 }
430 }
431 if (s_touch_pad_filter->timer == NULL) {
432 s_touch_pad_filter->timer = xTimerCreate("filter_tmr", filter_period_ms / portTICK_PERIOD_MS, pdFALSE,
433 NULL, (TimerCallbackFunction_t) touch_pad_filter_cb);
434 if (s_touch_pad_filter->timer == NULL) {
435 free(s_touch_pad_filter);
436 s_touch_pad_filter = NULL;
437 goto err_no_mem;
438 }
439 s_touch_pad_filter->period = filter_period_ms;
440 }
441 xSemaphoreGive(rtc_touch_mux);
442 touch_pad_filter_cb(NULL);
443 return ESP_OK;
444
445 err_no_mem:
446 xSemaphoreGive(rtc_touch_mux);
447 return ESP_ERR_NO_MEM;
448 }
449
touch_pad_filter_stop(void)450 esp_err_t touch_pad_filter_stop(void)
451 {
452 ESP_RETURN_ON_FALSE(s_touch_pad_filter, ESP_ERR_INVALID_STATE, TOUCH_TAG, "Touch pad filter not initialized");
453 ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_ERR_INVALID_STATE, TOUCH_TAG, "Touch pad not initialized");
454 esp_err_t ret = ESP_OK;
455 xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
456 if (s_touch_pad_filter) {
457 xTimerStop(s_touch_pad_filter->timer, portMAX_DELAY);
458 } else {
459 ESP_LOGE(TOUCH_TAG, "Touch pad filter deleted");
460 ret = ESP_ERR_INVALID_STATE;
461 }
462 xSemaphoreGive(rtc_touch_mux);
463 return ret;
464 }
465
touch_pad_filter_delete(void)466 esp_err_t touch_pad_filter_delete(void)
467 {
468 ESP_RETURN_ON_FALSE(s_touch_pad_filter, ESP_ERR_INVALID_STATE, TOUCH_TAG, "Touch pad filter not initialized");
469 ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_ERR_INVALID_STATE, TOUCH_TAG, "Touch pad not initialized");
470 xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
471 if (s_touch_pad_filter) {
472 if (s_touch_pad_filter->timer) {
473 xTimerStop(s_touch_pad_filter->timer, portMAX_DELAY);
474 xTimerDelete(s_touch_pad_filter->timer, portMAX_DELAY);
475 s_touch_pad_filter->timer = NULL;
476 }
477 free(s_touch_pad_filter);
478 s_touch_pad_filter = NULL;
479 }
480 xSemaphoreGive(rtc_touch_mux);
481 return ESP_OK;
482 }
483