diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 9ca4c9de..8f925d0b 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -291,7 +291,8 @@ elseif(CONFIG_BOARD_TYPE_ESP_VOCAT) set(BUILTIN_ICON_FONT font_awesome_20_4) set(DEFAULT_EMOJI_COLLECTION twemoji_64) set(EMOTE_RESOLUTION "360_360") - # set(EMOTE_EXTERNAL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/boards/esp-vocat/assets") + set(ESP_VOCAT_ASSETS_STAGING "${CMAKE_BINARY_DIR}/esp-vocat-assets") + set(EMOTE_EXTERNAL_PATH "${ESP_VOCAT_ASSETS_STAGING}") elseif(CONFIG_BOARD_TYPE_ESP_SENSAIRSHUTTLE) set(BOARD_TYPE "esp-sensairshuttle") set(BUILTIN_TEXT_FONT font_puhui_basic_16_4) @@ -537,6 +538,12 @@ elseif(CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_4_3) set(BUILTIN_TEXT_FONT font_puhui_basic_30_4) set(BUILTIN_ICON_FONT font_awesome_30_4) set(DEFAULT_EMOJI_COLLECTION twemoji_64) +elseif(CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_5) + set(MANUFACTURER "waveshare") + set(BOARD_TYPE "esp32-p4-wifi6-touch-lcd") + set(BUILTIN_TEXT_FONT font_puhui_basic_30_4) + set(BUILTIN_ICON_FONT font_awesome_30_4) + set(DEFAULT_EMOJI_COLLECTION twemoji_64) elseif(CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_7B) set(MANUFACTURER "waveshare") set(BOARD_TYPE "esp32-p4-wifi6-touch-lcd") @@ -1102,6 +1109,34 @@ if(XIAOZHI_FONTS_COMPONENT_PATH) set(XIAOZHI_FONTS_PATH "${XIAOZHI_FONTS_COMPONENT_PATH}") endif() +if(CONFIG_BOARD_TYPE_ESP_VOCAT) + find_component_by_pattern("esp_emote_assets" EMOTE_ASSETS_COMPONENT EMOTE_ASSETS_PATH) + if(EMOTE_ASSETS_PATH) + file(REMOVE_RECURSE "${ESP_VOCAT_ASSETS_STAGING}") + file(REMOVE + "${CMAKE_BINARY_DIR}/expression_assets.bin" + "${CMAKE_BINARY_DIR}/expression_assets.bin.validated" + ) + file(MAKE_DIRECTORY "${ESP_VOCAT_ASSETS_STAGING}/360_360") + file(MAKE_DIRECTORY "${ESP_VOCAT_ASSETS_STAGING}/emoji_large") + file(COPY "${EMOTE_ASSETS_PATH}/emoji_large/" DESTINATION "${ESP_VOCAT_ASSETS_STAGING}/emoji_large") + file(COPY "${EMOTE_ASSETS_PATH}/360_360/layout.json" DESTINATION "${ESP_VOCAT_ASSETS_STAGING}/360_360") + file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/boards/esp-vocat/assets/360_360/emote.json" + DESTINATION "${ESP_VOCAT_ASSETS_STAGING}/360_360") + file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/boards/esp-vocat/emoji/low_battery.eaf" + DESTINATION "${ESP_VOCAT_ASSETS_STAGING}/emoji_large") + file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/boards/esp-vocat/emoji/battery_connected.eaf" + DESTINATION "${ESP_VOCAT_ASSETS_STAGING}/emoji_large") + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + "${CMAKE_CURRENT_SOURCE_DIR}/boards/esp-vocat/assets/360_360/emote.json" + "${CMAKE_CURRENT_SOURCE_DIR}/boards/esp-vocat/emoji/low_battery.eaf" + "${CMAKE_CURRENT_SOURCE_DIR}/boards/esp-vocat/emoji/battery_connected.eaf" + ) + else() + message(WARNING "esp_emote_assets component not found; ESP-VoCat custom emotes will be skipped") + endif() +endif() + if(CONFIG_BOARD_TYPE_ESP_HI) set(URL "https://github.com/espressif2022/image_player/raw/main/test_apps/test_8bit") set(EMOJI_DIR "${CMAKE_BINARY_DIR}/emoji") @@ -1267,7 +1302,11 @@ if ("${size}" AND "${offset}") set(ASSETS_PARTITION "assets") set(ASSETS_FILE "${CMAKE_BINARY_DIR}/${ASSETS_NAME}.bin") - build_speaker_assets_bin("${ASSETS_PARTITION}" ${EMOTE_RESOLUTION} ${ASSETS_FILE} ${CONFIG_MMAP_FILE_NAME_LENGTH}) + if(EMOTE_EXTERNAL_PATH) + build_speaker_assets_bin("${ASSETS_PARTITION}" ${EMOTE_RESOLUTION} ${ASSETS_FILE} ${CONFIG_MMAP_FILE_NAME_LENGTH} "${EMOTE_EXTERNAL_PATH}") + else() + build_speaker_assets_bin("${ASSETS_PARTITION}" ${EMOTE_RESOLUTION} ${ASSETS_FILE} ${CONFIG_MMAP_FILE_NAME_LENGTH}) + endif() message(STATUS "Generated emote assets: ${ASSETS_FILE} -> ${ASSETS_PARTITION} partition") esptool_py_flash_to_partition(flash "${ASSETS_PARTITION}" "${ASSETS_FILE}") elseif(CONFIG_FLASH_NONE_ASSETS) diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 43beeef0..841fbeff 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -429,6 +429,9 @@ choice BOARD_TYPE config BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_4_3 bool "Waveshare ESP32-P4-WIFI6-Touch-LCD-4.3" depends on IDF_TARGET_ESP32P4 + config BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_5 + bool "Waveshare ESP32-P4-WIFI6-Touch-LCD-5" + depends on IDF_TARGET_ESP32P4 config BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_7B bool "Waveshare ESP32-P4-WIFI6-Touch-LCD-7B" depends on IDF_TARGET_ESP32P4 @@ -923,7 +926,7 @@ config USE_DEVICE_AEC default n depends on USE_AUDIO_PROCESSOR && (BOARD_TYPE_ESP_BOX_3 || BOARD_TYPE_ESP_BOX || BOARD_TYPE_ESP_BOX_LITE \ || BOARD_TYPE_LICHUANG_DEV_S3 || BOARD_TYPE_RYMCU_BIGSMART || BOARD_TYPE_ESP_KORVO2_V3 || BOARD_TYPE_WAVESHARE_ESP32_S3_TOUCH_AMOLED_1_75|| BOARD_TYPE_WAVESHARE_ESP32_S3_TOUCH_AMOLED_1_75C || BOARD_TYPE_WAVESHARE_ESP32_S3_TOUCH_LCD_1_83\ - || BOARD_TYPE_WAVESHARE_ESP32_S3_TOUCH_AMOLED_2_06 || BOARD_TYPE_WAVESHARE_ESP32_S3_TOUCH_LCD_4B || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_4B || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_4_3 \ + || BOARD_TYPE_WAVESHARE_ESP32_S3_TOUCH_AMOLED_2_06 || BOARD_TYPE_WAVESHARE_ESP32_S3_TOUCH_LCD_4B || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_4B || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_4_3 || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_5 \ || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_7B \ || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_3_4C || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_4C || BOARD_TYPE_ESP_S3_LCD_EV_Board_2 || BOARD_TYPE_YUNLIAO_S3 \ || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_7 || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_8 || BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_10_1 \ diff --git a/main/boards/esp-vocat/assets/360_360/emote.json b/main/boards/esp-vocat/assets/360_360/emote.json new file mode 100644 index 00000000..8310ad10 --- /dev/null +++ b/main/boards/esp-vocat/assets/360_360/emote.json @@ -0,0 +1,24 @@ +[ + {"emote": "happy", "src": "Happy.eaf", "loop": true, "fps": 20}, + {"emote": "laughing", "src": "Happy.eaf", "loop": true, "fps": 20}, + {"emote": "funny", "src": "Happy.eaf", "loop": true, "fps": 20}, + {"emote": "loving", "src": "Happy.eaf", "loop": true, "fps": 20}, + {"emote": "embarrassed", "src": "Happy.eaf", "loop": true, "fps": 20}, + {"emote": "confident", "src": "Happy.eaf", "loop": true, "fps": 20}, + {"emote": "delicious", "src": "Happy.eaf", "loop": true, "fps": 20}, + {"emote": "sad", "src": "Sad.eaf", "loop": true, "fps": 20}, + {"emote": "crying", "src": "cry.eaf", "loop": true, "fps": 20}, + {"emote": "sleepy", "src": "sleep.eaf", "loop": true, "fps": 20}, + {"emote": "silly", "src": "Happy.eaf", "loop": true, "fps": 20}, + {"emote": "angry", "src": "angry.eaf", "loop": true, "fps": 20}, + {"emote": "surprised", "src": "Happy.eaf", "loop": true, "fps": 20}, + {"emote": "shocked", "src": "shocked.eaf", "loop": true, "fps": 20}, + {"emote": "thinking", "src": "confused.eaf", "loop": true, "fps": 20}, + {"emote": "winking", "src": "neutral.eaf", "loop": true, "fps": 20}, + {"emote": "relaxed", "src": "Happy.eaf", "loop": true, "fps": 20}, + {"emote": "confused", "src": "confused.eaf", "loop": true, "fps": 20}, + {"emote": "neutral", "src": "winking.eaf", "loop": false, "fps": 20}, + {"emote": "idle", "src": "neutral.eaf", "loop": false, "fps": 20}, + {"emote": "low_battery", "src": "low_battery.eaf", "loop": false, "fps": 20}, + {"emote": "battery_connected", "src": "battery_connected.eaf", "loop": false, "fps": 20} +] diff --git a/main/boards/esp-vocat/emoji/battery_connected.eaf b/main/boards/esp-vocat/emoji/battery_connected.eaf new file mode 100644 index 00000000..d75df3f5 Binary files /dev/null and b/main/boards/esp-vocat/emoji/battery_connected.eaf differ diff --git a/main/boards/esp-vocat/emoji/low_battery.eaf b/main/boards/esp-vocat/emoji/low_battery.eaf new file mode 100644 index 00000000..ed188a9a Binary files /dev/null and b/main/boards/esp-vocat/emoji/low_battery.eaf differ diff --git a/main/boards/esp-vocat/esp_vocat.cc b/main/boards/esp-vocat/esp_vocat.cc index 4e14c4a9..49fb08fa 100644 --- a/main/boards/esp-vocat/esp_vocat.cc +++ b/main/boards/esp-vocat/esp_vocat.cc @@ -272,8 +272,18 @@ gpio_num_t TOUCH_PAD2 = TOUCH_PAD2_1; gpio_num_t UART1_TX = UART1_TX_1; gpio_num_t UART1_RX = UART1_RX_1; +class EspVocat; + class Charge : public I2cDevice { public: + static constexpr uint8_t kRegVoltage = 0x08; + static constexpr uint8_t kRegBatteryStatus = 0x0A; + static constexpr uint8_t kRegCurrent = 0x0C; + static constexpr uint8_t kRegStateOfCharge = 0x2C; + static constexpr uint8_t kRegAverageCurrent = 0x14; + static constexpr int kChargingCurrentMa = 30; + static constexpr uint16_t kBatteryStatusDsg = BIT0; + Charge(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) { read_buffer_ = new uint8_t[8]; @@ -282,27 +292,52 @@ public: { delete[] read_buffer_; } - void Printcharge() - { - ReadRegs(0x08, read_buffer_, 2); - ReadRegs(0x0c, read_buffer_ + 2, 2); - ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_sensor, &tsens_value)); - int16_t voltage = static_cast(read_buffer_[1] << 8 | read_buffer_[0]); - int16_t current = static_cast(read_buffer_[3] << 8 | read_buffer_[2]); - - // Use the variables to avoid warnings (can be removed if actual implementation uses them) + int16_t ReadWord(uint8_t reg) + { + uint8_t data[2] = {0}; + ReadRegs(reg, data, 2); + return static_cast(static_cast(data[0]) | (static_cast(data[1]) << 8)); + } + + int GetBatteryLevel() + { + int level = ReadWord(kRegStateOfCharge); + if (level < 0) { + return 0; + } + if (level > 100) { + return 100; + } + return level; + } + + bool IsCharging() + { + const uint16_t status = static_cast(ReadWord(kRegBatteryStatus)); + if ((status & kBatteryStatusDsg) == 0) { + return true; + } + + const int16_t avg_current_ma = ReadWord(kRegAverageCurrent); + const int16_t current_ma = ReadWord(kRegCurrent); + // Current is a fallback only: AverageCurrent can lag charger insertion noticeably. + return avg_current_ma > kChargingCurrentMa || current_ma > kChargingCurrentMa; + } + + bool IsDischarging() + { + return (static_cast(ReadWord(kRegBatteryStatus)) & kBatteryStatusDsg) != 0; + } + + void Update() + { + const int16_t voltage = ReadWord(kRegVoltage); + const int16_t current = ReadWord(kRegCurrent); + ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_sensor, &tsens_value)); (void)voltage; (void)current; } - static void TaskFunction(void *pvParameters) - { - Charge* charge = static_cast(pvParameters); - while (true) { - charge->Printcharge(); - vTaskDelay(pdMS_TO_TICKS(300)); - } - } private: uint8_t* read_buffer_ = nullptr; @@ -448,6 +483,10 @@ private: TaskHandle_t touch_slider_task_handle_ = nullptr; esp_timer_handle_t emotion_reset_timer_ = nullptr; bool bmi270_ready_ = false; + bool was_charging_ = false; + uint8_t low_battery_alert_mask_ = 0; + int low_battery_plays_left_ = 0; + int64_t next_low_battery_play_ms_ = 0; touch_slider_handle_t touch_slider_handle_ = nullptr; touch_button_handle_t touch_button_handle_ = nullptr; @@ -483,6 +522,92 @@ private: ShowTemporaryEmotion("happy", 2000); } + void PlayBatteryEmotion(const char* emotion, uint32_t duration_ms) + { +#if CONFIG_USE_EMOTE_MESSAGE_STYLE + if (display_ == nullptr || emotion == nullptr) { + return; + } + auto* emote_display = dynamic_cast(display_); + if (emote_display != nullptr) { + emote_display->InsertAnimDialog(emotion, duration_ms); + return; + } +#endif + ShowTemporaryEmotion(emotion, duration_ms); + } + + void StartLowBatteryAlertSequence() + { + constexpr int kMaxPlays = 3; + constexpr int64_t kIntervalMs = 5 * 60 * 1000; + + low_battery_plays_left_ = kMaxPlays - 1; + next_low_battery_play_ms_ = (esp_timer_get_time() / 1000) + kIntervalMs; + PlayBatteryEmotion("low_battery", 4000); + } + + void HandleBatteryEmotions() + { + if (charge_ == nullptr) { + return; + } + + const int level = charge_->GetBatteryLevel(); + const bool charging = charge_->IsCharging(); + + if (charging && !was_charging_) { + PlayBatteryEmotion("battery_connected", 4000); + low_battery_alert_mask_ = 0; + low_battery_plays_left_ = 0; + next_low_battery_play_ms_ = 0; + } + was_charging_ = charging; + + if (charging) { + return; + } + + if (level > 12) { + low_battery_alert_mask_ = 0; + low_battery_plays_left_ = 0; + next_low_battery_play_ms_ = 0; + return; + } + + const int64_t now_ms = esp_timer_get_time() / 1000; + if (low_battery_plays_left_ > 0 && now_ms >= next_low_battery_play_ms_) { + PlayBatteryEmotion("low_battery", 4000); + low_battery_plays_left_--; + if (low_battery_plays_left_ > 0) { + next_low_battery_play_ms_ = now_ms + 5 * 60 * 1000; + } + } + + if (level <= 5 && (low_battery_alert_mask_ & 0x02) == 0) { + low_battery_alert_mask_ |= 0x02; + StartLowBatteryAlertSequence(); + return; + } + + if (level <= 10 && (low_battery_alert_mask_ & 0x01) == 0) { + low_battery_alert_mask_ |= 0x01; + StartLowBatteryAlertSequence(); + } + } + + static void battery_task(void* arg) + { + auto* self = static_cast(arg); + while (true) { + if (self != nullptr && self->charge_ != nullptr) { + self->charge_->Update(); + self->HandleBatteryEmotions(); + } + vTaskDelay(pdMS_TO_TICKS(300)); + } + } + static void imu_event_task(void* arg) { auto* self = static_cast(arg); @@ -630,7 +755,8 @@ private: void InitializeCharge() { charge_ = new Charge(i2c_bus_, 0x55); - xTaskCreatePinnedToCore(Charge::TaskFunction, "batterydecTask", 3 * 1024, charge_, 6, &charge_task_handle_, 0); + was_charging_ = charge_->IsCharging(); + xTaskCreatePinnedToCore(battery_task, "batteryTask", 3 * 1024, this, 6, &charge_task_handle_, 0); } void InitializeCst816sTouchPad() @@ -1012,6 +1138,16 @@ public: virtual Camera* GetCamera() override { return camera_; } + + virtual bool GetBatteryLevel(int& level, bool& charging, bool& discharging) override { + if (charge_ == nullptr) { + return false; + } + level = charge_->GetBatteryLevel(); + charging = charge_->IsCharging(); + discharging = charge_->IsDischarging(); + return true; + } }; DECLARE_BOARD(EspVocat); diff --git a/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/README.md b/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/README.md index 3f5f1d53..fa1690c5 100644 --- a/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/README.md +++ b/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/README.md @@ -10,6 +10,7 @@ Configuration in `menuconfig`. Selection Board Type `Xiaozhi Assistant --> Board Type` - Waveshare ESP32-P4-WIFI6-Touch-LCD-4B - Waveshare ESP32-P4-WIFI6-Touch-LCD-4.3 +- Waveshare ESP32-P4-WIFI6-Touch-LCD-5 - Waveshare ESP32-P4-WIFI6-Touch-LCD-7B - Waveshare ESP32-P4-WIFI6-Touch-LCD-3.4C - Waveshare ESP32-P4-WIFI6-Touch-LCD-4C diff --git a/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/config.h b/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/config.h index 057f3d50..9b4c30dd 100644 --- a/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/config.h +++ b/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/config.h @@ -36,6 +36,13 @@ #define DISPLAY_BACKLIGHT_PIN GPIO_NUM_26 #define DISPLAY_BACKLIGHT_OUTPUT_INVERT true #define LCD_MIPI_DSI_LANE_BITRATE_MBPS (500) +#elif CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_5 +#define DISPLAY_WIDTH (720) +#define DISPLAY_HEIGHT (1280) +#define PIN_NUM_LCD_RST GPIO_NUM_27 +#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_26 +#define DISPLAY_BACKLIGHT_OUTPUT_INVERT false +#define LCD_MIPI_DSI_LANE_BITRATE_MBPS (700) #elif CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_7B #define DISPLAY_WIDTH (1024) #define DISPLAY_HEIGHT (600) diff --git a/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/config.json b/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/config.json index a434efe6..cc8c21dc 100644 --- a/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/config.json +++ b/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/config.json @@ -62,6 +62,36 @@ "CONFIG_XIAOZHI_ENABLE_CAMERA_ENDIANNESS_SWAP=y" ] }, + { + "name": "esp32-p4-wifi6-touch-lcd-5", + "sdkconfig_append": [ + "CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0", + "CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH=y", + "CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_5=y", + "CONFIG_USE_WECHAT_MESSAGE_STYLE=n", + "CONFIG_USE_DEVICE_AEC=y", + "CONFIG_CAMERA_OV5647=y", + "CONFIG_CAMERA_OV5647_AUTO_DETECT_MIPI_INTERFACE_SENSOR=y", + "CONFIG_CAMERA_OV5647_MIPI_RAW8_800X800_50FPS=y", + "CONFIG_XIAOZHI_ENABLE_CAMERA_ENDIANNESS_SWAP=y", + "CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y", + "CONFIG_ESP32P4_REV_MIN_100=y" + ] + }, + { + "name": "esp32-p4-wifi6-touch-lcd-5-p4x", + "sdkconfig_append": [ + "CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0", + "CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH=y", + "CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_5=y", + "CONFIG_USE_WECHAT_MESSAGE_STYLE=n", + "CONFIG_USE_DEVICE_AEC=y", + "CONFIG_CAMERA_OV5647=y", + "CONFIG_CAMERA_OV5647_AUTO_DETECT_MIPI_INTERFACE_SENSOR=y", + "CONFIG_CAMERA_OV5647_MIPI_RAW8_800X800_50FPS=y", + "CONFIG_XIAOZHI_ENABLE_CAMERA_ENDIANNESS_SWAP=y" + ] + }, { "name": "esp32-p4-wifi6-touch-lcd-7b", "sdkconfig_append": [ diff --git a/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/esp32-p4-wifi6-touch-lcd.cc b/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/esp32-p4-wifi6-touch-lcd.cc index b493aac1..5a7f76ea 100644 --- a/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/esp32-p4-wifi6-touch-lcd.cc +++ b/main/boards/waveshare/esp32-p4-wifi6-touch-lcd/esp32-p4-wifi6-touch-lcd.cc @@ -17,6 +17,8 @@ #include "esp_lcd_st7703.h" #elif CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_4_3 #include "esp_lcd_st7701.h" +#elif CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_5 +#include "esp_lcd_hx8394.h" #elif CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_7B #include "esp_lcd_ek79007.h" #elif CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_3_4C || CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_4C \ @@ -178,6 +180,44 @@ private: .vendor_config = &vendor_config, }; esp_lcd_new_panel_st7701(io, &lcd_dev_config, &disp_panel); +#elif CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_5 + esp_lcd_dpi_panel_config_t dpi_config = { + .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, + .dpi_clock_freq_mhz = 58, + .pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565, + .num_fbs = 1, + .video_timing = { + .h_size = DISPLAY_WIDTH, + .v_size = DISPLAY_HEIGHT, + .hsync_pulse_width = 20, + .hsync_back_porch = 20, + .hsync_front_porch = 40, + .vsync_pulse_width = 4, + .vsync_back_porch = 10, + .vsync_front_porch = 24, + }, + .flags = { + .use_dma2d = true, + }, + }; + hx8394_vendor_config_t vendor_config = { + .mipi_config = { + .dsi_bus = mipi_dsi_bus, + .dpi_config = &dpi_config, + .lane_num = 2, + }, + }; + + const esp_lcd_panel_dev_config_t lcd_dev_config = { + .reset_gpio_num = PIN_NUM_LCD_RST, + .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, + .bits_per_pixel = 16, + .flags = { + .reset_active_high = true, + }, + .vendor_config = &vendor_config, + }; + esp_lcd_new_panel_hx8394(io, &lcd_dev_config, &disp_panel); #elif CONFIG_BOARD_TYPE_WAVESHARE_ESP32_P4_WIFI6_TOUCH_LCD_7B esp_lcd_dpi_panel_config_t dpi_config = { .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, diff --git a/main/idf_component.yml b/main/idf_component.yml index 9baa9636..dda43d76 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -80,6 +80,10 @@ dependencies: version: '*' rules: - if: target in [esp32p4] + waveshare/esp_lcd_hx8394: + version: '*' + rules: + - if: target in [esp32p4] waveshare/esp_lcd_st7703: version: '*' rules: