forked from espressif/esp-bsp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request espressif#123 from Lzw655/feature/add_lcd_touch_cs…
…t816s lcd_touch: add new component CST816S
- Loading branch information
Showing
21 changed files
with
531 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
idf_component_register(SRCS "esp_lcd_touch_cst816s.c" INCLUDE_DIRS "include" REQUIRES "esp_lcd") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# ESP LCD Touch CST816S Controller | ||
|
||
[![Component Registry](https://components.espressif.com/components/espressif/esp_lcd_touch_cst816s/badge.svg)](https://components.espressif.com/components/espressif/esp_lcd_touch_cst816s) | ||
|
||
Implementation of the CST816S touch controller with esp_lcd_touch component. | ||
|
||
| Touch controller | Communication interface | Component name | Link to datasheet | | ||
| :--------------: | :---------------------: | :-------------------: | :------------------------------------------------------------------------: | | ||
| CST816S | I2C | esp_lcd_touch_cst816s | [datasheet](https://www.buydisplay.com/download/ic/DS-CST816S_DS_V1.3.pdf) | | ||
|
||
## Add to project | ||
|
||
Packages from this repository are uploaded to [Espressif's component service](https://components.espressif.com/). | ||
You can add them to your project via `idf.py add-dependancy`, e.g. | ||
``` | ||
idf.py add-dependency esp_lcd_touch_cst816s==1.0.0 | ||
``` | ||
|
||
Alternatively, you can create `idf_component.yml`. More is in [Espressif's documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html). | ||
|
||
## Example use | ||
|
||
Initialization of the touch component. | ||
|
||
``` | ||
esp_lcd_panel_io_i2c_config_t io_config = ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG(); | ||
esp_lcd_touch_config_t tp_cfg = { | ||
.x_max = CONFIG_LCD_HRES, | ||
.y_max = CONFIG_LCD_VRES, | ||
.rst_gpio_num = -1, | ||
.int_gpio_num = -1, | ||
.levels = { | ||
.reset = 0, | ||
.interrupt = 0, | ||
}, | ||
.flags = { | ||
.swap_xy = 0, | ||
.mirror_x = 0, | ||
.mirror_y = 0, | ||
}, | ||
}; | ||
esp_lcd_touch_handle_t tp; | ||
esp_lcd_touch_new_i2c_cst816s(io_handle, &tp_cfg, &tp); | ||
``` | ||
|
||
Read data from the touch controller and store it in RAM memory. It should be called regularly in poll. | ||
|
||
``` | ||
esp_lcd_touch_read_data(tp); | ||
``` | ||
|
||
Get one X and Y coordinates with strength of touch. | ||
|
||
``` | ||
uint16_t touch_x[1]; | ||
uint16_t touch_y[1]; | ||
uint16_t touch_strength[1]; | ||
uint8_t touch_cnt = 0; | ||
bool touchpad_pressed = esp_lcd_touch_get_coordinates(tp, touch_x, touch_y, touch_strength, &touch_cnt, 1); | ||
``` |
178 changes: 178 additions & 0 deletions
178
components/lcd_touch/esp_lcd_touch_cst816s/esp_lcd_touch_cst816s.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <inttypes.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include "freertos/FreeRTOS.h" | ||
#include "freertos/task.h" | ||
#include "driver/gpio.h" | ||
#include "driver/i2c.h" | ||
#include "esp_system.h" | ||
#include "esp_err.h" | ||
#include "esp_log.h" | ||
#include "esp_check.h" | ||
#include "esp_lcd_panel_io.h" | ||
#include "esp_lcd_touch.h" | ||
|
||
#define POINT_NUM_MAX (1) | ||
|
||
#define DATA_START_REG (0x02) | ||
#define CHIP_ID_REG (0xA7) | ||
|
||
static const char *TAG = "CST816S"; | ||
|
||
static esp_err_t read_data(esp_lcd_touch_handle_t tp); | ||
static bool get_xy(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, uint16_t *strength, uint8_t *point_num, uint8_t max_point_num); | ||
static esp_err_t del(esp_lcd_touch_handle_t tp); | ||
|
||
static esp_err_t i2c_read_bytes(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len); | ||
|
||
static esp_err_t reset(esp_lcd_touch_handle_t tp); | ||
static esp_err_t read_id(esp_lcd_touch_handle_t tp); | ||
|
||
esp_err_t esp_lcd_touch_new_i2c_cst816s(const esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *config, esp_lcd_touch_handle_t *tp) | ||
{ | ||
ESP_RETURN_ON_FALSE(io, ESP_ERR_INVALID_ARG, TAG, "Invalid io"); | ||
ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "Invalid config"); | ||
ESP_RETURN_ON_FALSE(tp, ESP_ERR_INVALID_ARG, TAG, "Invalid touch handle"); | ||
|
||
/* Prepare main structure */ | ||
esp_err_t ret = ESP_OK; | ||
esp_lcd_touch_handle_t cst816s = calloc(1, sizeof(esp_lcd_touch_t)); | ||
ESP_GOTO_ON_FALSE(cst816s, ESP_ERR_NO_MEM, err, TAG, "Touch handle malloc failed"); | ||
|
||
/* Communication interface */ | ||
cst816s->io = io; | ||
/* Only supported callbacks are set */ | ||
cst816s->read_data = read_data; | ||
cst816s->get_xy = get_xy; | ||
cst816s->del = del; | ||
/* Mutex */ | ||
cst816s->data.lock.owner = portMUX_FREE_VAL; | ||
/* Save config */ | ||
memcpy(&cst816s->config, config, sizeof(esp_lcd_touch_config_t)); | ||
|
||
/* Prepare pin for touch interrupt */ | ||
if (cst816s->config.int_gpio_num != GPIO_NUM_NC) { | ||
const gpio_config_t int_gpio_config = { | ||
.mode = GPIO_MODE_INPUT, | ||
.pin_bit_mask = BIT64(cst816s->config.int_gpio_num) | ||
}; | ||
ESP_GOTO_ON_ERROR(gpio_config(&int_gpio_config), err, TAG, "GPIO intr config failed"); | ||
} | ||
/* Prepare pin for touch controller reset */ | ||
if (cst816s->config.rst_gpio_num != GPIO_NUM_NC) { | ||
const gpio_config_t rst_gpio_config = { | ||
.mode = GPIO_MODE_OUTPUT, | ||
.pin_bit_mask = BIT64(cst816s->config.rst_gpio_num) | ||
}; | ||
ESP_GOTO_ON_ERROR(gpio_config(&rst_gpio_config), err, TAG, "GPIO reset config failed"); | ||
} | ||
/* Reset controller */ | ||
ESP_GOTO_ON_ERROR(reset(cst816s), err, TAG, "Reset failed"); | ||
/* Read product id */ | ||
ESP_GOTO_ON_ERROR(read_id(cst816s), err, TAG, "Read version failed"); | ||
*tp = cst816s; | ||
|
||
return ESP_OK; | ||
err: | ||
if (cst816s) { | ||
del(cst816s); | ||
} | ||
ESP_LOGE(TAG, "Initialization failed!"); | ||
return ret; | ||
} | ||
|
||
static esp_err_t read_data(esp_lcd_touch_handle_t tp) | ||
{ | ||
typedef struct { | ||
uint8_t num; | ||
uint8_t x_h : 4; | ||
uint8_t : 4; | ||
uint8_t x_l; | ||
uint8_t y_h : 4; | ||
uint8_t : 4; | ||
uint8_t y_l; | ||
} data_t; | ||
|
||
data_t point; | ||
ESP_RETURN_ON_ERROR(i2c_read_bytes(tp, DATA_START_REG, (uint8_t *)&point, sizeof(data_t)), TAG, "I2C read failed"); | ||
|
||
portENTER_CRITICAL(&tp->data.lock); | ||
point.num = (point.num > POINT_NUM_MAX ? POINT_NUM_MAX : point.num); | ||
tp->data.points = point.num; | ||
/* Fill all coordinates */ | ||
for (int i = 0; i < point.num; i++) { | ||
tp->data.coords[i].x = point.x_h << 8 | point.x_l; | ||
tp->data.coords[i].y = point.y_h << 8 | point.y_l; | ||
} | ||
portEXIT_CRITICAL(&tp->data.lock); | ||
|
||
return ESP_OK; | ||
} | ||
|
||
static bool get_xy(esp_lcd_touch_handle_t tp, uint16_t *x, uint16_t *y, uint16_t *strength, uint8_t *point_num, uint8_t max_point_num) | ||
{ | ||
portENTER_CRITICAL(&tp->data.lock); | ||
/* Count of points */ | ||
*point_num = (tp->data.points > max_point_num ? max_point_num : tp->data.points); | ||
for (size_t i = 0; i < *point_num; i++) { | ||
x[i] = tp->data.coords[i].x; | ||
y[i] = tp->data.coords[i].y; | ||
|
||
if (strength) { | ||
strength[i] = tp->data.coords[i].strength; | ||
} | ||
} | ||
/* Invalidate */ | ||
tp->data.points = 0; | ||
portEXIT_CRITICAL(&tp->data.lock); | ||
|
||
return (*point_num > 0); | ||
} | ||
|
||
static esp_err_t del(esp_lcd_touch_handle_t tp) | ||
{ | ||
/* Reset GPIO pin settings */ | ||
if (tp->config.int_gpio_num != GPIO_NUM_NC) { | ||
gpio_reset_pin(tp->config.int_gpio_num); | ||
} | ||
if (tp->config.rst_gpio_num != GPIO_NUM_NC) { | ||
gpio_reset_pin(tp->config.rst_gpio_num); | ||
} | ||
/* Release memory */ | ||
free(tp); | ||
|
||
return ESP_OK; | ||
} | ||
|
||
static esp_err_t reset(esp_lcd_touch_handle_t tp) | ||
{ | ||
if (tp->config.rst_gpio_num != GPIO_NUM_NC) { | ||
ESP_RETURN_ON_ERROR(gpio_set_level(tp->config.rst_gpio_num, tp->config.levels.reset), TAG, "GPIO set level failed"); | ||
vTaskDelay(pdMS_TO_TICKS(10)); | ||
ESP_RETURN_ON_ERROR(gpio_set_level(tp->config.rst_gpio_num, !tp->config.levels.reset), TAG, "GPIO set level failed"); | ||
vTaskDelay(pdMS_TO_TICKS(10)); | ||
} | ||
|
||
return ESP_OK; | ||
} | ||
|
||
static esp_err_t read_id(esp_lcd_touch_handle_t tp) | ||
{ | ||
uint8_t id; | ||
ESP_RETURN_ON_ERROR(i2c_read_bytes(tp, CHIP_ID_REG, &id, 1), TAG, "I2C read failed"); | ||
ESP_LOGI(TAG, "IC id: %d", id); | ||
return ESP_OK; | ||
} | ||
|
||
static esp_err_t i2c_read_bytes(esp_lcd_touch_handle_t tp, uint16_t reg, uint8_t *data, uint8_t len) | ||
{ | ||
ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "Invalid data"); | ||
|
||
return esp_lcd_panel_io_rx_param(tp->io, reg, data, len); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
version: "1.0.0" | ||
description: ESP LCD Touch CST816S - touch controller CST816S | ||
url: https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch/esp_lcd_touch_cst816s | ||
dependencies: | ||
idf: ">=4.4.2" | ||
esp_lcd_touch: | ||
version: "^1.0" |
57 changes: 57 additions & 0 deletions
57
components/lcd_touch/esp_lcd_touch_cst816s/include/esp_lcd_touch_cst816s.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** | ||
* @file | ||
* @brief ESP LCD touch: CST816S | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "esp_lcd_touch.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief Create a new CST816S touch driver | ||
* | ||
* @note The I2C communication should be initialized before use this function. | ||
* | ||
* @param io LCD panel IO handle, it should be created by `esp_lcd_new_panel_io_i2c()` | ||
* @param config Touch panel configuration | ||
* @param tp Touch panel handle | ||
* @return | ||
* - ESP_OK: on success | ||
*/ | ||
esp_err_t esp_lcd_touch_new_i2c_cst816s(const esp_lcd_panel_io_handle_t io, const esp_lcd_touch_config_t *config, esp_lcd_touch_handle_t *tp); | ||
|
||
/** | ||
* @brief I2C address of the CST816S controller | ||
* | ||
*/ | ||
#define ESP_LCD_TOUCH_IO_I2C_CST816S_ADDRESS (0x15) | ||
|
||
/** | ||
* @brief Touch IO configuration structure | ||
* | ||
*/ | ||
#define ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG() \ | ||
{ \ | ||
.dev_addr = ESP_LCD_TOUCH_IO_I2C_CST816S_ADDRESS, \ | ||
.control_phase_bytes = 1, \ | ||
.dc_bit_offset = 0, \ | ||
.lcd_cmd_bits = 8, \ | ||
.flags = \ | ||
{ \ | ||
.disable_control_phase = 1, \ | ||
} \ | ||
} | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
Oops, something went wrong.