Decouple P4 function board from BSP (#2159)
Co-authored-by: Xiaoxia <terrence.huang@tenclass.com>
This commit is contained in:
@@ -82,8 +82,8 @@ Espressif's current chip-identification table lists v0.0, v1.0, v1.3, v3.0, v3.1
|
||||
| `espressif/mqtt` | `1.0.0` | ✅ Upstream support | MQTT moved from a built-in SDK component to a Component Manager dependency in IDF 6 |
|
||||
| `78/esp-ml307` | `3.6.6` + project-level `espressif/mqtt` | ✅ Builds in CI | The upstream source compiles under IDF 6.0.1 when the project supplies the MQTT component moved out of IDF |
|
||||
| `espressif/esp_hosted` / `esp_wifi_remote` | `2.12.11` / `1.6.2` | ✅ Upstream support | Used for ESP32-P4 Hosted Wi-Fi |
|
||||
| `espressif/esp_video` | `^2.0.1` | ✅ Upstream support | Currently resolves to 2.3.0 on S3 and 2.0.1 on P4 due to BSP constraints |
|
||||
| P4 BSP / LCD drivers | BSP `5.2.3`, EK79007/ST7701 `2.0.x` | ✅ Upstream support | Resolves IDF 6 DPI, color-field, and split-driver-component issues |
|
||||
| `espressif/esp_video` | `^2.3.0` | ✅ Upstream support | Requires the current 2.3 API baseline and accepts future compatible 2.x releases on S3 and P4 |
|
||||
| P4 LCD drivers | EK79007/ST7701 `2.0.x` | ✅ Upstream support | ESP32-P4-Function-EV-Board initializes its hardware directly so its former BSP cannot constrain `esp_video`; the LCD drivers resolve IDF 6 DPI, color-field, and split-driver-component issues |
|
||||
| `espressif/esp_lcd_st77916` | `2.0.2` | ✅ Upstream support | Major version 2 uses the IDF 6 panel I/O definitions |
|
||||
| `espressif/esp_lcd_spd2010` | `^2.0.0` (resolved `2.0.0~1`) | ✅ Upstream support | Major version 2 declares ESP-IDF 6 compatibility |
|
||||
| `espressif/esp_lcd_co5300` | `2.1.0` | ✅ Upstream support | Used with explicit IDF 6-compatible QSPI I/O configuration in board code |
|
||||
|
||||
@@ -1023,6 +1023,12 @@ if(CONFIG_BOARD_TYPE_ESP_VOCAT AND IDF_VERSION_MAJOR LESS 6)
|
||||
espressif__touch_button_sensor
|
||||
)
|
||||
endif()
|
||||
if(CONFIG_BOARD_TYPE_ESP32_P4_FUNCTION_EV_BOARD)
|
||||
list(APPEND MAIN_PRIV_REQUIRES_EXTRA
|
||||
esp_driver_sdmmc
|
||||
sdmmc
|
||||
)
|
||||
endif()
|
||||
idf_component_register(SRCS ${SOURCES}
|
||||
EMBED_FILES ${LANG_SOUNDS} ${COMMON_SOUNDS}
|
||||
INCLUDE_DIRS ${INCLUDE_DIRS}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
virtual ~Camera() = default;
|
||||
|
||||
virtual void SetExplainUrl(const std::string& url, const std::string& token) = 0;
|
||||
virtual bool Capture() = 0;
|
||||
virtual bool SetHMirror(bool enabled) = 0;
|
||||
@@ -13,4 +15,4 @@ public:
|
||||
virtual std::string Explain(const std::string& question) = 0;
|
||||
};
|
||||
|
||||
#endif // CAMERA_H
|
||||
#endif // CAMERA_H
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/queue.h>
|
||||
|
||||
#include "camera.h"
|
||||
#include "jpg/image_to_jpeg.h"
|
||||
#include "esp_video_init.h"
|
||||
#include "jpg/image_to_jpeg.h"
|
||||
|
||||
struct JpegChunk {
|
||||
uint8_t* data;
|
||||
@@ -21,7 +21,7 @@ struct JpegChunk {
|
||||
class EspVideo : public Camera {
|
||||
private:
|
||||
struct FrameBuffer {
|
||||
uint8_t *data = nullptr;
|
||||
uint8_t* data = nullptr;
|
||||
size_t len = 0;
|
||||
uint16_t width = 0;
|
||||
uint16_t height = 0;
|
||||
@@ -34,7 +34,10 @@ private:
|
||||
#endif // CONFIG_XIAOZHI_ENABLE_ROTATE_CAMERA_IMAGE
|
||||
int video_fd_ = -1;
|
||||
bool streaming_on_ = false;
|
||||
struct MmapBuffer { void *start = nullptr; size_t length = 0; };
|
||||
struct MmapBuffer {
|
||||
void* start = nullptr;
|
||||
size_t length = 0;
|
||||
};
|
||||
std::vector<MmapBuffer> mmap_buffers_;
|
||||
std::string explain_url_;
|
||||
std::string explain_token_;
|
||||
@@ -42,7 +45,7 @@ private:
|
||||
|
||||
public:
|
||||
EspVideo(const esp_video_init_config_t& config);
|
||||
~EspVideo();
|
||||
~EspVideo() override;
|
||||
|
||||
virtual void SetExplainUrl(const std::string& url, const std::string& token);
|
||||
virtual bool Capture();
|
||||
|
||||
@@ -10,7 +10,7 @@ LCD is supported via the official MIPI‑DSI LCD adapter.
|
||||
- Audio: ES8311 codec with speaker and microphone support
|
||||
- Touch: GT911 capacitive touch controller
|
||||
- SD Card: MicroSD card support (MMC mode)
|
||||
- Camera: MIPI-CSI camera interface with fallback DVP configuration (OV5647, SC2336 sensors supported)
|
||||
- Camera: MIPI-CSI camera interface (OV5647 and SC2336 sensors supported)
|
||||
- USB: USB host/device support
|
||||
- SPIFFS: Built-in flash filesystem support
|
||||
- Fonts: Custom font support with Unicode characters (Vietnamese, Chinese, etc.)
|
||||
@@ -24,13 +24,19 @@ Ensure these are set (auto-set when building via config.json):
|
||||
- `CONFIG_ESP_HOSTED_SDIO_HOST_INTERFACE=y`
|
||||
- `CONFIG_ESP_HOSTED_SDIO_4_BIT_BUS=y`
|
||||
|
||||
The board initializes I2C, LCD, touch, audio, SDMMC, and camera hardware directly
|
||||
from the board implementation. It does not depend on the
|
||||
`espressif/esp32_p4_function_ev_board` BSP, allowing the project-wide
|
||||
`esp_video` dependency to resolve independently.
|
||||
|
||||
## LCD Connection (from Espressif user guide)
|
||||
- Connect the LCD adapter board J3 to the board’s MIPI DSI connector (reverse ribbon).
|
||||
- Wire `RST_LCD` (adapter J6) to `GPIO27` (board J1).
|
||||
- Wire `PWM` (adapter J6) to `GPIO26` (board J1).
|
||||
- Optionally power the LCD adapter via its USB or provide `5V` and `GND` from the board.
|
||||
|
||||
These pins are pre-configured in `config.h` as `PIN_NUM_LCD_RST=GPIO27` and `DISPLAY_BACKLIGHT_PIN=GPIO26`. Resolution is set to 1024×600.
|
||||
These pins are configured in `config.h` as `DISPLAY_RESET_PIN=GPIO27` and
|
||||
`DISPLAY_BACKLIGHT_PIN=GPIO26`. Resolution is set to 1024×600.
|
||||
|
||||
## Build (example)
|
||||
```powershell
|
||||
|
||||
@@ -1,11 +1,44 @@
|
||||
#ifndef _BOARD_CONFIG_H_
|
||||
#define _BOARD_CONFIG_H_
|
||||
|
||||
#include "bsp/esp32_p4_function_ev_board.h" // Library for board configs and pins
|
||||
#include <driver/gpio.h>
|
||||
#include <driver/i2c_types.h>
|
||||
|
||||
#define AUDIO_INPUT_SAMPLE_RATE 24000
|
||||
#define AUDIO_INPUT_SAMPLE_RATE 24000
|
||||
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
|
||||
|
||||
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_13
|
||||
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_12
|
||||
#define AUDIO_I2S_GPIO_WS GPIO_NUM_10
|
||||
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_9
|
||||
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_11
|
||||
#define AUDIO_CODEC_PA_PIN GPIO_NUM_53
|
||||
#define AUDIO_CODEC_I2C_PORT I2C_NUM_1
|
||||
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_7
|
||||
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_8
|
||||
|
||||
#define BOOT_BUTTON_GPIO GPIO_NUM_0
|
||||
|
||||
#define DISPLAY_WIDTH 1024
|
||||
#define DISPLAY_HEIGHT 600
|
||||
#define DISPLAY_OFFSET_X 0
|
||||
#define DISPLAY_OFFSET_Y 0
|
||||
#define DISPLAY_MIRROR_X true
|
||||
#define DISPLAY_MIRROR_Y true
|
||||
#define DISPLAY_SWAP_XY false
|
||||
#define DISPLAY_RESET_PIN GPIO_NUM_27
|
||||
#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_26
|
||||
#define DISPLAY_BACKLIGHT_OUTPUT_INVERT false
|
||||
|
||||
#endif // _BOARD_CONFIG_H_
|
||||
#define LCD_MIPI_DSI_LANE_NUM 2
|
||||
#define LCD_MIPI_DSI_LANE_BITRATE_MBPS 1000
|
||||
#define MIPI_DSI_PHY_PWR_LDO_CHAN 3
|
||||
#define MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV 2500
|
||||
|
||||
#define CAMERA_RESET_PIN GPIO_NUM_NC
|
||||
#define CAMERA_PWDN_PIN GPIO_NUM_NC
|
||||
|
||||
#define SD_CARD_MOUNT_POINT "/sdcard"
|
||||
#define SD_CARD_PWR_LDO_CHAN 4
|
||||
|
||||
#endif // _BOARD_CONFIG_H_
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"CONFIG_ESP_HOSTED_SDIO_HOST_INTERFACE=y",
|
||||
"CONFIG_ESP_HOSTED_SDIO_4_BIT_BUS=y",
|
||||
"CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y",
|
||||
"CONFIG_BSP_LCD_TYPE_1024_600=y",
|
||||
"CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y",
|
||||
"CONFIG_ESP32P4_REV_MIN_100=y"
|
||||
]
|
||||
@@ -23,8 +22,7 @@
|
||||
"CONFIG_ESP_HOSTED_P4_DEV_BOARD_FUNC_BOARD=y",
|
||||
"CONFIG_ESP_HOSTED_SDIO_HOST_INTERFACE=y",
|
||||
"CONFIG_ESP_HOSTED_SDIO_4_BIT_BUS=y",
|
||||
"CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y",
|
||||
"CONFIG_BSP_LCD_TYPE_1024_600=y"
|
||||
"CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,84 +1,119 @@
|
||||
#include "wifi_board.h"
|
||||
#include "audio/codecs/es8311_audio_codec.h"
|
||||
// Display
|
||||
#include "display/display.h"
|
||||
#include "display/lcd_display.h"
|
||||
#include "lvgl_theme.h"
|
||||
// Backlight
|
||||
// PwmBacklight is declared in backlight headers pulled by display/lcd_display includes via lvgl stack
|
||||
|
||||
#include "application.h"
|
||||
#include "audio/codecs/es8311_audio_codec.h"
|
||||
#include "button.h"
|
||||
#include "config.h"
|
||||
#include "display/display.h"
|
||||
#include "display/lcd_display.h"
|
||||
#include "esp_video.h"
|
||||
#include "lvgl_theme.h"
|
||||
#include "wifi_board.h"
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <inttypes.h>
|
||||
#include <driver/i2c_master.h>
|
||||
#include <driver/sdmmc_host.h>
|
||||
#include <esp_idf_version.h>
|
||||
#include <esp_lcd_mipi_dsi.h>
|
||||
#include <esp_lcd_panel_ops.h>
|
||||
#include <esp_ldo_regulator.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_lvgl_port.h>
|
||||
#include <soc/clk_tree_defs.h>
|
||||
// SD card
|
||||
#include <esp_vfs_fat.h>
|
||||
#include <sdmmc_cmd.h>
|
||||
#include <driver/sdmmc_host.h>
|
||||
#include <driver/sdspi_host.h>
|
||||
// SD power control (on-chip LDO)
|
||||
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||
|
||||
// MIPI-DSI / LCD vendor includes (library may replace some)
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lcd_mipi_dsi.h"
|
||||
#include "esp_ldo_regulator.h"
|
||||
#include "esp_lcd_ek79007.h"
|
||||
#include "esp_lcd_touch_gt911.h"
|
||||
|
||||
// Library includes
|
||||
#include "bsp/esp32_p4_function_ev_board.h"
|
||||
#include "bsp/touch.h"
|
||||
#include "sd_pwr_ctrl_by_on_chip_ldo.h"
|
||||
|
||||
#define TAG "ESP32P4FuncEV"
|
||||
|
||||
class ESP32P4FunctionEvBoard : public WifiBoard
|
||||
{
|
||||
class ESP32P4FunctionEvBoard : public WifiBoard {
|
||||
private:
|
||||
i2c_master_bus_handle_t codec_i2c_bus_ = nullptr;
|
||||
Button boot_button_;
|
||||
LcdDisplay *display_ = nullptr;
|
||||
LcdDisplay* display_ = nullptr;
|
||||
esp_lcd_dsi_bus_handle_t dsi_bus_ = nullptr;
|
||||
esp_ldo_channel_handle_t dsi_phy_power_ = nullptr;
|
||||
esp_lcd_touch_handle_t tp_ = nullptr;
|
||||
esp_lcd_panel_io_handle_t touch_io_ = nullptr;
|
||||
lv_indev_t* touch_indev_ = nullptr;
|
||||
EspVideo* camera_ = nullptr;
|
||||
sdmmc_card_t* sd_card_ = nullptr;
|
||||
sd_pwr_ctrl_handle_t sd_power_ = nullptr;
|
||||
bool sd_card_mounted_ = false;
|
||||
|
||||
void InitializeI2cBuses()
|
||||
{
|
||||
ESP_ERROR_CHECK(bsp_i2c_init());
|
||||
codec_i2c_bus_ = bsp_i2c_get_handle();
|
||||
}
|
||||
|
||||
// Touch I2C bus initialization is not required for this board (handled elsewhere)
|
||||
void InitializeTouchI2cBus()
|
||||
{
|
||||
// No implementation needed
|
||||
}
|
||||
|
||||
void InitializeLCD()
|
||||
{
|
||||
bsp_display_config_t config = {
|
||||
.hdmi_resolution = BSP_HDMI_RES_NONE,
|
||||
.dsi_bus = {
|
||||
.phy_clk_src = (mipi_dsi_phy_clock_source_t)SOC_MOD_CLK_PLL_F20M,
|
||||
.lane_bit_rate_mbps = 1000,
|
||||
},
|
||||
void InitializeI2cBus() {
|
||||
i2c_master_bus_config_t i2c_bus_config = {
|
||||
.i2c_port = AUDIO_CODEC_I2C_PORT,
|
||||
.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,
|
||||
},
|
||||
};
|
||||
|
||||
bsp_lcd_handles_t handles;
|
||||
ESP_ERROR_CHECK(bsp_display_new_with_handles(&config, &handles));
|
||||
|
||||
display_ = new MipiLcdDisplay(handles.io, handles.panel, 1024, 600, 0, 0, true, true, false);
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &codec_i2c_bus_));
|
||||
}
|
||||
|
||||
void InitializeButtons()
|
||||
{
|
||||
boot_button_.OnClick([this]()
|
||||
{
|
||||
void InitializeLcd() {
|
||||
esp_ldo_channel_config_t ldo_config = {
|
||||
.chan_id = MIPI_DSI_PHY_PWR_LDO_CHAN,
|
||||
.voltage_mv = MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_config, &dsi_phy_power_));
|
||||
|
||||
esp_lcd_dsi_bus_config_t bus_config = {
|
||||
.bus_id = 0,
|
||||
.num_data_lanes = LCD_MIPI_DSI_LANE_NUM,
|
||||
.lane_bit_rate_mbps = LCD_MIPI_DSI_LANE_BITRATE_MBPS,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &dsi_bus_));
|
||||
|
||||
esp_lcd_panel_io_handle_t panel_io = nullptr;
|
||||
esp_lcd_dbi_io_config_t dbi_config = {
|
||||
.virtual_channel = 0,
|
||||
.lcd_cmd_bits = 8,
|
||||
.lcd_param_bits = 8,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(dsi_bus_, &dbi_config, &panel_io));
|
||||
|
||||
esp_lcd_dpi_panel_config_t dpi_config =
|
||||
EK79007_1024_600_PANEL_60HZ_CONFIG_CF(LCD_COLOR_FMT_RGB565);
|
||||
dpi_config.num_fbs = 1;
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 0, 0)
|
||||
dpi_config.flags.use_dma2d = true;
|
||||
#endif
|
||||
|
||||
ek79007_vendor_config_t vendor_config = {
|
||||
.mipi_config =
|
||||
{
|
||||
.dsi_bus = dsi_bus_,
|
||||
.dpi_config = &dpi_config,
|
||||
},
|
||||
};
|
||||
esp_lcd_panel_dev_config_t panel_config = {};
|
||||
panel_config.reset_gpio_num = DISPLAY_RESET_PIN;
|
||||
panel_config.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB;
|
||||
panel_config.bits_per_pixel = 16;
|
||||
panel_config.vendor_config = &vendor_config;
|
||||
|
||||
esp_lcd_panel_handle_t panel = nullptr;
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_ek79007(panel_io, &panel_config, &panel));
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
|
||||
ESP_ERROR_CHECK(esp_lcd_dpi_panel_enable_dma2d(panel));
|
||||
#endif
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel));
|
||||
ESP_ERROR_CHECK(esp_lcd_panel_init(panel));
|
||||
|
||||
display_ = new MipiLcdDisplay(panel_io, panel, DISPLAY_WIDTH, DISPLAY_HEIGHT,
|
||||
DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X,
|
||||
DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
|
||||
}
|
||||
|
||||
void InitializeButtons() {
|
||||
boot_button_.OnClick([this]() {
|
||||
auto& app = Application::GetInstance();
|
||||
if (app.GetDeviceState() == kDeviceStateStarting) {
|
||||
EnterWifiConfigMode();
|
||||
@@ -88,91 +123,113 @@ private:
|
||||
});
|
||||
}
|
||||
|
||||
void InitializeTouch()
|
||||
{
|
||||
ESP_ERROR_CHECK(bsp_touch_new(NULL, &tp_));
|
||||
void InitializeTouch() {
|
||||
esp_lcd_touch_config_t touch_config = {
|
||||
.x_max = DISPLAY_WIDTH,
|
||||
.y_max = DISPLAY_HEIGHT,
|
||||
.rst_gpio_num = GPIO_NUM_NC,
|
||||
.int_gpio_num = GPIO_NUM_NC,
|
||||
.levels =
|
||||
{
|
||||
.reset = 0,
|
||||
.interrupt = 0,
|
||||
},
|
||||
.flags =
|
||||
{
|
||||
.swap_xy = 0,
|
||||
.mirror_x = 1,
|
||||
.mirror_y = 1,
|
||||
},
|
||||
};
|
||||
esp_lcd_panel_io_i2c_config_t touch_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
|
||||
touch_io_config.scl_speed_hz = 400000;
|
||||
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(codec_i2c_bus_, &touch_io_config, &touch_io_));
|
||||
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(touch_io_, &touch_config, &tp_));
|
||||
|
||||
lv_display_t* lv_display = lv_display_get_default();
|
||||
if (lv_display == nullptr) {
|
||||
ESP_LOGE(TAG, "Cannot register touch input without an LVGL display");
|
||||
return;
|
||||
}
|
||||
const lvgl_port_touch_cfg_t lv_touch_config = {
|
||||
.disp = lv_display,
|
||||
.handle = tp_,
|
||||
};
|
||||
touch_indev_ = lvgl_port_add_touch(&lv_touch_config);
|
||||
if (touch_indev_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Failed to register GT911 touch input");
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeSdCard()
|
||||
{
|
||||
void InitializeSdCard() {
|
||||
ESP_LOGI(TAG, "Initializing SD card");
|
||||
esp_err_t ret = bsp_sdcard_mount();
|
||||
|
||||
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
|
||||
host.slot = SDMMC_HOST_SLOT_0;
|
||||
host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
|
||||
|
||||
sdmmc_slot_config_t slot = {};
|
||||
slot.cd = SDMMC_SLOT_NO_CD;
|
||||
slot.wp = SDMMC_SLOT_NO_WP;
|
||||
slot.width = 4;
|
||||
|
||||
const esp_vfs_fat_sdmmc_mount_config_t mount_config = {
|
||||
.format_if_mount_failed = false,
|
||||
.max_files = 5,
|
||||
.allocation_unit_size = 64 * 1024,
|
||||
};
|
||||
|
||||
sd_pwr_ctrl_ldo_config_t power_config = {
|
||||
.ldo_chan_id = SD_CARD_PWR_LDO_CHAN,
|
||||
};
|
||||
esp_err_t ret = sd_pwr_ctrl_new_on_chip_ldo(&power_config, &sd_power_);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to enable SD card power: %s", esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
host.pwr_ctrl_handle = sd_power_;
|
||||
|
||||
ret = esp_vfs_fat_sdmmc_mount(SD_CARD_MOUNT_POINT, &host, &slot, &mount_config, &sd_card_);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to mount SD card: %s", esp_err_to_name(ret));
|
||||
sd_pwr_ctrl_del_on_chip_ldo(sd_power_);
|
||||
sd_power_ = nullptr;
|
||||
} else {
|
||||
sd_card_mounted_ = true;
|
||||
ESP_LOGI(TAG, "SD card mounted successfully");
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeCamera()
|
||||
{
|
||||
void InitializeCamera() {
|
||||
ESP_LOGI(TAG, "Initializing camera");
|
||||
|
||||
// Use BSP camera initialization for ESP-P4
|
||||
bsp_camera_cfg_t camera_cfg = {0};
|
||||
esp_err_t ret = bsp_camera_start(&camera_cfg);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to initialize BSP camera: %s", esp_err_to_name(ret));
|
||||
ESP_LOGI(TAG, "Attempting alternative camera initialization");
|
||||
|
||||
// Alternative: Direct EspVideo initialization if BSP fails
|
||||
// This provides more control over camera configuration
|
||||
static esp_cam_ctlr_dvp_pin_config_t dvp_pin_config = {
|
||||
.data_width = CAM_CTLR_DATA_WIDTH_8,
|
||||
.data_io = {
|
||||
[0] = BSP_I2C_SDA, // Reuse I2C pins if camera pins not defined
|
||||
[1] = BSP_I2C_SCL,
|
||||
[2] = GPIO_NUM_NC,
|
||||
[3] = GPIO_NUM_NC,
|
||||
[4] = GPIO_NUM_NC,
|
||||
[5] = GPIO_NUM_NC,
|
||||
[6] = GPIO_NUM_NC,
|
||||
[7] = GPIO_NUM_NC,
|
||||
esp_video_init_csi_config_t csi_config = {
|
||||
.sccb_config =
|
||||
{
|
||||
.init_sccb = false,
|
||||
.i2c_handle = codec_i2c_bus_,
|
||||
.freq = 400000,
|
||||
},
|
||||
.vsync_io = GPIO_NUM_NC,
|
||||
.de_io = GPIO_NUM_NC,
|
||||
.pclk_io = GPIO_NUM_NC,
|
||||
.xclk_io = GPIO_NUM_NC,
|
||||
};
|
||||
.reset_pin = CAMERA_RESET_PIN,
|
||||
.pwdn_pin = CAMERA_PWDN_PIN,
|
||||
};
|
||||
esp_video_init_config_t video_config = {
|
||||
.csi = &csi_config,
|
||||
};
|
||||
|
||||
esp_video_init_sccb_config_t sccb_config = {
|
||||
.init_sccb = false, // Use existing I2C bus
|
||||
.i2c_handle = codec_i2c_bus_, // Reuse the existing I2C bus
|
||||
.freq = 100000,
|
||||
};
|
||||
|
||||
esp_video_init_dvp_config_t dvp_config = {
|
||||
.sccb_config = sccb_config,
|
||||
.reset_pin = GPIO_NUM_NC,
|
||||
.pwdn_pin = GPIO_NUM_NC,
|
||||
.dvp_pin = dvp_pin_config,
|
||||
.xclk_freq = 20000000, // 20MHz typical for cameras
|
||||
};
|
||||
|
||||
esp_video_init_config_t video_config = {
|
||||
.dvp = &dvp_config,
|
||||
};
|
||||
|
||||
// Try to create camera with direct configuration
|
||||
camera_ = new EspVideo(video_config);
|
||||
ESP_LOGI(TAG, "Camera initialized with direct configuration");
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Camera initialized successfully via BSP");
|
||||
}
|
||||
camera_ = new EspVideo(video_config);
|
||||
}
|
||||
|
||||
void InitializeFonts()
|
||||
{
|
||||
void InitializeFonts() {
|
||||
ESP_LOGI(TAG, "Initializing font support");
|
||||
// Font initialization is handled by the Assets system
|
||||
// The board supports loading fonts from assets partition
|
||||
// Verify that fonts are properly loaded by checking theme
|
||||
auto& theme_manager = LvglThemeManager::GetInstance();
|
||||
auto current_theme = theme_manager.GetTheme("light");
|
||||
if (current_theme != nullptr) {
|
||||
auto text_font = current_theme->text_font();
|
||||
if (text_font != nullptr && text_font->font() != nullptr) {
|
||||
ESP_LOGI(TAG, "Custom font loaded successfully: line_height=%d", text_font->font()->line_height);
|
||||
ESP_LOGI(TAG, "Custom font loaded successfully: line_height=%d",
|
||||
text_font->font()->line_height);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Custom font not loaded, using built-in font");
|
||||
}
|
||||
@@ -180,12 +237,9 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
ESP32P4FunctionEvBoard() : boot_button_(0)
|
||||
{
|
||||
InitializeI2cBuses();
|
||||
// Audio is initialized by Es8311AudioCodec
|
||||
InitializeLCD();
|
||||
ESP32P4FunctionEvBoard() : boot_button_(BOOT_BUTTON_GPIO) {
|
||||
InitializeI2cBus();
|
||||
InitializeLcd();
|
||||
InitializeButtons();
|
||||
InitializeTouch();
|
||||
InitializeSdCard();
|
||||
@@ -194,40 +248,65 @@ public:
|
||||
GetBacklight()->RestoreBrightness();
|
||||
}
|
||||
|
||||
~ESP32P4FunctionEvBoard()
|
||||
{
|
||||
// Clean up display pointer
|
||||
~ESP32P4FunctionEvBoard() {
|
||||
delete camera_;
|
||||
camera_ = nullptr;
|
||||
|
||||
if (sd_card_mounted_) {
|
||||
esp_err_t ret = esp_vfs_fat_sdcard_unmount(SD_CARD_MOUNT_POINT, sd_card_);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to unmount SD card: %s", esp_err_to_name(ret));
|
||||
}
|
||||
sd_card_mounted_ = false;
|
||||
sd_card_ = nullptr;
|
||||
}
|
||||
if (sd_power_ != nullptr) {
|
||||
sd_pwr_ctrl_del_on_chip_ldo(sd_power_);
|
||||
sd_power_ = nullptr;
|
||||
}
|
||||
|
||||
if (touch_indev_ != nullptr) {
|
||||
lvgl_port_remove_touch(touch_indev_);
|
||||
touch_indev_ = nullptr;
|
||||
}
|
||||
if (tp_ != nullptr) {
|
||||
esp_lcd_touch_del(tp_);
|
||||
tp_ = nullptr;
|
||||
}
|
||||
if (touch_io_ != nullptr) {
|
||||
esp_lcd_panel_io_del(touch_io_);
|
||||
touch_io_ = nullptr;
|
||||
}
|
||||
|
||||
delete display_;
|
||||
display_ = nullptr;
|
||||
// Unmount SD card
|
||||
esp_err_t ret = bsp_sdcard_unmount();
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to unmount SD card: %s", esp_err_to_name(ret));
|
||||
|
||||
if (dsi_bus_ != nullptr) {
|
||||
esp_lcd_del_dsi_bus(dsi_bus_);
|
||||
dsi_bus_ = nullptr;
|
||||
}
|
||||
if (dsi_phy_power_ != nullptr) {
|
||||
esp_ldo_release_channel(dsi_phy_power_);
|
||||
dsi_phy_power_ = nullptr;
|
||||
}
|
||||
// If other resources need cleanup, add here
|
||||
}
|
||||
|
||||
virtual AudioCodec *GetAudioCodec() override
|
||||
{
|
||||
virtual AudioCodec* GetAudioCodec() override {
|
||||
static Es8311AudioCodec audio_codec(
|
||||
codec_i2c_bus_, (i2c_port_t)BSP_I2C_NUM, AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
|
||||
BSP_I2S_MCLK, BSP_I2S_SCLK, BSP_I2S_LCLK, BSP_I2S_DOUT, BSP_I2S_DSIN,
|
||||
BSP_POWER_AMP_IO, ES8311_CODEC_DEFAULT_ADDR, true, false);
|
||||
codec_i2c_bus_, AUDIO_CODEC_I2C_PORT, 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, ES8311_CODEC_DEFAULT_ADDR, true, false);
|
||||
return &audio_codec;
|
||||
}
|
||||
|
||||
virtual Display *GetDisplay() override { return display_; }
|
||||
virtual Display* GetDisplay() override { return display_; }
|
||||
|
||||
virtual Backlight *GetBacklight() override
|
||||
{
|
||||
static PwmBacklight backlight(BSP_LCD_BACKLIGHT, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
|
||||
virtual Backlight* GetBacklight() override {
|
||||
static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
|
||||
return &backlight;
|
||||
}
|
||||
|
||||
virtual Camera *GetCamera() override
|
||||
{
|
||||
return camera_;
|
||||
}
|
||||
virtual Camera* GetCamera() override { return camera_; }
|
||||
};
|
||||
|
||||
DECLARE_BOARD(ESP32P4FunctionEvBoard);
|
||||
|
||||
@@ -45,7 +45,7 @@ dependencies:
|
||||
rules:
|
||||
- if: target in [esp32s3]
|
||||
espressif/esp_video:
|
||||
version: ^2.0.1
|
||||
version: ^2.3.0
|
||||
rules:
|
||||
- if: target in [esp32p4, esp32s3]
|
||||
|
||||
@@ -91,10 +91,6 @@ dependencies:
|
||||
version: '*'
|
||||
rules:
|
||||
- if: target in [esp32p4]
|
||||
espressif/esp32_p4_function_ev_board:
|
||||
version: ^5.2.3
|
||||
rules:
|
||||
- if: target in [esp32p4]
|
||||
espressif/esp_lcd_ili9881c:
|
||||
version: ^1.0.1
|
||||
rules:
|
||||
|
||||
Reference in New Issue
Block a user