diff --git a/ESP_Panel_Board_Custom.h b/ESP_Panel_Board_Custom.h index 9a52bec8..7d1df917 100644 --- a/ESP_Panel_Board_Custom.h +++ b/ESP_Panel_Board_Custom.h @@ -212,7 +212,9 @@ * - CST816S * - FT5x06 * - GT911, GT1151 + * - ST7123 * - TT21100 + * - XPT2046 */ #define ESP_PANEL_TOUCH_NAME TT21100 @@ -229,7 +231,7 @@ /** * Touch panel bus type. Choose one of the following: * - ESP_PANEL_BUS_TYPE_I2C - * - ESP_PANEL_BUS_TYPE_SPI (not ready) + * - ESP_PANEL_BUS_TYPE_SPI */ #define ESP_PANEL_TOUCH_BUS_TYPE (ESP_PANEL_BUS_TYPE_I2C) /* Touch panel bus parameters */ @@ -246,6 +248,18 @@ #define ESP_PANEL_TOUCH_I2C_IO_SDA (8) #endif +#elif ESP_PANEL_TOUCH_BUS_TYPE == ESP_PANEL_BUS_TYPE_SPI + + #define ESP_PANEL_TOUCH_BUS_HOST_ID (1) // Typically set to 1 + #define ESP_PANEL_TOUCH_SPI_IO_CS (5) +#if !ESP_PANEL_TOUCH_BUS_SKIP_INIT_HOST + #define ESP_PANEL_TOUCH_SPI_IO_SCK (7) + #define ESP_PANEL_TOUCH_SPI_IO_MOSI (6) + #define ESP_PANEL_TOUCH_SPI_IO_MISO (9) +#endif + #define ESP_PANEL_TOUCH_SPI_CLK_HZ (1 * 1000 * 1000) + // Should be an integer divisor of 80M, typically set to 1M + #else #error "The function is not ready and will be implemented in the future." diff --git a/ESP_Panel_Conf.h b/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/ESP_Panel_Conf.h +++ b/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/README.md b/README.md index c5b26562..eb88d9c5 100644 --- a/README.md +++ b/README.md @@ -86,13 +86,14 @@ Below is a list of [supported touch controllers](src/touch/README.md): | GOODiX | GT911, GT1151 | | Sitronix | ST7123 | | Parade | TT21100 | +| Xptek | XPT2046 | ## Dependencies and Versions | **Dependency** | **Version** | | -------------- | ----------- | | [arduino-esp32](https://github.com/espressif/arduino-esp32) | >= v3.0.3 | -| [ESP32_IO_Expander](https://github.com/esp-arduino-libs/ESP32_IO_Expander) | >= v0.0.1 | +| [ESP32_IO_Expander](https://github.com/esp-arduino-libs/ESP32_IO_Expander) | >= 0.0.1 && < 0.1.0 | ## How to Use @@ -270,6 +271,7 @@ The following examples demonstrate how to develop different interface and model The following example demonstrates how to develop touch screens of different interfaces and models using standalone drivers and test them by printing touch point coordinates: * [I2C](examples/Touch/I2C/) +* [SPI](examples/Touch/SPI/) #### Panel diff --git a/README_CN.md b/README_CN.md index 91fc2387..be56c0ab 100644 --- a/README_CN.md +++ b/README_CN.md @@ -86,13 +86,14 @@ ESP32_Display_Panel 的功能框图如下所示,主要包含以下特性: | GOODiX | GT911, GT1151 | | Sitronix | ST7123 | | Parade | TT21100 | +| Xptek | XPT2046 | ## 依赖项及版本 | **依赖项** | **版本** | | ---------- | -------- | | [arduino-esp32](https://github.com/espressif/arduino-esp32) | >= v3.0.3 | -| [ESP32_IO_Expander](https://github.com/esp-arduino-libs/ESP32_IO_Expander) | >= v0.0.1 | +| [ESP32_IO_Expander](https://github.com/esp-arduino-libs/ESP32_IO_Expander) | >= 0.0.1 && < 0.1.0 | ## 如何使用 @@ -270,6 +271,7 @@ ESP32_Display_Panel 会根据 [ESP_Panel_Board_Custom.h](./ESP_Panel_Board_Custo 以下示例演示了如何使用独立的驱动开发不同接口和不同型号的触摸屏,并通过打印触摸点坐标进行测试: * [I2C](examples/Touch/I2C/) +* [SPI](examples/Touch/SPI/) #### Panel diff --git a/check_copyright_config.yaml b/check_copyright_config.yaml index 2d8361c7..7b484aaf 100644 --- a/check_copyright_config.yaml +++ b/check_copyright_config.yaml @@ -7,6 +7,7 @@ DEFAULT: # when setting this option in a section, you need to list all the allowed licenses allowed_licenses: - Apache-2.0 + - MIT license_for_new_files: Apache-2.0 # license to be used when inserting a new copyright notice new_notice_c: | # notice for new C, CPP, H, HPP and LD files /* diff --git a/examples/LCD/3wireSPI_RGB/ESP_Panel_Conf.h b/examples/LCD/3wireSPI_RGB/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/examples/LCD/3wireSPI_RGB/ESP_Panel_Conf.h +++ b/examples/LCD/3wireSPI_RGB/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/LCD/QSPI/ESP_Panel_Conf.h b/examples/LCD/QSPI/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/examples/LCD/QSPI/ESP_Panel_Conf.h +++ b/examples/LCD/QSPI/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/LCD/RGB/ESP_Panel_Conf.h b/examples/LCD/RGB/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/examples/LCD/RGB/ESP_Panel_Conf.h +++ b/examples/LCD/RGB/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/LCD/SPI/ESP_Panel_Conf.h b/examples/LCD/SPI/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/examples/LCD/SPI/ESP_Panel_Conf.h +++ b/examples/LCD/SPI/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/LVGL/v8/Porting/ESP_Panel_Board_Custom.h b/examples/LVGL/v8/Porting/ESP_Panel_Board_Custom.h index 9a52bec8..7d1df917 100644 --- a/examples/LVGL/v8/Porting/ESP_Panel_Board_Custom.h +++ b/examples/LVGL/v8/Porting/ESP_Panel_Board_Custom.h @@ -212,7 +212,9 @@ * - CST816S * - FT5x06 * - GT911, GT1151 + * - ST7123 * - TT21100 + * - XPT2046 */ #define ESP_PANEL_TOUCH_NAME TT21100 @@ -229,7 +231,7 @@ /** * Touch panel bus type. Choose one of the following: * - ESP_PANEL_BUS_TYPE_I2C - * - ESP_PANEL_BUS_TYPE_SPI (not ready) + * - ESP_PANEL_BUS_TYPE_SPI */ #define ESP_PANEL_TOUCH_BUS_TYPE (ESP_PANEL_BUS_TYPE_I2C) /* Touch panel bus parameters */ @@ -246,6 +248,18 @@ #define ESP_PANEL_TOUCH_I2C_IO_SDA (8) #endif +#elif ESP_PANEL_TOUCH_BUS_TYPE == ESP_PANEL_BUS_TYPE_SPI + + #define ESP_PANEL_TOUCH_BUS_HOST_ID (1) // Typically set to 1 + #define ESP_PANEL_TOUCH_SPI_IO_CS (5) +#if !ESP_PANEL_TOUCH_BUS_SKIP_INIT_HOST + #define ESP_PANEL_TOUCH_SPI_IO_SCK (7) + #define ESP_PANEL_TOUCH_SPI_IO_MOSI (6) + #define ESP_PANEL_TOUCH_SPI_IO_MISO (9) +#endif + #define ESP_PANEL_TOUCH_SPI_CLK_HZ (1 * 1000 * 1000) + // Should be an integer divisor of 80M, typically set to 1M + #else #error "The function is not ready and will be implemented in the future." diff --git a/examples/LVGL/v8/Porting/ESP_Panel_Conf.h b/examples/LVGL/v8/Porting/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/examples/LVGL/v8/Porting/ESP_Panel_Conf.h +++ b/examples/LVGL/v8/Porting/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/LVGL/v8/Rotation/ESP_Panel_Board_Custom.h b/examples/LVGL/v8/Rotation/ESP_Panel_Board_Custom.h index 9a52bec8..7d1df917 100644 --- a/examples/LVGL/v8/Rotation/ESP_Panel_Board_Custom.h +++ b/examples/LVGL/v8/Rotation/ESP_Panel_Board_Custom.h @@ -212,7 +212,9 @@ * - CST816S * - FT5x06 * - GT911, GT1151 + * - ST7123 * - TT21100 + * - XPT2046 */ #define ESP_PANEL_TOUCH_NAME TT21100 @@ -229,7 +231,7 @@ /** * Touch panel bus type. Choose one of the following: * - ESP_PANEL_BUS_TYPE_I2C - * - ESP_PANEL_BUS_TYPE_SPI (not ready) + * - ESP_PANEL_BUS_TYPE_SPI */ #define ESP_PANEL_TOUCH_BUS_TYPE (ESP_PANEL_BUS_TYPE_I2C) /* Touch panel bus parameters */ @@ -246,6 +248,18 @@ #define ESP_PANEL_TOUCH_I2C_IO_SDA (8) #endif +#elif ESP_PANEL_TOUCH_BUS_TYPE == ESP_PANEL_BUS_TYPE_SPI + + #define ESP_PANEL_TOUCH_BUS_HOST_ID (1) // Typically set to 1 + #define ESP_PANEL_TOUCH_SPI_IO_CS (5) +#if !ESP_PANEL_TOUCH_BUS_SKIP_INIT_HOST + #define ESP_PANEL_TOUCH_SPI_IO_SCK (7) + #define ESP_PANEL_TOUCH_SPI_IO_MOSI (6) + #define ESP_PANEL_TOUCH_SPI_IO_MISO (9) +#endif + #define ESP_PANEL_TOUCH_SPI_CLK_HZ (1 * 1000 * 1000) + // Should be an integer divisor of 80M, typically set to 1M + #else #error "The function is not ready and will be implemented in the future." diff --git a/examples/LVGL/v8/Rotation/ESP_Panel_Conf.h b/examples/LVGL/v8/Rotation/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/examples/LVGL/v8/Rotation/ESP_Panel_Conf.h +++ b/examples/LVGL/v8/Rotation/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/Panel/PanelTest/ESP_Panel_Board_Custom.h b/examples/Panel/PanelTest/ESP_Panel_Board_Custom.h index 9a52bec8..7d1df917 100644 --- a/examples/Panel/PanelTest/ESP_Panel_Board_Custom.h +++ b/examples/Panel/PanelTest/ESP_Panel_Board_Custom.h @@ -212,7 +212,9 @@ * - CST816S * - FT5x06 * - GT911, GT1151 + * - ST7123 * - TT21100 + * - XPT2046 */ #define ESP_PANEL_TOUCH_NAME TT21100 @@ -229,7 +231,7 @@ /** * Touch panel bus type. Choose one of the following: * - ESP_PANEL_BUS_TYPE_I2C - * - ESP_PANEL_BUS_TYPE_SPI (not ready) + * - ESP_PANEL_BUS_TYPE_SPI */ #define ESP_PANEL_TOUCH_BUS_TYPE (ESP_PANEL_BUS_TYPE_I2C) /* Touch panel bus parameters */ @@ -246,6 +248,18 @@ #define ESP_PANEL_TOUCH_I2C_IO_SDA (8) #endif +#elif ESP_PANEL_TOUCH_BUS_TYPE == ESP_PANEL_BUS_TYPE_SPI + + #define ESP_PANEL_TOUCH_BUS_HOST_ID (1) // Typically set to 1 + #define ESP_PANEL_TOUCH_SPI_IO_CS (5) +#if !ESP_PANEL_TOUCH_BUS_SKIP_INIT_HOST + #define ESP_PANEL_TOUCH_SPI_IO_SCK (7) + #define ESP_PANEL_TOUCH_SPI_IO_MOSI (6) + #define ESP_PANEL_TOUCH_SPI_IO_MISO (9) +#endif + #define ESP_PANEL_TOUCH_SPI_CLK_HZ (1 * 1000 * 1000) + // Should be an integer divisor of 80M, typically set to 1M + #else #error "The function is not ready and will be implemented in the future." diff --git a/examples/Panel/PanelTest/ESP_Panel_Conf.h b/examples/Panel/PanelTest/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/examples/Panel/PanelTest/ESP_Panel_Conf.h +++ b/examples/Panel/PanelTest/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/SquareLine/v8/Porting/ESP_Panel_Board_Custom.h b/examples/SquareLine/v8/Porting/ESP_Panel_Board_Custom.h index 9a52bec8..7d1df917 100644 --- a/examples/SquareLine/v8/Porting/ESP_Panel_Board_Custom.h +++ b/examples/SquareLine/v8/Porting/ESP_Panel_Board_Custom.h @@ -212,7 +212,9 @@ * - CST816S * - FT5x06 * - GT911, GT1151 + * - ST7123 * - TT21100 + * - XPT2046 */ #define ESP_PANEL_TOUCH_NAME TT21100 @@ -229,7 +231,7 @@ /** * Touch panel bus type. Choose one of the following: * - ESP_PANEL_BUS_TYPE_I2C - * - ESP_PANEL_BUS_TYPE_SPI (not ready) + * - ESP_PANEL_BUS_TYPE_SPI */ #define ESP_PANEL_TOUCH_BUS_TYPE (ESP_PANEL_BUS_TYPE_I2C) /* Touch panel bus parameters */ @@ -246,6 +248,18 @@ #define ESP_PANEL_TOUCH_I2C_IO_SDA (8) #endif +#elif ESP_PANEL_TOUCH_BUS_TYPE == ESP_PANEL_BUS_TYPE_SPI + + #define ESP_PANEL_TOUCH_BUS_HOST_ID (1) // Typically set to 1 + #define ESP_PANEL_TOUCH_SPI_IO_CS (5) +#if !ESP_PANEL_TOUCH_BUS_SKIP_INIT_HOST + #define ESP_PANEL_TOUCH_SPI_IO_SCK (7) + #define ESP_PANEL_TOUCH_SPI_IO_MOSI (6) + #define ESP_PANEL_TOUCH_SPI_IO_MISO (9) +#endif + #define ESP_PANEL_TOUCH_SPI_CLK_HZ (1 * 1000 * 1000) + // Should be an integer divisor of 80M, typically set to 1M + #else #error "The function is not ready and will be implemented in the future." diff --git a/examples/SquareLine/v8/Porting/ESP_Panel_Conf.h b/examples/SquareLine/v8/Porting/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/examples/SquareLine/v8/Porting/ESP_Panel_Conf.h +++ b/examples/SquareLine/v8/Porting/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/SquareLine/v8/WiFiClock/ESP_Panel_Board_Custom.h b/examples/SquareLine/v8/WiFiClock/ESP_Panel_Board_Custom.h index 9a52bec8..7d1df917 100644 --- a/examples/SquareLine/v8/WiFiClock/ESP_Panel_Board_Custom.h +++ b/examples/SquareLine/v8/WiFiClock/ESP_Panel_Board_Custom.h @@ -212,7 +212,9 @@ * - CST816S * - FT5x06 * - GT911, GT1151 + * - ST7123 * - TT21100 + * - XPT2046 */ #define ESP_PANEL_TOUCH_NAME TT21100 @@ -229,7 +231,7 @@ /** * Touch panel bus type. Choose one of the following: * - ESP_PANEL_BUS_TYPE_I2C - * - ESP_PANEL_BUS_TYPE_SPI (not ready) + * - ESP_PANEL_BUS_TYPE_SPI */ #define ESP_PANEL_TOUCH_BUS_TYPE (ESP_PANEL_BUS_TYPE_I2C) /* Touch panel bus parameters */ @@ -246,6 +248,18 @@ #define ESP_PANEL_TOUCH_I2C_IO_SDA (8) #endif +#elif ESP_PANEL_TOUCH_BUS_TYPE == ESP_PANEL_BUS_TYPE_SPI + + #define ESP_PANEL_TOUCH_BUS_HOST_ID (1) // Typically set to 1 + #define ESP_PANEL_TOUCH_SPI_IO_CS (5) +#if !ESP_PANEL_TOUCH_BUS_SKIP_INIT_HOST + #define ESP_PANEL_TOUCH_SPI_IO_SCK (7) + #define ESP_PANEL_TOUCH_SPI_IO_MOSI (6) + #define ESP_PANEL_TOUCH_SPI_IO_MISO (9) +#endif + #define ESP_PANEL_TOUCH_SPI_CLK_HZ (1 * 1000 * 1000) + // Should be an integer divisor of 80M, typically set to 1M + #else #error "The function is not ready and will be implemented in the future." diff --git a/examples/SquareLine/v8/WiFiClock/ESP_Panel_Conf.h b/examples/SquareLine/v8/WiFiClock/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/examples/SquareLine/v8/WiFiClock/ESP_Panel_Conf.h +++ b/examples/SquareLine/v8/WiFiClock/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/Touch/I2C/ESP_Panel_Conf.h b/examples/Touch/I2C/ESP_Panel_Conf.h index 7591d68e..1758b2c4 100644 --- a/examples/Touch/I2C/ESP_Panel_Conf.h +++ b/examples/Touch/I2C/ESP_Panel_Conf.h @@ -25,3 +25,36 @@ /* Maximum button number */ #define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/Touch/I2C/I2C.ino b/examples/Touch/I2C/I2C.ino index b05a5f8d..bc34da5a 100644 --- a/examples/Touch/I2C/I2C.ino +++ b/examples/Touch/I2C/I2C.ino @@ -2,8 +2,8 @@ * | Supported ESP SoCs | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | * | ------------------ | ----- | -------- | -------- | -------- | -------- | -------- | * - * | Supported Touch Controllers | CST816S | FT5x06 | GT911 | GT1151 | TT21100 | ST7123 | - * | --------------------------- | ------- | ------ | ----- | ------ | ------- | ------ | + * | Supported Touch Controllers | CST816S | FT5x06 | GT911 | GT1151 | ST7123 | TT21100 | + * | --------------------------- | ------- | ------ | ----- | ------ | ------ | ------- | * * # I2C Touch Example * diff --git a/examples/Touch/I2C/README.md b/examples/Touch/I2C/README.md index 14ff2f74..8e50f6cc 100644 --- a/examples/Touch/I2C/README.md +++ b/examples/Touch/I2C/README.md @@ -1,8 +1,8 @@ | Supported ESP SoCs | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | | ------------------ | ----- | -------- | -------- | -------- | -------- | -------- | -| Supported Touch Controllers | CST816S | FT5x06 | GT911 | GT1151 | TT21100 | ST7123 | -| --------------------------- | ------- | ------ | ----- | ------ | ------- | ------ | +| Supported Touch Controllers | CST816S | FT5x06 | GT911 | GT1151 | ST7123 | TT21100 | +| --------------------------- | ------- | ------ | ----- | ------ | ------ | ------- | # I2C Touch Example diff --git a/examples/Touch/SPI/ESP_Panel_Conf.h b/examples/Touch/SPI/ESP_Panel_Conf.h new file mode 100644 index 00000000..1758b2c4 --- /dev/null +++ b/examples/Touch/SPI/ESP_Panel_Conf.h @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +/** + * Debug configurations + * + */ +/* Set to 1 if assert on error. Otherwise print error message */ +#define ESP_PANEL_CHECK_RESULT_ASSERT (0) // 0/1 + +/* Set to 1 if print log message for debug */ +#define ESP_PANEL_ENABLE_LOG (0) // 0/1 + +/** + * Touch driver configurations + * + */ +/* Maximum point number */ +#define ESP_PANEL_TOUCH_MAX_POINTS (5) + +/* Maximum button number */ +#define ESP_PANEL_TOUCH_MAX_BUTTONS (1) + +/* Model configurations */ +// XPT2046 +#define ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD (400) // Minimum Z pressure threshold +/** + * Enable Interrupt (PENIRQ) output, also called Full Power Mode. + * Enable this to configure the XPT2046 to output low on the PENIRQ output if a touch is detected. + * This mode uses more power when enabled. Note that this signal goes low normally when a read is active. + */ +#define ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE (0) // 0/1 +/** + * Keep internal Vref enabled. + * Enable this to keep the internal Vref enabled between conversions. This uses slightly more power, + * but requires fewer transactions when reading the battery voltage, aux voltage and temperature. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_VREF_ON_MODE (0) // 0/1 +/** + * Convert touch coordinates to screen coordinates. + * When this option is enabled the raw ADC values will be converted from 0-4096 to 0-{screen width} or 0-{screen height}. + * When this option is disabled the process_coordinates method will need to be used to convert the raw ADC values into a + * screen coordinate. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS (1) // 0/1 +/** + * Enable data structure locking. + * By enabling this option the XPT2046 driver will lock the touch position data structures when reading values from the + * XPT2046 and when reading position data via API. + * WARNING: enabling this option may result in unintended crashes. + * + */ +#define ESP_PANEL_TOUCH_XPT2046_ENABLE_LOCKING (0) // 0/1 diff --git a/examples/Touch/SPI/README.md b/examples/Touch/SPI/README.md new file mode 100644 index 00000000..2b077674 --- /dev/null +++ b/examples/Touch/SPI/README.md @@ -0,0 +1,36 @@ +| Supported ESP SoCs | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ------------------ | ----- | -------- | -------- | -------- | -------- | -------- | + +| Supported Touch Controllers | CST816S | FT5x06 | GT911 | GT1151 | ST7123 | TT21100 | +| --------------------------- | ------- | ------ | ----- | ------ | ------ | ------- | + +# SPI Touch Example + +The example demonstrates how to develop different model touches with SPI interface using standalone drivers and test them by printing touch point coordinates. + +## How to use + +1. [Configure drivers](../../../README.md#configuring-drivers) if needed. +2. Modify the macros in the example to match the parameters according to your hardware. +3. Navigate to the `Tools` menu in the Arduino IDE to choose a ESP board and configure its parameters, please refter to [Configuring Supported Development Boards](../../../README.md#configuring-supported-development-boards) +4. Verify and upload the example to your ESP board. + +## Serial Output + +``` +... +SPI touch example start +Create SPI bus +Create touch device +SPI touch example end +Touch point(0): x 134, y 169, strength 50 +Touch point(1): x 154, y 301, strength 51 +Touch point(2): x 245, y 379, strength 30 +Touch point(3): x 290, y 75, strength 26 +Touch point(4): x 353, y 391, strength 35 +... +``` + +## Troubleshooting + +Please check the [FAQ](../../../README.md#faq) first to see if the same question exists. If not, please create a [Github issue](https://github.com/esp-arduino-libs/ESP32_Display_Panel/issues). We will get back to you as soon as possible. diff --git a/examples/Touch/SPI/SPI.ino b/examples/Touch/SPI/SPI.ino new file mode 100644 index 00000000..63f3b69a --- /dev/null +++ b/examples/Touch/SPI/SPI.ino @@ -0,0 +1,127 @@ +/** + * | Supported ESP SoCs | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | + * | ------------------ | ----- | -------- | -------- | -------- | -------- | -------- | + * + * | Supported Touch Controllers | XPT2046 | + * | --------------------------- | ------- | + * + * # SPI Touch Example + * + * The example demonstrates how to develop different model touches with SPI interface using standalone drivers and test them by printing touch point coordinates. + * + * ## How to use + * + * 1. [Configure drivers](https://github.com/esp-arduino-libs/ESP32_Display_Panel#configuring-drivers) if needed. + * 2. Modify the macros in the example to match the parameters according to your hardware. + * 3. Navigate to the `Tools` menu in the Arduino IDE to choose a ESP board and configure its parameters, please refter to [Configuring Supported Development Boards](https://github.com/esp-arduino-libs/ESP32_Display_Panel#configuring-supported-development-boards) + * 4. Verify and upload the example to your ESP board. + * + * ## Serial Output + * + * ``` + * ... + * SPI touch example start + * Create SPI bus + * Create touch device + * SPI touch example end + * Touch point(0): x 134, y 169, strength 50 + * Touch point(1): x 154, y 301, strength 51 + * Touch point(2): x 245, y 379, strength 30 + * Touch point(3): x 290, y 75, strength 26 + * Touch point(4): x 353, y 391, strength 35 + * ... + * ``` + * + * ## Troubleshooting + * + * Please check the [FAQ](https://github.com/esp-arduino-libs/ESP32_Display_Panel#faq) first to see if the same question exists. If not, please create a [Github issue](https://github.com/esp-arduino-libs/ESP32_Display_Panel/issues). We will get back to you as soon as possible. + * + */ + +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// Please update the following configuration according to your touch spec //////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Currently, the library supports the following SPI touch devices: + * - XPT2046 + */ +#define EXAMPLE_TOUCH_NAME XPT2046 +#define EXAMPLE_TOUCH_WIDTH (240) +#define EXAMPLE_TOUCH_HEIGHT (320) +#define EXAMPLE_TOUCH_SPI_FREQ_HZ (1 * 1000 * 1000) +#define EXAMPLE_TOUCH_READ_POINTS_NUM (1) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// Please update the following configuration according to your board spec //////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define EXAMPLE_TOUCH_PIN_NUM_SPI_CS (46) +#define EXAMPLE_TOUCH_PIN_NUM_SPI_SCK (10) +#define EXAMPLE_TOUCH_PIN_NUM_SPI_MOSI (14) +#define EXAMPLE_TOUCH_PIN_NUM_SPI_MISO (8) +#define EXAMPLE_TOUCH_PIN_NUM_RST (-1) +#define EXAMPLE_TOUCH_PIN_NUM_INT (-1) + +#define _EXAMPLE_TOUCH_CLASS(name, ...) ESP_PanelTouch_##name(__VA_ARGS__) +#define EXAMPLE_TOUCH_CLASS(name, ...) _EXAMPLE_TOUCH_CLASS(name, ##__VA_ARGS__) + +#if EXAMPLE_TOUCH_PIN_NUM_INT >= 0 +IRAM_ATTR bool onTouchInterruptCallback(void *user_data) +{ + esp_rom_printf("Touch interrupt callback\n"); + + return false; +} +#endif + +ESP_PanelTouch *touch = nullptr; + +void setup() +{ + Serial.begin(115200); + Serial.println("SPI touch example start"); + + Serial.println("Create SPI bus"); + ESP_PanelBus_SPI *touch_bus = new ESP_PanelBus_SPI( + EXAMPLE_TOUCH_PIN_NUM_SPI_SCK, EXAMPLE_TOUCH_PIN_NUM_SPI_MOSI, EXAMPLE_TOUCH_PIN_NUM_SPI_MISO, + ESP_PANEL_TOUCH_SPI_PANEL_IO_CONFIG(EXAMPLE_TOUCH_NAME, EXAMPLE_TOUCH_PIN_NUM_SPI_CS)); + // Taking XPT2046 as an example, the following is the code after macro expansion: + // ESP_PanelBus_SPI *touch_bus = new ESP_PanelBus_SPI( + // EXAMPLE_TOUCH_PIN_NUM_SPI_SCK, EXAMPLE_TOUCH_PIN_NUM_SPI_MOSI, EXAMPLE_TOUCH_PIN_NUM_SPI_MISO, + // ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(EXAMPLE_TOUCH_PIN_NUM_SPI_CS)); + touch_bus->configSpiFreqHz(EXAMPLE_TOUCH_SPI_FREQ_HZ); + touch_bus->begin(); + + Serial.println("Create touch device"); + touch = new EXAMPLE_TOUCH_CLASS(EXAMPLE_TOUCH_NAME, touch_bus, EXAMPLE_TOUCH_WIDTH, EXAMPLE_TOUCH_HEIGHT, + EXAMPLE_TOUCH_PIN_NUM_RST, EXAMPLE_TOUCH_PIN_NUM_INT); + // Taking XPT2046 as an example, the following is the code after macro expansion: + // touch = new ESP_PanelTouch_XPT2046(touch_bus, EXAMPLE_TOUCH_WIDTH, EXAMPLE_TOUCH_HEIGHT, + // EXAMPLE_TOUCH_PIN_NUM_RST, EXAMPLE_TOUCH_PIN_NUM_INT); + touch->init(); + touch->begin(); +#if EXAMPLE_TOUCH_PIN_NUM_INT >= 0 + touch->attachInterruptCallback(onTouchInterruptCallback, NULL); +#endif + + Serial.println("SPI touch example end"); +} + +void loop() +{ + ESP_PanelTouchPoint point[EXAMPLE_TOUCH_READ_POINTS_NUM]; + int read_touch_result = touch->readPoints(point, EXAMPLE_TOUCH_READ_POINTS_NUM, -1); + + if (read_touch_result > 0) { + for (int i = 0; i < read_touch_result; i++) { + Serial.printf("Touch point(%d): x %d, y %d, strength %d\n", i, point[i].x, point[i].y, point[i].strength); + } + } else if (read_touch_result < 0) { + Serial.println("Read touch point failed"); + } +#if EXAMPLE_TOUCH_PIN_NUM_INT < 0 + delay(30); +#endif +} diff --git a/library.properties b/library.properties index cd9aa552..43afb8b7 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=0.1.1 author=espressif maintainer=espressif sentence=ESP32_Display_Panel is an Arduino library designed for ESP SoCs to drive display panels and facilitate rapid GUI development. -paragraph=Currently supported boards:ESP32-C3-LCDkit,ESP32-S3-Box,ESP32-S3-Box-3,ESP32-S3-Box-3(beta),ESP32-S3-Box-Lite,ESP32-S3-EYE,ESP32-S3-Korvo-2,ESP32-S3-LCD-EV-Board,ESP32-S3-LCD-EV-Board-2,ESP32-S3-USB-OTG,ESP32-4848S040C_I_Y_3. Currently supported devices: Bus,LCD,Touch,Backlight,IO expander. Currently supported Bus: I2C,SPI,QSPI,3-wire SPI + RGB. Currently supported LCD controllers: GC9A01,GC9B71,GC9503,ILI9341,NV3022B,ST7262,ST7701,ST7789,ST7796,ST77916,ST77922. Currently supported Touch controllers: CST816S,FT5x06,GT1151,GT911,ST7123,TT21100. +paragraph=Currently supported boards:ESP32-C3-LCDkit,ESP32-S3-Box,ESP32-S3-Box-3,ESP32-S3-Box-3(beta),ESP32-S3-Box-Lite,ESP32-S3-EYE,ESP32-S3-Korvo-2,ESP32-S3-LCD-EV-Board,ESP32-S3-LCD-EV-Board-2,ESP32-S3-USB-OTG,ESP32-4848S040C_I_Y_3. Currently supported devices: Bus,LCD,Touch,Backlight,IO expander. Currently supported Bus: I2C,SPI,QSPI,3-wire SPI + RGB. Currently supported LCD controllers: GC9A01,GC9B71,GC9503,ILI9341,NV3022B,ST7262,ST7701,ST7789,ST7796,ST77916,ST77922. Currently supported Touch controllers: CST816S,FT5x06,GT1151,GT911,ST7123,TT21100,XPT2046. category=Other architectures=esp32 url=https://github.com/esp-arduino-libs/ESP32_Display_Panel diff --git a/src/ESP_Panel.cpp b/src/ESP_Panel.cpp index b4e2e50f..04df6f0c 100644 --- a/src/ESP_Panel.cpp +++ b/src/ESP_Panel.cpp @@ -313,7 +313,8 @@ bool ESP_Panel::init(void) #else /* For non-RGB LCD, should use `ADD_HOST()` to init host when `ESP_PANEL_LCD_BUS_SKIP_INIT_HOST` enabled */ #if !ESP_PANEL_LCD_BUS_SKIP_INIT_HOST - ADD_HOST(ESP_PANEL_LCD_BUS_NAME, host, lcd_bus_host_config, ESP_PANEL_LCD_BUS_HOST); + ESP_PANEL_CHECK_FALSE_RET(ADD_HOST(ESP_PANEL_LCD_BUS_NAME, host, lcd_bus_host_config, ESP_PANEL_LCD_BUS_HOST), + false, "Add host failed"); #endif lcd_bus_ptr = CREATE_BUS_SKIP_HOST(ESP_PANEL_LCD_BUS_NAME, lcd_panel_io_config, ESP_PANEL_LCD_BUS_HOST); #endif @@ -333,7 +334,7 @@ bool ESP_Panel::init(void) ESP_LOGD(TAG, "Use I2C bus"); // I2C bus #if !ESP_PANEL_TOUCH_BUS_SKIP_INIT_HOST - i2c_config_t lcd_touch_host_config = { + i2c_config_t touch_host_config = { .mode = I2C_MODE_MASTER, .sda_io_num = ESP_PANEL_TOUCH_I2C_IO_SDA, .scl_io_num = ESP_PANEL_TOUCH_I2C_IO_SCL, @@ -346,7 +347,31 @@ bool ESP_Panel::init(void) }; #endif // I2C touch panel IO - esp_lcd_panel_io_i2c_config_t lcd_touch_panel_io_config = ESP_PANEL_TOUCH_I2C_PANEL_IO_CONFIG(ESP_PANEL_TOUCH_NAME); + esp_lcd_panel_io_i2c_config_t touch_panel_io_config = ESP_PANEL_TOUCH_I2C_PANEL_IO_CONFIG(ESP_PANEL_TOUCH_NAME); + +#elif ESP_PANEL_TOUCH_BUS_TYPE == ESP_PANEL_BUS_TYPE_SPI + + ESP_LOGD(TAG, "Use SPI bus"); + // SPI bus +#if !ESP_PANEL_TOUCH_BUS_SKIP_INIT_HOST + spi_bus_config_t touch_host_config = { + .mosi_io_num = ESP_PANEL_TOUCH_SPI_IO_MOSI, + .miso_io_num = ESP_PANEL_TOUCH_SPI_IO_MISO, + .sclk_io_num = ESP_PANEL_TOUCH_SPI_IO_SCK, + .quadwp_io_num = GPIO_NUM_NC, + .quadhd_io_num = GPIO_NUM_NC, + .data4_io_num = GPIO_NUM_NC, + .data5_io_num = GPIO_NUM_NC, + .data6_io_num = GPIO_NUM_NC, + .data7_io_num = GPIO_NUM_NC, + .max_transfer_sz = ESP_PANEL_HOST_SPI_MAX_TRANSFER_SIZE, + .flags = SPICOMMON_BUSFLAG_MASTER, + .intr_flags = 0, + }; +#endif + // SPI panel IO + esp_lcd_panel_io_spi_config_t touch_panel_io_config = ESP_PANEL_TOUCH_SPI_PANEL_IO_CONFIG(ESP_PANEL_TOUCH_NAME, + ESP_PANEL_TOUCH_SPI_IO_CS); #else @@ -375,11 +400,12 @@ bool ESP_Panel::init(void) }; #if !ESP_PANEL_TOUCH_BUS_SKIP_INIT_HOST - ADD_HOST(ESP_PANEL_TOUCH_BUS_NAME, host, lcd_touch_host_config, ESP_PANEL_TOUCH_BUS_HOST); + ESP_PANEL_CHECK_FALSE_RET(ADD_HOST(ESP_PANEL_TOUCH_BUS_NAME, host, touch_host_config, ESP_PANEL_TOUCH_BUS_HOST), + false, "Add host failed"); #endif ESP_LOGD(TAG, "Create touch bus"); - touch_bus_ptr = CREATE_BUS_SKIP_HOST(ESP_PANEL_TOUCH_BUS_NAME, lcd_touch_panel_io_config, ESP_PANEL_TOUCH_BUS_HOST); + touch_bus_ptr = CREATE_BUS_SKIP_HOST(ESP_PANEL_TOUCH_BUS_NAME, touch_panel_io_config, ESP_PANEL_TOUCH_BUS_HOST); ESP_PANEL_CHECK_NULL_RET(touch_bus_ptr, false, "Create touch bus failed"); ESP_LOGD(TAG, "Create touch device"); @@ -411,7 +437,8 @@ bool ESP_Panel::init(void) }, .clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL, }; - ADD_HOST(I2C, host, expander_host_config, ESP_PANEL_TOUCH_BUS_HOST); + ESP_PANEL_CHECK_FALSE_RET(ADD_HOST(I2C, host, expander_host_config, ESP_PANEL_TOUCH_BUS_HOST), false, + "Add host failed"); #endif expander_ptr = CREATE_EXPANDER(ESP_PANEL_EXPANDER_NAME, ESP_PANEL_EXPANDER_HOST, ESP_PANEL_EXPANDER_I2C_ADDRESS); } diff --git a/src/ESP_PanelTypes.h b/src/ESP_PanelTypes.h index a5a097a4..ec5c14f8 100644 --- a/src/ESP_PanelTypes.h +++ b/src/ESP_PanelTypes.h @@ -24,7 +24,7 @@ #define _ESP_PANEL_TOUCH_I2C_PANEL_IO_CONFIG(name) ESP_LCD_TOUCH_IO_I2C_ ## name ## _CONFIG() /** - * @brief This macro is used to generate the panel IO configuration according to the touch panel name. + * @brief This macro is used to generate the I2C panel IO configuration according to the touch panel name. * * Taking GT911 as an example, the following is the actual code after macro expansion: * @@ -32,6 +32,16 @@ */ #define ESP_PANEL_TOUCH_I2C_PANEL_IO_CONFIG(name) _ESP_PANEL_TOUCH_I2C_PANEL_IO_CONFIG(name) +#define _ESP_PANEL_TOUCH_SPI_PANEL_IO_CONFIG(name, cs_io) ESP_LCD_TOUCH_IO_SPI_ ## name ## _CONFIG(cs_io) +/** + * @brief This macro is used to generate the SPI panel IO configuration according to the touch panel name. + * + * Taking XPT2046 as an example, the following is the actual code after macro expansion: + * + * ESP_PANEL_TOUCH_SPI_PANEL_IO_CONFIG(XPT2046, 5) => ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(5) + */ +#define ESP_PANEL_TOUCH_SPI_PANEL_IO_CONFIG(name, cs_io) _ESP_PANEL_TOUCH_SPI_PANEL_IO_CONFIG(name, cs_io) + /** * @brief Formater for single LCD vendor command with 8-bit parameter * diff --git a/src/ESP_Panel_Conf_Internal.h b/src/ESP_Panel_Conf_Internal.h index 25fac340..5ab67551 100644 --- a/src/ESP_Panel_Conf_Internal.h +++ b/src/ESP_Panel_Conf_Internal.h @@ -143,6 +143,12 @@ #define ESP_PANEL_TOUCH_BUS_NAME I2C #define ESP_PANEL_TOUCH_BUS_HOST ((i2c_port_t)ESP_PANEL_TOUCH_BUS_HOST_ID) + #elif ESP_PANEL_TOUCH_BUS_TYPE == ESP_PANEL_BUS_TYPE_SPI + + #include "hal/spi_types.h" + #define ESP_PANEL_TOUCH_BUS_NAME SPI + #define ESP_PANEL_TOUCH_BUS_HOST ((spi_host_device_t)ESP_PANEL_TOUCH_BUS_HOST_ID) + #else #error "Unkonw Touch bus type selected, please refer to the README for supported bus types." diff --git a/src/ESP_Panel_Library.h b/src/ESP_Panel_Library.h index 117855bb..7e0f5c02 100644 --- a/src/ESP_Panel_Library.h +++ b/src/ESP_Panel_Library.h @@ -42,6 +42,7 @@ #include "touch/GT911.h" #include "touch/ST7123.h" #include "touch/TT21100.h" +#include "touch/XPT2046.h" /* Backlight */ #include "backlight/ESP_PanelBacklight.h" diff --git a/src/bus/I2C.h b/src/bus/I2C.h index 32a417ee..496a83c3 100644 --- a/src/bus/I2C.h +++ b/src/bus/I2C.h @@ -21,6 +21,8 @@ class ESP_PanelBus_I2C: public ESP_PanelBus { /** * @brief Construct a I2C bus object in a common way, the host will be initialized by the driver * + * @note This function uses some default values (ESP_PANEL_HOST_I2C_CONFIG_DEFAULT) to config the bus object, + * use `config*()` functions to change them * @note The `init()` function should be called after this function * * @param scl_io I2C SCL pin diff --git a/src/bus/SPI.cpp b/src/bus/SPI.cpp index 68fe4ec5..a81a6646 100644 --- a/src/bus/SPI.cpp +++ b/src/bus/SPI.cpp @@ -20,6 +20,13 @@ ESP_PanelBus_SPI::ESP_PanelBus_SPI(int cs_io, int dc_io, int sck_io, int sda_io, { } +ESP_PanelBus_SPI::ESP_PanelBus_SPI(int sck_io, int mosi_io, int miso_io, const esp_lcd_panel_io_spi_config_t &io_config): + ESP_PanelBus((int)ESP_PANEL_HOST_SPI_ID_DEFAULT, ESP_PANEL_BUS_TYPE_SPI, true), + host_config((spi_bus_config_t)ESP_PANEL_HOST_SPI_CONFIG_DEFAULT(sck_io, mosi_io, miso_io)), + io_config(io_config) +{ +} + ESP_PanelBus_SPI::ESP_PanelBus_SPI(int cs_io, int dc_io): ESP_PanelBus((int)ESP_PANEL_HOST_SPI_ID_DEFAULT, ESP_PANEL_BUS_TYPE_SPI, false), io_config((esp_lcd_panel_io_spi_config_t)ESP_PANEL_IO_SPI_CONFIG_DEFAULT(cs_io, dc_io)) diff --git a/src/bus/SPI.h b/src/bus/SPI.h index 3773b375..07eee1e6 100644 --- a/src/bus/SPI.h +++ b/src/bus/SPI.h @@ -45,8 +45,8 @@ class ESP_PanelBus_SPI: public ESP_PanelBus { /** * @brief Construct a SPI bus object in a common way, the host will be initialized by the driver * - * @note This function uses some default values (ESP_PANEL_IO_SPI_CONFIG_DEFAULT) to config the bus object, - * use `config*()` functions to change them + * @note This function uses some default values (ESP_PANEL_HOST_SPI_CONFIG_DEFAULT && ESP_PANEL_IO_SPI_CONFIG_DEFAULT) + * to config the bus object, use `config*()` functions to change them * @note The `init()` function should be called after this function * * @param cs_io SPI CS pin @@ -58,9 +58,23 @@ class ESP_PanelBus_SPI: public ESP_PanelBus { ESP_PanelBus_SPI(int cs_io, int dc_io, int sck_io, int sda_io, int sdo_io = -1); /** - * @brief Construct a I2C bus object in a common way, the host needs to be initialized by the user + * @brief Construct a SPI bus object in a common way, the host will be initialized by the driver + * + * @note This function uses some default values (ESP_PANEL_HOST_SPI_CONFIG_DEFAULT) to config the bus object, + * use `config*()` functions to change them + * @note The `init()` function should be called after this function + * + * @param sck_io SPI SCK pin + * @param mosi_io SPI MOSI pin + * @param miso_io SPI MISO pin + * @param io_config SPI panel IO configuration + */ + ESP_PanelBus_SPI(int sck_io, int mosi_io, int miso_io, const esp_lcd_panel_io_spi_config_t &io_config); + + /** + * @brief Construct a SPI bus object in a common way, the host needs to be initialized by the user * - * @note This function uses some default values (ESP_PANEL_IO_I2C_CONFIG_DEFAULT) to config the bus object, + * @note This function uses some default values (ESP_PANEL_IO_SPI_CONFIG_DEFAULT) to config the bus object, * use `config*()` functions to change them * @note The `init()` function should be called after this function * @@ -70,7 +84,7 @@ class ESP_PanelBus_SPI: public ESP_PanelBus { ESP_PanelBus_SPI(int cs_io, int dc_io); /** - * @brief Construct a I2C bus object in a complex way, the host will be initialized by the driver + * @brief Construct a SPI bus object in a complex way, the host will be initialized by the driver * * @note The `init()` function should be called after this function * @@ -82,7 +96,7 @@ class ESP_PanelBus_SPI: public ESP_PanelBus { spi_host_device_t host_id = ESP_PANEL_HOST_SPI_ID_DEFAULT); /** - * @brief Construct a I2C bus object in a complex way, the host needs to be initialized by the user + * @brief Construct a SPI bus object in a complex way, the host needs to be initialized by the user * * @note The `init()` function should be called after this function * diff --git a/src/host/ESP_PanelHost.cpp b/src/host/ESP_PanelHost.cpp index 5d9ef479..24b59ed6 100644 --- a/src/host/ESP_PanelHost.cpp +++ b/src/host/ESP_PanelHost.cpp @@ -34,9 +34,9 @@ bool ESP_PanelHost::addHostI2C(const i2c_config_t &host_config, i2c_port_t host_ return true; } - ESP_PANEL_CHECK_FALSE_RET(!memcmp(&ret->second, &host_config, sizeof(i2c_config_t)), false, - "Host I2C[%d] is already exist and attempt to add with a different configuartion", (int)host_id); ESP_LOGD(TAG, "Host I2C[%d] is already exist", (int)host_id); + ESP_PANEL_CHECK_FALSE_RET(!memcmp(&ret->second, &host_config, sizeof(i2c_config_t)), false, + "Attempt to add with a different configuartion"); return true; } @@ -54,9 +54,9 @@ bool ESP_PanelHost::addHostI2C(int scl_io, int sda_io, i2c_port_t host_id) return true; } - ESP_PANEL_CHECK_FALSE_RET(!memcmp(&ret->second, &host_config, sizeof(i2c_config_t)), false, - "Host I2C[%d] is already exist and attempt to add with a different configuartion", (int)host_id); ESP_LOGD(TAG, "Host I2C[%d] is already exist", (int)host_id); + ESP_PANEL_CHECK_FALSE_RET(!memcmp(&ret->second, &host_config, sizeof(i2c_config_t)), false, + "Attempt to add with a different configuartion"); return true; } @@ -72,10 +72,11 @@ bool ESP_PanelHost::addHostSPI(const spi_bus_config_t &host_config, spi_host_dev return true; } - ESP_PANEL_CHECK_FALSE_RET(!memcmp(&ret->second, &host_config, sizeof(spi_bus_config_t)), false, - "Host SPI[%d] is already exist and attempt to add with a different configuartion", (int)host_id); ESP_LOGD(TAG, "Host SPI[%d] is already exist", (int)host_id); + ESP_PANEL_CHECK_FALSE_RET(compare_spi_host_config(ret->second, host_config), false, + "Attempt to add with a different configuartion"); + return true; } @@ -92,10 +93,11 @@ bool ESP_PanelHost::addHostSPI(int sck_io, int sda_io, int sdo_io, spi_host_devi return true; } - ESP_PANEL_CHECK_FALSE_RET(!memcmp(&ret->second, &host_config, sizeof(spi_bus_config_t)), false, - "SPI[%d] is already exist and attempt to add with a different configuartion", (int)host_id); ESP_LOGD(TAG, "Host SPI[%d] is already exist", (int)host_id); + ESP_PANEL_CHECK_FALSE_RET(compare_spi_host_config(ret->second, host_config), false, + "Attempt to add with a different configuartion"); + return true; } @@ -110,9 +112,9 @@ bool ESP_PanelHost::addHostQSPI(const spi_bus_config_t &host_config, spi_host_de return true; } - ESP_PANEL_CHECK_FALSE_RET(!memcmp(&ret->second, &host_config, sizeof(spi_bus_config_t)), false, - "Host SPI[%d] is already exist and attempt to add with a different configuartion", (int)host_id); ESP_LOGD(TAG, "Host SPI[%d] is already exist", (int)host_id); + ESP_PANEL_CHECK_FALSE_RET(!memcmp(&ret->second, &host_config, sizeof(spi_bus_config_t)), false, + "Attempt to add with a different configuartion"); return true; } @@ -130,9 +132,9 @@ bool ESP_PanelHost::addHostQSPI(int sck_io, int d0_io, int d1_io, int d2_io, int return true; } - ESP_PANEL_CHECK_FALSE_RET(!memcmp(&ret->second, &host_config, sizeof(spi_bus_config_t)), false, - "SPI[%d] is already exist and attempt to add with a different configuartion", (int)host_id); ESP_LOGD(TAG, "Host SPI[%d] is already exist", (int)host_id); + ESP_PANEL_CHECK_FALSE_RET(!memcmp(&ret->second, &host_config, sizeof(spi_bus_config_t)), false, + "Attempt to add with a different configuartion"); return true; } @@ -162,3 +164,17 @@ bool ESP_PanelHost::begin(void) return true; } + +bool ESP_PanelHost::compare_spi_host_config(spi_bus_config_t &old_config, const spi_bus_config_t &new_config) +{ + spi_bus_config_t temp_config = { }; + memcpy(&temp_config, &new_config, sizeof(spi_bus_config_t)); + + if (temp_config.miso_io_num == -1) { + temp_config.miso_io_num = old_config.miso_io_num; + } else if (old_config.miso_io_num == -1) { + old_config.miso_io_num = temp_config.miso_io_num; + } + + return !memcmp(&old_config, &temp_config, sizeof(spi_bus_config_t)); +} diff --git a/src/host/ESP_PanelHost.h b/src/host/ESP_PanelHost.h index 2ad0fb41..fbf9b769 100644 --- a/src/host/ESP_PanelHost.h +++ b/src/host/ESP_PanelHost.h @@ -90,6 +90,8 @@ class ESP_PanelHost { bool begin(void); private: + bool compare_spi_host_config(spi_bus_config_t &old_config, const spi_bus_config_t &new_config); + std::map _i2c_host_config_map; std::map _spi_host_config_map; }; diff --git a/src/touch/README.md b/src/touch/README.md index 74fa9718..ed006b9c 100644 --- a/src/touch/README.md +++ b/src/touch/README.md @@ -9,3 +9,4 @@ | [GT1151](https://components.espressif.com/components/espressif/esp_lcd_touch_gt1151) | 1.0.5~1 | | [ST7123](https://components.espressif.com/components/espressif/esp_lcd_touch_st7123) | 0.0.1 | | [TT21100](https://components.espressif.com/components/espressif/esp_lcd_touch_tt21100) | 1.1.0 | +| [XPT2046](https://components.espressif.com/components/atanisoft/esp_lcd_touch_xpt2046) | 1.0.4 | diff --git a/src/touch/XPT2046.cpp b/src/touch/XPT2046.cpp new file mode 100644 index 00000000..e770e12b --- /dev/null +++ b/src/touch/XPT2046.cpp @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ESP_PanelLog.h" +#include "XPT2046.h" + +static const char *TAG = "XPT2046_CPP"; + +ESP_PanelTouch_XPT2046::ESP_PanelTouch_XPT2046(ESP_PanelBus *bus, uint16_t width, uint16_t height, int rst_io, int int_io): + ESP_PanelTouch(bus, width, height, rst_io, int_io) +{ +} + +ESP_PanelTouch_XPT2046::ESP_PanelTouch_XPT2046(ESP_PanelBus *bus, const esp_lcd_touch_config_t &config): + ESP_PanelTouch(bus, config) +{ +} + +ESP_PanelTouch_XPT2046::~ESP_PanelTouch_XPT2046() +{ + ESP_PANEL_ENABLE_TAG_DEBUG_LOG(); + + if (handle == NULL) { + goto end; + } + + if (!del()) { + ESP_LOGE(TAG, "Delete device failed"); + } + +end: + ESP_LOGD(TAG, "Destroyed"); +} + +bool ESP_PanelTouch_XPT2046::begin(void) +{ + ESP_PANEL_CHECK_NULL_RET(bus, false, "Invalid bus"); + + ESP_PANEL_CHECK_ERR_RET(esp_lcd_touch_new_spi_xpt2046(bus->getHandle(), &config, &handle), false, "New driver failed"); + + return true; +} diff --git a/src/touch/XPT2046.h b/src/touch/XPT2046.h new file mode 100644 index 00000000..2d77e103 --- /dev/null +++ b/src/touch/XPT2046.h @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "base/esp_lcd_touch_xpt2046.h" +#include "ESP_PanelTouch.h" + +/** + * @brief XPT2046 touch device object class + * + * @note This class is a derived class of `ESP_PanelTouch`, user can use it directly + */ +class ESP_PanelTouch_XPT2046 : public ESP_PanelTouch { +public: + /** + * @brief Construct a new touch device in a simple way, the `init()` function should be called after this function + * + * @param bus Pointer to panel bus + * @param width The width of the touch screen + * @param height The height of the touch screen + * @param rst_io The reset pin of the touch screen, set to `-1` if not used + * @param int_io The interrupt pin of the touch screen, set to `-1` if not used + */ + ESP_PanelTouch_XPT2046(ESP_PanelBus *bus, uint16_t width, uint16_t height, int rst_io = -1, int int_io = -1); + + /** + * @brief Construct a new touch device in a complex way, the `init()` function should be called after this function + * + * @param bus Pointer to panel bus + * @param config Touch device configuration + */ + ESP_PanelTouch_XPT2046(ESP_PanelBus *bus, const esp_lcd_touch_config_t &config); + + /** + * @brief Destroy the LCD device + * + */ + ~ESP_PanelTouch_XPT2046() override; + + /** + * @brief Startup the touch device + * + * @return true if success, otherwise false + */ + bool begin(void) override; +}; diff --git a/src/touch/base/esp_lcd_touch_xpt2046.c b/src/touch/base/esp_lcd_touch_xpt2046.c new file mode 100644 index 00000000..dcf6a592 --- /dev/null +++ b/src/touch/base/esp_lcd_touch_xpt2046.c @@ -0,0 +1,395 @@ +/* + * SPDX-FileCopyrightText: 2022 atanisoft (github.com/atanisoft) + * + * SPDX-License-Identifier: MIT + * + * SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD + */ + +#include "ESP_PanelLog.h" + +#include +#include +#include +#include +#include +#include +#include +// This must be included after FreeRTOS includes due to missing include +// for portMUX_TYPE +#include "esp_lcd_touch.h" +#include + +#include "sdkconfig.h" + +#include "esp_lcd_touch_xpt2046.h" + +static const char *TAG = "xpt2046"; + +#ifdef CONFIG_XPT2046_INTERRUPT_MODE +#define XPT2046_PD0_BIT (0x00) +#else +#define XPT2046_PD0_BIT (0x01) +#endif + +#ifdef CONFIG_XPT2046_VREF_ON_MODE +#define XPT2046_PD1_BIT (0x02) +#else +#define XPT2046_PD1_BIT (0x00) +#endif + +#define XPT2046_PD_BITS (XPT2046_PD1_BIT | XPT2046_PD0_BIT) + +enum xpt2046_registers { + // START ADDR MODE SER/ VREF ADC (PENIRQ) + // 12/8b DFR INT/EXT ENA + Z_VALUE_1 = 0xB0 | XPT2046_PD_BITS, // 1 011 0 0 X X + Z_VALUE_2 = 0xC0 | XPT2046_PD_BITS, // 1 100 0 0 X X + Y_POSITION = 0x90 | XPT2046_PD_BITS, // 1 001 0 0 X X + X_POSITION = 0xD0 | XPT2046_PD_BITS, // 1 101 0 0 X X + BATTERY = 0xA6 | XPT2046_PD_BITS, // 1 010 0 1 1 X + AUX_IN = 0xE6 | XPT2046_PD_BITS, // 1 110 0 1 1 X + TEMP0 = 0x86 | XPT2046_PD_BITS, // 1 000 0 1 1 X + TEMP1 = 0xF6 | XPT2046_PD_BITS, // 1 111 0 1 1 X +}; + +#if CONFIG_XPT2046_ENABLE_LOCKING +#define XPT2046_LOCK(lock) portENTER_CRITICAL(lock) +#define XPT2046_UNLOCK(lock) portEXIT_CRITICAL(lock) +#else +#define XPT2046_LOCK(lock) +#define XPT2046_UNLOCK(lock) +#endif + +static const uint16_t XPT2046_ADC_LIMIT = 4096; +// refer the TSC2046 datasheet https://www.ti.com/lit/ds/symlink/tsc2046.pdf rev F 2008 +// TEMP0 reads approx 599.5 mV at 25C (Refer p8 TEMP0 diode voltage vs Vcc chart) +// Vref is approx 2.507V = 2507mV at moderate temperatures (refer p8 Vref vs Temperature chart) +// counts@25C = TEMP0_mV / Vref_mv * XPT2046_ADC_LIMIT +static const float XPT2046_TEMP0_COUNTS_AT_25C = (599.5 / 2507 * XPT2046_ADC_LIMIT); +static esp_err_t xpt2046_read_data(esp_lcd_touch_handle_t tp); +static bool xpt2046_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 xpt2046_del(esp_lcd_touch_handle_t tp); + +esp_err_t esp_lcd_touch_new_spi_xpt2046(const esp_lcd_panel_io_handle_t io, + const esp_lcd_touch_config_t *config, + esp_lcd_touch_handle_t *out_touch) +{ + esp_err_t ret = ESP_OK; + esp_lcd_touch_handle_t handle = NULL; + + ESP_PANEL_ENABLE_TAG_DEBUG_LOG(); + + ESP_GOTO_ON_FALSE(io, ESP_ERR_INVALID_ARG, err, TAG, + "esp_lcd_panel_io_handle_t must not be NULL"); + ESP_GOTO_ON_FALSE(config, ESP_ERR_INVALID_ARG, err, TAG, + "esp_lcd_touch_config_t must not be NULL"); + + handle = (esp_lcd_touch_handle_t)calloc(1, sizeof(esp_lcd_touch_t)); + ESP_GOTO_ON_FALSE(handle, ESP_ERR_NO_MEM, err, TAG, + "No memory available for XPT2046 state"); + handle->io = io; + handle->read_data = xpt2046_read_data; + handle->get_xy = xpt2046_get_xy; + handle->del = xpt2046_del; + handle->data.lock.owner = portMUX_FREE_VAL; + memcpy(&handle->config, config, sizeof(esp_lcd_touch_config_t)); + + // this is not yet supported by esp_lcd_touch. + if (config->int_gpio_num != GPIO_NUM_NC) { + ESP_GOTO_ON_FALSE(GPIO_IS_VALID_GPIO(config->int_gpio_num), + ESP_ERR_INVALID_ARG, err, TAG, "Invalid GPIO Interrupt Pin"); + gpio_config_t cfg; + memset(&cfg, 0, sizeof(gpio_config_t)); + esp_rom_gpio_pad_select_gpio(config->int_gpio_num); + cfg.pin_bit_mask = BIT64(config->int_gpio_num); + cfg.mode = GPIO_MODE_INPUT; + + // If the user has provided a callback routine for the interrupt enable + // the interrupt mode on the negative edge. + if (config->interrupt_callback) { + cfg.intr_type = GPIO_INTR_NEGEDGE; + } + + ESP_GOTO_ON_ERROR(gpio_config(&cfg), err, TAG, + "Configure GPIO for Interrupt failed"); + + // Connect the user interrupt callback routine. + if (config->interrupt_callback) { + esp_lcd_touch_register_interrupt_callback(handle, config->interrupt_callback); + } + } + +err: + if (ret != ESP_OK) { + if (handle) { + xpt2046_del(handle); + handle = NULL; + } + } + + *out_touch = handle; + + ESP_LOGI(TAG, "LCD touch panel create success, version: %d.%d.%d", ESP_LCD_TOUCH_XPT2046_VER_MAJOR, + ESP_LCD_TOUCH_XPT2046_VER_MINOR, ESP_LCD_TOUCH_XPT2046_VER_PATCH); + + return ret; +} + +static esp_err_t xpt2046_del(esp_lcd_touch_handle_t tp) +{ + if (tp != NULL) { + if (tp->config.int_gpio_num != GPIO_NUM_NC) { + gpio_reset_pin(tp->config.int_gpio_num); + } + } + free(tp); + + return ESP_OK; +} + +static inline esp_err_t xpt2046_read_register(esp_lcd_touch_handle_t tp, uint8_t reg, uint16_t *value) +{ + uint8_t buf[2] = {0, 0}; + ESP_RETURN_ON_ERROR(esp_lcd_panel_io_rx_param(tp->io, reg, buf, 2), TAG, "XPT2046 read error!"); + *value = ((buf[0] << 8) | (buf[1])); + return ESP_OK; +} + +static esp_err_t xpt2046_read_data(esp_lcd_touch_handle_t tp) +{ + uint16_t z1 = 0, z2 = 0, z = 0; + uint32_t x = 0, y = 0; + uint8_t point_count = 0; + +#ifdef CONFIG_XPT2046_INTERRUPT_MODE + if (tp->config.int_gpio_num != GPIO_NUM_NC) { + // Check the PENIRQ pin to see if there is a touch + if (gpio_get_level(tp->config.int_gpio_num)) { + XPT2046_LOCK(&tp->data.lock); + tp->data.coords[0].x = 0; + tp->data.coords[0].y = 0; + tp->data.coords[0].strength = 0; + tp->data.points = 0; + XPT2046_UNLOCK(&tp->data.lock); + + return ESP_OK; + } + } +#endif + + ESP_RETURN_ON_ERROR(xpt2046_read_register(tp, Z_VALUE_1, &z1), TAG, "XPT2046 read error!"); + ESP_RETURN_ON_ERROR(xpt2046_read_register(tp, Z_VALUE_2, &z2), TAG, "XPT2046 read error!"); + + // Convert the received values into a Z value. + z = (z1 >> 3) + (XPT2046_ADC_LIMIT - (z2 >> 3)); + + // If the Z (pressure) exceeds the threshold it is likely the user has + // pressed the screen, read in and average the positions. + if (z >= CONFIG_XPT2046_Z_THRESHOLD) { + uint16_t discard_buf = 0; + + // read and discard a value as it is usually not reliable. + ESP_RETURN_ON_ERROR(xpt2046_read_register(tp, X_POSITION, &discard_buf), + TAG, "XPT2046 read error!"); + + for (uint8_t idx = 0; idx < CONFIG_ESP_LCD_TOUCH_MAX_POINTS; idx++) { + uint16_t x_temp = 0; + uint16_t y_temp = 0; + // Read X position and convert returned data to 12bit value + ESP_RETURN_ON_ERROR(xpt2046_read_register(tp, X_POSITION, &x_temp), + TAG, "XPT2046 read error!"); + // drop lowest three bits to convert to 12-bit position + x_temp >>= 3; + + // Read Y position and convert returned data to 12bit value + ESP_RETURN_ON_ERROR(xpt2046_read_register(tp, Y_POSITION, &y_temp), + TAG, "XPT2046 read error!"); + // drop lowest three bits to convert to 12-bit position + y_temp >>= 3; + + // Test if the readings are valid (50 < reading < max - 50) + if ((x_temp >= 50) && (x_temp <= XPT2046_ADC_LIMIT - 50) && (y_temp >= 50) && (y_temp <= XPT2046_ADC_LIMIT - 50)) { +#if CONFIG_XPT2046_CONVERT_ADC_TO_COORDS + // Convert the raw ADC value into a screen coordinate and store it + // for averaging. + x += ((x_temp / (double)XPT2046_ADC_LIMIT) * tp->config.x_max); + y += ((y_temp / (double)XPT2046_ADC_LIMIT) * tp->config.y_max); +#else + // store the raw ADC values and let the user convert them to screen + // coordinates. + x += x_temp; + y += y_temp; +#endif // CONFIG_XPT2046_CONVERT_ADC_TO_COORDS + point_count++; + } + } + + // Check we had enough valid values + const int minimum_count = (1 == CONFIG_ESP_LCD_TOUCH_MAX_POINTS ? 1 : CONFIG_ESP_LCD_TOUCH_MAX_POINTS / 2); + if (point_count >= minimum_count) { + // Average the accumulated coordinate data points. + x /= point_count; + y /= point_count; + point_count = 1; + } else { + z = 0; + point_count = 0; + } + } + + XPT2046_LOCK(&tp->data.lock); + tp->data.coords[0].x = x; + tp->data.coords[0].y = y; + tp->data.coords[0].strength = z; + tp->data.points = point_count; + XPT2046_UNLOCK(&tp->data.lock); + + return ESP_OK; +} + +static bool xpt2046_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) +{ + XPT2046_LOCK(&tp->data.lock); + + // Determine how many touch points that are available. + if (tp->data.points > max_point_num) { + *point_num = max_point_num; + } else { + *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 stored touch data. + tp->data.points = 0; + + XPT2046_UNLOCK(&tp->data.lock); + + if (*point_num) { + ESP_LOGD(TAG, "Touch point: %dx%d", x[0], y[0]); + } else { + ESP_LOGV(TAG, "No touch points"); + } + + return (*point_num > 0); +} + +esp_err_t esp_lcd_touch_xpt2046_read_battery_level(const esp_lcd_touch_handle_t handle, float *output) +{ + uint16_t level; +#ifndef CONFIG_XPT2046_VREF_ON_MODE + // First read is to turn on the Vref, so it has extra time to stabilise before we read it for real + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, BATTERY, &level), TAG, "XPT2046 read error!"); +#endif + // Read the battery voltage + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, BATTERY, &level), TAG, "XPT2046 read error!"); + // drop lowest three bits to convert to 12-bit value + level >>= 3; + + // battery voltage is reported as 1/4 the actual voltage due to logic in + // the chip. + *output = level * 4.0; + + // adjust for internal vref of 2.5v + *output *= 2.507f; + + // adjust for ADC bit count + *output /= 4096.0f; + +#ifndef CONFIG_XPT2046_VREF_ON_MODE + // Final read is to turn the Vref off + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, Z_VALUE_1, &level), TAG, "XPT2046 read error!"); +#endif + + return ESP_OK; +} + +esp_err_t esp_lcd_touch_xpt2046_read_aux_level(const esp_lcd_touch_handle_t handle, float *output) +{ + uint16_t level; +#ifndef CONFIG_XPT2046_VREF_ON_MODE + // First read is to turn on the Vref, so it has extra time to stabilise before we read it for real + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, AUX_IN, &level), TAG, "XPT2046 read error!"); +#endif + // Read the aux input voltage + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, AUX_IN, &level), TAG, "XPT2046 read error!"); + // drop lowest three bits to convert to 12-bit value + level >>= 3; + *output = level; + + // adjust for internal vref of 2.5v + *output *= 2.507f; + + // adjust for ADC bit count + *output /= 4096.0f; + +#ifndef CONFIG_XPT2046_VREF_ON_MODE + // Final read is to turn on the ADC and the Vref off + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, Z_VALUE_1, &level), TAG, "XPT2046 read error!"); +#endif + + return ESP_OK; +} + +esp_err_t esp_lcd_touch_xpt2046_read_temp0_level(const esp_lcd_touch_handle_t handle, float *output) +{ + uint16_t temp0; +#ifndef CONFIG_XPT2046_VREF_ON_MODE + // First read is to turn on the Vref, so it has extra time to stabilise before we read it for real + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, TEMP0, &temp0), TAG, "XPT2046 read error!"); +#endif + // Read the temp0 value + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, TEMP0, &temp0), TAG, "XPT2046 read error!"); + // drop lowest three bits to convert to 12-bit value + temp0 >>= 3; + *output = temp0; + // Convert to temperature in degrees C + *output = (XPT2046_TEMP0_COUNTS_AT_25C - *output) * (2.507 / 4096.0) / 0.0021 + 25.0; + +#ifndef CONFIG_XPT2046_VREF_ON_MODE + // Final read is to turn on the ADC and the Vref off + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, Z_VALUE_1, &temp0), TAG, "XPT2046 read error!"); +#endif + + return ESP_OK; +} + +esp_err_t esp_lcd_touch_xpt2046_read_temp1_level(const esp_lcd_touch_handle_t handle, float *output) +{ + uint16_t temp0; + uint16_t temp1; +#ifndef CONFIG_XPT2046_VREF_ON_MODE + // First read is to turn on the Vref, so it has extra time to stabilise before we read it for real + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, TEMP0, &temp0), TAG, "XPT2046 read error!"); +#endif + // Read the temp0 value + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, TEMP0, &temp0), TAG, "XPT2046 read error!"); + // Read the temp1 value + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, TEMP1, &temp1), TAG, "XPT2046 read error!"); + // drop lowest three bits to convert to 12-bit value + temp0 >>= 3; + temp1 >>= 3; + *output = temp1 - temp0; + *output = *output * 1000.0 * (2.507 / 4096.0) * 2.573 - 273.0; + +#ifndef CONFIG_XPT2046_VREF_ON_MODE + // Final read is to turn on the ADC and the Vref off + ESP_RETURN_ON_ERROR(xpt2046_read_register(handle, Z_VALUE_1, &temp0), TAG, "XPT2046 read error!"); +#endif + + return ESP_OK; +} diff --git a/src/touch/base/esp_lcd_touch_xpt2046.h b/src/touch/base/esp_lcd_touch_xpt2046.h new file mode 100644 index 00000000..c67f4d67 --- /dev/null +++ b/src/touch/base/esp_lcd_touch_xpt2046.h @@ -0,0 +1,235 @@ +/* + * SPDX-FileCopyrightText: 2022 atanisoft (github.com/atanisoft) + * + * SPDX-License-Identifier: MIT + * + * SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD + */ + +#pragma once + +#include "esp_idf_version.h" +#include "esp_lcd_touch.h" +#include "esp_lcd_panel_io.h" + +#include "ESP_Panel_Conf_Internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ESP_LCD_TOUCH_XPT2046_VER_MAJOR (1) +#define ESP_LCD_TOUCH_XPT2046_VER_MINOR (0) +#define ESP_LCD_TOUCH_XPT2046_VER_PATCH (4) + +#define CONFIG_XPT2046_Z_THRESHOLD (ESP_PANEL_TOUCH_XPT2046_Z_THRESHOLD) +#define CONFIG_XPT2046_INTERRUPT_MODE (ESP_PANEL_TOUCH_XPT2046_INTERRUPT_MODE) +#define CONFIG_XPT2046_VREF_ON_MODE (ESP_PANEL_TOUCH_XPT2046_XPT2046_VREF_ON_MODE) +#define CONFIG_XPT2046_CONVERT_ADC_TO_COORDS (ESP_PANEL_TOUCH_XPT2046_CONVERT_ADC_TO_COORDS) + +/** + * @brief Recommended clock for SPI read of the XPT2046 + * + */ +#define ESP_LCD_TOUCH_SPI_CLOCK_HZ (1 * 1000 * 1000) + +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5,0,0) + +/** + * @brief Communication SPI device IO structure + * + */ +#define ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(touch_cs) \ + { \ + .cs_gpio_num = (gpio_num_t)touch_cs, \ + .dc_gpio_num = GPIO_NUM_NC, \ + .spi_mode = 0, \ + .pclk_hz = ESP_LCD_TOUCH_SPI_CLOCK_HZ, \ + .trans_queue_depth = 3, \ + .on_color_trans_done = NULL, \ + .user_ctx = NULL, \ + .lcd_cmd_bits = 8, \ + .lcd_param_bits = 8, \ + .flags = \ + { \ + .dc_as_cmd_phase = 0, \ + .dc_low_on_data = 0, \ + .octal_mode = 0, \ + .lsb_first = 0 \ + } \ + } +#elif ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5,1,0) + +/** + * @brief Communication SPI device IO structure + * + */ +#define ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(touch_cs) \ + { \ + .cs_gpio_num = (gpio_num_t)touch_cs, \ + .dc_gpio_num = GPIO_NUM_NC, \ + .spi_mode = 0, \ + .pclk_hz = ESP_LCD_TOUCH_SPI_CLOCK_HZ, \ + .trans_queue_depth = 3, \ + .on_color_trans_done = NULL, \ + .user_ctx = NULL, \ + .lcd_cmd_bits = 8, \ + .lcd_param_bits = 8, \ + .flags = \ + { \ + .dc_low_on_data = 0, \ + .octal_mode = 0, \ + .lsb_first = 0 \ + } \ + } +#elif ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5,1,2) + +/** + * @brief Communication SPI device IO structure + * + */ +#define ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(touch_cs) \ + { \ + .cs_gpio_num = (gpio_num_t)touch_cs, \ + .dc_gpio_num = GPIO_NUM_NC, \ + .spi_mode = 0, \ + .pclk_hz = ESP_LCD_TOUCH_SPI_CLOCK_HZ, \ + .trans_queue_depth = 3, \ + .on_color_trans_done = NULL, \ + .user_ctx = NULL, \ + .lcd_cmd_bits = 8, \ + .lcd_param_bits = 8, \ + .flags = \ + { \ + .dc_low_on_data = 0, \ + .octal_mode = 0, \ + .sio_mode = 0, \ + .lsb_first = 0, \ + .cs_high_active = 0 \ + } \ + } +#elif ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5,1,3) + +/** + * @brief Communication SPI device IO structure + * + */ +#define ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(touch_cs) \ + { \ + .cs_gpio_num = (gpio_num_t)touch_cs, \ + .dc_gpio_num = GPIO_NUM_NC, \ + .spi_mode = 0, \ + .pclk_hz = ESP_LCD_TOUCH_SPI_CLOCK_HZ, \ + .trans_queue_depth = 3, \ + .on_color_trans_done = NULL, \ + .user_ctx = NULL, \ + .lcd_cmd_bits = 8, \ + .lcd_param_bits = 8, \ + .flags = \ + { \ + .dc_low_on_data = 0, \ + .octal_mode = 0, \ + .quad_mode = 0, \ + .sio_mode = 0, \ + .lsb_first = 0, \ + .cs_high_active = 0 \ + } \ + } +#else + +/** + * @brief Communication SPI device IO structure + * + */ +#define ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(touch_cs) \ + { \ + .cs_gpio_num = (gpio_num_t)touch_cs, \ + .dc_gpio_num = GPIO_NUM_NC, \ + .spi_mode = 0, \ + .pclk_hz = ESP_LCD_TOUCH_SPI_CLOCK_HZ, \ + .trans_queue_depth = 3, \ + .on_color_trans_done = NULL, \ + .user_ctx = NULL, \ + .lcd_cmd_bits = 8, \ + .lcd_param_bits = 8, \ + .flags = \ + { \ + .dc_high_on_cmd = 0, \ + .dc_low_on_data = 0, \ + .dc_low_on_param = 0, \ + .octal_mode = 0, \ + .quad_mode = 0, \ + .sio_mode = 0, \ + .lsb_first = 0, \ + .cs_high_active = 0 \ + } \ + } +#endif // IDF v5.1.3 + +/** + * @brief Create a new XPT2046 touch driver + * + * @note The SPI communication should be initialized before use this function. + * + * @param io: LCD/Touch panel IO handle. + * @param config: Touch configuration. + * @param out_touch: XPT2046 instance handle. + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM if there is insufficient memory for allocating main structure. + * - ESP_ERR_INVALID_ARG if @param io or @param config are null. + */ +esp_err_t esp_lcd_touch_new_spi_xpt2046(const esp_lcd_panel_io_handle_t io, + const esp_lcd_touch_config_t *config, + esp_lcd_touch_handle_t *out_touch); + +/** + * @brief Reads the voltage from the v-bat pin of the XPT2046. + * + * @param handle: XPT2046 instance handle. + * @param out_level: Approximate voltage read in from the v-bat pin. + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + * + * @note The v-bat pin has a voltage range of 0.0 to 6.0 volts. + */ +esp_err_t esp_lcd_touch_xpt2046_read_battery_level(const esp_lcd_touch_handle_t handle, float *out_level); + +/** + * @brief Reads the voltage from the aux pin of the XPT2046. + * + * @param handle: XPT2046 instance handle. + * @param out_level: Approximate voltage read in from the aux pin. + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + * + * @note The aux pin has a voltage range of 0.0 to 2.5 volts. + */ +esp_err_t esp_lcd_touch_xpt2046_read_aux_level(const esp_lcd_touch_handle_t handle, float *out_level); + +/** + * @brief Reads the temperature from the XPT2046 using a one-point reading. + * High precision (0.3 degrees C) but low accuracy requires a + * calibration offset for accurate results. + * + * @param handle: XPT2046 instance handle. + * @param out_level: Approximate tempreature of the TSC2046 in degrees C + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ +esp_err_t esp_lcd_touch_xpt2046_read_temp0_level(const esp_lcd_touch_handle_t handle, float *output); + +/** + * @brief Reads the temperature from the XPT2046 using a two-point reading. + * Low precision (1.6 degrees C) but high accuracy requires no calibration. + * + * @param handle: XPT2046 instance handle. + * @param out_level: Approximate tempreature of the TSC2046 in degrees C + * @return + * - ESP_OK on success, otherwise returns ESP_ERR_xxx + */ +esp_err_t esp_lcd_touch_xpt2046_read_temp1_level(const esp_lcd_touch_handle_t handle, float *output); + +#ifdef __cplusplus +} +#endif