Skip to content

Commit 68ac1f5

Browse files
committed
fix(legacy_touch): fixed the concurrent issue in esp32 touch driver
1 parent 8a9d659 commit 68ac1f5

File tree

1 file changed

+83
-52
lines changed

1 file changed

+83
-52
lines changed

components/driver/touch_sensor/esp32/touch_sensor.c

Lines changed: 83 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,10 @@ static __attribute__((unused)) const char *TOUCH_TAG = "TOUCH_SENSOR";
5555
#define TOUCH_NULL_POINTER_CHECK(p, name) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, TOUCH_TAG, "input param '"name"' is NULL")
5656
#define TOUCH_PARAM_CHECK_STR(s) ""s" parameter error"
5757

58+
static portMUX_TYPE s_filter_spinlock = portMUX_INITIALIZER_UNLOCKED;
5859
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)
60+
#define TOUCH_ENTER_CRITICAL(spinlock) portENTER_CRITICAL(spinlock)
61+
#define TOUCH_EXIT_CRITICAL(spinlock) portEXIT_CRITICAL(spinlock)
6162

6263
/*---------------------------------------------------------------
6364
Touch Pad
@@ -97,62 +98,74 @@ esp_err_t touch_pad_set_filter_read_cb(filter_cb_t read_cb)
9798

9899
static void touch_pad_filter_cb(void *arg)
99100
{
100-
if (s_touch_pad_filter == NULL) {
101-
return;
102-
}
103-
uint16_t val = 0;
101+
uint16_t val[TOUCH_PAD_MAX] = {0};
102+
uint16_t filtered_val[TOUCH_PAD_MAX] = {0};
103+
bool filter_exist = true;
104104
touch_fsm_mode_t mode;
105105
touch_pad_get_fsm_mode(&mode);
106106
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
107107
if ((s_touch_pad_init_bit >> i) & 0x1) {
108-
_touch_pad_read(i, &val, mode);
109-
s_touch_pad_filter->raw_val[i] = val;
110-
s_touch_pad_filter->filter_last_val[i] = s_touch_pad_filter->filter_last_val[i] == 0 ?
111-
((uint32_t)val << TOUCH_PAD_SHIFT_DEFAULT) : s_touch_pad_filter->filter_last_val[i];
112-
s_touch_pad_filter->filter_last_val[i] = _touch_filter_iir((val << TOUCH_PAD_SHIFT_DEFAULT),
113-
s_touch_pad_filter->filter_last_val[i], TOUCH_PAD_FILTER_FACTOR_DEFAULT);
114-
s_touch_pad_filter->filtered_val[i] =
115-
(s_touch_pad_filter->filter_last_val[i] + TOUCH_PAD_SHIFT_ROUND_DEFAULT) >> TOUCH_PAD_SHIFT_DEFAULT;
108+
_touch_pad_read(i, &val[i], mode);
116109
}
117110
}
118-
if (s_filter_cb) {
111+
112+
TOUCH_ENTER_CRITICAL(&s_filter_spinlock);
113+
if (s_touch_pad_filter) {
114+
for (int i = 0; i < TOUCH_PAD_MAX; i++) {
115+
if ((s_touch_pad_init_bit >> i) & 0x1) {
116+
s_touch_pad_filter->raw_val[i] = val[i];
117+
s_touch_pad_filter->filter_last_val[i] = s_touch_pad_filter->filter_last_val[i] == 0 ?
118+
((uint32_t)val[i] << TOUCH_PAD_SHIFT_DEFAULT) : s_touch_pad_filter->filter_last_val[i];
119+
s_touch_pad_filter->filter_last_val[i] = _touch_filter_iir((val[i] << TOUCH_PAD_SHIFT_DEFAULT),
120+
s_touch_pad_filter->filter_last_val[i], TOUCH_PAD_FILTER_FACTOR_DEFAULT);
121+
s_touch_pad_filter->filtered_val[i] =
122+
(s_touch_pad_filter->filter_last_val[i] + TOUCH_PAD_SHIFT_ROUND_DEFAULT) >> TOUCH_PAD_SHIFT_DEFAULT;
123+
}
124+
val[i] = s_touch_pad_filter->raw_val[i];
125+
filtered_val[i] = s_touch_pad_filter->filtered_val[i];
126+
}
127+
} else {
128+
filter_exist = false;
129+
}
130+
TOUCH_EXIT_CRITICAL(&s_filter_spinlock);
131+
if (s_filter_cb && filter_exist) {
119132
//return the raw data and filtered data.
120-
s_filter_cb(s_touch_pad_filter->raw_val, s_touch_pad_filter->filtered_val);
133+
s_filter_cb(val, filtered_val);
121134
}
122135
}
123136

124137
esp_err_t touch_pad_set_measurement_interval(uint16_t interval_cycle)
125138
{
126-
TOUCH_ENTER_CRITICAL();
139+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
127140
touch_hal_set_sleep_time(interval_cycle);
128-
TOUCH_EXIT_CRITICAL();
141+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
129142
return ESP_OK;
130143
}
131144

132145
esp_err_t touch_pad_get_measurement_interval(uint16_t *interval_cycle)
133146
{
134147
TOUCH_NULL_POINTER_CHECK(interval_cycle, "interval_cycle");
135-
TOUCH_ENTER_CRITICAL();
148+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
136149
touch_hal_get_sleep_time(interval_cycle);
137-
TOUCH_EXIT_CRITICAL();
150+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
138151
return ESP_OK;
139152
}
140153

141154
esp_err_t touch_pad_set_measurement_clock_cycles(uint16_t clock_cycle)
142155
{
143-
TOUCH_ENTER_CRITICAL();
156+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
144157
touch_hal_set_meas_time(clock_cycle);
145-
TOUCH_EXIT_CRITICAL();
158+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
146159

147160
return ESP_OK;
148161
}
149162

150163
esp_err_t touch_pad_get_measurement_clock_cycles(uint16_t *clock_cycle)
151164
{
152165
TOUCH_NULL_POINTER_CHECK(clock_cycle, "clock_cycle");
153-
TOUCH_ENTER_CRITICAL();
166+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
154167
touch_hal_get_meas_time(clock_cycle);
155-
TOUCH_EXIT_CRITICAL();
168+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
156169

157170
return ESP_OK;
158171
}
@@ -176,9 +189,9 @@ esp_err_t touch_pad_get_meas_time(uint16_t *sleep_cycle, uint16_t *meas_cycle)
176189
esp_err_t touch_pad_set_trigger_mode(touch_trigger_mode_t mode)
177190
{
178191
ESP_RETURN_ON_FALSE((mode < TOUCH_TRIGGER_MAX), ESP_ERR_INVALID_ARG, TOUCH_TAG, TOUCH_PARAM_CHECK_STR("mode"));
179-
TOUCH_ENTER_CRITICAL();
192+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
180193
touch_hal_set_trigger_mode(mode);
181-
TOUCH_EXIT_CRITICAL();
194+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
182195
return ESP_OK;
183196
}
184197

@@ -192,9 +205,9 @@ esp_err_t touch_pad_get_trigger_mode(touch_trigger_mode_t *mode)
192205
esp_err_t touch_pad_set_trigger_source(touch_trigger_src_t src)
193206
{
194207
ESP_RETURN_ON_FALSE((src < TOUCH_TRIGGER_SOURCE_MAX), ESP_ERR_INVALID_ARG, TOUCH_TAG, TOUCH_PARAM_CHECK_STR("src"));
195-
TOUCH_ENTER_CRITICAL();
208+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
196209
touch_hal_set_trigger_source(src);
197-
TOUCH_EXIT_CRITICAL();
210+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
198211
return ESP_OK;
199212
}
200213

@@ -211,10 +224,10 @@ esp_err_t touch_pad_set_group_mask(uint16_t set1_mask, uint16_t set2_mask, uint1
211224
ESP_RETURN_ON_FALSE((set2_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch set2 bitmask error");
212225
ESP_RETURN_ON_FALSE((en_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch work_en bitmask error");
213226

214-
TOUCH_ENTER_CRITICAL();
227+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
215228
touch_hal_set_group_mask(set1_mask, set2_mask);
216229
touch_hal_set_channel_mask(en_mask);
217-
TOUCH_EXIT_CRITICAL();
230+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
218231

219232
return ESP_OK;
220233
}
@@ -224,10 +237,10 @@ esp_err_t touch_pad_get_group_mask(uint16_t *set1_mask, uint16_t *set2_mask, uin
224237
TOUCH_NULL_POINTER_CHECK(set1_mask, "set1_mask");
225238
TOUCH_NULL_POINTER_CHECK(set2_mask, "set2_mask");
226239
TOUCH_NULL_POINTER_CHECK(en_mask, "en_mask");
227-
TOUCH_ENTER_CRITICAL();
240+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
228241
touch_hal_get_channel_mask(en_mask);
229242
touch_hal_get_group_mask(set1_mask, set2_mask);
230-
TOUCH_EXIT_CRITICAL();
243+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
231244

232245
return ESP_OK;
233246
}
@@ -238,34 +251,34 @@ esp_err_t touch_pad_clear_group_mask(uint16_t set1_mask, uint16_t set2_mask, uin
238251
ESP_RETURN_ON_FALSE((set2_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch set2 bitmask error");
239252
ESP_RETURN_ON_FALSE((en_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch work_en bitmask error");
240253

241-
TOUCH_ENTER_CRITICAL();
254+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
242255
touch_hal_clear_channel_mask(en_mask);
243256
touch_hal_clear_group_mask(set1_mask, set2_mask);
244-
TOUCH_EXIT_CRITICAL();
257+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
245258
return ESP_OK;
246259
}
247260

248261
esp_err_t touch_pad_intr_enable(void)
249262
{
250-
TOUCH_ENTER_CRITICAL();
263+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
251264
touch_hal_intr_enable();
252-
TOUCH_EXIT_CRITICAL();
265+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
253266
return ESP_OK;
254267
}
255268

256269
esp_err_t touch_pad_intr_disable(void)
257270
{
258-
TOUCH_ENTER_CRITICAL();
271+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
259272
touch_hal_intr_disable();
260-
TOUCH_EXIT_CRITICAL();
273+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
261274
return ESP_OK;
262275
}
263276

264277
esp_err_t touch_pad_intr_clear(void)
265278
{
266-
TOUCH_ENTER_CRITICAL();
279+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
267280
touch_hal_intr_clear();
268-
TOUCH_EXIT_CRITICAL();
281+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
269282
return ESP_OK;
270283
}
271284

@@ -280,10 +293,10 @@ esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold)
280293
TOUCH_CHANNEL_CHECK(touch_num);
281294
touch_fsm_mode_t mode;
282295
touch_pad_io_init(touch_num);
283-
TOUCH_ENTER_CRITICAL();
296+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
284297
touch_hal_config(touch_num);
285298
touch_hal_set_threshold(touch_num, threshold);
286-
TOUCH_EXIT_CRITICAL();
299+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
287300
touch_pad_get_fsm_mode(&mode);
288301
if (TOUCH_FSM_MODE_SW == mode) {
289302
touch_pad_clear_group_mask((1 << touch_num), (1 << touch_num), (1 << touch_num));
@@ -323,9 +336,9 @@ esp_err_t touch_pad_init(void)
323336
if (rtc_touch_mux == NULL) {
324337
return ESP_FAIL;
325338
}
326-
TOUCH_ENTER_CRITICAL();
339+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
327340
touch_hal_init();
328-
TOUCH_EXIT_CRITICAL();
341+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
329342
return ESP_OK;
330343
}
331344

@@ -341,12 +354,14 @@ esp_err_t touch_pad_deinit(void)
341354
s_touch_pad_filter->timer = NULL;
342355
}
343356
free(s_touch_pad_filter);
357+
TOUCH_ENTER_CRITICAL(&s_filter_spinlock);
344358
s_touch_pad_filter = NULL;
359+
TOUCH_EXIT_CRITICAL(&s_filter_spinlock);
345360
}
346361
s_touch_pad_init_bit = 0x0000;
347-
TOUCH_ENTER_CRITICAL();
362+
TOUCH_ENTER_CRITICAL(&rtc_spinlock);
348363
touch_hal_deinit();
349-
TOUCH_EXIT_CRITICAL();
364+
TOUCH_EXIT_CRITICAL(&rtc_spinlock);
350365
xSemaphoreGive(rtc_touch_mux);
351366
vSemaphoreDelete(rtc_touch_mux);
352367
rtc_touch_mux = NULL;
@@ -398,28 +413,40 @@ esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value)
398413

399414
IRAM_ATTR esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint16_t *touch_value)
400415
{
416+
esp_err_t ret = ESP_OK;
401417
ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_FAIL, TOUCH_TAG, "Touch pad not initialized");
402418
TOUCH_CHANNEL_CHECK(touch_num);
403419
TOUCH_NULL_POINTER_CHECK(touch_value, "touch_value");
404-
ESP_RETURN_ON_FALSE(s_touch_pad_filter, ESP_FAIL, TOUCH_TAG, "Touch pad filter not initialized");
420+
xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
421+
ESP_GOTO_ON_FALSE(s_touch_pad_filter, ESP_FAIL, err, TOUCH_TAG, "Touch pad filter not initialized");
422+
TOUCH_ENTER_CRITICAL(&s_filter_spinlock);
405423
*touch_value = s_touch_pad_filter->raw_val[touch_num];
424+
TOUCH_EXIT_CRITICAL(&s_filter_spinlock);
406425
if (*touch_value == 0) {
407-
return ESP_ERR_INVALID_STATE;
426+
ret = ESP_ERR_INVALID_STATE;
408427
}
409-
return ESP_OK;
428+
err:
429+
xSemaphoreGive(rtc_touch_mux);
430+
return ret;
410431
}
411432

412433
IRAM_ATTR esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value)
413434
{
435+
esp_err_t ret = ESP_OK;
414436
ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_FAIL, TOUCH_TAG, "Touch pad not initialized");
415437
TOUCH_CHANNEL_CHECK(touch_num);
416438
TOUCH_NULL_POINTER_CHECK(touch_value, "touch_value");
417-
ESP_RETURN_ON_FALSE(s_touch_pad_filter, ESP_FAIL, TOUCH_TAG, "Touch pad filter not initialized");
439+
xSemaphoreTake(rtc_touch_mux, portMAX_DELAY);
440+
ESP_GOTO_ON_FALSE(s_touch_pad_filter, ESP_FAIL, err, TOUCH_TAG, "Touch pad filter not initialized");
441+
TOUCH_ENTER_CRITICAL(&s_filter_spinlock);
418442
*touch_value = (s_touch_pad_filter->filtered_val[touch_num]);
443+
TOUCH_EXIT_CRITICAL(&s_filter_spinlock);
419444
if (*touch_value == 0) {
420-
return ESP_ERR_INVALID_STATE;
445+
ret = ESP_ERR_INVALID_STATE;
421446
}
422-
return ESP_OK;
447+
err:
448+
xSemaphoreGive(rtc_touch_mux);
449+
return ret;
423450
}
424451

425452
esp_err_t touch_pad_set_filter_period(uint32_t new_period_ms)
@@ -490,7 +517,9 @@ esp_err_t touch_pad_filter_start(uint32_t filter_period_ms)
490517
esp_timer_delete(s_touch_pad_filter->timer);
491518
err_timer_create:
492519
free(s_touch_pad_filter);
520+
TOUCH_ENTER_CRITICAL(&s_filter_spinlock);
493521
s_touch_pad_filter = NULL;
522+
TOUCH_EXIT_CRITICAL(&s_filter_spinlock);
494523
err_no_mem:
495524
xSemaphoreGive(rtc_touch_mux);
496525
return ret;
@@ -523,7 +552,9 @@ esp_err_t touch_pad_filter_delete(void)
523552
s_touch_pad_filter->timer = NULL;
524553
}
525554
free(s_touch_pad_filter);
555+
TOUCH_ENTER_CRITICAL(&s_filter_spinlock);
526556
s_touch_pad_filter = NULL;
557+
TOUCH_EXIT_CRITICAL(&s_filter_spinlock);
527558
err:
528559
xSemaphoreGive(rtc_touch_mux);
529560
return ret;

0 commit comments

Comments
 (0)