Add initial board, HAL, and executor modules

This commit is contained in:
wang committed 2026-05-07 17:24:10 +08:00
1 parent 3b9e129c88
commit 0b2eebe76d
82 files changed
+20611

No files matched your search

@@ -0,0 +1,780 @@
/**
* @file board.cc
* @brief 板级外设初始化类,包含步进电机、毫米波雷达、I2C总线等外设的初始化函数。
* @author zouyuhua
* @date 2025年8月7日
*
*/
extern "C" {
#include "esp_log.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "driver/ledc.h"
#include "driver/gptimer.h"
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "hal/gpio_types.h"
#include "hal/uart_types.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "i2c_bus.h"
#include "esp_peripherals.h"
#include "periph_sdcard.h"
#include "esp_sleep.h"
#include "driver/rtc_io.h"
}
#include "board_sweekar.h"
#include "config.h"
#include "board.h" // 添加board.h以获取audio_board_sdcard_init函数声明
#include "drv8428.h"
#include "aw8646.h"
#include "esp_vfs_fat.h"
#include "audio_mem.h"
#include "esp_timer.h"
#include "base_board_hal_i2c.h"
#define TAG "board_sweekar"
static BoardSweekar* s_board_instance = nullptr;
BoardSweekar* BoardSweekar::GetInstance()
{
if (s_board_instance == nullptr) {
static BoardSweekar global_board;
s_board_instance = &global_board;
}
return s_board_instance;
}
BoardSweekar::BoardSweekar()
{
#ifdef CONFIG_STEPPER_DRIVER_AW8646
stepper_driver_ = new Aw8646Driver(io_expansion_);
#else
stepper_driver_ = new Drv8428Driver(io_expansion_);
#endif
// Initialize Shutdown Control Pin (GPIO_NUM_13) and pull it HIGH
// This is required to keep the main power on.
#ifdef SHUTDOWN_CTRL_PIN
gpio_config_t io_conf = {};
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = (1ULL << SHUTDOWN_CTRL_PIN);
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
gpio_config(&io_conf);
// 拉低开机
gpio_set_level(SHUTDOWN_CTRL_PIN, 0);
ESP_LOGI(TAG, "Initialized SHUTDOWN_CTRL_PIN (%d) to LOW (Power ON)", SHUTDOWN_CTRL_PIN);
#endif
}
BoardSweekar::~BoardSweekar()
{
if (stepper_driver_) {
delete stepper_driver_;
stepper_driver_ = nullptr;
}
}
void BoardSweekar::SetAudioAmplifier(bool enable) {
// 隐藏具体的硬件实现细节(比如当前版本是通过 IO 扩展板控制的)
io_expansion_.SetPaCtrlMode(enable);
ESP_LOGI(TAG, "Audio Amplifier %s", enable ? "ENABLED" : "DISABLED");
}
/*========================== 步进电机相关驱动 ==========================*/
/**
* @brief 步进电机初始化函数
* 配置步进电机所需的GPIO引脚模式,通过IO扩展板设置步进驱动芯片的工作模式
* 在 stepper_motor.cc 中完成 GPTimer + GPIO 翻转 STEP 脉冲的初始化
*/
void BoardSweekar::StepperMotorInit(void)
{
esp_err_t err = ESP_OK;
// 1) STEP 引脚改为普通 GPIO(不再用 LEDC)
gpio_config_t io_cfg;
io_cfg.pin_bit_mask = 1ULL << STEPPER_STEP_IO;
io_cfg.mode = GPIO_MODE_OUTPUT;
io_cfg.pull_up_en = GPIO_PULLUP_DISABLE;
io_cfg.pull_down_en = GPIO_PULLDOWN_DISABLE;
io_cfg.intr_type = GPIO_INTR_DISABLE;
err = gpio_config(&io_cfg);
if (err != ESP_OK)
{
ESP_LOGE(TAG_BOARD, "步进电机 STEP GPIO 配置失败, 错误码: 0x%x", err);
}
// 初始电平拉低,保证上电不乱跳
gpio_set_level(STEPPER_STEP_IO, 0);
// 2) 检查 I2C 总线是否已初始化
if (bus_handle_ == nullptr)
{
ESP_LOGE(TAG_BOARD, "I2C总线未初始化,请先调用I2CMasterInit()");
return;
}
// 3) 初始化驱动对象并初始化
if (stepper_driver_) {
err = stepper_driver_->Init();
if (err != ESP_OK) {
ESP_LOGE(TAG_BOARD, "步进电机驱动初始化失败, 错误码: 0x%x", err);
}
} else {
ESP_LOGE(TAG_BOARD, "步进电机驱动创建失败");
}
}
/**
* @brief LCD IO引脚初始化函数(消除与步进电机的耦合)
*
* 配置LCD所需的IO扩展板寄存器,确保LCD复位引脚正常工作
* 此函数独立于步进电机初始化,专门处理LCD相关的IO配置
*/
void BoardSweekar::LcdIoInit(void)
{
esp_err_t err = ESP_OK;
// 1) 检查I2C总线是否已初始化
if (bus_handle_ == nullptr)
{
ESP_LOGE(TAG_BOARD, "I2C总线未初始化,请先调用I2CMasterInit()");
return;
}
// 2) 执行硬件复位,确保IO扩展板处于已知状态
err = io_expansion_.ResetIoExpand();
if (err != ESP_OK)
{
ESP_LOGE(TAG_BOARD, "IO扩展板硬件复位失败, 错误码: 0x%x", err);
return;
}
else
{
ESP_LOGI(TAG_BOARD, "IO扩展板硬件复位成功");
}
// 3) 配置IO扩展板模式(端口方向等)
err = io_expansion_.IoexpandSetMode();
if (err != ESP_OK)
{
ESP_LOGE(TAG_BOARD, "IO扩展板模式配置失败, 错误码: 0x%x", err);
return;
}
else
{
ESP_LOGI(TAG_BOARD, "IO扩展板模式配置成功");
}
// 4) 初始化LCD复位引脚:设置为高电平
err = io_expansion_.SetLcdResetMode(LCD_RST_HIGH, LCD_RST_PORT, LCD_RST_PIN);
if (err != ESP_OK)
{
ESP_LOGE(TAG_BOARD, "LCD复位引脚高电平设置失败, 错误码: 0x%x", err);
return;
}
else
{
ESP_LOGI(TAG_BOARD, "LCD复位引脚高电平设置成功");
}
// 5) 初始化LED_EN电源为关闭状态 (PMOS高电平关)
// 只有在需要亮灯时,由ActuatorActor主动开启,避免平静状态下常亮
err = io_expansion_.SetLedEnMode(false);
if (err != ESP_OK)
{
ESP_LOGE(TAG_BOARD, "初始化LED_EN电源(关闭)失败, 错误码: 0x%x", err);
}
else
{
ESP_LOGI(TAG_BOARD, "初始化LED_EN电源(关闭)成功");
}
}
/**
* @brief 执行系统关机
* 内部拉高 SHUTDOWN_CTRL_PIN 引脚切断电源
*/
void BoardSweekar::SystemShutdown(void)
{
#ifdef SHUTDOWN_CTRL_PIN
ESP_LOGI(TAG, "Executing System Shutdown... Pulling SHUTDOWN_CTRL_PIN (%d) HIGH", SHUTDOWN_CTRL_PIN);
// 用户指定:拉高可以完成关机动作
gpio_set_level(SHUTDOWN_CTRL_PIN, 1);
// 给一点时间让电源完全断开
vTaskDelay(pdMS_TO_TICKS(1000));
#else
ESP_LOGW(TAG, "SHUTDOWN_CTRL_PIN is not defined. Cannot execute hardware shutdown.");
#endif
}
/*========================== 毫米波雷达相关驱动 ==========================*/
/**
* @brief 毫米波雷达串口初始化函数
*
* 配置毫米波雷达所使用的串口参数(波特率、数据位、校验位、停止位等),设置串口引脚,
* 并安装串口驱动。采用较大的RX/TX FIFO深度以处理突发数据,禁用驱动自带事件队列以避免
* 与自定义中断冲突。
*/
void BoardSweekar::MillimeterWaveRadarUartInit(void)
{
uart_config_t uart_config = {
.baud_rate = RADAR_BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
},
};
// 1. 设置串口参数
ESP_ERROR_CHECK(uart_param_config(RADAR_UART_NUM, &uart_config));
// 2. 设置 UART 引脚
ESP_ERROR_CHECK(uart_set_pin(RADAR_UART_NUM, UART_TX_PIN, UART_RX_PIN,
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
// 3. 安装 UART 驱动(禁用驱动自带事件队列,避免与自定义中断冲突)
// 增加 RX/TX FIFO 深度以处理突发数据
ESP_ERROR_CHECK(uart_driver_install(RADAR_UART_NUM, RADAR_BUF_SIZE * 4, RADAR_BUF_SIZE * 4,
0, NULL, 0));
}
/**
* @brief 毫米波雷达中断引脚初始化函数
*
* 配置毫米波雷达中断引脚为输入模式,禁用上拉电阻,使能下拉电阻,初始禁用中断功能
* (如需使用中断需单独进行配置)。
*/
void BoardSweekar::MillimeterWaveRadarGpioInit(void)
{
// GPIO配置结构体
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << MILLIMETER_WAVE_RADAR_PIN), // 选择GPIO引脚
.mode = GPIO_MODE_INPUT, // 设置为输入模式
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_ENABLE, // 使能下拉
.intr_type = GPIO_INTR_DISABLE // 禁用中断(如需中断需单独配置)
};
// 配置GPIO
gpio_config(&io_conf);
}
/*========================== I2C总线及挂载的从设备相关驱动 ==========================*/
/**
* @brief I2C总线及从机设备初始化函数
*
* 首先配置并创建I2C主机总线,然后依次添加IO扩展板和线性马达作为I2C从机设备到总线上。
* 若总线创建或设备添加失败,会输出错误信息并进行相应的资源清理(删除已创建的总线)。
* 初始化成功后,会通过ESP_LOGI输出IO扩展板和线性马达的从机地址信息。
*
* @return esp_err_t 初始化结果,ESP_OK表示成功,其他错误码表示相应的失败原因
*/
esp_err_t BoardSweekar::I2CMasterInit(void)
{
static const char *I2C_INIT = "I2C_INIT";
// 初始化IO扩展板复位引脚
gpio_config_t reset_io_conf = {
.pin_bit_mask = (1ULL << IO_EXPAND_RSTN),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_ENABLE, // 使能上拉
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&reset_io_conf);
// 执行复位时序:先拉低100ms,再拉高并等待100ms
gpio_set_level(IO_EXPAND_RSTN, 0); // 拉低复位
vTaskDelay(pdMS_TO_TICKS(100)); // 等待100ms
gpio_set_level(IO_EXPAND_RSTN, 1); // 释放复位
vTaskDelay(pdMS_TO_TICKS(100)); // 等待设备启动
ESP_LOGI(I2C_INIT, "IO扩展板复位完成");
// 创建统一的I2C总线(使用ESP-ADF的i2c_bus)
i2c_config_t i2c_cfg = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C0_MASTER_SDA_IO,
.scl_io_num = I2C0_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master = {
.clk_speed = 100000,
},
};
// 创建I2C总线(ESP-ADF的audio_board_init会复用这个总线)
bus_handle_ = i2c_bus_create(I2C0_MASTER_PORT, &i2c_cfg);
if (bus_handle_ == NULL) {
ESP_LOGE(TAG, "Failed to create I2C bus");
return ESP_FAIL;
}
vTaskDelay(pdMS_TO_TICKS(100)); // 等待设备启动
// ESP-ADF的i2c_bus不需要单独添加设备,直接通过总线句柄和设备地址进行通信
// 验证线性马达设备是否存在
esp_err_t err = i2c_bus_probe_addr(bus_handle_, LINEAR_MOTOR_I2C_SLAVE_ADDR << 1);
if (err != ESP_OK) {
ESP_LOGE(I2C_INIT, "线性马达设备未找到(地址:0x%02X),错误码: 0x%x", LINEAR_MOTOR_I2C_SLAVE_ADDR, err);
// 不返回错误,继续初始化
} else {
ESP_LOGI(I2C_INIT, "线性马达设备检测成功(地址:0x%02X)", LINEAR_MOTOR_I2C_SLAVE_ADDR);
}
// 验证IO扩展板设备是否存在
err = i2c_bus_probe_addr(bus_handle_, I2C_IO_EXPAND_SLAVE_ADDR << 1);
if (err != ESP_OK) {
ESP_LOGE(I2C_INIT, "IO扩展板设备未找到(地址:0x%02X),错误码: 0x%x", I2C_IO_EXPAND_SLAVE_ADDR, err);
// 不返回错误,继续初始化其他设备
} else {
ESP_LOGI(I2C_INIT, "IO扩展板设备检测成功(地址:0x%02X)", I2C_IO_EXPAND_SLAVE_ADDR);
}
// 验证陀螺仪设备是否存在
err = i2c_bus_probe_addr(bus_handle_, GYROSCOPE_I2C_SLAVE_ADDR << 1);
if (err != ESP_OK) {
ESP_LOGE(I2C_INIT, "陀螺仪设备未找到(地址:0x%02X),错误码: 0x%x", GYROSCOPE_I2C_SLAVE_ADDR, err);
// 不返回错误,继续初始化
} else {
ESP_LOGI(I2C_INIT, "陀螺仪设备检测成功(地址:0x%02X)", GYROSCOPE_I2C_SLAVE_ADDR);
}
// 为IO扩展板设置总线句柄和设备地址(使用7位地址)
io_expansion_.bus_handle_ = bus_handle_;
io_expansion_.device_addr_ = I2C_IO_EXPAND_SLAVE_ADDR << 1;
// 线性马达的初始化已移至 InitializeAllHardware 中统一调用 Init 方法
// linear_motor_ 的参数传递将在那里完成,不再此处直接赋值,提高内聚性
ESP_LOGI(I2C_INIT, "I2C总线初始化完成");
return ESP_OK;
}
/*========================== VBAT to VBAT_5V相关驱动 ==========================*/
/**
* @brief 开启VBAT to VBAT_5V
*
* 创建开启升压的电源管理单元
*
*/
void BoardSweekar::VbatToVbat5vInit(void)
{
// 配置VBAT_5V引脚为输出模式
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << VBAT_5V_PIN),
.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);
// 使能VBAT_5V
gpio_set_level(VBAT_5V_PIN, 1);
}
/*========================== 底座控制串口相关驱动 ==========================*/
/**
* @brief 底座控制命令串口初始化函数
*/
// 根据配置选择通信方式的HAL头文件
#ifdef CONFIG_BASE_BOARD_COMM_I2C
#include "base_board_hal_i2c.h"
#else
#include "base_board_hal_uart.h"
#endif
void BoardSweekar::BaseBoardControlInit(void)
{
#ifdef CONFIG_BASE_BOARD_COMM_I2C
// I2C Mode
if (bus_handle_ == nullptr) {
ESP_LOGE(TAG, "I2C bus not initialized before BaseBoardControlInit");
return;
}
// 创建 I2C HAL 实例
BaseBoardHalI2c *hal = new BaseBoardHalI2c(bus_handle_);
base_board_control_.Init(hal);
ESP_LOGI(TAG, "BaseBoardControl I2C initialized");
#else
// UART Mode
uart_config_t uart_config = {
.baud_rate = BASE_BOARD_CTL_UART_BAUDRATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
.flags = {
.allow_pd = 0,
.backup_before_sleep = 0,
},
};
// 1. 设置串口参数
ESP_ERROR_CHECK(uart_param_config(BASE_BOARD_CTL_UART_PORT, &uart_config));
// 2. 设置 UART 引脚
ESP_ERROR_CHECK(uart_set_pin(BASE_BOARD_CTL_UART_PORT, BASE_BOARD_CTL_UART_TX_PIN, BASE_BOARD_CTL_UART_RX_PIN,
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
// 3. 安装 UART 驱动
ESP_ERROR_CHECK(uart_driver_install(BASE_BOARD_CTL_UART_PORT,
BASE_BOARD_CTL_UART_BUF_SIZE,
BASE_BOARD_CTL_UART_BUF_SIZE,
0, NULL, 0));
BaseBoardHalUart *hal = new BaseBoardHalUart(BASE_BOARD_CTL_UART_PORT);
base_board_control_.Init(hal);
ESP_LOGI(TAG, "BaseBoardControl UART initialized");
#endif
}
/*========================== SD卡相关驱动 ==========================*/
/**
* @brief SD卡初始化函数
*
* 初始化SD卡外设,使用1线模式进行通信。该函数负责初始化外设管理器
* 并配置SD卡,为后续的文件系统操作做准备。
*
* @return esp_err_t 初始化结果,ESP_OK表示成功,其他错误码表示失败原因
*/
esp_err_t BoardSweekar::InitializeSdcard(void)
{
static const char *SDCARD_TAG = "SDCARD_INIT";
esp_err_t ret;
ESP_LOGI(SDCARD_TAG, "Initializing SD card");
if (is_sdcard_initialized_) {
ESP_LOGW(SDCARD_TAG, "SD card already initialized");
return ESP_OK;
}
// 初始化外设管理
esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
periph_cfg.extern_stack = true; // 将任务栈分配到 PSRAM 以节省 Internal SRAM
periph_set_ = esp_periph_set_init(&periph_cfg);
if (!periph_set_) {
ESP_LOGE(SDCARD_TAG, "Failed to initialize peripheral set");
return ESP_FAIL;
}
// 初始化SD卡外设
ret = audio_board_sdcard_init(periph_set_, SD_MODE_1_LINE);
if (ret != ESP_OK) {
ESP_LOGE(SDCARD_TAG, "Failed to initialize SD card: %s", esp_err_to_name(ret));
return ret;
}
is_sdcard_initialized_ = true;
ESP_LOGI(SDCARD_TAG, "SD card initialized successfully");
return ESP_OK;
}
/**
* @brief 统一的硬件初始化接口实现
*
* 按照依赖关系顺序初始化所有硬件资源:
* 1. I2C总线(最基础,其他设备可能依赖)
* 2. IO扩展板(可能影响其他设备)
* 3. SD卡(文件系统,供显示和音频使用)
* 4. 其他外设
*
* @return esp_err_t 初始化结果,ESP_OK表示全部成功
*/
esp_err_t BoardSweekar::InitializeAllHardware(void)
{
static const char *HW_INIT_TAG = "HW_INIT";
esp_err_t ret;
ESP_LOGI(HW_INIT_TAG, "Starting unified hardware initialization...");
// 1. 初始化I2C总线(最基础)
ret = I2CMasterInit();
if (ret != ESP_OK) {
ESP_LOGE(HW_INIT_TAG, "Failed to initialize I2C master: %s", esp_err_to_name(ret));
return ret;
}
ESP_LOGI(HW_INIT_TAG, "I2C master initialized");
// 2. 创建I2C读任务(IO扩展板需要)
io_expansion_.CreateI2cReadTask();
ESP_LOGI(HW_INIT_TAG, "I2C read task created");
// 3. 初始化SD卡(文件系统,供显示和音频使用)
ret = InitializeSdcard();
if (ret != ESP_OK) {
ESP_LOGE(HW_INIT_TAG, "Failed to initialize SD card: %s", esp_err_to_name(ret));
// SD卡失败不是致命错误,继续初始化其他硬件
ESP_LOGW(HW_INIT_TAG, "SD card initialization failed, but continuing with other hardware");
} else {
ESP_LOGI(HW_INIT_TAG, "SD card initialized");
}
// 4. 初始化LCD IO引脚
LcdIoInit();
ESP_LOGI(HW_INIT_TAG, "LCD IO pins initialized");
// 5. 初始化底座控制
if (bus_handle_ != nullptr) {
BaseBoardHalI2c *hal_i2c = new BaseBoardHalI2c(bus_handle_);
base_board_control_.Init(hal_i2c);
ESP_LOGI(HW_INIT_TAG, "Base board control initialized with I2C handle");
} else {
ESP_LOGE(HW_INIT_TAG, "Failed to initialize base board control: I2C bus is null");
}
// 6. 可选外设(根据具体应用需求)
// BaseBoardControlUartInit(); // 底座控制串口(demo5需要)
// ESP_LOGI(HW_INIT_TAG, "Base board control UART initialized");
// MillimeterWaveRadarUartInit();
// MillimeterWaveRadarGpioInit();
StepperMotorInit();
ESP_LOGI(HW_INIT_TAG, "Unified hardware initialization completed successfully");
return ESP_OK;
}
/**
* @brief 进入低功耗模式
*
* 根据指定的功耗模式,执行相应的功耗优化策略:
* - IDLE模式:关闭非必要外设,保持快速响应
* - LIGHT_SLEEP模式:进入轻度睡眠,CPU暂停,外设断电
* - DEEP_SLEEP模式:深度睡眠,仅RTC运行,功耗最低
*/
esp_err_t BoardSweekar::EnterLowPowerMode(power_mode_t mode) {
static const char *POWER_TAG = "POWER_MGMT";
esp_err_t ret = ESP_OK;
ESP_LOGI(POWER_TAG, "Entering power mode: %d", mode);
if (mode == current_power_mode_) {
ESP_LOGW(POWER_TAG, "Already in power mode %d", mode);
return ESP_OK;
}
// 保存当前模式,以便恢复
power_mode_t previous_mode = current_power_mode_;
switch (mode) {
case POWER_MODE_NORMAL:
// 正常模式,不需要特殊处理
break;
case POWER_MODE_IDLE:
// 空闲模式:关闭非必要外设
ESP_LOGI(POWER_TAG, "Idle mode: disabling non-essential peripherals");
// 关闭SD卡(如果正在使用,需要先卸载)
if (is_sdcard_initialized_) {
// 注意:这里只是示例,实际应用中需要确保没有文件操作
ESP_LOGW(POWER_TAG, "SD card still active in idle mode");
}
// 关闭显示背光
// 关闭非必要GPIO的上拉/下拉
// 降低I2C时钟频率
break;
case POWER_MODE_LIGHT_SLEEP:
// 轻度睡眠
ESP_LOGI(POWER_TAG, "Light sleep mode: preparing for sleep");
// 设置唤醒源(需要根据具体需求配置)
// esp_sleep_enable_timer_wakeup(1000000); // 1秒后唤醒
// esp_sleep_enable_ext0_wakeup(GPIO_NUM_XX, 0); // 外部中断唤醒
// 进入轻度睡眠
// ret = esp_light_sleep_start();
if (ret != ESP_OK) {
ESP_LOGE(POWER_TAG, "Failed to enter light sleep: %s", esp_err_to_name(ret));
current_power_mode_ = previous_mode;
return ret;
}
break;
case POWER_MODE_DEEP_SLEEP:
// 深度睡眠
ESP_LOGI(POWER_TAG, "Deep sleep mode: system will restart after wake-up");
// 保存必要的RTC数据
// rtc_gpio_isolate(GPIO_NUM_XX); // 隔离GPIO
// 设置深度睡眠唤醒源
// esp_sleep_enable_timer_wakeup(60000000); // 60秒后唤醒
// 进入深度睡眠
// esp_deep_sleep_start();
// 注意:深度睡眠后系统会重启,不会返回
break;
default:
ESP_LOGE(POWER_TAG, "Invalid power mode: %d", mode);
return ESP_ERR_INVALID_ARG;
}
current_power_mode_ = mode;
ESP_LOGI(POWER_TAG, "Successfully entered power mode: %d", mode);
return ret;
}
/**
* @brief 退出低功耗模式
*
* 从低功耗模式恢复到正常运行模式,重新初始化必要的硬件资源。
*/
esp_err_t BoardSweekar::ExitLowPowerMode(void) {
static const char *POWER_TAG = "POWER_MGMT";
ESP_LOGI(POWER_TAG, "Exiting low power mode");
if (current_power_mode_ == POWER_MODE_NORMAL) {
ESP_LOGW(POWER_TAG, "Already in normal mode");
return ESP_OK;
}
// 根据之前的功耗模式执行相应的恢复操作
switch (current_power_mode_) {
case POWER_MODE_IDLE:
// 恢复空闲模式
ESP_LOGI(POWER_TAG, "Restoring from idle mode");
// 重新初始化必要的外设
// 恢复I2C时钟频率
// 重新开启显示背光
break;
case POWER_MODE_LIGHT_SLEEP:
// 轻度睡眠唤醒后会自动继续执行
ESP_LOGI(POWER_TAG, "Woken up from light sleep");
// 重新配置时钟(如果需要)
// 重新初始化外设
break;
case POWER_MODE_DEEP_SLEEP:
// 深度睡眠后系统会重启,不会执行到这里
ESP_LOGW(POWER_TAG, "Deep sleep recovery should not reach here");
break;
default:
break;
}
// 恢复到正常模式
current_power_mode_ = POWER_MODE_NORMAL;
ESP_LOGI(POWER_TAG, "Successfully exited low power mode");
return ESP_OK;
}
/**
* @brief 设置硬件模块电源状态
*
* 提供精细化的电源管理,可以单独控制各个硬件模块的电源状态。
*/
esp_err_t BoardSweekar::SetModulePower(hardware_module_t module, bool enable) {
static const char *POWER_TAG = "POWER_MODULE";
esp_err_t ret = ESP_OK;
ESP_LOGI(POWER_TAG, "%s module %d", enable ? "Enabling" : "Disabling", module);
// 更新电源状态位图
if (enable) {
power_state_flags_ |= (1 << module);
} else {
power_state_flags_ &= ~(1 << module);
}
switch (module) {
case HW_MODULE_I2C:
if (!enable && bus_handle_) {
// 注意:I2C总线通常不建议完全关闭,可能影响多个设备
ESP_LOGW(POWER_TAG, "I2C bus power control not recommended");
}
break;
case HW_MODULE_SDCARD:
if (enable && !is_sdcard_initialized_) {
ret = InitializeSdcard();
} else if (!enable && is_sdcard_initialized_) {
// 卸载SD卡文件系统
// 注意:需要确保没有打开的文件
ESP_LOGW(POWER_TAG, "SD card power down requires file system cleanup");
}
break;
case HW_MODULE_LCD:
// LCD背光控制
// LCD电源引脚控制(如果有)
break;
case HW_MODULE_AUDIO:
// 音频编解码器电源控制
// 需要与AudioPlayer协调
break;
case HW_MODULE_MOTOR:
// 步进电机驱动器电源控制
// 电机睡眠模式
break;
case HW_MODULE_GYROSCOPE:
// 陀螺仪电源控制
// 设置陀螺仪为低功耗模式
break;
case HW_MODULE_TOUCH:
// 触摸传感器电源控制
// 设置触摸传感器为睡眠模式
break;
case HW_MODULE_RADAR:
// 毫米波雷达电源控制
// 设置雷达为低功耗模式
break;
case HW_MODULE_IO_EXPAND:
// IO扩展板电源控制
// 设置扩展板为低功耗模式
break;
default:
ESP_LOGE(POWER_TAG, "Unknown hardware module: %d", module);
return ESP_ERR_INVALID_ARG;
}
if (ret == ESP_OK) {
ESP_LOGI(POWER_TAG, "Module %d power %s successfully", module, enable ? "enabled" : "disabled");
} else {
ESP_LOGE(POWER_TAG, "Failed to %s module %d: %s", enable ? "enable" : "disable", module, esp_err_to_name(ret));
}
return ret;
}
@@ -0,0 +1,181 @@
#ifndef __BOARD_H__
#define __BOARD_H__
#include "config.h"
#include "io_expansion_board.h"
#include "stepper_motor.h"
#include "stepper_driver.h"
#include "i2c_bus.h"
#include "gyroscope.h"
#include "touch_sensor.h"
#include "base_board_control.h"
#include "esp_peripherals.h"
#include "periph_sdcard.h"
#include "esp_sleep.h"
#include "driver/rtc_io.h"
/**
* @brief 功耗模式枚举
*/
typedef enum {
POWER_MODE_NORMAL, // 正常运行模式,所有硬件可用
POWER_MODE_IDLE, // 空闲模式,关闭非必要外设
POWER_MODE_LIGHT_SLEEP, // 轻度睡眠,快速唤醒
POWER_MODE_DEEP_SLEEP, // 深度睡眠,仅RTC运行
} power_mode_t;
/**
* @brief 硬件模块枚举,用于精细化电源管理
*/
typedef enum {
HW_MODULE_I2C, // I2C总线
HW_MODULE_SDCARD, // SD卡
HW_MODULE_LCD, // LCD显示
HW_MODULE_AUDIO, // 音频编解码器
HW_MODULE_MOTOR, // 步进电机
HW_MODULE_GYROSCOPE, // 陀螺仪
HW_MODULE_TOUCH, // 触摸传感器
HW_MODULE_RADAR, // 毫米波雷达
HW_MODULE_IO_EXPAND, // IO扩展板
} hardware_module_t;
/**
* @brief 硬件板级管理器
*
* 采用高内聚低耦合设计原则,统一管理所有硬件资源。
* 提供统一的硬件初始化接口和资源访问,避免各模块重复初始化。
*/
class BoardSweekar
{
private:
i2c_bus_handle_t bus_handle_ = nullptr; // 使用ESP-ADF的I2C总线句柄
esp_periph_set_handle_t periph_set_ = nullptr; // 外设管理句柄
bool is_sdcard_initialized_ = false; // SD卡初始化状态
power_mode_t current_power_mode_ = POWER_MODE_NORMAL; // 当前功耗模式
uint32_t power_state_flags_ = 0xFFFFFFFF; // 各模块电源状态位图(1为开启)
public:
BoardSweekar();
~BoardSweekar();
static BoardSweekar* GetInstance();
// --- 语义化的高层 API:音频与功放控制 ---
// 开启或关闭外放功放 (PA),供上层 AudioActor/AudioPlayer 调用,屏蔽底层引脚实现
void SetAudioAmplifier(bool enable);
IOExpansionBoard io_expansion_; // IO扩展板对象
Gyroscope gyroscope_; // 陀螺仪对象
TouchSensor touch_sensor_; // 触摸传感器对象
BaseBoardControl base_board_control_; // 底座控制对象
StepperDriver* stepper_driver_ = nullptr; // 步进电机驱动对象
StepperDriver* GetStepperDriver() const { return stepper_driver_; }
// 初始化步进电机
void StepperMotorInit(void);
// 初始化LCD IO引脚(消除与步进电机的耦合)
void LcdIoInit(void);
// 初始化串口
void MillimeterWaveRadarUartInit(void);
//初始化毫米波雷达的中断引脚
void MillimeterWaveRadarGpioInit(void);
/**
* @brief 执行系统关机
* 内部拉高/拉低 SHUTDOWN_CTRL_PIN 引脚切断电源
*/
void SystemShutdown(void);
// 初始化I2C总线
esp_err_t I2CMasterInit(void);
// 初始化VBAT toVBAT_5V引脚
void VbatToVbat5vInit(void);
// 初始化底座控制串口
void BaseBoardControlInit(void);
// 初始化SD卡(推荐使用统一的硬件初始化)
esp_err_t InitializeSdcard(void);
// 获取SD卡初始化状态
bool IsSdcardInitialized() const { return is_sdcard_initialized_; }
// 获取外设管理句柄(供需要访问SD卡的模块使用)
esp_periph_set_handle_t GetPeriphSet() const { return periph_set_; }
// 获取I2C总线句柄
i2c_bus_handle_t GetBusHandle() const { return bus_handle_; }
/**
* @brief 统一的硬件初始化接口
*
* 按照依赖关系顺序初始化所有硬件资源,确保各模块可以安全使用。
* 推荐在主程序启动时调用此函数,而不是分别调用各个初始化函数。
*
* @return esp_err_t 初始化结果,ESP_OK表示全部成功
*/
esp_err_t InitializeAllHardware(void);
/**
* @brief 完整的统一硬件初始化接口(专为复杂应用优化)
*
* 包含所有必要外设的完整初始化,适用于demo5等复杂应用场景。
* 这个函数会初始化:I2C总线、IO扩展板、SD卡、LCD IO、底座控制等。
*
* @return esp_err_t 初始化结果,ESP_OK表示全部成功
*/
esp_err_t InitializeAllHardwareComplete(void);
/**
* @brief 针对特定应用的硬件初始化配置
*
* 为不同类型的应用提供专门的初始化配置,优化启动流程。
*
* @param app_type 应用类型(demo5、音频播放器、显示应用等)
* @return esp_err_t 初始化结果,ESP_OK表示全部成功
*/
esp_err_t InitializeHardwareForApplication(int app_type);
/**
* @brief 功耗管理接口 - 进入低功耗模式
*
* 根据指定的功耗模式,关闭非必要硬件、设置GPIO为低功耗状态、
* 调整时钟频率等。支持多种功耗模式以适应不同应用场景。
*
* @param mode 功耗模式
* @return esp_err_t 操作结果
*/
esp_err_t EnterLowPowerMode(power_mode_t mode);
/**
* @brief 功耗管理接口 - 退出低功耗模式
*
* 从低功耗模式恢复,重新初始化必要的硬件资源。
*
* @return esp_err_t 操作结果
*/
esp_err_t ExitLowPowerMode(void);
/**
* @brief 获取当前功耗模式
*
* @return power_mode_t 当前功耗模式
*/
power_mode_t GetPowerMode(void) const { return current_power_mode_; }
/**
* @brief 设置硬件模块电源状态
*
* 单独控制某个硬件模块的电源状态,用于精细化的功耗管理。
*
* @param module 硬件模块
* @param enable true为开启,false为关闭
* @return esp_err_t 操作结果
*/
esp_err_t SetModulePower(hardware_module_t module, bool enable);
};
#endif
@@ -0,0 +1,186 @@
/**
* @file board_sweekar_complete_init.cc
* @brief 完整的统一硬件初始化实现
*
* 这个文件提供了完整的统一硬件初始化函数,包含所有必要的硬件初始化步骤。
* 专为demo5等复杂应用场景设计。
*/
/**
* @brief 完整的统一硬件初始化接口(专为demo5优化)
*
* 按照依赖关系顺序初始化所有硬件资源:
* 1. I2C总线(最基础,其他设备依赖)
* 2. IO扩展板(控制其他外设)
* 3. SD卡(文件系统,供显示和音频使用)
* 4. LCD IO引脚(显示相关)
* 5. 底座控制串口(通信)
* 6. 底座控制模块(业务逻辑)
* 7. 其他外设(根据应用需求)
*
* @return esp_err_t 初始化结果,ESP_OK表示全部成功
*/
esp_err_t BoardSweekar::InitializeAllHardwareComplete(void)
{
static const char *HW_INIT_TAG = "HW_INIT_COMPLETE";
esp_err_t ret;
ESP_LOGI(HW_INIT_TAG, "Starting complete hardware initialization...");
// 1. 初始化I2C总线(最基础,其他设备依赖)
ret = I2CMasterInit();
if (ret != ESP_OK) {
ESP_LOGE(HW_INIT_TAG, "Failed to initialize I2C master: %s", esp_err_to_name(ret));
return ret;
}
ESP_LOGI(HW_INIT_TAG, "✓ I2C master initialized");
// 2. 创建I2C读任务(IO扩展板需要)
io_expansion_.CreateI2cReadTask();
ESP_LOGI(HW_INIT_TAG, "✓ I2C read task created");
// 3. 初始化SD卡(文件系统,供显示和音频使用)
ret = InitializeSdcard();
if (ret != ESP_OK) {
ESP_LOGE(HW_INIT_TAG, "Failed to initialize SD card: %s", esp_err_to_name(ret));
// SD卡失败不是致命错误,继续初始化其他硬件
ESP_LOGW(HW_INIT_TAG, "⚠ SD card initialization failed, but continuing with other hardware");
} else {
ESP_LOGI(HW_INIT_TAG, "✓ SD card initialized");
}
// 4. 初始化LCD IO引脚(显示相关)
LcdIoInit();
ESP_LOGI(HW_INIT_TAG, "✓ LCD IO pins initialized");
// 5. 初始化底座控制串口(demo5需要)
BaseBoardControlUartInit();
ESP_LOGI(HW_INIT_TAG, "✓ Base board control UART initialized");
// 6. 初始化底座控制模块
base_board_control_.Init();
ESP_LOGI(HW_INIT_TAG, "✓ Base board control initialized");
// 7. 设置IO扩展板的PA控制模式(demo5需要)
io_expansion_.SetPaCtrlMode(true);
ESP_LOGI(HW_INIT_TAG, "✓ IO expansion PA control mode set");
// 8. 可选外设(根据具体应用需求启用)
// ESP_LOGI(HW_INIT_TAG, "Initializing optional peripherals...");
//
// // 毫米波雷达(如需要)
// MillimeterWaveRadarUartInit();
// MillimeterWaveRadarGpioInit();
// ESP_LOGI(HW_INIT_TAG, "✓ Millimeter wave radar initialized");
//
// // VBAT升压(如需要)
// VbatToVbat5vInit();
// ESP_LOGI(HW_INIT_TAG, "✓ VBAT to 5V booster initialized");
//
// // 步进电机(如需要)
// StepperMotorInit();
// ESP_LOGI(HW_INIT_TAG, "✓ Stepper motor initialized");
ESP_LOGI(HW_INIT_TAG, "=== Complete hardware initialization finished successfully ===");
return ESP_OK;
}
/**
* @brief 针对特定应用的硬件初始化配置
*
* 为不同类型的应用提供专门的初始化配置
*/
esp_err_t BoardSweekar::InitializeHardwareForApplication(application_type_t app_type) {
static const char *APP_INIT_TAG = "APP_HW_INIT";
ESP_LOGI(APP_INIT_TAG, "Initializing hardware for application type: %d", app_type);
// 基础硬件初始化(所有应用都需要)
esp_err_t ret = InitializeAllHardwareComplete();
if (ret != ESP_OK) {
ESP_LOGE(APP_INIT_TAG, "Basic hardware initialization failed");
return ret;
}
switch (app_type) {
case APP_TYPE_DEMO5: // 宠物游戏demo
ESP_LOGI(APP_INIT_TAG, "Configuring for Demo5 (Pet Game)...");
// Demo5需要的额外初始化
// 触摸传感器、陀螺仪、RGB LED等会在应用层初始化
ESP_LOGI(APP_INIT_TAG, "✓ Demo5 hardware configuration complete");
break;
case APP_TYPE_AUDIO_PLAYER: // 音频播放器
ESP_LOGI(APP_INIT_TAG, "Configuring for Audio Player...");
// 音频应用需要确保音频编解码器正确初始化
// 这部分通常在AudioPlayer类中处理
ESP_LOGI(APP_INIT_TAG, "✓ Audio player hardware configuration complete");
break;
case APP_TYPE_DISPLAY_ONLY: // 纯显示应用
ESP_LOGI(APP_INIT_TAG, "Configuring for Display Only...");
// 显示应用需要确保LCD相关硬件正确配置
// 这部分通常在Display类中处理
ESP_LOGI(APP_INIT_TAG, "✓ Display-only hardware configuration complete");
break;
case APP_TYPE_MINIMAL: // 最小化应用
ESP_LOGI(APP_INIT_TAG, "Configuring for Minimal Application...");
// 最小化配置,只保留最基本的功能
// 关闭非必要外设以节省功耗
ESP_LOGI(APP_INIT_TAG, "✓ Minimal hardware configuration complete");
break;
default:
ESP_LOGW(APP_INIT_TAG, "Unknown application type, using default configuration");
break;
}
return ESP_OK;
}
/**
* @brief 硬件初始化状态报告
*
* 提供详细的硬件初始化状态报告,便于调试和问题排查
*/
void BoardSweekar::ReportHardwareStatus(void) {
static const char *STATUS_TAG = "HW_STATUS";
ESP_LOGI(STATUS_TAG, "=== Hardware Initialization Status Report ===");
// I2C总线状态
ESP_LOGI(STATUS_TAG, "I2C Bus: %s", (bus_handle_ != nullptr) ? "✓ Initialized" : "✗ Not initialized");
// SD卡状态
ESP_LOGI(STATUS_TAG, "SD Card: %s", (is_sdcard_initialized_) ? "✓ Initialized" : "✗ Not initialized");
if (is_sdcard_initialized_) {
ESP_LOGI(STATUS_TAG, " Peripheral Set: %s", (periph_set_ != nullptr) ? "✓ Available" : "✗ Not available");
}
// IO扩展板状态
ESP_LOGI(STATUS_TAG, "IO Expansion Board: %s", (io_expansion_.bus_handle_ != nullptr) ? "✓ Configured" : "✗ Not configured");
// 底座控制状态
ESP_LOGI(STATUS_TAG, "Base Board Control: %s", (base_board_control_.GetUartPort() != 0) ? "✓ Initialized" : "✗ Not initialized");
// 功耗管理状态
ESP_LOGI(STATUS_TAG, "Power Management: %s", (current_power_mode_ == POWER_MODE_NORMAL) ? "✓ Normal mode" : "⚠ Low power mode");
ESP_LOGI(STATUS_TAG, " Current Mode: %d", current_power_mode_);
ESP_LOGI(STATUS_TAG, " Module Power States: 0x%08X", power_state_flags_);
// 内存状态
ESP_LOGI(STATUS_TAG, "Memory Status:");
ESP_LOGI(STATUS_TAG, " Internal RAM Free: %d bytes", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
ESP_LOGI(STATUS_TAG, " PSRAM Free: %d bytes", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
ESP_LOGI(STATUS_TAG, "=== End of Hardware Status Report ===");
}
@@ -0,0 +1,136 @@
/* 定义引脚分配 */
#ifndef _BOARD_CONFIG_H_
#define _BOARD_CONFIG_H_
/**
* @file config.h
* @brief 定义了引脚的分配。
* @author zouyuhua
* @date 2025年8月7日
*
*/
#include "driver/gpio.h"
#include "driver/i2c_master.h"
#include "driver/i2s.h"
#include "esp_log.h"
#include "esp_rom_sys.h" // 用于 esp_rom_delay_us
#include "esp_timer.h"
#include "esp_mac.h"
#include "driver/ledc.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/gptimer.h"
#include "esp_intr_alloc.h"
#include "driver/uart.h"
#include "esp_err.h"
#include "freertos/queue.h"
#include "soc/uart_reg.h"
#include "linear_motor.h"
#include "gyroscope.h"
#define TAG_BOARD "SWEEKAR_ESP32"
/*I2C总线引脚定义*/
#define I2C0_MASTER_PORT I2C_NUM_0
#define I2C0_MASTER_SDA_IO GPIO_NUM_2
#define I2C0_MASTER_SCL_IO GPIO_NUM_3
/* 步进电机配置 */
#define STEPPER_STEP_IO GPIO_NUM_42 // 步进电机脉冲输入引脚
#define STEPPER_TIMER_RES_HZ 1000000 // 步进电机定时器分辨率 1 MHz(1 us 步进)
/* 定义屏幕驱动控制引脚 */
#define ST7789_PIN_CLK GPIO_NUM_48 // SPI时钟引脚
#define ST7789_PIN_DC GPIO_NUM_38 // 数据/命令选择引脚RSEL
#define ST7789_PIN_MOSI GPIO_NUM_47 // SPI数据输出引脚
#define ST7789_PIN_CS GPIO_NUM_46 // SPI片选引脚
#define ST7789_PIN_BL GPIO_NUM_45 // 背光引脚
#define ST7789_PIN_RST GPIO_NUM_NC // 复位引脚
#define LCD_BL_ACTIVE_LEVEL 0 // 背光有效电平:1=高电平有效(NMOS),0=低电平有效(PMOS)
#define LCD_WIDTH 172 // 屏幕宽度(水平方向像素数)
#define LCD_HEIGHT 320 // 屏幕高度(垂直方向像素数)
/* 毫米波雷达配置参数 */
/* 定义毫米波雷达的中断引脚 */
#define MILLIMETER_WAVE_RADAR_PIN GPIO_NUM_35
// UART 配置参数
#define RADAR_UART_NUM UART_NUM_1 // 使用 UART1
#define UART_TX_PIN GPIO_NUM_40 // GPIO40 作为 TX(根据实际硬件连接调整)
#define UART_RX_PIN GPIO_NUM_39 // GPIO39 作为 RX
#define RADAR_BAUD_RATE 9600 // 雷达波特率
#define RADAR_BUF_SIZE 100 // 雷达接收缓冲区大小
/* IO扩展硬件配置常量 */
#define I2C_MASTER_FREQ_HZ 100000 // I2C通信频率(100kHz)(可更改至400000)
#define I2C_IO_EXPAND_SLAVE_ADDR 0x58 // AW9523BTQR器件地址,v1_1_13的addr1和addr0是0
#define GPIO_INPUT_PIN_SEL GPIO_NUM_10 // 中断检测引脚
#define ESP_INTR_FLAG_DEFAULT 0 // 中断标志默认值
#define IO_EXPAND_RSTN GPIO_NUM_14 // IO扩展板复位引脚
/* 定义线性马达的I2C从机配置常量 */
#define LINEAR_MOTOR_I2C_SLAVE_ADDR 0x5A // 线性马达的I2C从机地址
/* 定义陀螺仪的I2C从机配置常量 */
#define GYROSCOPE_I2C_SLAVE_ADDR 0x6A // 陀螺仪的I2C从机地址
#define GYROSCOPE_INPUT_PIN_SEL GPIO_NUM_21 // 陀螺仪中断引脚
/* AW触摸芯片配置 */
#define AW_TOUCH_IRQ_PIN GPIO_NUM_11 // AW触摸芯片中断引脚
#define NFC_RST_PIN GPIO_NUM_12 // NFC复位引脚
#define SHUTDOWN_CTRL_PIN GPIO_NUM_13 // 关机控制引脚
/* 原生触摸引脚配置 (v1.1.17已改为上述功能,保留定义需谨慎) */
// 触摸按键数量配置
#define TOUCH_BUTTON_NUM 3
// 触摸通道定义 - 注意:v1.1.17如果不使用ESP32原生触摸,这些定义可能不再适用
// 但为了兼容编译,可以保留或注释
#define TOUCH_PAD_CHANNEL_1 TOUCH_PAD_NUM11 // GPIO11 (Now AW_IRQ)
#define TOUCH_PAD_CHANNEL_2 TOUCH_PAD_NUM12 // GPIO12 (Now NFC_RST)
#define TOUCH_PAD_CHANNEL_3 TOUCH_PAD_NUM13 // GPIO13 (Now SHUTDOWN)
/* ES8311音频编解码器配置 (ESP-ADF兼容) */
#define AUDIO_INPUT_SAMPLE_RATE 24000
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
#define AUDIO_INPUT_REFERENCE true
/* I2S GPIO定义 */
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_15
#define AUDIO_I2S_GPIO_WS GPIO_NUM_4
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_5
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_6
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_7
/* PA引脚定义 */
#define AUDIO_CODEC_PA_PIN GPIO_NUM_NC
/* I2C配置 */
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_2
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_3
#define AUDIO_CODEC_ES8311_ADDR 0x18
#define AUDIO_CODEC_ES7210_ADDR 0x40
/* WS2812 RGB LED配置 */
#define WS2812_PIN GPIO_NUM_41 // WS2812数据引脚
#define WS2812_NUM_LEDS 2 // WS2812 LED数量
/* 创建VBAT to VBAT_5V */
#define VBAT_5V_PIN GPIO_NUM_NC // VBAT_5V引脚
/* 定义按键的中断引脚 */
#define BUTTON_PIN GPIO_NUM_0 // 按键中断引脚
#define RIGHT_BUTTON_PIN GPIO_NUM_8 // 按键中断引脚
/* 底座控制命令串口配置 */
#define BASE_BOARD_CTL_UART_PORT UART_NUM_0
#define BASE_BOARD_CTL_UART_TX_PIN GPIO_NUM_43
#define BASE_BOARD_CTL_UART_RX_PIN GPIO_NUM_44
#define BASE_BOARD_CTL_UART_BAUDRATE 115200
#define BASE_BOARD_CTL_UART_BUF_SIZE 256
/* 背光控制引脚配置 */
#define BL_PIN GPIO_NUM_45
#endif // _BOARD_CONFIG_H_
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,432 @@
#ifndef IO_EXPANSION_BOARD_H
#define IO_EXPANSION_BOARD_H
#include <cstdint>
#include <esp_log.h>
#include <esp_check.h>
#include <esp_timer.h>
#include <driver/gpio.h>
#include <functional>
#include "i2c_bus.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <freertos/semphr.h>
#include "esp_err.h"
#include "config.h"
#include "portmacro.h"
// 前向声明,避免循环引用
class MillimeterWaveRadar;
class PhotoInterrupter;
class AdcBatteryMonitor;
// 回调函数类型定义
typedef std::function<void()> RadarCallback;
typedef std::function<void()> PhotoInterrupterStartCallback;
typedef std::function<void()> PhotoInterrupterEndCallback;
typedef std::function<void()> BatteryChargingCallback;
typedef std::function<void()> BatteryFullCallback;
typedef std::function<void()> BatteryNotChargingCallback;
/* 寄存器地址 */
#define INPUT_PORT0 0x00 // 输入端口0寄存器
#define INPUT_PORT1 0x01 // 输入端口1寄存器 0为低电平(仅支持读取)
#define OUTPUT_PORT0 0x02 // 输出端口0寄存器
#define OUTPUT_PORT1 0x03 // 输出端口1寄存器 0为低电平
#define CONFIG_PORT0 0x04 // 配置端口0寄存器
#define CONFIG_PORT1 0x05 // 配置端口1寄存器 0为输出模式
#define INT_PORT0 0x06 // 中断端口0寄存器
#define INT_PORT1 0x07 // 中断端口1寄存器 0为使能中断(根据手册默认是使能的)
#define CTL 0x11 // 全局控制寄存器
#define ID 0x23 // 芯片ID寄存器(0x23)
/***********************************IO扩展板电机引脚配置参数*************************************/
/* 设置步进电机方向 */
#define STEPPER_MOTOR_LEFT false //步进电机的方向为左转
#define STEPPER_MOTOR_RIGHT true //步进电机的方向为右转
#define STEPPER_MOTOR_DIR_PORT OUTPUT_PORT0 //步进电机方向引脚挂载在IO扩展板的输出端口OUTPUT_PORT0
#define STEPPER_MOTOR_DIR_PIN 4 //步进电机方向引脚对应的IO扩展板引脚P0_4
#define STEPPER_MOTOR_DIR_CONFIG CONFIG_PORT0 //步进电机方向引脚配置在P0_4
/* 设置步进电机细分模式 */
#define STEPPER_MOTOR_M0_PIN 5 //步进电机细分模式选择引脚对应IO扩展板引脚P1_5
#define STEPPER_MOTOR_M0_MADE_PORT OUTPUT_PORT1 //步进电机模式选择引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
#define STEPPER_MOTOR_M0_CONFIG CONFIG_PORT1 //步进电机细分模式选择引脚配置在P1_5
#define STEPPER_MOTOR_M1_PIN 4 //步进电机细分模式选择引脚对应IO扩展板引脚P1_4
#define STEPPER_MOTOR_M1_MADE_PORT OUTPUT_PORT1 //步进电机模式选择引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
#define STEPPER_MOTOR_M1_CONFIG CONFIG_PORT1 //步进电机细分模式选择引脚配置在P1_4
/* 设置步进电机睡眠引脚 */
#define STEPPER_MOTOR_SLEEP false //步进电机进入睡眠模式
#define STEPPER_MOTOR_WORK true //步进电机进入工作模式
#define STEPPER_MOTOR_SLEEP_PIN 6 //步进电机睡眠引脚对应IO扩展板引脚P1_6
#define STEPPER_MOTOR_SLEEP_CONFIG CONFIG_PORT1 //步进电机睡眠引脚配置在P1_6
#define STEPPER_MOTOR_SLEEP_PORT OUTPUT_PORT1 //步进电机睡眠引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
/* 设置电机的使能引脚 */
#define STEPPER_MOTOR_ENABLE_PIN 7 //电机使能引脚对应IO扩展板引脚P0_7
#define STEPPER_MOTOR_ENABLE_PORT OUTPUT_PORT0 //电机使能引脚挂载在IO扩展板的输出端口OUTPUT_PORT0
#define STEPPER_MOTOR_ENABLE_CONFIG CONFIG_PORT0 //电机使能引脚配置在P0_7
#define STEPPER_MOTOR_ENABLE_ENABLE true //电机使能引脚状态为高电平
#define STEPPER_MOTOR_ENABLE_DISABLE false //电机使能引脚状态为低电平
/* 设置毫米波雷达对应IO扩展板的中断引脚 */
#define RADAR_INTERRUPT_PIN 7 //毫米波雷达中断引脚对应IO扩展板引脚P1_7
#define RADAR_INTERRUPT_CONFIG CONFIG_PORT1 //毫米波雷达中断引脚挂载在IO扩展板的输入端口
#define RADAR_INTERRUPT_INPUT INPUT_PORT1 //毫米波雷达中断引脚输入状态检测在INPUT_PORT1
#define RADAR_INTERRUPT_ENABLE true //毫米波雷达中断引脚状态为输入状态
#define RADAR_INTERRUPT_DISABLE false //毫米波雷达中断引脚状态为输出状态
/* 任务配置常量 */
#define WRITE_BUF_SIZE 2 // I2C单次写入字节数
#define READ_BUF_SIZE 2 // I2C单次读取字节数
#define I2C_TASK_PRIORITY 2 // 任务优先级(中等)
#define I2C_TASK_STACK 4096 // 任务栈大小(4KB)
// 光学传感器引脚定义
#define START_PHOTO_INTERRUPTER_PIN 2 // 光学传感器引脚(P0_2)
#define START_PHOTO_INTERRUPTER_CONFIG CONFIG_PORT0 // 光学传感器引脚挂载在IO扩展板的输入端口
#define START_PHOTO_INTERRUPTER_INPUT INPUT_PORT0 // 光学传感器引脚输入状态检测在INPUT_PORT0
#define START_PHOTO_INTERRUPTER_HIGH true // 光学传感器引脚状态为高电平
#define START_PHOTO_INTERRUPTER_LOW false // 光学传感器引脚状态为低电平
#define END_PHOTO_INTERRUPTER_PIN 3 // 光学传感器引脚(P0_3)
#define END_PHOTO_INTERRUPTER_PORT_CONFIG CONFIG_PORT0 // 光学传感器引脚挂载在IO扩展板的输入端口
#define END_PHOTO_INTERRUPTER_INPUT INPUT_PORT0 // 光学传感器引脚输入状态检测在INPUT_PORT0
#define END_PHOTO_INTERRUPTER_HIGH true // 光学传感器引脚状态为高电平
#define END_PHOTO_INTERRUPTER_LOW false // 光学传感器引脚状态为低电平
/***********************************IO扩展板LCD引脚配置参数*************************************/
// /* 设置LCD的BL引脚 */
// #define LCD_BL_PIN 6 //LCD背光引脚对应IO扩展板引脚P0_6
// #define LCD_BL_PORT OUTPUT_PORT0 //LCD背光引脚挂载在IO扩展板的输出端口OUTPUT_PORT0
// #define LCD_BL_CONFIG CONFIG_PORT0 //LCD背光引脚配置在P0_6
// #define LCD_BL_HIGH true //LCD背光引脚状态为高电平
// #define LCD_BL_LOW false //LCD背光引脚状态为低电平
/* 设置LED_EN (LCD背光/LED控制)引脚, PMOS高侧驱动 */
#define LED_EN_PIN 1 //LED_EN对应IO扩展板引脚P0_1
#define LED_EN_PORT OUTPUT_PORT0 //挂载在输出端口OUTPUT_PORT0
#define LED_EN_CONFIG CONFIG_PORT0 //配置在P0_1
#define LED_EN_OFF true //高电平关(PMOS)
#define LED_EN_ON false //低电平开(PMOS)
/* 设置LCD的RST引脚 */
#define LCD_RST_PIN 1 //LCD复位引脚对应IO扩展板引脚P1_1
#define LCD_RST_CONFIG CONFIG_PORT1 //LCD复位引脚配置在P1_1
#define LCD_RST_PORT OUTPUT_PORT1 //LCD复位引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
#define LCD_RST_HIGH true //LCD复位引脚状态为高电平
#define LCD_RST_LOW false //LCD复位引脚状态为低电平
/* 设置PA控制引脚 */
#define PA_CTRL_PIN 2 //PA控制引脚对应IO扩展板引脚P1_2
#define PA_CTRL_CONFIG CONFIG_PORT1 //PA控制引脚配置在P1_2
#define PA_CTRL_PORT OUTPUT_PORT1 //PA控制引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
#define PA_CTRL_HIGH true //PA控制引脚状态为高电平
#define PA_CTRL_LOW false //PA控制引脚状态为低电平
// 电池充电检测引脚定义
#define BATTERY_FULL_INPUT INPUT_PORT1 // 电池充满检测引脚挂载在IO扩展板的输入端口
#define BATTERY_FULL_PIN 3 // 电池充满检测引脚对应IO扩展板引脚P1_3
#define BATTERY_FULL_CONFIG CONFIG_PORT1 // 电池充满检测引脚配置在P1_3
#define BATTERY_CHRG_INPUT INPUT_PORT0 // 充电检测引脚挂载在IO扩展板的输入端口
#define BATTERY_CHRG_PIN 5 // 充电检测引脚(P0_5)
#define BATTERY_CHRG_CONFIG CONFIG_PORT0 // 充电检测引脚挂载在IO扩展板的输入端口
#define TAG_GPIO_IO_EXPAND_DETECT "GPIO_IO_EXPAND_DETECT" // GPIO中断检测日志标签
#define TAG_I2C_IO_EXPAND_TASK "I2C_IO_EXPAND_TASK" // I2CIO扩展板任务日志标签
// GPIO引脚定义
#define GPIO_INPUT_PIN_SEL GPIO_NUM_10 // IO扩展板中断检测引脚
// #define IO_EXPAND_RSTN GPIO_NUM_14 // IO扩展板复位引脚
/**
* @class IOExpansionBoard
* @brief I/O扩展板驱动类,封装AW9523BTQR芯片操作
*/
class IOExpansionBoard
{
public:
/**
* @brief 构造函数
*/
IOExpansionBoard();
/**
* @brief 设置毫米波雷达指针
* @param radar 毫米波雷达对象指针
*/
void SetRadar(MillimeterWaveRadar* radar) { radar_ = radar; };
/**
* @brief 设置限位开关指针
* @param photo_interrupter 限位开关对象指针
*/
void setPhotoInterrupter(PhotoInterrupter* photo_interrupter) { photo_interrupter_ = photo_interrupter; };
/**
* @brief 设置电池监控器指针
* @param battery_monitor 电池监控器对象指针
*/
void setBatteryMonitor(AdcBatteryMonitor* battery_monitor) { battery_monitor_ = battery_monitor; };
/**
* @brief 析构函数
*/
~IOExpansionBoard();
/**
* @brief 初始化GPIO中断检测
* @param gpio_num 中断引脚编号
* @return esp_err_t 初始化结果
*/
esp_err_t InterruptGpioInit(gpio_num_t gpio_num);
/**
* @brief 初始化IO扩展板复位引脚
* @param gpio_num 复位引脚编号
* @return esp_err_t 初始化结果
*/
esp_err_t ResetGpioInit(gpio_num_t gpio_num);
/**
* @brief 初始化IO扩展板复位引脚
* @param gpio_num 复位引脚编号
* @return esp_err_t 初始化结果
*/
esp_err_t ResetIoExpand();
/**
* @brief 初始化I2C主机通信
* @return esp_err_t 初始化结果
*/
// esp_err_t IoExpansionI2cInit();
/**
* @brief 创建I2C数据读取任务
*/
void CreateI2cReadTask();
/**
* @brief 启动I2C任务(整合初始化和任务创建)
* @return esp_err_t 操作结果
*/
esp_err_t StartTask();
/**
* @brief 写寄存器数据
* @param reg_addr 寄存器地址
* @param data 要写入的数据
* @return esp_err_t 操作结果
*/
esp_err_t IoexpandWriteReg(uint8_t reg_addr, uint8_t data);
/**
* @brief 读寄存器数据
* @param reg_addr 寄存器地址
* @param data 要读出的数据
* @return esp_err_t 操作结果
*/
esp_err_t IoexpandReadReg(uint8_t reg_addr, uint8_t *data);
/**
* @brief 读取输入端口0寄存器数据
* @param data 输出参数,用于存储读取到的数据
* @return esp_err_t 操作结果
*/
esp_err_t ReadInputPort0(uint8_t *data);
/**
* @brief 读取输入端口1寄存器数据
* @param data 输出参数,用于存储读取到的数据
* @return esp_err_t 操作结果
*/
esp_err_t ReadInputPort1(uint8_t *data);
// /**
// * @brief 设置IO扩展板GPIO中断状态 通过读取Input_Port0 和 Input_Port1 寄存器可以清除中断
// * @param reg_addr 寄存器地址
// * @return esp_err_t 操作结果
// */
// esp_err_t SetInterruptStatus(bool status);
/**
* @brief 配置IO扩展版上的IO口为输出还是输入,并且设置初始为高电平
* @return esp_err_t 操作结果
*/
esp_err_t IoexpandSetMode();
/**
* @brief 设置步进电机的细分模式
* @param mode 模式:1/2/4/8/16/32/64
* @return esp_err_t 操作结果
*/
void SetStepperMicrostepMode(uint8_t mode, uint8_t OUTPUT_PORT_m0, uint8_t m0_pin, uint8_t OUTPUT_PORT_m1, uint8_t m1_pin);
/**
* @brief 设置步进电机的方向
* @param dir 方向
* @param OUTPUT_PORT 输出端口
* @param pin 引脚号
* @return esp_err_t 操作结果
*/
esp_err_t StepperMotorSetDir(bool dir, uint8_t OUTPUT_PORT, uint8_t pin);
/**
* @brief 设置步进电机的睡眠模式
* @param 是否进入睡眠模式
* @param 输出端口
* @param 引脚号
* @return esp_err_t 操作结果
*/
esp_err_t SetMotorSleepMode(bool mode, uint8_t OUTPUT_PORT, uint8_t nsleep_pin);
/**
* @brief 设置步进电机的使能引脚状态
* @param 使能状态
* @return esp_err_t 操作结果
*/
esp_err_t SetMotorEnableMode(bool enable, uint8_t OUTPUT_PORT, uint8_t enable_pin);
/**
* @brief 设置LCD的BL引脚状态
* @param BL状态
* @return esp_err_t 操作结果
*/
esp_err_t SetLcdBlMode(bool mode, uint8_t OUTPUT_PORT, uint8_t bl_pin);
/**
* @brief 设置 LED_EN 引脚电平(用于控制LCD背光/LED灯电源)
* @param mode true:开启(低电平), false:关闭(高电平)
*/
esp_err_t SetLedEnMode(bool mode);
/**
* @brief 设置LCD的RST引脚状态
* @param RST状态
* @return esp_err_t 操作结果
*/
esp_err_t SetLcdResetMode(bool mode, uint8_t OUTPUT_PORT, uint8_t rst_pin);
/**
* @brief 设置PA控制引脚状态
* @param mode PA_CTRL状态(true为高电平,false为低电平)
* @return esp_err_t 操作结果
*/
esp_err_t SetPaCtrlMode(bool mode);
/**
* @brief 设置雷达中断引脚
* @param 毫米波雷达的中断引脚模式
* @param 输入端口
* @param 引脚号
* @return esp_err_t 操作结果
*/
esp_err_t SetRadarInterruptPin(bool mode, uint8_t INPUT_PORT, uint8_t interrupt_pin);
/**
* @brief 计算Port0的字节值
* @return uint8_t 操作结果
*/
uint8_t ByteCalculatePort0();
/**
* @brief 计算Port1的字节值
* @return uint8_t 操作结果
*/
uint8_t ByteCalculatePort1();
/**
* @brief 设置雷达中断回调函数
* @param callback 雷达中断回调函数
*/
void SetRadarCallback(RadarCallback callback) { radar_callback_ = callback; }
/**
* @brief 设置光学传感器开始中断回调函数
* @param callback 光学传感器开始中断回调函数
*/
void SetPhotoInterrupterStartCallback(PhotoInterrupterStartCallback callback) { photo_start_callback_ = callback; }
/**
* @brief 设置光学传感器结束中断回调函数
* @param callback 光学传感器结束中断回调函数
*/
void SetPhotoInterrupterEndCallback(PhotoInterrupterEndCallback callback) { photo_end_callback_ = callback; }
/**
* @brief 设置电池充电中断回调函数
* @param callback 电池充电中断回调函数
*/
void SetBatteryChargingCallback(BatteryChargingCallback callback) { battery_charging_callback_ = callback; }
/**
* @brief 设置电池充满中断回调函数
* @param callback 电池充满中断回调函数
*/
void SetBatteryFullCallback(BatteryFullCallback callback) { battery_full_callback_ = callback; }
/**
* @brief 设置电池非充电中断回调函数
* @param callback 电池非充电中断回调函数
*/
void SetBatteryNotChargingCallback(BatteryNotChargingCallback callback) { battery_not_charging_callback_ = callback; }
// 公共成员变量
i2c_bus_handle_t bus_handle_ = nullptr; // I2C总线句柄
uint8_t device_addr_; // I2C设备地址
private:
// 静态成员函数
MillimeterWaveRadar* radar_ = nullptr; // 毫米波雷达指针,用于触发回调
PhotoInterrupter* photo_interrupter_ = nullptr; // 限位开关指针,用于触发回调
AdcBatteryMonitor* battery_monitor_ = nullptr; // 电池监控器指针,用于触发回调
static void IRAM_ATTR GpioIsrHandler(void* arg); // 中断处理函数
static void I2cReadTask(void* pvParameters); // I2C数据读取任务函数
// 成员变量用于状态跟踪
uint8_t last_port0_state_ = 0; // 上次检测到的Port0状态
uint8_t last_port1_state_ = 0; // 上次检测到的Port1状态
bool radar_last_state_ = false; // 雷达引脚上一次的状态
bool battery_charging_last_state_ = false; // 电池充电状态上一次的状态
bool battery_full_last_state_ = false; // 电池充满状态上一次的状态
// 回调函数成员变量
RadarCallback radar_callback_ = nullptr;
PhotoInterrupterStartCallback photo_start_callback_ = nullptr;
PhotoInterrupterEndCallback photo_end_callback_ = nullptr;
BatteryChargingCallback battery_charging_callback_ = nullptr;
BatteryFullCallback battery_full_callback_ = nullptr;
BatteryNotChargingCallback battery_not_charging_callback_ = nullptr;
// PhotoInterrupter* photo_interrupter_ = nullptr; // 光学传感器指针,用于触发回调
// /**
// * @brief 分配静态任务所需的内存
// * @return bool 分配是否成功
// */
// bool AllocateStaticTaskMemory();
// /**
// * @brief 释放静态任务分配的内存
// */
// void FreeStaticTaskMemory();
// 实例成员变量
EventGroupHandle_t i2c_task_event_group_ = nullptr; // 事件组
TaskHandle_t xI2CReadTaskHandle_ = nullptr; // 任务句柄
bool is_initialized_ = false; // 初始化状态标记(新增)
gpio_num_t interrupt_gpio_ = GPIO_NUM_NC; // 中断引脚
gpio_num_t reset_gpio_ = GPIO_NUM_NC; // 复位引脚
// StackType_t* pI2CReadTaskStackBuffer = nullptr; // 任务栈指针(PSRAM)
// StaticTask_t* pxI2CReadTaskBuffer = nullptr; // 任务控制块指针(内部RAM)
};
#endif
@@ -0,0 +1,178 @@
/**
* @file power_management_config.h
* @brief 功耗管理配置和策略定义
* @author Embedded Software Expert
* @date 2025年1月
*
* 这个文件定义了功耗管理的配置参数、策略和优化建议,
* 为系统提供灵活的功耗管理方案。
*/
#ifndef POWER_MANAGEMENT_CONFIG_H
#define POWER_MANAGEMENT_CONFIG_H
#include "esp_sleep.h"
#include "driver/rtc_io.h"
#include "esp32/rom/rtc.h"
/**
* @brief 功耗管理配置结构体
*/
typedef struct {
// 睡眠模式配置
uint64_t light_sleep_duration_us; // 轻度睡眠持续时间(微秒)
uint64_t deep_sleep_duration_us; // 深度睡眠持续时间(微秒)
// 唤醒源配置
bool enable_timer_wakeup; // 启用定时器唤醒
bool enable_gpio_wakeup; // 启用GPIO唤醒
bool enable_touch_wakeup; // 启用触摸唤醒
gpio_num_t wakeup_gpio_num; // 唤醒GPIO编号
int wakeup_level; // 唤醒电平(0或1)
// 功耗优化配置
bool disable_bt_in_sleep; // 睡眠时关闭蓝牙
bool disable_wifi_in_sleep; // 睡眠时关闭WiFi
bool reduce_cpu_frequency; // 降低CPU频率
uint32_t cpu_frequency_hz; // CPU频率(Hz)
// 外设功耗配置
bool power_down_sdcard; // 睡眠时关闭SD卡电源
bool power_down_display; // 睡眠时关闭显示电源
bool power_down_audio; // 睡眠时关闭音频电源
bool power_down_motor; // 睡眠时关闭电机电源
// RTC内存配置
bool preserve_rtc_memory; // 保留RTC内存
size_t rtc_memory_size; // RTC内存大小
} power_management_config_t;
/**
* @brief 默认功耗管理配置
*/
#define DEFAULT_POWER_CONFIG { \
.light_sleep_duration_us = 1000000, /* 1秒 */ \
.deep_sleep_duration_us = 30000000, /* 30秒 */ \
.enable_timer_wakeup = true, /* 启用定时器唤醒 */ \
.enable_gpio_wakeup = false, /* 不启用GPIO唤醒 */ \
.enable_touch_wakeup = false, /* 不启用触摸唤醒 */ \
.wakeup_gpio_num = GPIO_NUM_NC, /* 无GPIO唤醒 */ \
.wakeup_level = 0, /* 低电平唤醒 */ \
.disable_bt_in_sleep = true, /* 睡眠时关闭蓝牙 */ \
.disable_wifi_in_sleep = true, /* 睡眠时关闭WiFi */ \
.reduce_cpu_frequency = true, /* 降低CPU频率 */ \
.cpu_frequency_hz = 80000000, /* 80MHz */ \
.power_down_sdcard = true, /* 睡眠时关闭SD卡 */ \
.power_down_display = true, /* 睡眠时关闭显示 */ \
.power_down_audio = true, /* 睡眠时关闭音频 */ \
.power_down_motor = true, /* 睡眠时关闭电机 */ \
.preserve_rtc_memory = true, /* 保留RTC内存 */ \
.rtc_memory_size = 4096, /* 4KB RTC内存 */ \
}
/**
* @brief 各功耗模式的详细配置
*/
static const power_management_config_t idle_mode_config = {
.light_sleep_duration_us = 500000, // 500ms轻度睡眠
.deep_sleep_duration_us = 0, // 不使用深度睡眠
.enable_timer_wakeup = true,
.enable_gpio_wakeup = true,
.wakeup_gpio_num = GPIO_NUM_0, // 按键唤醒
.wakeup_level = 0,
.disable_bt_in_sleep = false, // 保持蓝牙连接
.disable_wifi_in_sleep = false, // 保持WiFi连接
.reduce_cpu_frequency = true,
.cpu_frequency_hz = 40000000, // 40MHz
.power_down_sdcard = false, // 保持SD卡(可能有后台任务)
.power_down_display = true, // 关闭显示背光
.power_down_audio = true, // 关闭音频
.power_down_motor = true, // 关闭电机
.preserve_rtc_memory = true,
.rtc_memory_size = 2048,
};
static const power_management_config_t light_sleep_config = {
.light_sleep_duration_us = 0, // 直接进入轻度睡眠
.deep_sleep_duration_us = 0,
.enable_timer_wakeup = true,
.enable_gpio_wakeup = true,
.wakeup_gpio_num = GPIO_NUM_0,
.wakeup_level = 0,
.disable_bt_in_sleep = true, // 关闭蓝牙
.disable_wifi_in_sleep = true, // 关闭WiFi
.reduce_cpu_frequency = true,
.cpu_frequency_hz = 40000000,
.power_down_sdcard = true, // 关闭SD卡
.power_down_display = true, // 关闭显示
.power_down_audio = true, // 关闭音频
.power_down_motor = true, // 关闭电机
.preserve_rtc_memory = true,
.rtc_memory_size = 4096,
};
static const power_management_config_t deep_sleep_config = {
.light_sleep_duration_us = 0,
.deep_sleep_duration_us = 60000000, // 60秒深度睡眠
.enable_timer_wakeup = true,
.enable_gpio_wakeup = true,
.wakeup_gpio_num = GPIO_NUM_0,
.wakeup_level = 0,
.disable_bt_in_sleep = true, // 关闭蓝牙
.disable_wifi_in_sleep = true, // 关闭WiFi
.reduce_cpu_frequency = true,
.cpu_frequency_hz = 10000000, // 10MHz
.power_down_sdcard = true, // 关闭SD卡
.power_down_display = true, // 关闭显示
.power_down_audio = true, // 关闭音频
.power_down_motor = true, // 关闭电机
.preserve_rtc_memory = true,
.rtc_memory_size = 8192,
};
/**
* @brief 功耗统计和监控结构体
*/
typedef struct {
uint64_t total_sleep_time_us; // 总睡眠时间
uint64_t total_wake_time_us; // 总唤醒时间
uint32_t sleep_count; // 睡眠次数
uint32_t wake_count; // 唤醒次数
uint32_t average_sleep_duration_us; // 平均睡眠时长
uint32_t average_wake_duration_us; // 平均唤醒时长
float estimated_power_saving_percent; // 估计的功耗节省百分比
} power_statistics_t;
/**
* @brief 功耗优化建议
*
* 基于硬件特性和使用模式,提供功耗优化建议
*/
typedef enum {
OPTIMIZATION_NONE = 0,
OPTIMIZATION_REDUCE_CPU_FREQ, // 降低CPU频率
OPTIMIZATION_DISABLE_UNUSED_PERIPHERALS, // 关闭未使用的外设
OPTIMIZATION_USE_LIGHT_SLEEP, // 使用轻度睡眠
OPTIMIZATION_USE_DEEP_SLEEP, // 使用深度睡眠
OPTIMIZATION_OPTIMIZE_GPIO_STATES, // 优化GPIO状态
OPTIMIZATION_USE_RTC_MEMORY, // 使用RTC内存
OPTIMIZATION_BATCH_OPERATIONS, // 批量操作
} power_optimization_t;
/**
* @brief 功耗管理事件回调
*/
typedef void (*power_event_callback_t)(power_mode_t old_mode, power_mode_t new_mode, void* user_data);
/**
* @brief 功耗管理事件
*/
typedef enum {
POWER_EVENT_MODE_CHANGE, // 功耗模式改变
POWER_EVENT_SLEEP_START, // 睡眠开始
POWER_EVENT_SLEEP_END, // 睡眠结束
POWER_EVENT_WAKEUP, // 系统唤醒
POWER_EVENT_OPTIMIZATION_TRIGGER, // 功耗优化触发
} power_event_t;
#endif // POWER_MANAGEMENT_CONFIG_H