-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add CST816 touch controller and MaTouch Rotary Display components (#286)
* Add MaTouch Rotary Display component * Update button to expose event callback function from interrupt for easier use * Add CS816 touch driver peripheral * Add MaTouch Rotary Display component * update to use interrupt class for both button and touch update * update docs and ci * update cs816 example * readme: update * update docs * update ci * readme: update * readme: update * readme: update
- Loading branch information
Showing
26 changed files
with
1,435 additions
and
3 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
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,4 @@ | ||
idf_component_register( | ||
INCLUDE_DIRS "include" | ||
REQUIRES "base_peripheral" | ||
) |
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,21 @@ | ||
# The following lines of boilerplate have to be in your project's CMakeLists | ||
# in this exact order for cmake to work correctly | ||
cmake_minimum_required(VERSION 3.5) | ||
|
||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
|
||
# add the component directories that we want to use | ||
set(EXTRA_COMPONENT_DIRS | ||
"../../../components/" | ||
) | ||
|
||
set( | ||
COMPONENTS | ||
"main esptool_py task cst816 i2c" | ||
CACHE STRING | ||
"List of components to include" | ||
) | ||
|
||
project(cst816_example) | ||
|
||
set(CMAKE_CXX_STANDARD 20) |
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,43 @@ | ||
# CST816 Example | ||
|
||
This example shows how to use the CST816 touch controller with ESP32. It is | ||
designed to run on a [Matouch Rotary | ||
Display](https://wiki.makerfabs.com/MaTouch_ESP32_S3_Rotary_IPS_Display_1.28_GC9A01.html). | ||
|
||
## How to use example | ||
|
||
### Hardware Required | ||
|
||
The [Matouch Rotary | ||
Display](https://wiki.makerfabs.com/MaTouch_ESP32_S3_Rotary_IPS_Display_1.28_GC9A01.html) | ||
is required for this example. | ||
|
||
If you have other hardware with CST816, you can run menuconfig, and select the | ||
`HARDWARE_CUSTOM` option. and then select which pins are connected to the | ||
CST816. | ||
|
||
### Configure | ||
|
||
``` | ||
idf.py menuconfig | ||
``` | ||
|
||
Set the hardware configuration for the example. | ||
|
||
### Build and Flash | ||
|
||
Build the project and flash it to the board, then run monitor tool to view serial output: | ||
|
||
``` | ||
idf.py -p PORT flash monitor | ||
``` | ||
|
||
(Replace PORT with the name of the serial port to use.) | ||
|
||
(To exit the serial monitor, type ``Ctrl-]``.) | ||
|
||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. | ||
|
||
## Example Output | ||
|
||
![CleanShot 2024-07-08 at 21 57 00](https://github.com/esp-cpp/espp/assets/213467/c275598a-0759-4d40-b22b-224d2197be8f) |
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,2 @@ | ||
idf_component_register(SRC_DIRS "." | ||
INCLUDE_DIRS ".") |
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,33 @@ | ||
menu "Example Configuration" | ||
|
||
choice EXAMPLE_HARDWARE | ||
prompt "Hardware" | ||
default EXAMPLE_HARDWARE_MATOUCH_ROTARY_DISPLAY | ||
help | ||
Select the hardware to run this example on. | ||
|
||
config EXAMPLE_HARDWARE_MATOUCH_ROTARY_DISPLAY | ||
depends on IDF_TARGET_ESP32S3 | ||
bool "ESP32-S3 Matouch Rotary Display" | ||
|
||
config EXAMPLE_HARDWARE_CUSTOM | ||
bool "Custom" | ||
endchoice | ||
|
||
config EXAMPLE_I2C_SCL_GPIO | ||
int "SCL GPIO Num" | ||
range 0 50 | ||
default 39 if EXAMPLE_HARDWARE_MATOUCH_ROTARY_DISPLAY | ||
default 19 if EXAMPLE_HARDWARE_CUSTOM | ||
help | ||
GPIO number for I2C Master clock line. | ||
|
||
config EXAMPLE_I2C_SDA_GPIO | ||
int "SDA GPIO Num" | ||
range 0 50 | ||
default 38 if EXAMPLE_HARDWARE_MATOUCH_ROTARY_DISPLAY | ||
default 22 if EXAMPLE_HARDWARE_CUSTOM | ||
help | ||
GPIO number for I2C Master data line. | ||
|
||
endmenu |
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,84 @@ | ||
#include <chrono> | ||
#include <sdkconfig.h> | ||
#include <vector> | ||
|
||
#include "cst816.hpp" | ||
#include "i2c.hpp" | ||
#include "task.hpp" | ||
|
||
using namespace std::chrono_literals; | ||
|
||
extern "C" void app_main(void) { | ||
{ | ||
std::atomic<bool> quit_test = false; | ||
fmt::print("Starting cst816 example\n"); | ||
//! [cst816 example] | ||
// make the I2C that we'll use to communicate | ||
espp::I2c i2c({ | ||
.port = I2C_NUM_0, | ||
.sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO, | ||
.scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO, | ||
.sda_pullup_en = GPIO_PULLUP_ENABLE, | ||
.scl_pullup_en = GPIO_PULLUP_ENABLE, | ||
.timeout_ms = 100, | ||
.clk_speed = 400 * 1000, | ||
}); | ||
|
||
bool has_cst816 = i2c.probe_device(espp::Cst816::DEFAULT_ADDRESS); | ||
fmt::print("Touchpad probe: {}\n", has_cst816); | ||
|
||
// now make the cst816 which decodes the data | ||
espp::Cst816 cst816({.write = std::bind(&espp::I2c::write, &i2c, std::placeholders::_1, | ||
std::placeholders::_2, std::placeholders::_3), | ||
.read = std::bind(&espp::I2c::read, &i2c, std::placeholders::_1, | ||
std::placeholders::_2, std::placeholders::_3), | ||
.log_level = espp::Logger::Verbosity::WARN}); | ||
|
||
// and finally, make the task to periodically poll the cst816 and print | ||
// the state | ||
auto task_fn = [&cst816](std::mutex &m, std::condition_variable &cv) { | ||
std::error_code ec; | ||
// update the state | ||
bool new_data = cst816.update(ec); | ||
if (ec) { | ||
fmt::print("Could not update state\n"); | ||
return false; | ||
} | ||
if (!new_data) { | ||
return false; // don't stop the task | ||
} | ||
// get the state | ||
bool home_pressed = false; | ||
home_pressed = cst816.get_home_button_state(); | ||
fmt::print("home_pressed: {}\n", home_pressed); | ||
uint8_t num_touch_points = 0; | ||
uint16_t x = 0, y = 0; | ||
cst816.get_touch_point(&num_touch_points, &x, &y); | ||
if (ec) { | ||
fmt::print("Could not get touch point\n"); | ||
return false; | ||
} | ||
fmt::print("num_touch_points: {}, x: {}, y: {}\n", num_touch_points, x, y); | ||
// NOTE: sleeping in this way allows the sleep to exit early when the | ||
// task is being stopped / destroyed | ||
{ | ||
std::unique_lock<std::mutex> lk(m); | ||
cv.wait_for(lk, 50ms); | ||
} | ||
return false; // don't stop the task | ||
}; | ||
auto task = espp::Task( | ||
{.name = "Cst816 Task", .callback = task_fn, .log_level = espp::Logger::Verbosity::WARN}); | ||
task.start(); | ||
//! [cst816 example] | ||
while (true) { | ||
std::this_thread::sleep_for(100ms); | ||
} | ||
} | ||
|
||
fmt::print("Cst816 example complete!\n"); | ||
|
||
while (true) { | ||
std::this_thread::sleep_for(1s); | ||
} | ||
} |
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,6 @@ | ||
CONFIG_IDF_TARGET="esp32s3" | ||
|
||
# Common ESP-related | ||
# | ||
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096 | ||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 |
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,105 @@ | ||
#pragma once | ||
|
||
#include <atomic> | ||
#include <functional> | ||
|
||
#include "base_peripheral.hpp" | ||
|
||
namespace espp { | ||
/// @brief Driver for the CST816 touch controller | ||
/// @note This chip does not respond to I2C commands normally, only after an | ||
/// event. To properly interact with this chip, you should register an | ||
/// interrupt on the chip's IRQ line. After the IRQ line is asserted, it | ||
/// will respond to I2C reads for a short period of time. | ||
/// | ||
/// For more information, you can look at some reference code and the datasheet | ||
/// here: | ||
/// https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch/esp_lcd_touch_cst816s | ||
/// | ||
/// \section Example | ||
/// \snippet cst816_example.cpp cst816 example | ||
class Cst816 : public BasePeripheral<std::uint8_t> { | ||
public: | ||
/// Default address for the CST816 chip | ||
static constexpr uint8_t DEFAULT_ADDRESS = 0x15; | ||
|
||
/// @brief Configuration for the CST816 driver | ||
struct Config { | ||
BasePeripheral::write_fn write; ///< Function for writing to the CST816 chip | ||
BasePeripheral::read_fn read; ///< Function for reading from the CST816 chip | ||
uint8_t address = DEFAULT_ADDRESS; ///< Which address to use for this chip? | ||
espp::Logger::Verbosity log_level{ | ||
espp::Logger::Verbosity::WARN}; ///< Log verbosity for the input driver. | ||
}; | ||
|
||
/// @brief Constructor for the CST816 driver | ||
/// @param config The configuration for the driver | ||
explicit Cst816(const Config &config) | ||
: BasePeripheral({.address = config.address, .write = config.write, .read = config.read}, | ||
"Cst816", config.log_level) {} | ||
|
||
/// @brief Update the state of the CST816 driver | ||
/// @param ec Error code to set if an error occurs | ||
/// @return True if the CST816 has new data, false otherwise | ||
bool update(std::error_code &ec) { | ||
bool new_data = false; | ||
Data data{}; | ||
read_many_from_register((uint8_t)Registers::DATA_START, (uint8_t *)&data, sizeof(data), ec); | ||
if (ec) | ||
return false; | ||
|
||
num_touch_points_ = data.num; | ||
x_ = (data.x_h << 8) | data.x_l; | ||
y_ = (data.y_h << 8) | data.y_l; | ||
home_button_pressed_ = false; | ||
new_data = true; | ||
return new_data; | ||
} | ||
|
||
/// @brief Get the number of touch points | ||
/// @return The number of touch points as of the last update | ||
/// @note This is a cached value from the last update() call | ||
uint8_t get_num_touch_points() const { return num_touch_points_; } | ||
|
||
/// @brief Get the touch point data | ||
/// @param num_touch_points The number of touch points as of the last update | ||
/// @param x The x coordinate of the touch point | ||
/// @param y The y coordinate of the touch point | ||
/// @note This is a cached value from the last update() call | ||
void get_touch_point(uint8_t *num_touch_points, uint16_t *x, uint16_t *y) const { | ||
*num_touch_points = get_num_touch_points(); | ||
if (*num_touch_points != 0) { | ||
*x = x_; | ||
*y = y_; | ||
} | ||
} | ||
|
||
/// @brief Get the home button state | ||
/// @return True if the home button is pressed, false otherwise | ||
/// @note This is a cached value from the last update() call | ||
bool get_home_button_state() const { return home_button_pressed_; } | ||
|
||
protected: | ||
static constexpr int MAX_CONTACTS = 1; | ||
|
||
struct Data { | ||
uint8_t num = 0; | ||
uint8_t x_h : 4; | ||
uint8_t : 4; | ||
uint8_t x_l = 0; | ||
uint8_t y_h : 4; | ||
uint8_t : 4; | ||
uint8_t y_l = 0; | ||
}; | ||
|
||
enum class Registers : uint8_t { | ||
DATA_START = 0x02, | ||
CHIP_ID = 0xA7, | ||
}; | ||
|
||
std::atomic<bool> home_button_pressed_{false}; | ||
std::atomic<uint8_t> num_touch_points_; | ||
std::atomic<uint16_t> x_; | ||
std::atomic<uint16_t> y_; | ||
}; | ||
} // namespace espp |
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 @@ | ||
# only register the component if the target is esp32s3 | ||
idf_component_register( | ||
INCLUDE_DIRS "include" | ||
SRC_DIRS "src" | ||
REQUIRES driver esp_lcd base_component button cst816 encoder display display_drivers i2c input_drivers task | ||
REQUIRED_IDF_TARGETS "esp32s3" | ||
) |
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,8 @@ | ||
menu "Matouch Rotary Display Configuration" | ||
config MATOUCH_INTERRUPT_STACK_SIZE | ||
int "Interrupt stack size" | ||
default 4096 | ||
help | ||
Size of the stack used for the interrupt handler. Shared by the | ||
button callback and the touch callbacks. | ||
endmenu |
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,21 @@ | ||
# The following lines of boilerplate have to be in your project's CMakeLists | ||
# in this exact order for cmake to work correctly | ||
cmake_minimum_required(VERSION 3.5) | ||
|
||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
|
||
# add the component directories that we want to use | ||
set(EXTRA_COMPONENT_DIRS | ||
"../../../components/" | ||
) | ||
|
||
set( | ||
COMPONENTS | ||
"main esptool_py matouch-rotary-display" | ||
CACHE STRING | ||
"List of components to include" | ||
) | ||
|
||
project(matouch_rotary_display_example) | ||
|
||
set(CMAKE_CXX_STANDARD 20) |
Oops, something went wrong.