]> granicus.if.org Git - esp-idf/commitdiff
fix(touch_pad): modify touch pad read function and touch_pad_deinit
authorChu Shu Chen <chushuchen@espressif.com>
Thu, 2 Mar 2017 08:13:30 +0000 (16:13 +0800)
committerChu Shu Chen <chushuchen@espressif.com>
Sat, 11 Mar 2017 03:42:44 +0000 (11:42 +0800)
The touch pad read function taks too much time within spin lock waiting for the "done bit". (about 7.6ms as we tested)
So we try to use a mutex on the touch read function and any other functions might change the "done bit".

components/driver/include/driver/touch_pad.h
components/driver/rtc_module.c

index 4f78b2351be4b2f73a313a6280abc1454e4d91d7..e880ff611f2ae4412f8cab3ec3d9f9dd0540882a 100644 (file)
@@ -43,10 +43,21 @@ typedef intr_handle_t touch_isr_handle_t;
  *
  *This function int touch pad module ,enable touch module
  *
- * @return    None
+ * @return
+ *     - ESP_OK Success
+ *     - ESP_FAIL Touch pad init error
+ *
+ */
+esp_err_t touch_pad_init();
+
+/**
+ * @brief Uninstall TouchPad driver.
  *
+ * @return
+ *     - ESP_OK   Success
+ *     - ESP_FAIL Touch pad deinit error
  */
-void touch_pad_init();
+esp_err_t touch_pad_deinit();
 
 /**
  * @brief       Configure touch pad interrupt threshold.
@@ -60,6 +71,7 @@ void touch_pad_init();
  *
  * @return    - ESP_OK Success
  *            - ESP_ERR_INVALID_ARG Touch pad error
+ *            - ESP_FAIL Touch pad not initialized
  *
  */
 esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold);
@@ -76,6 +88,7 @@ esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold);
  *
  *  @return   - ESP_OK Success
  *            - ESP_ERR_INVALID_ARG Touch pad error
+ *            - ESP_FAIL Touch pad not initialized
  *
  */
 esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t * touch_value);
index 3d3cab06828f346919fed3754228e79faf4c567c..2a8204db9d9f672a5debcecc5418a685fee99c9f 100644 (file)
@@ -23,6 +23,7 @@
 #include "dac.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/xtensa_api.h"
+#include "freertos/semphr.h"
 
 static const char *RTC_MODULE_TAG = "RTC_MODULE";
 
@@ -37,6 +38,7 @@ static const char *RTC_MODULE_TAG = "RTC_MODULE";
 }
 
 portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED;
+static xSemaphoreHandle rtc_touch_sem = NULL;
 
 //Reg,Mux,Fun,IE,Up,Down,Rtc_number
 const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = {
@@ -323,6 +325,7 @@ static esp_err_t touch_pad_get_io_num(touch_pad_t touch_num, gpio_num_t *gpio_nu
 
 static esp_err_t touch_pad_init_config(uint16_t sleep_cycle, uint16_t sample_cycle_num)
 {
+    xSemaphoreTake(rtc_touch_sem, portMAX_DELAY);
     portENTER_CRITICAL(&rtc_spinlock);
     SET_PERI_REG_BITS(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS, 1, RTC_IO_TOUCH_XPD_BIAS_S);
     SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR);
@@ -336,13 +339,30 @@ static esp_err_t touch_pad_init_config(uint16_t sleep_cycle, uint16_t sample_cyc
     //Touch Pad Measure Time= 8Mhz
     SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_MEAS_DELAY, sample_cycle_num, SENS_TOUCH_MEAS_DELAY_S); //8Mhz
     portEXIT_CRITICAL(&rtc_spinlock);
-
+    xSemaphoreGive(rtc_touch_sem);
     return ESP_OK;
 }
 
-void touch_pad_init()
+esp_err_t touch_pad_init()
 {
-    touch_pad_init_config(TOUCH_PAD_SLEEP_CYCLE_CONFIG, TOUCH_PAD_MEASURE_CYCLE_CONFIG);
+    if(rtc_touch_sem == NULL) {
+        rtc_touch_sem = xSemaphoreCreateMutex();
+    }
+    if(rtc_touch_sem == NULL) {
+        return ESP_FAIL;
+    }
+    return touch_pad_init_config(TOUCH_PAD_SLEEP_CYCLE_CONFIG, TOUCH_PAD_MEASURE_CYCLE_CONFIG);
+}
+
+esp_err_t touch_pad_deinit()
+{
+
+    if(rtc_touch_sem == NULL) {
+        return ESP_FAIL;
+    }
+    vSemaphoreDelete(rtc_touch_sem);
+    rtc_touch_sem=NULL;
+    return ESP_OK;
 }
 
 static void touch_pad_counter_init(touch_pad_t touch_num)
@@ -391,7 +411,9 @@ static esp_err_t touch_start(touch_pad_t touch_num)
 
 esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold)
 {
+    RTC_MODULE_CHECK(rtc_touch_sem != NULL, "Touch pad not initialized", ESP_FAIL);
     RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
+    xSemaphoreTake(rtc_touch_sem, portMAX_DELAY);
     portENTER_CRITICAL(&rtc_spinlock);
     //clear touch force ,select the Touch mode is Timer
     CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M);
@@ -407,18 +429,20 @@ esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold)
     //Enable Rtc Touch Module Intr,the Interrupt need Rtc out  Enable
     SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_TOUCH_INT_ENA);
     portEXIT_CRITICAL(&rtc_spinlock);
+    xSemaphoreGive(rtc_touch_sem);
     touch_pad_power_on(touch_num);
     toch_pad_io_init(touch_num);
     touch_pad_counter_init(touch_num);
     touch_start(touch_num);
-
     return ESP_OK;
 }
 
 esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value)
 {
     RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG);
-    RTC_MODULE_CHECK(touch_value!=NULL, "touch_value", ESP_ERR_INVALID_ARG);
+    RTC_MODULE_CHECK(touch_value != NULL, "touch_value", ESP_ERR_INVALID_ARG);
+    RTC_MODULE_CHECK(rtc_touch_sem != NULL, "Touch pad not initialized", ESP_FAIL);
+    xSemaphoreTake(rtc_touch_sem, portMAX_DELAY);
     uint32_t v0 = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
     portENTER_CRITICAL(&rtc_spinlock);
     SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (touch_num)));
@@ -432,16 +456,18 @@ esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value)
     SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M);
     SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_M);
     SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_XPD_WAIT, 10, SENS_TOUCH_XPD_WAIT_S);
+    portEXIT_CRITICAL(&rtc_spinlock);
     while (GET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_DONE) == 0) {};
     uint8_t shift = (touch_num & 1) ? SENS_TOUCH_MEAS_OUT1_S : SENS_TOUCH_MEAS_OUT0_S;
     *touch_value = READ_PERI_REG(SENS_SAR_TOUCH_OUT1_REG + (touch_num / 2) * 4) >> shift;
     WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, v0);
     //force oneTime test end
     //clear touch force ,select the Touch mode is Timer
+    portENTER_CRITICAL(&rtc_spinlock);
     CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M);
     CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_M);
     portEXIT_CRITICAL(&rtc_spinlock);
-
+    xSemaphoreGive(rtc_touch_sem);
     return ESP_OK;
 }