diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index d9751fc5..489a0a35 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -264,6 +264,11 @@ elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_3_5B) set(BUILTIN_TEXT_FONT font_puhui_basic_16_4) set(BUILTIN_ICON_FONT font_awesome_16_4) set(DEFAULT_EMOJI_COLLECTION twemoji_32) +elseif(CONFIG_BOARD_TYPE_ESP32S3_Touch_LCD_3_49) + set(BOARD_TYPE "waveshare-s3-touch-lcd-3.49") + set(LVGL_TEXT_FONT font_puhui_basic_30_4) + set(LVGL_ICON_FONT font_awesome_30_4) + set(DEFAULT_EMOJI_COLLECTION twemoji_64) elseif(CONFIG_BOARD_TYPE_ESP32C6_LCD_1_69) set(BOARD_TYPE "waveshare-c6-lcd-1.69") set(BUILTIN_TEXT_FONT font_puhui_basic_20_4) diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 68753e16..b8017723 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -233,6 +233,9 @@ choice BOARD_TYPE config BOARD_TYPE_ESP32C6_Touch_AMOLED_1_43 bool "Waveshare ESP32-C6-Touch-AMOLOED-1.43" depends on IDF_TARGET_ESP32C6 + config BOARD_TYPE_ESP32S3_Touch_LCD_3_49 + bool "Waveshare ESP32-S3-Touch-LCD-3.49" + depends on IDF_TARGET_ESP32S3 config BOARD_TYPE_ESP32S3_Touch_LCD_3_5 bool "Waveshare ESP32-S3-Touch-LCD-3.5" depends on IDF_TARGET_ESP32S3 @@ -549,7 +552,7 @@ config USE_DEVICE_AEC || BOARD_TYPE_LICHUANG_DEV || BOARD_TYPE_ESP32S3_KORVO2_V3 || BOARD_TYPE_ESP32S3_Touch_AMOLED_1_75 \ || BOARD_TYPE_ESP32S3_Touch_AMOLED_2_06 || BOARD_TYPE_ESP32S3_Touch_LCD_4B || BOARD_TYPE_ESP32P4_WIFI6_Touch_LCD_4B \ || BOARD_TYPE_ESP32P4_WIFI6_Touch_LCD_XC || BOARD_TYPE_ESP_S3_LCD_EV_Board_2 || BOARD_TYPE_YUNLIAO_S3 \ - || BOARD_TYPE_ECHOEAR) + || BOARD_TYPE_ECHOEAR || BOARD_TYPE_ESP32S3_Touch_LCD_3_49) help 因为性能不够,不建议和微信聊天界面风格同时开启 diff --git a/main/boards/waveshare-s3-touch-lcd-3.49/README.md b/main/boards/waveshare-s3-touch-lcd-3.49/README.md new file mode 100644 index 00000000..657331d3 --- /dev/null +++ b/main/boards/waveshare-s3-touch-lcd-3.49/README.md @@ -0,0 +1,3 @@ +新增 微雪 开发板: ESP32-S3-Touch-LCD-3.49 +产品链接: +https://www.waveshare.net/shop/ESP32-S3-Touch-LCD-3.49.htm \ No newline at end of file diff --git a/main/boards/waveshare-s3-touch-lcd-3.49/config.h b/main/boards/waveshare-s3-touch-lcd-3.49/config.h new file mode 100644 index 00000000..e2e9b79a --- /dev/null +++ b/main/boards/waveshare-s3-touch-lcd-3.49/config.h @@ -0,0 +1,62 @@ +#ifndef _BOARD_CONFIG_H_ +#define _BOARD_CONFIG_H_ + +#include +#include +#include "lvgl.h" + +#define AUDIO_INPUT_SAMPLE_RATE 24000 +#define AUDIO_OUTPUT_SAMPLE_RATE 24000 + +#define AUDIO_INPUT_REFERENCE true + +#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_7 +#define AUDIO_I2S_GPIO_WS GPIO_NUM_46 +#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_15 +#define AUDIO_I2S_GPIO_DIN GPIO_NUM_6 +#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_45 + +#define AUDIO_CODEC_PA_PIN GPIO_NUM_NC +#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_47 +#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_48 +#define Dev_Touch_I2C_SDA_PIN GPIO_NUM_17 +#define Dev_Touch_I2C_SCL_PIN GPIO_NUM_18 +#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR +#define AUDIO_CODEC_ES7210_ADDR ES7210_CODEC_DEFAULT_ADDR + +#define I2C_Touch_ADDRESS 0x3b +#define I2C_Touch_SDA_PIN GPIO_NUM_17 +#define I2C_Touch_SCL_PIN GPIO_NUM_18 + +#define BOOT_BUTTON_GPIO GPIO_NUM_0 +#define PWR_BUTTON_GPIO GPIO_NUM_16 + +#define LCD_CS GPIO_NUM_9 +#define LCD_PCLK GPIO_NUM_10 +#define LCD_D0 GPIO_NUM_11 +#define LCD_D1 GPIO_NUM_12 +#define LCD_D2 GPIO_NUM_13 +#define LCD_D3 GPIO_NUM_14 +#define LCD_RST GPIO_NUM_21 +#define LCD_LIGHT (-1) + +#define DISPLAY_WIDTH 172 +#define DISPLAY_HEIGHT 640 +#define LVGL_DMA_BUFF_LEN (DISPLAY_WIDTH * 64 * 2) +#define LVGL_SPIRAM_BUFF_LEN (DISPLAY_WIDTH * DISPLAY_HEIGHT * 2) + +#define DISPLAY_ROTATION_90 false + +#define DISPLAY_MIRROR_X false +#define DISPLAY_MIRROR_Y false +#define DISPLAY_SWAP_XY false + +#define DISPLAY_OFFSET_X 0 +#define DISPLAY_OFFSET_Y 0 + + +#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_8 +#define DISPLAY_BACKLIGHT_OUTPUT_INVERT true + + +#endif // _BOARD_CONFIG_H_ diff --git a/main/boards/waveshare-s3-touch-lcd-3.49/config.json b/main/boards/waveshare-s3-touch-lcd-3.49/config.json new file mode 100644 index 00000000..32de3cff --- /dev/null +++ b/main/boards/waveshare-s3-touch-lcd-3.49/config.json @@ -0,0 +1,12 @@ +{ + "target": "esp32s3", + "builds": [ + { + "name": "waveshare-s3-touch-lcd-3.49", + "sdkconfig_append": [ + "CONFIG_USE_WECHAT_MESSAGE_STYLE=n", + "CONFIG_USE_DEVICE_AEC=y" + ] + } + ] +} \ No newline at end of file diff --git a/main/boards/waveshare-s3-touch-lcd-3.49/custom_lcd_display.cc b/main/boards/waveshare-s3-touch-lcd-3.49/custom_lcd_display.cc new file mode 100644 index 00000000..a5a466f3 --- /dev/null +++ b/main/boards/waveshare-s3-touch-lcd-3.49/custom_lcd_display.cc @@ -0,0 +1,145 @@ +#include "custom_lcd_display.h" + +#include "lcd_display.h" + +#include +#include +#include +#include +#include "assets/lang_config.h" +#include +#include "settings.h" + +#include "esp_lcd_panel_io.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" + +#include "config.h" + +#include "board.h" + +#define TAG "CustomLcdDisplay" + +static SemaphoreHandle_t trans_done_sem = NULL; +static uint16_t *trans_buf_1; + +#if (DISPLAY_ROTATION_90 == true) +static uint16_t *dest_map; +#endif + + +bool CustomLcdDisplay::lvgl_port_flush_io_ready_callback(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx) { + BaseType_t taskAwake = pdFALSE; + lv_display_t *disp_drv = (lv_display_t *)user_ctx; + assert(disp_drv != NULL); + if (trans_done_sem) { + xSemaphoreGiveFromISR(trans_done_sem, &taskAwake); + } + return false; +} + +void CustomLcdDisplay::lvgl_port_flush_callback(lv_display_t *drv, const lv_area_t *area, uint8_t *color_map) { + assert(drv != NULL); + esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t)lv_display_get_user_data(drv); + assert(panel_handle != NULL); + + lv_draw_sw_rgb565_swap(color_map, lv_area_get_width(area) * lv_area_get_height(area)); + +#if (DISPLAY_ROTATION_90 == true) + lv_display_rotation_t rotation = lv_display_get_rotation(drv); + lv_area_t rotated_area; + if(rotation != LV_DISPLAY_ROTATION_0) { + lv_color_format_t cf = lv_display_get_color_format(drv); + /*Calculate the position of the rotated area*/ + rotated_area = *area; + lv_display_rotate_area(drv, &rotated_area); + /*Calculate the source stride (bytes in a line) from the width of the area*/ + uint32_t src_stride = lv_draw_buf_width_to_stride(lv_area_get_width(area), cf); + /*Calculate the stride of the destination (rotated) area too*/ + uint32_t dest_stride = lv_draw_buf_width_to_stride(lv_area_get_width(&rotated_area), cf); + /*Have a buffer to store the rotated area and perform the rotation*/ + + int32_t src_w = lv_area_get_width(area); + int32_t src_h = lv_area_get_height(area); + lv_draw_sw_rotate(color_map, dest_map, src_w, src_h, src_stride, dest_stride, rotation, cf); + /*Use the rotated area and rotated buffer from now on*/ + area = &rotated_area; + } +#endif + const int flush_coun = (LVGL_SPIRAM_BUFF_LEN / LVGL_DMA_BUFF_LEN); + const int offgap = (DISPLAY_HEIGHT / flush_coun); + const int dmalen = (LVGL_DMA_BUFF_LEN / 2); + int offsetx1 = 0; + int offsety1 = 0; + int offsetx2 = DISPLAY_WIDTH; + int offsety2 = offgap; +#if (DISPLAY_ROTATION_90 == true) + uint16_t *map = (uint16_t*)dest_map; +#else + uint16_t *map = (uint16_t*)color_map; +#endif + xSemaphoreGive(trans_done_sem); + + for(int i = 0; i +#include "i2c_device.h" +#include +#include +#include +#include +#include +#include + +#include +#include "esp_io_expander_tca9554.h" + +#include "esp_lcd_axs15231b.h" + +#include "custom_lcd_display.h" + +#include + +#define TAG "waveshare_lcd_3_39" + + +static const axs15231b_lcd_init_cmd_t lcd_init_cmds[] = { + {0x11, (uint8_t []){0x00}, 0, 100}, + {0x29, (uint8_t []){0x00}, 0, 100}, +}; + +class CustomBoard : public WifiBoard { +private: + Button boot_button_; + Button pwr_button_; + i2c_master_bus_handle_t i2c_bus_; + esp_io_expander_handle_t io_expander = NULL; + LcdDisplay* display_; + i2c_master_dev_handle_t disp_touch_dev_handle = NULL; + lv_indev_t *touch_indev = NULL; //touch + bool is_PwrControlEn = false; + + void InitializeI2c() { + // Initialize I2C peripheral + i2c_master_bus_config_t i2c_bus_cfg = { + .i2c_port = (i2c_port_t)I2C_NUM_0, + .sda_io_num = AUDIO_CODEC_I2C_SDA_PIN, + .scl_io_num = AUDIO_CODEC_I2C_SCL_PIN, + .clk_source = I2C_CLK_SRC_DEFAULT, + .glitch_ignore_cnt = 7, + .intr_priority = 0, + .trans_queue_depth = 0, + .flags = { + .enable_internal_pullup = 1, + }, + }; + ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &i2c_bus_)); + } + + void InitializeTca9554(void) { + esp_err_t ret = esp_io_expander_new_i2c_tca9554(i2c_bus_, ESP_IO_EXPANDER_I2C_TCA9554_ADDRESS_000, &io_expander); + if(ret != ESP_OK) + ESP_LOGE(TAG, "TCA9554 create returned error"); + ret = esp_io_expander_set_dir(io_expander, IO_EXPANDER_PIN_NUM_7 | IO_EXPANDER_PIN_NUM_6, IO_EXPANDER_OUTPUT); + ESP_ERROR_CHECK(ret); + vTaskDelay(pdMS_TO_TICKS(100)); + ret = esp_io_expander_set_level(io_expander, IO_EXPANDER_PIN_NUM_7 | IO_EXPANDER_PIN_NUM_6, 1); + ESP_ERROR_CHECK(ret); + } + + void InitializeSpi() { + ESP_LOGI(TAG, "Initialize QSPI bus"); + spi_bus_config_t buscfg = {}; + buscfg.data0_io_num = LCD_D0; + buscfg.data1_io_num = LCD_D1; + buscfg.data2_io_num = LCD_D2; + buscfg.data3_io_num = LCD_D3; + buscfg.sclk_io_num = LCD_PCLK; + buscfg.max_transfer_sz = LVGL_DMA_BUFF_LEN; + ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO)); + } + + void InitializeLcdDisplay() { + esp_lcd_panel_io_handle_t panel_io = nullptr; + esp_lcd_panel_handle_t panel = nullptr; + // RESET PIN INIT + gpio_config_t gpio_conf = {}; + gpio_conf.intr_type = GPIO_INTR_DISABLE; + gpio_conf.mode = GPIO_MODE_OUTPUT; + gpio_conf.pin_bit_mask = ((uint64_t)0x01<0 && buff[1]<5) { + indevData->state = LV_INDEV_STATE_PRESSED; + if(pointX > DISPLAY_WIDTH) pointX = DISPLAY_WIDTH; + if(pointY > DISPLAY_HEIGHT) pointY = DISPLAY_HEIGHT; + indevData->point.x = pointY; + indevData->point.y = (DISPLAY_HEIGHT-pointX); + ESP_LOGE("Touch","(%ld,%ld)",indevData->point.x,indevData->point.y); + } else { + indevData->state = LV_INDEV_STATE_RELEASED; + } + } + + void GetPwrCurrentState() { + if(gpio_get_level(PWR_BUTTON_GPIO)) { + is_PwrControlEn = true; + } + } + +public: + CustomBoard() : + boot_button_(BOOT_BUTTON_GPIO), + pwr_button_(PWR_BUTTON_GPIO) { + InitializeI2c(); + InitializeTca9554(); + InitializeSpi(); + InitializeLcdDisplay(); + InitializeButtons(); + InitializeTouch(); + GetPwrCurrentState(); + GetBacklight()->RestoreBrightness(); + } + + virtual AudioCodec* GetAudioCodec() override { + static BoxAudioCodec audio_codec( + i2c_bus_, + AUDIO_INPUT_SAMPLE_RATE, + AUDIO_OUTPUT_SAMPLE_RATE, + AUDIO_I2S_GPIO_MCLK, + AUDIO_I2S_GPIO_BCLK, + AUDIO_I2S_GPIO_WS, + AUDIO_I2S_GPIO_DOUT, + AUDIO_I2S_GPIO_DIN, + AUDIO_CODEC_PA_PIN, + AUDIO_CODEC_ES8311_ADDR, + AUDIO_CODEC_ES7210_ADDR, + AUDIO_INPUT_REFERENCE); + return &audio_codec; + } + + virtual Display* GetDisplay() override { + return display_; + } + + virtual Backlight* GetBacklight() override { + static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT); + return &backlight; + } +}; + +DECLARE_BOARD(CustomBoard); \ No newline at end of file