增加LED状态显示功能:

1、设备上电红灯红灯常亮
2、设备连接上COM口红灯闪烁
3、设备连接上BLE绿灯常亮
4、设备进入OTA绿灯闪烁
This commit is contained in:
2026-08-03 14:53:46 +08:00
parent 65af06eed9
commit 59361cd9d5
23 changed files with 6501 additions and 482 deletions
+262
View File
@@ -0,0 +1,262 @@
/******************************************************************************
* @file usr_led_status.c
* @brief 状态指示灯实现
* @author cyWu <1917507415@qq.com>
* @date 2026.08.03
* @version V1.0.0
* @history
* - V1.0.0, 2026.08.03, cyWu, 首次发布
*
* 显示规则:
* 红灯(PA8):上电常亮;COM(DTR)打开时 1Hz 闪烁(优先于常亮)
* 绿灯(PA7)BLE 已连接常亮;OTA 进行中 1Hz 闪烁(优先于常亮);否则熄灭
*
* 依赖:
* - BLEusr_get_conn_service() != 0
* - COMcdc_is_com_open() == 1(与 Dengle 暂停语义一致)
* - OTAusr_get_ota_status() == 0dual_ota_idle=0 表示忙)
******************************************************************************/
#include "system/includes.h"
#include "app_config.h"
#include "asm/gpio.h"
#include "usr_led_status.h"
#if TCFG_USB_SLAVE_CDC_ENABLE
#include "usb/device/cdc.h"
#endif
#define LOG_TAG_CONST APP
#define LOG_TAG "[LED]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
/*============================================================================*/
/* 私有宏 (Private macros) */
/*============================================================================*/
#define USR_LED_GREEN_PIN IO_PORTA_07 /**< 绿灯 */
#define USR_LED_RED_PIN IO_PORTA_08 /**< 红灯 */
/**
* LED 点亮电平:1=高电平点亮,0=低电平点亮
* 若实测灯反了,改此宏即可
*/
#define USR_LED_ON_LEVEL (0)
#define USR_LED_OFF_LEVEL (!(USR_LED_ON_LEVEL))
#define USR_LED_BLINK_HALF_MS (500) /**< 1Hz:亮/灭各 500ms */
#define USR_LED_HALF_TICKS (USR_LED_BLINK_HALF_MS / USR_LED_TICK_MS)
/*============================================================================*/
/* 私有类型 (Private types) */
/*============================================================================*/
typedef enum {
LED_MODE_OFF = 0,
LED_MODE_ON,
LED_MODE_BLINK
} LedMode_t;
/*============================================================================*/
/* 私有变量 (Private variables) */
/*============================================================================*/
static uint8_t s_initialized = 0;
static u16 s_tick_timer = 0;
static uint8_t s_blink_phase = 0; /**< 0=半周期灭侧,1=半周期亮侧 */
static uint8_t s_blink_cnt = 0; /**< 半周期内已走过的 tick 数 */
extern u16 usr_get_conn_service(void);
extern u8 usr_get_ota_status(void);
/*============================================================================*/
/* 私有函数声明 (Private function prototypes) */
/*============================================================================*/
static void usr_led_gpio_init(u32 pin);
static void usr_led_set(u32 pin, uint8_t on);
static uint8_t usr_led_is_com_open(void);
static uint8_t usr_led_is_ble_conn(void);
static uint8_t usr_led_is_ota_busy(void);
static void usr_led_apply(u32 pin, LedMode_t mode);
static void usr_led_tick(void *priv);
/*============================================================================*/
/* 公有函数实现 (Public API implementation) */
/*============================================================================*/
/**
* @brief 初始化状态灯
* @return UsrLed_Ret_t 错误码
*/
UsrLed_Ret_t usr_led_status_init(void)
{
if (s_initialized) {
return USR_LED_OK;
}
usr_led_gpio_init(USR_LED_GREEN_PIN);
usr_led_gpio_init(USR_LED_RED_PIN);
/* 上电:红灯常亮,绿灯熄灭 */
usr_led_set(USR_LED_RED_PIN, 1);
usr_led_set(USR_LED_GREEN_PIN, 0);
s_blink_phase = 1;
s_blink_cnt = 0;
s_initialized = 1;
if (s_tick_timer == 0) {
s_tick_timer = sys_timer_add(NULL, usr_led_tick, USR_LED_TICK_MS);
}
printf("usr_led_status_init ok (red=PA8 green=PA7)\n");
return USR_LED_OK;
}
/**
* @brief 主处理:刷新红/绿灯显示模式
*/
void usr_led_status_run(void)
{
LedMode_t red_mode;
LedMode_t green_mode;
if (!s_initialized) {
return;
}
/* 红灯:COM 打开 → 闪烁;否则上电常亮 */
if (usr_led_is_com_open()) {
red_mode = LED_MODE_BLINK;
} else {
red_mode = LED_MODE_ON;
}
/* 绿灯:OTA 忙 → 闪烁;BLE 已连 → 常亮;否则熄灭 */
if (usr_led_is_ota_busy()) {
green_mode = LED_MODE_BLINK;
} else if (usr_led_is_ble_conn()) {
green_mode = LED_MODE_ON;
} else {
green_mode = LED_MODE_OFF;
}
/* 任一灯在闪时推进公共 1Hz 相位,保证同频同相 */
if (red_mode == LED_MODE_BLINK || green_mode == LED_MODE_BLINK) {
s_blink_cnt++;
if (s_blink_cnt >= USR_LED_HALF_TICKS) {
s_blink_cnt = 0;
s_blink_phase ^= 1;
}
} else {
s_blink_cnt = 0;
s_blink_phase = 1;
}
usr_led_apply(USR_LED_RED_PIN, red_mode);
usr_led_apply(USR_LED_GREEN_PIN, green_mode);
}
/**
* @brief 获取当前初始化状态
* @return UsrLed_Ret_t
*/
UsrLed_Ret_t usr_led_status_get_status(void)
{
if (!s_initialized) {
return USR_LED_ERR_NOT_INIT;
}
return USR_LED_OK;
}
/*============================================================================*/
/* 私有函数实现 (Private functions) */
/*============================================================================*/
/**
* @brief 配置 LED 引脚为推挽输出
* @param pin GPIO 宏(如 IO_PORTA_07
*/
static void usr_led_gpio_init(u32 pin)
{
gpio_set_die(pin, 1);
gpio_set_pull_up(pin, 0);
gpio_set_pull_down(pin, 0);
gpio_direction_output(pin, USR_LED_OFF_LEVEL);
}
/**
* @brief 点亮/熄灭指定 LED
* @param pin GPIO
* @param on 1=亮,0=灭
*/
static void usr_led_set(u32 pin, uint8_t on)
{
gpio_direction_output(pin, on ? USR_LED_ON_LEVEL : USR_LED_OFF_LEVEL);
}
/**
* @brief COM 口是否打开(CDC DTR
* @return 1=已打开,0=未打开/无 CDC
*/
static uint8_t usr_led_is_com_open(void)
{
#if TCFG_USB_SLAVE_CDC_ENABLE
return cdc_is_com_open() ? 1 : 0;
#else
return 0;
#endif
}
/**
* @brief BLE 是否已连接
* @return 1=已连接
*/
static uint8_t usr_led_is_ble_conn(void)
{
return (usr_get_conn_service() != 0) ? 1 : 0;
}
/**
* @brief 是否正在 OTAusr_get_ota_status==0 表示忙)
* @return 1=OTA 进行中
*/
static uint8_t usr_led_is_ota_busy(void)
{
return (usr_get_ota_status() == 0) ? 1 : 0;
}
/**
* @brief 按模式驱动单灯
* @param pin GPIO
* @param mode 灭 / 常亮 / 闪烁
*/
static void usr_led_apply(u32 pin, LedMode_t mode)
{
switch (mode) {
case LED_MODE_ON:
usr_led_set(pin, 1);
break;
case LED_MODE_BLINK:
usr_led_set(pin, s_blink_phase);
break;
case LED_MODE_OFF:
default:
usr_led_set(pin, 0);
break;
}
}
/**
* @brief sys_timer 回调:100ms 刷新一次
* @param priv 未使用
*/
static void usr_led_tick(void *priv)
{
(void)priv;
usr_led_status_run();
}