I have interfaced CPT112S via i2c to my esp32. the sensor gives an interrupt, from this gpio interrupt handler sends a queue to "gpio_task_example" Task, which will then read our touch buffer from sensor. i am giving this buffer data to "cpt112s_parse_event" and "cpt112s_button_event" for processing slider and touch events respectively.
following are related functions:
Code: Select all
#define I2C_MASTER_NUM I2C_NUM_0 //I2C_NUMBER(CONFIG_I2C_MASTER_PORT_NUM) /*!< I2C port number for master dev */
#define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define CPT112S_ADDRESS 0x09 /*!< ESP32 slave address, you can set any 7bit value */
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */
#define ESP_INTR_FLAG_DEFAULT 0
#define CPT112S_EVENT_TOUCH 0x00
#define CPT112S_EVENT_TOUCH_RELEASE 0x01
#define CPT112S_EVENT_SLIDER 0x02
#define CPT112S_EVENT_TYPE(x) (x & 0x0f)
#define CPT112S_EVENT_COUNTER(x) ((x & 0xf0) >> 4)
#define CPT112S_SLIDER_THRESHOLD 50
#define CPT112S_EVENT_SLIDER_POSITION(x, y) ((x << 8 | y))
static void cpt112s_button_event(uint8_t *event)
{
//0x04, 0x05, 0x06, 0x07, 0x08, 0x09,0xa0
// event [0], event [1] event [2]
//int validetor =0x00;
if (event[1] == 0x04)
{
if (event[0] % 2 == 1)
{
ESP_LOGI(TAG, "gpio release event[1] with value: 0x%02x ", event[1]);
// switch_value(1);
}
}
else if (event[1] == 0x05)
{
if (event[0] % 2 == 1)
{
ESP_LOGI(TAG, "gpio release event[1] with value: 0x%02x ", event[1]);
// switch_value(2);
}
}
else if (event[1] == 0x06)
{
if (event[0] % 2 == 1)
{
ESP_LOGI(TAG, "gpio release event[1] with value: 0x%02x ", event[1]);
// switch_value(3);
}
}
else if (event[1] == 0x07)
{
if (event[0] % 2 == 1)
{
ESP_LOGI(TAG, "gpio release event with value: 0x%02x ", event[1]);
// switch_value(4);
}
}
else if (event[1] == 0x08)
{
if (event[0] % 2 == 1)
{
ESP_LOGI(TAG, "gpio release event[1] with value: 0x%02x ", event[1]);
// switch_value(5);
}
}
else if (event[1] == 0x09)
{
if (event[0] % 2 == 1)
{
ESP_LOGI(TAG, "gpio release event[1] with value: 0x%02x ", event[1]);
// switch_value(6);
}
}
else
{
}
}
static void cpt112s_parse_event(uint8_t *event)
{
ESP_LOGI(TAG, "cpt112s_parse_event. ");
int eventType = CPT112S_EVENT_TYPE(event[0]);
static int16_t lastSliderPos = -1;
static uint32_t lastSliderTime = 0;
uint32_t currtime = xthal_get_ccount();
uint32_t diff = currtime - lastSliderTime;
if (CPT112S_EVENT_TOUCH == eventType)
{
ESP_LOGI(TAG, "eventType = EVENT_TOUCH ");
}
else if (CPT112S_EVENT_TOUCH_RELEASE == eventType)
{
ESP_LOGI(TAG, "eventType = EVENT_TOUCH_RELEASE ");
}
else if (CPT112S_EVENT_SLIDER == eventType)
{
ESP_LOGI(TAG, "eventType = EVENT_SLIDER ");
int currentPos = CPT112S_EVENT_SLIDER_POSITION(event[1], event[2]);
if (currentPos == 0xffff)
{
ESP_LOGI(TAG, "%s: SLIDER RELEASE", __func__);
//slider release, skip it
lastSliderPos = -1;
return;
}
if (lastSliderPos < 0)
{
//slider touch
lastSliderPos = currentPos;
lastSliderTime = currtime;
ESP_LOGI(TAG, "%d: SLIDER TOUCH: lastSliderPos %d, lastSliderTime %d", __LINE__, lastSliderPos, lastSliderTime);
return;
}
ESP_LOGI(TAG, "%d: SLIDER0: =====> lastSliderPos %d lastSliderTime %d", __LINE__, lastSliderPos, lastSliderTime);
ESP_LOGI(TAG, "%d: SLIDER1: =====> currentPos %d diff %d", __LINE__, currentPos, diff / 240000);
check_value(currentPos);
if (abs(currentPos - lastSliderPos) < CPT112S_SLIDER_THRESHOLD)
{
return;
}
lastSliderPos = currentPos;
lastSliderTime = currtime;
}
}
esp_err_t i2c_master_read_slave(uint8_t addr, uint8_t *buf)
{
esp_err_t ret = ESP_OK;
ESP_LOGD(TAG, "i2c_master_read_slave \n");
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ret = i2c_master_start(cmd);
if(ret != ESP_OK)
{
ESP_LOGI(TAG, "i2c_master_start error %s", esp_err_to_name(ret));
}
ret = i2c_master_write_byte(cmd, (CPT112S_ADDRESS << 1) | READ_BIT, ACK_CHECK_EN);
// ret = i2c_master_write_byte(cmd, (CPT112S_ADDRESS << 1) | READ_BIT, ACK_CHECK_DIS);
if(ret != ESP_OK)
{
ESP_LOGI(TAG, "i2c_master_write_byte error %s", esp_err_to_name(ret));
}
ret = i2c_master_read(cmd, buf, 2, ACK_VAL);
if(ret != ESP_OK)
{
ESP_LOGI(TAG, "i2c_master_read error %s", esp_err_to_name(ret));
}
ret = i2c_master_read_byte(cmd, &buf[2], NACK_VAL);
if(ret != ESP_OK)
{
ESP_LOGI(TAG, "i2c_master_read_byte error %s", esp_err_to_name(ret));
}
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 2000 / portTICK_RATE_MS);
if(ret != ESP_OK)
{
ESP_LOGI(TAG, "i2c_master_cmd_begin error %s", esp_err_to_name(ret));
}
i2c_cmd_link_delete(cmd);
return ret;
}
static void gpio_task_example(void *arg)
{
ESP_LOGI(TAG, "gpio_task_example");
uint32_t io_num;
esp_err_t ret;
for (;;)
{
if (xQueueReceiveFromISR(gpio_evt_queue, &io_num, portMAX_DELAY))
{
ret = i2c_master_read_slave(CPT112S_ADDRESS, &buf);
if(ret != ESP_OK)
{
// ESP_LOGI(TAG, "i2c_master_read_slave error %s", esp_err_to_name(ret));
}else{
ESP_LOGI(TAG, "i2c_master_read_slave %s", esp_err_to_name(ret));
cpt112s_parse_event(buf);
cpt112s_button_event(buf);
}
}
vTaskDelay(100 / portTICK_RATE_MS);
}
vTaskDelete(NULL);
}
static esp_err_t i2c_master_init()
{
ESP_LOGI(TAG, "i2c_master_init");
int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = CPT_I2C_SDA;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = CPT_I2C_SCL;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
i2c_param_config(i2c_master_port, &conf);
return i2c_driver_install(i2c_master_port, conf.mode,
I2C_MASTER_RX_BUF_DISABLE,
I2C_MASTER_TX_BUF_DISABLE, 0);
}
The the i2c settings and functional logic used is same on other idf 3.3 and idf 4.2. on the idf 3.3 i am able to read data from sensor successfully even in the case of slider.