Test FSMC driver

This commit is contained in:
fvanroie 2020-05-18 00:46:47 +02:00
parent 1e957ff864
commit e691d4a959
50 changed files with 6241 additions and 26 deletions

357
include/lv_drv_conf.h Normal file
View File

@ -0,0 +1,357 @@
/**
* @file lv_drv_conf.h
*
*/
#if 1 /*Set it to "1" to enable the content*/
#ifndef LV_DRV_CONF_H
#define LV_DRV_CONF_H
#include "lv_conf.h"
/*********************
* DELAY INTERFACE
*********************/
#define LV_DRV_DELAY_INCLUDE <Arduino.h> /*Dummy include by default*/
#define LV_DRV_DELAY_US(us) delayMicroseconds(ud) /*Delay the given number of microseconds*/
#define LV_DRV_DELAY_MS(ms) delay(ms) /*Delay the given number of milliseconds*/
/*********************
* DISPLAY INTERFACE
*********************/
/*------------
* Common
*------------*/
#define LV_DRV_DISP_INCLUDE <stdint.h> /*Dummy include by default*/
#define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/
#define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/
/*---------
* SPI
*---------*/
#define LV_DRV_DISP_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/
#define LV_DRV_DISP_SPI_WR_BYTE(data) /*spi_wr(data)*/ /*Write a byte the SPI bus*/
#define LV_DRV_DISP_SPI_WR_ARRAY(adr, n) /*spi_wr_mem(adr, n)*/ /*Write 'n' bytes to SPI bus from 'adr'*/
/*------------------
* Parallel port
*-----------------*/
#define LV_DRV_DISP_PAR_CS(val) /*par_cs_set(val)*/ /*Set the Parallel port's Chip select to 'val'*/
#define LV_DRV_DISP_PAR_SLOW /*par_slow()*/ /*Set low speed on the parallel port*/
#define LV_DRV_DISP_PAR_FAST /*par_fast()*/ /*Set high speed on the parallel port*/
#define LV_DRV_DISP_PAR_WR_WORD(data) /*par_wr(data)*/ /*Write a word to the parallel port*/
#define LV_DRV_DISP_PAR_WR_ARRAY(adr, n) /*par_wr_mem(adr,n)*/ /*Write 'n' bytes to Parallel ports from 'adr'*/
/***************************
* INPUT DEVICE INTERFACE
***************************/
/*----------
* Common
*----------*/
#define LV_DRV_INDEV_INCLUDE <stdint.h> /*Dummy include by default*/
#define LV_DRV_INDEV_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/
#define LV_DRV_INDEV_IRQ_READ 0 /*pn_x_read()*/ /*Read the IRQ pin*/
/*---------
* SPI
*---------*/
#define LV_DRV_INDEV_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/
#define LV_DRV_INDEV_SPI_XCHG_BYTE(data) 0 /*spi_xchg(val)*/ /*Write 'val' to SPI and give the read value*/
/*---------
* I2C
*---------*/
#define LV_DRV_INDEV_I2C_START /*i2c_start()*/ /*Make an I2C start*/
#define LV_DRV_INDEV_I2C_STOP /*i2c_stop()*/ /*Make an I2C stop*/
#define LV_DRV_INDEV_I2C_RESTART /*i2c_restart()*/ /*Make an I2C restart*/
#define LV_DRV_INDEV_I2C_WR(data) /*i2c_wr(data)*/ /*Write a byte to the I1C bus*/
#define LV_DRV_INDEV_I2C_READ(last_read) 0 /*i2c_rd()*/ /*Read a byte from the I2C bud*/
/*********************
* DISPLAY DRIVERS
*********************/
#define USE_TFT_ESPI 1
#define USE_FSMC_ILI9341 1
/*-------------------
* Monitor of PC
*-------------------*/
#ifndef USE_MONITOR
#define USE_MONITOR 0
#endif
#if USE_MONITOR
#define MONITOR_HOR_RES LV_HOR_RES
#define MONITOR_VER_RES LV_VER_RES
/* Scale window by this factor (useful when simulating small screens) */
#define MONITOR_ZOOM 1
/* Used to test true double buffering with only address changing.
* Set LV_VDB_SIZE = (LV_HOR_RES * LV_VER_RES) and LV_VDB_DOUBLE = 1 and LV_COLOR_DEPTH = 32" */
#define MONITOR_DOUBLE_BUFFERED 0
/*Eclipse: <SDL2/SDL.h> Visual Studio: <SDL.h>*/
#define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
/*Different rendering might be used if running in a Virtual machine*/
#define MONITOR_VIRTUAL_MACHINE 0
/*Open two windows to test multi display support*/
#define MONITOR_DUAL 0
#endif
/*-----------------------------------
* Native Windows (including mouse)
*----------------------------------*/
#ifndef USE_WINDOWS
#define USE_WINDOWS 0
#endif
#define USE_WINDOWS 0
#if USE_WINDOWS
#define WINDOW_HOR_RES 480
#define WINDOW_VER_RES 320
#endif
/*----------------
* SSD1963
*--------------*/
#ifndef USE_SSD1963
#define USE_SSD1963 0
#endif
#if USE_SSD1963
#define SSD1963_HOR_RES LV_HOR_RES
#define SSD1963_VER_RES LV_VER_RES
#define SSD1963_HT 531
#define SSD1963_HPS 43
#define SSD1963_LPS 8
#define SSD1963_HPW 10
#define SSD1963_VT 288
#define SSD1963_VPS 12
#define SSD1963_FPS 4
#define SSD1963_VPW 10
#define SSD1963_HS_NEG 0 /*Negative hsync*/
#define SSD1963_VS_NEG 0 /*Negative vsync*/
#define SSD1963_ORI 0 /*0, 90, 180, 270*/
#define SSD1963_COLOR_DEPTH 16
#endif
/*----------------
* R61581
*--------------*/
#ifndef USE_R61581
#define USE_R61581 0
#endif
#if USE_R61581
#define R61581_HOR_RES LV_HOR_RES
#define R61581_VER_RES LV_VER_RES
#define R61581_HSPL 0 /*HSYNC signal polarity*/
#define R61581_HSL 10 /*HSYNC length (Not Implemented)*/
#define R61581_HFP 10 /*Horitontal Front poarch (Not Implemented)*/
#define R61581_HBP 10 /*Horitontal Back poarch (Not Implemented */
#define R61581_VSPL 0 /*VSYNC signal polarity*/
#define R61581_VSL 10 /*VSYNC length (Not Implemented)*/
#define R61581_VFP 8 /*Vertical Front poarch*/
#define R61581_VBP 8 /*Vertical Back poarch */
#define R61581_DPL 0 /*DCLK signal polarity*/
#define R61581_EPL 1 /*ENABLE signal polarity*/
#define R61581_ORI 0 /*0, 180*/
#define R61581_LV_COLOR_DEPTH 16 /*Fix 16 bit*/
#endif
/*------------------------------
* ST7565 (Monochrome, low res.)
*-----------------------------*/
#ifndef USE_ST7565
#define USE_ST7565 0
#endif
#if USE_ST7565
/*No settings*/
#endif /*USE_ST7565*/
/*------------------------------------------
* UC1610 (4 gray 160*[104|128])
* (EA DOGXL160 160x104 tested)
*-----------------------------------------*/
#ifndef USE_UC1610
#define USE_UC1610 0
#endif
#if USE_UC1610
#define UC1610_HOR_RES LV_HOR_RES
#define UC1610_VER_RES LV_VER_RES
#define UC1610_INIT_CONTRAST 33 /* init contrast, values in [%] */
#define UC1610_INIT_HARD_RST 0 /* 1 : hardware reset at init, 0 : software reset */
#define UC1610_TOP_VIEW 0 /* 0 : Bottom View, 1 : Top View */
#endif /*USE_UC1610*/
/*-------------------------------------------------
* SHARP memory in pixel monochrome display series
* LS012B7DD01 (184x38 pixels.)
* LS013B7DH03 (128x128 pixels.)
* LS013B7DH05 (144x168 pixels.)
* LS027B7DH01 (400x240 pixels.) (tested)
* LS032B7DD02 (336x536 pixels.)
* LS044Q7DH01 (320x240 pixels.)
*------------------------------------------------*/
#ifndef USE_SHARP_MIP
#define USE_SHARP_MIP 0
#endif
#if USE_SHARP_MIP
#define SHARP_MIP_HOR_RES LV_HOR_RES
#define SHARP_MIP_VER_RES LV_VER_RES
#define SHARP_MIP_SOFT_COM_INVERSION 0
#define SHARP_MIP_REV_BYTE( \
b) /*((uint8_t) __REV(__RBIT(b)))*/ /*Architecture / compiler dependent byte bits order reverse*/
#endif /*USE_SHARP_MIP*/
/*-----------------------------------------
* Linux frame buffer device (/dev/fbx)
*-----------------------------------------*/
#ifndef USE_FBDEV
#define USE_FBDEV 0
#endif
#if USE_FBDEV
#define FBDEV_PATH "/dev/fb0"
#endif
/*-----------------------------------------
* FreeBSD frame buffer device (/dev/fbx)
*.........................................*/
#ifndef USE_BSD_FBDEV
#define USE_BSD_FBDEV 0
#endif
#if USE_BSD_FBDEV
#define FBDEV_PATH "/dev/fb0"
#endif
/*********************
* INPUT DEVICES
*********************/
/*--------------
* XPT2046
*--------------*/
#ifndef USE_XPT2046
#define USE_XPT2046 1
#endif
#if USE_XPT2046
#define XPT2046_HOR_RES 480
#define XPT2046_VER_RES 320
#define XPT2046_X_MIN 200
#define XPT2046_Y_MIN 200
#define XPT2046_X_MAX 3800
#define XPT2046_Y_MAX 3800
#define XPT2046_AVG 4
#define XPT2046_INV 0
#endif
/*-----------------
* FT5406EE8
*-----------------*/
#ifndef USE_FT5406EE8
#define USE_FT5406EE8 0
#endif
#if USE_FT5406EE8
#define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/
#endif
/*---------------
* AD TOUCH
*--------------*/
#ifndef USE_AD_TOUCH
#define USE_AD_TOUCH 0
#endif
#if USE_AD_TOUCH
/*No settings*/
#endif
/*---------------------------------------
* Mouse or touchpad on PC (using SDL)
*-------------------------------------*/
#ifndef USE_MOUSE
#define USE_MOUSE 0
#endif
#if USE_MOUSE
/*No settings*/
#endif
/*-------------------------------------------
* Mousewheel as encoder on PC (using SDL)
*------------------------------------------*/
#ifndef USE_MOUSEWHEEL
#define USE_MOUSEWHEEL 0
#endif
#if USE_MOUSEWHEEL
/*No settings*/
#endif
/*-------------------------------------------------
* Touchscreen as libinput interface (for Linux based systems)
*------------------------------------------------*/
#ifndef USE_LIBINPUT
#define USE_LIBINPUT 0
#endif
#if USE_LIBINPUT
#define LIBINPUT_NAME \
"/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/
#endif /*USE_LIBINPUT*/
/*-------------------------------------------------
* Mouse or touchpad as evdev interface (for Linux based systems)
*------------------------------------------------*/
#ifndef USE_EVDEV
#define USE_EVDEV 0
#endif
#if USE_EVDEV
#define EVDEV_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test \
them*/
#define EVDEV_SWAP_AXES 0 /*Swap the x and y axes of the touchscreen*/
#define EVDEV_SCALE 0 /* Scale input, e.g. if touchscreen resolution does not match display resolution */
#if EVDEV_SCALE
#define EVDEV_SCALE_HOR_RES (4096) /* Horizontal resolution of touchscreen */
#define EVDEV_SCALE_VER_RES (4096) /* Vertical resolution of touchscreen */
#endif /*EVDEV_SCALE*/
#define EVDEV_CALIBRATE \
0 /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/
#if EVDEV_CALIBRATE
#define EVDEV_HOR_MIN 3800 /*If EVDEV_XXX_MIN > EVDEV_XXX_MAX the XXX axis is automatically inverted*/
#define EVDEV_HOR_MAX 200
#define EVDEV_VER_MIN 200
#define EVDEV_VER_MAX 3800
#endif /*EVDEV_SCALE*/
#endif /*USE_EVDEV*/
/*-------------------------------
* Keyboard of a PC (using SDL)
*------------------------------*/
#ifndef USE_KEYBOARD
#define USE_KEYBOARD 0
#endif
#if USE_KEYBOARD
/*No settings*/
#endif
#endif /*LV_DRV_CONF_H*/
#endif /*End of "Content enable"*/

