Add lvgl custom drivers

This commit is contained in:
fvanroie 2020-05-21 23:13:18 +02:00
parent d9a6402f0f
commit 7d79ba2709
9 changed files with 281 additions and 77 deletions

View File

@ -73,8 +73,13 @@
/********************* /*********************
* DISPLAY DRIVERS * DISPLAY DRIVERS
*********************/ *********************/
#define USE_TFT_ESPI 1 #if defined(USE_FSMC)
#define USE_TFT_ESPI 0
#define USE_FSMC_ILI9341 1 #define USE_FSMC_ILI9341 1
#else
#define USE_TFT_ESPI 1
#define USE_FSMC_ILI9341 0
#endif
/*------------------- /*-------------------
* Monitor of PC * Monitor of PC
@ -238,17 +243,22 @@
/********************* /*********************
* INPUT DEVICES * INPUT DEVICES
*********************/ *********************/
#define USE_XPT2046_ALT_DRV 0
/*-------------- /*--------------
* XPT2046 * XPT2046
*--------------*/ *--------------*/
#ifndef USE_XPT2046 #ifndef USE_XPT2046
#if defined(USE_FSMC)
#define USE_XPT2046 1 #define USE_XPT2046 1
#else
#define USE_XPT2046 0
#endif
#endif #endif
#if USE_XPT2046 #if USE_XPT2046
#define XPT2046_HOR_RES 480 #define XPT2046_HOR_RES TFT_WIDTH
#define XPT2046_VER_RES 320 #define XPT2046_VER_RES TFT_HEIGHT
#define XPT2046_X_MIN 200 #define XPT2046_X_MIN 200
#define XPT2046_Y_MIN 200 #define XPT2046_Y_MIN 200
#define XPT2046_X_MAX 3800 #define XPT2046_X_MAX 3800

View File

