Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,8 @@ elseif(CONFIG_BOARD_TYPE_WIRELESS_TAG_WTP4C5MP07S)
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_LC_S3_WIFI_1_54TFT)
set(BOARD_TYPE "lc-s3-wifi-1.54tft")
elseif(CONFIG_BOARD_TYPE_AIPI_LITE)
set(BOARD_TYPE "aipi-lite")
set(BUILTIN_TEXT_FONT font_puhui_basic_14_1)
Expand Down
3 changes: 3 additions & 0 deletions main/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ choice BOARD_TYPE
config BOARD_TYPE_BREAD_COMPACT_ESP32_LCD
bool "Bread Compact ESP32 DevKit + LCD (面包板)"
depends on IDF_TARGET_ESP32
config BOARD_TYPE_LC_S3_WIFI_1_54TFT
bool "LC-S3-WIFI-1.54TFT开发板"
depends on IDF_TARGET_ESP32S3
config BOARD_TYPE_XMINI_C3_V3
bool "Xmini C3 V3"
depends on IDF_TARGET_ESP32C3
Expand Down
50 changes: 50 additions & 0 deletions main/boards/lc-s3-wifi-1.54tft/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#ifndef _BOARD_CONFIG_H_
#define _BOARD_CONFIG_H_

#include <driver/gpio.h>
#include <driver/uart.h>

// 音频配置
#define AUDIO_INPUT_SAMPLE_RATE 16000
#define AUDIO_OUTPUT_SAMPLE_RATE 16000

#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_5
#define AUDIO_I2S_GPIO_WS GPIO_NUM_2
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_4
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_3
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_1

#define AUDIO_CODEC_PA_PIN GPIO_NUM_8
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_7
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_6
#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR

// 按钮配置
#define BUILTIN_LED_GPIO GPIO_NUM_46
#define BOOT_BUTTON_GPIO GPIO_NUM_0
#define VOLUME_UP_BUTTON_GPIO GPIO_NUM_40
#define VOLUME_DOWN_BUTTON_GPIO GPIO_NUM_39

// 显示屏配置
#define DISPLAY_WIDTH 240
#define DISPLAY_HEIGHT 240
#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_DC_GPIO GPIO_NUM_10
#define DISPLAY_CS_GPIO GPIO_NUM_13
#define DISPLAY_CLK_GPIO GPIO_NUM_14
#define DISPLAY_MOSI_GPIO GPIO_NUM_15
#define DISPLAY_RST_GPIO GPIO_NUM_16

#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_21
#define DISPLAY_BACKLIGHT_OUTPUT_INVERT false

//扩展
#define RELAY_LED GPIO_NUM_17

#endif // _BOARD_CONFIG_H_
9 changes: 9 additions & 0 deletions main/boards/lc-s3-wifi-1.54tft/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"target": "esp32s3",
"builds": [
{
"name": "lc-s3-wifi-1.54tft",
"sdkconfig_append": []
}
]
}
261 changes: 261 additions & 0 deletions main/boards/lc-s3-wifi-1.54tft/lc-s3-wifi-1.54tft.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
#include "wifi_board.h"
#include "codecs/es8311_audio_codec.h"
#include "display/lcd_display.h"
#include "system_reset.h"
#include "application.h"
#include "button.h"
#include "config.h"
#include "assets/lang_config.h"
#include "led/single_led.h"
#include "mcp_server.h"
#include "power_manager.h"

#include <wifi_station.h>
#include <esp_log.h>
#include <esp_lcd_panel_vendor.h>
#include <driver/i2c_master.h>
#include <driver/spi_common.h>

#define TAG "lc-s3-wifi-1.54tft"

LV_FONT_DECLARE(font_puhui_20_4);
LV_FONT_DECLARE(font_awesome_20_4);

class lc_s3_wifi_1_54tft : public WifiBoard {
private:
i2c_master_bus_handle_t i2c_bus_;
Button volume_up_button_;
Button volume_down_button_;
Button boot_button_;
PowerManager* power_manager_;
Display* display_;
bool led_on_ = false;
//电源管理初始化
void InitializePowerManager() {
power_manager_ = new PowerManager(GPIO_NUM_38);
power_manager_->OnChargingStatusChanged([this](bool is_charging) {
if (is_charging) {
//power_save_timer_->SetEnabled(false);
} else {
//power_save_timer_->SetEnabled(true);
}
});
}

//i2c初始化,音频ES8311
void InitializeI2c() {
// Initialize I2C peripheral
i2c_master_bus_config_t i2c_bus_cfg = {
.i2c_port = 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_));
}

//SPI初始化,显示屏
void InitializeSpi() {
spi_bus_config_t buscfg = {};
buscfg.mosi_io_num = DISPLAY_MOSI_GPIO;
buscfg.miso_io_num = GPIO_NUM_NC;
buscfg.sclk_io_num = DISPLAY_CLK_GPIO;
buscfg.quadwp_io_num = GPIO_NUM_NC;
buscfg.quadhd_io_num = GPIO_NUM_NC;
buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t);
ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO));
}

//按钮初始化
void InitializeButtons() {
boot_button_.OnClick([this]() {
auto& app = Application::GetInstance();
if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
ResetWifiConfiguration();
}
app.ToggleChatState();
});
volume_up_button_.OnClick([this]() {
auto codec = GetAudioCodec();
auto volume = codec->output_volume() + 10;
if (volume > 100) {
volume = 100;
}
codec->SetOutputVolume(volume);
GetDisplay()->ShowNotification(Lang::Strings::VOLUME + std::to_string(volume));
});