1
lib/lv_drivers/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
**/*.o

21
lib/lv_drivers/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 LittlevGL
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.

7
lib/lv_drivers/README.md Normal file
View File

@ -0,0 +1,7 @@
# Display and Touch pad drivers
Display controller and touchpad driver to can be directly used with [LittlevGL](https://littlevgl.com).
To learn more about using drivers in LittlevGL visit the [Porting guide](https://littlevgl.com/porting).
If you used a new display or touch pad driver with LittlevGL please share it with other people!

View File

@ -0,0 +1,425 @@
/**
* @file R61581.c
*
*/
/*********************
* INCLUDES
*********************/
#include "R61581.h"
#if USE_R61581 != 0
#include <stdbool.h>
#include "lvgl/lv_core/lv_vdb.h"
#include LV_DRV_DISP_INCLUDE
#include LV_DRV_DELAY_INCLUDE
/*********************
* DEFINES
*********************/
#define R61581_CMD_MODE 0
#define R61581_DATA_MODE 1
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void r61581_io_init(void);
static void r61581_reset(void);
static void r61581_set_tft_spec(void);
static inline void r61581_cmd_mode(void);
static inline void r61581_data_mode(void);
static inline void r61581_cmd(uint8_t cmd);
static inline void r61581_data(uint8_t data);
/**********************
* STATIC VARIABLES
**********************/
static bool cmd_mode = true;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the R61581 display controller
* @return HW_RES_OK or any error from hw_res_t enum
*/
void r61581_init(void)
{
r61581_io_init();
/*Slow mode until the PLL is not started in the display controller*/
LV_DRV_DISP_PAR_SLOW;
r61581_reset();
r61581_set_tft_spec();
r61581_cmd(0x13); //SET display on
r61581_cmd(0x29); //SET display on
LV_DRV_DELAY_MS(30);
/*Parallel to max speed*/
LV_DRV_DISP_PAR_FAST;
}
void r61581_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
/*Return if the area is out the screen*/
if(x2 < 0) return;
if(y2 < 0) return;
if(x1 > R61581_HOR_RES - 1) return;
if(y1 > R61581_VER_RES - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = x1 < 0 ? 0 : x1;
int32_t act_y1 = y1 < 0 ? 0 : y1;
int32_t act_x2 = x2 > R61581_HOR_RES - 1 ? R61581_HOR_RES - 1 : x2;
int32_t act_y2 = y2 > R61581_VER_RES - 1 ? R61581_VER_RES - 1 : y2;
//Set the rectangular area
r61581_cmd(0x002A);
r61581_data(act_x1 >> 8);
r61581_data(0x00FF & act_x1);
r61581_data(act_x2 >> 8);
r61581_data(0x00FF & act_x2);
r61581_cmd(0x002B);
r61581_data(act_y1 >> 8);
r61581_data(0x00FF & act_y1);
r61581_data(act_y2 >> 8);
r61581_data(0x00FF & act_y2);
r61581_cmd(0x2c);
int16_t i;
uint16_t full_w = x2 - x1 + 1;
r61581_data_mode();
#if LV_COLOR_DEPTH == 16
uint16_t act_w = act_x2 - act_x1 + 1;
for(i = act_y1; i <= act_y2; i++) {
LV_DRV_DISP_PAR_WR_ARRAY((uint16_t *)color_p, act_w);
color_p += full_w;
}
#else
int16_t j;
for(i = act_y1; i <= act_y2; i++) {
for(j = 0; j <= act_x2 - act_x1 + 1; j++) {
LV_DRV_DISP_PAR_WR_WORD(lv_color_to16(color_p[j]));
color_p += full_w;
}
}
#endif
lv_flush_ready();
}
void r61581_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
{
/*Return if the area is out the screen*/
if(x2 < 0) return;
if(y2 < 0) return;
if(x1 > R61581_HOR_RES - 1) return;
if(y1 > R61581_VER_RES - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = x1 < 0 ? 0 : x1;
int32_t act_y1 = y1 < 0 ? 0 : y1;
int32_t act_x2 = x2 > R61581_HOR_RES - 1 ? R61581_HOR_RES - 1 : x2;
int32_t act_y2 = y2 > R61581_VER_RES - 1 ? R61581_VER_RES - 1 : y2;
//Set the rectangular area
r61581_cmd(0x002A);
r61581_data(act_x1 >> 8);
r61581_data(0x00FF & act_x1);
r61581_data(act_x2 >> 8);
r61581_data(0x00FF & act_x2);
r61581_cmd(0x002B);
r61581_data(act_y1 >> 8);
r61581_data(0x00FF & act_y1);
r61581_data(act_y2 >> 8);
r61581_data(0x00FF & act_y2);
r61581_cmd(0x2c);
r61581_data_mode();
uint16_t color16 = lv_color_to16(color);
uint32_t size = (act_x2 - act_x1 + 1) * (act_y2 - act_y1 + 1);
uint32_t i;
for(i = 0; i < size; i++) {
LV_DRV_DISP_PAR_WR_WORD(color16);
}
}
void r61581_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
/*Return if the area is out the screen*/
if(x2 < 0) return;
if(y2 < 0) return;
if(x1 > R61581_HOR_RES - 1) return;
if(y1 > R61581_VER_RES - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = x1 < 0 ? 0 : x1;
int32_t act_y1 = y1 < 0 ? 0 : y1;
int32_t act_x2 = x2 > R61581_HOR_RES - 1 ? R61581_HOR_RES - 1 : x2;
int32_t act_y2 = y2 > R61581_VER_RES - 1 ? R61581_VER_RES - 1 : y2;
//Set the rectangular area
r61581_cmd(0x002A);
r61581_data(act_x1 >> 8);
r61581_data(0x00FF & act_x1);
r61581_data(act_x2 >> 8);
r61581_data(0x00FF & act_x2);
r61581_cmd(0x002B);
r61581_data(act_y1 >> 8);
r61581_data(0x00FF & act_y1);
r61581_data(act_y2 >> 8);
r61581_data(0x00FF & act_y2);
r61581_cmd(0x2c);
int16_t i;
uint16_t full_w = x2 - x1 + 1;
r61581_data_mode();
#if LV_COLOR_DEPTH == 16
uint16_t act_w = act_x2 - act_x1 + 1;
for(i = act_y1; i <= act_y2; i++) {
LV_DRV_DISP_PAR_WR_ARRAY((uint16_t *)color_p, act_w);
color_p += full_w;
}
#else
int16_t j;
for(i = act_y1; i <= act_y2; i++) {
for(j = 0; j <= act_x2 - act_x1 + 1; j++) {
LV_DRV_DISP_PAR_WR_WORD(lv_color_to16(color_p[j]));
color_p += full_w;
}
}
#endif
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Io init
*/
static void r61581_io_init(void)
{
LV_DRV_DISP_CMD_DATA(R61581_CMD_MODE)
cmd_mode = true;
}
/**
* Reset
*/
static void r61581_reset(void)
{
/*Hardware reset*/
LV_DRV_DISP_RST(1);
LV_DRV_DELAY_MS(50);
LV_DRV_DISP_RST(0);
LV_DRV_DELAY_MS(50);
LV_DRV_DISP_RST(1);
LV_DRV_DELAY_MS(50);
/*Chip enable*/
LV_DRV_DISP_PAR_CS(1);
LV_DRV_DELAY_MS(10);
LV_DRV_DISP_PAR_CS(0);
LV_DRV_DELAY_MS(5);
/*Software reset*/
r61581_cmd(0x01);
LV_DRV_DELAY_MS(20);
r61581_cmd(0x01);
LV_DRV_DELAY_MS(20);
r61581_cmd(0x01);
LV_DRV_DELAY_MS(20);
}
/**
* TFT specific initialization
*/
static void r61581_set_tft_spec(void)
{
r61581_cmd(0xB0);
r61581_data(0x00);
r61581_cmd(0xB3);
r61581_data(0x02);
r61581_data(0x00);
r61581_data(0x00);
r61581_data(0x10);
r61581_cmd(0xB4);
r61581_data(0x00);//0X10
r61581_cmd(0xB9); //PWM
r61581_data(0x01);
r61581_data(0xFF); //FF brightness
r61581_data(0xFF);
r61581_data(0x18);
/*Panel Driving Setting*/
r61581_cmd(0xC0);
r61581_data(0x02);
r61581_data(0x3B);
r61581_data(0x00);
r61581_data(0x00);
r61581_data(0x00);
r61581_data(0x01);
r61581_data(0x00);//NW
r61581_data(0x43);
/*Display Timing Setting for Normal Mode */
r61581_cmd(0xC1);
r61581_data(0x08);
r61581_data(0x15); //CLOCK
r61581_data(R61581_VFP);
r61581_data(R61581_VBP);
/*Source/VCOM/Gate Driving Timing Setting*/
r61581_cmd(0xC4);
r61581_data(0x15);
r61581_data(0x03);
r61581_data(0x03);
r61581_data(0x01);
/*Interface Setting*/
r61581_cmd(0xC6);
r61581_data((R61581_DPL << 0) |
(R61581_EPL << 1) |
(R61581_HSPL << 4) |
(R61581_VSPL << 5));
/*Gamma Set*/
r61581_cmd(0xC8);
r61581_data(0x0c);
r61581_data(0x05);
r61581_data(0x0A);
r61581_data(0x6B);
r61581_data(0x04);
r61581_data(0x06);
r61581_data(0x15);
r61581_data(0x10);
r61581_data(0x00);
r61581_data(0x31);
r61581_cmd(0x36);
if(R61581_ORI == 0) r61581_data(0xE0);
else r61581_data(0x20);
r61581_cmd(0x0C);
r61581_data(0x55);
r61581_cmd(0x3A);
r61581_data(0x55);
r61581_cmd(0x38);
r61581_cmd(0xD0);
r61581_data(0x07);
r61581_data(0x07);
r61581_data(0x14);
r61581_data(0xA2);
r61581_cmd(0xD1);
r61581_data(0x03);
r61581_data(0x5A);
r61581_data(0x10);
r61581_cmd(0xD2);
r61581_data(0x03);
r61581_data(0x04);
r61581_data(0x04);
r61581_cmd(0x11);
LV_DRV_DELAY_MS(10);
r61581_cmd(0x2A);
r61581_data(0x00);
r61581_data(0x00);
r61581_data(((R61581_HOR_RES - 1) >> 8) & 0XFF);
r61581_data((R61581_HOR_RES - 1) & 0XFF);
r61581_cmd(0x2B);
r61581_data(0x00);
r61581_data(0x00);
r61581_data(((R61581_VER_RES - 1) >> 8) & 0XFF);
r61581_data((R61581_VER_RES - 1) & 0XFF);
LV_DRV_DELAY_MS(10);
r61581_cmd(0x29);
LV_DRV_DELAY_MS(5);
r61581_cmd(0x2C);
LV_DRV_DELAY_MS(5);
}
/**
* Command mode
*/
static inline void r61581_cmd_mode(void)
{
if(cmd_mode == false) {
LV_DRV_DISP_CMD_DATA(R61581_CMD_MODE)
cmd_mode = true;
}
}
/**
* Data mode
*/
static inline void r61581_data_mode(void)
{
if(cmd_mode != false) {
LV_DRV_DISP_CMD_DATA(R61581_DATA_MODE);
cmd_mode = false;
}
}
/**
* Write command
* @param cmd the command
*/
static inline void r61581_cmd(uint8_t cmd)
{
r61581_cmd_mode();
LV_DRV_DISP_PAR_WR_WORD(cmd);
}
/**
* Write data
* @param data the data
*/
static inline void r61581_data(uint8_t data)
{
r61581_data_mode();
LV_DRV_DISP_PAR_WR_WORD(data);
}
#endif

View File

@ -0,0 +1,57 @@
/**
* @file R61581.h
*
*/
#ifndef R61581_H
#define R61581_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_R61581
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void r61581_init(void);
void r61581_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
void r61581_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
void r61581_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
/**********************
* MACROS
**********************/
#endif /* USE_R61581 */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* R61581_H */

View File

@ -0,0 +1,182 @@
/**
* @file SHARP_MIP.c
*
*/
/*-------------------------------------------------------------------------------------------------
* SHARP memory in pixel monochrome display series
* LS012B7DD01 (184x38 pixels.)
* LS013B7DH03 (128x128 pixels.)
* LS013B7DH05 (144x168 pixels.)
* LS027B7DH01 (400x240 pixels.) (tested)
* LS032B7DD02 (336x536 pixels.)
* LS044Q7DH01 (320x240 pixels.)
*
* These displays need periodic com inversion, there are two ways :
* - software com inversion :
* define SHARP_MIP_SOFT_COM_INVERSION 1 and set EXTMODE display pin LOW,
* call sharp_mip_com_inversion() periodically
* - hardware com inversion with EXTCOMIN display pin :
* define SHARP_MIP_SOFT_COM_INVERSION 0,
* set EXTMODE display pin HIGH and handle
* EXTCOMIN waveform (for example with mcu pwm output),
* see datasheet pages 8-12 for details
*
* VDB size : (LV_VER_RES / X) * (2 + LV_HOR_RES / 8) + 2 bytes, structure :
* [FRAME_HEADER (1 byte)] [GATE_ADDR (1 byte )] [LINE_DATA (LV_HOR_RES / 8 bytes)] 1st line
* [DUMMY (1 byte)] [GATE_ADDR (1 byte )] [LINE_DATA (LV_HOR_RES / 8 bytes)] 2nd line
* ...........................................................................................
* [DUMMY (1 byte)] [GATE_ADDR (1 byte )] [LINE_DATA (LV_HOR_RES / 8 bytes)] last line
* [DUMMY (2 bytes)]
*
* Since extra bytes (dummy, addresses, header) are stored in VDB, we need to use
* an "oversized" VDB. Buffer declaration in "lv_port_disp.c" becomes for example :
* static lv_disp_buf_t disp_buf;
* static uint8_t buf[(LV_VER_RES_MAX / X) * (2 + (LV_HOR_RES_MAX / 8)) + 2];
* lv_disp_buf_init(&disp_buf, buf, NULL, LV_VER_RES_MAX * LV_HOR_RES_MAX / X);
*-----------------------------------------------------------------------------------------------*/
/*********************
* INCLUDES
*********************/
#include "SHARP_MIP.h"
#if USE_SHARP_MIP
#include <stdbool.h>
#include LV_DRV_DISP_INCLUDE
#include LV_DRV_DELAY_INCLUDE
/*********************
* DEFINES
*********************/
#define SHARP_MIP_HEADER 0
#define SHARP_MIP_UPDATE_RAM_FLAG (1 << 7) /* (M0) Mode flag : H -> update memory, L -> maintain memory */
#define SHARP_MIP_COM_INVERSION_FLAG (1 << 6) /* (M1) Frame inversion flag : relevant when EXTMODE = L, */
/* H -> outputs VCOM = H, L -> outputs VCOM = L */
#define SHARP_MIP_CLEAR_SCREEN_FLAG (1 << 5) /* (M2) All clear flag : H -> clear all pixels */
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
#if SHARP_MIP_SOFT_COM_INVERSION
static bool_t com_output_state = false;
#endif
/**********************
* MACROS
**********************/
/*
* Return the VDB byte index corresponding to the pixel
* relatives coordinates (x, y) in the area.
* The area is rounded to a whole screen line.
*/
#define BUFIDX(x, y) (((x) >> 3) + ((y) * (2 + (SHARP_MIP_HOR_RES >> 3))) + 2)
/*
* Return the byte bitmask of a pixel bit corresponding
* to VDB arrangement (8 pixels per byte on lines).
*/
#define PIXIDX(x) SHARP_MIP_REV_BYTE(1 << ((x) & 7))
/**********************
* GLOBAL FUNCTIONS
**********************/
void sharp_mip_init(void) {
/* These displays have nothing to initialize */
}
void sharp_mip_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {
/*Return if the area is out the screen*/
if(area->y2 < 0) return;
if(area->y1 > SHARP_MIP_VER_RES - 1) return;
/*Truncate the area to the screen*/
uint16_t act_y1 = area->y1 < 0 ? 0 : area->y1;
uint16_t act_y2 = area->y2 > SHARP_MIP_VER_RES - 1 ? SHARP_MIP_VER_RES - 1 : area->y2;
uint8_t * buf = (uint8_t *) color_p; /*Get the buffer address*/
uint16_t buf_h = (act_y2 - act_y1 + 1); /*Number of buffer lines*/
uint16_t buf_size = buf_h * (2 + SHARP_MIP_HOR_RES / 8) + 2; /*Buffer size in bytes */
/* Set lines to flush dummy byte & gate address in VDB*/
for(uint16_t act_y = 0 ; act_y < buf_h ; act_y++) {
buf[BUFIDX(0, act_y) - 1] = SHARP_MIP_REV_BYTE((act_y1 + act_y + 1));
buf[BUFIDX(0, act_y) - 2] = 0;
}
/* Set last dummy two bytes in VDB */
buf[BUFIDX(0, buf_h) - 1] = 0;
buf[BUFIDX(0, buf_h) - 2] = 0;
/* Set frame header in VDB */
buf[0] = SHARP_MIP_HEADER |
SHARP_MIP_UPDATE_RAM_FLAG;
/* Write the frame on display memory */
LV_DRV_DISP_SPI_CS(1);
LV_DRV_DISP_SPI_WR_ARRAY(buf, buf_size);
LV_DRV_DISP_SPI_CS(0);
lv_disp_flush_ready(disp_drv);
}
void sharp_mip_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa) {
(void) disp_drv;
(void) buf_w;
(void) opa;
if (lv_color_to1(color) != 0) {
buf[BUFIDX(x, y)] |= PIXIDX(x); /*Set VDB pixel bit to 1 for other colors than BLACK*/
} else {
buf[BUFIDX(x, y)] &= ~PIXIDX(x); /*Set VDB pixel bit to 0 for BLACK color*/
}
}
void sharp_mip_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area) {
(void) disp_drv;
/* Round area to a whole line */
area->x1 = 0;
area->x2 = SHARP_MIP_HOR_RES - 1;
}
#if SHARP_MIP_SOFT_COM_INVERSION
void sharp_mip_com_inversion(void) {
uint8_t inversion_header[2] = {0};
/* Set inversion header */
if (com_output_state) {
com_output_state = false;
} else {
inversion_header[0] |= SHARP_MIP_COM_INVERSION_FLAG;
com_output_state = true;
}
/* Write inversion header on display memory */
LV_DRV_DISP_SPI_CS(1);
LV_DRV_DISP_SPI_WR_ARRAY(inversion_header, 2);
LV_DRV_DISP_SPI_CS(0);
}
#endif
/**********************
* STATIC FUNCTIONS
**********************/
#endif

View File

@ -0,0 +1,63 @@
/**
* @file SHARP_MIP.h
*
*/
#ifndef SHARP_MIP_H
#define SHARP_MIP_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_SHARP_MIP
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void sharp_mip_init(void);
void sharp_mip_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
void sharp_mip_rounder(lv_disp_drv_t * disp_drv, lv_area_t * area);
void sharp_mip_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
#if SHARP_MIP_SOFT_COM_INVERSION
void sharp_mip_com_inversion(void);
#endif
/**********************
* MACROS
**********************/
#endif /* USE_SHARP_MIP */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SHARP_MIP_H */

View File

@ -0,0 +1,292 @@
/**
* @file SSD1963.c
*
*/
/*********************
* INCLUDES
*********************/
#include "SSD1963.h"
#if USE_SSD1963
#include <stdbool.h>
#include LV_DRV_DISP_INCLUDE
#include LV_DRV_DELAY_INCLUDE
/*********************
* DEFINES
*********************/
#define SSD1963_CMD_MODE 0
#define SSD1963_DATA_MODE 1
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static inline void ssd1963_cmd_mode(void);
static inline void ssd1963_data_mode(void);
static inline void ssd1963_cmd(uint8_t cmd);
static inline void ssd1963_data(uint8_t data);
static void ssd1963_io_init(void);
static void ssd1963_reset(void);
static void ssd1963_set_clk(void);
static void ssd1963_set_tft_spec(void);
static void ssd1963_init_bl(void);
/**********************
* STATIC VARIABLES
**********************/
static bool cmd_mode = true;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void ssd1963_init(void)
{
LV_DRV_DISP_CMD_DATA(SSD1963_CMD_MODE);
cmd_mode = true;
LV_DRV_DELAY_MS(250);
ssd1963_cmd(0x00E2); //PLL multiplier, set PLL clock to 120M
ssd1963_data(0x0023); //N=0x36 for 6.5M, 0x23 for 10M crystal
ssd1963_data(0x0002);
ssd1963_data(0x0004);
ssd1963_cmd(0x00E0); // PLL enable
ssd1963_data(0x0001);
LV_DRV_DELAY_MS(1);
ssd1963_cmd(0x00E0);
ssd1963_data(0x0003); // now, use PLL output as system clock
LV_DRV_DELAY_MS(1);
ssd1963_cmd(0x0001); // software reset
LV_DRV_DELAY_MS(1);
ssd1963_cmd(0x00E6); //PLL setting for PCLK, depends on resolution
ssd1963_data(0x0001); //HX8257C
ssd1963_data(0x0033); //HX8257C
ssd1963_data(0x0033); //HX8257C
ssd1963_cmd(0x00B0); //LCD SPECIFICATION
ssd1963_data(0x0020);
ssd1963_data(0x0000);
ssd1963_data(((SSD1963_HOR_RES - 1) >> 8) & 0X00FF); //Set HDP
ssd1963_data((SSD1963_HOR_RES - 1) & 0X00FF);
ssd1963_data(((SSD1963_VER_RES - 1) >> 8) & 0X00FF); //Set VDP
ssd1963_data((SSD1963_VER_RES - 1) & 0X00FF);
ssd1963_data(0x0000);
LV_DRV_DELAY_MS(1);//Delay10us(5);
ssd1963_cmd(0x00B4); //HSYNC
ssd1963_data((SSD1963_HT >> 8) & 0X00FF); //Set HT
ssd1963_data(SSD1963_HT & 0X00FF);
ssd1963_data((SSD1963_HPS >> 8) & 0X00FF); //Set HPS
ssd1963_data(SSD1963_HPS & 0X00FF);
ssd1963_data(SSD1963_HPW); //Set HPW
ssd1963_data((SSD1963_LPS >> 8) & 0X00FF); //SetLPS
ssd1963_data(SSD1963_LPS & 0X00FF);
ssd1963_data(0x0000);
ssd1963_cmd(0x00B6); //VSYNC
ssd1963_data((SSD1963_VT >> 8) & 0X00FF); //Set VT
ssd1963_data(SSD1963_VT & 0X00FF);
ssd1963_data((SSD1963_VPS >> 8) & 0X00FF); //Set VPS
ssd1963_data(SSD1963_VPS & 0X00FF);
ssd1963_data(SSD1963_VPW); //Set VPW
ssd1963_data((SSD1963_FPS >> 8) & 0X00FF); //Set FPS
ssd1963_data(SSD1963_FPS & 0X00FF);
ssd1963_cmd(0x00B8);
ssd1963_data(0x000f); //GPIO is controlled by host GPIO[3:0]=output GPIO[0]=1 LCD ON GPIO[0]=1 LCD OFF
ssd1963_data(0x0001); //GPIO0 normal
ssd1963_cmd(0x00BA);
ssd1963_data(0x0001); //GPIO[0] out 1 --- LCD display on/off control PIN
ssd1963_cmd(0x0036); //rotation
ssd1963_data(0x0008); //RGB=BGR
ssd1963_cmd(0x003A); //Set the current pixel format for RGB image data
ssd1963_data(0x0050); //16-bit/pixel
ssd1963_cmd(0x00F0); //Pixel Data Interface Format
ssd1963_data(0x0003); //16-bit(565 format) data
ssd1963_cmd(0x00BC);
ssd1963_data(0x0040); //contrast value
ssd1963_data(0x0080); //brightness value
ssd1963_data(0x0040); //saturation value
ssd1963_data(0x0001); //Post Processor Enable
LV_DRV_DELAY_MS(1);
ssd1963_cmd(0x0029); //display on
ssd1963_cmd(0x00BE); //set PWM for B/L
ssd1963_data(0x0006);
ssd1963_data(0x0080);
ssd1963_data(0x0001);
ssd1963_data(0x00f0);
ssd1963_data(0x0000);
ssd1963_data(0x0000);
ssd1963_cmd(0x00d0);
ssd1963_data(0x000d);
//DisplayBacklightOn();
LV_DRV_DELAY_MS(30);
}
void ssd1963_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
/*Return if the area is out the screen*/
if(area->x2 < 0) return;
if(area->y2 < 0) return;
if(area->x1 > SSD1963_HOR_RES - 1) return;
if(area->y1 > SSD1963_VER_RES - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
int32_t act_x2 = area->x2 > SSD1963_HOR_RES - 1 ? SSD1963_HOR_RES - 1 : area->x2;
int32_t act_y2 = area->y2 > SSD1963_VER_RES - 1 ? SSD1963_VER_RES - 1 : area->y2;
//Set the rectangular area
ssd1963_cmd(0x002A);
ssd1963_data(act_x1 >> 8);
ssd1963_data(0x00FF & act_x1);
ssd1963_data(act_x2 >> 8);
ssd1963_data(0x00FF & act_x2);
ssd1963_cmd(0x002B);
ssd1963_data(act_y1 >> 8);
ssd1963_data(0x00FF & act_y1);
ssd1963_data(act_y2 >> 8);
ssd1963_data(0x00FF & act_y2);
ssd1963_cmd(0x2c);
int16_t i;
uint16_t full_w = area->x2 - area->x1 + 1;
ssd1963_data_mode();
LV_DRV_DISP_PAR_CS(0);
#if LV_COLOR_DEPTH == 16
uint16_t act_w = act_x2 - act_x1 + 1;
for(i = act_y1; i <= act_y2; i++) {
LV_DRV_DISP_PAR_WR_ARRAY((uint16_t *)color_p, act_w);
color_p += full_w;
}
LV_DRV_DISP_PAR_CS(1);
#else
int16_t j;
for(i = act_y1; i <= act_y2; i++) {
for(j = 0; j <= act_x2 - act_x1 + 1; j++) {
LV_DRV_DISP_PAR_WR_WORD(color_p[j]);
color_p += full_w;
}
}
#endif
lv_disp_flush_ready(disp_drv);
}
/**********************
* STATIC FUNCTIONS
**********************/
static void ssd1963_io_init(void)
{
LV_DRV_DISP_CMD_DATA(SSD1963_CMD_MODE);
cmd_mode = true;
}
static void ssd1963_reset(void)
{
/*Hardware reset*/
LV_DRV_DISP_RST(1);
LV_DRV_DELAY_MS(50);
LV_DRV_DISP_RST(0);
LV_DRV_DELAY_MS(50);
LV_DRV_DISP_RST(1);
LV_DRV_DELAY_MS(50);
/*Chip enable*/
LV_DRV_DISP_PAR_CS(0);
LV_DRV_DELAY_MS(10);
LV_DRV_DISP_PAR_CS(1);
LV_DRV_DELAY_MS(5);
/*Software reset*/
ssd1963_cmd(0x01);
LV_DRV_DELAY_MS(20);
ssd1963_cmd(0x01);
LV_DRV_DELAY_MS(20);
ssd1963_cmd(0x01);
LV_DRV_DELAY_MS(20);
}
/**
* Command mode
*/
static inline void ssd1963_cmd_mode(void)
{
if(cmd_mode == false) {
LV_DRV_DISP_CMD_DATA(SSD1963_CMD_MODE);
cmd_mode = true;
}
}
/**
* Data mode
*/
static inline void ssd1963_data_mode(void)
{
if(cmd_mode != false) {
LV_DRV_DISP_CMD_DATA(SSD1963_DATA_MODE);
cmd_mode = false;
}
}
/**
* Write command
* @param cmd the command
*/
static inline void ssd1963_cmd(uint8_t cmd)
{
LV_DRV_DISP_PAR_CS(0);
ssd1963_cmd_mode();
LV_DRV_DISP_PAR_WR_WORD(cmd);
LV_DRV_DISP_PAR_CS(1);
}
/**
* Write data
* @param data the data
*/
static inline void ssd1963_data(uint8_t data)
{
LV_DRV_DISP_PAR_CS(0);
ssd1963_data_mode();
LV_DRV_DISP_PAR_WR_WORD(data);
LV_DRV_DISP_PAR_CS(1);
}
#endif

