#define LGFX_USE_V1
#include <lvgl.h>
#include <lv_conf_internal.h>
#include <lv_conf.h>
#include "demos/lv_demos.h"
#include <LovyanGFX.hpp>
#include "CST816T.h"
#define I2C_SDA 21
#define I2C_SCL 22
class LGFX : public lgfx::LGFX_Device {
lgfx::Panel_ST7789 _panel_instance;
lgfx::Bus_SPI _bus_instance;
lgfx::Light_PWM _light_instance;
public:
LGFX(void) {
{
auto cfg = _bus_instance.config();
// SPIバスの設定
cfg.spi_host = VSPI_HOST; // 使用するSPIを選択 ESP32-S2,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
// ※ ESP-IDFバージョンアップに伴い、VSPI_HOST , HSPI_HOSTの記述は非推奨になるため、エラーが出る場合は代わりにSPI2_HOST , SPI3_HOSTを使用してください。
cfg.spi_mode = 0; // SPI通信モードを設定 (0 ~ 3)
cfg.freq_write = 80000000; // 传输时的SPI时钟(最高80MHz,四舍五入为80MHz除以整数得到的值)
cfg.freq_read = 600000; // 接收时的SPI时钟
cfg.spi_3wire = false; // 受信をMOSIピンで行う場合はtrueを設定
cfg.use_lock = true; // 使用事务锁时设置为 true
cfg.dma_channel = 0; // 使用するDMAチャンネルを設定 (0=DMA不使用 / 1=1ch / 2=ch / SPI_DMA_CH_AUTO=自動設定)
// ※ ESP-IDFバージョンアップに伴い、DMAチャンネルはSPI_DMA_CH_AUTO(自動設定)が推奨になりました。1ch,2chの指定は非推奨になります。
cfg.pin_sclk = 18; // SPIのSCLKピン番号を設定
cfg.pin_mosi = 19; // SPIのCLKピン番号を設定
cfg.pin_miso = -1; // SPIのMISOピン番号を設定 (-1 = disable)
cfg.pin_dc = 16; // SPIのD/Cピン番号を設定 (-1 = disable)
_bus_instance.config(cfg); // 設定値をバスに反映します。
_panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
_panel_instance.setLight(&_light_instance);
}
{
auto cfg = _light_instance.config();
cfg.pin_bl = 4;
cfg.invert = false;
cfg.freq = 44100;
cfg.pwm_channel = 7;
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance);
}
{ // 表示パネル制御の設定を行います。
auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。
cfg.pin_cs = 5; // CSが接続されているピン番号 (-1 = disable)
cfg.pin_rst = 23; // RSTが接続されているピン番号 (-1 = disable)
cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)
// ※ 以下の設定値はパネル毎に一般的な初期値が設定さ BUSYが接続されているピン番号 (-1 = disable)れていますので、不明な項目はコメントアウトして試してみてください。
cfg.memory_width = 240; // ドライバICがサポートしている最大の幅
cfg.memory_height = 280; // ドライバICがサポートしている最大の高さ
cfg.panel_width = 240; // 実際に表示可能な幅
cfg.panel_height = 280; // 実際に表示可能な高さ
cfg.offset_x = 0; // パネルのX方向オフセット量
cfg.offset_y = 20; // パネルのY方向オフセット量
cfg.offset_rotation = 0; //值在旋转方向的偏移0~7(4~7是倒置的)
cfg.dummy_read_pixel = 8; // 在读取像素之前读取的虚拟位数
cfg.dummy_read_bits = 1; // 读取像素以外的数据之前的虚拟读取位数
cfg.readable = false; // 如果可以读取数据,则设置为 true
cfg.invert = true; // 如果面板的明暗反转,则设置为 true
cfg.rgb_order = true; // 如果面板的红色和蓝色被交换,则设置为 true
cfg.dlen_16bit = false; // 对于以 16 位单位发送数据长度的面板,设置为 true
cfg.bus_shared = false; // 如果总线与 SD 卡共享,则设置为 true(使用 drawJpgFile 等执行总线控制)
_panel_instance.config(cfg);
}
setPanel(&_panel_instance); // 使用するパネルをセットします。
}
};
// 準備したクラスのインスタンスを作成します。
LGFX tft;
CST816T cst816t(I2C_SDA, I2C_SCL);
/*更改为您的屏幕分辨率*/
static const uint32_t screenWidth = 240;
static const uint32_t screenHeight = 280;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[2][screenWidth * 30];
#if LV_USE_LOG != 0
/* Serial debugging */
void my_print(lv_log_level_t level, const char *file, uint32_t line, const char *fn_name, const char *dsc) {
Serial.printf("%s(%s)@%d->%s\r\n", file, fn_name, line, dsc);
Serial.flush();
}
#endif
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
if (tft.getStartCount() == 0) {
tft.endWrite();
}
tft.pushImageDMA(area->x1, area->y1, area->x2 - area->x1 + 1, area->y2 - area->y1 + 1, (lgfx::rgb565_t *)&color_p->full);
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}
/*Read the touchpad*/
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {
TouchInfos tp;
tp = cst816t.GetTouchInfo();
bool touched = (tp.touching == 1&&tp.isValid == 1);
if (!touched)
{
data->state = LV_INDEV_STATE_REL;
}
else
{
data->state = LV_INDEV_STATE_PR;
/*Set the coordinates*/
data->point.x = tp.x;
data->point.y = tp.y;
// Serial.printf("touchX = %d, touchY = %d\n", tp.x, tp.y);
}
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug */
Serial.println("Hello Arduino! (V8.2.X)");
Serial.println("I am LVGL_Arduino");
tft.init();
cst816t.begin();
tft.initDMA();
tft.startWrite();
lv_init();
#if LV_USE_LOG != 0
lv_log_register_print_cb(my_print); /* register print function for debugging */
#endif
lv_disp_draw_buf_init(&draw_buf, buf[0], buf[1], screenWidth * 30);
/*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 = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
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 = my_touchpad_read;
lv_indev_drv_register(&indev_drv);
#if 0
/* Create simple label */
lv_obj_t *label = lv_label_create( lv_scr_act() );
lv_label_set_text( label, "Hello Arduino! (V8.0.X)" );
lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
#else
/* Try an example from the lv_examples Arduino library
make sure to include it as written above.
lv_example_btn_1();
*/
// uncomment one of these demos
lv_demo_widgets(); // OK
//lv_demo_benchmark(); // OK
//lv_demo_keypad_encoder();
// works, but I haven't an encoder
//lv_demo_music(); // NOK
//lv_demo_printer();
//lv_demo_stress(); // seems to be OK
#endif
Serial.println("Setup done");
}
void loop() {
lv_timer_handler(); /* let the GUI do its work */
delay(5);
}