volume_up_button_.OnLongPress([this]() {
GetAudioCodec()->SetOutputVolume(100);
GetDisplay()->ShowNotification(Lang::Strings::MAX_VOLUME);
});

volume_down_button_.OnClick([this]() {
auto codec = GetAudioCodec();
auto volume = codec->output_volume() - 10;
if (volume < 0) {
volume = 0;
}
codec->SetOutputVolume(volume);
GetDisplay()->ShowNotification(Lang::Strings::VOLUME + std::to_string(volume));
});

volume_down_button_.OnLongPress([this]() {
GetAudioCodec()->SetOutputVolume(0);
GetDisplay()->ShowNotification(Lang::Strings::MUTED);
});
}

//显示屏初始化
void InitializeDisplay() {
esp_lcd_panel_io_handle_t panel_io = nullptr;
esp_lcd_panel_handle_t panel = nullptr;

// 液晶屏控制IO初始化
ESP_LOGD(TAG, "Install panel IO");
esp_lcd_panel_io_spi_config_t io_config = {};
io_config.cs_gpio_num = DISPLAY_CS_GPIO;
io_config.dc_gpio_num = DISPLAY_DC_GPIO;
io_config.spi_mode = 0;
io_config.pclk_hz = 40 * 1000 * 1000;
io_config.trans_queue_depth = 10;
io_config.lcd_cmd_bits = 8;
io_config.lcd_param_bits = 8;
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io));

// 初始化液晶屏驱动芯片
ESP_LOGD(TAG, "Install LCD driver");

esp_lcd_panel_dev_config_t panel_config = {};
panel_config.reset_gpio_num = DISPLAY_RST_GPIO;
panel_config.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB;
panel_config.bits_per_pixel = 16;
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel));

esp_lcd_panel_reset(panel);
esp_lcd_panel_init(panel);
esp_lcd_panel_invert_color(panel, true);
esp_lcd_panel_disp_on_off(panel, true);
// display_ = new SpiLcdDisplay(panel_io, panel,
// DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY,
// {
// .text_font = &font_puhui_20_4,
// .icon_font = &font_awesome_20_4,
// .emoji_font = font_emoji_64_init(),
// });
display_ = new SpiLcdDisplay(
panel_io,
panel,
DISPLAY_WIDTH,
DISPLAY_HEIGHT,
DISPLAY_OFFSET_X,
DISPLAY_OFFSET_Y,
DISPLAY_SWAP_XY,
DISPLAY_MIRROR_X,
DISPLAY_MIRROR_Y
);
}

void InitializeGpio() {
gpio_config_t io_conf = {
.pin_bit_mask = 1 << RELAY_LED, // 配置 GPIO
.mode = GPIO_MODE_OUTPUT, // 设置为输出模式
.pull_up_en = GPIO_PULLUP_DISABLE, // 禁用上拉电阻
.pull_down_en = GPIO_PULLDOWN_DISABLE, // 禁用下拉电阻
.intr_type = GPIO_INTR_DISABLE, // 禁用中断
};
gpio_config(&io_conf); // 应用配置
gpio_set_level(RELAY_LED,0);
}
// 物联网初始化,添加对 AI 可见设备
void InitializeTools() {
auto& mcp_server = McpServer::GetInstance();
// 灯光控制
mcp_server.AddTool("self.light.get_power", "获取灯是否打开", PropertyList(), [this](const PropertyList& properties) -> ReturnValue {
return led_on_;
});

mcp_server.AddTool("self.light.turn_on", "打开灯", PropertyList(), [this](const PropertyList& properties) -> ReturnValue {
gpio_set_level(RELAY_LED, 1);
led_on_ = true;
return true;
});

mcp_server.AddTool("self.light.turn_off", "关闭灯", PropertyList(), [this](const PropertyList& properties) -> ReturnValue {
gpio_set_level(RELAY_LED, 0);
led_on_ = false;
return true;
});
// thing_manager.AddThing(iot::CreateThing("Speaker"));
// thing_manager.AddThing(iot::CreateThing("Screen"));
// thing_manager.AddThing(iot::CreateThing("Battery"));
// thing_manager.AddThing(iot::CreateThing("Relay"));
//在此扩展IOT设备
}

public:
//构造函数
lc_s3_wifi_1_54tft() :
volume_up_button_(VOLUME_UP_BUTTON_GPIO),
volume_down_button_(VOLUME_DOWN_BUTTON_GPIO),
boot_button_(BOOT_BUTTON_GPIO) {
InitializePowerManager();
InitializeI2c();
InitializeSpi();
InitializeDisplay();
InitializeButtons();
InitializeGpio();
InitializeTools();
GetBacklight()->SetBrightness(70);
}

//获取音频编码器
virtual AudioCodec* GetAudioCodec() override {
static Es8311AudioCodec audio_codec(
i2c_bus_,
I2C_NUM_0,
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);
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;
}

virtual bool GetBatteryLevel(int& level, bool& charging, bool& discharging) override {
static bool last_discharging = false;
charging = power_manager_->IsCharging();
discharging = power_manager_->IsDischarging();
if (discharging != last_discharging) {
//power_save_timer_->SetEnabled(discharging);
last_discharging = discharging;
}
level = power_manager_->GetBatteryLevel();
return true;
}
virtual Led* GetLed() override {
static SingleLed led(BUILTIN_LED_GPIO);
return &led;
}
};

DECLARE_BOARD(lc_s3_wifi_1_54tft);
Loading