View File

@ -0,0 +1,150 @@
/**
* @file SSD1963.h
*
*/
#ifndef SSD1963_H
#define SSD1963_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_SSD1963
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
// SSD1963 command table
#define CMD_NOP 0x00 //No operation
#define CMD_SOFT_RESET 0x01 //Software reset
#define CMD_GET_PWR_MODE 0x0A //Get the current power mode
#define CMD_GET_ADDR_MODE 0x0B //Get the frame memory to the display panel read order
#define CMD_GET_PIXEL_FORMAT 0x0C //Get the current pixel format
#define CMD_GET_DISPLAY_MODE 0x0D //Returns the display mode
#define CMD_GET_SIGNAL_MODE 0x0E //
#define CMD_GET_DIAGNOSTIC 0x0F
#define CMD_ENT_SLEEP 0x10
#define CMD_EXIT_SLEEP 0x11
#define CMD_ENT_PARTIAL_MODE 0x12
#define CMD_ENT_NORMAL_MODE 0x13
#define CMD_EXIT_INVERT_MODE 0x20
#define CMD_ENT_INVERT_MODE 0x21
#define CMD_SET_GAMMA 0x26
#define CMD_BLANK_DISPLAY 0x28
#define CMD_ON_DISPLAY 0x29
#define CMD_SET_COLUMN 0x2A
#define CMD_SET_PAGE 0x2B
#define CMD_WR_MEMSTART 0x2C
#define CMD_RD_MEMSTART 0x2E
#define CMD_SET_PARTIAL_AREA 0x30
#define CMD_SET_SCROLL_AREA 0x33
#define CMD_SET_TEAR_OFF 0x34 //synchronization information is not sent from the display
#define CMD_SET_TEAR_ON 0x35 //sync. information is sent from the display
#define CMD_SET_ADDR_MODE 0x36 //set fram buffer read order to the display panel
#define CMD_SET_SCROLL_START 0x37
#define CMD_EXIT_IDLE_MODE 0x38
#define CMD_ENT_IDLE_MODE 0x39
#define CMD_SET_PIXEL_FORMAT 0x3A //defines how many bits per pixel is used
#define CMD_WR_MEM_AUTO 0x3C
#define CMD_RD_MEM_AUTO 0x3E
#define CMD_SET_TEAR_SCANLINE 0x44
#define CMD_GET_SCANLINE 0x45
#define CMD_RD_DDB_START 0xA1
#define CMD_RD_DDB_AUTO 0xA8
#define CMD_SET_PANEL_MODE 0xB0
#define CMD_GET_PANEL_MODE 0xB1
#define CMD_SET_HOR_PERIOD 0xB4
#define CMD_GET_HOR_PERIOD 0xB5
#define CMD_SET_VER_PERIOD 0xB6
#define CMD_GET_VER_PERIOD 0xB7
#define CMD_SET_GPIO_CONF 0xB8
#define CMD_GET_GPIO_CONF 0xB9
#define CMD_SET_GPIO_VAL 0xBA
#define CMD_GET_GPIO_STATUS 0xBB
#define CMD_SET_POST_PROC 0xBC
#define CMD_GET_POST_PROC 0xBD
#define CMD_SET_PWM_CONF 0xBE
#define CMD_GET_PWM_CONF 0xBF
#define CMD_SET_LCD_GEN0 0xC0
#define CMD_GET_LCD_GEN0 0xC1
#define CMD_SET_LCD_GEN1 0xC2
#define CMD_GET_LCD_GEN1 0xC3
#define CMD_SET_LCD_GEN2 0xC4
#define CMD_GET_LCD_GEN2 0xC5
#define CMD_SET_LCD_GEN3 0xC6
#define CMD_GET_LCD_GEN3 0xC7
#define CMD_SET_GPIO0_ROP 0xC8
#define CMD_GET_GPIO0_ROP 0xC9
#define CMD_SET_GPIO1_ROP 0xCA
#define CMD_GET_GPIO1_ROP 0xCB
#define CMD_SET_GPIO2_ROP 0xCC
#define CMD_GET_GPIO2_ROP 0xCD
#define CMD_SET_GPIO3_ROP 0xCE
#define CMD_GET_GPIO3_ROP 0xCF
#define CMD_SET_ABC_DBC_CONF 0xD0
#define CMD_GET_ABC_DBC_CONF 0xD1
#define CMD_SET_DBC_HISTO_PTR 0xD2
#define CMD_GET_DBC_HISTO_PTR 0xD3
#define CMD_SET_DBC_THRES 0xD4
#define CMD_GET_DBC_THRES 0xD5
#define CMD_SET_ABM_TMR 0xD6
#define CMD_GET_ABM_TMR 0xD7
#define CMD_SET_AMB_LVL0 0xD8
#define CMD_GET_AMB_LVL0 0xD9
#define CMD_SET_AMB_LVL1 0xDA
#define CMD_GET_AMB_LVL1 0xDB
#define CMD_SET_AMB_LVL2 0xDC
#define CMD_GET_AMB_LVL2 0xDD
#define CMD_SET_AMB_LVL3 0xDE
#define CMD_GET_AMB_LVL3 0xDF
#define CMD_PLL_START 0xE0 //start the PLL
#define CMD_PLL_STOP 0xE1 //disable the PLL
#define CMD_SET_PLL_MN 0xE2
#define CMD_GET_PLL_MN 0xE3
#define CMD_GET_PLL_STATUS 0xE4 //get the current PLL status
#define CMD_ENT_DEEP_SLEEP 0xE5
#define CMD_SET_PCLK 0xE6 //set pixel clock (LSHIFT signal) frequency
#define CMD_GET_PCLK 0xE7 //get pixel clock (LSHIFT signal) freq. settings
#define CMD_SET_DATA_INTERFACE 0xF0
#define CMD_GET_DATA_INTERFACE 0xF1
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void ssd1963_init(void);
void ssd1963_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
/**********************
* MACROS
**********************/
#endif /* USE_SSD1963 */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SSD1963_H */

View File

