Merge branch 'bugfix/touch_pad_read_takes_too_much_time' into 'master'

modify touch pad read function

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".

See merge request !543
This commit is contained in:
Ivan Grokhotkov 2017-03-21 14:46:30 +08:00
commit e4e8a903c3
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
*
* @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.
@ -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);

View 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;
}