fix(touch_pad): modify touch pad read function and touch_pad_deinit

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".
This commit is contained in:
Chu Shu Chen
2017-03-02 16:13:30 +08:00
parent 47d3759474
commit 194d4e9ffd
2 changed files with 47 additions and 8 deletions

View File

@@ -43,10 +43,21 @@ typedef intr_handle_t touch_isr_handle_t;
* *
*This function int touch pad module ,enable touch module *This function int touch pad module ,enable touch module
* *
* @return None * @return
* - ESP_OK Success
* - ESP_FAIL Touch pad init error
* *
*/ */
void touch_pad_init(); esp_err_t touch_pad_init();
/**
* @brief Uninstall TouchPad driver.
*
* @return
* - ESP_OK Success
* - ESP_FAIL Touch pad deinit error
*/
esp_err_t touch_pad_deinit();
/** /**
* @brief Configure touch pad interrupt threshold. * @brief Configure touch pad interrupt threshold.
@@ -60,6 +71,7 @@ void touch_pad_init();
* *
* @return - ESP_OK Success * @return - ESP_OK Success
* - ESP_ERR_INVALID_ARG Touch pad error * - 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); 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 * @return - ESP_OK Success
* - ESP_ERR_INVALID_ARG Touch pad error * - 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); esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t * touch_value);

View File

@@ -23,6 +23,7 @@
#include "dac.h" #include "dac.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/xtensa_api.h" #include "freertos/xtensa_api.h"
#include "freertos/semphr.h"
static const char *RTC_MODULE_TAG = "RTC_MODULE"; 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; portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED;
static xSemaphoreHandle rtc_touch_sem = NULL;
//Reg,Mux,Fun,IE,Up,Down,Rtc_number //Reg,Mux,Fun,IE,Up,Down,Rtc_number
const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = { 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) 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); 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_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); 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 //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 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); portEXIT_CRITICAL(&rtc_spinlock);
xSemaphoreGive(rtc_touch_sem);
return ESP_OK; 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) 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) 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); 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); portENTER_CRITICAL(&rtc_spinlock);
//clear touch force ,select the Touch mode is Timer //clear touch force ,select the Touch mode is Timer
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_EN_M);
@@ -407,11 +429,11 @@ 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 //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); SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_TOUCH_INT_ENA);
portEXIT_CRITICAL(&rtc_spinlock); portEXIT_CRITICAL(&rtc_spinlock);
xSemaphoreGive(rtc_touch_sem);
touch_pad_power_on(touch_num); touch_pad_power_on(touch_num);
toch_pad_io_init(touch_num); toch_pad_io_init(touch_num);
touch_pad_counter_init(touch_num); touch_pad_counter_init(touch_num);
touch_start(touch_num); touch_start(touch_num);
return ESP_OK; return ESP_OK;
} }
@@ -419,6 +441,8 @@ 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_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); uint32_t v0 = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
portENTER_CRITICAL(&rtc_spinlock); portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (touch_num))); 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_EN_M);
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_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); 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) {}; 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; 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; *touch_value = READ_PERI_REG(SENS_SAR_TOUCH_OUT1_REG + (touch_num / 2) * 4) >> shift;
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, v0); WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, v0);
//force oneTime test end //force oneTime test end
//clear touch force ,select the Touch mode is Timer //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_EN_M);
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_M); CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_M);
portEXIT_CRITICAL(&rtc_spinlock); portEXIT_CRITICAL(&rtc_spinlock);
xSemaphoreGive(rtc_touch_sem);
return ESP_OK; return ESP_OK;
} }