@ -0,0 +1,289 @@
/**
* @file ST7565.c
*
*/
/*********************
* INCLUDES
*********************/
#include "ST7565.h"
#if USE_ST7565
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include "lvgl/lv_core/lv_vdb.h"
#include LV_DRV_DISP_INCLUDE
#include LV_DRV_DELAY_INCLUDE
/*********************
* DEFINES
*********************/
#define ST7565_BAUD 2000000 /*< 2,5 MHz (400 ns)*/
#define ST7565_CMD_MODE 0
#define ST7565_DATA_MODE 1
#define ST7565_HOR_RES 128
#define ST7565_VER_RES 64
#define CMD_DISPLAY_OFF 0xAE
#define CMD_DISPLAY_ON 0xAF
#define CMD_SET_DISP_START_LINE 0x40
#define CMD_SET_PAGE 0xB0
#define CMD_SET_COLUMN_UPPER 0x10
#define CMD_SET_COLUMN_LOWER 0x00
#define CMD_SET_ADC_NORMAL 0xA0
#define CMD_SET_ADC_REVERSE 0xA1
#define CMD_SET_DISP_NORMAL 0xA6
#define CMD_SET_DISP_REVERSE 0xA7
#define CMD_SET_ALLPTS_NORMAL 0xA4
#define CMD_SET_ALLPTS_ON 0xA5
#define CMD_SET_BIAS_9 0xA2
#define CMD_SET_BIAS_7 0xA3
#define CMD_RMW 0xE0
#define CMD_RMW_CLEAR 0xEE
#define CMD_INTERNAL_RESET 0xE2
#define CMD_SET_COM_NORMAL 0xC0
#define CMD_SET_COM_REVERSE 0xC8
#define CMD_SET_POWER_CONTROL 0x28
#define CMD_SET_RESISTOR_RATIO 0x20
#define CMD_SET_VOLUME_FIRST 0x81
#define CMD_SET_VOLUME_SECOND 0x00
#define CMD_SET_STATIC_OFF 0xAC
#define CMD_SET_STATIC_ON 0xAD
#define CMD_SET_STATIC_REG 0x00
#define CMD_SET_BOOSTER_FIRST 0xF8
#define CMD_SET_BOOSTER_234 0x00
#define CMD_SET_BOOSTER_5 0x01
#define CMD_SET_BOOSTER_6 0x03
#define CMD_NOP 0xE3
#define CMD_TEST 0xF0
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void st7565_sync(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
static void st7565_command(uint8_t cmd);
static void st7565_data(uint8_t data);
/**********************
* STATIC VARIABLES
**********************/
static uint8_t lcd_fb[ST7565_HOR_RES * ST7565_VER_RES / 8] = {0xAA, 0xAA};
static uint8_t pagemap[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the ST7565
*/
void st7565_init(void)
{
LV_DRV_DISP_RST(1);
LV_DRV_DELAY_MS(10);
LV_DRV_DISP_RST(0);
LV_DRV_DELAY_MS(10);
LV_DRV_DISP_RST(1);
LV_DRV_DELAY_MS(10);
LV_DRV_DISP_SPI_CS(0);
st7565_command(CMD_SET_BIAS_7);
st7565_command(CMD_SET_ADC_NORMAL);
st7565_command(CMD_SET_COM_NORMAL);
st7565_command(CMD_SET_DISP_START_LINE);
st7565_command(CMD_SET_POWER_CONTROL | 0x4);
LV_DRV_DELAY_MS(50);
st7565_command(CMD_SET_POWER_CONTROL | 0x6);
LV_DRV_DELAY_MS(50);
st7565_command(CMD_SET_POWER_CONTROL | 0x7);
LV_DRV_DELAY_MS(10);
st7565_command(CMD_SET_RESISTOR_RATIO | 0x6); // Defaulted to 0x26 (but could also be between 0x20-0x27 based on display's specs)
st7565_command(CMD_DISPLAY_ON);
st7565_command(CMD_SET_ALLPTS_NORMAL);
/*Set brightness*/
st7565_command(CMD_SET_VOLUME_FIRST);
st7565_command(CMD_SET_VOLUME_SECOND | (0x18 & 0x3f));
LV_DRV_DISP_SPI_CS(1);
memset(lcd_fb, 0x00, sizeof(lcd_fb));
}
void st7565_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
/*Return if the area is out the screen*/
if(x2 < 0) return;
if(y2 < 0) return;
if(x1 > ST7565_HOR_RES - 1) return;
if(y1 > ST7565_VER_RES - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = x1 < 0 ? 0 : x1;
int32_t act_y1 = y1 < 0 ? 0 : y1;
int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
int32_t x, y;
/*Set the first row in */
/*Refresh frame buffer*/
for(y = act_y1; y <= act_y2; y++) {
for(x = act_x1; x <= act_x2; x++) {
if(lv_color_to1(*color_p) != 0) {
lcd_fb[x + (y / 8)*ST7565_HOR_RES] &= ~(1 << (7 - (y % 8)));
} else {
lcd_fb[x + (y / 8)*ST7565_HOR_RES] |= (1 << (7 - (y % 8)));
}
color_p ++;
}
color_p += x2 - act_x2; /*Next row*/
}
st7565_sync(act_x1, act_y1, act_x2, act_y2);
lv_flush_ready();
}
void st7565_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
{
/*Return if the area is out the screen*/
if(x2 < 0) return;
if(y2 < 0) return;
if(x1 > ST7565_HOR_RES - 1) return;
if(y1 > ST7565_VER_RES - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = x1 < 0 ? 0 : x1;
int32_t act_y1 = y1 < 0 ? 0 : y1;
int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
int32_t x, y;
uint8_t white = lv_color_to1(color);
/*Refresh frame buffer*/
for(y = act_y1; y <= act_y2; y++) {
for(x = act_x1; x <= act_x2; x++) {
if(white != 0) {
lcd_fb[x + (y / 8)*ST7565_HOR_RES] |= (1 << (7 - (y % 8)));
} else {
lcd_fb[x + (y / 8)*ST7565_HOR_RES] &= ~(1 << (7 - (y % 8)));
}
}
}
st7565_sync(act_x1, act_y1, act_x2, act_y2);
}
void st7565_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
/*Return if the area is out the screen*/
if(x2 < 0) return;
if(y2 < 0) return;
if(x1 > ST7565_HOR_RES - 1) return;
if(y1 > ST7565_VER_RES - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = x1 < 0 ? 0 : x1;
int32_t act_y1 = y1 < 0 ? 0 : y1;
int32_t act_x2 = x2 > ST7565_HOR_RES - 1 ? ST7565_HOR_RES - 1 : x2;
int32_t act_y2 = y2 > ST7565_VER_RES - 1 ? ST7565_VER_RES - 1 : y2;
int32_t x, y;
/*Set the first row in */
/*Refresh frame buffer*/
for(y = act_y1; y <= act_y2; y++) {
for(x = act_x1; x <= act_x2; x++) {
if(lv_color_to1(*color_p) != 0) {
lcd_fb[x + (y / 8)*ST7565_HOR_RES] &= ~(1 << (7 - (y % 8)));
} else {
lcd_fb[x + (y / 8)*ST7565_HOR_RES] |= (1 << (7 - (y % 8)));
}
color_p ++;
}
color_p += x2 - act_x2; /*Next row*/
}
st7565_sync(act_x1, act_y1, act_x2, act_y2);
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Flush a specific part of the buffer to the display
* @param x1 left coordinate of the area to flush
* @param y1 top coordinate of the area to flush
* @param x2 right coordinate of the area to flush
* @param y2 bottom coordinate of the area to flush
*/
static void st7565_sync(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
{
LV_DRV_DISP_SPI_CS(0);
uint8_t c, p;
for(p = y1 / 8; p <= y2 / 8; p++) {
st7565_command(CMD_SET_PAGE | pagemap[p]);
st7565_command(CMD_SET_COLUMN_LOWER | (x1 & 0xf));
st7565_command(CMD_SET_COLUMN_UPPER | ((x1 >> 4) & 0xf));
st7565_command(CMD_RMW);
for(c = x1; c <= x2; c++) {
st7565_data(lcd_fb[(ST7565_HOR_RES * p) + c]);
}
}
LV_DRV_DISP_SPI_CS(1);
}
/**
* Write a command to the ST7565
* @param cmd the command
*/
static void st7565_command(uint8_t cmd)
{
LV_DRV_DISP_CMD_DATA(ST7565_CMD_MODE);
LV_DRV_DISP_SPI_WR_BYTE(cmd);
}
/**
* Write data to the ST7565
* @param data the data
*/
static void st7565_data(uint8_t data)
{
LV_DRV_DISP_CMD_DATA(ST7565_DATA_MODE);
LV_DRV_DISP_SPI_WR_BYTE(data);
}
#endif

View File

@ -0,0 +1,58 @@
/**
* @file ST7565.h
*
*/
#ifndef ST7565_H
#define ST7565_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_ST7565
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void st7565_init(void);
void st7565_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
void st7565_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
void st7565_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
/**********************
* MACROS
**********************/
#endif /* USE_ST7565 */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* ST7565_H */

View File

@ -0,0 +1,206 @@
/**
* @file UC1610.c
*
*/
/*********************
* INCLUDES
*********************/
#include "UC1610.h"
#if USE_UC1610
#include <stdbool.h>
#include LV_DRV_DISP_INCLUDE
#include LV_DRV_DELAY_INCLUDE
/*********************
* DEFINES
*********************/
#define UC1610_CMD_MODE 0
#define UC1610_DATA_MODE 1
#define UC1610_RESET_MODE 0
#define UC1610_SET_MODE 1
/* hardware control commands */
#define UC1610_SYSTEM_RESET 0xE2 /* software reset */
#define UC1610_NOP 0xE3
#define UC1610_SET_TEMP_COMP 0x24 /* set temperature compensation, default -0.05%/°C */
#define UC1610_SET_PANEL_LOADING 0x29 /* set panel loading, default 16~21 nF */
#define UC1610_SET_PUMP_CONTROL 0x2F /* default internal Vlcd (8x pump) */
#define UC1610_SET_LCD_BIAS_RATIO 0xEB /* default 11 */
#define UC1610_SET_VBIAS_POT 0x81 /* 1 byte (0~255) to follow setting the contrast, default 0x81 */
#define UC1610_SET_LINE_RATE 0xA0 /* default 12,1 Klps */
#define UC1610_SET_DISPLAY_ENABLE 0xAE /* + 1 / 0 : exit sleep mode / entering sleep mode */
#define UC1610_SET_LCD_GRAY_SHADE 0xD0 /* default 24% between the two gray shade levels */
#define UC1610_SET_COM_END 0xF1 /* set the number of used com electrodes (lines number -1) */
/* ram address control */
#define UC1610_SET_AC 0x88 /* set ram address control */
#define UC1610_AC_WA_FLAG 1 /* automatic column/page increment wrap around (1 : cycle increment) */
#define UC1610_AC_AIO_FLAG (1 << 1) /* auto increment order (0/1 : column/page increment first) */
#define UC1610_AC_PID_FLAG (1 << 2) /* page address auto increment order (0/1 : +1/-1) */
/* set cursor ram address */
#define UC1610_SET_CA_LSB 0x00 /* + 4 LSB bits */
#define UC1610_SET_CA_MSB 0x10 /* + 4 MSB bits // MSB + LSB values range : 0~159 */
#define UC1610_SET_PA 0x60 /* + 5 bits // values range : 0~26 */
/* display control commands */
#define UC1610_SET_FIXED_LINES 0x90 /* + 4 bits = 2xFL */
#define UC1610_SET_SCROLL_LINES_LSB 0x40 /* + 4 LSB bits scroll up display by N (7 bits) lines */
#define UC1610_SET_SCROLL_LINES_MSB 0x50 /* + 3 MSB bits */
#define UC1610_SET_ALL_PIXEL_ON 0xA4 /* + 1 / 0 : set all pixel on, reverse */
#define UC1610_SET_INVERSE_DISPLAY 0xA6 /* + 1 / 0 : inverse all data stored in ram, reverse */
#define UC1610_SET_MAPPING_CONTROL 0xC0 /* control mirorring */
#define UC1610_SET_MAPPING_CONTROL_LC_FLAG 1
#define UC1610_SET_MAPPING_CONTROL_MX_FLAG (1 << 1)
#define UC1610_SET_MAPPING_CONTROL_MY_FLAG (1 << 2)
/* window program mode */
#define UC1610_SET_WINDOW_PROGRAM_ENABLE 0xF8 /* + 1 / 0 : enable / disable window programming mode, */
/* reset before changing boundaries */
#define UC1610_SET_WP_STARTING_CA 0xF4 /* 1 byte to follow for column address */
#define UC1610_SET_WP_ENDING_CA 0xF6 /* 1 byte to follow for column address */
#define UC1610_SET_WP_STARTING_PA 0xF5 /* 1 byte to follow for page address */
#define UC1610_SET_WP_ENDING_PA 0xF7 /* 1 byte to follow for page address */
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static uint8_t cmd_buf[12];
/**********************
* MACROS
**********************/
/* Return the byte bitmask of a pixel color corresponding to VDB arrangement */
#define PIXIDX(y, c) ((c) << (((y) & 3) << 1))
/**********************
* GLOBAL FUNCTIONS
**********************/
void uc1610_init(void) {
LV_DRV_DELAY_MS(12);
/* initialization sequence */
#if UC1610_INIT_HARD_RST
LV_DRV_DISP_RST(UC1610_RESET_MODE); /* hardware reset */
LV_DRV_DELAY_MS(1);
LV_DRV_DISP_RST(UC1610_SET_MODE);
#else
cmd_buf[0] = UC1610_SYSTEM_RESET; /* software reset */
LV_DRV_DISP_CMD_DATA(UC1610_CMD_MODE);
LV_DRV_DISP_SPI_CS(0);
LV_DRV_DISP_SPI_WR_ARRAY(cmd_buf, 1);
LV_DRV_DISP_SPI_CS(1);
#endif
LV_DRV_DELAY_MS(2);
cmd_buf[0] = UC1610_SET_COM_END; /* set com end value */
cmd_buf[1] = UC1610_VER_RES - 1;
cmd_buf[2] = UC1610_SET_PANEL_LOADING;
cmd_buf[3] = UC1610_SET_LCD_BIAS_RATIO;
cmd_buf[4] = UC1610_SET_VBIAS_POT; /* set contrast */
cmd_buf[5] = (UC1610_INIT_CONTRAST * 255) / 100;
#if UC1610_TOP_VIEW
cmd_buf[6] = UC1610_SET_MAPPING_CONTROL | /* top view */
UC1610_SET_MAPPING_CONTROL_MY_FLAG |
UC1610_SET_MAPPING_CONTROL_MX_FLAG;
#else
cmd_buf[6] = UC1610_SET_MAPPING_CONTROL; /* bottom view */
#endif
cmd_buf[7] = UC1610_SET_SCROLL_LINES_LSB | 0; /* set scroll line on line 0 */
cmd_buf[8] = UC1610_SET_SCROLL_LINES_MSB | 0;
cmd_buf[9] = UC1610_SET_AC | UC1610_AC_WA_FLAG; /* set auto increment wrap around */
cmd_buf[10] = UC1610_SET_INVERSE_DISPLAY | 1; /* invert colors to complies lv color system */
cmd_buf[11] = UC1610_SET_DISPLAY_ENABLE | 1; /* turn display on */
LV_DRV_DISP_CMD_DATA(UC1610_CMD_MODE);
LV_DRV_DISP_SPI_CS(0);
LV_DRV_DISP_SPI_WR_ARRAY(cmd_buf, 12);
LV_DRV_DISP_SPI_CS(1);
}
void uc1610_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {
/*Return if the area is out the screen*/
if(area->x2 < 0) return;
if(area->y2 < 0) return;
if(area->x1 > UC1610_HOR_RES - 1) return;
if(area->y1 > UC1610_VER_RES - 1) return;
/*Truncate the area to the screen*/
uint8_t act_x1 = area->x1 < 0 ? 0 : area->x1;
uint8_t act_y1 = area->y1 < 0 ? 0 : area->y1;
uint8_t act_x2 = area->x2 > UC1610_HOR_RES - 1 ? UC1610_HOR_RES - 1 : area->x2;
uint8_t act_y2 = area->y2 > UC1610_VER_RES - 1 ? UC1610_VER_RES - 1 : area->y2;
uint8_t * buf = (uint8_t *) color_p;
uint16_t buf_size = (act_x2 - act_x1 + 1) * (((act_y2 - act_y1) >> 2) + 1);
/*Set display window to fill*/
cmd_buf[0] = UC1610_SET_WINDOW_PROGRAM_ENABLE | 0; /* before changing boundaries */
cmd_buf[1] = UC1610_SET_WP_STARTING_CA;
cmd_buf[2] = act_x1;
cmd_buf[3] = UC1610_SET_WP_ENDING_CA;
cmd_buf[4] = act_x2;
cmd_buf[5] = UC1610_SET_WP_STARTING_PA;
cmd_buf[6] = act_y1 >> 2;
cmd_buf[7] = UC1610_SET_WP_ENDING_PA;
cmd_buf[8] = act_y2 >> 2;
cmd_buf[9] = UC1610_SET_WINDOW_PROGRAM_ENABLE | 1; /* entering window programming */
LV_DRV_DISP_CMD_DATA(UC1610_CMD_MODE);
LV_DRV_DISP_SPI_CS(0);
LV_DRV_DISP_SPI_WR_ARRAY(cmd_buf, 10);
LV_DRV_DISP_SPI_CS(1);
/*Flush VDB on display memory*/
LV_DRV_DISP_CMD_DATA(UC1610_DATA_MODE);
LV_DRV_DISP_SPI_CS(0);
LV_DRV_DISP_SPI_WR_ARRAY(buf, buf_size);
LV_DRV_DISP_SPI_CS(1);
lv_disp_flush_ready(disp_drv);
}
void uc1610_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa) {
(void) disp_drv;
(void) opa;
uint16_t idx = x + buf_w * (y >> 2);
/* Convert color to depth 2 */
#if LV_COLOR_DEPTH == 1
uint8_t color2 = color.full * 3;
#else
uint8_t color2 = color.full >> (LV_COLOR_DEPTH - 2);
#endif
buf[idx] &= ~PIXIDX(y, 3); /* reset pixel color */
buf[idx] |= PIXIDX(y, color2); /* write new color */
}
void uc1610_rounder_cb(lv_disp_drv_t * disp_drv, lv_area_t * area) {
(void) disp_drv;
/* Round y window to display memory page size */
area->y1 = (area->y1 & (~3));
area->y2 = (area->y2 & (~3)) + 3;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif

View File

@ -0,0 +1,58 @@
/**
* @file UC1610.h
*
*/
#ifndef UC1610_H
#define UC1610_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_UC1610
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void uc1610_init(void);
void uc1610_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
void uc1610_rounder_cb(lv_disp_drv_t * disp_drv, lv_area_t * area);
void uc1610_set_px_cb(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
/**********************
* MACROS
**********************/
#endif /* USE_UC1610 */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UC1610_H */

View File

@ -0,0 +1,12 @@
CSRCS += fbdev.c
CSRCS += monitor.c
CSRCS += R61581.c
CSRCS += SSD1963.c
CSRCS += ST7565.c
CSRCS += UC1610.c
CSRCS += SHARP_MIP.c
DEPPATH += --dep-path $(LVGL_DIR)/lv_drivers/display
VPATH += :$(LVGL_DIR)/lv_drivers/display
CFLAGS += "-I$(LVGL_DIR)/lv_drivers/display"

View File

@ -0,0 +1,241 @@
/**
* @file fbdev.c
*
*/
/*********************
* INCLUDES
*********************/
#include "fbdev.h"
#if USE_FBDEV || USE_BSD_FBDEV
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#if USE_BSD_FBDEV
#include <sys/fcntl.h>
#include <sys/time.h>
#include <sys/consio.h>
#include <sys/fbio.h>
#else /* USE_BSD_FBDEV */
#include <linux/fb.h>
#endif /* USE_BSD_FBDEV */
/*********************
* DEFINES
*********************/
#ifndef FBDEV_PATH
#define FBDEV_PATH "/dev/fb0"
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* STRUCTURES
**********************/
struct bsd_fb_var_info{
uint32_t xoffset;
uint32_t yoffset;
uint32_t xres;
uint32_t yres;
int bits_per_pixel;
};
struct bsd_fb_fix_info{
long int line_length;
};
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
#if USE_BSD_FBDEV
static struct bsd_fb_var_info vinfo;
static struct bsd_fb_fix_info finfo;
#else
static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
#endif /* USE_BSD_FBDEV */
static char *fbp = 0;
static long int screensize = 0;
static int fbfd = 0;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void fbdev_init(void)
{
// Open the file for reading and writing
fbfd = open(FBDEV_PATH, O_RDWR);
if(fbfd == -1) {
perror("Error: cannot open framebuffer device");
return;
}
printf("The framebuffer device was opened successfully.\n");
#if USE_BSD_FBDEV
struct fbtype fb;
unsigned line_length;
//Get fb type
if (ioctl(fbfd, FBIOGTYPE, &fb) != 0) {
perror("ioctl(FBIOGTYPE)");
return;
}
//Get screen width
if (ioctl(fbfd, FBIO_GETLINEWIDTH, &line_length) != 0) {
perror("ioctl(FBIO_GETLINEWIDTH)");
return;
}
vinfo.xres = (unsigned) fb.fb_width;
vinfo.yres = (unsigned) fb.fb_height;
vinfo.bits_per_pixel = fb.fb_depth + 8;
vinfo.xoffset = 0;
vinfo.yoffset = 0;
finfo.line_length = line_length;
#else /* USE_BSD_FBDEV */
// Get fixed screen information
if(ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
perror("Error reading fixed information");
return;
}
// Get variable screen information
if(ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
perror("Error reading variable information");
return;
}
#endif /* USE_BSD_FBDEV */
printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
// Figure out the size of the screen in bytes
screensize = finfo.smem_len; //finfo.line_length * vinfo.yres;
// Map the device to memory
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
if((intptr_t)fbp == -1) {
perror("Error: failed to map framebuffer device to memory");
return;
}
memset(fbp, 0, screensize);
printf("The framebuffer device was mapped to memory successfully.\n");
}
void fbdev_exit(void)
{
close(fbfd);
}
/**
* Flush a buffer to the marked area
* @param drv pointer to driver where this function belongs
* @param area an area where to copy `color_p`
* @param color_p an array of pixel to copy to the `area` part of the screen
*/
void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
{
if(fbp == NULL ||
area->x2 < 0 ||
area->y2 < 0 ||
area->x1 > (int32_t)vinfo.xres - 1 ||
area->y1 > (int32_t)vinfo.yres - 1) {
lv_disp_flush_ready(drv);
return;
}
/*Truncate the area to the screen*/
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
int32_t act_x2 = area->x2 > (int32_t)vinfo.xres - 1 ? (int32_t)vinfo.xres - 1 : area->x2;
int32_t act_y2 = area->y2 > (int32_t)vinfo.yres - 1 ? (int32_t)vinfo.yres - 1 : area->y2;
lv_coord_t w = lv_area_get_width(area);
long int location = 0;
long int byte_location = 0;
unsigned char bit_location = 0;
/*32 or 24 bit per pixel*/
if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
uint32_t * fbp32 = (uint32_t *)fbp;
int32_t y;
for(y = act_y1; y <= act_y2; y++) {
location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 4;
memcpy(&fbp32[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 4);
color_p += w;
}
}
/*16 bit per pixel*/
else if(vinfo.bits_per_pixel == 16) {
uint16_t * fbp16 = (uint16_t *)fbp;
int32_t y;
for(y = act_y1; y <= act_y2; y++) {
location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 2;
memcpy(&fbp16[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 2);
color_p += w;
}
}
/*8 bit per pixel*/
else if(vinfo.bits_per_pixel == 8) {
uint8_t * fbp8 = (uint8_t *)fbp;
int32_t y;
for(y = act_y1; y <= act_y2; y++) {
location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length;
memcpy(&fbp8[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1));
color_p += w;
}
}
/*1 bit per pixel*/
else if(vinfo.bits_per_pixel == 1) {
uint8_t * fbp8 = (uint8_t *)fbp;
int32_t x;
int32_t y;
for(y = act_y1; y <= act_y2; y++) {
for(x = act_x1; x <= act_x2; x++) {
location = (x + vinfo.xoffset) + (y + vinfo.yoffset) * vinfo.xres;
byte_location = location / 8; /* find the byte we need to change */
bit_location = location % 8; /* inside the byte found, find the bit we need to change */
fbp8[byte_location] &= ~(((uint8_t)(1)) << bit_location);
fbp8[byte_location] |= ((uint8_t)(color_p->full)) << bit_location;
color_p++;
}
color_p += area->x2 - act_x2;
}
} else {
/*Not supported bit per pixel*/
}
//May be some direct update command is required
//ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));
lv_disp_flush_ready(drv);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif

View File

@ -0,0 +1,58 @@
/**
* @file fbdev.h
*
*/
#ifndef FBDEV_H
#define FBDEV_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_FBDEV || USE_BSD_FBDEV
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void fbdev_init(void);
void fbdev_exit(void);
void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p);
/**********************
* MACROS
**********************/
#endif /*USE_FBDEV*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*FBDEV_H*/

View File

@ -0,0 +1,109 @@
/**
* @file fsmc_ili9341.cpp
*
*/
/*********************
* INCLUDES
*********************/
#include "fsmc_ili9341.h"
#if USE_FSMC_ILI9341 != 0
#include <stdbool.h>
#include <Arduino.h>
#include <SPI.h>
//#include <XPT2046_Touchscreen.h>
#include <Wire.h>
#include "GxTFT_GFX.h" // Hardware-specific library
#include "GxTFT.h" // Hardware-specific library
#define TFT_Class GxTFT
#include "GxIO/GxIO.h"
// select one GxIO class,
// 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".
// Specific Board "BLACK F407ZG (M4 DEMO)"
// I use it with ST-LINK-V2, Upload method "STLink[Automatic serial = SerialUSB]", USB disabled.
// For Serial I use a Serial to USB converter on PA9, PA10, "SerialUART1".
// https://github.com/danieleff/STM32GENERIC
#include "GxIO/STM32DUINO/GxIO_STM32F4_FSMC/GxIO_STM32F4_FSMC.h"
#include "myTFTs/my_3.2_TFT_320x240_ILI9341_STM32F407ZGM4_FSMC.h"
#include LV_DRV_DISP_INCLUDE
#include LV_DRV_DELAY_INCLUDE
// For 3.2" TFT of bundle 1 of:
// https://www.aliexpress.com/item/STM32F407ZGT6-Development-Board-ARM-M4-STM32F4-cortex-M4-core-Board-Compatibility-Multiple-Extension/32795142050.html
// select one GxCTRL class
#include <GxCTRL/GxCTRL_ILI9341/GxCTRL_ILI9341.h> // 240x320
#include "GxReadRegisters.h"
/*********************
* DEFINES
*********************/
#if !defined(ESP8266)
#define yield()
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the R61581 display controller
* @return HW_RES_OK or any error from hw_res_t enum
*/
void fsmc_ili9341_init(uint8_t rotation)
{
tft.init();
tft.setRotation(rotation);
}
void fsmc_ili9341_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
size_t len = (x2 - x1 + 1) * (y2 - y1 + 1); /* Number of pixels */
/* Update TFT */
// tft.startWrite(); /* Start new TFT transaction */
tft.setWindow(x1, y1, x2, y2); /* set the working window */
tft.pushColors((uint16_t *)color_p, len); /* Write words at once */
// tft.endWrite(); /* terminate TFT transaction */
/* Tell lvgl that flushing is done */
// lv_disp_flush_ready();
}
void fsmc_ili9341_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
{
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)
{
fsmc_ili9341_flush(x1, y1, x2, y2, color_p);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif

View File

@ -0,0 +1,67 @@
/**
* @file fsmc_ili9341.h
*
*/
#ifndef TFT_FSMC_ILI9341_DRV_H
#define TFT_FSMC_ILI9341_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_FSMC_ILI9341
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* 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
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
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_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);
/**********************
* MACROS
**********************/
#endif /* USE_FSMC_ILI9341 */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* TFT_FSMC_ILI9341_DRV_H */

View File

@ -0,0 +1,415 @@
/**
* @file monitor.c
*
*/
/*********************
* INCLUDES
*********************/
#include "monitor.h"
#if USE_MONITOR
#ifndef MONITOR_SDL_INCLUDE_PATH
# define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
#endif
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include MONITOR_SDL_INCLUDE_PATH
#include "../indev/mouse.h"
#include "../indev/keyboard.h"
#include "../indev/mousewheel.h"
/*********************
* DEFINES
*********************/
#define SDL_REFR_PERIOD 50 /*ms*/
#ifndef MONITOR_ZOOM
#define MONITOR_ZOOM 1
#endif
#ifndef MONITOR_HOR_RES
#define MONITOR_HOR_RES LV_HOR_RES
#endif
#ifndef MONITOR_VER_RES
#define MONITOR_VER_RES LV_VER_RES
#endif
#if defined(__APPLE__) && defined(TARGET_OS_MAC)
# if __APPLE__ && TARGET_OS_MAC
#define MONITOR_APPLE
# endif
#endif
#if defined(__EMSCRIPTEN__)
# define MONITOR_EMSCRIPTEN
#endif
/**********************
* TYPEDEFS
**********************/
typedef struct {
SDL_Window * window;
SDL_Renderer * renderer;
SDL_Texture * texture;
volatile bool sdl_refr_qry;
#if MONITOR_DOUBLE_BUFFERED
uint32_t * tft_fb_act;
#else
uint32_t tft_fb[LV_HOR_RES_MAX * LV_VER_RES_MAX];
#endif
}monitor_t;
/**********************
* STATIC PROTOTYPES
**********************/
static int monitor_sdl_refr_thread(void * param);
static void window_create(monitor_t * m);
static void window_update(monitor_t * m);
/***********************
* GLOBAL PROTOTYPES
***********************/
/**********************
* STATIC VARIABLES
**********************/
monitor_t monitor;
#if MONITOR_DUAL
monitor_t monitor2;
#endif
static volatile bool sdl_inited = false;
static volatile bool sdl_quit_qry = false;
int quit_filter(void * userdata, SDL_Event * event);
static void monitor_sdl_clean_up(void);
static void monitor_sdl_init(void);
#ifdef MONITOR_EMSCRIPTEN
void monitor_sdl_refr_core(void); /* called from Emscripten loop */
#else
static void monitor_sdl_refr_core(void);
#endif
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the monitor
*/
void monitor_init(void)
{
/*OSX needs to initialize SDL here*/
#if defined(MONITOR_APPLE) || defined(MONITOR_EMSCRIPTEN)
monitor_sdl_init();
#endif
#ifndef MONITOR_EMSCRIPTEN
SDL_CreateThread(monitor_sdl_refr_thread, "sdl_refr", NULL);
while(sdl_inited == false); /*Wait until 'sdl_refr' initializes the SDL*/
#endif
}
/**
* Flush a buffer to the marked area
* @param drv pointer to driver where this function belongs
* @param area an area where to copy `color_p`
* @param color_p an array of pixel to copy to the `area` part of the screen
*/
void monitor_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
lv_coord_t hres = disp_drv->rotated == 0 ? disp_drv->hor_res : disp_drv->ver_res;
lv_coord_t vres = disp_drv->rotated == 0 ? disp_drv->ver_res : disp_drv->hor_res;
// printf("x1:%d,y1:%d,x2:%d,y2:%d\n", area->x1, area->y1, area->x2, area->y2);
/*Return if the area is out the screen*/
if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) {
lv_disp_flush_ready(disp_drv);
return;
}
#if MONITOR_DOUBLE_BUFFERED
monitor.tft_fb_act = (uint32_t *)color_p;
monitor.sdl_refr_qry = true;
/*IMPORTANT! It must be called to tell the system the flush is ready*/
lv_disp_flush_ready(disp_drv);
#else
int32_t y;
#if LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32 /*32 is valid but support 24 for backward compatibility too*/
int32_t x;
for(y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++) {
for(x = area->x1; x <= area->x2; x++) {
monitor.tft_fb[y * disp_drv->hor_res + x] = lv_color_to32(*color_p);
color_p++;
}
}
#else
uint32_t w = lv_area_get_width(area);
for(y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++) {
memcpy(&monitor.tft_fb[y * MONITOR_HOR_RES + area->x1], color_p, w * sizeof(lv_color_t));
color_p += w;
}
#endif
monitor.sdl_refr_qry = true;
/*IMPORTANT! It must be called to tell the system the flush is ready*/
lv_disp_flush_ready(disp_drv);
#endif
}
#if MONITOR_DUAL
/**
* Flush a buffer to the marked area
* @param drv pointer to driver where this function belongs
* @param area an area where to copy `color_p`
* @param color_p an array of pixel to copy to the `area` part of the screen
*/
void monitor_flush2(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
lv_coord_t hres = disp_drv->rotated == 0 ? disp_drv->hor_res : disp_drv->ver_res;
lv_coord_t vres = disp_drv->rotated == 0 ? disp_drv->ver_res : disp_drv->hor_res;
/*Return if the area is out the screen*/
if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) {
lv_disp_flush_ready(disp_drv);
return;
}
#if MONITOR_DOUBLE_BUFFERED
monitor2.tft_fb_act = (uint32_t *)color_p;
monitor2.sdl_refr_qry = true;
/*IMPORTANT! It must be called to tell the system the flush is ready*/
lv_disp_flush_ready(disp_drv);
#else
int32_t y;
#if LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32 /*32 is valid but support 24 for backward compatibility too*/
int32_t x;
for(y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++) {
for(x = area->x1; x <= area->x2; x++) {
monitor2.tft_fb[y * disp_drv->hor_res + x] = lv_color_to32(*color_p);
color_p++;
}
}
#else
uint32_t w = lv_area_get_width(area);
for(y = area->y1; y <= area->y2 && y < disp_drv->ver_res; y++) {
memcpy(&monitor2.tft_fb[y * disp_drv->hor_res + area->x1], color_p, w * sizeof(lv_color_t));
color_p += w;
}
#endif
monitor2.sdl_refr_qry = true;
/*IMPORTANT! It must be called to tell the system the flush is ready*/
lv_disp_flush_ready(disp_drv);
#endif
}
#endif
/**********************
* STATIC FUNCTIONS
**********************/
/**
* SDL main thread. All SDL related task have to be handled here!
* It initializes SDL, handles drawing and the mouse.
*/
static int monitor_sdl_refr_thread(void * param)
{
(void)param;
/*If not OSX initialize SDL in the Thread*/
#ifndef MONITOR_APPLE
monitor_sdl_init();
#endif
/*Run until quit event not arrives*/
while(sdl_quit_qry == false) {
/*Refresh handling*/
monitor_sdl_refr_core();
}
monitor_sdl_clean_up();
exit(0);
return 0;
}
int quit_filter(void * userdata, SDL_Event * event)
{
(void)userdata;
if(event->type == SDL_WINDOWEVENT) {
if(event->window.event == SDL_WINDOWEVENT_CLOSE) {
sdl_quit_qry = true;
}
}
else if(event->type == SDL_QUIT) {
sdl_quit_qry = true;
}
return 1;
}
static void monitor_sdl_clean_up(void)
{
SDL_DestroyTexture(monitor.texture);
SDL_DestroyRenderer(monitor.renderer);
SDL_DestroyWindow(monitor.window);
#if MONITOR_DUAL
SDL_DestroyTexture(monitor2.texture);
SDL_DestroyRenderer(monitor2.renderer);
SDL_DestroyWindow(monitor2.window);
#endif
SDL_Quit();
}
static void monitor_sdl_init(void)
{
/*Initialize the SDL*/
SDL_Init(SDL_INIT_VIDEO);
SDL_SetEventFilter(quit_filter, NULL);
window_create(&monitor);
#if MONITOR_DUAL
window_create(&monitor2);
int x, y;
SDL_GetWindowPosition(monitor2.window, &x, &y);
SDL_SetWindowPosition(monitor.window, x + MONITOR_HOR_RES / 2 + 10, y);
SDL_SetWindowPosition(monitor2.window, x - MONITOR_HOR_RES / 2 - 10, y);
#endif
sdl_inited = true;
}
#ifdef MONITOR_EMSCRIPTEN
void monitor_sdl_refr_core(void)
#else
static void monitor_sdl_refr_core(void)
#endif
{
if(monitor.sdl_refr_qry != false) {
monitor.sdl_refr_qry = false;
window_update(&monitor);
}
#if MONITOR_DUAL
if(monitor2.sdl_refr_qry != false) {
monitor2.sdl_refr_qry = false;
window_update(&monitor2);
}
#endif
#if !defined(MONITOR_APPLE) && !defined(MONITOR_EMSCRIPTEN)
SDL_Event event;
while(SDL_PollEvent(&event)) {
#if USE_MOUSE != 0
mouse_handler(&event);
#endif
#if USE_MOUSEWHEEL != 0
mousewheel_handler(&event);
#endif
#if USE_KEYBOARD
keyboard_handler(&event);
#endif
if((&event)->type == SDL_WINDOWEVENT) {
switch((&event)->window.event) {
#if SDL_VERSION_ATLEAST(2, 0, 5)
case SDL_WINDOWEVENT_TAKE_FOCUS:
#endif
case SDL_WINDOWEVENT_EXPOSED:
window_update(&monitor);
#if MONITOR_DUAL
window_update(&monitor2);
#endif
break;
default:
break;
}
}
}
#endif /*MONITOR_APPLE*/
/*Sleep some time*/
SDL_Delay(SDL_REFR_PERIOD);
}
static void window_create(monitor_t * m)
{
m->window = SDL_CreateWindow("TFT Simulator",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
MONITOR_HOR_RES * MONITOR_ZOOM, MONITOR_VER_RES * MONITOR_ZOOM, 0); /*last param. SDL_WINDOW_BORDERLESS to hide borders*/
#if MONITOR_VIRTUAL_MACHINE || defined(MONITOR_EMSCRIPTEN)
m->renderer = SDL_CreateRenderer(m->window, -1, SDL_RENDERER_SOFTWARE);
#else
m->renderer = SDL_CreateRenderer(m->window, -1, 0);
#endif
m->texture = SDL_CreateTexture(m->renderer,
SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, MONITOR_HOR_RES, MONITOR_VER_RES);
SDL_SetTextureBlendMode(m->texture, SDL_BLENDMODE_BLEND);
/*Initialize the frame buffer to gray (77 is an empirical value) */
#if MONITOR_DOUBLE_BUFFERED
SDL_UpdateTexture(m->texture, NULL, m->tft_fb_act, MONITOR_HOR_RES * sizeof(uint32_t));
#else
memset(m->tft_fb, 0x44, MONITOR_HOR_RES * MONITOR_VER_RES * sizeof(uint32_t));
#endif
m->sdl_refr_qry = true;
}
static void window_update(monitor_t * m)
{
#if MONITOR_DOUBLE_BUFFERED == 0
SDL_UpdateTexture(m->texture, NULL, m->tft_fb, MONITOR_HOR_RES * sizeof(uint32_t));
#else
if(m->tft_fb_act == NULL) return;
SDL_UpdateTexture(m->texture, NULL, m->tft_fb_act, MONITOR_HOR_RES * sizeof(uint32_t));
#endif
SDL_RenderClear(m->renderer);
/*Test: Draw a background to test transparent screens (LV_COLOR_SCREEN_TRANSP)*/
// SDL_SetRenderDrawColor(renderer, 0xff, 0, 0, 0xff);
// SDL_Rect r;
// r.x = 0; r.y = 0; r.w = MONITOR_HOR_RES; r.w = MONITOR_VER_RES;
// SDL_RenderDrawRect(renderer, &r);
/*Update the renderer with the texture containing the rendered image*/
SDL_RenderCopy(m->renderer, m->texture, NULL, NULL);
SDL_RenderPresent(m->renderer);
}
#endif /*USE_MONITOR*/

View File

@ -0,0 +1,57 @@
/**
* @file monitor.h
*
*/
#ifndef MONITOR_H
#define MONITOR_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_MONITOR
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void monitor_init(void);
void monitor_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
void monitor_flush2(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
/**********************
* MACROS
**********************/
#endif /* USE_MONITOR */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* MONITOR_H */

View File

@ -0,0 +1,97 @@
/**
* @file tft_espi_drv.cpp
*
*/
/*********************
* INCLUDES
*********************/
#include "tft_espi_drv.h"
#include "../../../src/hasp_tft.h"
#if USE_TFT_ESPI != 0
#include <stdbool.h>
#include "TFT_eSPI.h"
#include LV_DRV_DISP_INCLUDE
#include LV_DRV_DELAY_INCLUDE
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static TFT_eSPI tft;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the R61581 display controller
* @return HW_RES_OK or any error from hw_res_t enum
*/
void tft_espi_init(uint8_t rotation)
{
/* TFT init */
tft.begin();
tft.setSwapBytes(true); /* set endianess */
tft.setRotation(rotation);
#ifdef USE_DMA_TO_TFT
// DMA - should work with STM32F2xx/F4xx/F7xx processors
// NOTE: >>>>>> DMA IS FOR SPI DISPLAYS ONLY <<<<<<
tft.initDMA(); // Initialise the DMA engine (tested with STM32F446 and STM32F767)
#endif
tftSetup(tft);
}
void tft_espi_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
size_t len = (x2 - x1 + 1) * (y2 - y1 + 1); /* Number of pixels */
/* Update TFT */
tft.startWrite(); /* Start new TFT transaction */
tft.setWindow(x1, y1, x2, y2); /* set the working window */
#ifdef USE_DMA_TO_TFT
tft.pushPixelsDMA((uint16_t *)color_p, len); /* Write words at once */
#else
tft.pushPixels((uint16_t *)color_p, len); /* Write words at once */
#endif
tft.endWrite(); /* terminate TFT transaction */
/* Tell lvgl that flushing is done */
// lv_disp_flush_ready();
}
void tft_espi_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
{
tft.fillRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1, color.full);
}
void tft_espi_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
tft_espi_flush(x1, y1, x2, y2, color_p);
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif

View File

@ -0,0 +1,67 @@
/**
* @file tft_espi_drv.h
*
*/
#ifndef TFT_ESPI_DRV_H
#define TFT_ESPI_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_TFT_ESPI
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* 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
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
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_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);
/**********************
* MACROS
**********************/
#endif /* USE_TFT_ESPI */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* TFT_ESPI_DRV_H */

View File

@ -0,0 +1 @@
--style=kr --convert-tabs --indent=spaces=4 --indent-switches --pad-oper --unpad-paren --align-pointer=middle --suffix=.bak --lineend=linux --min-conditional-indent=

View File

@ -0,0 +1 @@
--convert-tabs --indent=spaces=4

View File

@ -0,0 +1,383 @@
/**
* @file AD_touch.c
*
*/
#include "AD_touch.h"
#if USE_AD_TOUCH
#include LV_DRV_INDEV_INCLUDE
#include LV_DRV_DELAY_INCLUDE
#define SAMPLE_POINTS 4
#define CALIBRATIONINSET 20 // range 0 <= CALIBRATIONINSET <= 40
#define RESISTIVETOUCH_AUTO_SAMPLE_MODE
#define TOUCHSCREEN_RESISTIVE_PRESS_THRESHOLD 350 // between 0-0x03ff the lesser this value
// Current ADC values for X and Y channels
int16_t adcX = 0;
int16_t adcY = 0;
volatile unsigned int adcTC = 0;
// coefficient values
volatile long _trA;
volatile long _trB;
volatile long _trC;
volatile long _trD;
volatile int16_t xRawTouch[SAMPLE_POINTS] = {TOUCHCAL_ULX, TOUCHCAL_URX, TOUCHCAL_LRX, TOUCHCAL_LLX};
volatile int16_t yRawTouch[SAMPLE_POINTS] = {TOUCHCAL_ULY, TOUCHCAL_URY, TOUCHCAL_LRY, TOUCHCAL_LLY};
#define TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR 8
// use this scale factor to avoid working in floating point numbers
#define SCALE_FACTOR (1 << TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR)
typedef enum {
IDLE, //0
SET_X, //1
RUN_X, //2
GET_X, //3
RUN_CHECK_X, //4
CHECK_X, //5
SET_Y, //6
RUN_Y, //7
GET_Y, //8
CHECK_Y, //9
SET_VALUES, //10
GET_POT, //11
RUN_POT //12
} TOUCH_STATES;
volatile TOUCH_STATES state = IDLE;
#define CAL_X_INSET (((GetMaxX() + 1) * (CALIBRATIONINSET >> 1)) / 100)
#define CAL_Y_INSET (((GetMaxY() + 1) * (CALIBRATIONINSET >> 1)) / 100)
int stat;
int16_t temp_x, temp_y;
static int16_t TouchGetX(void);
static int16_t TouchGetRawX(void);
static int16_t TouchGetY(void);
static int16_t TouchGetRawY(void);
static int16_t TouchDetectPosition(void);
static void TouchCalculateCalPoints(void);
/********************************************************************/
void ad_touch_init(void)
{
// Initialize ADC for auto sampling mode
AD1CON1 = 0; // reset
AD1CON2 = 0; // AVdd, AVss, int every conversion, MUXA only
AD1CON3 = 0x1FFF; // 31 Tad auto-sample, Tad = 256*Tcy
AD1CON1 = 0x80E0; // Turn on A/D module, use auto-convert
ADPCFG_XPOS = RESISTIVETOUCH_ANALOG;
ADPCFG_YPOS = RESISTIVETOUCH_ANALOG;
AD1CSSL = 0; // No scanned inputs
state = SET_X; // set the state of the state machine to start the sampling
/*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();
}
/*Use this in lv_indev_drv*/
bool ad_touch_read(lv_indev_drv_t * indev_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;
}
/* Call periodically (e.g. in every 1 ms) to handle reading with ADC*/
int16_t ad_touch_handler(void)
{
static int16_t tempX, tempY;
int16_t temp;
switch(state) {
case IDLE:
adcX = 0;
adcY = 0;
break;
case SET_VALUES:
if(!TOUCH_ADC_DONE)
break;
if((WORD)TOUCHSCREEN_RESISTIVE_PRESS_THRESHOLD < (WORD)ADC1BUF0) {
adcX = 0;
adcY = 0;
} else {
adcX = tempX;
adcY = tempY;
}
state = SET_X;
return 1; // touch screen acquisition is done
case SET_X:
TOUCH_ADC_INPUT_SEL = ADC_XPOS;
ResistiveTouchScreen_XPlus_Config_As_Input();
ResistiveTouchScreen_YPlus_Config_As_Input();
ResistiveTouchScreen_XMinus_Config_As_Input();
ResistiveTouchScreen_YMinus_Drive_Low();
ResistiveTouchScreen_YMinus_Config_As_Output();
ADPCFG_YPOS = RESISTIVETOUCH_DIGITAL; // set to digital pin
ADPCFG_XPOS = RESISTIVETOUCH_ANALOG; // set to analog pin
TOUCH_ADC_START = 1; // run conversion
state = CHECK_X;
break;
case CHECK_X:
case CHECK_Y:
if(TOUCH_ADC_DONE == 0) {
break;
}
if((WORD)TOUCHSCREEN_RESISTIVE_PRESS_THRESHOLD > (WORD)ADC1BUF0) {
if(state == CHECK_X) {
ResistiveTouchScreen_YPlus_Drive_High();
ResistiveTouchScreen_YPlus_Config_As_Output();
tempX = 0;
state = RUN_X;
} else {
ResistiveTouchScreen_XPlus_Drive_High();
ResistiveTouchScreen_XPlus_Config_As_Output();
tempY = 0;
state = RUN_Y;
}
} else {
adcX = 0;
adcY = 0;
state = SET_X;
return 1; // touch screen acquisition is done
break;
}
case RUN_X:
case RUN_Y:
TOUCH_ADC_START = 1;
state = (state == RUN_X) ? GET_X : GET_Y;
// no break needed here since the next state is either GET_X or GET_Y
break;
case GET_X:
case GET_Y:
if(!TOUCH_ADC_DONE)
break;
temp = ADC1BUF0;
if(state == GET_X) {
if(temp != tempX) {
tempX = temp;
state = RUN_X;
break;
}
} else {
if(temp != tempY) {
tempY = temp;
state = RUN_Y;
break;
}
}
if(state == GET_X)
ResistiveTouchScreen_YPlus_Config_As_Input();
else
ResistiveTouchScreen_XPlus_Config_As_Input();
TOUCH_ADC_START = 1;
state = (state == GET_X) ? SET_Y : SET_VALUES;
break;
case SET_Y:
if(!TOUCH_ADC_DONE)
break;
if((WORD)TOUCHSCREEN_RESISTIVE_PRESS_THRESHOLD < (WORD)ADC1BUF0) {
adcX = 0;
adcY = 0;
state = SET_X;
return 1; // touch screen acquisition is done
break;
}
TOUCH_ADC_INPUT_SEL = ADC_YPOS;
ResistiveTouchScreen_XPlus_Config_As_Input();
ResistiveTouchScreen_YPlus_Config_As_Input();
ResistiveTouchScreen_XMinus_Drive_Low();
ResistiveTouchScreen_XMinus_Config_As_Output();
ResistiveTouchScreen_YMinus_Config_As_Input();
ADPCFG_YPOS = RESISTIVETOUCH_ANALOG; // set to analog pin
ADPCFG_XPOS = RESISTIVETOUCH_DIGITAL; // set to digital pin
TOUCH_ADC_START = 1; // run conversion
state = CHECK_Y;
break;
default:
state = SET_X;
return 1; // touch screen acquisition is done
}
stat = state;
temp_x = adcX;
temp_y = adcY;
return 0; // touch screen acquisition is not done
}
/**********************
* STATIC FUNCTIONS
**********************/
/********************************************************************/
static int16_t TouchGetX(void)
{
long result;
result = TouchGetRawX();
if(result > 0) {
result = (long)((((long)_trC * result) + _trD) >> TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR);
}
return ((int16_t)result);
}
/********************************************************************/
static int16_t TouchGetRawX(void)
{
#ifdef TOUCHSCREEN_RESISTIVE_SWAP_XY
return adcY;
#else
return adcX;
#endif
}
/********************************************************************/
static int16_t TouchGetY(void)
{
long result;
result = TouchGetRawY();
if(result > 0) {
result = (long)((((long)_trA * result) + (long)_trB) >> TOUCHSCREEN_RESISTIVE_CALIBRATION_SCALE_FACTOR);
}
return ((int16_t)result);
}
/********************************************************************/
static int16_t TouchGetRawY(void)
{
#ifdef TOUCHSCREEN_RESISTIVE_SWAP_XY
return adcX;
#else
return adcY;
#endif
}
static void TouchCalculateCalPoints(void)
{
long trA, trB, trC, trD; // variables for the coefficients
long trAhold, trBhold, trChold, trDhold;
long test1, test2; // temp variables (must be signed type)
int16_t xPoint[SAMPLE_POINTS], yPoint[SAMPLE_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 functiona
// 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 = (long)yPoint[0] - (long)yPoint[3];
test2 = (long)yRawTouch[0] - (long)yRawTouch[3];
trA = ((long)((long)test1 * SCALE_FACTOR) / test2);
trB = ((long)((long)yPoint[0] * SCALE_FACTOR) - (trA * (long)yRawTouch[0]));
test1 = (long)xPoint[0] - (long)xPoint[2];
test2 = (long)xRawTouch[0] - (long)xRawTouch[2];
trC = ((long)((long)test1 * SCALE_FACTOR) / test2);
trD = ((long)((long)xPoint[0] * SCALE_FACTOR) - (trC * (long)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 = (long)yPoint[1] - (long)yPoint[2];
test2 = (long)yRawTouch[1] - (long)yRawTouch[2];
trA = ((long)(test1 * SCALE_FACTOR) / test2);
trB = ((long)((long)yPoint[1] * SCALE_FACTOR) - (trA * (long)yRawTouch[1]));
test1 = (long)xPoint[1] - (long)xPoint[3];
test2 = (long)xRawTouch[1] - (long)xRawTouch[3];
trC = ((long)((long)test1 * SCALE_FACTOR) / test2);
trD = ((long)((long)xPoint[1] * SCALE_FACTOR) - (trC * (long)xRawTouch[1]));
// get the average and use the average
_trA = (trA + trAhold) >> 1;
_trB = (trB + trBhold) >> 1;
_trC = (trC + trChold) >> 1;
_trD = (trD + trDhold) >> 1;
}
#endif

View File

@ -0,0 +1,120 @@
/**
* @file AD_touch.h
*
*/
#ifndef AD_TOUCH_H
#define AD_TOUCH_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_AD_TOUCH
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#define _SUPPRESS_PLIB_WARNING
#include <plib.h>
#include "GenericTypeDefs.h"
#define DISP_ORIENTATION 0
#define DISP_HOR_RESOLUTION 320
#define DISP_VER_RESOLUTION 240
/*GetMaxX Macro*/
#if (DISP_ORIENTATION == 90) || (DISP_ORIENTATION == 270)
#define GetMaxX() (DISP_VER_RESOLUTION - 1)
#elif (DISP_ORIENTATION == 0) || (DISP_ORIENTATION == 180)
#define GetMaxX() (DISP_HOR_RESOLUTION - 1)
#endif
/*GetMaxY Macro*/
#if (DISP_ORIENTATION == 90) || (DISP_ORIENTATION == 270)
#define GetMaxY() (DISP_HOR_RESOLUTION - 1)
#elif (DISP_ORIENTATION == 0) || (DISP_ORIENTATION == 180)
#define GetMaxY() (DISP_VER_RESOLUTION - 1)
#endif
/*********************************************************************
* HARDWARE PROFILE FOR THE RESISTIVE TOUCHSCREEN
*********************************************************************/
#define TOUCH_ADC_INPUT_SEL AD1CHS
// ADC Sample Start
#define TOUCH_ADC_START AD1CON1bits.SAMP
// ADC Status
#define TOUCH_ADC_DONE AD1CON1bits.DONE
#define RESISTIVETOUCH_ANALOG 1
#define RESISTIVETOUCH_DIGITAL 0
// ADC channel constants
#define ADC_XPOS ADC_CH0_POS_SAMPLEA_AN12
#define ADC_YPOS ADC_CH0_POS_SAMPLEA_AN13
// ADC Port Control Bits
#define ADPCFG_XPOS AD1PCFGbits.PCFG12 //XR
#define ADPCFG_YPOS AD1PCFGbits.PCFG13 //YD
// X port definitions
#define ResistiveTouchScreen_XPlus_Drive_High() LATBbits.LATB12 = 1
#define ResistiveTouchScreen_XPlus_Drive_Low() LATBbits.LATB12 = 0 //LAT_XPOS
#define ResistiveTouchScreen_XPlus_Config_As_Input() TRISBbits.TRISB12 = 1 //TRIS_XPOS
#define ResistiveTouchScreen_XPlus_Config_As_Output() TRISBbits.TRISB12 = 0
#define ResistiveTouchScreen_XMinus_Drive_High() LATFbits.LATF0 = 1
#define ResistiveTouchScreen_XMinus_Drive_Low() LATFbits.LATF0 = 0 //LAT_XNEG
#define ResistiveTouchScreen_XMinus_Config_As_Input() TRISFbits.TRISF0 = 1 //TRIS_XNEG
#define ResistiveTouchScreen_XMinus_Config_As_Output() TRISFbits.TRISF0 = 0
// Y port definitions
#define ResistiveTouchScreen_YPlus_Drive_High() LATBbits.LATB13 = 1
#define ResistiveTouchScreen_YPlus_Drive_Low() LATBbits.LATB13 = 0 //LAT_YPOS
#define ResistiveTouchScreen_YPlus_Config_As_Input() TRISBbits.TRISB13 = 1 //TRIS_YPOS
#define ResistiveTouchScreen_YPlus_Config_As_Output() TRISBbits.TRISB13 = 0
#define ResistiveTouchScreen_YMinus_Drive_High() LATFbits.LATF1 = 1
#define ResistiveTouchScreen_YMinus_Drive_Low() LATFbits.LATF1 = 0 //LAT_YNEG
#define ResistiveTouchScreen_YMinus_Config_As_Input() TRISFbits.TRISF1 = 1 //TRIS_YNEG
#define ResistiveTouchScreen_YMinus_Config_As_Output() TRISFbits.TRISF1 = 0
// Default calibration points
#define TOUCHCAL_ULX 0x0348
#define TOUCHCAL_ULY 0x00CC
#define TOUCHCAL_URX 0x00D2
#define TOUCHCAL_URY 0x00CE
#define TOUCHCAL_LLX 0x034D
#define TOUCHCAL_LLY 0x0335
#define TOUCHCAL_LRX 0x00D6
#define TOUCHCAL_LRY 0x032D
void ad_touch_init(void);
bool ad_touch_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
int16_t ad_touch_handler(void);
#endif /* USE_AD_TOUCH */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* AD_TOUCH_H */

View File

@ -0,0 +1,179 @@
/**
* @file FT5406EE8.c
*
*/
/*********************
* INCLUDES
*********************/
#include "FT5406EE8.h"
#if USE_FT5406EE8
#include <stddef.h>
#include <stdbool.h>
#include LV_DRV_INDEV_INCLUDE
#include LV_DRV_DELAY_INCLUDE
/*********************
* DEFINES
*********************/
#define I2C_WR_BIT 0x00
#define I2C_RD_BIT 0x01
/*DEVICE MODES*/
#define OPERAT_MD 0x00
#define TEST_MD 0x04
#define SYS_INF_MD 0x01
/*OPERATING MODE*/
#define DEVICE_MODE 0x00
#define GEST_ID 0x01
#define TD_STATUS 0x02
#define FT5406EE8_FINGER_MAX 10
/*Register adresses*/
#define FT5406EE8_REG_DEVICE_MODE 0x00
#define FT5406EE8_REG_GEST_ID 0x01
#define FT5406EE8_REG_TD_STATUS 0x02
#define FT5406EE8_REG_YH 0x03
#define FT5406EE8_REG_YL 0x04
#define FT5406EE8_REG_XH 0x05
#define FT5406EE8_REG_XL 0x06
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static bool ft5406ee8_get_touch_num(void);
static bool ft5406ee8_read_finger1(int16_t * x, int16_t * y);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
*
*/
void ft5406ee8_init(void)
{
}
/**
* Get the current position and state of the touchpad
* @param data store the read data here
* @return false: because no ore data to be read
*/
bool ft5406ee8_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
static int16_t x_last;
static int16_t y_last;
int16_t x;
int16_t y;
bool valid = true;
valid = ft5406ee8_get_touch_num();
if(valid == true) {
valid = ft5406ee8_read_finger1(&x, &y);
}
if(valid == true) {
x = (uint32_t)((uint32_t)x * 320) / 2048;
y = (uint32_t)((uint32_t)y * 240) / 2048;
x_last = x;
y_last = y;
} else {
x = x_last;
y = y_last;
}
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 bool ft5406ee8_get_touch_num(void)
{
bool ok = true;
uint8_t t_num = 0;
LV_DRV_INDEV_I2C_START;
LV_DRV_INDEV_I2C_WR((FT5406EE8_I2C_ADR << 1) | I2C_WR_BIT);
LV_DRV_INDEV_I2C_WR(FT5406EE8_REG_TD_STATUS)
LV_DRV_INDEV_I2C_RESTART;
LV_DRV_INDEV_I2C_WR((FT5406EE8_I2C_ADR << 1) | I2C_RD_BIT);
t_num = LV_DRV_INDEV_I2C_READ(0);
/* Error if not touched or too much finger */
if(t_num > FT5406EE8_FINGER_MAX || t_num == 0) {
ok = false;
}
return ok;
}
/**
* Read the x and y coordinated
* @param x store the x coordinate here
* @param y store the y coordinate here
* @return false: not valid point; true: valid point
*/
static bool ft5406ee8_read_finger1(int16_t * x, int16_t * y)
{
uint8_t temp_xH = 0;
uint8_t temp_xL = 0;
uint8_t temp_yH = 0;
uint8_t temp_yL = 0;
/*Read Y High and low byte*/
LV_DRV_INDEV_I2C_START;
LV_DRV_INDEV_I2C_WR((FT5406EE8_I2C_ADR << 1) | I2C_WR_BIT);
LV_DRV_INDEV_I2C_WR(FT5406EE8_REG_YH)
LV_DRV_INDEV_I2C_RESTART;
LV_DRV_INDEV_I2C_WR((FT5406EE8_I2C_ADR << 1) | I2C_RD_BIT);
temp_yH = LV_DRV_INDEV_I2C_READ(1);
temp_yL = LV_DRV_INDEV_I2C_READ(1);
/*The upper two bit must be 2 on valid press*/
if(((temp_yH >> 6) & 0xFF) != 2) {
(void) LV_DRV_INDEV_I2C_READ(0); /*Dummy read to close read sequence*/
*x = 0;
*y = 0;
return false;
}
/*Read X High and low byte*/
temp_xH = LV_DRV_INDEV_I2C_READ(1);
temp_xL = LV_DRV_INDEV_I2C_READ(0);
/*Save the result*/
*x = (temp_xH & 0x0F) << 8;
*x += temp_xL;
*y = (temp_yH & 0x0F) << 8;
*y += temp_yL;
return true;
}
#endif

View File

@ -0,0 +1,56 @@
/**
* @file FT5406EE8.h
*
*/
#ifndef FT5406EE8_H
#define FT5406EE8_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_FT5406EE8
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void ft5406ee8_init(void);
bool ft5406ee8_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
/**********************
* MACROS
**********************/
#endif /* USE_FT5406EE8 */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* FT5406EE8_H */

View File

@ -0,0 +1,174 @@
/**
* @file XPT2046.c
*
*/
/*********************
* INCLUDES
*********************/
#include "XPT2046.h"
#if USE_XPT2046
#include <stddef.h>
#include LV_DRV_INDEV_INCLUDE
#include LV_DRV_DELAY_INCLUDE
/*********************
* DEFINES
*********************/
#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)
{
}
/**
* Get the current position and state of the touchpad
* @param data store the read data here
* @return false: because no ore data to be read
*/
bool xpt2046_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
static int16_t last_x = 0;
static int16_t last_y = 0;
uint8_t buf;
int16_t x = 0;
int16_t y = 0;
uint8_t irq = LV_DRV_INDEV_IRQ_READ;
if(irq == 0) {
LV_DRV_INDEV_SPI_CS(0);
LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_X_READ); /*Start x read*/
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read x MSB*/
x = buf << 8;
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_Y_READ); /*Until x LSB converted y command can be sent*/
x += buf;
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read y MSB*/
y = buf << 8;
buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0); /*Read y LSB*/
y += buf;
/*Normalize Data*/
x = x >> 3;
y = y >> 3;
xpt2046_corr(&x, &y);
xpt2046_avg(&x, &y);
last_x = x;
last_y = y;
data->state = LV_INDEV_STATE_PR;
LV_DRV_INDEV_SPI_CS(1);
} else {
x = last_x;
y = last_y;
avg_last = 0;
data->state = LV_INDEV_STATE_REL;
}
data->point.x = x;
data->point.y = y;
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) * XPT2046_HOR_RES) /
(XPT2046_X_MAX - XPT2046_X_MIN);
(*y) = (uint32_t)((uint32_t)(*y) * XPT2046_VER_RES) /
(XPT2046_Y_MAX - XPT2046_Y_MIN);
#if XPT2046_X_INV != 0
(*x) = XPT2046_HOR_RES - (*x);
#endif
#if XPT2046_Y_INV != 0
(*y) = XPT2046_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;
}
#endif

