diff --git a/CYD-Klipper/boards/esp32-CROWPANEL-35C.json b/CYD-Klipper/boards/esp32-CROWPANEL-35C.json new file mode 100644 index 0000000..56f68e4 --- /dev/null +++ b/CYD-Klipper/boards/esp32-CROWPANEL-35C.json @@ -0,0 +1,55 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32s3_out.ld", + "partitions": "default_16MB.csv", + "memory_type": "qio_opi" + }, + "core": "esp32", + "extra_flags": [ + "-DCYD_SCREEN_HEIGHT_PX=320", + "-DCYD_SCREEN_WIDTH_PX=480", + "-DCYD_SCREEN_GAP_PX=10", + "-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45", + "-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45", + "-DCYD_SCREEN_FONT=lv_font_montserrat_16", + "-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12", + "-DCYD_SCREEN_SIDEBAR_SIZE_PX=50", + "-DCYD_SCREEN_DRIVER_ESP32_CROWPANEL_35C=1", + "-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "esp32s3" + }, + "connectivity": [ + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "esp32-8048S043C-SD", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "use_1200bps_touch": true, + "wait_for_upload_port": true, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://www.elecrow.com/esp-terminal-with-esp32-3-5-inch-parallel-480x320-tft-capacitive-touch-display-rgb-by-chip-ili9488.html", + "vendor": "CROWPANEL" + } \ No newline at end of file diff --git a/CYD-Klipper/platformio.ini b/CYD-Klipper/platformio.ini index d1e7486..c39c3d1 100644 --- a/CYD-Klipper/platformio.ini +++ b/CYD-Klipper/platformio.ini @@ -102,3 +102,14 @@ lib_deps = plageoj/UrlEncode@^1.0.1 knolleary/PubSubClient@^2.8 WiFiClientSecure + +[env:esp32-CROWPANEL-35C] +board = esp32-CROWPANEL-35C +lib_deps = + SPI + https://github.com/suchmememanyskill/lvgl + https://github.com/lovyan03/LovyanGFX@1.2.0 + bblanchon/ArduinoJson@^7.0.0 + plageoj/UrlEncode@^1.0.1 + knolleary/PubSubClient@^2.8 + WiFiClientSecure diff --git a/CYD-Klipper/src/core/device/ESP32-CROWPANEL-35C.cpp b/CYD-Klipper/src/core/device/ESP32-CROWPANEL-35C.cpp new file mode 100644 index 0000000..554646a --- /dev/null +++ b/CYD-Klipper/src/core/device/ESP32-CROWPANEL-35C.cpp @@ -0,0 +1,177 @@ +// Adapted from https://github.com/OzInFl/Elecrow-3.5-RGB-TFT-SQUARELINE-EXAMPLE + +#ifdef CYD_SCREEN_DRIVER_ESP32_CROWPANEL_35C +#include "../screen_driver.h" +#include "lvgl.h" +#include "../../conf/global_config.h" +#include +#include +#include + +#ifdef CYD_SCREEN_VERTICAL +#error "Vertical screen not supported with the ESP32_CROWPANEL_28R driver" +#endif + +static lv_disp_draw_buf_t draw_buf; +static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10]; + +#define LCD_BL 46 +#define SDA_FT6236 38 +#define SCL_FT6236 39 +#define I2C_TOUCH_ADDR 0x38 + +class LGFX : public lgfx::LGFX_Device +{ + lgfx::Panel_ILI9488 _panel_instance; + lgfx::Bus_Parallel16 _bus_instance; + lgfx::Touch_FT5x06 _touch_instance; + +public: + LGFX() + { + auto bus_cfg = _bus_instance.config(); + bus_cfg.port = 0; + bus_cfg.freq_write = 80000000; + bus_cfg.pin_wr = 18; + bus_cfg.pin_rd = 48; + bus_cfg.pin_rs = 45; + bus_cfg.pin_d0 = 47; + bus_cfg.pin_d1 = 21; + bus_cfg.pin_d2 = 14; + bus_cfg.pin_d3 = 13; + bus_cfg.pin_d4 = 12; + bus_cfg.pin_d5 = 11; + bus_cfg.pin_d6 = 10; + bus_cfg.pin_d7 = 9; + bus_cfg.pin_d8 = 3; + bus_cfg.pin_d9 = 8; + bus_cfg.pin_d10 = 16; + bus_cfg.pin_d11 = 15; + bus_cfg.pin_d12 = 7; + bus_cfg.pin_d13 = 6; + bus_cfg.pin_d14 = 5; + bus_cfg.pin_d15 = 4; + _bus_instance.config(bus_cfg); + _panel_instance.setBus(&_bus_instance); + + auto panel_cfg = _panel_instance.config(); + panel_cfg.pin_cs = -1; + panel_cfg.pin_rst = -1; + panel_cfg.pin_busy = -1; + panel_cfg.memory_width = 320; + panel_cfg.memory_height = 480; + panel_cfg.panel_width = 320; + panel_cfg.panel_height = 480; + panel_cfg.offset_x = 0; + panel_cfg.offset_y = 0; + panel_cfg.offset_rotation = 0; + panel_cfg.dummy_read_pixel = 8; + panel_cfg.dummy_read_bits = 1; + panel_cfg.readable = true; + panel_cfg.invert = false; + panel_cfg.rgb_order = false; + panel_cfg.dlen_16bit = true; + panel_cfg.bus_shared = true; + + _panel_instance.config(panel_cfg); + + auto touch_cfg = _touch_instance.config(); + touch_cfg.x_min = 0; + touch_cfg.x_max = 319; + touch_cfg.y_min = 0; + touch_cfg.y_max = 479; + touch_cfg.pin_int = -1; + touch_cfg.bus_shared = false; + touch_cfg.offset_rotation = 0; + + touch_cfg.i2c_port = 1; + touch_cfg.i2c_addr = 0x38; + touch_cfg.pin_sda = 38; + touch_cfg.pin_scl = 39; + touch_cfg.freq = 400000; + + _touch_instance.config(touch_cfg); + _panel_instance.setTouch(&_touch_instance); + + setPanel(&_panel_instance); + } +}; + +LGFX tft; + +void screen_setBrightness(unsigned char brightness) +{ + // calculate duty, 4095 from 2 ^ 12 - 1 + uint32_t duty = (4095 / 255) * brightness; + + // write duty to LEDC + ledcWrite(0, duty); +} + +void set_invert_display() +{ + // TODO +} + +void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) +{ + uint32_t w = (area->x2 - area->x1 + 1); + uint32_t h = (area->y2 - area->y1 + 1); + + tft.startWrite(); + tft.setAddrWindow(area->x1, area->y1, w, h); + tft.writePixels((lgfx::rgb565_t *)&color_p->full, w * h); + tft.endWrite(); + + lv_disp_flush_ready(disp); +} + +void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) +{ + uint16_t touchX, touchY; + + bool touched = tft.getTouch(&touchX, &touchY); + + if (touchX > CYD_SCREEN_WIDTH_PX || touchY > CYD_SCREEN_HEIGHT_PX) + { + LOG_LN("Y or y outside of expected parameters.."); + } + else + { + data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; + data->point.x = touchX; + data->point.y = touchY; + } +} + +void screen_setup() +{ + tft.begin(); + tft.setRotation(global_config.rotate_screen ? 2 : 0); + + delay(500); + + ledcSetup(0, 5000, 12); + ledcAttachPin(LCD_BL, 0); + + lv_init(); + lv_disp_draw_buf_init(&draw_buf, buf, NULL, CYD_SCREEN_WIDTH_PX * CYD_SCREEN_HEIGHT_PX / 10); + + /*Initialize the display*/ + static lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.hor_res = CYD_SCREEN_WIDTH_PX; + disp_drv.ver_res = CYD_SCREEN_HEIGHT_PX; + disp_drv.flush_cb = screen_lv_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 = screen_lv_touchRead; + lv_indev_drv_register(&indev_drv); +} + +#endif \ No newline at end of file