@ -8,7 +8,7 @@
*********************/ *********************/
#include "fsmc_ili9341.h" #include "fsmc_ili9341.h"
#if USE_FSMC_ILI9341 != 0 #if USE_FSMC_ILI9341 > 0
#include <stdbool.h> #include <stdbool.h>
#include <Arduino.h> #include <Arduino.h>
@ -17,12 +17,12 @@
#include <Wire.h> #include <Wire.h>
#include "GxTFT_GFX.h" // Hardware-specific library #include "GxTFT_GFX.h" // Hardware-specific library
#include "GxTFT.h" // Hardware-specific library #include "GxTFT.h" // Hardware-specific library
#define TFT_Class GxTFT #define TFT_Class GxTFT
#include "GxIO/GxIO.h" #include "GxIO/GxIO.h"
// select one GxIO class, // select one GxIO class,
// note: "error: 'GxIO_Class' does not name a type": indicates target board selection mismatch // note: "error: 'GxIO_Class' does not name a type": indicates target board selection mismatch
// this version is for use with Arduino package STM32GENERIC, board "BLACK F407VE/ZE/ZG boards". // this version is for use with Arduino package STM32GENERIC, board "BLACK F407VE/ZE/ZG boards".
// Specific Board "BLACK F407ZG (M4 DEMO)" // Specific Board "BLACK F407ZG (M4 DEMO)"
@ -30,7 +30,14 @@
// For Serial I use a Serial to USB converter on PA9, PA10, "SerialUART1". // For Serial I use a Serial to USB converter on PA9, PA10, "SerialUART1".
// https://github.com/danieleff/STM32GENERIC // https://github.com/danieleff/STM32GENERIC
#include "GxIO/STM32DUINO/GxIO_STM32F4_FSMC/GxIO_STM32F4_FSMC.h" #include "GxIO/STM32DUINO/GxIO_STM32F4_FSMC/GxIO_STM32F4_FSMC.h"
#include "myTFTs/my_3.2_TFT_320x240_ILI9341_STM32F407ZGM4_FSMC.h" //#include "myTFTs/my_3.2_TFT_320x240_ILI9341_STM32F407ZGM4_FSMC.h"
// #include "../GxIO/STM32GENERIC/GxIO_STM32F407ZGM4_FSMC/GxIO_STM32F407ZGM4_FSMC.h"
//#include "../GxIO/STM32DUINO/GxIO_STM32F4_FSMC/GxIO_STM32F4_FSMC.h"
#include "GxCTRL/GxCTRL_ILI9341/GxCTRL_ILI9341.h" // 240x320
GxIO_Class io; // #define GxIO_Class is in the selected header file
GxCTRL_Class controller(io); // #define GxCTRL_Class is in the selected header file
TFT_Class tft(io, controller, TFT_WIDTH, TFT_HEIGHT);
#include LV_DRV_DISP_INCLUDE #include LV_DRV_DISP_INCLUDE
#include LV_DRV_DELAY_INCLUDE #include LV_DRV_DELAY_INCLUDE
@ -76,17 +83,49 @@ void fsmc_ili9341_init(uint8_t rotation)
{ {
tft.init(); tft.init();
tft.setRotation(rotation); tft.setRotation(rotation);
// tft.fillScreen(BLUE);
} }
void fsmc_ili9341_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p) /* GxTFT::pushColors only supports writing up to 255 at a time */
/* This local function circumvents this artificial limit */
static inline void pushColors(uint16_t * data, uint32_t len)
{ {
io.startTransaction();
while(len--) {
uint16_t color = *data++;
io.writeData16(color);
}
io.endTransaction();
}
void fsmc_ili9341_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t * color_p)
{
tft.setWindow(x1, y1, x2, y2);
size_t len = (x2 - x1 + 1) * (y2 - y1 + 1); /* Number of pixels */ size_t len = (x2 - x1 + 1) * (y2 - y1 + 1); /* Number of pixels */
#if 1
pushColors((uint16_t *)color_p, len);
#else
// tft.init();
// Serial.print("flush ");
// Serial.print(x1);
// Serial.print(" ");
// Serial.print(y1);
// Serial.print(" ");
// Serial.print(x2);
// Serial.print(" ");
// Serial.print(y2);
// Serial.print(" ");
// Serial.println(len);
/* Update TFT */ /* Update TFT */
// tft.startWrite(); /* Start new TFT transaction */ while(len > 255) {
tft.setWindow(x1, y1, x2, y2); /* set the working window */ tft.pushColors((uint16_t *)color_p, 255);
tft.pushColors((uint16_t *)color_p, len); /* Write words at once */ len -= 255;
// tft.endWrite(); /* terminate TFT transaction */ color_p += 255;
}
tft.pushColors((uint16_t *)color_p, len); // remainder
#endif
/* Tell lvgl that flushing is done */ /* Tell lvgl that flushing is done */
// lv_disp_flush_ready(); // lv_disp_flush_ready();
@ -97,7 +136,7 @@ void fsmc_ili9341_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_
tft.fillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1, color.full); tft.fillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1, color.full);
} }
void fsmc_ili9341_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p) void fsmc_ili9341_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t * color_p)
{ {
fsmc_ili9341_flush(x1, y1, x2, y2, color_p); fsmc_ili9341_flush(x1, y1, x2, y2, color_p);
} }

View File

@ -21,7 +21,7 @@ extern "C" {
#endif #endif
#endif #endif
#if USE_FSMC_ILI9341 #if USE_FSMC_ILI9341>0
#ifdef LV_LVGL_H_INCLUDE_SIMPLE #ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h" #include "lvgl.h"
@ -32,16 +32,6 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define ILI9341_DRIVER 1
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
#define TFT_ROTATION 2 // 0=0, 1=90, 2=180 or 3=270 degree
#define SPI_FREQUENCY 40000000
#define SPI_TOUCH_FREQUENCY 2500000
#define SPI_READ_FREQUENCY 20000000
#define USER_SETUP_LOADED 1
#define TOUCH_DRIVER 0 // XPT2606 Resistive touch panel driver
#define SUPPORT_TRANSACTIONS
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@ -51,9 +41,9 @@ extern "C" {
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
void fsmc_ili9341_init(uint8_t rotation); void fsmc_ili9341_init(uint8_t rotation);
void fsmc_ili9341_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p); void fsmc_ili9341_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t * color_p);
void fsmc_ili9341_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color); void fsmc_ili9341_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
void fsmc_ili9341_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p); void fsmc_ili9341_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t * color_p);
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/