View File

@ -0,0 +1,56 @@
/**
* @file XPT2046.h
*
*/
#ifndef XPT2046_H
#define XPT2046_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
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void xpt2046_init(void);
bool xpt2046_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
/**********************
* MACROS
**********************/
#endif /* USE_XPT2046 */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* XPT2046_H */

View File

@ -0,0 +1,223 @@
/**
* @file evdev.c
*
*/
/*********************
* INCLUDES
*********************/
#include "evdev.h"
#if USE_EVDEV != 0
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
int map(int x, int in_min, int in_max, int out_min, int out_max);
/**********************
* STATIC VARIABLES
**********************/
int evdev_fd;
int evdev_root_x;
int evdev_root_y;
int evdev_button;
int evdev_key_val;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the evdev interface
*/
void evdev_init(void)
{
evdev_fd = open(EVDEV_NAME, O_RDWR | O_NOCTTY | O_NDELAY);
if(evdev_fd == -1) {
perror("unable open evdev interface:");
return;
}
fcntl(evdev_fd, F_SETFL, O_ASYNC | O_NONBLOCK);
evdev_root_x = 0;
evdev_root_y = 0;
evdev_key_val = 0;
evdev_button = LV_INDEV_STATE_REL;
}
/**
* reconfigure the device file for evdev
* @param dev_name set the evdev device filename
* @return true: the device file set complete
* false: the device file doesn't exist current system
*/
bool evdev_set_file(char* dev_name)
{
if(evdev_fd != -1) {
close(evdev_fd);
}
evdev_fd = open(dev_name, O_RDWR | O_NOCTTY | O_NDELAY);
if(evdev_fd == -1) {
perror("unable open evdev interface:");
return false;
}
fcntl(evdev_fd, F_SETFL, O_ASYNC | O_NONBLOCK);
evdev_root_x = 0;
evdev_root_y = 0;
evdev_key_val = 0;
evdev_button = LV_INDEV_STATE_REL;
return true;
}
/**
* Get the current position and state of the evdev
* @param data store the evdev data here
* @return false: because the points are not buffered, so no more data to be read
*/
bool evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
{
struct input_event in;
while(read(evdev_fd, &in, sizeof(struct input_event)) > 0) {
if(in.type == EV_REL) {
if(in.code == REL_X)
#if EVDEV_SWAP_AXES
evdev_root_y += in.value;
#else
evdev_root_x += in.value;
#endif
else if(in.code == REL_Y)
#if EVDEV_SWAP_AXES
evdev_root_x += in.value;
#else
evdev_root_y += in.value;
#endif
} else if(in.type == EV_ABS) {
if(in.code == ABS_X)
#if EVDEV_SWAP_AXES
evdev_root_y = in.value;
#else
evdev_root_x = in.value;
#endif
else if(in.code == ABS_Y)
#if EVDEV_SWAP_AXES
evdev_root_x = in.value;
#else
evdev_root_y = in.value;
#endif
else if(in.code == ABS_MT_POSITION_X)
#if EVDEV_SWAP_AXES
evdev_root_y = in.value;
#else
evdev_root_x = in.value;
#endif
else if(in.code == ABS_MT_POSITION_Y)
#if EVDEV_SWAP_AXES
evdev_root_x = in.value;
#else
evdev_root_y = in.value;
#endif
} else if(in.type == EV_KEY) {
if(in.code == BTN_MOUSE || in.code == BTN_TOUCH) {
if(in.value == 0)
evdev_button = LV_INDEV_STATE_REL;
else if(in.value == 1)
evdev_button = LV_INDEV_STATE_PR;
} else if(drv->type == LV_INDEV_TYPE_KEYPAD) {
data->state = (in.value) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
switch(in.code) {
case KEY_BACKSPACE:
data->key = LV_KEY_BACKSPACE;
break;
case KEY_ENTER:
data->key = LV_KEY_ENTER;
break;
case KEY_UP:
data->key = LV_KEY_UP;
break;
case KEY_LEFT:
data->key = LV_KEY_PREV;
break;
case KEY_RIGHT:
data->key = LV_KEY_NEXT;
break;
case KEY_DOWN:
data->key = LV_KEY_DOWN;
break;
default:
data->key = 0;
break;
}
evdev_key_val = data->key;
evdev_button = data->state;
return false;
}
}
}
if(drv->type == LV_INDEV_TYPE_KEYPAD) {
/* No data retrieved */
data->key = evdev_key_val;
data->state = evdev_button;
return false;
}
if(drv->type != LV_INDEV_TYPE_POINTER)
return false;
/*Store the collected data*/
#if EVDEV_SCALE
data->point.x = map(evdev_root_x, 0, EVDEV_SCALE_HOR_RES, 0, lv_disp_get_hor_res(drv->disp));
data->point.y = map(evdev_root_y, 0, EVDEV_SCALE_VER_RES, 0, lv_disp_get_ver_res(drv->disp));
#endif
#if EVDEV_CALIBRATE
data->point.x = map(evdev_root_x, EVDEV_HOR_MIN, EVDEV_HOR_MAX, 0, lv_disp_get_hor_res(drv->disp));
data->point.y = map(evdev_root_y, EVDEV_VER_MIN, EVDEV_VER_MAX, 0, lv_disp_get_ver_res(drv->disp));
#else
data->point.x = evdev_root_x;
data->point.y = evdev_root_y;
#endif
data->state = evdev_button;
if(data->point.x < 0)
data->point.x = 0;
if(data->point.y < 0)
data->point.y = 0;
if(data->point.x >= lv_disp_get_hor_res(drv->disp))
data->point.x = lv_disp_get_hor_res(drv->disp) - 1;
if(data->point.y >= lv_disp_get_ver_res(drv->disp))
data->point.y = lv_disp_get_ver_res(drv->disp) - 1;
return false;
}
/**********************
* STATIC FUNCTIONS
**********************/
int map(int x, int in_min, int in_max, int out_min, int out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
#endif

View File

@ -0,0 +1,73 @@
/**
* @file evdev.h
*
*/
#ifndef EVDEV_H
#define EVDEV_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_EVDEV
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the evdev
*/
void evdev_init(void);
/**
* reconfigure the device file for evdev
* @param dev_name set the evdev device filename
* @return true: the device file set complete
* false: the device file doesn't exist current system
*/
bool evdev_set_file(char* dev_name);
/**
* Get the current position and state of the evdev
* @param data store the evdev data here
* @return false: because the points are not buffered, so no more data to be read
*/
bool evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data);
/**********************
* MACROS
**********************/
#endif /* USE_EVDEV */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* EVDEV_H */

