chore(examples): add submodule and remove LVGL examples
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
|||||||
[submodule "TFT_eSPI"]
|
[submodule "TFT_eSPI"]
|
||||||
path = TFT_eSPI
|
path = TFT_eSPI
|
||||||
url = https://github.com/Cincinnatu/TFT_eSPI
|
url = https://github.com/Cincinnatu/TFT_eSPI
|
||||||
|
[submodule "examples/Waveshare-ESP32-S3-Touch-LCD-4.3-and-Arduino"]
|
||||||
|
path = examples/Waveshare-ESP32-S3-Touch-LCD-4.3-and-Arduino
|
||||||
|
url = https://github.com/Westcott1/Waveshare-ESP32-S3-Touch-LCD-4.3-and-Arduino.git
|
||||||
|
|||||||
@@ -1,243 +0,0 @@
|
|||||||
#include "Display_ST7789.h"
|
|
||||||
|
|
||||||
#define SPI_WRITE(_dat) SPI.transfer(_dat)
|
|
||||||
#define SPI_WRITE_Word(_dat) SPI.transfer16(_dat)
|
|
||||||
void SPI_Init()
|
|
||||||
{
|
|
||||||
SPI.begin(EXAMPLE_PIN_NUM_SCLK,EXAMPLE_PIN_NUM_MISO,EXAMPLE_PIN_NUM_MOSI);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LCD_WriteCommand(uint8_t Cmd)
|
|
||||||
{
|
|
||||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, LOW);
|
|
||||||
SPI_WRITE(Cmd);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
|
||||||
SPI.endTransaction();
|
|
||||||
}
|
|
||||||
void LCD_WriteData(uint8_t Data)
|
|
||||||
{
|
|
||||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
|
||||||
SPI_WRITE(Data);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
|
||||||
SPI.endTransaction();
|
|
||||||
}
|
|
||||||
void LCD_WriteData_Word(uint16_t Data)
|
|
||||||
{
|
|
||||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
|
||||||
SPI_WRITE_Word(Data);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
|
||||||
SPI.endTransaction();
|
|
||||||
}
|
|
||||||
void LCD_WriteData_nbyte(uint8_t* SetData,uint8_t* ReadData,uint32_t Size)
|
|
||||||
{
|
|
||||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
|
||||||
SPI.transferBytes(SetData, ReadData, Size);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
|
||||||
SPI.endTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LCD_Reset(void)
|
|
||||||
{
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
|
||||||
delay(50);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_RST, LOW);
|
|
||||||
delay(50);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_RST, HIGH);
|
|
||||||
delay(50);
|
|
||||||
}
|
|
||||||
void LCD_Init(void)
|
|
||||||
{
|
|
||||||
pinMode(EXAMPLE_PIN_NUM_LCD_CS, OUTPUT);
|
|
||||||
pinMode(EXAMPLE_PIN_NUM_LCD_DC, OUTPUT);
|
|
||||||
pinMode(EXAMPLE_PIN_NUM_LCD_RST, OUTPUT);
|
|
||||||
Backlight_Init();
|
|
||||||
SPI_Init();
|
|
||||||
|
|
||||||
LCD_Reset();
|
|
||||||
//************* Start Initial Sequence **********//
|
|
||||||
LCD_WriteCommand(0x11);
|
|
||||||
delay(120);
|
|
||||||
LCD_WriteCommand(0x36);
|
|
||||||
if (HORIZONTAL)
|
|
||||||
LCD_WriteData(0x00);
|
|
||||||
else
|
|
||||||
LCD_WriteData(0x70);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0x3A);
|
|
||||||
LCD_WriteData(0x05);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xB0);
|
|
||||||
LCD_WriteData(0x00);
|
|
||||||
LCD_WriteData(0xE8);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xB2);
|
|
||||||
LCD_WriteData(0x0C);
|
|
||||||
LCD_WriteData(0x0C);
|
|
||||||
LCD_WriteData(0x00);
|
|
||||||
LCD_WriteData(0x33);
|
|
||||||
LCD_WriteData(0x33);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xB7);
|
|
||||||
LCD_WriteData(0x35);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xBB);
|
|
||||||
LCD_WriteData(0x35);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xC0);
|
|
||||||
LCD_WriteData(0x2C);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xC2);
|
|
||||||
LCD_WriteData(0x01);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xC3);
|
|
||||||
LCD_WriteData(0x13);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xC4);
|
|
||||||
LCD_WriteData(0x20);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xC6);
|
|
||||||
LCD_WriteData(0x0F);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xD0);
|
|
||||||
LCD_WriteData(0xA4);
|
|
||||||
LCD_WriteData(0xA1);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xD6);
|
|
||||||
LCD_WriteData(0xA1);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xE0);
|
|
||||||
LCD_WriteData(0xF0);
|
|
||||||
LCD_WriteData(0x00);
|
|
||||||
LCD_WriteData(0x04);
|
|
||||||
LCD_WriteData(0x04);
|
|
||||||
LCD_WriteData(0x04);
|
|
||||||
LCD_WriteData(0x05);
|
|
||||||
LCD_WriteData(0x29);
|
|
||||||
LCD_WriteData(0x33);
|
|
||||||
LCD_WriteData(0x3E);
|
|
||||||
LCD_WriteData(0x38);
|
|
||||||
LCD_WriteData(0x12);
|
|
||||||
LCD_WriteData(0x12);
|
|
||||||
LCD_WriteData(0x28);
|
|
||||||
LCD_WriteData(0x30);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xE1);
|
|
||||||
LCD_WriteData(0xF0);
|
|
||||||
LCD_WriteData(0x07);
|
|
||||||
LCD_WriteData(0x0A);
|
|
||||||
LCD_WriteData(0x0D);
|
|
||||||
LCD_WriteData(0x0B);
|
|
||||||
LCD_WriteData(0x07);
|
|
||||||
LCD_WriteData(0x28);
|
|
||||||
LCD_WriteData(0x33);
|
|
||||||
LCD_WriteData(0x3E);
|
|
||||||
LCD_WriteData(0x36);
|
|
||||||
LCD_WriteData(0x14);
|
|
||||||
LCD_WriteData(0x14);
|
|
||||||
LCD_WriteData(0x29);
|
|
||||||
LCD_WriteData(0x32);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0x21);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0x11);
|
|
||||||
delay(120);
|
|
||||||
LCD_WriteCommand(0x29);
|
|
||||||
}
|
|
||||||
/******************************************************************************
|
|
||||||
function: Set the cursor position
|
|
||||||
parameter :
|
|
||||||
Xstart: Start uint16_t x coordinate
|
|
||||||
Ystart: Start uint16_t y coordinate
|
|
||||||
Xend : End uint16_t coordinates
|
|
||||||
Yend : End uint16_t coordinatesen
|
|
||||||
******************************************************************************/
|
|
||||||
void LCD_SetCursor(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend)
|
|
||||||
{
|
|
||||||
if (HORIZONTAL) {
|
|
||||||
// set the X coordinates
|
|
||||||
LCD_WriteCommand(0x2A);
|
|
||||||
LCD_WriteData(Xstart >> 8);
|
|
||||||
LCD_WriteData(Xstart + Offset_X);
|
|
||||||
LCD_WriteData(Xend >> 8);
|
|
||||||
LCD_WriteData(Xend + Offset_X);
|
|
||||||
|
|
||||||
// set the Y coordinates
|
|
||||||
LCD_WriteCommand(0x2B);
|
|
||||||
LCD_WriteData(Ystart >> 8);
|
|
||||||
LCD_WriteData(Ystart + Offset_Y);
|
|
||||||
LCD_WriteData(Yend >> 8);
|
|
||||||
LCD_WriteData(Yend + Offset_Y);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// set the X coordinates
|
|
||||||
LCD_WriteCommand(0x2A);
|
|
||||||
LCD_WriteData(Ystart >> 8);
|
|
||||||
LCD_WriteData(Ystart + Offset_Y);
|
|
||||||
LCD_WriteData(Yend >> 8);
|
|
||||||
LCD_WriteData(Yend + Offset_Y);
|
|
||||||
// set the Y coordinates
|
|
||||||
LCD_WriteCommand(0x2B);
|
|
||||||
LCD_WriteData(Xstart >> 8);
|
|
||||||
LCD_WriteData(Xstart + Offset_X);
|
|
||||||
LCD_WriteData(Xend >> 8);
|
|
||||||
LCD_WriteData(Xend + Offset_X);
|
|
||||||
}
|
|
||||||
LCD_WriteCommand(0x2C);
|
|
||||||
}
|
|
||||||
/******************************************************************************
|
|
||||||
function: Refresh the image in an area
|
|
||||||
parameter :
|
|
||||||
Xstart: Start uint16_t x coordinate
|
|
||||||
Ystart: Start uint16_t y coordinate
|
|
||||||
Xend : End uint16_t coordinates
|
|
||||||
Yend : End uint16_t coordinates
|
|
||||||
color : Set the color
|
|
||||||
******************************************************************************/
|
|
||||||
void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint16_t* color)
|
|
||||||
{
|
|
||||||
// uint16_t i,j;
|
|
||||||
// LCD_SetCursor(Xstart, Ystart, Xend,Yend);
|
|
||||||
// uint16_t Show_Width = Xend - Xstart + 1;
|
|
||||||
// uint16_t Show_Height = Yend - Ystart + 1;
|
|
||||||
// for(i = 0; i < Show_Height; i++){
|
|
||||||
// for(j = 0; j < Show_Width; j++){
|
|
||||||
// LCD_WriteData_Word(color[(i*(Show_Width))+j]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
uint16_t Show_Width = Xend - Xstart + 1;
|
|
||||||
uint16_t Show_Height = Yend - Ystart + 1;
|
|
||||||
uint32_t numBytes = Show_Width * Show_Height * sizeof(uint16_t);
|
|
||||||
uint8_t Read_D[numBytes];
|
|
||||||
LCD_SetCursor(Xstart, Ystart, Xend, Yend);
|
|
||||||
LCD_WriteData_nbyte((uint8_t*)color, Read_D, numBytes);
|
|
||||||
}
|
|
||||||
// backlight
|
|
||||||
void Backlight_Init(void)
|
|
||||||
{
|
|
||||||
ledcAttach(EXAMPLE_PIN_NUM_BK_LIGHT, Frequency, Resolution);
|
|
||||||
ledcWrite(EXAMPLE_PIN_NUM_BK_LIGHT, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Set_Backlight(uint8_t Light) //
|
|
||||||
{
|
|
||||||
|
|
||||||
if(Light > 100 || Light < 0)
|
|
||||||
printf("Set Backlight parameters in the range of 0 to 100 \r\n");
|
|
||||||
else{
|
|
||||||
uint32_t Backlight = Light*10;
|
|
||||||
ledcWrite(EXAMPLE_PIN_NUM_BK_LIGHT, Backlight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
#define LCD_WIDTH 172 //LCD width
|
|
||||||
#define LCD_HEIGHT 320 //LCD height
|
|
||||||
|
|
||||||
#define SPIFreq 80000000
|
|
||||||
#define EXAMPLE_PIN_NUM_MISO 5
|
|
||||||
#define EXAMPLE_PIN_NUM_MOSI 6
|
|
||||||
#define EXAMPLE_PIN_NUM_SCLK 7
|
|
||||||
#define EXAMPLE_PIN_NUM_LCD_CS 14
|
|
||||||
#define EXAMPLE_PIN_NUM_LCD_DC 15
|
|
||||||
#define EXAMPLE_PIN_NUM_LCD_RST 21
|
|
||||||
#define EXAMPLE_PIN_NUM_BK_LIGHT 22
|
|
||||||
#define Frequency 1000
|
|
||||||
#define Resolution 10
|
|
||||||
|
|
||||||
#define VERTICAL 0
|
|
||||||
#define HORIZONTAL 1
|
|
||||||
|
|
||||||
#define Offset_X 34
|
|
||||||
#define Offset_Y 0
|
|
||||||
|
|
||||||
|
|
||||||
void LCD_SetCursor(uint16_t x1, uint16_t y1, uint16_t x2,uint16_t y2);
|
|
||||||
|
|
||||||
void LCD_Init(void);
|
|
||||||
void LCD_SetCursor(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend);
|
|
||||||
void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint16_t* color);
|
|
||||||
|
|
||||||
void Backlight_Init(void);
|
|
||||||
void Set_Backlight(uint8_t Light);
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#include "SD_Card.h"
|
|
||||||
#include "Display_ST7789.h"
|
|
||||||
#include "LVGL_Driver.h"
|
|
||||||
#include "LVGL_Example.h"
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Flash_test();
|
|
||||||
LCD_Init();
|
|
||||||
Lvgl_Init();
|
|
||||||
SD_Init();
|
|
||||||
|
|
||||||
Lvgl_Example1();
|
|
||||||
// lv_demo_widgets();
|
|
||||||
// lv_demo_benchmark();
|
|
||||||
// lv_demo_keypad_encoder();
|
|
||||||
// lv_demo_music();
|
|
||||||
// lv_demo_stress();
|
|
||||||
|
|
||||||
Wireless_Test2();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
Timer_Loop();
|
|
||||||
delay(5);
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
| File : LVGL_Driver.c
|
|
||||||
|
|
||||||
| help :
|
|
||||||
The provided LVGL library file must be installed first
|
|
||||||
******************************************************************************/
|
|
||||||
#include "LVGL_Driver.h"
|
|
||||||
|
|
||||||
static lv_disp_draw_buf_t draw_buf;
|
|
||||||
static lv_color_t buf1[ LVGL_BUF_LEN ];
|
|
||||||
static lv_color_t buf2[ LVGL_BUF_LEN ];
|
|
||||||
// static lv_color_t* buf1 = (lv_color_t*) heap_caps_malloc(LVGL_BUF_LEN, MALLOC_CAP_SPIRAM);
|
|
||||||
// static lv_color_t* buf2 = (lv_color_t*) heap_caps_malloc(LVGL_BUF_LEN, MALLOC_CAP_SPIRAM);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Serial debugging */
|
|
||||||
void Lvgl_print(const char * buf)
|
|
||||||
{
|
|
||||||
// Serial.printf(buf);
|
|
||||||
// Serial.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Display flushing
|
|
||||||
Displays LVGL content on the LCD
|
|
||||||
This function implements associating LVGL data to the LCD screen
|
|
||||||
*/
|
|
||||||
void Lvgl_Display_LCD( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p )
|
|
||||||
{
|
|
||||||
LCD_addWindow(area->x1, area->y1, area->x2, area->y2, ( uint16_t *)&color_p->full);
|
|
||||||
lv_disp_flush_ready( disp_drv );
|
|
||||||
}
|
|
||||||
/*Read the touchpad*/
|
|
||||||
void Lvgl_Touchpad_Read( lv_indev_drv_t * indev_drv, lv_indev_data_t * data )
|
|
||||||
{
|
|
||||||
// NULL
|
|
||||||
}
|
|
||||||
void example_increase_lvgl_tick(void *arg)
|
|
||||||
{
|
|
||||||
/* Tell LVGL how many milliseconds has elapsed */
|
|
||||||
lv_tick_inc(EXAMPLE_LVGL_TICK_PERIOD_MS);
|
|
||||||
}
|
|
||||||
void Lvgl_Init(void)
|
|
||||||
{
|
|
||||||
lv_init();
|
|
||||||
lv_disp_draw_buf_init( &draw_buf, buf1, buf2, LVGL_BUF_LEN);
|
|
||||||
|
|
||||||
/*Initialize the display*/
|
|
||||||
static lv_disp_drv_t disp_drv;
|
|
||||||
lv_disp_drv_init( &disp_drv );
|
|
||||||
/*Change the following line to your display resolution*/
|
|
||||||
disp_drv.hor_res = LVGL_WIDTH;
|
|
||||||
disp_drv.ver_res = LVGL_HEIGHT;
|
|
||||||
disp_drv.flush_cb = Lvgl_Display_LCD;
|
|
||||||
disp_drv.full_refresh = 1; /**< 1: Always make the whole screen redrawn*/
|
|
||||||
disp_drv.draw_buf = &draw_buf;
|
|
||||||
lv_disp_drv_register( &disp_drv );
|
|
||||||
|
|
||||||
/*Initialize the (dummy) input device driver*/
|
|
||||||
static lv_indev_drv_t indev_drv;
|
|
||||||
lv_indev_drv_init( &indev_drv );
|
|
||||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
|
||||||
indev_drv.read_cb = Lvgl_Touchpad_Read;
|
|
||||||
lv_indev_drv_register( &indev_drv );
|
|
||||||
|
|
||||||
/* Create simple label */
|
|
||||||
lv_obj_t *label = lv_label_create( lv_scr_act() );
|
|
||||||
lv_label_set_text( label, "Hello Ardino and LVGL!");
|
|
||||||
lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
|
|
||||||
|
|
||||||
const esp_timer_create_args_t lvgl_tick_timer_args = {
|
|
||||||
.callback = &example_increase_lvgl_tick,
|
|
||||||
.name = "lvgl_tick"
|
|
||||||
};
|
|
||||||
esp_timer_handle_t lvgl_tick_timer = NULL;
|
|
||||||
esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer);
|
|
||||||
esp_timer_start_periodic(lvgl_tick_timer, EXAMPLE_LVGL_TICK_PERIOD_MS * 1000);
|
|
||||||
|
|
||||||
}
|
|
||||||
void Timer_Loop(void)
|
|
||||||
{
|
|
||||||
lv_timer_handler(); /* let the GUI do its work */
|
|
||||||
// delay( 5 );
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <lvgl.h>
|
|
||||||
#include <lv_conf.h>
|
|
||||||
#include <demos/lv_demos.h>
|
|
||||||
#include <esp_heap_caps.h>
|
|
||||||
#include "Display_ST7789.h"
|
|
||||||
|
|
||||||
#define LVGL_WIDTH (LCD_WIDTH )
|
|
||||||
#define LVGL_HEIGHT LCD_HEIGHT
|
|
||||||
#define LVGL_BUF_LEN (LVGL_WIDTH * LVGL_HEIGHT / 20)
|
|
||||||
|
|
||||||
#define EXAMPLE_LVGL_TICK_PERIOD_MS 5
|
|
||||||
|
|
||||||
|
|
||||||
void Lvgl_print(const char * buf);
|
|
||||||
void Lvgl_Display_LCD( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p ); // Displays LVGL content on the LCD. This function implements associating LVGL data to the LCD screen
|
|
||||||
void Lvgl_Touchpad_Read( lv_indev_drv_t * indev_drv, lv_indev_data_t * data ); // Read the touchpad
|
|
||||||
void example_increase_lvgl_tick(void *arg);
|
|
||||||
|
|
||||||
void Lvgl_Init(void);
|
|
||||||
void Timer_Loop(void);
|
|
||||||
@@ -1,440 +0,0 @@
|
|||||||
#include "LVGL_Example.h"
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
typedef enum {
|
|
||||||
DISP_SMALL,
|
|
||||||
DISP_MEDIUM,
|
|
||||||
DISP_LARGE,
|
|
||||||
} disp_size_t;
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
static void Onboard_create(lv_obj_t * parent);
|
|
||||||
static void color_changer_create(lv_obj_t * parent);
|
|
||||||
|
|
||||||
static void color_changer_event_cb(lv_event_t * e);
|
|
||||||
static void color_event_cb(lv_event_t * e);
|
|
||||||
static void ta_event_cb(lv_event_t * e);
|
|
||||||
static void birthday_event_cb(lv_event_t * e);
|
|
||||||
static void calendar_event_cb(lv_event_t * e);
|
|
||||||
void IRAM_ATTR example1_increase_lvgl_tick(lv_timer_t * t);
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
static disp_size_t disp_size;
|
|
||||||
|
|
||||||
static lv_obj_t * tv;
|
|
||||||
static lv_obj_t * calendar;
|
|
||||||
lv_style_t style_text_muted;
|
|
||||||
lv_style_t style_title;
|
|
||||||
static lv_style_t style_icon;
|
|
||||||
static lv_style_t style_bullet;
|
|
||||||
|
|
||||||
static lv_obj_t * chart1;
|
|
||||||
static lv_obj_t * chart2;
|
|
||||||
static lv_obj_t * chart3;
|
|
||||||
|
|
||||||
static lv_chart_series_t * ser1;
|
|
||||||
static lv_chart_series_t * ser2;
|
|
||||||
static lv_chart_series_t * ser3;
|
|
||||||
static lv_chart_series_t * ser4;
|
|
||||||
|
|
||||||
static const lv_font_t * font_large;
|
|
||||||
static const lv_font_t * font_normal;
|
|
||||||
|
|
||||||
static lv_timer_t * auto_step_timer;
|
|
||||||
static lv_color_t original_screen_bg_color;
|
|
||||||
|
|
||||||
static lv_timer_t * meter2_timer;
|
|
||||||
|
|
||||||
lv_obj_t * SD_Size;
|
|
||||||
lv_obj_t * FlashSize;
|
|
||||||
lv_obj_t * Board_angle;
|
|
||||||
lv_obj_t * RTC_Time;
|
|
||||||
lv_obj_t * Wireless_Scan;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void IRAM_ATTR auto_switch(lv_timer_t * t)
|
|
||||||
{
|
|
||||||
uint16_t page = lv_tabview_get_tab_act(tv);
|
|
||||||
|
|
||||||
if (page == 0) {
|
|
||||||
lv_tabview_set_act(tv, 1, LV_ANIM_ON);
|
|
||||||
} else if (page == 3) {
|
|
||||||
lv_tabview_set_act(tv, 2, LV_ANIM_ON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Lvgl_Example1(void){
|
|
||||||
|
|
||||||
disp_size = DISP_SMALL;
|
|
||||||
|
|
||||||
font_large = LV_FONT_DEFAULT;
|
|
||||||
font_normal = LV_FONT_DEFAULT;
|
|
||||||
|
|
||||||
lv_coord_t tab_h;
|
|
||||||
tab_h = 45;
|
|
||||||
#if LV_FONT_MONTSERRAT_18
|
|
||||||
font_large = &lv_font_montserrat_18;
|
|
||||||
#else
|
|
||||||
LV_LOG_WARN("LV_FONT_MONTSERRAT_18 is not enabled for the widgets demo. Using LV_FONT_DEFAULT instead.");
|
|
||||||
#endif
|
|
||||||
#if LV_FONT_MONTSERRAT_12
|
|
||||||
font_normal = &lv_font_montserrat_12;
|
|
||||||
#else
|
|
||||||
LV_LOG_WARN("LV_FONT_MONTSERRAT_12 is not enabled for the widgets demo. Using LV_FONT_DEFAULT instead.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lv_style_init(&style_text_muted);
|
|
||||||
lv_style_set_text_opa(&style_text_muted, LV_OPA_90);
|
|
||||||
|
|
||||||
lv_style_init(&style_title);
|
|
||||||
lv_style_set_text_font(&style_title, font_large);
|
|
||||||
|
|
||||||
lv_style_init(&style_icon);
|
|
||||||
lv_style_set_text_color(&style_icon, lv_theme_get_color_primary(NULL));
|
|
||||||
lv_style_set_text_font(&style_icon, font_large);
|
|
||||||
|
|
||||||
lv_style_init(&style_bullet);
|
|
||||||
lv_style_set_border_width(&style_bullet, 0);
|
|
||||||
lv_style_set_radius(&style_bullet, LV_RADIUS_CIRCLE);
|
|
||||||
|
|
||||||
tv = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, tab_h);
|
|
||||||
|
|
||||||
lv_obj_set_style_text_font(lv_scr_act(), font_normal, 0);
|
|
||||||
|
|
||||||
|
|
||||||
lv_obj_t * t1 = lv_tabview_add_tab(tv, "Onboard");
|
|
||||||
|
|
||||||
|
|
||||||
Onboard_create(t1);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Lvgl_Example1_close(void)
|
|
||||||
{
|
|
||||||
/*Delete all animation*/
|
|
||||||
lv_anim_del(NULL, NULL);
|
|
||||||
|
|
||||||
lv_timer_del(meter2_timer);
|
|
||||||
meter2_timer = NULL;
|
|
||||||
|
|
||||||
lv_obj_clean(lv_scr_act());
|
|
||||||
|
|
||||||
lv_style_reset(&style_text_muted);
|
|
||||||
lv_style_reset(&style_title);
|
|
||||||
lv_style_reset(&style_icon);
|
|
||||||
lv_style_reset(&style_bullet);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static void Onboard_create(lv_obj_t * parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*Create a panel*/
|
|
||||||
lv_obj_t * panel1 = lv_obj_create(parent);
|
|
||||||
lv_obj_set_height(panel1, LV_SIZE_CONTENT);
|
|
||||||
|
|
||||||
lv_obj_t * panel1_title = lv_label_create(panel1);
|
|
||||||
lv_label_set_text(panel1_title, "Onboard parameter");
|
|
||||||
lv_obj_add_style(panel1_title, &style_title, 0);
|
|
||||||
|
|
||||||
lv_obj_t * SD_label = lv_label_create(panel1);
|
|
||||||
lv_label_set_text(SD_label, "SD Card");
|
|
||||||
lv_obj_add_style(SD_label, &style_text_muted, 0);
|
|
||||||
|
|
||||||
SD_Size = lv_textarea_create(panel1);
|
|
||||||
lv_textarea_set_one_line(SD_Size, true);
|
|
||||||
lv_textarea_set_placeholder_text(SD_Size, "SD Size");
|
|
||||||
lv_obj_add_event_cb(SD_Size, ta_event_cb, LV_EVENT_ALL, NULL);
|
|
||||||
|
|
||||||
lv_obj_t * Flash_label = lv_label_create(panel1);
|
|
||||||
lv_label_set_text(Flash_label, "Flash Size");
|
|
||||||
lv_obj_add_style(Flash_label, &style_text_muted, 0);
|
|
||||||
|
|
||||||
FlashSize = lv_textarea_create(panel1);
|
|
||||||
lv_textarea_set_one_line(FlashSize, true);
|
|
||||||
lv_textarea_set_placeholder_text(FlashSize, "Flash Size");
|
|
||||||
lv_obj_add_event_cb(FlashSize, ta_event_cb, LV_EVENT_ALL, NULL);
|
|
||||||
|
|
||||||
lv_obj_t * Wireless_label = lv_label_create(panel1);
|
|
||||||
lv_label_set_text(Wireless_label, "Wireless scan");
|
|
||||||
lv_obj_add_style(Wireless_label, &style_text_muted, 0);
|
|
||||||
|
|
||||||
Wireless_Scan = lv_textarea_create(panel1);
|
|
||||||
lv_textarea_set_one_line(Wireless_Scan, true);
|
|
||||||
lv_textarea_set_placeholder_text(Wireless_Scan, "Wireless number");
|
|
||||||
lv_obj_add_event_cb(Wireless_Scan, ta_event_cb, LV_EVENT_ALL, NULL);
|
|
||||||
|
|
||||||
// 器件布局
|
|
||||||
static lv_coord_t grid_main_col_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
|
||||||
static lv_coord_t grid_main_row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
|
||||||
lv_obj_set_grid_dsc_array(parent, grid_main_col_dsc, grid_main_row_dsc);
|
|
||||||
|
|
||||||
|
|
||||||
/*Create the top panel*/
|
|
||||||
static lv_coord_t grid_1_col_dsc[] = {LV_GRID_CONTENT, LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
|
||||||
static lv_coord_t grid_1_row_dsc[] = {LV_GRID_CONTENT, /*Avatar*/
|
|
||||||
LV_GRID_CONTENT, /*Name*/
|
|
||||||
LV_GRID_CONTENT, /*Description*/
|
|
||||||
LV_GRID_CONTENT, /*Email*/
|
|
||||||
LV_GRID_CONTENT, /*Phone number*/
|
|
||||||
LV_GRID_CONTENT, /*Button1*/
|
|
||||||
LV_GRID_CONTENT, /*Button2*/
|
|
||||||
LV_GRID_TEMPLATE_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
lv_obj_set_grid_dsc_array(panel1, grid_1_col_dsc, grid_1_row_dsc);
|
|
||||||
|
|
||||||
|
|
||||||
static lv_coord_t grid_2_col_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
|
||||||
static lv_coord_t grid_2_row_dsc[] = {
|
|
||||||
LV_GRID_CONTENT, /*Title*/
|
|
||||||
5, /*Separator*/
|
|
||||||
LV_GRID_CONTENT, /*Box title*/
|
|
||||||
40, /*Box*/
|
|
||||||
LV_GRID_CONTENT, /*Box title*/
|
|
||||||
40, /*Box*/
|
|
||||||
LV_GRID_CONTENT, /*Box title*/
|
|
||||||
40, /*Box*/
|
|
||||||
LV_GRID_CONTENT, /*Box title*/
|
|
||||||
40, /*Box*/
|
|
||||||
LV_GRID_CONTENT, /*Box title*/
|
|
||||||
40, /*Box*/
|
|
||||||
LV_GRID_CONTENT, /*Box title*/
|
|
||||||
40, /*Box*/
|
|
||||||
LV_GRID_TEMPLATE_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
// lv_obj_set_grid_dsc_array(panel2, grid_2_col_dsc, grid_2_row_dsc);
|
|
||||||
// lv_obj_set_grid_dsc_array(panel3, grid_2_col_dsc, grid_2_row_dsc);
|
|
||||||
|
|
||||||
lv_obj_set_grid_cell(panel1, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_START, 0, 1);
|
|
||||||
lv_obj_set_grid_dsc_array(panel1, grid_2_col_dsc, grid_2_row_dsc);
|
|
||||||
lv_obj_set_grid_cell(panel1_title, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_CENTER, 0, 1);
|
|
||||||
lv_obj_set_grid_cell(SD_label, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 2, 1);
|
|
||||||
lv_obj_set_grid_cell(SD_Size, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 3, 1);
|
|
||||||
lv_obj_set_grid_cell(Flash_label, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 4, 1);
|
|
||||||
lv_obj_set_grid_cell(FlashSize, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 5, 1);
|
|
||||||
lv_obj_set_grid_cell(Wireless_label, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 6, 1);
|
|
||||||
lv_obj_set_grid_cell(Wireless_Scan, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 7, 1);
|
|
||||||
|
|
||||||
// 器件布局 END
|
|
||||||
|
|
||||||
auto_step_timer = lv_timer_create(example1_increase_lvgl_tick, 100, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IRAM_ATTR example1_increase_lvgl_tick(lv_timer_t * t)
|
|
||||||
{
|
|
||||||
char buf[100]={0};
|
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%d MB\r\n", SDCard_Size);
|
|
||||||
lv_textarea_set_placeholder_text(SD_Size, buf);
|
|
||||||
snprintf(buf, sizeof(buf), "%d MB\r\n", Flash_Size);
|
|
||||||
lv_textarea_set_placeholder_text(FlashSize, buf);
|
|
||||||
if(Scan_finish)
|
|
||||||
snprintf(buf, sizeof(buf), "W: %d B: %d OK.\r\n",WIFI_NUM,BLE_NUM);
|
|
||||||
// snprintf(buf, sizeof(buf), "WIFI: %d ..OK.\r\n",WIFI_NUM);
|
|
||||||
else
|
|
||||||
snprintf(buf, sizeof(buf), "W: %d B: %d\r\n",WIFI_NUM,BLE_NUM);
|
|
||||||
// snprintf(buf, sizeof(buf), "WIFI: %d \r\n",WIFI_NUM);
|
|
||||||
lv_textarea_set_placeholder_text(Wireless_Scan, buf);
|
|
||||||
}
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
static void color_changer_create(lv_obj_t * parent)
|
|
||||||
{
|
|
||||||
static lv_palette_t palette[] = {
|
|
||||||
LV_PALETTE_BLUE, LV_PALETTE_GREEN, LV_PALETTE_BLUE_GREY, LV_PALETTE_ORANGE,
|
|
||||||
LV_PALETTE_RED, LV_PALETTE_PURPLE, LV_PALETTE_TEAL, _LV_PALETTE_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
lv_obj_t * color_cont = lv_obj_create(parent);
|
|
||||||
lv_obj_remove_style_all(color_cont);
|
|
||||||
lv_obj_set_flex_flow(color_cont, LV_FLEX_FLOW_ROW);
|
|
||||||
lv_obj_set_flex_align(color_cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
|
||||||
lv_obj_add_flag(color_cont, LV_OBJ_FLAG_FLOATING);
|
|
||||||
|
|
||||||
lv_obj_set_style_bg_color(color_cont, lv_color_white(), 0);
|
|
||||||
lv_obj_set_style_pad_right(color_cont, disp_size == DISP_SMALL ? LV_DPX(47) : LV_DPX(55), 0);
|
|
||||||
lv_obj_set_style_bg_opa(color_cont, LV_OPA_COVER, 0);
|
|
||||||
lv_obj_set_style_radius(color_cont, LV_RADIUS_CIRCLE, 0);
|
|
||||||
|
|
||||||
if(disp_size == DISP_SMALL) lv_obj_set_size(color_cont, LV_DPX(52), LV_DPX(52));
|
|
||||||
else lv_obj_set_size(color_cont, LV_DPX(60), LV_DPX(60));
|
|
||||||
|
|
||||||
lv_obj_align(color_cont, LV_ALIGN_BOTTOM_RIGHT, - LV_DPX(10), - LV_DPX(10));
|
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; palette[i] != _LV_PALETTE_LAST; i++) {
|
|
||||||
lv_obj_t * c = lv_btn_create(color_cont);
|
|
||||||
lv_obj_set_style_bg_color(c, lv_palette_main(palette[i]), 0);
|
|
||||||
lv_obj_set_style_radius(c, LV_RADIUS_CIRCLE, 0);
|
|
||||||
lv_obj_set_style_opa(c, LV_OPA_TRANSP, 0);
|
|
||||||
lv_obj_set_size(c, 20, 20);
|
|
||||||
lv_obj_add_event_cb(c, color_event_cb, LV_EVENT_ALL, &palette[i]);
|
|
||||||
lv_obj_clear_flag(c, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
lv_obj_t * btn = lv_btn_create(parent);
|
|
||||||
lv_obj_add_flag(btn, LV_OBJ_FLAG_FLOATING | LV_OBJ_FLAG_CLICKABLE);
|
|
||||||
lv_obj_set_style_bg_color(btn, lv_color_white(), LV_STATE_CHECKED);
|
|
||||||
lv_obj_set_style_pad_all(btn, 10, 0);
|
|
||||||
lv_obj_set_style_radius(btn, LV_RADIUS_CIRCLE, 0);
|
|
||||||
lv_obj_add_event_cb(btn, color_changer_event_cb, LV_EVENT_ALL, color_cont);
|
|
||||||
lv_obj_set_style_shadow_width(btn, 0, 0);
|
|
||||||
lv_obj_set_style_bg_img_src(btn, LV_SYMBOL_TINT, 0);
|
|
||||||
|
|
||||||
if(disp_size == DISP_SMALL) {
|
|
||||||
lv_obj_set_size(btn, LV_DPX(42), LV_DPX(42));
|
|
||||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -LV_DPX(15), -LV_DPX(15));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lv_obj_set_size(btn, LV_DPX(50), LV_DPX(50));
|
|
||||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -LV_DPX(15), -LV_DPX(15));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void color_changer_anim_cb(void * var, int32_t v)
|
|
||||||
{
|
|
||||||
lv_obj_t * obj =(lv_obj_t *) var;
|
|
||||||
lv_coord_t max_w = lv_obj_get_width(lv_obj_get_parent(obj)) - LV_DPX(20);
|
|
||||||
lv_coord_t w;
|
|
||||||
|
|
||||||
if(disp_size == DISP_SMALL) {
|
|
||||||
w = lv_map(v, 0, 256, LV_DPX(52), max_w);
|
|
||||||
lv_obj_set_width(obj, w);
|
|
||||||
lv_obj_align(obj, LV_ALIGN_BOTTOM_RIGHT, - LV_DPX(10), - LV_DPX(10));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
w = lv_map(v, 0, 256, LV_DPX(60), max_w);
|
|
||||||
lv_obj_set_width(obj, w);
|
|
||||||
lv_obj_align(obj, LV_ALIGN_BOTTOM_RIGHT, - LV_DPX(10), - LV_DPX(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(v > LV_OPA_COVER) v = LV_OPA_COVER;
|
|
||||||
|
|
||||||
uint32_t i;
|
|
||||||
for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
|
|
||||||
lv_obj_set_style_opa(lv_obj_get_child(obj, i), v, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void color_changer_event_cb(lv_event_t * e)
|
|
||||||
{
|
|
||||||
if(lv_event_get_code(e) == LV_EVENT_CLICKED) {
|
|
||||||
lv_obj_t * color_cont = (lv_obj_t *)lv_event_get_user_data(e);
|
|
||||||
if(lv_obj_get_width(color_cont) < LV_HOR_RES / 2) {
|
|
||||||
lv_anim_t a;
|
|
||||||
lv_anim_init(&a);
|
|
||||||
lv_anim_set_var(&a, color_cont);
|
|
||||||
lv_anim_set_exec_cb(&a, color_changer_anim_cb);
|
|
||||||
lv_anim_set_values(&a, 0, 256);
|
|
||||||
lv_anim_set_time(&a, 200);
|
|
||||||
lv_anim_start(&a);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lv_anim_t a;
|
|
||||||
lv_anim_init(&a);
|
|
||||||
lv_anim_set_var(&a, color_cont);
|
|
||||||
lv_anim_set_exec_cb(&a, color_changer_anim_cb);
|
|
||||||
lv_anim_set_values(&a, 256, 0);
|
|
||||||
lv_anim_set_time(&a, 200);
|
|
||||||
lv_anim_start(&a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void color_event_cb(lv_event_t * e)
|
|
||||||
{
|
|
||||||
lv_event_code_t code = lv_event_get_code(e);
|
|
||||||
lv_obj_t * obj = lv_event_get_target(e);
|
|
||||||
|
|
||||||
if(code == LV_EVENT_FOCUSED) {
|
|
||||||
lv_obj_t * color_cont = lv_obj_get_parent(obj);
|
|
||||||
if(lv_obj_get_width(color_cont) < LV_HOR_RES / 2) {
|
|
||||||
lv_anim_t a;
|
|
||||||
lv_anim_init(&a);
|
|
||||||
lv_anim_set_var(&a, color_cont);
|
|
||||||
lv_anim_set_exec_cb(&a, color_changer_anim_cb);
|
|
||||||
lv_anim_set_values(&a, 0, 256);
|
|
||||||
lv_anim_set_time(&a, 200);
|
|
||||||
lv_anim_start(&a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(code == LV_EVENT_CLICKED) {
|
|
||||||
lv_palette_t * palette_primary = (lv_palette_t *)lv_event_get_user_data(e);
|
|
||||||
lv_palette_t palette_secondary =(lv_palette_t) ((*palette_primary) + 3); /*Use another palette as secondary*/
|
|
||||||
if(palette_secondary >= _LV_PALETTE_LAST) palette_secondary =(lv_palette_t)(0);
|
|
||||||
#if LV_USE_THEME_DEFAULT
|
|
||||||
lv_theme_default_init(NULL, lv_palette_main(*palette_primary), lv_palette_main(palette_secondary),
|
|
||||||
LV_THEME_DEFAULT_DARK, font_normal);
|
|
||||||
#endif
|
|
||||||
lv_color_t color = lv_palette_main(*palette_primary);
|
|
||||||
lv_style_set_text_color(&style_icon, color);
|
|
||||||
lv_chart_set_series_color(chart1, ser1, color);
|
|
||||||
lv_chart_set_series_color(chart2, ser3, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ta_event_cb(lv_event_t * e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void birthday_event_cb(lv_event_t * e)
|
|
||||||
{
|
|
||||||
lv_event_code_t code = lv_event_get_code(e);
|
|
||||||
lv_obj_t * ta = lv_event_get_target(e);
|
|
||||||
|
|
||||||
if(code == LV_EVENT_FOCUSED) {
|
|
||||||
if(lv_indev_get_type(lv_indev_get_act()) == LV_INDEV_TYPE_POINTER) {
|
|
||||||
if(calendar == NULL) {
|
|
||||||
lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE);
|
|
||||||
calendar = lv_calendar_create(lv_layer_top());
|
|
||||||
lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_50, 0);
|
|
||||||
lv_obj_set_style_bg_color(lv_layer_top(), lv_palette_main(LV_PALETTE_GREY), 0);
|
|
||||||
if(disp_size == DISP_SMALL) lv_obj_set_size(calendar, 180, 200);
|
|
||||||
else if(disp_size == DISP_MEDIUM) lv_obj_set_size(calendar, 200, 220);
|
|
||||||
else lv_obj_set_size(calendar, 300, 330);
|
|
||||||
lv_calendar_set_showed_date(calendar, 1990, 01);
|
|
||||||
lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 30);
|
|
||||||
lv_obj_add_event_cb(calendar, calendar_event_cb, LV_EVENT_ALL, ta);
|
|
||||||
|
|
||||||
lv_calendar_header_dropdown_create(calendar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void calendar_event_cb(lv_event_t * e)
|
|
||||||
{
|
|
||||||
lv_event_code_t code = lv_event_get_code(e);
|
|
||||||
lv_obj_t * ta = (lv_obj_t *)lv_event_get_user_data(e);
|
|
||||||
lv_obj_t * obj = (lv_obj_t *)lv_event_get_current_target(e);
|
|
||||||
if(code == LV_EVENT_VALUE_CHANGED) {
|
|
||||||
lv_calendar_date_t d;
|
|
||||||
lv_calendar_get_pressed_date(obj, &d);
|
|
||||||
char buf[32];
|
|
||||||
lv_snprintf(buf, sizeof(buf), "%02d.%02d.%d", d.day, d.month, d.year);
|
|
||||||
lv_textarea_set_text(ta, buf);
|
|
||||||
|
|
||||||
lv_obj_del(calendar);
|
|
||||||
calendar = NULL;
|
|
||||||
lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE);
|
|
||||||
lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_TRANSP, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "LVGL_Driver.h"
|
|
||||||
#include "SD_Card.h"
|
|
||||||
#include "Wireless.h"
|
|
||||||
|
|
||||||
#define EXAMPLE1_LVGL_TICK_PERIOD_MS 1000
|
|
||||||
|
|
||||||
|
|
||||||
void Lvgl_Example1(void);
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
#include "SD_Card.h"
|
|
||||||
|
|
||||||
uint16_t SDCard_Size;
|
|
||||||
uint16_t Flash_Size;
|
|
||||||
|
|
||||||
bool SD_Init() {
|
|
||||||
// SD
|
|
||||||
pinMode(SD_CS, OUTPUT);
|
|
||||||
digitalWrite(SD_CS, HIGH);
|
|
||||||
if (SD.begin(SD_CS, SPI)) {
|
|
||||||
printf("SD card initialization successful!\r\n");
|
|
||||||
} else {
|
|
||||||
printf("SD card initialization failed!\r\n");
|
|
||||||
}
|
|
||||||
uint8_t cardType = SD.cardType();
|
|
||||||
if(cardType == CARD_NONE){
|
|
||||||
printf("No SD card attached\r\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
printf("SD Card Type: ");
|
|
||||||
if(cardType == CARD_MMC){
|
|
||||||
printf("MMC\r\n");
|
|
||||||
} else if(cardType == CARD_SD){
|
|
||||||
printf("SDSC\r\n");
|
|
||||||
} else if(cardType == CARD_SDHC){
|
|
||||||
printf("SDHC\r\n");
|
|
||||||
} else {
|
|
||||||
printf("UNKNOWN\r\n");
|
|
||||||
}
|
|
||||||
uint64_t totalBytes = SD.totalBytes();
|
|
||||||
uint64_t usedBytes = SD.usedBytes();
|
|
||||||
SDCard_Size = totalBytes/(1024*1024);
|
|
||||||
printf("Total space: %llu\n", totalBytes);
|
|
||||||
printf("Used space: %llu\n", usedBytes);
|
|
||||||
printf("Free space: %llu\n", totalBytes - usedBytes);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool File_Search(const char* directory, const char* fileName)
|
|
||||||
{
|
|
||||||
File Path = SD.open(directory);
|
|
||||||
if (!Path) {
|
|
||||||
printf("Path: <%s> does not exist\r\n",directory);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
File file = Path.openNextFile();
|
|
||||||
while (file) {
|
|
||||||
if (strcmp(file.name(), fileName) == 0) {
|
|
||||||
if (strcmp(directory, "/") == 0)
|
|
||||||
printf("File '%s%s' found in root directory.\r\n",directory,fileName);
|
|
||||||
else
|
|
||||||
printf("File '%s/%s' found in root directory.\r\n",directory,fileName);
|
|
||||||
Path.close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
file = Path.openNextFile();
|
|
||||||
}
|
|
||||||
if (strcmp(directory, "/") == 0)
|
|
||||||
printf("File '%s%s' not found in root directory.\r\n",directory,fileName);
|
|
||||||
else
|
|
||||||
printf("File '%s/%s' not found in root directory.\r\n",directory,fileName);
|
|
||||||
Path.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][100],uint16_t maxFiles)
|
|
||||||
{
|
|
||||||
File Path = SD.open(directory);
|
|
||||||
if (!Path) {
|
|
||||||
printf("Path: <%s> does not exist\r\n",directory);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t fileCount = 0;
|
|
||||||
char filePath[100];
|
|
||||||
File file = Path.openNextFile();
|
|
||||||
while (file && fileCount < maxFiles) {
|
|
||||||
if (!file.isDirectory() && strstr(file.name(), fileExtension)) {
|
|
||||||
strncpy(File_Name[fileCount], file.name(), sizeof(File_Name[fileCount]));
|
|
||||||
if (strcmp(directory, "/") == 0) {
|
|
||||||
snprintf(filePath, 100, "%s%s", directory, file.name());
|
|
||||||
} else {
|
|
||||||
snprintf(filePath, 100, "%s/%s", directory, file.name());
|
|
||||||
}
|
|
||||||
printf("File found: %s\r\n", filePath);
|
|
||||||
fileCount++;
|
|
||||||
}
|
|
||||||
file = Path.openNextFile();
|
|
||||||
}
|
|
||||||
Path.close();
|
|
||||||
if (fileCount > 0) {
|
|
||||||
printf(" %d <%s> files were retrieved\r\n",fileCount,fileExtension);
|
|
||||||
return fileCount;
|
|
||||||
} else {
|
|
||||||
printf("No files with extension '%s' found in directory: %s\r\n", fileExtension, directory);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_file_extension(char *file_name) {
|
|
||||||
char *last_dot = strrchr(file_name, '.');
|
|
||||||
if (last_dot != NULL) {
|
|
||||||
*last_dot = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flash_test()
|
|
||||||
{
|
|
||||||
printf("/********** RAM Test**********/\r\n");
|
|
||||||
// Get Flash size
|
|
||||||
uint32_t flashSize = ESP.getFlashChipSize();
|
|
||||||
Flash_Size = flashSize/1024/1024;
|
|
||||||
printf("Flash size: %d MB \r\n", flashSize/1024/1024);
|
|
||||||
|
|
||||||
printf("/******* RAM Test Over********/\r\n\r\n");
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include <cstring>
|
|
||||||
#include "Display_ST7789.h"
|
|
||||||
#include "SD.h"
|
|
||||||
#include "FS.h"
|
|
||||||
|
|
||||||
// Digital I/O used
|
|
||||||
#define SD_CS 4 // SD_D3:
|
|
||||||
|
|
||||||
extern uint16_t SDCard_Size;
|
|
||||||
extern uint16_t Flash_Size;
|
|
||||||
|
|
||||||
bool SD_Init();
|
|
||||||
void Flash_test();
|
|
||||||
|
|
||||||
bool File_Search(const char* directory, const char* fileName);
|
|
||||||
uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][100],uint16_t maxFiles);
|
|
||||||
void remove_file_extension(char *file_name);
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
#include "Wireless.h"
|
|
||||||
|
|
||||||
|
|
||||||
bool WIFI_Connection = 0;
|
|
||||||
uint8_t WIFI_NUM = 0;
|
|
||||||
uint8_t BLE_NUM = 0;
|
|
||||||
bool Scan_finish = 0;
|
|
||||||
int wifi_scan_number()
|
|
||||||
{
|
|
||||||
printf("/**********WiFi Test**********/\r\n");
|
|
||||||
// Set WiFi to station mode and disconnect from an AP if it was previously connected.
|
|
||||||
WiFi.mode(WIFI_STA);
|
|
||||||
WiFi.setSleep(true);
|
|
||||||
// WiFi.scanNetworks will return the number of networks found.
|
|
||||||
int count = WiFi.scanNetworks();
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
printf("No WIFI device was scanned\r\n");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
printf("Scanned %d Wi-Fi devices\r\n",count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the scan result to free memory for code below.
|
|
||||||
WiFi.disconnect(true);
|
|
||||||
WiFi.scanDelete();
|
|
||||||
WiFi.mode(WIFI_OFF);
|
|
||||||
vTaskDelay(100);
|
|
||||||
printf("/*******WiFi Test Over********/\r\n\r\n");
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
int ble_scan_number()
|
|
||||||
{
|
|
||||||
printf("/**********BLE Test**********/\r\n");
|
|
||||||
BLEDevice::init("ESP32");
|
|
||||||
BLEScan* pBLEScan = BLEDevice::getScan();
|
|
||||||
pBLEScan->setActiveScan(true);
|
|
||||||
|
|
||||||
BLEScanResults* foundDevices = pBLEScan->start(5);
|
|
||||||
int count = foundDevices->getCount();
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
printf("No Bluetooth device was scanned\r\n");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
printf("Scanned %d Bluetooth devices\r\n",count);
|
|
||||||
}
|
|
||||||
pBLEScan->stop();
|
|
||||||
pBLEScan->clearResults();
|
|
||||||
BLEDevice::deinit(true);
|
|
||||||
vTaskDelay(100);
|
|
||||||
printf("/**********BLE Test Over**********/\r\n\r\n");
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
extern char buffer[128]; /* Make sure buffer is enough for `sprintf` */
|
|
||||||
void Wireless_Test1(){
|
|
||||||
BLE_NUM = ble_scan_number(); // !!! Please note that continuing to use Bluetooth will result in allocation failure due to RAM usage, so pay attention to RAM usage when Bluetooth is turned on
|
|
||||||
WIFI_NUM = wifi_scan_number();
|
|
||||||
Scan_finish = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WirelessScanTask(void *parameter) {
|
|
||||||
BLE_NUM = ble_scan_number(); // !!! Please note that continuing to use Bluetooth will result in allocation failure due to RAM usage, so pay attention to RAM usage when Bluetooth is turned on
|
|
||||||
WIFI_NUM = wifi_scan_number();
|
|
||||||
Scan_finish = 1;
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
|
||||||
void Wireless_Test2(){
|
|
||||||
xTaskCreatePinnedToCore(
|
|
||||||
WirelessScanTask,
|
|
||||||
"WirelessScanTask",
|
|
||||||
4096,
|
|
||||||
NULL,
|
|
||||||
2,
|
|
||||||
NULL,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "WiFi.h"
|
|
||||||
#include <BLEDevice.h>
|
|
||||||
#include <BLEScan.h>
|
|
||||||
|
|
||||||
extern bool WIFI_Connection;
|
|
||||||
extern uint8_t WIFI_NUM;
|
|
||||||
extern uint8_t BLE_NUM;
|
|
||||||
extern bool Scan_finish;
|
|
||||||
|
|
||||||
int wifi_scan_number();
|
|
||||||
int ble_scan_number();
|
|
||||||
void Wireless_Test1();
|
|
||||||
void Wireless_Test2();
|
|
||||||
@@ -1,245 +0,0 @@
|
|||||||
#include "Display_ST7789.h"
|
|
||||||
|
|
||||||
#define SPI_WRITE(_dat) SPI.transfer(_dat)
|
|
||||||
#define SPI_WRITE_Word(_dat) SPI.transfer16(_dat)
|
|
||||||
#define SPI_WRITE_nByte(_SetData,_ReadData,_Size) SPI.transferBytes(_SetData,_ReadData,_Size)
|
|
||||||
void SPI_Init()
|
|
||||||
{
|
|
||||||
SPI.begin(EXAMPLE_PIN_NUM_SCLK,EXAMPLE_PIN_NUM_MISO,EXAMPLE_PIN_NUM_MOSI);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LCD_WriteCommand(uint8_t Cmd)
|
|
||||||
{
|
|
||||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, LOW);
|
|
||||||
SPI_WRITE(Cmd);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
|
||||||
SPI.endTransaction();
|
|
||||||
}
|
|
||||||
void LCD_WriteData(uint8_t Data)
|
|
||||||
{
|
|
||||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
|
||||||
SPI_WRITE(Data);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
|
||||||
SPI.endTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LCD_WriteData_Word(uint16_t Data)
|
|
||||||
{
|
|
||||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
|
||||||
SPI_WRITE_Word(Data);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
|
||||||
SPI.endTransaction();
|
|
||||||
}
|
|
||||||
void LCD_WriteData_nbyte(uint8_t* SetData,uint8_t* ReadData,uint32_t Size)
|
|
||||||
{
|
|
||||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
|
||||||
SPI_WRITE_nByte(SetData, ReadData, Size);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
|
||||||
SPI.endTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LCD_Reset(void)
|
|
||||||
{
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
|
||||||
delay(50);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_RST, LOW);
|
|
||||||
delay(50);
|
|
||||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_RST, HIGH);
|
|
||||||
delay(50);
|
|
||||||
}
|
|
||||||
void LCD_Init(void)
|
|
||||||
{
|
|
||||||
pinMode(EXAMPLE_PIN_NUM_LCD_CS, OUTPUT);
|
|
||||||
pinMode(EXAMPLE_PIN_NUM_LCD_DC, OUTPUT);
|
|
||||||
pinMode(EXAMPLE_PIN_NUM_LCD_RST, OUTPUT);
|
|
||||||
Backlight_Init();
|
|
||||||
SPI_Init();
|
|
||||||
|
|
||||||
LCD_Reset();
|
|
||||||
//************* Start Initial Sequence **********//
|
|
||||||
LCD_WriteCommand(0x11);
|
|
||||||
delay(120);
|
|
||||||
LCD_WriteCommand(0x36);
|
|
||||||
if (HORIZONTAL)
|
|
||||||
LCD_WriteData(0x00);
|
|
||||||
else
|
|
||||||
LCD_WriteData(0x70);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0x3A);
|
|
||||||
LCD_WriteData(0x05);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xB0);
|
|
||||||
LCD_WriteData(0x00);
|
|
||||||
LCD_WriteData(0xE8);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xB2);
|
|
||||||
LCD_WriteData(0x0C);
|
|
||||||
LCD_WriteData(0x0C);
|
|
||||||
LCD_WriteData(0x00);
|
|
||||||
LCD_WriteData(0x33);
|
|
||||||
LCD_WriteData(0x33);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xB7);
|
|
||||||
LCD_WriteData(0x35);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xBB);
|
|
||||||
LCD_WriteData(0x35);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xC0);
|
|
||||||
LCD_WriteData(0x2C);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xC2);
|
|
||||||
LCD_WriteData(0x01);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xC3);
|
|
||||||
LCD_WriteData(0x13);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xC4);
|
|
||||||
LCD_WriteData(0x20);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xC6);
|
|
||||||
LCD_WriteData(0x0F);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xD0);
|
|
||||||
LCD_WriteData(0xA4);
|
|
||||||
LCD_WriteData(0xA1);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xD6);
|
|
||||||
LCD_WriteData(0xA1);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xE0);
|
|
||||||
LCD_WriteData(0xF0);
|
|
||||||
LCD_WriteData(0x00);
|
|
||||||
LCD_WriteData(0x04);
|
|
||||||
LCD_WriteData(0x04);
|
|
||||||
LCD_WriteData(0x04);
|
|
||||||
LCD_WriteData(0x05);
|
|
||||||
LCD_WriteData(0x29);
|
|
||||||
LCD_WriteData(0x33);
|
|
||||||
LCD_WriteData(0x3E);
|
|
||||||
LCD_WriteData(0x38);
|
|
||||||
LCD_WriteData(0x12);
|
|
||||||
LCD_WriteData(0x12);
|
|
||||||
LCD_WriteData(0x28);
|
|
||||||
LCD_WriteData(0x30);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0xE1);
|
|
||||||
LCD_WriteData(0xF0);
|
|
||||||
LCD_WriteData(0x07);
|
|
||||||
LCD_WriteData(0x0A);
|
|
||||||
LCD_WriteData(0x0D);
|
|
||||||
LCD_WriteData(0x0B);
|
|
||||||
LCD_WriteData(0x07);
|
|
||||||
LCD_WriteData(0x28);
|
|
||||||
LCD_WriteData(0x33);
|
|
||||||
LCD_WriteData(0x3E);
|
|
||||||
LCD_WriteData(0x36);
|
|
||||||
LCD_WriteData(0x14);
|
|
||||||
LCD_WriteData(0x14);
|
|
||||||
LCD_WriteData(0x29);
|
|
||||||
LCD_WriteData(0x32);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0x21);
|
|
||||||
|
|
||||||
LCD_WriteCommand(0x11);
|
|
||||||
delay(120);
|
|
||||||
LCD_WriteCommand(0x29);
|
|
||||||
}
|
|
||||||
/******************************************************************************
|
|
||||||
function: Set the cursor position
|
|
||||||
parameter :
|
|
||||||
Xstart: Start uint16_t x coordinate
|
|
||||||
Ystart: Start uint16_t y coordinate
|
|
||||||
Xend : End uint16_t coordinates
|
|
||||||
Yend : End uint16_t coordinatesen
|
|
||||||
******************************************************************************/
|
|
||||||
void LCD_SetCursor(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend)
|
|
||||||
{
|
|
||||||
if (HORIZONTAL) {
|
|
||||||
// set the X coordinates
|
|
||||||
LCD_WriteCommand(0x2A);
|
|
||||||
LCD_WriteData(Xstart >> 8);
|
|
||||||
LCD_WriteData(Xstart + Offset_X);
|
|
||||||
LCD_WriteData(Xend >> 8);
|
|
||||||
LCD_WriteData(Xend + Offset_X);
|
|
||||||
|
|
||||||
// set the Y coordinates
|
|
||||||
LCD_WriteCommand(0x2B);
|
|
||||||
LCD_WriteData(Ystart >> 8);
|
|
||||||
LCD_WriteData(Ystart + Offset_Y);
|
|
||||||
LCD_WriteData(Yend >> 8);
|
|
||||||
LCD_WriteData(Yend + Offset_Y);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// set the X coordinates
|
|
||||||
LCD_WriteCommand(0x2A);
|
|
||||||
LCD_WriteData(Ystart >> 8);
|
|
||||||
LCD_WriteData(Ystart + Offset_Y);
|
|
||||||
LCD_WriteData(Yend >> 8);
|
|
||||||
LCD_WriteData(Yend + Offset_Y);
|
|
||||||
// set the Y coordinates
|
|
||||||
LCD_WriteCommand(0x2B);
|
|
||||||
LCD_WriteData(Xstart >> 8);
|
|
||||||
LCD_WriteData(Xstart + Offset_X);
|
|
||||||
LCD_WriteData(Xend >> 8);
|
|
||||||
LCD_WriteData(Xend + Offset_X);
|
|
||||||
}
|
|
||||||
LCD_WriteCommand(0x2C);
|
|
||||||
}
|
|
||||||
/******************************************************************************
|
|
||||||
function: Refresh the image in an area
|
|
||||||
parameter :
|
|
||||||
Xstart: Start uint16_t x coordinate
|
|
||||||
Ystart: Start uint16_t y coordinate
|
|
||||||
Xend : End uint16_t coordinates
|
|
||||||
Yend : End uint16_t coordinates
|
|
||||||
color : Set the color
|
|
||||||
******************************************************************************/
|
|
||||||
void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint16_t* color)
|
|
||||||
{
|
|
||||||
// uint16_t i,j;
|
|
||||||
// LCD_SetCursor(Xstart, Ystart, Xend,Yend);
|
|
||||||
// uint16_t Show_Width = Xend - Xstart + 1;
|
|
||||||
// uint16_t Show_Height = Yend - Ystart + 1;
|
|
||||||
// for(i = 0; i < Show_Height; i++){
|
|
||||||
// for(j = 0; j < Show_Width; j++){
|
|
||||||
// LCD_WriteData_Word(color[(i*(Show_Width))+j]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
uint16_t Show_Width = Xend - Xstart + 1;
|
|
||||||
uint16_t Show_Height = Yend - Ystart + 1;
|
|
||||||
uint32_t numBytes = Show_Width * Show_Height * sizeof(uint16_t);
|
|
||||||
uint8_t Read_D[numBytes];
|
|
||||||
LCD_SetCursor(Xstart, Ystart, Xend, Yend);
|
|
||||||
LCD_WriteData_nbyte((uint8_t*)color, Read_D, numBytes);
|
|
||||||
}
|
|
||||||
// backlight
|
|
||||||
void Backlight_Init(void)
|
|
||||||
{
|
|
||||||
ledcAttach(EXAMPLE_PIN_NUM_BK_LIGHT, Frequency, Resolution);
|
|
||||||
ledcWrite(EXAMPLE_PIN_NUM_BK_LIGHT, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Set_Backlight(uint8_t Light) //
|
|
||||||
{
|
|
||||||
|
|
||||||
if(Light > 100 || Light < 0)
|
|
||||||
printf("Set Backlight parameters in the range of 0 to 100 \r\n");
|
|
||||||
else{
|
|
||||||
uint32_t Backlight = Light*10;
|
|
||||||
ledcWrite(EXAMPLE_PIN_NUM_BK_LIGHT, Backlight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
#define LCD_WIDTH 172 //LCD width
|
|
||||||
#define LCD_HEIGHT 320 //LCD height
|
|
||||||
|
|
||||||
#define SPIFreq 80000000
|
|
||||||
#define EXAMPLE_PIN_NUM_MISO 5
|
|
||||||
#define EXAMPLE_PIN_NUM_MOSI 6
|
|
||||||
#define EXAMPLE_PIN_NUM_SCLK 7
|
|
||||||
#define EXAMPLE_PIN_NUM_LCD_CS 14
|
|
||||||
#define EXAMPLE_PIN_NUM_LCD_DC 15
|
|
||||||
#define EXAMPLE_PIN_NUM_LCD_RST 21
|
|
||||||
#define EXAMPLE_PIN_NUM_BK_LIGHT 22
|
|
||||||
#define Frequency 1000
|
|
||||||
#define Resolution 10
|
|
||||||
|
|
||||||
#define VERTICAL 0
|
|
||||||
#define HORIZONTAL 1
|
|
||||||
|
|
||||||
#define Offset_X 34
|
|
||||||
#define Offset_Y 0
|
|
||||||
|
|
||||||
void SPI_Init();
|
|
||||||
|
|
||||||
void LCD_Init(void);
|
|
||||||
void LCD_SetCursor(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend);
|
|
||||||
void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint16_t* color);
|
|
||||||
|
|
||||||
void Backlight_Init(void);
|
|
||||||
void Set_Backlight(uint8_t Light);
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
#include "LCD_Image.h"
|
|
||||||
|
|
||||||
PNG png;
|
|
||||||
File Image_file;
|
|
||||||
|
|
||||||
uint16_t Image_CNT;
|
|
||||||
char SD_Image_Name[100][100] ;
|
|
||||||
char File_Image_Name[100][100] ;
|
|
||||||
|
|
||||||
int16_t xpos = 0;
|
|
||||||
int16_t ypos = 0;
|
|
||||||
void * pngOpen(const char *filePath, int32_t *size) {
|
|
||||||
Image_file = SD.open(filePath);
|
|
||||||
*size = Image_file.size();
|
|
||||||
return &Image_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pngClose(void *handle) {
|
|
||||||
File Image_file = *((File*)handle);
|
|
||||||
if (Image_file) Image_file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t pngRead(PNGFILE *page, uint8_t *buffer, int32_t length) {
|
|
||||||
if (!Image_file) return 0;
|
|
||||||
page = page; // Avoid warning
|
|
||||||
return Image_file.read(buffer, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t pngSeek(PNGFILE *page, int32_t position) {
|
|
||||||
if (!Image_file) return 0;
|
|
||||||
page = page; // Avoid warning
|
|
||||||
return Image_file.seek(position);
|
|
||||||
}
|
|
||||||
//=========================================v==========================================
|
|
||||||
// pngDraw
|
|
||||||
//====================================================================================
|
|
||||||
// This next function will be called during decoding of the png file to
|
|
||||||
// render each image line to the TFT. If you use a different TFT library
|
|
||||||
// you will need to adapt this function to suit.
|
|
||||||
// Callback function to draw pixels to the display
|
|
||||||
static uint16_t lineBuffer[MAX_IMAGE_WIDTH];
|
|
||||||
void pngDraw(PNGDRAW *pDraw) {
|
|
||||||
png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
|
|
||||||
uint32_t size = pDraw->iWidth;
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
|
||||||
lineBuffer[i] = (((lineBuffer[i] >> 8) & 0xFF) | ((lineBuffer[i] << 8) & 0xFF00)); // 所有数据修正
|
|
||||||
}
|
|
||||||
LCD_addWindow(xpos, pDraw->y, xpos + pDraw->iWidth, ypos + pDraw->y + 1,lineBuffer); // x_end End index on x-axis (x_end not included)
|
|
||||||
|
|
||||||
}
|
|
||||||
/////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void Search_Image(const char* directory, const char* fileExtension) {
|
|
||||||
Image_CNT = Folder_retrieval(directory,fileExtension,SD_Image_Name,100);
|
|
||||||
if(Image_CNT) {
|
|
||||||
for (int i = 0; i < Image_CNT; i++) {
|
|
||||||
strcpy(File_Image_Name[i], SD_Image_Name[i]);
|
|
||||||
remove_file_extension(File_Image_Name[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Show_Image(const char * filePath)
|
|
||||||
{
|
|
||||||
printf("Currently display picture %s\r\n",filePath);
|
|
||||||
int16_t ret = png.open(filePath, pngOpen, pngClose, pngRead, pngSeek, pngDraw);
|
|
||||||
if (ret == PNG_SUCCESS) {
|
|
||||||
printf("image specs: (%d x %d), %d bpp, pixel type: %d\r\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
|
|
||||||
|
|
||||||
uint32_t dt = millis();
|
|
||||||
if (png.getWidth() > MAX_IMAGE_WIDTH) {
|
|
||||||
printf("Image too wide for allocated line buffer size!\r\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ret = png.decode(NULL, 0);
|
|
||||||
png.close();
|
|
||||||
}
|
|
||||||
printf("%d ms\r\n",millis()-dt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Display_Image(const char* directory, const char* fileExtension, uint16_t ID)
|
|
||||||
{
|
|
||||||
Search_Image(directory,fileExtension);
|
|
||||||
if(Image_CNT) {
|
|
||||||
String FilePath;
|
|
||||||
if (String(directory) == "/") { // Handle the case when the directory is the root
|
|
||||||
FilePath = String(directory) + SD_Image_Name[ID];
|
|
||||||
} else {
|
|
||||||
FilePath = String(directory) + "/" + SD_Image_Name[ID];
|
|
||||||
}
|
|
||||||
const char* filePathCStr = FilePath.c_str(); // Convert String to c_str() for Show_Image function
|
|
||||||
printf("Show : %s \r\n", filePathCStr); // Print file path for debugging
|
|
||||||
Show_Image(filePathCStr); // Show the image using the file path
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("No files with extension '%s' found in directory: %s\r\n", fileExtension, directory);
|
|
||||||
|
|
||||||
}
|
|
||||||
uint16_t Now_Image = 0;
|
|
||||||
void Image_Next(const char* directory, const char* fileExtension)
|
|
||||||
{
|
|
||||||
if(!digitalRead(BOOT_KEY_PIN)){
|
|
||||||
while(!digitalRead(BOOT_KEY_PIN));
|
|
||||||
Now_Image ++;
|
|
||||||
if(Now_Image == Image_CNT)
|
|
||||||
Now_Image = 0;
|
|
||||||
Display_Image(directory,fileExtension,Now_Image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Image_Next_Loop(const char* directory, const char* fileExtension,uint32_t NextTime)
|
|
||||||
{
|
|
||||||
static uint32_t NextTime_Now=0;
|
|
||||||
NextTime_Now++;
|
|
||||||
if(NextTime_Now == NextTime)
|
|
||||||
{
|
|
||||||
NextTime_Now = 0;
|
|
||||||
Now_Image ++;
|
|
||||||
if(Now_Image == Image_CNT)
|
|
||||||
Now_Image = 0;
|
|
||||||
Display_Image(directory,fileExtension,Now_Image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <PNGdec.h>
|
|
||||||
#include "SD_Card.h"
|
|
||||||
#include "Display_ST7789.h"
|
|
||||||
|
|
||||||
#define BOOT_KEY_PIN 9
|
|
||||||
#define MAX_IMAGE_WIDTH 172 // Adjust for your images
|
|
||||||
|
|
||||||
void Search_Image(const char* directory, const char* fileExtension);
|
|
||||||
void Show_Image(const char * filePath);
|
|
||||||
void Display_Image(const char* directory, const char* fileExtension, uint16_t ID);
|
|
||||||
void Image_Next(const char* directory, const char* fileExtension);
|
|
||||||
void Image_Next_Loop(const char* directory, const char* fileExtension,uint32_t NextTime);
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#include "SD_Card.h"
|
|
||||||
#include "Display_ST7789.h"
|
|
||||||
#include "LCD_Image.h"
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Flash_test();
|
|
||||||
LCD_Init();
|
|
||||||
SD_Init();
|
|
||||||
Display_Image("/",".png", 0);
|
|
||||||
pinMode(BOOT_KEY_PIN, INPUT);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
Image_Next_Loop("/",".png",300);
|
|
||||||
delay(5);
|
|
||||||
}
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
#include "SD_Card.h"
|
|
||||||
|
|
||||||
uint16_t SDCard_Size;
|
|
||||||
uint16_t Flash_Size;
|
|
||||||
|
|
||||||
void SD_Init() {
|
|
||||||
// SD
|
|
||||||
if (SD.begin(SD_CS, SPI, 80000000, "/sd", 5, true)) {
|
|
||||||
printf("SD card initialization successful!\r\n");
|
|
||||||
} else {
|
|
||||||
printf("SD card initialization failed!\r\n");
|
|
||||||
}
|
|
||||||
uint8_t cardType = SD.cardType();
|
|
||||||
if(cardType == CARD_NONE){
|
|
||||||
printf("No SD card attached\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
printf("SD Card Type: ");
|
|
||||||
if(cardType == CARD_MMC){
|
|
||||||
printf("MMC\r\n");
|
|
||||||
} else if(cardType == CARD_SD){
|
|
||||||
printf("SDSC\r\n");
|
|
||||||
} else if(cardType == CARD_SDHC){
|
|
||||||
printf("SDHC\r\n");
|
|
||||||
} else {
|
|
||||||
printf("UNKNOWN\r\n");
|
|
||||||
}
|
|
||||||
uint64_t totalBytes = SD.totalBytes();
|
|
||||||
uint64_t usedBytes = SD.usedBytes();
|
|
||||||
SDCard_Size = totalBytes/(1024*1024);
|
|
||||||
printf("Total space: %llu\n", totalBytes);
|
|
||||||
printf("Used space: %llu\n", usedBytes);
|
|
||||||
printf("Free space: %llu\n", totalBytes - usedBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool File_Search(const char* directory, const char* fileName)
|
|
||||||
{
|
|
||||||
File Path = SD.open(directory);
|
|
||||||
if (!Path) {
|
|
||||||
printf("Path: <%s> does not exist\r\n",directory);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
File file = Path.openNextFile();
|
|
||||||
while (file) {
|
|
||||||
if (strcmp(file.name(), fileName) == 0) {
|
|
||||||
if (strcmp(directory, "/") == 0)
|
|
||||||
printf("File '%s%s' found in root directory.\r\n",directory,fileName);
|
|
||||||
else
|
|
||||||
printf("File '%s/%s' found in root directory.\r\n",directory,fileName);
|
|
||||||
Path.close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
file = Path.openNextFile();
|
|
||||||
}
|
|
||||||
if (strcmp(directory, "/") == 0)
|
|
||||||
printf("File '%s%s' not found in root directory.\r\n",directory,fileName);
|
|
||||||
else
|
|
||||||
printf("File '%s/%s' not found in root directory.\r\n",directory,fileName);
|
|
||||||
Path.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][100],uint16_t maxFiles)
|
|
||||||
{
|
|
||||||
File Path = SD.open(directory);
|
|
||||||
if (!Path) {
|
|
||||||
printf("Path: <%s> does not exist\r\n",directory);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t fileCount = 0;
|
|
||||||
char filePath[100];
|
|
||||||
File file = Path.openNextFile();
|
|
||||||
while (file && fileCount < maxFiles) {
|
|
||||||
if (!file.isDirectory() && strstr(file.name(), fileExtension)) {
|
|
||||||
strncpy(File_Name[fileCount], file.name(), sizeof(File_Name[fileCount]));
|
|
||||||
if (strcmp(directory, "/") == 0) {
|
|
||||||
snprintf(filePath, 100, "%s%s", directory, file.name());
|
|
||||||
} else {
|
|
||||||
snprintf(filePath, 100, "%s/%s", directory, file.name());
|
|
||||||
}
|
|
||||||
printf("File found: %s\r\n", filePath);
|
|
||||||
fileCount++;
|
|
||||||
}
|
|
||||||
file = Path.openNextFile();
|
|
||||||
}
|
|
||||||
Path.close();
|
|
||||||
if (fileCount > 0) {
|
|
||||||
printf(" %d <%s> files were retrieved\r\n",fileCount,fileExtension);
|
|
||||||
return fileCount;
|
|
||||||
} else {
|
|
||||||
printf("No files with extension '%s' found in directory: %s\r\n", fileExtension, directory);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_file_extension(char *file_name) {
|
|
||||||
char *last_dot = strrchr(file_name, '.');
|
|
||||||
if (last_dot != NULL) {
|
|
||||||
*last_dot = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flash_test()
|
|
||||||
{
|
|
||||||
printf("/********** RAM Test**********/\r\n");
|
|
||||||
// Get Flash size
|
|
||||||
uint32_t flashSize = ESP.getFlashChipSize();
|
|
||||||
Flash_Size = flashSize/1024/1024;
|
|
||||||
printf("Flash size: %d MB \r\n", flashSize/1024/1024);
|
|
||||||
|
|
||||||
printf("/******* RAM Test Over********/\r\n\r\n");
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include <cstring>
|
|
||||||
#include "Display_ST7789.h"
|
|
||||||
#include "SD.h"
|
|
||||||
#include "FS.h"
|
|
||||||
|
|
||||||
// Digital I/O used
|
|
||||||
#define SD_CS 4 // SD_D3:
|
|
||||||
|
|
||||||
extern uint16_t SDCard_Size;
|
|
||||||
extern uint16_t Flash_Size;
|
|
||||||
|
|
||||||
void SD_Init();
|
|
||||||
void Flash_test();
|
|
||||||
|
|
||||||
bool File_Search(const char* directory, const char* fileName);
|
|
||||||
uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][100],uint16_t maxFiles);
|
|
||||||
void remove_file_extension(char *file_name);
|
|
||||||
Submodule examples/Waveshare-ESP32-S3-Touch-LCD-4.3-and-Arduino added at 18ddf3f807
26
sketches/doorbell-touch/.clang-format
Normal file
26
sketches/doorbell-touch/.clang-format
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Arduino/C++ friendly format
|
||||||
|
BasedOnStyle: WebKit
|
||||||
|
|
||||||
|
# Indentation
|
||||||
|
IndentWidth: 4
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
|
IndentCaseLabels: false
|
||||||
|
|
||||||
|
# Braces - keep opening brace on same line
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
|
||||||
|
# Spacing (fixed)
|
||||||
|
SpaceBeforeParens: Never
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
PointerAlignment: Left
|
||||||
|
|
||||||
|
# Line length
|
||||||
|
ColumnLimit: 100
|
||||||
|
|
||||||
|
# Includes
|
||||||
|
SortIncludes: true
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
@@ -1,256 +1,244 @@
|
|||||||
#include "DisplayDriverGFX.h"
|
#include "LovyanPins.h"
|
||||||
#include "board_config.h"
|
#include "board_config.h"
|
||||||
|
#include <Arduino.h>
|
||||||
#include <ESP_IOExpander_Library.h>
|
#include <ESP_IOExpander_Library.h>
|
||||||
|
|
||||||
|
// Global display instance
|
||||||
|
static LGFX* _gfx = nullptr;
|
||||||
|
static ESP_IOExpander* _expander = nullptr;
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
void initExpander();
|
||||||
|
void initDisplay();
|
||||||
|
|
||||||
|
// ── Expander initialization (from Westcott) ──
|
||||||
|
void initExpander()
|
||||||
|
{
|
||||||
|
Serial.println("IO expander init...");
|
||||||
|
#include <Arduino.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
|
#include <ESP_IOExpander_Library.h>
|
||||||
|
#include "LovyanPins.h"
|
||||||
|
#include "board_config.h"
|
||||||
|
#include "DisplayDriverGFX.h"
|
||||||
|
|
||||||
#ifndef BLACK
|
// ── Globals ──
|
||||||
#define BLACK 0x0000
|
static LGFX* _gfx = nullptr;
|
||||||
#endif
|
static ESP_IOExpander* _expander = nullptr;
|
||||||
#ifndef WHITE
|
|
||||||
#define WHITE 0xFFFF
|
|
||||||
#endif
|
|
||||||
#ifndef RED
|
|
||||||
#define RED 0xF800
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// CH422G logical pin numbers
|
// ── Forward declarations ──
|
||||||
#define EXIO_TP_RST IO_EXPANDER_PIN_NUM_1
|
static void initExpander();
|
||||||
#define EXIO_LCD_BL IO_EXPANDER_PIN_NUM_2
|
static void initDisplay();
|
||||||
#define EXIO_LCD_RST IO_EXPANDER_PIN_NUM_3
|
|
||||||
#define EXIO_SD_CS IO_EXPANDER_PIN_NUM_4
|
|
||||||
#define EXIO_USB_SEL IO_EXPANDER_PIN_NUM_5
|
|
||||||
|
|
||||||
static ESP_IOExpander* expander = nullptr;
|
// ── Dimensions ──
|
||||||
|
static constexpr int DISP_W = 800;
|
||||||
|
static constexpr int DISP_H = 480;
|
||||||
|
|
||||||
// ── IO Expander ──
|
// ── Expander initialization ──
|
||||||
|
static void initExpander() {
|
||||||
void DisplayDriverGFX::expanderInit() {
|
Serial.println("IO expander init...");
|
||||||
Serial.println("[IO] IO expander init...");
|
|
||||||
expander = new ESP_IOExpander_CH422G(
|
// Initialize I2C for expander
|
||||||
I2C_MASTER_NUM,
|
Wire.begin(TOUCH_SDA, TOUCH_SCL);
|
||||||
|
|
||||||
|
_expander = new ESP_IOExpander_CH422G(
|
||||||
|
(i2c_port_t)I2C_NUM_0,
|
||||||
ESP_IO_EXPANDER_I2C_CH422G_ADDRESS
|
ESP_IO_EXPANDER_I2C_CH422G_ADDRESS
|
||||||
);
|
);
|
||||||
expander->init();
|
_expander->init();
|
||||||
expander->begin();
|
_expander->begin();
|
||||||
expander->multiPinMode(
|
|
||||||
EXIO_TP_RST | EXIO_LCD_BL | EXIO_LCD_RST | EXIO_SD_CS | EXIO_USB_SEL,
|
// Set all pins to output
|
||||||
OUTPUT
|
_expander->multiPinMode(TP_RST | LCD_BL | LCD_RST | SD_CS | USB_SEL, OUTPUT);
|
||||||
);
|
|
||||||
// Deassert resets, backlight OFF for now
|
// Reset sequence
|
||||||
expander->multiDigitalWrite(
|
_expander->digitalWrite(LCD_RST, LOW);
|
||||||
EXIO_TP_RST | EXIO_LCD_RST | EXIO_SD_CS,
|
delay(50);
|
||||||
0xFF
|
_expander->digitalWrite(LCD_RST, HIGH);
|
||||||
);
|
delay(150);
|
||||||
expander->digitalWrite(EXIO_LCD_BL, LOW);
|
|
||||||
Serial.println("[IO] CH422G initialized");
|
// Turn on backlight
|
||||||
|
_expander->digitalWrite(LCD_BL, HIGH);
|
||||||
|
|
||||||
|
Serial.println("IO expander ready");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Display initialization ──
|
||||||
|
static void initDisplay() {
|
||||||
|
Serial.println("LovyanGFX init...");
|
||||||
|
|
||||||
|
_gfx = new LGFX();
|
||||||
|
_gfx->init();
|
||||||
|
_gfx->setRotation(1); // Landscape
|
||||||
|
_gfx->fillScreen(0x000000);
|
||||||
|
|
||||||
|
Serial.println("Display ready");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Singleton ──
|
||||||
|
DisplayDriverGFX& DisplayDriverGFX::instance() {
|
||||||
|
static DisplayDriverGFX inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── IDisplayDriver implementation ──
|
||||||
|
|
||||||
|
void DisplayDriverGFX::begin() {
|
||||||
|
initExpander();
|
||||||
|
initDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayDriverGFX::setBacklight(bool on) {
|
void DisplayDriverGFX::setBacklight(bool on) {
|
||||||
if (expander) {
|
if (_expander) {
|
||||||
expander->digitalWrite(EXIO_LCD_BL, on ? HIGH : LOW);
|
_expander->digitalWrite(LCD_BL, on ? HIGH : LOW);
|
||||||
Serial.printf("[GFX] Backlight %s\n", on ? "ON" : "OFF");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Touch ──
|
int DisplayDriverGFX::width() {
|
||||||
|
return DISP_W;
|
||||||
void DisplayDriverGFX::touchInit() {
|
|
||||||
Wire.begin(I2C_MASTER_SDA, I2C_MASTER_SCL);
|
|
||||||
Wire.beginTransmission(GT911_ADDR);
|
|
||||||
uint8_t err = Wire.endTransmission();
|
|
||||||
if (err == 0) {
|
|
||||||
Serial.println("[TOUCH] GT911 initialized");
|
|
||||||
} else {
|
|
||||||
Serial.printf("[TOUCH] GT911 not found (I2C err %d)\n", err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DisplayDriverGFX::height() {
|
||||||
|
return DISP_H;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Touch handling ──
|
||||||
|
|
||||||
TouchEvent DisplayDriverGFX::readTouch() {
|
TouchEvent DisplayDriverGFX::readTouch() {
|
||||||
TouchEvent ev = { false, 0, 0 };
|
TouchEvent evt;
|
||||||
Wire.beginTransmission(GT911_ADDR);
|
|
||||||
if (Wire.endTransmission() != 0) return ev;
|
if (!_gfx) return evt;
|
||||||
|
|
||||||
// Read touch status register (0x814E)
|
int32_t x, y;
|
||||||
Wire.beginTransmission(GT911_ADDR);
|
if (_gfx->getTouch(&x, &y)) {
|
||||||
Wire.write(0x81);
|
evt.pressed = true;
|
||||||
Wire.write(0x4E);
|
evt.x = static_cast<int>(x);
|
||||||
Wire.endTransmission(false);
|
evt.y = static_cast<int>(y);
|
||||||
Wire.requestFrom((uint8_t)GT911_ADDR, (uint8_t)1);
|
|
||||||
if (!Wire.available()) return ev;
|
// Track press start
|
||||||
|
if (!_lastTouch.pressed) {
|
||||||
uint8_t status = Wire.read();
|
_pressStartMs = millis();
|
||||||
uint8_t touches = status & 0x0F;
|
_isHolding = false;
|
||||||
|
|
||||||
if ((status & 0x80) && touches > 0 && touches <= 5) {
|
|
||||||
// Read first touch point (0x8150)
|
|
||||||
Wire.beginTransmission(GT911_ADDR);
|
|
||||||
Wire.write(0x81);
|
|
||||||
Wire.write(0x50);
|
|
||||||
Wire.endTransmission(false);
|
|
||||||
Wire.requestFrom((uint8_t)GT911_ADDR, (uint8_t)4);
|
|
||||||
if (Wire.available() >= 4) {
|
|
||||||
uint8_t xl = Wire.read();
|
|
||||||
uint8_t xh = Wire.read();
|
|
||||||
uint8_t yl = Wire.read();
|
|
||||||
uint8_t yh = Wire.read();
|
|
||||||
ev.pressed = true;
|
|
||||||
ev.x = (xh << 8) | xl;
|
|
||||||
ev.y = (yh << 8) | yl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear status
|
_lastTouch = evt;
|
||||||
Wire.beginTransmission(GT911_ADDR);
|
return evt;
|
||||||
Wire.write(0x81);
|
|
||||||
Wire.write(0x4E);
|
|
||||||
Wire.write(0x00);
|
|
||||||
Wire.endTransmission();
|
|
||||||
|
|
||||||
return ev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DisplayDriverGFX::dashboardTouch(int x, int y) {
|
int DisplayDriverGFX::dashboardTouch(int x, int y) {
|
||||||
// Unified 2x2 grid
|
// Dashboard tiles: 2 rows × 4 columns
|
||||||
int col = (x * 2) / DISPLAY_WIDTH; // 0 or 1
|
constexpr int cols = 4;
|
||||||
int row = (y * 2) / DISPLAY_HEIGHT; // 0 or 1
|
constexpr int rows = 2;
|
||||||
return row * 2 + col; // 0, 1, 2, or 3
|
constexpr int tileW = DISP_W / cols;
|
||||||
|
constexpr int tileH = DISP_H / rows;
|
||||||
|
|
||||||
|
if (x < 0 || x >= DISP_W || y < 0 || y >= DISP_H) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int col = x / tileW;
|
||||||
|
int row = y / tileH;
|
||||||
|
|
||||||
|
return row * cols + col;
|
||||||
}
|
}
|
||||||
|
|
||||||
HoldState DisplayDriverGFX::updateHold(unsigned long holdMs) {
|
HoldState DisplayDriverGFX::updateHold(unsigned long holdMs) {
|
||||||
TouchEvent ev = readTouch();
|
HoldState state;
|
||||||
|
|
||||||
if (ev.pressed) {
|
if (!_lastTouch.pressed) {
|
||||||
if (!_lastTouched) {
|
_isHolding = false;
|
||||||
_holdStart = millis();
|
return state;
|
||||||
_lastTouched = true;
|
|
||||||
}
|
|
||||||
unsigned long elapsed = millis() - _holdStart;
|
|
||||||
float progress = constrain((float)elapsed / holdMs, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
if (elapsed >= holdMs) {
|
|
||||||
_lastTouched = false;
|
|
||||||
_holdStart = 0;
|
|
||||||
return {false, true, 1.0f};
|
|
||||||
}
|
|
||||||
return {true, false, progress};
|
|
||||||
} else {
|
|
||||||
_lastTouched = false;
|
|
||||||
_holdStart = 0;
|
|
||||||
return {false, false, 0.0f};
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
void DisplayDriverGFX::updateHint() {
|
unsigned long elapsed = millis() - _pressStartMs;
|
||||||
// placeholder for idle hint animation
|
|
||||||
}
|
if (!_isHolding) {
|
||||||
|
// Start tracking hold
|
||||||
// ── Display ──
|
_isHolding = true;
|
||||||
|
|
||||||
void DisplayDriverGFX::begin() {
|
|
||||||
// 1. Touch (I2C on GPIO 8/9)
|
|
||||||
touchInit();
|
|
||||||
delay(200);
|
|
||||||
|
|
||||||
// 2. IO expander
|
|
||||||
expanderInit();
|
|
||||||
|
|
||||||
// 3. RGB display
|
|
||||||
Serial.println("[GFX] GFX init...");
|
|
||||||
Arduino_ESP32RGBPanel* rgbPanel = new Arduino_ESP32RGBPanel(
|
|
||||||
LCD_DE, LCD_VSYNC, LCD_HSYNC, LCD_PCLK,
|
|
||||||
LCD_R0, LCD_R1, LCD_R2, LCD_R3, LCD_R4,
|
|
||||||
LCD_G0, LCD_G1, LCD_G2, LCD_G3, LCD_G4, LCD_G5,
|
|
||||||
LCD_B0, LCD_B1, LCD_B2, LCD_B3, LCD_B4,
|
|
||||||
0, // hsync_polarity
|
|
||||||
40, // hsync_front_porch
|
|
||||||
48, // hsync_pulse_width
|
|
||||||
88, // hsync_back_porch
|
|
||||||
0, // vsync_polarity
|
|
||||||
13, // vsync_front_porch
|
|
||||||
3, // vsync_pulse_width
|
|
||||||
32, // vsync_back_porch
|
|
||||||
1, // pclk_active_neg
|
|
||||||
16000000 // prefer_speed
|
|
||||||
);
|
|
||||||
|
|
||||||
_gfx = new Arduino_RGB_Display(
|
|
||||||
DISPLAY_WIDTH, DISPLAY_HEIGHT, rgbPanel,
|
|
||||||
DISPLAY_ROTATION, true
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!_gfx->begin()) {
|
|
||||||
Serial.println("[GFX] *** Display init FAILED ***");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.printf("[GFX] Display OK: %dx%d\n", DISPLAY_WIDTH, DISPLAY_HEIGHT);
|
state.active = true;
|
||||||
Serial.printf("[MEM] Free heap: %d | Free PSRAM: %d\n",
|
state.progress = static_cast<float>(elapsed) / static_cast<float>(holdMs);
|
||||||
ESP.getFreeHeap(), ESP.getFreePsram());
|
|
||||||
|
if (state.progress >= 1.0f) {
|
||||||
// 4. Clear and backlight on
|
state.progress = 1.0f;
|
||||||
_gfx->fillScreen(BLACK);
|
state.completed = true;
|
||||||
setBacklight(true);
|
}
|
||||||
drawBoot();
|
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DisplayDriverGFX::width() { return _gfx ? _gfx->width() : DISPLAY_WIDTH; }
|
// ── Rendering ──
|
||||||
int DisplayDriverGFX::height() { return _gfx ? _gfx->height() : DISPLAY_HEIGHT; }
|
|
||||||
|
|
||||||
// ── Render (state machine driven) ──
|
|
||||||
|
|
||||||
void DisplayDriverGFX::render(const ScreenState& state) {
|
void DisplayDriverGFX::render(const ScreenState& state) {
|
||||||
if (!_gfx) return;
|
if (!_gfx) return;
|
||||||
switch (state.screen) {
|
|
||||||
case ScreenID::BOOT: drawBoot(); break;
|
// Clear with background color
|
||||||
case ScreenID::DASHBOARD: drawDashboard(state); break;
|
_gfx->fillScreen(0x001030); // Dark blue
|
||||||
case ScreenID::ALERT: drawAlert(state); break;
|
|
||||||
case ScreenID::OFF: drawOff(); break;
|
if (!state.showDashboard) {
|
||||||
default: drawBoot(); break;
|
// Show alert/message screen
|
||||||
|
renderAlert(state);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw dashboard tiles
|
||||||
|
constexpr int cols = 4;
|
||||||
|
constexpr int rows = 2;
|
||||||
|
constexpr int tileW = DISP_W / cols;
|
||||||
|
constexpr int tileH = DISP_H / rows;
|
||||||
|
constexpr int margin = 8;
|
||||||
|
|
||||||
|
for (int i = 0; i < state.dashTiles.size(); i++) {
|
||||||
|
int col = i % cols;
|
||||||
|
int row = i / cols;
|
||||||
|
|
||||||
|
int x = col * tileW + margin;
|
||||||
|
int y = row * tileH + margin;
|
||||||
|
int w = tileW - 2 * margin;
|
||||||
|
int h = tileH - 2 * margin;
|
||||||
|
|
||||||
|
// Tile background
|
||||||
|
uint16_t tileColor = state.dashTiles[i].active ? 0x04A0 : 0x0220;
|
||||||
|
_gfx->fillRoundRect(x, y, w, h, 8, tileColor);
|
||||||
|
|
||||||
|
// Tile border
|
||||||
|
_gfx->drawRoundRect(x, y, w, h, 8, 0xFFFF);
|
||||||
|
|
||||||
|
// Tile label
|
||||||
|
_gfx->setTextColor(0xFFFF);
|
||||||
|
_gfx->setTextSize(2);
|
||||||
|
_gfx->setCursor(x + 10, y + 10);
|
||||||
|
_gfx->print(state.dashTiles[i].label);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw WiFi status
|
||||||
|
_gfx->setTextSize(1);
|
||||||
|
_gfx->setCursor(DISP_W - 100, 10);
|
||||||
|
_gfx->printf("WiFi: %s", state.wifiConnected ? "ON" : "OFF");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayDriverGFX::drawBoot() {
|
void DisplayDriverGFX::updateHint() {
|
||||||
if (!_gfx) return;
|
if (!_gfx) return;
|
||||||
_gfx->fillScreen(BLACK);
|
|
||||||
_gfx->setTextColor(WHITE);
|
static uint32_t lastTime = 0;
|
||||||
_gfx->setTextSize(4);
|
uint32_t now = millis();
|
||||||
_gfx->setCursor(250, 200);
|
if (now - lastTime < 50) return;
|
||||||
_gfx->println("Klubhaus Alert");
|
lastTime = now;
|
||||||
_gfx->setTextSize(2);
|
|
||||||
_gfx->setCursor(300, 260);
|
float t = (now % 2000) / 2000.0f;
|
||||||
_gfx->println("Booting...");
|
uint8_t v = static_cast<uint8_t>(30.0f + 30.0f * sinf(t * 2 * 3.14159f));
|
||||||
|
uint16_t col = ((v >> 3) << 11) | ((v >> 2) << 5) | (v >> 3);
|
||||||
|
|
||||||
|
_gfx->drawCircle(DISP_W / 2, DISP_H / 2, 50, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayDriverGFX::drawDashboard(const ScreenState& state) {
|
// Helper for alert rendering (implement as needed)
|
||||||
if (!_gfx) return;
|
void DisplayDriverGFX::renderAlert(const ScreenState& state) {
|
||||||
_gfx->fillScreen(BLACK);
|
// Placeholder - implement based on your ScreenState fields
|
||||||
_gfx->setTextColor(WHITE);
|
_gfx->setTextColor(0xFFFF);
|
||||||
_gfx->setTextSize(3);
|
_gfx->setTextSize(3);
|
||||||
_gfx->setCursor(20, 20);
|
_gfx->setCursor(200, 200);
|
||||||
_gfx->println("KLUBHAUS DASHBOARD");
|
_gfx->print("Alert Mode");
|
||||||
_gfx->setTextSize(2);
|
|
||||||
_gfx->setCursor(20, 80);
|
|
||||||
_gfx->printf("IP: %s", state.ipAddr.c_str());
|
|
||||||
_gfx->setCursor(20, 110);
|
|
||||||
_gfx->printf("RSSI: %d dBm", state.wifiRssi);
|
|
||||||
_gfx->setCursor(20, 140);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayDriverGFX::drawAlert(const ScreenState& state) {
|
|
||||||
if (!_gfx) return;
|
|
||||||
_gfx->fillScreen(RED);
|
|
||||||
_gfx->setTextColor(WHITE);
|
|
||||||
_gfx->setTextSize(5);
|
|
||||||
_gfx->setCursor(200, 180);
|
|
||||||
_gfx->println("DOORBELL!");
|
|
||||||
_gfx->setTextSize(3);
|
|
||||||
_gfx->setCursor(100, 280);
|
|
||||||
const char* body = state.alertBody.c_str();
|
|
||||||
_gfx->println(state.alertBody.length() ? body : "Someone is at the door");
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayDriverGFX::drawOff() {
|
|
||||||
if (!_gfx) return;
|
|
||||||
_gfx->fillScreen(BLACK);
|
|
||||||
setBacklight(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,42 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <IDisplayDriver.h>
|
#include <Arduino.h>
|
||||||
#include <Arduino_GFX_Library.h>
|
#include "ScreenState.h"
|
||||||
|
#include "IDisplayDriver.h"
|
||||||
|
|
||||||
|
struct TouchEvent {
|
||||||
|
bool pressed = false;
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HoldState {
|
||||||
|
bool active = false;
|
||||||
|
bool completed = false;
|
||||||
|
float progress = 0.0f; // 0.0 – 1.0
|
||||||
|
};
|
||||||
|
|
||||||
class DisplayDriverGFX : public IDisplayDriver {
|
class DisplayDriverGFX : public IDisplayDriver {
|
||||||
public:
|
public:
|
||||||
|
// ── IDisplayDriver ──
|
||||||
void begin() override;
|
void begin() override;
|
||||||
void setBacklight(bool on) override;
|
void setBacklight(bool on) override;
|
||||||
void render(const ScreenState& state) override;
|
void render(const ScreenState& state) override;
|
||||||
|
|
||||||
TouchEvent readTouch() override;
|
TouchEvent readTouch() override;
|
||||||
int dashboardTouch(int x, int y) override;
|
int dashboardTouch(int x, int y) override;
|
||||||
HoldState updateHold(unsigned long holdMs) override;
|
HoldState updateHold(unsigned long holdMs) override;
|
||||||
void updateHint() override;
|
void updateHint() override;
|
||||||
int width() override;
|
|
||||||
int height() override;
|
int width() override;
|
||||||
|
int height() override;
|
||||||
|
|
||||||
|
// ── Internal ──
|
||||||
|
static DisplayDriverGFX& instance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void expanderInit();
|
// Touch handling
|
||||||
void touchInit();
|
TouchEvent _lastTouch = {false, 0, 0};
|
||||||
void drawBoot();
|
unsigned long _pressStartMs = 0;
|
||||||
void drawDashboard(const ScreenState& state);
|
bool _isHolding = false;
|
||||||
void drawAlert(const ScreenState& state);
|
|
||||||
void drawOff();
|
|
||||||
Arduino_RGB_Display* _gfx = nullptr;
|
|
||||||
bool _lastTouched = false;
|
|
||||||
unsigned long _holdStart = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
118
sketches/doorbell-touch/boards/esp32-s3-lcd-43/LovyanPins.h
Normal file
118
sketches/doorbell-touch/boards/esp32-s3-lcd-43/LovyanPins.h
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define LGFX_USE_V1
|
||||||
|
#include <LovyanGFX.hpp>
|
||||||
|
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
|
||||||
|
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>
|
||||||
|
|
||||||
|
// ── Display dimensions ──
|
||||||
|
#define TFT_HOR_RES 800
|
||||||
|
#define TFT_VER_RES 480
|
||||||
|
|
||||||
|
// ── Touch I2C (from Westcott example) ──
|
||||||
|
#define TOUCH_SDA 8
|
||||||
|
#define TOUCH_SCL 9
|
||||||
|
#define TOUCH_INT 4
|
||||||
|
#define TOUCH_RST -1
|
||||||
|
|
||||||
|
// ── CH422G Expander pins ──
|
||||||
|
#define TP_RST 1
|
||||||
|
#define LCD_BL 2
|
||||||
|
#define LCD_RST 3
|
||||||
|
#define SD_CS 4
|
||||||
|
#define USB_SEL 5
|
||||||
|
|
||||||
|
class LGFX : public lgfx::LGFX_Device {
|
||||||
|
public:
|
||||||
|
lgfx::Bus_RGB _bus_instance;
|
||||||
|
lgfx::Panel_RGB _panel_instance;
|
||||||
|
lgfx::Touch_GT911 _touch_instance;
|
||||||
|
|
||||||
|
LGFX(void) {
|
||||||
|
// Panel config
|
||||||
|
{
|
||||||
|
auto cfg = _panel_instance.config();
|
||||||
|
cfg.memory_width = TFT_HOR_RES;
|
||||||
|
cfg.memory_height = TFT_VER_RES;
|
||||||
|
cfg.panel_width = TFT_HOR_RES;
|
||||||
|
cfg.panel_height = TFT_VER_RES;
|
||||||
|
cfg.offset_x = 0;
|
||||||
|
cfg.offset_y = 0;
|
||||||
|
_panel_instance.config(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RGB parallel bus config (from Westcott)
|
||||||
|
{
|
||||||
|
auto cfg = _bus_instance.config();
|
||||||
|
cfg.panel = &_panel_instance;
|
||||||
|
|
||||||
|
// Blue channel
|
||||||
|
cfg.pin_d0 = 14;
|
||||||
|
cfg.pin_d1 = 38;
|
||||||
|
cfg.pin_d2 = 18;
|
||||||
|
cfg.pin_d3 = 17;
|
||||||
|
cfg.pin_d4 = 10;
|
||||||
|
|
||||||
|
// Green channel
|
||||||
|
cfg.pin_d5 = 39;
|
||||||
|
cfg.pin_d6 = 0;
|
||||||
|
cfg.pin_d7 = 45;
|
||||||
|
cfg.pin_d8 = 48;
|
||||||
|
cfg.pin_d9 = 47;
|
||||||
|
cfg.pin_d10 = 21;
|
||||||
|
|
||||||
|
// Red channel
|
||||||
|
cfg.pin_d11 = 1;
|
||||||
|
cfg.pin_d12 = 2;
|
||||||
|
cfg.pin_d13 = 42;
|
||||||
|
cfg.pin_d14 = 41;
|
||||||
|
cfg.pin_d15 = 40;
|
||||||
|
|
||||||
|
// Timing
|
||||||
|
cfg.pin_henable = 5;
|
||||||
|
cfg.pin_vsync = 3;
|
||||||
|
cfg.pin_hsync = 46;
|
||||||
|
cfg.pin_pclk = 7;
|
||||||
|
cfg.freq_write = 14000000;
|
||||||
|
|
||||||
|
cfg.hsync_polarity = 0;
|
||||||
|
cfg.hsync_front_porch = 20;
|
||||||
|
cfg.hsync_pulse_width = 10;
|
||||||
|
cfg.hsync_back_porch = 10;
|
||||||
|
|
||||||
|
cfg.vsync_polarity = 0;
|
||||||
|
cfg.vsync_front_porch = 10;
|
||||||
|
cfg.vsync_pulse_width = 10;
|
||||||
|
cfg.vsync_back_porch = 10;
|
||||||
|
|
||||||
|
cfg.pclk_active_neg = 0;
|
||||||
|
cfg.de_idle_high = 0;
|
||||||
|
cfg.pclk_idle_high = 0;
|
||||||
|
|
||||||
|
_bus_instance.config(cfg);
|
||||||
|
}
|
||||||
|
_panel_instance.setBus(&_bus_instance);
|
||||||
|
|
||||||
|
// Touch config (I2C port 1, address 0x14 - from Westcott!)
|
||||||
|
{
|
||||||
|
auto cfg = _touch_instance.config();
|
||||||
|
cfg.x_min = 0;
|
||||||
|
cfg.x_max = TFT_HOR_RES - 1;
|
||||||
|
cfg.y_min = 0;
|
||||||
|
cfg.y_max = TFT_VER_RES - 1;
|
||||||
|
cfg.pin_int = TOUCH_INT;
|
||||||
|
cfg.pin_rst = TOUCH_RST;
|
||||||
|
cfg.bus_shared = false;
|
||||||
|
cfg.offset_rotation = 0;
|
||||||
|
cfg.i2c_port = I2C_NUM_1; // IMPORTANT: Port 1, not 0!
|
||||||
|
cfg.pin_sda = TOUCH_SDA;
|
||||||
|
cfg.pin_scl = TOUCH_SCL;
|
||||||
|
cfg.freq = 400000;
|
||||||
|
cfg.i2c_addr = 0x14; // IMPORTANT: Address 0x14, not 0x5D!
|
||||||
|
_touch_instance.config(cfg);
|
||||||
|
_panel_instance.setTouch(&_touch_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPanel(&_panel_instance);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,41 +1,40 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define BOARD_NAME "WS_S3_43"
|
#define BOARD_NAME "WS_S3_43"
|
||||||
#define DISPLAY_WIDTH 800
|
#define DISPLAY_WIDTH 800
|
||||||
#define DISPLAY_HEIGHT 480
|
#define DISPLAY_HEIGHT 480
|
||||||
#define DISPLAY_ROTATION 0
|
#define DISPLAY_ROTATION 0
|
||||||
|
|
||||||
// ── RGB parallel bus (from Westcott1 reference) ──
|
// ── RGB parallel bus (from Westcott1 reference) ──
|
||||||
#define LCD_DE 5
|
#define LCD_DE 5
|
||||||
#define LCD_VSYNC 3
|
#define LCD_VSYNC 3
|
||||||
#define LCD_HSYNC 46
|
#define LCD_HSYNC 46
|
||||||
#define LCD_PCLK 7
|
#define LCD_PCLK 7
|
||||||
|
|
||||||
#define LCD_R0 1
|
#define LCD_R0 1
|
||||||
#define LCD_R1 2
|
#define LCD_R1 2
|
||||||
#define LCD_R2 42
|
#define LCD_R2 42
|
||||||
#define LCD_R3 41
|
#define LCD_R3 41
|
||||||
#define LCD_R4 40
|
#define LCD_R4 40
|
||||||
|
|
||||||
#define LCD_G0 39
|
#define LCD_G0 39
|
||||||
#define LCD_G1 0
|
#define LCD_G1 0
|
||||||
#define LCD_G2 45
|
#define LCD_G2 45
|
||||||
#define LCD_G3 48
|
#define LCD_G3 48
|
||||||
#define LCD_G4 47
|
#define LCD_G4 47
|
||||||
#define LCD_G5 21
|
#define LCD_G5 21
|
||||||
|
|
||||||
#define LCD_B0 14
|
#define LCD_B0 14
|
||||||
#define LCD_B1 38
|
#define LCD_B1 38
|
||||||
#define LCD_B2 18
|
#define LCD_B2 18
|
||||||
#define LCD_B3 17
|
#define LCD_B3 17
|
||||||
#define LCD_B4 10
|
#define LCD_B4 10
|
||||||
|
|
||||||
// ── I2C bus (shared: CH422G + GT911) ──
|
// ── I2C bus (shared: CH422G + GT911) ──
|
||||||
#define I2C_MASTER_NUM ((i2c_port_t)0)
|
#define I2C_MASTER_NUM ((i2c_port_t)0)
|
||||||
#define I2C_MASTER_SDA 8
|
#define I2C_MASTER_SDA 8
|
||||||
#define I2C_MASTER_SCL 9
|
#define I2C_MASTER_SCL 9
|
||||||
|
|
||||||
// ── GT911 Touch ──
|
// ── GT911 Touch ──
|
||||||
#define GT911_ADDR 0x5D
|
#define GT911_ADDR 0x5D
|
||||||
#define TOUCH_INT -1
|
// #define TOUCH_INT -1
|
||||||
|
|
||||||
|
|||||||
@@ -3,21 +3,24 @@
|
|||||||
#define FW_VERSION "5.1"
|
#define FW_VERSION "5.1"
|
||||||
|
|
||||||
// ── ntfy.sh ──
|
// ── ntfy.sh ──
|
||||||
#define NTFY_SERVER "ntfy.sh"
|
#define NTFY_SERVER "ntfy.sh"
|
||||||
#define ALERT_TOPIC "ALERT_klubhaus_topic"
|
#define ALERT_TOPIC "ALERT_klubhaus_topic"
|
||||||
#define SILENCE_TOPIC "SILENCE_klubhaus_topic"
|
#define SILENCE_TOPIC "SILENCE_klubhaus_topic"
|
||||||
#define ADMIN_TOPIC "ADMIN_klubhaus_topic"
|
#define ADMIN_TOPIC "ADMIN_klubhaus_topic"
|
||||||
#define STATUS_TOPIC "STATUS_klubhaus_topic"
|
#define STATUS_TOPIC "STATUS_klubhaus_topic"
|
||||||
|
|
||||||
// ── Timing ──
|
// ── Timing ──
|
||||||
#define POLL_INTERVAL_MS 15000
|
#define POLL_INTERVAL_MS 15000
|
||||||
#define HEARTBEAT_INTERVAL_MS 300000
|
#define HEARTBEAT_INTERVAL_MS 300000
|
||||||
#define BOOT_GRACE_MS 5000
|
#define BOOT_GRACE_MS 5000
|
||||||
#define HOLD_TO_SILENCE_MS 3000
|
#define HOLD_TO_SILENCE_MS 3000
|
||||||
#define ALERT_TIMEOUT_MS 120000
|
#define ALERT_TIMEOUT_MS 120000
|
||||||
#define SILENCE_DISPLAY_MS 10000
|
#define SILENCE_DISPLAY_MS 10000
|
||||||
#define WIFI_CONNECT_TIMEOUT_MS 15000
|
#define WIFI_CONNECT_TIMEOUT_MS 15000
|
||||||
#define HTTP_TIMEOUT_MS 10000
|
#define HTTP_TIMEOUT_MS 10000
|
||||||
|
#define HINT_ANIMATION_MS 2000
|
||||||
|
#define HINT_MIN_BRIGHTNESS 30
|
||||||
|
#define HINT_MAX_BRIGHTNESS 60
|
||||||
|
|
||||||
// ── WiFi credential struct (populated in each board's secrets.h) ──
|
// ── WiFi credential struct (populated in each board's secrets.h) ──
|
||||||
struct WiFiCred {
|
struct WiFiCred {
|
||||||
|
|||||||
@@ -28,17 +28,21 @@ echo "[OK] TFT_eSPI 2.5.43 vendored + configured"
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
[tasks.install-libs-s3-43]
|
[tasks.install-libs-s3-43]
|
||||||
description = "Vendor Arduino_GFX into vendor/esp32-s3-lcd-43"
|
description = "Vendor LovyanGFX into vendor/esp32-s3-lcd-43"
|
||||||
run = """
|
run = """
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
if [ ! -d "vendor/esp32-s3-lcd-43/GFX_Library_for_Arduino" ]; then
|
|
||||||
echo "Cloning Arduino_GFX..."
|
# Clone LovyanGFX (latest)
|
||||||
git clone --depth 1 --branch v1.6.5 \
|
if [ ! -d "vendor/esp32-s3-lcd-43/LovyanGFX" ]; then
|
||||||
https://github.com/moononournation/Arduino_GFX.git \
|
echo "Cloning LovyanGFX..."
|
||||||
vendor/esp32-s3-lcd-43/GFX_Library_for_Arduino
|
git clone --depth 1 \
|
||||||
|
https://github.com/lovyan03/LovyanGFX.git \
|
||||||
|
vendor/esp32-s3-lcd-43/LovyanGFX
|
||||||
|
else
|
||||||
|
echo "LovyanGFX already exists, skipping"
|
||||||
fi
|
fi
|
||||||
echo "[OK] Arduino_GFX 1.6.5 vendored"
|
echo "[OK] LovyanGFX vendored"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[tasks.install-libs]
|
[tasks.install-libs]
|
||||||
@@ -52,12 +56,13 @@ description = "Compile ESP32-32E sketch"
|
|||||||
depends = ["install-libs"]
|
depends = ["install-libs"]
|
||||||
run = """
|
run = """
|
||||||
arduino-cli compile \
|
arduino-cli compile \
|
||||||
--fqbn "esp32:esp32:esp32:FlashSize=4M,PartitionScheme=default" \
|
--fqbn "esp32:esp32:waveshare_esp32_s3_touch_lcd_43:PSRAM=enabled,FlashSize=16M,USBMode=hwcdc,PartitionScheme=app3M_fat9M_16MB" \
|
||||||
--libraries ./libraries \
|
--libraries ./libraries \
|
||||||
--libraries ./vendor/esp32-32e \
|
--libraries ./vendor/esp32-s3-lcd-43 \
|
||||||
--build-property "compiler.cpp.extra_flags=-DDEBUG_MODE" \
|
--build-property "compiler.cpp.extra_flags=-DDEBUG_MODE -DBOARD_HAS_PSRAM" \
|
||||||
|
--build-property "build.extra_flags=-DCONFIG_ESP32S3_OLD_I2C_LEGACY_DEVICE_COMPAT_MODE=1" \
|
||||||
--warnings default \
|
--warnings default \
|
||||||
./boards/esp32-32e
|
./boards/esp32-s3-lcd-43
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[tasks.upload-32e]
|
[tasks.upload-32e]
|
||||||
@@ -84,7 +89,7 @@ run = """
|
|||||||
arduino-cli compile \
|
arduino-cli compile \
|
||||||
--fqbn "esp32:esp32:waveshare_esp32_s3_touch_lcd_43:PSRAM=enabled,FlashSize=16M,USBMode=hwcdc,PartitionScheme=app3M_fat9M_16MB" \
|
--fqbn "esp32:esp32:waveshare_esp32_s3_touch_lcd_43:PSRAM=enabled,FlashSize=16M,USBMode=hwcdc,PartitionScheme=app3M_fat9M_16MB" \
|
||||||
--libraries ./libraries \
|
--libraries ./libraries \
|
||||||
--libraries ./vendor/esp32-s3-lcd-43 \
|
--libraries ./vendor/esp32-s3-lcd-43/LovyanGFX \
|
||||||
--build-property "compiler.cpp.extra_flags=-DDEBUG_MODE -DBOARD_HAS_PSRAM" \
|
--build-property "compiler.cpp.extra_flags=-DDEBUG_MODE -DBOARD_HAS_PSRAM" \
|
||||||
--warnings default \
|
--warnings default \
|
||||||
./boards/esp32-s3-lcd-43
|
./boards/esp32-s3-lcd-43
|
||||||
|
|||||||
1
sketches/doorbell-touch/vendor/esp32-s3-lcd-43/LovyanGFX
vendored
Submodule
1
sketches/doorbell-touch/vendor/esp32-s3-lcd-43/LovyanGFX
vendored
Submodule
Submodule sketches/doorbell-touch/vendor/esp32-s3-lcd-43/LovyanGFX added at 42998359d8
Reference in New Issue
Block a user