diff --git a/components/driver/touch_sensor/esp32/touch_sensor.c b/components/driver/touch_sensor/esp32/touch_sensor.c index abe55ba7cb..5e1798960a 100644 --- a/components/driver/touch_sensor/esp32/touch_sensor.c +++ b/components/driver/touch_sensor/esp32/touch_sensor.c @@ -55,9 +55,10 @@ static __attribute__((unused)) const char *TOUCH_TAG = "TOUCH_SENSOR"; #define TOUCH_NULL_POINTER_CHECK(p, name) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, TOUCH_TAG, "input param '"name"' is NULL") #define TOUCH_PARAM_CHECK_STR(s) ""s" parameter error" +static portMUX_TYPE s_filter_spinlock = portMUX_INITIALIZER_UNLOCKED; extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished. -#define TOUCH_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) -#define TOUCH_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) +#define TOUCH_ENTER_CRITICAL(spinlock) portENTER_CRITICAL(spinlock) +#define TOUCH_EXIT_CRITICAL(spinlock) portEXIT_CRITICAL(spinlock) /*--------------------------------------------------------------- Touch Pad @@ -97,52 +98,64 @@ esp_err_t touch_pad_set_filter_read_cb(filter_cb_t read_cb) static void touch_pad_filter_cb(void *arg) { - if (s_touch_pad_filter == NULL) { - return; - } - uint16_t val = 0; + uint16_t val[TOUCH_PAD_MAX] = {0}; + uint16_t filtered_val[TOUCH_PAD_MAX] = {0}; + bool filter_exist = true; touch_fsm_mode_t mode; touch_pad_get_fsm_mode(&mode); for (int i = 0; i < TOUCH_PAD_MAX; i++) { if ((s_touch_pad_init_bit >> i) & 0x1) { - _touch_pad_read(i, &val, mode); - s_touch_pad_filter->raw_val[i] = val; - s_touch_pad_filter->filter_last_val[i] = s_touch_pad_filter->filter_last_val[i] == 0 ? - ((uint32_t)val << TOUCH_PAD_SHIFT_DEFAULT) : s_touch_pad_filter->filter_last_val[i]; - s_touch_pad_filter->filter_last_val[i] = _touch_filter_iir((val << TOUCH_PAD_SHIFT_DEFAULT), - s_touch_pad_filter->filter_last_val[i], TOUCH_PAD_FILTER_FACTOR_DEFAULT); - s_touch_pad_filter->filtered_val[i] = - (s_touch_pad_filter->filter_last_val[i] + TOUCH_PAD_SHIFT_ROUND_DEFAULT) >> TOUCH_PAD_SHIFT_DEFAULT; + _touch_pad_read(i, &val[i], mode); } } - if (s_filter_cb) { + + TOUCH_ENTER_CRITICAL(&s_filter_spinlock); + if (s_touch_pad_filter) { + for (int i = 0; i < TOUCH_PAD_MAX; i++) { + if ((s_touch_pad_init_bit >> i) & 0x1) { + s_touch_pad_filter->raw_val[i] = val[i]; + s_touch_pad_filter->filter_last_val[i] = s_touch_pad_filter->filter_last_val[i] == 0 ? + ((uint32_t)val[i] << TOUCH_PAD_SHIFT_DEFAULT) : s_touch_pad_filter->filter_last_val[i]; + s_touch_pad_filter->filter_last_val[i] = _touch_filter_iir((val[i] << TOUCH_PAD_SHIFT_DEFAULT), + s_touch_pad_filter->filter_last_val[i], TOUCH_PAD_FILTER_FACTOR_DEFAULT); + s_touch_pad_filter->filtered_val[i] = + (s_touch_pad_filter->filter_last_val[i] + TOUCH_PAD_SHIFT_ROUND_DEFAULT) >> TOUCH_PAD_SHIFT_DEFAULT; + } + val[i] = s_touch_pad_filter->raw_val[i]; + filtered_val[i] = s_touch_pad_filter->filtered_val[i]; + } + } else { + filter_exist = false; + } + TOUCH_EXIT_CRITICAL(&s_filter_spinlock); + if (s_filter_cb && filter_exist) { //return the raw data and filtered data. - s_filter_cb(s_touch_pad_filter->raw_val, s_touch_pad_filter->filtered_val); + s_filter_cb(val, filtered_val); } } esp_err_t touch_pad_set_measurement_interval(uint16_t interval_cycle) { - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_set_sleep_time(interval_cycle); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } esp_err_t touch_pad_get_measurement_interval(uint16_t *interval_cycle) { TOUCH_NULL_POINTER_CHECK(interval_cycle, "interval_cycle"); - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_get_sleep_time(interval_cycle); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } esp_err_t touch_pad_set_measurement_clock_cycles(uint16_t clock_cycle) { - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_set_meas_time(clock_cycle); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } @@ -150,9 +163,9 @@ esp_err_t touch_pad_set_measurement_clock_cycles(uint16_t clock_cycle) esp_err_t touch_pad_get_measurement_clock_cycles(uint16_t *clock_cycle) { TOUCH_NULL_POINTER_CHECK(clock_cycle, "clock_cycle"); - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_get_meas_time(clock_cycle); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } @@ -176,9 +189,9 @@ esp_err_t touch_pad_get_meas_time(uint16_t *sleep_cycle, uint16_t *meas_cycle) esp_err_t touch_pad_set_trigger_mode(touch_trigger_mode_t mode) { ESP_RETURN_ON_FALSE((mode < TOUCH_TRIGGER_MAX), ESP_ERR_INVALID_ARG, TOUCH_TAG, TOUCH_PARAM_CHECK_STR("mode")); - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_set_trigger_mode(mode); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } @@ -192,9 +205,9 @@ esp_err_t touch_pad_get_trigger_mode(touch_trigger_mode_t *mode) esp_err_t touch_pad_set_trigger_source(touch_trigger_src_t src) { ESP_RETURN_ON_FALSE((src < TOUCH_TRIGGER_SOURCE_MAX), ESP_ERR_INVALID_ARG, TOUCH_TAG, TOUCH_PARAM_CHECK_STR("src")); - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_set_trigger_source(src); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } @@ -211,10 +224,10 @@ esp_err_t touch_pad_set_group_mask(uint16_t set1_mask, uint16_t set2_mask, uint1 ESP_RETURN_ON_FALSE((set2_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch set2 bitmask error"); ESP_RETURN_ON_FALSE((en_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch work_en bitmask error"); - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_set_group_mask(set1_mask, set2_mask); touch_hal_set_channel_mask(en_mask); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } @@ -224,10 +237,10 @@ esp_err_t touch_pad_get_group_mask(uint16_t *set1_mask, uint16_t *set2_mask, uin TOUCH_NULL_POINTER_CHECK(set1_mask, "set1_mask"); TOUCH_NULL_POINTER_CHECK(set2_mask, "set2_mask"); TOUCH_NULL_POINTER_CHECK(en_mask, "en_mask"); - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_get_channel_mask(en_mask); touch_hal_get_group_mask(set1_mask, set2_mask); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } @@ -238,34 +251,34 @@ esp_err_t touch_pad_clear_group_mask(uint16_t set1_mask, uint16_t set2_mask, uin ESP_RETURN_ON_FALSE((set2_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch set2 bitmask error"); ESP_RETURN_ON_FALSE((en_mask <= TOUCH_PAD_BIT_MASK_ALL), ESP_ERR_INVALID_ARG, TOUCH_TAG, "touch work_en bitmask error"); - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_clear_channel_mask(en_mask); touch_hal_clear_group_mask(set1_mask, set2_mask); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } esp_err_t touch_pad_intr_enable(void) { - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_intr_enable(); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } esp_err_t touch_pad_intr_disable(void) { - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_intr_disable(); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } esp_err_t touch_pad_intr_clear(void) { - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_intr_clear(); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } @@ -280,10 +293,10 @@ esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold) TOUCH_CHANNEL_CHECK(touch_num); touch_fsm_mode_t mode; touch_pad_io_init(touch_num); - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_config(touch_num); touch_hal_set_threshold(touch_num, threshold); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); touch_pad_get_fsm_mode(&mode); if (TOUCH_FSM_MODE_SW == mode) { 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) if (rtc_touch_mux == NULL) { return ESP_FAIL; } - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_init(); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); return ESP_OK; } @@ -341,12 +354,14 @@ esp_err_t touch_pad_deinit(void) s_touch_pad_filter->timer = NULL; } free(s_touch_pad_filter); + TOUCH_ENTER_CRITICAL(&s_filter_spinlock); s_touch_pad_filter = NULL; + TOUCH_EXIT_CRITICAL(&s_filter_spinlock); } s_touch_pad_init_bit = 0x0000; - TOUCH_ENTER_CRITICAL(); + TOUCH_ENTER_CRITICAL(&rtc_spinlock); touch_hal_deinit(); - TOUCH_EXIT_CRITICAL(); + TOUCH_EXIT_CRITICAL(&rtc_spinlock); xSemaphoreGive(rtc_touch_mux); vSemaphoreDelete(rtc_touch_mux); rtc_touch_mux = NULL; @@ -398,28 +413,40 @@ esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value) IRAM_ATTR esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint16_t *touch_value) { + esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_FAIL, TOUCH_TAG, "Touch pad not initialized"); TOUCH_CHANNEL_CHECK(touch_num); TOUCH_NULL_POINTER_CHECK(touch_value, "touch_value"); - ESP_RETURN_ON_FALSE(s_touch_pad_filter, ESP_FAIL, TOUCH_TAG, "Touch pad filter not initialized"); + xSemaphoreTake(rtc_touch_mux, portMAX_DELAY); + ESP_GOTO_ON_FALSE(s_touch_pad_filter, ESP_FAIL, err, TOUCH_TAG, "Touch pad filter not initialized"); + TOUCH_ENTER_CRITICAL(&s_filter_spinlock); *touch_value = s_touch_pad_filter->raw_val[touch_num]; + TOUCH_EXIT_CRITICAL(&s_filter_spinlock); if (*touch_value == 0) { - return ESP_ERR_INVALID_STATE; + ret = ESP_ERR_INVALID_STATE; } - return ESP_OK; +err: + xSemaphoreGive(rtc_touch_mux); + return ret; } IRAM_ATTR esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value) { + esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE(rtc_touch_mux, ESP_FAIL, TOUCH_TAG, "Touch pad not initialized"); TOUCH_CHANNEL_CHECK(touch_num); TOUCH_NULL_POINTER_CHECK(touch_value, "touch_value"); - ESP_RETURN_ON_FALSE(s_touch_pad_filter, ESP_FAIL, TOUCH_TAG, "Touch pad filter not initialized"); + xSemaphoreTake(rtc_touch_mux, portMAX_DELAY); + ESP_GOTO_ON_FALSE(s_touch_pad_filter, ESP_FAIL, err, TOUCH_TAG, "Touch pad filter not initialized"); + TOUCH_ENTER_CRITICAL(&s_filter_spinlock); *touch_value = (s_touch_pad_filter->filtered_val[touch_num]); + TOUCH_EXIT_CRITICAL(&s_filter_spinlock); if (*touch_value == 0) { - return ESP_ERR_INVALID_STATE; + ret = ESP_ERR_INVALID_STATE; } - return ESP_OK; +err: + xSemaphoreGive(rtc_touch_mux); + return ret; } esp_err_t touch_pad_set_filter_period(uint32_t new_period_ms) @@ -490,7 +517,9 @@ err_timer_start: esp_timer_delete(s_touch_pad_filter->timer); err_timer_create: free(s_touch_pad_filter); + TOUCH_ENTER_CRITICAL(&s_filter_spinlock); s_touch_pad_filter = NULL; + TOUCH_EXIT_CRITICAL(&s_filter_spinlock); err_no_mem: xSemaphoreGive(rtc_touch_mux); return ret; @@ -521,7 +550,9 @@ esp_err_t touch_pad_filter_delete(void) s_touch_pad_filter->timer = NULL; } free(s_touch_pad_filter); + TOUCH_ENTER_CRITICAL(&s_filter_spinlock); s_touch_pad_filter = NULL; + TOUCH_EXIT_CRITICAL(&s_filter_spinlock); err: xSemaphoreGive(rtc_touch_mux); return ret;