View File

@ -0,0 +1,12 @@
CSRCS += FT5406EE8.c
CSRCS += keyboard.c
CSRCS += mouse.c
CSRCS += mousewheel.c
CSRCS += evdev.c
CSRCS += libinput.c
CSRCS += XPT2046.c
DEPPATH += --dep-path $(LVGL_DIR)/lv_drivers/indev
VPATH += :$(LVGL_DIR)/lv_drivers/indev
CFLAGS += "-I$(LVGL_DIR)/lv_drivers/indev"

View File

@ -0,0 +1,130 @@
/**
* @file sdl_kb.c
*
*/
/*********************
* INCLUDES
*********************/
#include "keyboard.h"
#if USE_KEYBOARD
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static uint32_t keycode_to_ascii(uint32_t sdl_key);
/**********************
* STATIC VARIABLES
**********************/
static uint32_t last_key;
static lv_indev_state_t state;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the keyboard
*/
void keyboard_init(void)
{
/*Nothing to init*/
}
/**
* Get the last pressed or released character from the PC's keyboard
* @param indev_drv pointer to the related input device driver
* @param data store the read data here
* @return false: because the points are not buffered, so no more data to be read
*/
bool keyboard_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
(void) indev_drv; /*Unused*/
data->state = state;
data->key = keycode_to_ascii(last_key);
return false;
}
/**
* It is called periodically from the SDL thread to check a key is pressed/released
* @param event describes the event
*/
void keyboard_handler(SDL_Event * event)
{
/* We only care about SDL_KEYDOWN and SDL_KEYUP events */
switch(event->type) {
case SDL_KEYDOWN: /*Button press*/
last_key = event->key.keysym.sym; /*Save the pressed key*/
state = LV_INDEV_STATE_PR; /*Save the key is pressed now*/
break;
case SDL_KEYUP: /*Button release*/
state = LV_INDEV_STATE_REL; /*Save the key is released but keep the last key*/
break;
default:
break;
}
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Convert the key code LV_KEY_... "codes" or leave them if they are not control characters
* @param sdl_key the key code
* @return
*/
static uint32_t keycode_to_ascii(uint32_t sdl_key)
{
/*Remap some key to LV_KEY_... to manage groups*/
switch(sdl_key) {
case SDLK_RIGHT:
case SDLK_KP_PLUS:
return LV_KEY_RIGHT;
case SDLK_LEFT:
case SDLK_KP_MINUS:
return LV_KEY_LEFT;
case SDLK_UP:
return LV_KEY_UP;
case SDLK_DOWN:
return LV_KEY_DOWN;
case SDLK_ESCAPE:
return LV_KEY_ESC;
#ifdef LV_KEY_BACKSPACE /*For backward compatibility*/
case SDLK_BACKSPACE:
return LV_KEY_BACKSPACE;
#endif
#ifdef LV_KEY_DEL /*For backward compatibility*/
case SDLK_DELETE:
return LV_KEY_DEL;
#endif
case SDLK_KP_ENTER:
case '\r':
return LV_KEY_ENTER;
default:
return sdl_key;
}
}
#endif

View File

@ -0,0 +1,78 @@
/**
* @file keyboard.h
*
*/
#ifndef KEYBOARD_H
#define KEYBOARD_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_KEYBOARD
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#ifndef MONITOR_SDL_INCLUDE_PATH
#define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
#endif
#include MONITOR_SDL_INCLUDE_PATH
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the keyboard
*/
void keyboard_init(void);
/**
* Get the last pressed or released character from the PC's keyboard
* @param indev_drv pointer to the related input device driver
* @param data store the read data here
* @return false: because the points are not buffered, so no more data to be read
*/
bool keyboard_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
/**
* It is called periodically from the SDL thread to check a key is pressed/released
* @param event describes the event
*/
void keyboard_handler(SDL_Event *event);
/**********************
* MACROS
**********************/
#endif /*USE_KEYBOARD*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*KEYBOARD_H*/

View File

@ -0,0 +1,175 @@
/**
* @file libinput.c
*
*/
/*********************
* INCLUDES
*********************/
#include "libinput_drv.h"
#if USE_LIBINPUT != 0
#include <stdio.h>
#include <unistd.h>
#include <linux/limits.h>
#include <fcntl.h>
#include <errno.h>
#include <stdbool.h>
#include <poll.h>
#include <libinput.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static int open_restricted(const char *path, int flags, void *user_data);
static void close_restricted(int fd, void *user_data);
/**********************
* STATIC VARIABLES
**********************/
static int libinput_fd;
static int libinput_button;
static const int timeout = 0; // do not block
static const nfds_t nfds = 1;
static struct pollfd fds[1];
static lv_point_t most_recent_touch_point = { .x = 0, .y = 0};
static struct libinput *libinput_context;
static struct libinput_device *libinput_device;
const static struct libinput_interface interface = {
.open_restricted = open_restricted,
.close_restricted = close_restricted,
};
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* reconfigure the device file for libinput
* @param dev_name set the libinput device filename
* @return true: the device file set complete
* false: the device file doesn't exist current system
*/
bool libinput_set_file(char* dev_name)
{
// This check *should* not be necessary, yet applications crashes even on NULL handles.
// citing libinput.h:libinput_path_remove_device:
// > If no matching device exists, this function does nothing.
if (libinput_device) {
libinput_device = libinput_device_unref(libinput_device);
libinput_path_remove_device(libinput_device);
}
libinput_device = libinput_path_add_device(libinput_context, dev_name);
if(!libinput_device) {
perror("unable to add device to libinput context:");
return false;
}
libinput_device = libinput_device_ref(libinput_device);
if(!libinput_device) {
perror("unable to reference device within libinput context:");
return false;
}
libinput_button = LV_INDEV_STATE_REL;
return true;
}
/**
* Initialize the libinput interface
*/
void libinput_init(void)
{
libinput_device = NULL;
libinput_context = libinput_path_create_context(&interface, NULL);
if(!libinput_set_file(LIBINPUT_NAME)) {
perror("unable to add device \"" LIBINPUT_NAME "\" to libinput context:");
return;
}
libinput_fd = libinput_get_fd(libinput_context);
/* prepare poll */
fds[0].fd = libinput_fd;
fds[0].events = POLLIN;
fds[0].revents = 0;
}
/**
* Get the current position and state of the libinput
* @param indev_drv driver object itself
* @param data store the libinput data here
* @return false: because the points are not buffered, so no more data to be read
*/
bool libinput_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
struct libinput_event *event;
struct libinput_event_touch *touch_event = NULL;
int rc = 0;
rc = poll(fds, nfds, timeout);
switch (rc){
case -1:
perror(NULL);
case 0:
goto report_most_recent_state;
default:
break;
}
libinput_dispatch(libinput_context);
while((event = libinput_get_event(libinput_context)) != NULL) {
enum libinput_event_type type = libinput_event_get_type(event);
switch (type) {
case LIBINPUT_EVENT_TOUCH_MOTION:
case LIBINPUT_EVENT_TOUCH_DOWN:
touch_event = libinput_event_get_touch_event(event);
most_recent_touch_point.x = libinput_event_touch_get_x_transformed(touch_event, LV_HOR_RES);
most_recent_touch_point.y = libinput_event_touch_get_y_transformed(touch_event, LV_VER_RES);
libinput_button = LV_INDEV_STATE_PR;
break;
case LIBINPUT_EVENT_TOUCH_UP:
libinput_button = LV_INDEV_STATE_REL;
break;
default:
break;
}
libinput_event_destroy(event);
}
report_most_recent_state:
data->point.x = most_recent_touch_point.x;
data->point.y = most_recent_touch_point.y;
data->state = libinput_button;
return false;
}
/**********************
* STATIC FUNCTIONS
**********************/
static int open_restricted(const char *path, int flags, void *user_data)
{
int fd = open(path, flags);
return fd < 0 ? -errno : fd;
}
static void close_restricted(int fd, void *user_data)
{
close(fd);
}
#endif

