Move drivers from the lv_port_esp32 to here
This commit is contained in:
parent
5a32d98f83
commit
08384030b0
69 changed files with 14977 additions and 2 deletions
34
lvgl_touch/CMakeLists.txt
Normal file
34
lvgl_touch/CMakeLists.txt
Normal file
|
@ -0,0 +1,34 @@
|
|||
if(ESP_PLATFORM)
|
||||
|
||||
set(SOURCES "touch_driver.c")
|
||||
|
||||
# Include only the source file of the selected
|
||||
# display controller.
|
||||
if(CONFIG_LV_TOUCH_CONTROLLER_XPT2046)
|
||||
list(APPEND SOURCES "xpt2046.c")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
|
||||
list(APPEND SOURCES "ft6x36.c")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
|
||||
list(APPEND SOURCES "stmpe610")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
|
||||
list(APPEND SOURCES "adcraw.c")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_FT81X)
|
||||
list(APPEND SOURCES "FT81x.c")
|
||||
elseif(CONFIG_LV_TOUCH_CONTROLLER_RA8875)
|
||||
list(APPEND SOURCES "ra8875_touch.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
|
||||
list(APPEND SOURCES "tp_spi.c")
|
||||
elseif(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)
|
||||
list(APPEND SOURCES "tp_i2c.c")
|
||||
endif()
|
||||
|
||||
# Print the included source files
|
||||
message("SOURCES contents: " "${SOURCES}")
|
||||
|
||||
idf_component_register(SRCS ${SOURCES}
|
||||
INCLUDE_DIRS .
|
||||
REQUIRES lvgl)
|
||||
|
||||
endif()
|
85
lvgl_touch/FT81x.c
Normal file
85
lvgl_touch/FT81x.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* @file FT81x.c
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "FT81x.h"
|
||||
|
||||
#include "../lvgl_tft/EVE.h"
|
||||
#include "../lvgl_tft/EVE_commands.h"
|
||||
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
|
||||
/**
|
||||
* Get the current position and state of the touchpad
|
||||
* @param data store the read data here
|
||||
* @return false: because no more data to be read
|
||||
*/
|
||||
bool FT81x_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||
{
|
||||
static int16_t last_x = 0;
|
||||
static int16_t last_y = 0;
|
||||
bool touched = true;
|
||||
|
||||
uint32_t XY = EVE_memRead32(REG_TOUCH_SCREEN_XY);
|
||||
uint16_t Y = XY & 0xffff;
|
||||
uint16_t X = XY >> 16;
|
||||
|
||||
// is it not touched (or invalid because of calibration range)
|
||||
if(X == 0x8000 || Y == 0x8000 || X > LV_HOR_RES_MAX || Y > LV_VER_RES_MAX)
|
||||
{
|
||||
touched = false;
|
||||
X = last_x;
|
||||
Y = last_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_x = X;
|
||||
last_y = Y;
|
||||
}
|
||||
|
||||
data->point.x = X;
|
||||
data->point.y = Y;
|
||||
data->state = (touched == false ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
46
lvgl_touch/FT81x.h
Normal file
46
lvgl_touch/FT81x.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* @file STMPE610.h
|
||||
*/
|
||||
|
||||
#ifndef FT81X_TOUCH__H
|
||||
#define FT81X_TOUCH__H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
;
|
||||
bool FT81x_read(lv_indev_drv_t * drv, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* FT81X_TOUCH__H */
|
458
lvgl_touch/Kconfig
Normal file
458
lvgl_touch/Kconfig
Normal file
|
@ -0,0 +1,458 @@
|
|||
menu "LVGL Touch controller"
|
||||
|
||||
config LV_TOUCH_CONTROLLER
|
||||
int
|
||||
default 0 if LV_TOUCH_CONTROLLER_NONE
|
||||
default 1 if LV_TOUCH_CONTROLLER_XPT2046
|
||||
default 2 if LV_TOUCH_CONTROLLER_FT6X06
|
||||
default 3 if LV_TOUCH_CONTROLLER_STMPE610
|
||||
default 4 if LV_TOUCH_CONTROLLER_ADCRAW
|
||||
default 5 if LV_TOUCH_CONTROLLER_FT81X
|
||||
default 6 if LV_TOUCH_CONTROLLER_RA8875
|
||||
|
||||
choice
|
||||
prompt "Select a touch panel controller model."
|
||||
default LV_TOUCH_CONTROLLER_NONE
|
||||
help
|
||||
Select the controller for your touch panel.
|
||||
|
||||
config LV_TOUCH_CONTROLLER_NONE
|
||||
bool "None"
|
||||
config LV_TOUCH_CONTROLLER_XPT2046
|
||||
select LV_TOUCH_DRIVER_PROTOCOL_SPI
|
||||
bool "XPT2046"
|
||||
config LV_TOUCH_CONTROLLER_FT6X06
|
||||
select LV_TOUCH_DRIVER_PROTOCOL_I2C
|
||||
bool "FT6X06"
|
||||
config LV_TOUCH_CONTROLLER_STMPE610
|
||||
select LV_TOUCH_DRIVER_PROTOCOL_SPI
|
||||
bool "STMPE610"
|
||||
config LV_TOUCH_CONTROLLER_ADCRAW
|
||||
select LV_TOUCH_DRIVER_ADC
|
||||
bool "ADCRAW"
|
||||
config LV_TOUCH_CONTROLLER_FT81X
|
||||
select LV_TOUCH_DRIVER_PROTOCOL_SPI
|
||||
bool "FT81X"
|
||||
config LV_TOUCH_CONTROLLER_RA8875
|
||||
select LV_TOUCH_DRIVER_DISPLAY
|
||||
bool "RA8875"
|
||||
endchoice
|
||||
|
||||
config LV_TOUCH_DRIVER_PROTOCOL_SPI
|
||||
bool
|
||||
help
|
||||
Touch controller protocol SPI
|
||||
|
||||
config LV_TOUCH_DRIVER_PROTOCOL_I2C
|
||||
bool
|
||||
help
|
||||
Touch controller protocol I2C
|
||||
|
||||
config LV_TOUCH_DRIVER_ADC
|
||||
bool
|
||||
help
|
||||
Touch controller via ADC
|
||||
|
||||
config LV_TOUCH_DRIVER_DISPLAY
|
||||
bool
|
||||
help
|
||||
Touch controller uses same interface/device as display
|
||||
(Note: Display must be initialized before touch)
|
||||
|
||||
choice
|
||||
prompt "Touch I2C port"
|
||||
depends on LV_TOUCH_DRIVER_PROTOCOL_I2C
|
||||
|
||||
default LV_TOUCH_I2C_PORT_0
|
||||
help
|
||||
Select the I2C port used by the touch controller.
|
||||
|
||||
config LV_TOUCH_I2C_PORT_0
|
||||
bool "I2C PORT 0"
|
||||
config LV_TOUCH_I2C_PORT_1
|
||||
bool "I2C PORT 1"
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Touch Controller SPI Bus."
|
||||
depends on LV_TOUCH_DRIVER_PROTOCOL_SPI
|
||||
|
||||
default LV_TOUCH_CONTROLLER_SPI_VSPI if !IDF_TARGET_ESP32S2
|
||||
default LV_TOUCH_CONTROLLER_SPI_FSPI if IDF_TARGET_ESP32S2
|
||||
help
|
||||
Select the SPI Bus the TFT Display is attached to.
|
||||
|
||||
config LV_TOUCH_CONTROLLER_SPI_HSPI
|
||||
bool "HSPI"
|
||||
config LV_TOUCH_CONTROLLER_SPI_VSPI
|
||||
bool "VSPI" if !IDF_TARGET_ESP32S2
|
||||
config LV_TOUCH_CONTROLLER_SPI_FSPI
|
||||
bool "FSPI" if IDF_TARGET_ESP32S2
|
||||
endchoice
|
||||
|
||||
menu "Touchpanel (XPT2046) Pin Assignments"
|
||||
depends on LV_TOUCH_CONTROLLER_XPT2046
|
||||
|
||||
config LV_TOUCH_SPI_MISO
|
||||
int
|
||||
prompt "GPIO for MISO (Master In Slave Out)"
|
||||
range 0 39
|
||||
default 35 if LV_PREDEFINED_PINS_38V1
|
||||
default 19
|
||||
|
||||
help
|
||||
Configure the touchpanel MISO pin here.
|
||||
|
||||
config LV_TOUCH_SPI_MOSI
|
||||
int
|
||||
prompt "GPIO for MOSI (Master Out Slave In)"
|
||||
range 0 39
|
||||
default 32 if LV_PREDEFINED_PINS_38V1
|
||||
default 23
|
||||
|
||||
help
|
||||
Configure the touchpanel MOSI pin here.
|
||||
|
||||
config LV_TOUCH_SPI_CLK
|
||||
int "GPIO for CLK (SCK / Serial Clock)"
|
||||
range 0 39
|
||||
default 26 if LV_PREDEFINED_PINS_38V1
|
||||
default 18
|
||||
help
|
||||
Configure the touchpanel CLK pin here.
|
||||
|
||||
config LV_TOUCH_SPI_CS
|
||||
int "GPIO for CS (Slave Select)"
|
||||
range 0 39
|
||||
default 33 if LV_PREDEFINED_PINS_38V1
|
||||
default 5
|
||||
help
|
||||
Configure the touchpanel CS pin here.
|
||||
|
||||
config LV_TOUCH_PIN_IRQ
|
||||
int "GPIO for IRQ (Interrupt Request)"
|
||||
range 0 39
|
||||
default 27 if LV_PREDEFINED_PINS_38V4
|
||||
default 25
|
||||
help
|
||||
Configure the touchpanel CS pin here.
|
||||
endmenu
|
||||
|
||||
menu "Touchpanel Configuration (XPT2046)"
|
||||
depends on LV_TOUCH_CONTROLLER_XPT2046
|
||||
|
||||
config LV_TOUCH_X_MIN
|
||||
int
|
||||
prompt "Minimum X coordinate value."
|
||||
default 0 if LV_PREDEFINED_PINS_38V4
|
||||
default 200
|
||||
|
||||
config LV_TOUCH_Y_MIN
|
||||
int
|
||||
prompt "Minimum Y coordinate value."
|
||||
default 0 if LV_PREDEFINED_PINS_38V4
|
||||
default 120
|
||||
|
||||
config LV_TOUCH_X_MAX
|
||||
int
|
||||
prompt "Maximum X coordinate value."
|
||||
default 4095 if LV_PREDEFINED_PINS_38V4
|
||||
default 1900
|
||||
|
||||
config LV_TOUCH_Y_MAX
|
||||
int
|
||||
prompt "Maximum Y coordinate value."
|
||||
default 4095 if LV_PREDEFINED_PINS_38V4
|
||||
default 1900
|
||||
|
||||
config LV_TOUCH_XY_SWAP
|
||||
bool
|
||||
prompt "Swap XY."
|
||||
default y
|
||||
|
||||
config LV_TOUCH_INVERT_X
|
||||
bool
|
||||
prompt "Invert X coordinate value."
|
||||
default y
|
||||
|
||||
config LV_TOUCH_INVERT_Y
|
||||
bool
|
||||
prompt "Invert Y coordinate value."
|
||||
default y
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Touchpanel (FT6X06) Pin Assignments"
|
||||
depends on LV_TOUCH_CONTROLLER_FT6X06
|
||||
|
||||
config LV_TOUCH_I2C_SDA
|
||||
int
|
||||
prompt "GPIO for SDA (I2C)"
|
||||
range 0 39
|
||||
default 21
|
||||
help
|
||||
Configure the I2C touchpanel SDA pin here.
|
||||
|
||||
config LV_TOUCH_I2C_SCL
|
||||
int "GPIO for clock signal SCL (I2C)"
|
||||
range 0 39
|
||||
default 22
|
||||
help
|
||||
Configure the I2C touchpanel SCL pin here.
|
||||
endmenu
|
||||
|
||||
menu "Touchpanel Configuration (FT6X06)"
|
||||
depends on LV_TOUCH_CONTROLLER_FT6X06
|
||||
|
||||
config LV_FT6X36_SWAPXY
|
||||
bool
|
||||
prompt "Swap X with Y coordinate."
|
||||
default y
|
||||
|
||||
config LV_FT6X36_INVERT_X
|
||||
bool
|
||||
prompt "Invert X coordinate value."
|
||||
default n
|
||||
|
||||
config LV_FT6X36_INVERT_Y
|
||||
bool
|
||||
prompt "Invert Y coordinate value."
|
||||
default y
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Touchpanel (STMPE610) Pin Assignments"
|
||||
depends on LV_TOUCH_CONTROLLER_STMPE610
|
||||
|
||||
config LV_TOUCH_SPI_MISO
|
||||
int
|
||||
prompt "GPIO for MISO (Master In Slave Out)"
|
||||
range 0 39
|
||||
default 35 if LV_PREDEFINED_PINS_38V1
|
||||
default 19 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
|
||||
default 19
|
||||
|
||||
help
|
||||
Configure the touchpanel MISO pin here.
|
||||
|
||||
config LV_TOUCH_SPI_MOSI
|
||||
int
|
||||
prompt "GPIO for MOSI (Master Out Slave In)"
|
||||
range 0 39
|
||||
default 32 if LV_PREDEFINED_PINS_38V1
|
||||
default 18 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
|
||||
default 23
|
||||
|
||||
help
|
||||
Configure the touchpanel MOSI pin here.
|
||||
|
||||
config LV_TOUCH_SPI_CLK
|
||||
int "GPIO for CLK (SCK / Serial Clock)"
|
||||
range 0 39
|
||||
default 26 if LV_PREDEFINED_PINS_38V1
|
||||
default 5 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
|
||||
default 18
|
||||
help
|
||||
Configure the touchpanel CLK pin here.
|
||||
|
||||
config LV_TOUCH_SPI_CS
|
||||
int "GPIO for CS (Slave Select)"
|
||||
range 0 39
|
||||
default 33 if LV_PREDEFINED_PINS_38V1
|
||||
default 32 if LV_PREDEFINED_DISPLAY_ADA_FEATHERWING
|
||||
default 5
|
||||
help
|
||||
Configure the touchpanel CS pin here.
|
||||
endmenu
|
||||
|
||||
menu "Touchpanel Configuration (STMPE610)"
|
||||
depends on LV_TOUCH_CONTROLLER_STMPE610
|
||||
|
||||
config LV_TOUCH_X_MIN
|
||||
int
|
||||
prompt "Minimum X coordinate value."
|
||||
default 160
|
||||
|
||||
config LV_TOUCH_Y_MIN
|
||||
int
|
||||
prompt "Minimum Y coordinate value."
|
||||
default 230
|
||||
|
||||
config LV_TOUCH_X_MAX
|
||||
int
|
||||
prompt "Maximum X coordinate value."
|
||||
default 3800
|
||||
|
||||
config LV_TOUCH_Y_MAX
|
||||
int
|
||||
prompt "Maximum Y coordinate value."
|
||||
default 3800
|
||||
|
||||
config LV_TOUCH_XY_SWAP
|
||||
bool
|
||||
prompt "Swap XY."
|
||||
default n
|
||||
|
||||
config LV_TOUCH_INVERT_X
|
||||
bool
|
||||
prompt "Invert X coordinate value."
|
||||
default y
|
||||
|
||||
config LV_TOUCH_INVERT_Y
|
||||
bool
|
||||
prompt "Invert Y coordinate value."
|
||||
default y
|
||||
endmenu
|
||||
|
||||
menu "Touchpanel (ADCRAW) Pin Assignments"
|
||||
depends on LV_TOUCH_CONTROLLER_ADCRAW
|
||||
|
||||
config LV_TOUCHSCREEN_RESISTIVE_PIN_YU
|
||||
int
|
||||
prompt "GPIO Y+"
|
||||
default 26 if CONFIG_LV_PREDEFINED_DISPLAY_WROVER4
|
||||
default 26
|
||||
|
||||
help
|
||||
Configure the touchpanel Y+ pin. Can be a regular GPIO.
|
||||
|
||||
config LV_TOUCHSCREEN_RESISTIVE_PIN_YD
|
||||
int
|
||||
prompt "GPIO/ADC Y-"
|
||||
default 32 if CONFIG_LV_PREDEFINED_DISPLAY_WROVER4
|
||||
default 32
|
||||
|
||||
help
|
||||
Configure the touchpanel Y- pin. Must be ADC input.
|
||||
|
||||
config LV_TOUCHSCREEN_RESISTIVE_PIN_XL
|
||||
int
|
||||
prompt "GPIO X-"
|
||||
default 27 if CONFIG_LV_PREDEFINED_DISPLAY_WROVER4
|
||||
default 27
|
||||
|
||||
help
|
||||
Configure the touchpanel X- pin. Can be a regular GPIO.
|
||||
|
||||
config LV_TOUCHSCREEN_RESISTIVE_PIN_XR
|
||||
int
|
||||
prompt "GPIO/ADC X+"
|
||||
default 33 if CONFIG_LV_PREDEFINED_DISPLAY_WROVER4
|
||||
default 33
|
||||
|
||||
help
|
||||
Configure the touchpanel X- pin. Must be ADC input.
|
||||
endmenu
|
||||
|
||||
menu "Touchpanel Configuration (ADCRAW)"
|
||||
depends on LV_TOUCH_CONTROLLER_ADCRAW
|
||||
|
||||
config LV_TOUCH_X_MIN
|
||||
int
|
||||
prompt "Minimum X coordinate value."
|
||||
default 160
|
||||
|
||||
config LV_TOUCH_Y_MIN
|
||||
int
|
||||
prompt "Minimum Y coordinate value."
|
||||
default 230
|
||||
|
||||
config LV_TOUCH_X_MAX
|
||||
int
|
||||
prompt "Maximum X coordinate value."
|
||||
default 3800
|
||||
|
||||
config LV_TOUCH_Y_MAX
|
||||
int
|
||||
prompt "Maximum Y coordinate value."
|
||||
default 3800
|
||||
|
||||
config LV_TOUCH_XY_SWAP
|
||||
bool
|
||||
prompt "Swap XY."
|
||||
default n
|
||||
|
||||
config LV_TOUCH_INVERT_X
|
||||
bool
|
||||
prompt "Invert X coordinate value."
|
||||
default y
|
||||
|
||||
config LV_TOUCH_INVERT_Y
|
||||
bool
|
||||
prompt "Invert Y coordinate value."
|
||||
default y
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Touchpanel Configuration (RA8875)"
|
||||
depends on LV_TOUCH_CONTROLLER_RA8875
|
||||
|
||||
config LV_TOUCH_X_MIN
|
||||
int
|
||||
prompt "Minimum X coordinate ADC value"
|
||||
range 0 1023
|
||||
default 0
|
||||
|
||||
config LV_TOUCH_Y_MIN
|
||||
int
|
||||
prompt "Minimum Y coordinate ADC value"
|
||||
range 0 1023
|
||||
default 0
|
||||
|
||||
config LV_TOUCH_X_MAX
|
||||
int
|
||||
prompt "Maximum X coordinate ADC value"
|
||||
range 0 1023
|
||||
default 1023
|
||||
|
||||
config LV_TOUCH_Y_MAX
|
||||
int
|
||||
prompt "Maximum Y coordinate ADC value"
|
||||
range 0 1023
|
||||
default 1023
|
||||
|
||||
config LV_TOUCH_XY_SWAP
|
||||
bool
|
||||
prompt "Swap XY"
|
||||
default n
|
||||
|
||||
config LV_TOUCH_INVERT_X
|
||||
bool
|
||||
prompt "Invert X coordinate value"
|
||||
default n
|
||||
|
||||
config LV_TOUCH_INVERT_Y
|
||||
bool
|
||||
prompt "Invert Y coordinate value"
|
||||
default n
|
||||
|
||||
config LV_TOUCH_RA8875_SAMPLE_TIME
|
||||
int
|
||||
prompt "TP Sample Time Adjusting"
|
||||
range 0 7
|
||||
default 0
|
||||
|
||||
config LV_TOUCH_RA8875_ADC_CLOCK
|
||||
int
|
||||
prompt "ADC Clock Setting"
|
||||
range 0 7
|
||||
default 0
|
||||
|
||||
config LV_TOUCH_RA8875_WAKEUP_ENABLE
|
||||
bool
|
||||
prompt "Touch Panel Wakeup Enable"
|
||||
default n
|
||||
|
||||
config LV_TOUCH_RA8875_EXTERNAL_VREF
|
||||
bool
|
||||
prompt "TP ADC Use External Reference Voltage Source"
|
||||
default n
|
||||
|
||||
config LV_TOUCH_RA8875_DEBOUNCE_ENABLE
|
||||
bool
|
||||
prompt "De-bounce Circuit Enable for Touch Panel Interrupt"
|
||||
default y
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu
|
324
lvgl_touch/adcraw.c
Normal file
324
lvgl_touch/adcraw.c
Normal file
|
@ -0,0 +1,324 @@
|
|||
/**
|
||||
* @file ADCRAW.c
|
||||
*/
|
||||
|
||||
#include "adcraw.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#if CONFIG_LV_TOUCH_CONTROLLER_ADCRAW
|
||||
|
||||
#define TAG "ADCRAW"
|
||||
#define CALIBRATIONINSET 1 // range 0 <= CALIBRATIONINSET <= 40
|
||||
#define SAMPLE_CALIBRATION_POINTS 4
|
||||
// use this scale factor to avoid working in floating point numbers
|
||||
#define TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR 8
|
||||
#define SCALE_FACTOR (1 << TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR)
|
||||
#define CAL_X_INSET (((GetMaxX() + 1) * (CALIBRATIONINSET >> 1)) / 100)
|
||||
#define CAL_Y_INSET (((GetMaxY() + 1) * (CALIBRATIONINSET >> 1)) / 100)
|
||||
#define NUMSAMPLES 8
|
||||
|
||||
static void ad_touch_handler(void *arg);
|
||||
|
||||
static const esp_timer_create_args_t periodic_timer_args = {
|
||||
.callback = &ad_touch_handler,
|
||||
};
|
||||
static esp_timer_handle_t periodic_timer;
|
||||
|
||||
// Current ADC values for X and Y channels
|
||||
int16_t adcX, adcY = 0;
|
||||
int16_t temp_x, temp_y, temp_z1, temp_z2;
|
||||
|
||||
// coefficient values
|
||||
int _trA, _trB, _trC, _trD;
|
||||
|
||||
int16_t xRawTouch[SAMPLE_CALIBRATION_POINTS];
|
||||
int16_t yRawTouch[SAMPLE_CALIBRATION_POINTS];
|
||||
TOUCH_STATES state;
|
||||
|
||||
const gpio_num_t yu = TOUCHSCREEN_RESISTIVE_PIN_YU;
|
||||
const gpio_num_t xl = TOUCHSCREEN_RESISTIVE_PIN_XL;
|
||||
const gpio_num_t yd = TOUCHSCREEN_RESISTIVE_PIN_YD;
|
||||
const gpio_num_t xr = TOUCHSCREEN_RESISTIVE_PIN_XR;
|
||||
|
||||
static const int gpio_to_adc[] = {
|
||||
GPIO_TO_ADC_ELEMENT(TOUCHSCREEN_RESISTIVE_PIN_YD),
|
||||
GPIO_TO_ADC_ELEMENT(TOUCHSCREEN_RESISTIVE_PIN_XR)
|
||||
};
|
||||
|
||||
static void TouchCalculateCalPoints(void)
|
||||
{
|
||||
int32_t trA, trB, trC, trD; // variables for the coefficients
|
||||
int32_t trAhold, trBhold, trChold, trDhold;
|
||||
int32_t test1, test2; // temp variables (must be signed type)
|
||||
|
||||
int16_t xPoint[SAMPLE_CALIBRATION_POINTS], yPoint[SAMPLE_CALIBRATION_POINTS];
|
||||
|
||||
yPoint[0] = yPoint[1] = CAL_Y_INSET;
|
||||
yPoint[2] = yPoint[3] = (GetMaxY() - CAL_Y_INSET);
|
||||
xPoint[0] = xPoint[3] = CAL_X_INSET;
|
||||
xPoint[1] = xPoint[2] = (GetMaxX() - CAL_X_INSET);
|
||||
|
||||
// calculate points transfer function
|
||||
// based on two simultaneous equations solve for the constants
|
||||
|
||||
// use sample points 1 and 4
|
||||
// Dy1 = aTy1 + b; Dy4 = aTy4 + b
|
||||
// Dx1 = cTx1 + d; Dy4 = aTy4 + b
|
||||
|
||||
test1 = (int32_t)yPoint[0] - (int32_t)yPoint[3];
|
||||
test2 = (int32_t)yRawTouch[0] - (int32_t)yRawTouch[3];
|
||||
|
||||
trA = ((int32_t)((int32_t)test1 * SCALE_FACTOR) / test2);
|
||||
trB = ((int32_t)((int32_t)yPoint[0] * SCALE_FACTOR) - (trA * (int32_t)yRawTouch[0]));
|
||||
|
||||
test1 = (int32_t)xPoint[0] - (int32_t)xPoint[2];
|
||||
test2 = (int32_t)xRawTouch[0] - (int32_t)xRawTouch[2];
|
||||
|
||||
trC = ((int32_t)((int32_t)test1 * SCALE_FACTOR) / test2);
|
||||
trD = ((int32_t)((int32_t)xPoint[0] * SCALE_FACTOR) - (trC * (int32_t)xRawTouch[0]));
|
||||
|
||||
trAhold = trA;
|
||||
trBhold = trB;
|
||||
trChold = trC;
|
||||
trDhold = trD;
|
||||
|
||||
// use sample points 2 and 3
|
||||
// Dy2 = aTy2 + b; Dy3 = aTy3 + b
|
||||
// Dx2 = cTx2 + d; Dy3 = aTy3 + b
|
||||
|
||||
test1 = (int32_t)yPoint[1] - (int32_t)yPoint[2];
|
||||
test2 = (int32_t)yRawTouch[1] - (int32_t)yRawTouch[2];
|
||||
|
||||
trA = ((int32_t)(test1 * SCALE_FACTOR) / test2);
|
||||
trB = ((int32_t)((int32_t)yPoint[1] * SCALE_FACTOR) - (trA * (int32_t)yRawTouch[1]));
|
||||
|
||||
test1 = (int32_t)xPoint[1] - (int32_t)xPoint[3];
|
||||
test2 = (int32_t)xRawTouch[1] - (int32_t)xRawTouch[3];
|
||||
|
||||
trC = ((int32_t)((int32_t)test1 * SCALE_FACTOR) / test2);
|
||||
trD = ((int32_t)((int32_t)xPoint[1] * SCALE_FACTOR) - (trC * (int32_t)xRawTouch[1]));
|
||||
|
||||
// get the average and use it
|
||||
_trA = (trA + trAhold) >> 1;
|
||||
_trB = (trB + trBhold) >> 1;
|
||||
_trC = (trC + trChold) >> 1;
|
||||
_trD = (trD + trDhold) >> 1;
|
||||
}
|
||||
|
||||
void adcraw_init(void)
|
||||
{
|
||||
state = IDLE; // set the state of the state machine to start the sampling
|
||||
|
||||
gpio_set_drive_capability(yu, GPIO_DRIVE_CAP_3);
|
||||
gpio_set_drive_capability(yd, GPIO_DRIVE_CAP_3);
|
||||
gpio_set_drive_capability(xl, GPIO_DRIVE_CAP_3);
|
||||
gpio_set_drive_capability(xr, GPIO_DRIVE_CAP_3);
|
||||
|
||||
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
|
||||
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 5 * 1000)); //5ms (expressed as microseconds)
|
||||
|
||||
/*Load calibration data*/
|
||||
xRawTouch[0] = TOUCHCAL_ULX;
|
||||
yRawTouch[0] = TOUCHCAL_ULY;
|
||||
xRawTouch[1] = TOUCHCAL_URX;
|
||||
yRawTouch[1] = TOUCHCAL_URY;
|
||||
xRawTouch[3] = TOUCHCAL_LLX;
|
||||
yRawTouch[3] = TOUCHCAL_LLY;
|
||||
xRawTouch[2] = TOUCHCAL_LRX;
|
||||
yRawTouch[2] = TOUCHCAL_LRY;
|
||||
|
||||
TouchCalculateCalPoints();
|
||||
}
|
||||
|
||||
static void setup_axis(gpio_num_t plus, gpio_num_t minus, gpio_num_t measure, gpio_num_t ignore)
|
||||
{
|
||||
// Set GPIOs:
|
||||
// - Float "ignore" and "measure"
|
||||
gpio_pad_select_gpio(ignore);
|
||||
gpio_set_direction(ignore, GPIO_MODE_DISABLE);
|
||||
gpio_set_pull_mode(ignore, GPIO_FLOATING);
|
||||
gpio_pad_select_gpio(measure);
|
||||
gpio_set_direction(measure, GPIO_MODE_DISABLE);
|
||||
gpio_set_pull_mode(measure, GPIO_FLOATING);
|
||||
// - Set "plus" to 1, "minus" to 0
|
||||
gpio_config(&(gpio_config_t) {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = (1ULL << plus) | (1ULL << minus)
|
||||
});
|
||||
gpio_set_level(plus, 1);
|
||||
gpio_set_level(minus, 0);
|
||||
}
|
||||
|
||||
static void setup_adc(gpio_num_t measure)
|
||||
{
|
||||
// Init ADC
|
||||
adc1_channel_t channel = gpio_to_adc[measure];
|
||||
adc_gpio_init(ADC_UNIT_1, channel);
|
||||
adc1_config_width(ADC_WIDTH_BIT_10);
|
||||
adc1_config_channel_atten(channel, ADC_ATTEN_DB_11);
|
||||
}
|
||||
|
||||
static void insert_sort(int16_t array[], uint8_t size) {
|
||||
uint8_t j;
|
||||
int16_t save;
|
||||
|
||||
for (int i = 1; i < size; i++) {
|
||||
save = array[i];
|
||||
for (j = i; j >= 1 && save < array[j - 1]; j--)
|
||||
array[j] = array[j - 1];
|
||||
array[j] = save;
|
||||
}
|
||||
}
|
||||
|
||||
static void ad_touch_handler(void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
uint8_t i;
|
||||
int16_t samples[NUMSAMPLES];
|
||||
|
||||
switch (state) {
|
||||
case IDLE:
|
||||
adcX = 0;
|
||||
adcY = 0;
|
||||
|
||||
case SET_X :
|
||||
setup_axis(yd, yu, xr, xl);
|
||||
setup_adc(xr);
|
||||
state = READ_X;
|
||||
break;
|
||||
|
||||
case READ_X:
|
||||
for (i = 0; i < NUMSAMPLES; i++)
|
||||
samples[i] = adc1_get_raw(gpio_to_adc[xr]);
|
||||
insert_sort(samples, NUMSAMPLES);
|
||||
temp_x = samples[NUMSAMPLES / 2];
|
||||
|
||||
case SET_Y :
|
||||
setup_axis(xl, xr, yd, yu);
|
||||
setup_adc(yd);
|
||||
state = READ_Y;
|
||||
break;
|
||||
|
||||
case READ_Y:
|
||||
for (i = 0; i < NUMSAMPLES; i++)
|
||||
samples[i] = adc1_get_raw(gpio_to_adc[yd]);
|
||||
insert_sort(samples, NUMSAMPLES);
|
||||
temp_y = samples[NUMSAMPLES / 2];
|
||||
|
||||
case SET_Z1 :
|
||||
setup_axis(yu, xl, yd, xr);
|
||||
setup_adc(yd);
|
||||
state = READ_Z1;
|
||||
break;
|
||||
|
||||
case READ_Z1:
|
||||
temp_z1 = adc1_get_raw(gpio_to_adc[yd]);
|
||||
|
||||
case SET_Z2 :
|
||||
setup_axis(yu, xl, xr, yd);
|
||||
setup_adc(yd);
|
||||
state = READ_Z2;
|
||||
break;
|
||||
|
||||
case READ_Z2:
|
||||
temp_z2 = adc1_get_raw(gpio_to_adc[xr]);
|
||||
|
||||
if (temp_z1 < TOUCHSCREEN_RESISTIVE_PRESS_THRESHOLD) {
|
||||
#if CONFIG_LV_TOUCH_XY_SWAP
|
||||
adcX = temp_y;
|
||||
adcY = temp_x;
|
||||
#else
|
||||
adcX = temp_x;
|
||||
adcY = temp_y;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
adcX = -1;
|
||||
adcY = -1;
|
||||
}
|
||||
state = SET_X;
|
||||
//printf("x: %d y: %d z: %d\n", adcX, adcY, temp_z1 - temp_z2);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int16_t TouchGetRawX(void)
|
||||
{
|
||||
int16_t x = adcX;
|
||||
|
||||
#if CONFIG_LV_TOUCH_INVERT_X
|
||||
x = 1023 - x;
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
||||
static int16_t TouchGetX(void)
|
||||
{
|
||||
int16_t result = TouchGetRawX();
|
||||
|
||||
if (result > 0) {
|
||||
result = (int16_t)((((int32_t)_trC * result) + _trD) >> TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR);
|
||||
}
|
||||
printf("x: %d\n", result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static int16_t TouchGetRawY(void)
|
||||
{
|
||||
int16_t y = adcY;
|
||||
|
||||
#if CONFIG_LV_TOUCH_INVERT_Y
|
||||
y = 1023 - y;
|
||||
#endif
|
||||
return y;
|
||||
}
|
||||
|
||||
static int16_t TouchGetY(void)
|
||||
{
|
||||
int16_t result = TouchGetRawY();
|
||||
|
||||
if (result > 0) {
|
||||
result = (int16_t)((((int32_t)_trA * result) + (int32_t)_trB) >> TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR);
|
||||
}
|
||||
printf("y: %d\n", result);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current position and state of the touchpad
|
||||
* @param data store the read data here
|
||||
* @return false: because no more data to be read
|
||||
*/
|
||||
bool adcraw_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||
{
|
||||
static int16_t last_x = 0;
|
||||
static int16_t last_y = 0;
|
||||
|
||||
int16_t x, y;
|
||||
|
||||
x = TouchGetX();
|
||||
y = TouchGetY();
|
||||
|
||||
if ((x > 0) && (y > 0)) {
|
||||
data->point.x = x;
|
||||
data->point.y = y;
|
||||
last_x = data->point.x;
|
||||
last_y = data->point.y;
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
}
|
||||
else {
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif //CONFIG_LV_TOUCH_CONTROLLER_ADCRAW
|
79
lvgl_touch/adcraw.h
Normal file
79
lvgl_touch/adcraw.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* @file ADCRAW.h
|
||||
*/
|
||||
|
||||
#ifndef ADCRAW_H
|
||||
#define ADCRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/adc.h"
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#define TOUCHSCREEN_RESISTIVE_PIN_YU CONFIG_LV_TOUCHSCREEN_RESSITIVE_PIN_YU // Y+ any gpio
|
||||
#define TOUCHSCREEN_RESISTIVE_PIN_YD CONFIG_LV_TOUCHSCREEN_RESISTIVE_PIN_YD // Y- also ADC
|
||||
#define TOUCHSCREEN_RESISTIVE_PIN_XL CONFIG_LV_TOUCHSCREEN_RESISTIVE_PIN_XL // X- any gpio
|
||||
#define TOUCHSCREEN_RESISTIVE_PIN_XR CONFIG_LV_TOUCHSCREEN_RESISTIVE_PIN_XR // X+ also ADC
|
||||
|
||||
// Default calibration points
|
||||
#define TOUCHCAL_ULX 29 // Upper Left X
|
||||
#define TOUCHCAL_ULY 84 // Upper Left Y
|
||||
#define TOUCHCAL_URX 828 // Upper Right X
|
||||
#define TOUCHCAL_URY 60 // Upper Right Y
|
||||
#define TOUCHCAL_LLX 29 // Lower Left X
|
||||
#define TOUCHCAL_LLY 928 // Lower Left Y
|
||||
#define TOUCHCAL_LRX 828 // Lower Right X
|
||||
#define TOUCHCAL_LRY 928 // Lower Right Y
|
||||
|
||||
#define TOUCHSCREEN_RESISTIVE_PRESS_THRESHOLD 1023
|
||||
|
||||
/*GetMaxX Macro*/
|
||||
#if CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
|
||||
#define GetMaxX() (CONFIG_LV_DISPLAY_WIDTH - 1)
|
||||
#else
|
||||
#define GetMaxX() (CONFIG_LV_DISPLAY_HEIGHT - 1)
|
||||
#endif
|
||||
|
||||
/*GetMaxY Macro*/
|
||||
#if CONFIG_LV_DISPLAY_ORIENTATION_LANDSCAPE
|
||||
#define GetMaxY() (CONFIG_LV_DISPLAY_HEIGHT - 1)
|
||||
#else
|
||||
#define GetMaxY() (CONFIG_LV_DISPLAY_WIDTH - 1)
|
||||
#endif
|
||||
|
||||
#ifndef CONCAT3
|
||||
#define _CONCAT3(a,b,c) a ## b ## c
|
||||
#define CONCAT3(a,b,c) _CONCAT3(a,b,c)
|
||||
#endif
|
||||
|
||||
#define GPIO_TO_ADC_ELEMENT(x) [x] = CONCAT3(ADC1_GPIO, x, _CHANNEL)
|
||||
|
||||
typedef enum {
|
||||
IDLE,
|
||||
SET_X,
|
||||
SET_Y,
|
||||
SET_Z1,
|
||||
SET_Z2,
|
||||
READ_X,
|
||||
READ_Y,
|
||||
READ_Z1,
|
||||
READ_Z2
|
||||
} TOUCH_STATES;
|
||||
|
||||
void adcraw_init(void);
|
||||
bool adcraw_read(lv_indev_drv_t * drv, lv_indev_data_t * data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* ADCRAW_H */
|
4
lvgl_touch/component.mk
Normal file
4
lvgl_touch/component.mk
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Touch drivers
|
||||
|
||||
COMPONENT_SRCDIRS := .
|
||||
COMPONENT_ADD_INCLUDEDIRS := .
|
200
lvgl_touch/ft6x36.c
Normal file
200
lvgl_touch/ft6x36.c
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright © 2020 Wolfgang Christl
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
* software and associated documentation files (the “Software”), to deal in the Software
|
||||
* without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
* to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <driver/i2c.h>
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include <lvgl.h>
|
||||
#else
|
||||
#include <lvgl/lvgl.h>
|
||||
#endif
|
||||
#include "ft6x36.h"
|
||||
#include "tp_i2c.h"
|
||||
|
||||
#define TAG "FT6X36"
|
||||
|
||||
|
||||
ft6x36_status_t ft6x36_status;
|
||||
uint8_t current_dev_addr; // set during init
|
||||
|
||||
esp_err_t ft6x06_i2c_read8(uint8_t slave_addr, uint8_t register_addr, uint8_t *data_buf) {
|
||||
i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
|
||||
|
||||
i2c_master_start(i2c_cmd);
|
||||
i2c_master_write_byte(i2c_cmd, (slave_addr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(i2c_cmd, register_addr, I2C_MASTER_ACK);
|
||||
|
||||
i2c_master_start(i2c_cmd);
|
||||
i2c_master_write_byte(i2c_cmd, (slave_addr << 1) | I2C_MASTER_READ, true);
|
||||
|
||||
i2c_master_read_byte(i2c_cmd, data_buf, I2C_MASTER_NACK);
|
||||
i2c_master_stop(i2c_cmd);
|
||||
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, i2c_cmd, 1000 / portTICK_RATE_MS);
|
||||
i2c_cmd_link_delete(i2c_cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the FT6x36 gesture ID. Initialize first!
|
||||
* @param dev_addr: I2C FT6x36 Slave address.
|
||||
* @retval The gesture ID or 0x00 in case of failure
|
||||
*/
|
||||
uint8_t ft6x36_get_gesture_id() {
|
||||
if (!ft6x36_status.inited) {
|
||||
ESP_LOGE(TAG, "Init first!");
|
||||
return 0x00;
|
||||
}
|
||||
uint8_t data_buf;
|
||||
esp_err_t ret;
|
||||
if ((ret = ft6x06_i2c_read8(current_dev_addr, FT6X36_GEST_ID_REG, &data_buf) != ESP_OK))
|
||||
ESP_LOGE(TAG, "Error reading from device: %s", esp_err_to_name(ret));
|
||||
return data_buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize for FT6x36 communication via I2C
|
||||
* @param dev_addr: Device address on communication Bus (I2C slave address of FT6X36).
|
||||
* @retval None
|
||||
*/
|
||||
void ft6x06_init(uint16_t dev_addr) {
|
||||
if (!ft6x36_status.inited) {
|
||||
|
||||
/* I2C master is initialized before calling this function */
|
||||
#if 0
|
||||
esp_err_t code = i2c_master_init();
|
||||
#else
|
||||
esp_err_t code = ESP_OK;
|
||||
#endif
|
||||
|
||||
if (code != ESP_OK) {
|
||||
ft6x36_status.inited = false;
|
||||
ESP_LOGE(TAG, "Error during I2C init %s", esp_err_to_name(code));
|
||||
} else {
|
||||
ft6x36_status.inited = true;
|
||||
current_dev_addr = dev_addr;
|
||||
uint8_t data_buf;
|
||||
esp_err_t ret;
|
||||
ESP_LOGI(TAG, "Found touch panel controller");
|
||||
if ((ret = ft6x06_i2c_read8(dev_addr, FT6X36_PANEL_ID_REG, &data_buf) != ESP_OK))
|
||||
ESP_LOGE(TAG, "Error reading from device: %s",
|
||||
esp_err_to_name(ret)); // Only show error the first time
|
||||
ESP_LOGI(TAG, "\tDevice ID: 0x%02x", data_buf);
|
||||
|
||||
ft6x06_i2c_read8(dev_addr, FT6X36_CHIPSELECT_REG, &data_buf);
|
||||
ESP_LOGI(TAG, "\tChip ID: 0x%02x", data_buf);
|
||||
|
||||
ft6x06_i2c_read8(dev_addr, FT6X36_DEV_MODE_REG, &data_buf);
|
||||
ESP_LOGI(TAG, "\tDevice mode: 0x%02x", data_buf);
|
||||
|
||||
ft6x06_i2c_read8(dev_addr, FT6X36_FIRMWARE_ID_REG, &data_buf);
|
||||
ESP_LOGI(TAG, "\tFirmware ID: 0x%02x", data_buf);
|
||||
|
||||
ft6x06_i2c_read8(dev_addr, FT6X36_RELEASECODE_REG, &data_buf);
|
||||
ESP_LOGI(TAG, "\tRelease code: 0x%02x", data_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the touch screen X and Y positions values. Ignores multi touch
|
||||
* @param drv:
|
||||
* @param data: Store data here
|
||||
* @retval Always false
|
||||
*/
|
||||
bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
||||
uint8_t data_xy[4]; // 2 bytes X | 2 bytes Y
|
||||
uint8_t touch_pnt_cnt; // Number of detected touch points
|
||||
static int16_t last_x = 0; // 12bit pixel value
|
||||
static int16_t last_y = 0; // 12bit pixel value
|
||||
|
||||
ft6x06_i2c_read8(current_dev_addr, FT6X36_TD_STAT_REG, &touch_pnt_cnt);
|
||||
if (touch_pnt_cnt != 1) { // ignore no touch & multi touch
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read X value
|
||||
i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();
|
||||
|
||||
i2c_master_start(i2c_cmd);
|
||||
i2c_master_write_byte(i2c_cmd, (current_dev_addr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(i2c_cmd, FT6X36_P1_XH_REG, I2C_MASTER_ACK);
|
||||
|
||||
i2c_master_start(i2c_cmd);
|
||||
i2c_master_write_byte(i2c_cmd, (current_dev_addr << 1) | I2C_MASTER_READ, true);
|
||||
|
||||
i2c_master_read_byte(i2c_cmd, &data_xy[0], I2C_MASTER_ACK); // reads FT6X36_P1_XH_REG
|
||||
i2c_master_read_byte(i2c_cmd, &data_xy[1], I2C_MASTER_NACK); // reads FT6X36_P1_XL_REG
|
||||
i2c_master_stop(i2c_cmd);
|
||||
esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, i2c_cmd, 1000 / portTICK_RATE_MS);
|
||||
i2c_cmd_link_delete(i2c_cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error getting X coordinates: %s", esp_err_to_name(ret));
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
data->state = LV_INDEV_STATE_REL; // no touch detected
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read Y value
|
||||
i2c_cmd = i2c_cmd_link_create();
|
||||
|
||||
i2c_master_start(i2c_cmd);
|
||||
i2c_master_write_byte(i2c_cmd, (current_dev_addr << 1) | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(i2c_cmd, FT6X36_P1_YH_REG, I2C_MASTER_ACK);
|
||||
|
||||
i2c_master_start(i2c_cmd);
|
||||
i2c_master_write_byte(i2c_cmd, (current_dev_addr << 1) | I2C_MASTER_READ, true);
|
||||
|
||||
i2c_master_read_byte(i2c_cmd, &data_xy[2], I2C_MASTER_ACK); // reads FT6X36_P1_YH_REG
|
||||
i2c_master_read_byte(i2c_cmd, &data_xy[3], I2C_MASTER_NACK); // reads FT6X36_P1_YL_REG
|
||||
i2c_master_stop(i2c_cmd);
|
||||
ret = i2c_master_cmd_begin(I2C_NUM_0, i2c_cmd, 1000 / portTICK_RATE_MS);
|
||||
i2c_cmd_link_delete(i2c_cmd);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error getting Y coordinates: %s", esp_err_to_name(ret));
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
data->state = LV_INDEV_STATE_REL; // no touch detected
|
||||
return false;
|
||||
}
|
||||
|
||||
last_x = ((data_xy[0] & FT6X36_MSB_MASK) << 8) | (data_xy[1] & FT6X36_LSB_MASK);
|
||||
last_y = ((data_xy[2] & FT6X36_MSB_MASK) << 8) | (data_xy[3] & FT6X36_LSB_MASK);
|
||||
|
||||
#if CONFIG_LV_FT6X36_SWAPXY
|
||||
int16_t swap_buf = last_x;
|
||||
last_x = last_y;
|
||||
last_y = swap_buf;
|
||||
#endif
|
||||
#if CONFIG_LV_FT6X36_INVERT_X
|
||||
last_x = LV_HOR_RES - last_x;
|
||||
#endif
|
||||
#if CONFIG_LV_FT6X36_INVERT_Y
|
||||
last_y = LV_VER_RES - last_y;
|
||||
#endif
|
||||
data->point.x = last_x;
|
||||
data->point.y = last_y;
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
ESP_LOGV(TAG, "X=%u Y=%u", data->point.x, data->point.y);
|
||||
return false;
|
||||
}
|
162
lvgl_touch/ft6x36.h
Normal file
162
lvgl_touch/ft6x36.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
#ifndef __FT6X06_H
|
||||
/*
|
||||
* Copyright © 2020 Wolfgang Christl
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
* software and associated documentation files (the “Software”), to deal in the Software
|
||||
* without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
* to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#define __FT6X06_H
|
||||
|
||||
#include <lvgl/src/lv_hal/lv_hal.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FT6236_I2C_SLAVE_ADDR 0x38
|
||||
|
||||
/* Maximum border values of the touchscreen pad that the chip can handle */
|
||||
#define FT6X36_MAX_WIDTH ((uint16_t)800)
|
||||
#define FT6X36_MAX_HEIGHT ((uint16_t)480)
|
||||
|
||||
/* Max detectable simultaneous touch points */
|
||||
#define FT6X36_MAX_TOUCH_PNTS 2
|
||||
|
||||
/* Register of the current mode */
|
||||
#define FT6X36_DEV_MODE_REG 0x00
|
||||
|
||||
/* Possible modes as of FT6X36_DEV_MODE_REG */
|
||||
#define FT6X36_DEV_MODE_WORKING 0x00
|
||||
#define FT6X36_DEV_MODE_FACTORY 0x04
|
||||
|
||||
#define FT6X36_DEV_MODE_MASK 0x70
|
||||
#define FT6X36_DEV_MODE_SHIFT 4
|
||||
|
||||
/* Gesture ID register */
|
||||
#define FT6X36_GEST_ID_REG 0x01
|
||||
|
||||
/* Possible values returned by FT6X36_GEST_ID_REG */
|
||||
#define FT6X36_GEST_ID_NO_GESTURE 0x00
|
||||
#define FT6X36_GEST_ID_MOVE_UP 0x10
|
||||
#define FT6X36_GEST_ID_MOVE_RIGHT 0x14
|
||||
#define FT6X36_GEST_ID_MOVE_DOWN 0x18
|
||||
#define FT6X36_GEST_ID_MOVE_LEFT 0x1C
|
||||
#define FT6X36_GEST_ID_ZOOM_IN 0x48
|
||||
#define FT6X36_GEST_ID_ZOOM_OUT 0x49
|
||||
|
||||
/* Status register: stores number of active touch points (0, 1, 2) */
|
||||
#define FT6X36_TD_STAT_REG 0x02
|
||||
#define FT6X36_TD_STAT_MASK 0x0F
|
||||
#define FT6X36_TD_STAT_SHIFT 0x00
|
||||
|
||||
/* Touch events */
|
||||
#define FT6X36_TOUCH_EVT_FLAG_PRESS_DOWN 0x00
|
||||
#define FT6X36_TOUCH_EVT_FLAG_LIFT_UP 0x01
|
||||
#define FT6X36_TOUCH_EVT_FLAG_CONTACT 0x02
|
||||
#define FT6X36_TOUCH_EVT_FLAG_NO_EVENT 0x03
|
||||
|
||||
#define FT6X36_TOUCH_EVT_FLAG_SHIFT 6
|
||||
#define FT6X36_TOUCH_EVT_FLAG_MASK (3 << FT6X36_TOUCH_EVT_FLAG_SHIFT)
|
||||
|
||||
#define FT6X36_MSB_MASK 0x0F
|
||||
#define FT6X36_MSB_SHIFT 0
|
||||
#define FT6X36_LSB_MASK 0xFF
|
||||
#define FT6X36_LSB_SHIFT 0
|
||||
|
||||
#define FT6X36_P1_XH_REG 0x03
|
||||
#define FT6X36_P1_XL_REG 0x04
|
||||
#define FT6X36_P1_YH_REG 0x05
|
||||
#define FT6X36_P1_YL_REG 0x06
|
||||
|
||||
#define FT6X36_P1_WEIGHT_REG 0x07 /* Register reporting touch pressure - read only */
|
||||
#define FT6X36_TOUCH_WEIGHT_MASK 0xFF
|
||||
#define FT6X36_TOUCH_WEIGHT_SHIFT 0
|
||||
|
||||
#define FT6X36_P1_MISC_REG 0x08 /* Touch area register */
|
||||
|
||||
#define FT6X36_TOUCH_AREA_MASK (0x04 << 4) /* Values related to FT6X36_Pn_MISC_REG */
|
||||
#define FT6X36_TOUCH_AREA_SHIFT 0x04
|
||||
|
||||
#define FT6X36_P2_XH_REG 0x09
|
||||
#define FT6X36_P2_XL_REG 0x0A
|
||||
#define FT6X36_P2_YH_REG 0x0B
|
||||
#define FT6X36_P2_YL_REG 0x0C
|
||||
#define FT6X36_P2_WEIGHT_REG 0x0D
|
||||
#define FT6X36_P2_MISC_REG 0x0E
|
||||
|
||||
/* Threshold for touch detection */
|
||||
#define FT6X36_TH_GROUP_REG 0x80
|
||||
#define FT6X36_THRESHOLD_MASK 0xFF /* Values FT6X36_TH_GROUP_REG : threshold related */
|
||||
#define FT6X36_THRESHOLD_SHIFT 0
|
||||
|
||||
#define FT6X36_TH_DIFF_REG 0x85 /* Filter function coefficients */
|
||||
|
||||
#define FT6X36_CTRL_REG 0x86 /* Control register */
|
||||
|
||||
#define FT6X36_CTRL_KEEP_ACTIVE_MODE 0x00 /* Will keep the Active mode when there is no touching */
|
||||
#define FT6X36_CTRL_KEEP_AUTO_SWITCH_MONITOR_MODE 0x01 /* Switching from Active mode to Monitor mode automatically when there is no touching */
|
||||
|
||||
#define FT6X36_TIME_ENTER_MONITOR_REG 0x87 /* The time period of switching from Active mode to Monitor mode when there is no touching */
|
||||
|
||||
#define FT6X36_PERIOD_ACTIVE_REG 0x88 /* Report rate in Active mode */
|
||||
#define FT6X36_PERIOD_MONITOR_REG 0x89 /* Report rate in Monitor mode */
|
||||
|
||||
#define FT6X36_RADIAN_VALUE_REG 0x91 /* The value of the minimum allowed angle while Rotating gesture mode */
|
||||
|
||||
#define FT6X36_OFFSET_LEFT_RIGHT_REG 0x92 /* Maximum offset while Moving Left and Moving Right gesture */
|
||||
#define FT6X36_OFFSET_UP_DOWN_REG 0x93 /* Maximum offset while Moving Up and Moving Down gesture */
|
||||
|
||||
#define FT6X36_DISTANCE_LEFT_RIGHT_REG 0x94 /* Minimum distance while Moving Left and Moving Right gesture */
|
||||
#define FT6X36_DISTANCE_UP_DOWN_REG 0x95 /* Minimum distance while Moving Up and Moving Down gesture */
|
||||
|
||||
#define FT6X36_LIB_VER_H_REG 0xA1 /* High 8-bit of LIB Version info */
|
||||
#define FT6X36_LIB_VER_L_REG 0xA2 /* Low 8-bit of LIB Version info */
|
||||
|
||||
#define FT6X36_CHIPSELECT_REG 0xA3 /* 0x36 for ft6236; 0x06 for ft6206 */
|
||||
|
||||
#define FT6X36_POWER_MODE_REG 0xA5
|
||||
#define FT6X36_FIRMWARE_ID_REG 0xA6
|
||||
#define FT6X36_RELEASECODE_REG 0xAF
|
||||
#define FT6X36_PANEL_ID_REG 0xA8
|
||||
#define FT6X36_OPMODE_REG 0xBC
|
||||
|
||||
|
||||
typedef struct {
|
||||
bool inited;
|
||||
} ft6x36_status_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize for FT6x36 communication via I2C
|
||||
* @param dev_addr: Device address on communication Bus (I2C slave address of FT6X36).
|
||||
* @retval None
|
||||
*/
|
||||
void ft6x06_init(uint16_t dev_addr);
|
||||
|
||||
uint8_t ft6x36_get_gesture_id();
|
||||
|
||||
/**
|
||||
* @brief Get the touch screen X and Y positions values. Ignores multi touch
|
||||
* @param drv:
|
||||
* @param data: Store data here
|
||||
* @retval Always false
|
||||
*/
|
||||
bool ft6x36_read(lv_indev_drv_t *drv, lv_indev_data_t *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __FT6X06_H */
|
181
lvgl_touch/ra8875_touch.c
Normal file
181
lvgl_touch/ra8875_touch.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
/**
|
||||
* @file RA8875_TOUCH.c
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "ra8875_touch.h"
|
||||
|
||||
#include "../lvgl_tft/ra8875.h"
|
||||
|
||||
#ifndef CONFIG_LV_TFT_DISPLAY_CONTROLLER_RA8875
|
||||
#error "Display controller must be RA8875"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define DEBUG false
|
||||
#define TAG "RA8875-Touch"
|
||||
|
||||
#define DIV_ROUND_UP(n, d) (((n)+(d)-1)/(d))
|
||||
|
||||
#define INTC2_TP_INT (0x04)
|
||||
|
||||
#define TPCR0_ADC_TIMING ((CONFIG_LV_TOUCH_RA8875_SAMPLE_TIME << 4) | CONFIG_LV_TOUCH_RA8875_ADC_CLOCK)
|
||||
#if LVGL_TOUCH_RA8875_WAKEUP_ENABLE
|
||||
#define TPCR0_VAL (0x08 | TPCR0_ADC_TIMING)
|
||||
#else
|
||||
#define TPCR0_VAL (TPCR0_ADC_TIMING)
|
||||
#endif
|
||||
|
||||
#if LVGL_TOUCH_RA8875_EXTERNAL_VREF
|
||||
#if LVGL_TOUCH_RA8875_DEBOUNCE_ENABLE
|
||||
#define TPCR1_VAL (0x24)
|
||||
#else
|
||||
#define TPCR1_VAL (0x20)
|
||||
#endif
|
||||
#else
|
||||
#if LVGL_TOUCH_RA8875_DEBOUNCE_ENABLE
|
||||
#define TPCR1_VAL (0x04)
|
||||
#else
|
||||
#define TPCR1_VAL (0x00)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void ra8875_corr(int * x, int * y);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void ra8875_touch_init(void)
|
||||
{
|
||||
struct {
|
||||
uint8_t cmd; // Register address of command
|
||||
uint8_t data; // Value to write to register
|
||||
} init_cmds[] = {
|
||||
{RA8875_REG_TPCR0, TPCR0_VAL}, // Touch Panel Control Register 0 (TPCR0)
|
||||
{RA8875_REG_TPCR1, TPCR1_VAL}, // Touch Panel Control Register 1 (TPCR1)
|
||||
};
|
||||
#define INIT_CMDS_SIZE (sizeof(init_cmds)/sizeof(init_cmds[0]))
|
||||
|
||||
ESP_LOGI(TAG, "Initializing RA8875 Touch...");
|
||||
|
||||
// Send all the commands
|
||||
for (unsigned int i = 0; i < INIT_CMDS_SIZE; i++) {
|
||||
ra8875_write_cmd(init_cmds[i].cmd, init_cmds[i].data);
|
||||
}
|
||||
ra8875_touch_enable(true);
|
||||
}
|
||||
|
||||
void ra8875_touch_enable(bool enable)
|
||||
{
|
||||
ESP_LOGI(TAG, "%s touch.", enable ? "Enabling" : "Disabling");
|
||||
uint8_t val = enable ? (0x80 | TPCR0_VAL) : (TPCR0_VAL);
|
||||
ra8875_write_cmd(RA8875_REG_TPCR0, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current position and state of the touchscreen
|
||||
* @param data store the read data here
|
||||
* @return false: because no more data to be read
|
||||
*/
|
||||
bool ra8875_touch_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||
{
|
||||
static int x = 0;
|
||||
static int y = 0;
|
||||
|
||||
int intr = ra8875_read_cmd(RA8875_REG_INTC2); // Interrupt Control Register2 (INTC2)
|
||||
|
||||
data->state = (intr & INTC2_TP_INT) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
|
||||
if (data->state == LV_INDEV_STATE_PR) {
|
||||
x = ra8875_read_cmd(RA8875_REG_TPXH); // Touch Panel X High Byte Data Register (TPXH)
|
||||
y = ra8875_read_cmd(RA8875_REG_TPYH); // Touch Panel Y High Byte Data Register (TPYH)
|
||||
int xy = ra8875_read_cmd(RA8875_REG_TPXYL); // Touch Panel X/Y Low Byte Data Register (TPXYL)
|
||||
|
||||
x = (x << 2) | (xy & 0x03);
|
||||
y = (y << 2) | ((xy >> 2) & 0x03);
|
||||
|
||||
#if DEBUG
|
||||
ESP_LOGI(TAG, "Touch Poll Raw: %d,%d", x, y);
|
||||
#endif
|
||||
|
||||
// Convert to display coordinates
|
||||
ra8875_corr(&x, &y);
|
||||
|
||||
// Clear interrupt
|
||||
ra8875_write_cmd(RA8875_REG_INTC2, INTC2_TP_INT); // Interrupt Control Register2 (INTC2)
|
||||
}
|
||||
|
||||
data->point.x = x;
|
||||
data->point.y = y;
|
||||
|
||||
#if DEBUG
|
||||
ESP_LOGI(TAG, "Touch Poll - Event: %d; %d,%d", data->state, data->point.x, data->point.y);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void ra8875_corr(int * x, int * y)
|
||||
{
|
||||
#if RA8875_XY_SWAP != 0
|
||||
int tmp = *x;
|
||||
*x = *y;
|
||||
*y = tmp;
|
||||
#endif
|
||||
|
||||
if ((*x) <= RA8875_X_MIN) {
|
||||
(*x) = 0;
|
||||
} else if ((*x) >= RA8875_X_MAX) {
|
||||
(*x) = LV_HOR_RES-1;
|
||||
} else {
|
||||
(*x) = (((*x) - RA8875_X_MIN) * (LV_HOR_RES-1)) / (RA8875_X_MAX - RA8875_X_MIN);
|
||||
}
|
||||
|
||||
if ((*y) <= RA8875_Y_MIN) {
|
||||
(*y) = 0;
|
||||
} else if ((*y) >= RA8875_Y_MAX) {
|
||||
(*y) = LV_VER_RES-1;
|
||||
} else {
|
||||
(*y) = (((*y) - RA8875_Y_MIN) * (LV_VER_RES-1)) / (RA8875_Y_MAX - RA8875_Y_MIN);
|
||||
}
|
||||
|
||||
#if RA8875_X_INV != 0
|
||||
(*x) = (LV_HOR_RES-1) - (*x);
|
||||
#endif
|
||||
|
||||
#if RA8875_Y_INV != 0
|
||||
(*y) = (LV_VER_RES-1) - (*y);
|
||||
#endif
|
||||
}
|
56
lvgl_touch/ra8875_touch.h
Normal file
56
lvgl_touch/ra8875_touch.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* @file RA8875_TOUCH.h
|
||||
*/
|
||||
|
||||
#ifndef RA8875X_TOUCH__H
|
||||
#define RA8875X_TOUCH__H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define RA8875_X_MIN CONFIG_LV_TOUCH_X_MIN
|
||||
#define RA8875_Y_MIN CONFIG_LV_TOUCH_Y_MIN
|
||||
#define RA8875_X_MAX CONFIG_LV_TOUCH_X_MAX
|
||||
#define RA8875_Y_MAX CONFIG_LV_TOUCH_Y_MAX
|
||||
#define RA8875_X_INV CONFIG_LV_TOUCH_INVERT_X
|
||||
#define RA8875_Y_INV CONFIG_LV_TOUCH_INVERT_Y
|
||||
#define RA8875_XY_SWAP CONFIG_LV_TOUCH_XY_SWAP
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void ra8875_touch_init(void);
|
||||
void ra8875_touch_enable(bool enable);
|
||||
bool ra8875_touch_read(lv_indev_drv_t * drv, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* RA8875_TOUCH__H */
|
242
lvgl_touch/stmpe610.c
Normal file
242
lvgl_touch/stmpe610.c
Normal file
|
@ -0,0 +1,242 @@
|
|||
/**
|
||||
* @file STMPE610.c
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "stmpe610.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "tp_spi.h"
|
||||
#include <stddef.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define TAG "STMPE610"
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void write_8bit_reg(uint8_t reg, uint8_t val);
|
||||
static uint16_t read_16bit_reg(uint8_t reg);
|
||||
static uint8_t read_8bit_reg(uint8_t reg);
|
||||
static void read_data(int16_t *x, int16_t *y, uint8_t *z);
|
||||
static bool buffer_empty();
|
||||
static void adjust_data(int16_t * x, int16_t * y);
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the STMPE610
|
||||
*/
|
||||
void stmpe610_init(void)
|
||||
{
|
||||
uint8_t u8;
|
||||
uint16_t u16;
|
||||
|
||||
ESP_LOGI(TAG, "Initialization.");
|
||||
|
||||
// Get the initial SPI configuration
|
||||
//u8 = read_8bit_reg(STMPE_SPI_CFG);
|
||||
//ESP_LOGI(TAG, "SPI_CFG = 0x%x", u8);
|
||||
|
||||
// Attempt a software reset
|
||||
write_8bit_reg(STMPE_SYS_CTRL1, STMPE_SYS_CTRL1_RESET);
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
|
||||
// Reset the SPI configuration, making sure auto-increment is set
|
||||
u8 = read_8bit_reg(STMPE_SPI_CFG);
|
||||
write_8bit_reg(STMPE_SPI_CFG, u8 | STMPE_SPI_CFG_AA);
|
||||
u8 = read_8bit_reg(STMPE_SPI_CFG);
|
||||
ESP_LOGI(TAG, "SPI_CFG = 0x%x", u8);
|
||||
|
||||
// Verify SPI communication
|
||||
u16 = read_16bit_reg(STMPE_CHIP_ID);
|
||||
if (u16 != 0x811) {
|
||||
ESP_LOGE(TAG, "Incorrect version: 0x%x", u16);
|
||||
}
|
||||
|
||||
write_8bit_reg(STMPE_SYS_CTRL2, 0x00); // Disable clocks
|
||||
write_8bit_reg(STMPE_TSC_CTRL, 0); // Disable to allow writing
|
||||
|
||||
write_8bit_reg(STMPE_TSC_CTRL,
|
||||
STEMP_TSC_CTRL_TRACK_0 |
|
||||
STMPE_TSC_CTRL_XYZ |
|
||||
STMPE_TSC_CTRL_EN);
|
||||
|
||||
write_8bit_reg(STMPE_TSC_CFG, STMPE_TSC_CFG_4SAMPLE |
|
||||
STMPE_TSC_CFG_DELAY_1MS |
|
||||
STMPE_TSC_CFG_SETTLE_1MS);
|
||||
|
||||
write_8bit_reg(STMPE_TSC_FRACTION_Z, 0x7);
|
||||
write_8bit_reg(STMPE_TSC_I_DRIVE, STMPE_TSC_I_DRIVE_50MA);
|
||||
|
||||
write_8bit_reg(STMPE_SYS_CTRL2, 0x04); // GPIO clock off, TSC clock on, ADC clock on
|
||||
|
||||
write_8bit_reg(STMPE_ADC_CTRL1, STMPE_ADC_CTRL1_12BIT | STMPE_ADC_CTRL1_80CLK);
|
||||
write_8bit_reg(STMPE_ADC_CTRL2, STMPE_ADC_CTRL2_3_25MHZ);
|
||||
|
||||
write_8bit_reg(STMPE_GPIO_ALT_FUNCT, 0x00); // Disable GPIO
|
||||
|
||||
write_8bit_reg(STMPE_FIFO_TH, 1); // Set FIFO threshold
|
||||
write_8bit_reg(STMPE_FIFO_STA, STMPE_FIFO_STA_RESET); // Assert FIFO reset
|
||||
write_8bit_reg(STMPE_FIFO_STA, 0); // Deassert FIFO reset
|
||||
|
||||
write_8bit_reg(STMPE_INT_EN, 0x00); // No interrupts
|
||||
write_8bit_reg(STMPE_INT_STA, 0xFF); // reset all ints
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current position and state of the touchpad
|
||||
* @param data store the read data here
|
||||
* @return false: because no more data to be read
|
||||
*/
|
||||
bool stmpe610_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||
{
|
||||
static int16_t last_x = 0;
|
||||
static int16_t last_y = 0;
|
||||
bool valid = true;
|
||||
int c = 0;
|
||||
int16_t x = 0;
|
||||
int16_t y = 0;
|
||||
uint8_t z;
|
||||
|
||||
if ((read_8bit_reg(STMPE_TSC_CTRL) & STMPE_TSC_TOUCHED) == STMPE_TSC_TOUCHED) {
|
||||
// Making sure that we read all data and return the latest point
|
||||
while (!buffer_empty()) {
|
||||
read_data(&x, &y, &z);
|
||||
c++;
|
||||
}
|
||||
|
||||
if (c > 0) {
|
||||
//ESP_LOGI(TAG, "%d: %d %d %d", c, x, y, z);
|
||||
|
||||
adjust_data(&x, &y);
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
//ESP_LOGI(TAG, " ==> %d %d", x, y);
|
||||
}
|
||||
|
||||
z = read_8bit_reg(STMPE_INT_STA); // Clear interrupts
|
||||
z = read_8bit_reg(STMPE_FIFO_STA);
|
||||
if ((z & STMPE_FIFO_STA_OFLOW) == STMPE_FIFO_STA_OFLOW) {
|
||||
// Clear the FIFO if we discover an overflow
|
||||
write_8bit_reg(STMPE_FIFO_STA, STMPE_FIFO_STA_RESET);
|
||||
write_8bit_reg(STMPE_FIFO_STA, 0); // unreset
|
||||
ESP_LOGE(TAG, "Fifo overflow");
|
||||
}
|
||||
}
|
||||
|
||||
if (c == 0) {
|
||||
x = last_x;
|
||||
y = last_y;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
data->point.x = (int16_t) x;
|
||||
data->point.y = (int16_t) y;
|
||||
data->state = valid == false ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
static void write_8bit_reg(uint8_t reg, uint8_t val)
|
||||
{
|
||||
uint8_t data_send[2];
|
||||
|
||||
data_send[0] = reg;
|
||||
data_send[1] = val;
|
||||
tp_spi_write_reg(data_send, 2);
|
||||
}
|
||||
|
||||
|
||||
static uint16_t read_16bit_reg(uint8_t reg)
|
||||
{
|
||||
uint8_t data_recv[2];
|
||||
|
||||
tp_spi_read_reg(0x80 | reg, data_recv, 2);
|
||||
|
||||
return data_recv[0] << 8 | data_recv[1];
|
||||
}
|
||||
|
||||
|
||||
static uint8_t read_8bit_reg(uint8_t reg)
|
||||
{
|
||||
uint8_t data_recv;
|
||||
|
||||
tp_spi_read_reg(0x80 | reg, &data_recv, 1);
|
||||
|
||||
return data_recv;
|
||||
}
|
||||
|
||||
|
||||
static void read_data(int16_t *x, int16_t *y, uint8_t *z)
|
||||
{
|
||||
*x = read_16bit_reg(STMPE_TSC_DATA_X);
|
||||
*y = read_16bit_reg(STMPE_TSC_DATA_Y);
|
||||
*z = read_8bit_reg(STMPE_TSC_DATA_Z);
|
||||
}
|
||||
|
||||
|
||||
static bool buffer_empty()
|
||||
{
|
||||
return ((read_8bit_reg(STMPE_FIFO_STA) & STMPE_FIFO_STA_EMPTY) == STMPE_FIFO_STA_EMPTY);
|
||||
}
|
||||
|
||||
|
||||
static void adjust_data(int16_t * x, int16_t * y)
|
||||
{
|
||||
#if STMPE610_XY_SWAP != 0
|
||||
int16_t swap_tmp;
|
||||
swap_tmp = *x;
|
||||
*x = *y;
|
||||
*y = swap_tmp;
|
||||
#endif
|
||||
|
||||
if((*x) > STMPE610_X_MIN)(*x) -= STMPE610_X_MIN;
|
||||
else(*x) = 0;
|
||||
|
||||
if((*y) > STMPE610_Y_MIN)(*y) -= STMPE610_Y_MIN;
|
||||
else(*y) = 0;
|
||||
|
||||
(*x) = (uint32_t)((uint32_t)(*x) * LV_HOR_RES) /
|
||||
(STMPE610_X_MAX - STMPE610_X_MIN);
|
||||
|
||||
(*y) = (uint32_t)((uint32_t)(*y) * LV_VER_RES) /
|
||||
(STMPE610_Y_MAX - STMPE610_Y_MIN);
|
||||
|
||||
#if STMPE610_X_INV != 0
|
||||
(*x) = LV_HOR_RES - (*x);
|
||||
#endif
|
||||
|
||||
#if STMPE610_Y_INV != 0
|
||||
(*y) = LV_VER_RES - (*y);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
185
lvgl_touch/stmpe610.h
Normal file
185
lvgl_touch/stmpe610.h
Normal file
|
@ -0,0 +1,185 @@
|
|||
/**
|
||||
* @file STMPE610.h
|
||||
*/
|
||||
|
||||
#ifndef STMPE610_H
|
||||
#define STMPE610_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/** 16-bit Chip Version **/
|
||||
#define STMPE_CHIP_ID 0x00
|
||||
|
||||
/** Reset Control **/
|
||||
#define STMPE_SYS_CTRL1 0x03
|
||||
#define STMPE_SYS_CTRL1_RESET 0x02
|
||||
|
||||
/** Clock Contrl **/
|
||||
#define STMPE_SYS_CTRL2 0x04
|
||||
|
||||
/** SPI Config **/
|
||||
#define STMPE_SPI_CFG 0x08
|
||||
#define STMPE_SPI_CFG_MODE0 0x00
|
||||
#define STMPE_SPI_CFG_MODE1 0x01
|
||||
#define STMPE_SPI_CFG_MODE2 0x02
|
||||
#define STMPE_SPI_CFG_MODE3 0x03
|
||||
#define STMPE_SPI_CFG_AA 0x04
|
||||
|
||||
/** Touchscreen controller setup **/
|
||||
#define STMPE_TSC_CTRL 0x40
|
||||
#define STMPE_TSC_CTRL_EN 0x01
|
||||
#define STMPE_TSC_CTRL_XYZ 0x00
|
||||
#define STMPE_TSC_CTRL_XY 0x02
|
||||
#define STEMP_TSC_CTRL_TRACK_0 0x00
|
||||
#define STEMP_TSC_CTRL_TRACK_4 0x10
|
||||
#define STEMP_TSC_CTRL_TRACK_8 0x20
|
||||
#define STEMP_TSC_CTRL_TRACK_16 0x30
|
||||
#define STEMP_TSC_CTRL_TRACK_32 0x40
|
||||
#define STEMP_TSC_CTRL_TRACK_64 0x50
|
||||
#define STEMP_TSC_CTRL_TRACK_92 0x60
|
||||
#define STEMP_TSC_CTRL_TRACK_127 0x70
|
||||
#define STMPE_TSC_TOUCHED 0x80
|
||||
|
||||
/** Interrupt control **/
|
||||
#define STMPE_INT_CTRL 0x09
|
||||
#define STMPE_INT_CTRL_POL_HIGH 0x04
|
||||
#define STMPE_INT_CTRL_POL_LOW 0x00
|
||||
#define STMPE_INT_CTRL_EDGE 0x02
|
||||
#define STMPE_INT_CTRL_LEVEL 0x00
|
||||
#define STMPE_INT_CTRL_ENABLE 0x01
|
||||
#define STMPE_INT_CTRL_DISABLE 0x00
|
||||
|
||||
/** Interrupt enable **/
|
||||
#define STMPE_INT_EN 0x0A
|
||||
#define STMPE_INT_EN_TOUCHDET 0x01
|
||||
#define STMPE_INT_EN_FIFOTH 0x02
|
||||
#define STMPE_INT_EN_FIFOOF 0x04
|
||||
#define STMPE_INT_EN_FIFOFULL 0x08
|
||||
#define STMPE_INT_EN_FIFOEMPTY 0x10
|
||||
#define STMPE_INT_EN_ADC 0x40
|
||||
#define STMPE_INT_EN_GPIO 0x80
|
||||
|
||||
/** Interrupt status **/
|
||||
#define STMPE_INT_STA 0x0B
|
||||
#define STMPE_INT_STA_TOUCHDET 0x01
|
||||
|
||||
/** ADC control **/
|
||||
#define STMPE_ADC_CTRL1 0x20
|
||||
#define STMPE_ADC_CTRL1_INT 0x00
|
||||
#define STMPE_ADC_CTRL1_EXT 0x02
|
||||
#define STMPE_ADC_CTRL1_12BIT 0x08
|
||||
#define STMPE_ADC_CTRL1_10BIT 0x00
|
||||
#define STMPE_ADC_CTRL1_36CLK 0x00
|
||||
#define STMPE_ADC_CTRL1_44CLK 0x10
|
||||
#define STMPE_ADC_CTRL1_56CLK 0x20
|
||||
#define STMPE_ADC_CTRL1_64CLK 0x30
|
||||
#define STMPE_ADC_CTRL1_80CLK 0x40
|
||||
#define STMPE_ADC_CTRL1_96CLK 0x50
|
||||
#define STMPE_ADC_CTRL1_124CLK 0x60
|
||||
|
||||
/** ADC control **/
|
||||
#define STMPE_ADC_CTRL2 0x21
|
||||
#define STMPE_ADC_CTRL2_1_625MHZ 0x00
|
||||
#define STMPE_ADC_CTRL2_3_25MHZ 0x01
|
||||
#define STMPE_ADC_CTRL2_6_5MHZ 0x02
|
||||
|
||||
/** Touchscreen controller configuration **/
|
||||
#define STMPE_TSC_CFG 0x41
|
||||
#define STMPE_TSC_CFG_1SAMPLE 0x00
|
||||
#define STMPE_TSC_CFG_2SAMPLE 0x40
|
||||
#define STMPE_TSC_CFG_4SAMPLE 0x80
|
||||
#define STMPE_TSC_CFG_8SAMPLE 0xC0
|
||||
#define STMPE_TSC_CFG_DELAY_10US 0x00
|
||||
#define STMPE_TSC_CFG_DELAY_50US 0x08
|
||||
#define STMPE_TSC_CFG_DELAY_100US 0x10
|
||||
#define STMPE_TSC_CFG_DELAY_500US 0x18
|
||||
#define STMPE_TSC_CFG_DELAY_1MS 0x20
|
||||
#define STMPE_TSC_CFG_DELAY_5MS 0x28
|
||||
#define STMPE_TSC_CFG_DELAY_10MS 0x30
|
||||
#define STMPE_TSC_CFG_DELAY_50MS 0x38
|
||||
#define STMPE_TSC_CFG_SETTLE_10US 0x00
|
||||
#define STMPE_TSC_CFG_SETTLE_100US 0x01
|
||||
#define STMPE_TSC_CFG_SETTLE_500US 0x02
|
||||
#define STMPE_TSC_CFG_SETTLE_1MS 0x03
|
||||
#define STMPE_TSC_CFG_SETTLE_5MS 0x04
|
||||
#define STMPE_TSC_CFG_SETTLE_10MS 0x05
|
||||
#define STMPE_TSC_CFG_SETTLE_50MS 0x06
|
||||
#define STMPE_TSC_CFG_SETTLE_100MS 0x07
|
||||
|
||||
/** FIFO level to generate interrupt **/
|
||||
#define STMPE_FIFO_TH 0x4A
|
||||
|
||||
/** Current filled level of FIFO **/
|
||||
#define STMPE_FIFO_SIZE 0x4C
|
||||
|
||||
/** Current status of FIFO **/
|
||||
#define STMPE_FIFO_STA 0x4B
|
||||
#define STMPE_FIFO_STA_RESET 0x01
|
||||
#define STMPE_FIFO_STA_OFLOW 0x80
|
||||
#define STMPE_FIFO_STA_FULL 0x40
|
||||
#define STMPE_FIFO_STA_EMPTY 0x20
|
||||
#define STMPE_FIFO_STA_THTRIG 0x10
|
||||
|
||||
/** Touchscreen controller drive I **/
|
||||
#define STMPE_TSC_I_DRIVE 0x58
|
||||
#define STMPE_TSC_I_DRIVE_20MA 0x00
|
||||
#define STMPE_TSC_I_DRIVE_50MA 0x01
|
||||
|
||||
/** Data port for TSC data address **/
|
||||
#define STMPE_TSC_DATA_X 0x4D
|
||||
#define STMPE_TSC_DATA_Y 0x4F
|
||||
#define STMPE_TSC_DATA_Z 0x51
|
||||
#define STMPE_TSC_FRACTION_Z 0x56
|
||||
|
||||
/** GPIO **/
|
||||
#define STMPE_GPIO_SET_PIN 0x10
|
||||
#define STMPE_GPIO_CLR_PIN 0x11
|
||||
#define STMPE_GPIO_DIR 0x13
|
||||
#define STMPE_GPIO_ALT_FUNCT 0x17
|
||||
|
||||
|
||||
/** Calibration Constants **/
|
||||
#define STMPE610_X_MIN CONFIG_LV_TOUCH_X_MIN
|
||||
#define STMPE610_Y_MIN CONFIG_LV_TOUCH_Y_MIN
|
||||
#define STMPE610_X_MAX CONFIG_LV_TOUCH_X_MAX
|
||||
#define STMPE610_Y_MAX CONFIG_LV_TOUCH_Y_MAX
|
||||
#define STMPE610_XY_SWAP CONFIG_LV_TOUCH_XY_SWAP
|
||||
#define STMPE610_X_INV CONFIG_LV_TOUCH_INVERT_X
|
||||
#define STMPE610_Y_INV CONFIG_LV_TOUCH_INVERT_Y
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void stmpe610_init(void);
|
||||
bool stmpe610_read(lv_indev_drv_t * drv, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* STMPE610_H */
|
47
lvgl_touch/touch_driver.c
Normal file
47
lvgl_touch/touch_driver.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @file touch_driver.c
|
||||
*/
|
||||
|
||||
#include "touch_driver.h"
|
||||
#include "tp_spi.h"
|
||||
#include "tp_i2c.h"
|
||||
|
||||
|
||||
void touch_driver_init(void)
|
||||
{
|
||||
#if defined (CONFIG_LV_TOUCH_CONTROLLER_XPT2046)
|
||||
xpt2046_init();
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
|
||||
ft6x06_init(FT6236_I2C_SLAVE_ADDR);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
|
||||
stmpe610_init();
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
|
||||
adcraw_init();
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
|
||||
/* nothing to do */
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
|
||||
ra8875_touch_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
|
||||
{
|
||||
bool res = false;
|
||||
|
||||
#if defined (CONFIG_LV_TOUCH_CONTROLLER_XPT2046)
|
||||
res = xpt2046_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
|
||||
res = ft6x36_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
|
||||
res = stmpe610_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
|
||||
res = adcraw_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
|
||||
res = FT81x_read(drv, data);
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
|
||||
res = ra8875_touch_read(drv, data);
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
52
lvgl_touch/touch_driver.h
Normal file
52
lvgl_touch/touch_driver.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* @file touch_driver.h
|
||||
*/
|
||||
|
||||
#ifndef TOUCH_DRIVER_H
|
||||
#define TOUCH_DRIVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_LV_TOUCH_CONTROLLER_XPT2046)
|
||||
#include "xpt2046.h"
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
|
||||
#include "ft6x36.h"
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
|
||||
#include "stmpe610.h"
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
|
||||
#include "adcraw.h"
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
|
||||
#include "FT81x.h"
|
||||
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
|
||||
#include "ra8875_touch.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void touch_driver_init(void);
|
||||
bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* TOUCH_DRIVER_H */
|
||||
|
43
lvgl_touch/tp_i2c.c
Normal file
43
lvgl_touch/tp_i2c.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright © 2020 Wolfgang Christl
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
* software and associated documentation files (the “Software”), to deal in the Software
|
||||
* without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
* to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <driver/i2c.h>
|
||||
#include <esp_log.h>
|
||||
|
||||
#define I2C_MASTER_FREQ_HZ 100000 /* 100kHz*/
|
||||
#define I2C_MASTER_TX_BUF_DISABLE 0 /* I2C master doesn't need buffer */
|
||||
#define I2C_MASTER_RX_BUF_DISABLE 0 /* I2C master doesn't need buffer */
|
||||
|
||||
/**
|
||||
* @brief ESP32 I2C init as master
|
||||
* @ret ESP32 error code
|
||||
*/
|
||||
esp_err_t i2c_master_init(void) {
|
||||
int i2c_master_port = I2C_NUM_0;
|
||||
i2c_config_t conf;
|
||||
conf.mode = I2C_MODE_MASTER;
|
||||
conf.sda_io_num = CONFIG_LV_TOUCH_I2C_SDA;
|
||||
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
conf.scl_io_num = CONFIG_LV_TOUCH_I2C_SCL;
|
||||
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
|
||||
i2c_param_config(i2c_master_port, &conf);
|
||||
return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
|
||||
}
|
36
lvgl_touch/tp_i2c.h
Normal file
36
lvgl_touch/tp_i2c.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright © 2020 Wolfgang Christl
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
* software and associated documentation files (the “Software”), to deal in the Software
|
||||
* without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
* to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __TS_H
|
||||
#define __TS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
esp_err_t i2c_master_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TS_H */
|
109
lvgl_touch/tp_spi.c
Normal file
109
lvgl_touch/tp_spi.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* @file tp_spi.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "tp_spi.h"
|
||||
#include "touch_driver.h"
|
||||
#include "esp_system.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "../lvgl_helpers.h"
|
||||
#include "../lvgl_spi_conf.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static spi_device_handle_t spi;
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
void tp_spi_add_device_config(spi_host_device_t host, spi_device_interface_config_t *devcfg)
|
||||
{
|
||||
esp_err_t ret=spi_bus_add_device(host, devcfg, &spi);
|
||||
assert(ret==ESP_OK);
|
||||
}
|
||||
|
||||
void tp_spi_add_device(spi_host_device_t host)
|
||||
{
|
||||
spi_device_interface_config_t devcfg={
|
||||
.clock_speed_hz = SPI_TOUCH_CLOCK_SPEED_HZ,
|
||||
.mode = SPI_TOUCH_SPI_MODE,
|
||||
.spics_io_num=TP_SPI_CS, //CS pin
|
||||
.queue_size=1,
|
||||
.pre_cb=NULL,
|
||||
.post_cb=NULL,
|
||||
.command_bits = 8,
|
||||
.address_bits = 0,
|
||||
.dummy_bits = 0,
|
||||
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_NO_DUMMY,
|
||||
};
|
||||
|
||||
//Attach the Touch controller to the SPI bus
|
||||
tp_spi_add_device_config(host, &devcfg);
|
||||
}
|
||||
|
||||
void tp_spi_xchg(uint8_t* data_send, uint8_t* data_recv, uint8_t byte_count)
|
||||
{
|
||||
spi_transaction_t t = {
|
||||
.length = byte_count * 8, // SPI transaction length is in bits
|
||||
.tx_buffer = data_send,
|
||||
.rx_buffer = data_recv};
|
||||
|
||||
esp_err_t ret = spi_device_transmit(spi, &t);
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
|
||||
void tp_spi_write_reg(uint8_t* data, uint8_t byte_count)
|
||||
{
|
||||
spi_transaction_t t = {
|
||||
.length = byte_count * 8,
|
||||
.tx_buffer = data,
|
||||
.flags = 0
|
||||
};
|
||||
|
||||
esp_err_t ret = spi_device_transmit(spi, &t);
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
|
||||
void tp_spi_read_reg(uint8_t reg, uint8_t* data, uint8_t byte_count)
|
||||
{
|
||||
spi_transaction_t t = {
|
||||
.length = (byte_count + sizeof(reg)) * 8,
|
||||
.rxlength = byte_count * 8,
|
||||
.cmd = reg,
|
||||
.rx_buffer = data,
|
||||
.flags = 0
|
||||
};
|
||||
|
||||
// Read - send first byte as command
|
||||
esp_err_t ret = spi_device_transmit(spi, &t);
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
45
lvgl_touch/tp_spi.h
Normal file
45
lvgl_touch/tp_spi.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* @file tp_spi.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TP_SPI_H
|
||||
#define TP_SPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <stdint.h>
|
||||
#include <driver/spi_master.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void tp_spi_add_device(spi_host_device_t host);
|
||||
void tp_spi_add_device_config(spi_host_device_t host, spi_device_interface_config_t *config);
|
||||
void tp_spi_xchg(uint8_t* data_send, uint8_t* data_recv, uint8_t byte_count);
|
||||
void tp_spi_write_reg(uint8_t* data, uint8_t byte_count);
|
||||
void tp_spi_read_reg(uint8_t reg, uint8_t* data, uint8_t byte_count);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*TP_SPI_H*/
|
180
lvgl_touch/xpt2046.c
Normal file
180
lvgl_touch/xpt2046.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
/**
|
||||
* @file XPT2046.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "xpt2046.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "tp_spi.h"
|
||||
#include <stddef.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define TAG "XPT2046"
|
||||
|
||||
#define CMD_X_READ 0b10010000
|
||||
#define CMD_Y_READ 0b11010000
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void xpt2046_corr(int16_t * x, int16_t * y);
|
||||
static void xpt2046_avg(int16_t * x, int16_t * y);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
int16_t avg_buf_x[XPT2046_AVG];
|
||||
int16_t avg_buf_y[XPT2046_AVG];
|
||||
uint8_t avg_last;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the XPT2046
|
||||
*/
|
||||
void xpt2046_init(void)
|
||||
{
|
||||
gpio_config_t irq_config = {
|
||||
.pin_bit_mask = BIT64(XPT2046_IRQ),
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "XPT2046 Initialization");
|
||||
|
||||
esp_err_t ret = gpio_config(&irq_config);
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current position and state of the touchpad
|
||||
* @param data store the read data here
|
||||
* @return false: because no more data to be read
|
||||
*/
|
||||
bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||||
{
|
||||
static int16_t last_x = 0;
|
||||
static int16_t last_y = 0;
|
||||
bool valid = true;
|
||||
|
||||
int16_t x = 0;
|
||||
int16_t y = 0;
|
||||
|
||||
uint8_t irq = gpio_get_level(XPT2046_IRQ);
|
||||
|
||||
if (irq == 0) {
|
||||
uint8_t data[2];
|
||||
|
||||
tp_spi_read_reg(CMD_X_READ, data, 2);
|
||||
x = (data[0] << 8) | data[1];
|
||||
|
||||
tp_spi_read_reg(CMD_Y_READ, data, 2);
|
||||
y = (data[0] << 8) | data[1];
|
||||
ESP_LOGI(TAG, "P(%d,%d)", x, y);
|
||||
|
||||
/*Normalize Data back to 12-bits*/
|
||||
x = x >> 4;
|
||||
y = y >> 4;
|
||||
ESP_LOGI(TAG, "P_norm(%d,%d)", x, y);
|
||||
|
||||
xpt2046_corr(&x, &y);
|
||||
xpt2046_avg(&x, &y);
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
|
||||
ESP_LOGI(TAG, "x = %d, y = %d", x, y);
|
||||
} else {
|
||||
x = last_x;
|
||||
y = last_y;
|
||||
avg_last = 0;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
data->point.x = x;
|
||||
data->point.y = y;
|
||||
data->state = valid == false ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
static void xpt2046_corr(int16_t * x, int16_t * y)
|
||||
{
|
||||
#if XPT2046_XY_SWAP != 0
|
||||
int16_t swap_tmp;
|
||||
swap_tmp = *x;
|
||||
*x = *y;
|
||||
*y = swap_tmp;
|
||||
#endif
|
||||
|
||||
if((*x) > XPT2046_X_MIN)(*x) -= XPT2046_X_MIN;
|
||||
else(*x) = 0;
|
||||
|
||||
if((*y) > XPT2046_Y_MIN)(*y) -= XPT2046_Y_MIN;
|
||||
else(*y) = 0;
|
||||
|
||||
(*x) = (uint32_t)((uint32_t)(*x) * LV_HOR_RES) /
|
||||
(XPT2046_X_MAX - XPT2046_X_MIN);
|
||||
|
||||
(*y) = (uint32_t)((uint32_t)(*y) * LV_VER_RES) /
|
||||
(XPT2046_Y_MAX - XPT2046_Y_MIN);
|
||||
|
||||
#if XPT2046_X_INV != 0
|
||||
(*x) = LV_HOR_RES - (*x);
|
||||
#endif
|
||||
|
||||
#if XPT2046_Y_INV != 0
|
||||
(*y) = LV_VER_RES - (*y);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void xpt2046_avg(int16_t * x, int16_t * y)
|
||||
{
|
||||
/*Shift out the oldest data*/
|
||||
uint8_t i;
|
||||
for(i = XPT2046_AVG - 1; i > 0 ; i--) {
|
||||
avg_buf_x[i] = avg_buf_x[i - 1];
|
||||
avg_buf_y[i] = avg_buf_y[i - 1];
|
||||
}
|
||||
|
||||
/*Insert the new point*/
|
||||
avg_buf_x[0] = *x;
|
||||
avg_buf_y[0] = *y;
|
||||
if(avg_last < XPT2046_AVG) avg_last++;
|
||||
|
||||
/*Sum the x and y coordinates*/
|
||||
int32_t x_sum = 0;
|
||||
int32_t y_sum = 0;
|
||||
for(i = 0; i < avg_last ; i++) {
|
||||
x_sum += avg_buf_x[i];
|
||||
y_sum += avg_buf_y[i];
|
||||
}
|
||||
|
||||
/*Normalize the sums*/
|
||||
(*x) = (int32_t)x_sum / avg_last;
|
||||
(*y) = (int32_t)y_sum / avg_last;
|
||||
}
|
57
lvgl_touch/xpt2046.h
Normal file
57
lvgl_touch/xpt2046.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* @file XPT2046.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XPT2046_H
|
||||
#define XPT2046_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define XPT2046_IRQ CONFIG_LV_TOUCH_PIN_IRQ
|
||||
|
||||
#define XPT2046_AVG 4
|
||||
#define XPT2046_X_MIN CONFIG_LV_TOUCH_X_MIN
|
||||
#define XPT2046_Y_MIN CONFIG_LV_TOUCH_Y_MIN
|
||||
#define XPT2046_X_MAX CONFIG_LV_TOUCH_X_MAX
|
||||
#define XPT2046_Y_MAX CONFIG_LV_TOUCH_Y_MAX
|
||||
#define XPT2046_X_INV CONFIG_LV_TOUCH_INVERT_X
|
||||
#define XPT2046_Y_INV CONFIG_LV_TOUCH_INVERT_Y
|
||||
#define XPT2046_XY_SWAP CONFIG_LV_TOUCH_XY_SWAP
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void xpt2046_init(void);
|
||||
bool xpt2046_read(lv_indev_drv_t * drv, lv_indev_data_t * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* XPT2046_H */
|
Loading…
Add table
Add a link
Reference in a new issue