Files
Wang Beihong ffdb7065e3 功能:集成SU-03T语音模块,完善UI代码文档
- 在CMakeLists.txt中添加SU-03T语音模块依赖。
- 在main.cpp中实现SU-03T接收回调函数,处理接收消息。
- 完善各UI源文件文档,包括动作、屏幕和字体,明确模块作用与数据流向。
- 更新主应用逻辑,初始化并启动SU-03T接收器。
- 修改过程中确保兼容性,保留原有接口。
2026-04-22 01:06:10 +08:00

138 lines
5.0 KiB
C

/*
* 文件: components/relay_ctrl/relay_ctrl.c
* 角色: 四路继电器状态控制
* 说明:
* - 本文件用于实现当前模块的核心功能或接口定义。
* - 修改前请先确认该模块与其它任务/外设之间的数据流关系。
* - 涉及协议与硬件时,优先保持现有接口兼容,避免联调回归。
*/
#include "relay_ctrl.h"
#include <stdint.h>
#include "esp_check.h"
#include "esp_log.h"
static const char *TAG = "relay_ctrl";
typedef struct {
bool inited;
relay_config_t config[RELAY_CTRL_ID_MAX];
bool states[RELAY_CTRL_ID_MAX];
} relay_ctx_t;
static relay_ctx_t s_ctx;
/* 函数: relay_level_from_state
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static inline int relay_level_from_state(int id, bool on)
{
return (on == s_ctx.config[id].active_high) ? 1 : 0;
}
/* 函数: relay_validate_id
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
static esp_err_t relay_validate_id(relay_ctrl_id_t relay_id)
{
ESP_RETURN_ON_FALSE(relay_id >= RELAY_CTRL_ID_1 && relay_id < RELAY_CTRL_ID_MAX,
ESP_ERR_INVALID_ARG, TAG, "invalid relay id");
return ESP_OK;
}
/* 函数: relay_ctrl_init
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t relay_ctrl_init(const relay_config_t config[RELAY_CTRL_ID_MAX])
{
uint64_t pin_bit_mask = 0;
for (int i = 0; i < RELAY_CTRL_ID_MAX; ++i) {
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(config[i].pin),
ESP_ERR_INVALID_ARG, TAG, "relay gpio invalid");
s_ctx.config[i] = config[i];
pin_bit_mask |= (1ULL << config[i].pin);
}
const gpio_config_t io_cfg = {
.pin_bit_mask = pin_bit_mask,
.mode = GPIO_MODE_OUTPUT,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.pull_up_en = GPIO_PULLUP_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
ESP_RETURN_ON_ERROR(gpio_config(&io_cfg), TAG, "relay gpio config failed");
// 根据每个继电器的配置设置初始电平(默认关闭)
for (int i = 0; i < RELAY_CTRL_ID_MAX; ++i) {
s_ctx.states[i] = false;
ESP_RETURN_ON_ERROR(gpio_set_level(s_ctx.config[i].pin, relay_level_from_state(i, false)),
TAG, "relay set init level failed");
}
s_ctx.inited = true;
ESP_LOGI(TAG, "继电器初始化完成(独立电平配置已应用)");
return ESP_OK;
}
/* 函数: relay_ctrl_set
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t relay_ctrl_set(relay_ctrl_id_t relay_id, bool on)
{
ESP_RETURN_ON_FALSE(s_ctx.inited, ESP_ERR_INVALID_STATE, TAG, "relay not initialized");
ESP_RETURN_ON_ERROR(relay_validate_id(relay_id), TAG, "invalid relay id");
ESP_RETURN_ON_ERROR(gpio_set_level(s_ctx.config[relay_id].pin, relay_level_from_state(relay_id, on)),
TAG, "relay set level failed");
s_ctx.states[relay_id] = on;
ESP_LOGI(TAG, "继电器%d -> %s (GPIO%d level=%d)",
relay_id + 1, on ? "ON" : "OFF",
s_ctx.config[relay_id].pin,
relay_level_from_state(relay_id, on));
return ESP_OK;
}
/* 函数: relay_ctrl_toggle
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t relay_ctrl_toggle(relay_ctrl_id_t relay_id)
{
ESP_RETURN_ON_FALSE(s_ctx.inited, ESP_ERR_INVALID_STATE, TAG, "relay not initialized");
ESP_RETURN_ON_ERROR(relay_validate_id(relay_id), TAG, "invalid relay id");
return relay_ctrl_set(relay_id, !s_ctx.states[relay_id]);
}
/* 函数: relay_ctrl_get
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t relay_ctrl_get(relay_ctrl_id_t relay_id, bool *on_out)
{
ESP_RETURN_ON_FALSE(s_ctx.inited, ESP_ERR_INVALID_STATE, TAG, "relay not initialized");
ESP_RETURN_ON_FALSE(on_out != NULL, ESP_ERR_INVALID_ARG, TAG, "on_out is null");
ESP_RETURN_ON_ERROR(relay_validate_id(relay_id), TAG, "invalid relay id");
*on_out = s_ctx.states[relay_id];
return ESP_OK;
}
/* 函数: relay_ctrl_set_all
* 作用: 执行模块内与函数名对应的业务逻辑。
* 重点: 关注输入合法性、返回码与并发安全。
*/
esp_err_t relay_ctrl_set_all(bool relay1_on, bool relay2_on, bool relay3_on, bool relay4_on)
{
ESP_RETURN_ON_ERROR(relay_ctrl_set(RELAY_CTRL_ID_1, relay1_on), TAG, "set relay1 failed");
ESP_RETURN_ON_ERROR(relay_ctrl_set(RELAY_CTRL_ID_2, relay2_on), TAG, "set relay2 failed");
ESP_RETURN_ON_ERROR(relay_ctrl_set(RELAY_CTRL_ID_3, relay3_on), TAG, "set relay3 failed");
ESP_RETURN_ON_ERROR(relay_ctrl_set(RELAY_CTRL_ID_4, relay4_on), TAG, "set relay4 failed");
return ESP_OK;
}