View File

@ -0,0 +1,74 @@
/**
* @file libinput.h
*
*/
#ifndef LVGL_LIBINPUT_H
#define LVGL_LIBINPUT_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_LIBINPUT
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the libinput
*/
void libinput_init(void);
/**
* reconfigure the device file for libinput
* @param dev_name set the libinput device filename
* @return true: the device file set complete
* false: the device file doesn't exist current system
*/
bool libinput_set_file(char* dev_name);
/**
* Get the current position and state of the libinput
* @param indev_drv driver object itself
* @param data store the libinput data here
* @return false: because the points are not buffered, so no more data to be read
*/
bool libinput_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
/**********************
* MACROS
**********************/
#endif /* USE_LIBINPUT */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LVGL_LIBINPUT_H */

View File

@ -0,0 +1,98 @@
/**
* @file mouse.c
*
*/
/*********************
* INCLUDES
*********************/
#include "mouse.h"
#if USE_MOUSE != 0
/*********************
* DEFINES
*********************/
#ifndef MONITOR_ZOOM
#define MONITOR_ZOOM 1
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static bool left_button_down = false;
static int16_t last_x = 0;
static int16_t last_y = 0;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the mouse
*/
void mouse_init(void)
{
}
/**
* Get the current position and state of the mouse
* @param indev_drv pointer to the related input device driver
* @param data store the mouse data here
* @return false: because the points are not buffered, so no more data to be read
*/
bool mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
(void) indev_drv; /*Unused*/
/*Store the collected data*/
data->point.x = last_x;
data->point.y = last_y;
data->state = left_button_down ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
return false;
}
/**
* It will be called from the main SDL thread
*/
void mouse_handler(SDL_Event * event)
{
switch(event->type) {
case SDL_MOUSEBUTTONUP:
if(event->button.button == SDL_BUTTON_LEFT)
left_button_down = false;
break;
case SDL_MOUSEBUTTONDOWN:
if(event->button.button == SDL_BUTTON_LEFT) {
left_button_down = true;
last_x = event->motion.x / MONITOR_ZOOM;
last_y = event->motion.y / MONITOR_ZOOM;
}
break;
case SDL_MOUSEMOTION:
last_x = event->motion.x / MONITOR_ZOOM;
last_y = event->motion.y / MONITOR_ZOOM;
break;
}
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif

View File

@ -0,0 +1,78 @@
/**
* @file mouse.h
*
*/
#ifndef MOUSE_H
#define MOUSE_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_MOUSE
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#ifndef MONITOR_SDL_INCLUDE_PATH
#define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
#endif
#include MONITOR_SDL_INCLUDE_PATH
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the mouse
*/
void mouse_init(void);
/**
* Get the current position and state of the mouse
* @param indev_drv pointer to the related input device driver
* @param data store the mouse data here
* @return false: because the points are not buffered, so no more data to be read
*/
bool mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
/**
* It will be called from the main SDL thread
*/
void mouse_handler(SDL_Event *event);
/**********************
* MACROS
**********************/
#endif /* USE_MOUSE */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* MOUSE_H */

View File

@ -0,0 +1,100 @@
/**
* @file mousewheel.c
*
*/
/*********************
* INCLUDES
*********************/
#include "mousewheel.h"
#if USE_MOUSEWHEEL
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static int16_t enc_diff = 0;
static lv_indev_state_t state = LV_INDEV_STATE_REL;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the mousewheel
*/
void mousewheel_init(void)
{
/*Nothing to init*/
}
/**
* Get encoder (i.e. mouse wheel) ticks difference and pressed state
* @param indev_drv pointer to the related input device driver
* @param data store the read data here
* @return false: all ticks and button state are handled
*/
bool mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
(void) indev_drv; /*Unused*/
data->state = state;
data->enc_diff = enc_diff;
enc_diff = 0;
return false; /*No more data to read so return false*/
}
/**
* It is called periodically from the SDL thread to check mouse wheel state
* @param event describes the event
*/
void mousewheel_handler(SDL_Event * event)
{
switch(event->type) {
case SDL_MOUSEWHEEL:
// Scroll down (y = -1) means positive encoder turn,
// so invert it
#ifdef __EMSCRIPTEN__
/*Escripten scales it wrong*/
if(event->wheel.y < 0) enc_diff++;
if(event->wheel.y > 0) enc_diff--;
#else
enc_diff = -event->wheel.y;
#endif
break;
case SDL_MOUSEBUTTONDOWN:
if(event->button.button == SDL_BUTTON_MIDDLE) {
state = LV_INDEV_STATE_PR;
}
break;
case SDL_MOUSEBUTTONUP:
if(event->button.button == SDL_BUTTON_MIDDLE) {
state = LV_INDEV_STATE_REL;
}
break;
default:
break;
}
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif

View File

@ -0,0 +1,79 @@
/**
* @file mousewheel.h
*
*/
#ifndef MOUSEWHEEL_H
#define MOUSEWHEEL_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_MOUSEWHEEL
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#ifndef MONITOR_SDL_INCLUDE_PATH
#define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
#endif
#include MONITOR_SDL_INCLUDE_PATH
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the encoder
*/
void mousewheel_init(void);
/**
* Get encoder (i.e. mouse wheel) ticks difference and pressed state
* @param indev_drv pointer to the related input device driver
* @param data store the read data here
* @return false: all ticks and button state are handled
*/
bool mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
/**
* It is called periodically from the SDL thread to check a key is pressed/released
* @param event describes the event
*/
void mousewheel_handler(SDL_Event *event);
/**********************
* MACROS
**********************/
#endif /*USE_MOUSEWHEEL*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*MOUSEWHEEL_H*/

View File

@ -0,0 +1,13 @@
{
"name": "lv_drivers",
"version": "6.0.2",
"keywords": "littlevgl, lvgl, driver, display, touchpad",
"description": "Drivers for LittlevGL graphics library.",
"repository": {
"type": "git",
"url": "https://github.com/littlevgl/lv_drivers.git"
},
"build": {
"includeDir": "."
}
}

View File

@ -0,0 +1,10 @@
include $(LVGL_DIR)/lv_drivers/display/display.mk
include $(LVGL_DIR)/lv_drivers/indev/indev.mk
CSRCS += win_drv.c
DEPPATH += --dep-path $(LVGL_DIR)/lv_drivers
VPATH += :$(LVGL_DIR)/lv_drivers
CFLAGS += "-I$(LVGL_DIR)/lv_drivers"

View File

@ -0,0 +1,357 @@
/**
* @file lv_drv_conf.h
*
*/
/*
* COPY THIS FILE AS lv_drv_conf.h
*/
#if 0 /*Set it to "1" to enable the content*/
#ifndef LV_DRV_CONF_H
#define LV_DRV_CONF_H
#include "lv_conf.h"
/*********************
* DELAY INTERFACE
*********************/
#define LV_DRV_DELAY_INCLUDE <stdint.h> /*Dummy include by default*/
#define LV_DRV_DELAY_US(us) /*delay_us(us)*/ /*Delay the given number of microseconds*/
#define LV_DRV_DELAY_MS(ms) /*delay_ms(ms)*/ /*Delay the given number of milliseconds*/
/*********************
* DISPLAY INTERFACE
*********************/
/*------------
* Common
*------------*/
#define LV_DRV_DISP_INCLUDE <stdint.h> /*Dummy include by default*/
#define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/
#define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/
/*---------
* SPI
*---------*/
#define LV_DRV_DISP_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/
#define LV_DRV_DISP_SPI_WR_BYTE(data) /*spi_wr(data)*/ /*Write a byte the SPI bus*/
#define LV_DRV_DISP_SPI_WR_ARRAY(adr, n) /*spi_wr_mem(adr, n)*/ /*Write 'n' bytes to SPI bus from 'adr'*/
/*------------------
* Parallel port
*-----------------*/
#define LV_DRV_DISP_PAR_CS(val) /*par_cs_set(val)*/ /*Set the Parallel port's Chip select to 'val'*/
#define LV_DRV_DISP_PAR_SLOW /*par_slow()*/ /*Set low speed on the parallel port*/
#define LV_DRV_DISP_PAR_FAST /*par_fast()*/ /*Set high speed on the parallel port*/
#define LV_DRV_DISP_PAR_WR_WORD(data) /*par_wr(data)*/ /*Write a word to the parallel port*/
#define LV_DRV_DISP_PAR_WR_ARRAY(adr, n) /*par_wr_mem(adr,n)*/ /*Write 'n' bytes to Parallel ports from 'adr'*/
/***************************
* INPUT DEVICE INTERFACE
***************************/
/*----------
* Common
*----------*/
#define LV_DRV_INDEV_INCLUDE <stdint.h> /*Dummy include by default*/
#define LV_DRV_INDEV_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/
#define LV_DRV_INDEV_IRQ_READ 0 /*pn_x_read()*/ /*Read the IRQ pin*/
/*---------
* SPI
*---------*/
#define LV_DRV_INDEV_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/
#define LV_DRV_INDEV_SPI_XCHG_BYTE(data) 0 /*spi_xchg(val)*/ /*Write 'val' to SPI and give the read value*/
/*---------
* I2C
*---------*/
#define LV_DRV_INDEV_I2C_START /*i2c_start()*/ /*Make an I2C start*/
#define LV_DRV_INDEV_I2C_STOP /*i2c_stop()*/ /*Make an I2C stop*/
#define LV_DRV_INDEV_I2C_RESTART /*i2c_restart()*/ /*Make an I2C restart*/
#define LV_DRV_INDEV_I2C_WR(data) /*i2c_wr(data)*/ /*Write a byte to the I1C bus*/
#define LV_DRV_INDEV_I2C_READ(last_read) 0 /*i2c_rd()*/ /*Read a byte from the I2C bud*/
/*********************
* DISPLAY DRIVERS
*********************/
/*-------------------
* Monitor of PC
*-------------------*/
#ifndef USE_MONITOR
# define USE_MONITOR 0
#endif
#if USE_MONITOR
# define MONITOR_HOR_RES LV_HOR_RES
# define MONITOR_VER_RES LV_VER_RES
/* Scale window by this factor (useful when simulating small screens) */
# define MONITOR_ZOOM 1
/* Used to test true double buffering with only address changing.
* Set LV_VDB_SIZE = (LV_HOR_RES * LV_VER_RES) and LV_VDB_DOUBLE = 1 and LV_COLOR_DEPTH = 32" */
# define MONITOR_DOUBLE_BUFFERED 0
/*Eclipse: <SDL2/SDL.h> Visual Studio: <SDL.h>*/
# define MONITOR_SDL_INCLUDE_PATH <SDL2/SDL.h>
/*Different rendering might be used if running in a Virtual machine*/
# define MONITOR_VIRTUAL_MACHINE 0
/*Open two windows to test multi display support*/
# define MONITOR_DUAL 0
#endif
/*-----------------------------------
* Native Windows (including mouse)
*----------------------------------*/
#ifndef USE_WINDOWS
# define USE_WINDOWS 0
#endif
#define USE_WINDOWS 0
#if USE_WINDOWS
# define WINDOW_HOR_RES 480
# define WINDOW_VER_RES 320
#endif
/*----------------
* SSD1963
*--------------*/
#ifndef USE_SSD1963
# define USE_SSD1963 0
#endif
#if USE_SSD1963
# define SSD1963_HOR_RES LV_HOR_RES
# define SSD1963_VER_RES LV_VER_RES
# define SSD1963_HT 531
# define SSD1963_HPS 43
# define SSD1963_LPS 8
# define SSD1963_HPW 10
# define SSD1963_VT 288
# define SSD1963_VPS 12
# define SSD1963_FPS 4
# define SSD1963_VPW 10
# define SSD1963_HS_NEG 0 /*Negative hsync*/
# define SSD1963_VS_NEG 0 /*Negative vsync*/
# define SSD1963_ORI 0 /*0, 90, 180, 270*/
# define SSD1963_COLOR_DEPTH 16
#endif
/*----------------
* R61581
*--------------*/
#ifndef USE_R61581
# define USE_R61581 0
#endif
#if USE_R61581
# define R61581_HOR_RES LV_HOR_RES
# define R61581_VER_RES LV_VER_RES
# define R61581_HSPL 0 /*HSYNC signal polarity*/
# define R61581_HSL 10 /*HSYNC length (Not Implemented)*/
# define R61581_HFP 10 /*Horitontal Front poarch (Not Implemented)*/
# define R61581_HBP 10 /*Horitontal Back poarch (Not Implemented */
# define R61581_VSPL 0 /*VSYNC signal polarity*/
# define R61581_VSL 10 /*VSYNC length (Not Implemented)*/
# define R61581_VFP 8 /*Vertical Front poarch*/
# define R61581_VBP 8 /*Vertical Back poarch */
# define R61581_DPL 0 /*DCLK signal polarity*/
# define R61581_EPL 1 /*ENABLE signal polarity*/
# define R61581_ORI 0 /*0, 180*/
# define R61581_LV_COLOR_DEPTH 16 /*Fix 16 bit*/
#endif
/*------------------------------
* ST7565 (Monochrome, low res.)
*-----------------------------*/
#ifndef USE_ST7565
# define USE_ST7565 0
#endif
#if USE_ST7565
/*No settings*/
#endif /*USE_ST7565*/
/*------------------------------------------
* UC1610 (4 gray 160*[104|128])
* (EA DOGXL160 160x104 tested)
*-----------------------------------------*/
#ifndef USE_UC1610
# define USE_UC1610 0
#endif
#if USE_UC1610
# define UC1610_HOR_RES LV_HOR_RES
# define UC1610_VER_RES LV_VER_RES
# define UC1610_INIT_CONTRAST 33 /* init contrast, values in [%] */
# define UC1610_INIT_HARD_RST 0 /* 1 : hardware reset at init, 0 : software reset */
# define UC1610_TOP_VIEW 0 /* 0 : Bottom View, 1 : Top View */
#endif /*USE_UC1610*/
/*-------------------------------------------------
* SHARP memory in pixel monochrome display series
* LS012B7DD01 (184x38 pixels.)
* LS013B7DH03 (128x128 pixels.)
* LS013B7DH05 (144x168 pixels.)
* LS027B7DH01 (400x240 pixels.) (tested)
* LS032B7DD02 (336x536 pixels.)
* LS044Q7DH01 (320x240 pixels.)
*------------------------------------------------*/
#ifndef USE_SHARP_MIP
# define USE_SHARP_MIP 0
#endif
#if USE_SHARP_MIP
# define SHARP_MIP_HOR_RES LV_HOR_RES
# define SHARP_MIP_VER_RES LV_VER_RES
# define SHARP_MIP_SOFT_COM_INVERSION 0
# define SHARP_MIP_REV_BYTE(b) /*((uint8_t) __REV(__RBIT(b)))*/ /*Architecture / compiler dependent byte bits order reverse*/
#endif /*USE_SHARP_MIP*/
/*-----------------------------------------
* Linux frame buffer device (/dev/fbx)
*-----------------------------------------*/
#ifndef USE_FBDEV
# define USE_FBDEV 0
#endif
#if USE_FBDEV
# define FBDEV_PATH "/dev/fb0"
#endif
/*-----------------------------------------
* FreeBSD frame buffer device (/dev/fbx)
*.........................................*/
#ifndef USE_BSD_FBDEV
# define USE_BSD_FBDEV 0
#endif
#if USE_BSD_FBDEV
# define FBDEV_PATH "/dev/fb0"
#endif
/*********************
* INPUT DEVICES
*********************/
/*--------------
* XPT2046
*--------------*/
#ifndef USE_XPT2046
# define USE_XPT2046 0
#endif
#if USE_XPT2046
# define XPT2046_HOR_RES 480
# define XPT2046_VER_RES 320
# define XPT2046_X_MIN 200
# define XPT2046_Y_MIN 200
# define XPT2046_X_MAX 3800
# define XPT2046_Y_MAX 3800
# define XPT2046_AVG 4
# define XPT2046_INV 0
#endif
/*-----------------
* FT5406EE8
*-----------------*/
#ifndef USE_FT5406EE8
# define USE_FT5406EE8 0
#endif
#if USE_FT5406EE8
# define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/
#endif
/*---------------
* AD TOUCH
*--------------*/
#ifndef USE_AD_TOUCH
# define USE_AD_TOUCH 0
#endif
#if USE_AD_TOUCH
/*No settings*/
#endif
/*---------------------------------------
* Mouse or touchpad on PC (using SDL)
*-------------------------------------*/
#ifndef USE_MOUSE
# define USE_MOUSE 0
#endif
#if USE_MOUSE
/*No settings*/
#endif
/*-------------------------------------------
* Mousewheel as encoder on PC (using SDL)
*------------------------------------------*/
#ifndef USE_MOUSEWHEEL
# define USE_MOUSEWHEEL 0
#endif
#if USE_MOUSEWHEEL
/*No settings*/
#endif
/*-------------------------------------------------
* Touchscreen as libinput interface (for Linux based systems)
*------------------------------------------------*/
#ifndef USE_LIBINPUT
# define USE_LIBINPUT 0
#endif
#if USE_LIBINPUT
# define LIBINPUT_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/
#endif /*USE_LIBINPUT*/
/*-------------------------------------------------
* Mouse or touchpad as evdev interface (for Linux based systems)
*------------------------------------------------*/
#ifndef USE_EVDEV
# define USE_EVDEV 0
#endif
#if USE_EVDEV
# define EVDEV_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/
# define EVDEV_SWAP_AXES 0 /*Swap the x and y axes of the touchscreen*/
# define EVDEV_SCALE 0 /* Scale input, e.g. if touchscreen resolution does not match display resolution */
# if EVDEV_SCALE
# define EVDEV_SCALE_HOR_RES (4096) /* Horizontal resolution of touchscreen */
# define EVDEV_SCALE_VER_RES (4096) /* Vertical resolution of touchscreen */
# endif /*EVDEV_SCALE*/
# define EVDEV_CALIBRATE 0 /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/
# if EVDEV_CALIBRATE
# define EVDEV_HOR_MIN 3800 /*If EVDEV_XXX_MIN > EVDEV_XXX_MAX the XXX axis is automatically inverted*/
# define EVDEV_HOR_MAX 200
# define EVDEV_VER_MIN 200
# define EVDEV_VER_MAX 3800
# endif /*EVDEV_SCALE*/
#endif /*USE_EVDEV*/
/*-------------------------------
* Keyboard of a PC (using SDL)
*------------------------------*/
#ifndef USE_KEYBOARD
# define USE_KEYBOARD 0
#endif
#if USE_KEYBOARD
/*No settings*/
#endif
#endif /*LV_DRV_CONF_H*/
#endif /*End of "Content enable"*/

318
lib/lv_drivers/win_drv.c Normal file
View File

@ -0,0 +1,318 @@
/**
* @file win_drv.c
*
*/
/*********************
* INCLUDES
*********************/
#include "win_drv.h"
#if USE_WINDOWS
#include <windows.h>
#include <windowsx.h>
#include "lvgl/lvgl.h"
#if LV_COLOR_DEPTH < 16
#error Windows driver only supports true RGB colors at this time
#endif
/**********************
* DEFINES
**********************/
#define WINDOW_STYLE (WS_OVERLAPPEDWINDOW & ~(WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME))
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void do_register(void);
static void win_drv_flush(lv_disp_t *drv, lv_area_t *area, const lv_color_t * color_p);
static void win_drv_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
static void win_drv_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
static bool win_drv_read(lv_indev_t *drv, lv_indev_data_t * data);
static void msg_handler(void *param);
static COLORREF lv_color_to_colorref(const lv_color_t color);
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
/**********************
* GLOBAL VARIABLES
**********************/
bool lv_win_exit_flag = false;
lv_disp_t *lv_windows_disp;
/**********************
* STATIC VARIABLES
**********************/
static HWND hwnd;
static uint32_t *fbp = NULL; /* Raw framebuffer memory */
static bool mouse_pressed;
static int mouse_x, mouse_y;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
const char g_szClassName[] = "LittlevGL";
HWND windrv_init(void)
{
WNDCLASSEX wc;
RECT winrect;
HICON lvgl_icon;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
lvgl_icon = (HICON) LoadImage( NULL, "lvgl_icon.bmp", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
if(lvgl_icon == NULL)
lvgl_icon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIcon = lvgl_icon;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = lvgl_icon;
if(!RegisterClassEx(&wc))
{
return NULL;
}
winrect.left = 0;
winrect.right = WINDOW_HOR_RES - 1;
winrect.top = 0;
winrect.bottom = WINDOW_VER_RES - 1;
AdjustWindowRectEx(&winrect, WINDOW_STYLE, FALSE, WS_EX_CLIENTEDGE);
OffsetRect(&winrect, -winrect.left, -winrect.top);
// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"LittlevGL Simulator",
WINDOW_STYLE,
CW_USEDEFAULT, CW_USEDEFAULT, winrect.right, winrect.bottom,
NULL, NULL, GetModuleHandle(NULL), NULL);
if(hwnd == NULL)
{
return NULL;
}
ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);
lv_task_create(msg_handler, 0, LV_TASK_PRIO_HIGHEST, NULL);
lv_win_exit_flag = false;
do_register();
}
/**********************
* STATIC FUNCTIONS
**********************/
static void do_register(void)
{
/*-----------------------------
* Create a buffer for drawing
*----------------------------*/
/* LittlevGL requires a buffer where it draw the objects. The buffer's has to be greater than 1 display row
*
* There are three buffering configurations:
* 1. Create ONE buffer some rows: LittlevGL will draw the display's content here and writes it to your display
* 2. Create TWO buffer some rows: LittlevGL will draw the display's content to a buffer and writes it your display.
* You should use DMA to write the buffer's content to the display.
* It will enable LittlevGL to draw the next part of the screen to the other buffer while
* the data is being sent form the first buffer. It makes rendering and flushing parallel.
* 3. Create TWO screen buffer: Similar to 2) but the buffer have to be screen sized. When LittlevGL is ready it will give the
* whole frame to display. This way you only need to change the frame buffer's address instead of
* copying the pixels.
* */
/* Example for 1) */
static lv_disp_buf_t disp_buf_1;
static lv_color_t buf1_1[WINDOW_HOR_RES * WINDOW_VER_RES]; /*A buffer for 10 rows*/
lv_disp_buf_init(&disp_buf_1, buf1_1, NULL, WINDOW_HOR_RES * WINDOW_VER_RES); /*Initialize the display buffer*/
/*-----------------------------------
* Register the display in LittlevGL
*----------------------------------*/
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set up the functions to access to your display*/
/*Set the resolution of the display*/
disp_drv.hor_res = WINDOW_HOR_RES;
disp_drv.ver_res = WINDOW_VER_RES;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = win_drv_flush;
/*Set a display buffer*/
disp_drv.buffer = &disp_buf_1;
/*Finally register the driver*/
lv_windows_disp = lv_disp_drv_register(&disp_drv);
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = win_drv_read;
lv_indev_drv_register(&indev_drv);
}
static void msg_handler(void *param)
{
(void)param;
MSG msg;
BOOL bRet;
if( (bRet = PeekMessage( &msg, NULL, 0, 0, TRUE )) != 0)
{
if (bRet == -1)
{
return;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
if(msg.message == WM_QUIT)
lv_win_exit_flag = true;
}
static bool win_drv_read(lv_indev_t *drv, lv_indev_data_t * data)
{
data->state = mouse_pressed ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
data->point.x = mouse_x;
data->point.y = mouse_y;
return false;
}
static void on_paint(void)
{
HBITMAP bmp = CreateBitmap(WINDOW_HOR_RES, WINDOW_VER_RES, 1, 32, fbp);
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = SelectObject(hdcMem, bmp);
BitBlt(hdc, 0, 0, WINDOW_HOR_RES, WINDOW_VER_RES, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
DeleteObject(bmp);
}
/**
* Flush a buffer to the marked area
* @param x1 left coordinate
* @param y1 top coordinate
* @param x2 right coordinate
* @param y2 bottom coordinate
* @param color_p an array of colors
*/
static void win_drv_flush(lv_disp_t *drv, lv_area_t *area, const lv_color_t * color_p)
{
win_drv_map(area->x1, area->y1, area->x2, area->y2, color_p);
lv_disp_flush_ready(drv);
}
/**
* Put a color map to the marked area
* @param x1 left coordinate
* @param y1 top coordinate
* @param x2 right coordinate
* @param y2 bottom coordinate
* @param color_p an array of colors
*/
static void win_drv_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p)
{
for(int y = y1; y <= y2; y++)
{
for(int x = x1; x <= x2; x++)
{
fbp[y*WINDOW_HOR_RES+x] = lv_color_to32(*color_p);
color_p++;
}
}
InvalidateRect(hwnd, NULL, FALSE);
UpdateWindow(hwnd);
}
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch(msg) {
case WM_CREATE:
fbp = malloc(4*WINDOW_HOR_RES*WINDOW_VER_RES);
if(fbp == NULL)
return 1;
return 0;
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
mouse_x = GET_X_LPARAM(lParam);
mouse_y = GET_Y_LPARAM(lParam);
if(msg == WM_LBUTTONDOWN || msg == WM_LBUTTONUP) {
mouse_pressed = (msg == WM_LBUTTONDOWN);
}
return 0;
case WM_CLOSE:
free(fbp);
fbp = NULL;
DestroyWindow(hwnd);
return 0;
case WM_PAINT:
on_paint();
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
static COLORREF lv_color_to_colorref(const lv_color_t color)
{
uint32_t raw_color = lv_color_to32(color);
lv_color32_t tmp;
tmp.full = raw_color;
uint32_t colorref = RGB(tmp.ch.red, tmp.ch.green, tmp.ch.blue);
return colorref;
}
#endif

60
lib/lv_drivers/win_drv.h Normal file
View File

@ -0,0 +1,60 @@
/**
* @file fbdev.h
*
*/
#ifndef WINDRV_H
#define WINDRV_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_WINDOWS
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#include <windows.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
extern bool lv_win_exit_flag;
extern lv_disp_t *lv_windows_disp;
HWND windrv_init(void);
/**********************
* MACROS
**********************/
#endif /*USE_WINDOWS*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*WIN_DRV_H*/

View File

@ -69,6 +69,7 @@ build_flags =
;-w ; Suppress warnings ;-w ; Suppress warnings
-D CORE_DEBUG_LEVEL=1 ; Errors -D CORE_DEBUG_LEVEL=1 ; Errors
-D LV_CONF_INCLUDE_SIMPLE -D LV_CONF_INCLUDE_SIMPLE
-D LV_LVGL_H_INCLUDE_SIMPLE ; for lv_drivers
-D SPIFFS_TEMPORAL_FD_CACHE ; speedup opening recent files -D SPIFFS_TEMPORAL_FD_CACHE ; speedup opening recent files
-D ARDUINOJSON_DECODE_UNICODE=1 ; for utf-8 symbols -D ARDUINOJSON_DECODE_UNICODE=1 ; for utf-8 symbols
-D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments

View File

@ -3,11 +3,21 @@
#include "lv_conf.h" #include "lv_conf.h"
#include "lvgl.h" #include "lvgl.h"
// Display Driver
#include "lv_drv_conf.h"
#include "display/tft_espi_drv.h"
#include "display/fsmc_ili9341.h"
// Touch Driver
// Filesystem Driver
#include "lv_fs_if.h" #include "lv_fs_if.h"
#include "TFT_eSPI.h"
//#include "TFT_eSPI.h"
//#include "lv_zifont.h" //#include "lv_zifont.h"
#include "hasp_tft.h" //#include "hasp_tft.h"
#include "hasp_debug.h" #include "hasp_debug.h"
#include "hasp_config.h" #include "hasp_config.h"
#include "hasp_dispatch.h" #include "hasp_dispatch.h"
@ -82,7 +92,7 @@ static Ticker tick; /* timer for interrupt handler */
#else #else
static Ticker tick(lv_tick_handler, guiTickPeriod); static Ticker tick(lv_tick_handler, guiTickPeriod);
#endif #endif
static TFT_eSPI tft; // = TFT_eSPI(); /* TFT instance */ // static TFT_eSPI tft; // = TFT_eSPI(); /* TFT instance */
static uint16_t calData[5] = {0, 65535, 0, 65535, 0}; static uint16_t calData[5] = {0, 65535, 0, 65535, 0};
static bool guiCheckSleep() static bool guiCheckSleep()
@ -195,8 +205,9 @@ static void gui_take_screenshot(uint8_t * data_p, size_t len)
} }
/* Experimetnal Display flushing */ /* Experimetnal Display flushing */
static void IRAM_ATTR tft_espi_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) static void IRAM_ATTR tft_espi_flush_cb(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p)
{ {
#if 0
size_t len = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1); /* Number of pixels */ size_t len = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1); /* Number of pixels */
/* Update TFT */ /* Update TFT */
@ -209,6 +220,9 @@ static void IRAM_ATTR tft_espi_flush(lv_disp_drv_t * disp, const lv_area_t * are
if(guiSnapshot != 0) { if(guiSnapshot != 0) {
gui_take_screenshot((uint8_t *)color_p, len * sizeof(lv_color_t)); /* Number of bytes */ gui_take_screenshot((uint8_t *)color_p, len * sizeof(lv_color_t)); /* Number of bytes */
} }
#endif
fsmc_ili9341_flush(area->x1, area->y1, area->x2, area->y2, color_p);
/* Tell lvgl that flushing is done */ /* Tell lvgl that flushing is done */
lv_disp_flush_ready(disp); lv_disp_flush_ready(disp);
@ -555,14 +569,14 @@ bool IRAM_ATTR my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t *
{ {
//#ifdef TOUCH_CS //#ifdef TOUCH_CS
uint16_t touchX, touchY; uint16_t touchX, touchY;
bool touched;
#if TOUCH_DRIVER == 0 #if TOUCH_DRIVER == 0
bool touched = tft.getTouch(&touchX, &touchY, 600); // touched = tft.getTouch(&touchX, &touchY, 600);
#elif TOUCH_DRIVER == 1 #elif TOUCH_DRIVER == 1
// return false; // return false;
bool touched = GT911_getXY(&touchX, &touchY, true); touched = GT911_getXY(&touchX, &touchY, true);
#else #else
bool touched = Touch_getXY(&touchX, &touchY, false); touched = Touch_getXY(&touchX, &touchY, false);
#endif #endif
if(!touched) return false; if(!touched) return false;
@ -571,21 +585,21 @@ bool IRAM_ATTR my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t *
// Ignore first press? // Ignore first press?
if(touchX > tft.width() || touchY > tft.height()) { // if(touchX > tft.width() || touchY > tft.height()) {
Serial.print(F("Y or y outside of expected parameters.. x: ")); // Serial.print(F("Y or y outside of expected parameters.. x: "));
Serial.print(touchX); // Serial.print(touchX);
Serial.print(F(" / y: ")); // Serial.print(F(" / y: "));
Serial.println(touchY); // Serial.println(touchY);
} else { // } else {
/*Save the state and save the pressed coordinate*/ /*Save the state and save the pressed coordinate*/
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
data->point.x = touchX; data->point.x = touchX;
data->point.y = touchY; data->point.y = touchY;
/* Serial.print("Data x"); /* Serial.print("Data x");
Serial.println(touchX); Serial.println(touchX);
Serial.print("Data y"); Serial.print("Data y");
Serial.println(touchY);*/ Serial.println(touchY);*/
} //}
//#endif //#endif
return false; /*Return `false` because we are not buffering and no more data to read*/ return false; /*Return `false` because we are not buffering and no more data to read*/
@ -593,7 +607,7 @@ bool IRAM_ATTR my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t *
void guiCalibrate() void guiCalibrate()
{ {
#if TOUCH_DRIVER == 0 #if TOUCH_DRIVER == 0 && 0
tft.fillScreen(TFT_BLACK); tft.fillScreen(TFT_BLACK);
tft.setCursor(20, 0); tft.setCursor(20, 0);
tft.setTextFont(1); tft.setTextFont(1);
@ -620,6 +634,8 @@ void guiCalibrate()
void guiSetup() void guiSetup()
{ {
/* TFT init */ /* TFT init */
tft_espi_init(guiRotation);
#if 0
tft.begin(); tft.begin();
tft.setSwapBytes(true); /* set endianess */ tft.setSwapBytes(true); /* set endianess */
@ -632,6 +648,7 @@ void guiSetup()
tft.setRotation(guiRotation); /* 1/3=Landscape or 0/2=Portrait orientation */ tft.setRotation(guiRotation); /* 1/3=Landscape or 0/2=Portrait orientation */
#if TOUCH_DRIVER == 0 #if TOUCH_DRIVER == 0
tft.setTouch(calData); tft.setTouch(calData);
#endif
#endif #endif
/* Initialize the Virtual Device Buffers */ /* Initialize the Virtual Device Buffers */
@ -675,7 +692,7 @@ void guiSetup()
#endif #endif
/* Dump TFT Configuration */ /* Dump TFT Configuration */
tftSetup(tft); // tftSetup(tft);
#ifdef USE_DMA_TO_TFT #ifdef USE_DMA_TO_TFT
Log.verbose(F("TFT: DMA : ENABELD")); Log.verbose(F("TFT: DMA : ENABELD"));
#else #else
@ -715,7 +732,7 @@ void guiSetup()
/* Initialize the display driver */ /* Initialize the display driver */
lv_disp_drv_t disp_drv; lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv); lv_disp_drv_init(&disp_drv);
disp_drv.flush_cb = tft_espi_flush; disp_drv.flush_cb = tft_espi_flush_cb;
disp_drv.buffer = &disp_buf; disp_drv.buffer = &disp_buf;
if(guiRotation == 0 || guiRotation == 2 || guiRotation == 4 || guiRotation == 6) { if(guiRotation == 0 || guiRotation == 2 || guiRotation == 4 || guiRotation == 6) {
/* 1/3=Landscape or 0/2=Portrait orientation */ /* 1/3=Landscape or 0/2=Portrait orientation */
@ -912,7 +929,9 @@ bool guiGetConfig(const JsonObject & settings)
v.set(calData[i]); v.set(calData[i]);
} else { } else {
changed = true; changed = true;
#if 0
tft.setTouch(calData); tft.setTouch(calData);
#endif
} }
i++; i++;
} }
@ -924,7 +943,9 @@ bool guiGetConfig(const JsonObject & settings)
array.add(calData[i]); array.add(calData[i]);
} }
changed = true; changed = true;
#if 0
tft.setTouch(calData); tft.setTouch(calData);
#endif
} }
if(changed) configOutput(settings); if(changed) configOutput(settings);
@ -981,7 +1002,9 @@ bool guiSetConfig(const JsonObject & settings)
oobeSetAutoCalibrate(true); oobeSetAutoCalibrate(true);
} }
#if 0
if(status) tft.setTouch(calData); if(status) tft.setTouch(calData);
#endif
changed |= status; changed |= status;
} }