View File

@ -7,7 +7,6 @@
* INCLUDES * INCLUDES
*********************/ *********************/
#include "tft_espi_drv.h" #include "tft_espi_drv.h"
#include "../../../src/hasp_tft.h"
#if USE_TFT_ESPI != 0 #if USE_TFT_ESPI != 0
@ -16,6 +15,7 @@
#include LV_DRV_DISP_INCLUDE #include LV_DRV_DISP_INCLUDE
#include LV_DRV_DELAY_INCLUDE #include LV_DRV_DELAY_INCLUDE
#include "../../../src/hasp_tft.h"
/********************* /*********************
* DEFINES * DEFINES
@ -90,6 +90,13 @@ void tft_espi_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color
tft_espi_flush(x1, y1, x2, y2, color_p); tft_espi_flush(x1, y1, x2, y2, color_p);
} }
#if defined(TOUCH_CS)
bool tft_espi_get_touch(uint16_t * touchX, uint16_t * touchY, uint16_t threshold)
{
return tft.getTouch(touchX, touchY, threshold);
}
#endif
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/

View File

@ -32,16 +32,7 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define ILI9341_DRIVER 1
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
#define TFT_ROTATION 2 // 0=0, 1=90, 2=180 or 3=270 degree
#define SPI_FREQUENCY 40000000
#define SPI_TOUCH_FREQUENCY 2500000
#define SPI_READ_FREQUENCY 20000000
#define USER_SETUP_LOADED 1
#define TOUCH_DRIVER 0 // XPT2606 Resistive touch panel driver
#define SUPPORT_TRANSACTIONS
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@ -54,6 +45,11 @@ void tft_espi_init(uint8_t rotation);
void tft_espi_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p); void tft_espi_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
void tft_espi_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color); void tft_espi_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
void tft_espi_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p); void tft_espi_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
#if defined(TOUCH_CS)
bool tft_espi_get_touch(uint16_t * touchX, uint16_t * touchY, uint16_t threshold);
#endif
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/

View File

@ -12,12 +12,14 @@
#include <stddef.h> #include <stddef.h>
#include LV_DRV_INDEV_INCLUDE #include LV_DRV_INDEV_INCLUDE
#include LV_DRV_DELAY_INCLUDE #include LV_DRV_DELAY_INCLUDE
#include <SPI.h>
#include "XPT2046_Touchscreen.h"
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#define CMD_X_READ 0b10010000 #define CMD_X_READ 0b10010000
#define CMD_Y_READ 0b11010000 #define CMD_Y_READ 0b11010000
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@ -35,6 +37,8 @@ static void xpt2046_avg(int16_t * x, int16_t * y);
int16_t avg_buf_x[XPT2046_AVG]; int16_t avg_buf_x[XPT2046_AVG];
int16_t avg_buf_y[XPT2046_AVG]; int16_t avg_buf_y[XPT2046_AVG];
uint8_t avg_last; uint8_t avg_last;
SPIClass xpt2046_spi(PB15, PB14, PB13, PB12);
XPT2046_Touchscreen ts(PB12);
/********************** /**********************
* MACROS * MACROS
@ -47,9 +51,10 @@ uint8_t avg_last;
/** /**
* Initialize the XPT2046 * Initialize the XPT2046
*/ */
void xpt2046_init(void) void xpt2046_init(uint8_t rotation)
{ {
ts.begin();
ts.setRotation(rotation);
} }
/** /**
@ -66,22 +71,31 @@ bool xpt2046_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
int16_t x = 0; int16_t x = 0;
int16_t y = 0; int16_t y = 0;
uint8_t irq = LV_DRV_INDEV_IRQ_READ; // uint8_t irq = LV_DRV_INDEV_IRQ_READ;
data->state = ts.touched();
if(irq == 0) { if(data->state) {
LV_DRV_INDEV_SPI_CS(0); TS_Point p = ts.getPoint();
x = p.x;
y = p.y;
xpt2046_corr(&x, &y);
LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_X_READ); /*Start x read*/ #if 0
// LV_DRV_INDEV_SPI_CS(0);
xpt2046_spi.beginTransaction(SPI_SETTING);
digitalWrite(PB12, LOW);
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read x MSB*/ xpt2046_spi.transfer(CMD_X_READ); /*Start x read*/
x = buf << 8;
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_Y_READ); /*Until x LSB converted y command can be sent*/ buf = xpt2046_spi.transfer(0); /*Read x MSB*/
x = buf << 8;
buf = xpt2046_spi.transfer(CMD_Y_READ); /*Until x LSB converted y command can be sent*/
x += buf; x += buf;
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read y MSB*/ buf = xpt2046_spi.transfer(0); /*Read y MSB*/
y = buf << 8; y = buf << 8;
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read y LSB*/ buf = xpt2046_spi.transfer(0); /*Read y LSB*/
y += buf; y += buf;
/*Normalize Data*/ /*Normalize Data*/
@ -90,20 +104,38 @@ bool xpt2046_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
xpt2046_corr(&x, &y); xpt2046_corr(&x, &y);
xpt2046_avg(&x, &y); xpt2046_avg(&x, &y);
last_x = x; last_x = x;
last_y = y; last_y = y;
data->state = LV_INDEV_STATE_PR; data->state = LV_INDEV_STATE_PR;
LV_DRV_INDEV_SPI_CS(1); if(data->state) {
Serial.print(x);
Serial.print(" - ");
Serial.println(y);
} else {
Serial.print(".");
}
// LV_DRV_INDEV_SPI_CS(1);
digitalWrite(PB12, HIGH);
xpt2046_spi.endTransaction();
#endif
} else { } else {
x = last_x; x = last_x;
y = last_y; y = last_y;
avg_last = 0; avg_last = 0;
data->state = LV_INDEV_STATE_REL; data->state = LV_INDEV_STATE_REL;
} }
data->point.x = x; data->point.x = x;
data->point.y = y; data->point.y = y;
if(data->state) {
Serial.print(x);
Serial.print(" - ");
Serial.println(y);
} else {
// Serial.print(".");
}
return false; return false;
} }
@ -116,39 +148,38 @@ static void xpt2046_corr(int16_t * x, int16_t * y)
#if XPT2046_XY_SWAP != 0 #if XPT2046_XY_SWAP != 0
int16_t swap_tmp; int16_t swap_tmp;
swap_tmp = *x; swap_tmp = *x;
*x = *y; *x = *y;
*y = swap_tmp; *y = swap_tmp;
#endif #endif
if((*x) > XPT2046_X_MIN)(*x) -= XPT2046_X_MIN; if((*x) > XPT2046_X_MIN)
else(*x) = 0; (*x) -= XPT2046_X_MIN;
else
(*x) = 0;
if((*y) > XPT2046_Y_MIN)(*y) -= XPT2046_Y_MIN; if((*y) > XPT2046_Y_MIN)
else(*y) = 0; (*y) -= XPT2046_Y_MIN;
else
(*y) = 0;
(*x) = (uint32_t)((uint32_t)(*x) * XPT2046_HOR_RES) / (*x) = (uint32_t)((uint32_t)(*x) * XPT2046_HOR_RES) / (XPT2046_X_MAX - XPT2046_X_MIN);
(XPT2046_X_MAX - XPT2046_X_MIN);
(*y) = (uint32_t)((uint32_t)(*y) * XPT2046_VER_RES) / (*y) = (uint32_t)((uint32_t)(*y) * XPT2046_VER_RES) / (XPT2046_Y_MAX - XPT2046_Y_MIN);
(XPT2046_Y_MAX - XPT2046_Y_MIN);
#if XPT2046_X_INV != 0 #if XPT2046_X_INV != 0
(*x) = XPT2046_HOR_RES - (*x); (*x) = XPT2046_HOR_RES - (*x);
#endif #endif
#if XPT2046_Y_INV != 0 #if XPT2046_Y_INV != 0
(*y) = XPT2046_VER_RES - (*y); (*y) = XPT2046_VER_RES - (*y);
#endif #endif
} }
static void xpt2046_avg(int16_t * x, int16_t * y) static void xpt2046_avg(int16_t * x, int16_t * y)
{ {
/*Shift out the oldest data*/ /*Shift out the oldest data*/
uint8_t i; uint8_t i;
for(i = XPT2046_AVG - 1; i > 0 ; i--) { for(i = XPT2046_AVG - 1; i > 0; i--) {
avg_buf_x[i] = avg_buf_x[i - 1]; avg_buf_x[i] = avg_buf_x[i - 1];
avg_buf_y[i] = avg_buf_y[i - 1]; avg_buf_y[i] = avg_buf_y[i - 1];
} }
@ -161,7 +192,7 @@ static void xpt2046_avg(int16_t * x, int16_t * y)
/*Sum the x and y coordinates*/ /*Sum the x and y coordinates*/
int32_t x_sum = 0; int32_t x_sum = 0;
int32_t y_sum = 0; int32_t y_sum = 0;
for(i = 0; i < avg_last ; i++) { for(i = 0; i < avg_last; i++) {
x_sum += avg_buf_x[i]; x_sum += avg_buf_x[i];
y_sum += avg_buf_y[i]; y_sum += avg_buf_y[i];
} }

View File

@ -40,7 +40,7 @@ extern "C" {
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
void xpt2046_init(void); void xpt2046_init(uint8_t rotation);
bool xpt2046_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); bool xpt2046_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
/********************** /**********************

View File

@ -0,0 +1,75 @@
/**
* @file XPT2046.c
*
*/
/*********************
* INCLUDES
*********************/
#include "XPT2046_alt_drv.h"
#if USE_XPT2046_ALT_DRV
#include <stddef.h>
#include LV_DRV_INDEV_INCLUDE
#include LV_DRV_DELAY_INCLUDE
#include <XPT2046_Touchscreen.h>
/*********************
* DEFINES
*********************/
#define CS_PIN PB12
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
XPT2046_Touchscreen ts(CS_PIN);
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the XPT2046
*/
void xpt2046_alt_drv_init(uint8_t rotation)
{
ts.begin();
ts.setRotation(rotation);
}
/**
* 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_alt_drv_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
data->state = ts.touched();
if(data->state) {
TS_Point p = ts.getPoint();
data->point.x = p.x;
data->point.y = p.y;
Serial.print(p.x);
Serial.print(" - ");
Serial.println(p.y);
}
return false;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif

View File

@ -0,0 +1,56 @@
/**
* @file XPT2046_alt_drv.h
*
*/
#ifndef XPT2046_ALT_DRV_H
#define XPT2046_ALT_DRV_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#ifndef LV_DRV_NO_CONF
#ifdef LV_CONF_INCLUDE_SIMPLE
#include "lv_drv_conf.h"
#else
#include "../../lv_drv_conf.h"
#endif
#endif
#if USE_XPT2046_ALT_DRV
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void xpt2046_alt_drv_init(uint8_t rotation);
bool xpt2046_alt_drv_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
/**********************
* MACROS
**********************/
#endif /* USE_XPT2046_ALT_DRV */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* XPT2046_ALT_DRV_H */