View File

@ -0,0 +1,54 @@
;***************************************************;
; STM32F4xx build with ;
; - STM32F407VET6 black board ;
; - FSMC 16 bit ili9341 TFT ;
; - xpt2046 touch controller ;
;***************************************************;
[env:STM32F407VET6_black_fsmc]
platform = ststm32
board = black_f407ve
;board_build.mcu = stm32f407vet6
; upload_protocol = dfu
upload_protocol = stlink
debug_tool = stlink
monitor_port = COM19 ; To change the port, use platform_override.ini
build_flags =
${env.build_flags}
${flags.stm32_flags}
-I include/stm32f4
-I include/GxTFT/src
-I include/GxTFT/src/GxCTRL/GxCTRL_ILI9341
; -- TFT_eSPI build options ------------------------
-D ILI9341_DRIVER=1
-D TFT_WIDTH=240
-D TFT_HEIGHT=320
-D USER_SETUP_LOADED=1
-D TOUCH_CS=PA6 ;NC
-D TFT_RST=-1 ;D4
-D STM32
-D TFT_SPI3
-D USE_DMA_TO_TFT
-D HASP_USE_TASMOTA_SLAVE=1
-D HASP_OUTPUT_PIN=PA1 ; User LED D2 on DevEBox board
-D HASP_INPUT_PIN=PA0 ; User Button K1 on DevEBox board
-D STM32_SERIAL1 ; Set this option to use Serial1 as default sersial port, leave out if using Serial2
-D HASP_USE_ETHERNET=1
-D USE_BUILTIN_ETHERNET=1
-D HAL_ETH_MODULE_ENABLED=1
; -D LAN8742A_PHY_ADDRESS=0x01U ; moved to include\stm32f4\hal_conf_custom.h
; -D DP83848_PHY_ADDRESS=0x01U
lib_deps =
${env.lib_deps}
Ticker@^3.1.5
; STM32duino LwIP@^2.1.2
; STM32duino STM32Ethernet@^1.0.5
https://github.com/stm32duino/LwIP.git
https://github.com/stm32duino/STM32Ethernet.git
https://github.com/khoih-prog/EthernetWebServer_STM32
Adafruit GFX Library@^1.7.5
;https://github.com/ZinggJM/GxTFT.git
XPT2046_Touchscreen
src_filter = +<*> -<.git/> -<.svn/> -<example/> -<examples/> -<test/> -<tests/> -<lv_lib_zifont/> +<stm32f4/>