/****************************************************************************** * @file led_manager.c * @brief CBC2 灯事件:充电红与待机绿走不同通道,可同时亮 * @author cyWu <1917507415@qq.com> * @date 2026.08.25 * @version V1.0.0 * @history * - V1.0.0, 2026.08.25, cyWu, 首次发布,实现红绿独立通道灯事件表 ******************************************************************************/ #include "led_manager.h" #include "system/includes.h" #include "bsp_hw.h" #include "board_pin.h" static uint8_t led_keep_handler(LED_Config_t *led_config); static uint8_t led_standby_handler(LED_Config_t *led_config); static uint8_t led_pairing_handler(LED_Config_t *led_config); static uint8_t led_mode_handler(LED_Config_t *led_config); static uint8_t led_pair_ok_handler(LED_Config_t *led_config); static uint8_t led_pair_fail_handler(LED_Config_t *led_config); static uint8_t led_ota_handler(LED_Config_t *led_config); /** * @brief 只改掩码里的通道,其它灯保持原样 * @param led 通道掩码 * @param state LED_ON / LED_OFF * @return 无 */ static void set_led_multi(uint16_t led, uint8_t state) { if (led & LED_CHANNEL(LED_CH_RED)) { bsp_led_red_set(state); } if (led & LED_CHANNEL(LED_CH_GREEN)) { bsp_led_green_set(state); } } /** * @brief 常亮/闪烁一直跑:返回 0,让其它通道的事件继续执行 * @param led_config 配置 * @return 0 */ static uint8_t led_keep_handler(LED_Config_t *led_config) { (void)LED_Update(led_config); return 0; /* 返回 0:不独占,其它通道的事件还能继续跑 */ } /** * @brief 待机绿灯;BOARD_LED_STANDBY_ON=0 时亮满 runNum 秒后删事件 * @param led_config 配置 * @return 0 */ static uint8_t led_standby_handler(LED_Config_t *led_config) { if (LED_Update(led_config) == 0) { LED_EventDelete(LED_EVENT_STANDBY); /* runNum 到点(限时待机绿)后删事件 */ } return 0; } /** * @brief 配对绿快闪(无限) * @param led_config 配置 * @return 0 */ static uint8_t led_pairing_handler(LED_Config_t *led_config) { (void)LED_Update(led_config); return 0; } /** * @brief 切模式闪完两下后删事件 * @param led_config 配置 * @return 0 */ static uint8_t led_mode_handler(LED_Config_t *led_config) { if (LED_Update(led_config) == 0) { LED_EventDelete(LED_EVENT_MODE); /* 闪完两下后删,绿灯还给待机/配对 */ } return 0; } /** * @brief 配对成功常绿若干秒后删事件 * @param led_config 配置 * @return 0 */ static uint8_t led_pair_ok_handler(LED_Config_t *led_config) { if (LED_Update(led_config) == 0) { LED_EventDelete(LED_EVENT_PAIR_OK); } return 0; } /** * @brief 配对失败红绿交替完后删事件 * @param led_config 配置 * @return 0 */ static uint8_t led_pair_fail_handler(LED_Config_t *led_config) { if (LED_Update(led_config) == 0) { LED_EventDelete(LED_EVENT_PAIR_FAIL); return 0; } /* 红绿都占用,拦住充电红,避免交替被冲掉 */ return 1; } /** * @brief OTA 红绿交替(无限):拦住其它灯,升级期间只剩这一种提示 * @param led_config 配置 * @return 1=拦住更低优先级 */ static uint8_t led_ota_handler(LED_Config_t *led_config) { (void)LED_Update(led_config); return 1; } /** * @brief 注册回调并装载 CBC2 事件表(GPIO 已在 bsp_hw_init) * @return 无 */ void user_led_init(void) { static LED_EventTableItem_t led_event_category[LED_EVENT_MAX] = { [LED_EVENT_STANDBY] = { /* 待机绿灯常亮,可与充电红共存 */ .event = LED_EVENT_STANDBY, .priority = PRIORITY_1, .config.ledMask = LED_CHANNEL(LED_CH_GREEN), .config.state = LED_LIGHT, #if BOARD_LED_STANDBY_ON .config.runNum = 0, /* 0=一直亮 */ #else .config.runNum = (uint16_t)((BOARD_LED_POWER_ON_MS + 999u) / 1000u), #endif .ledEventHandler = led_standby_handler, }, [LED_EVENT_LOWBAT] = { /* 低电红闪 */ .event = LED_EVENT_LOWBAT, .priority = PRIORITY_2, .config.ledMask = LED_CHANNEL(LED_CH_RED), .config.state = LED_BLINKING, .config.blinkParams.orDer = 0, .config.blinkParams.onTime = BOARD_LED_LOWBAT_ON_MS, .config.blinkParams.offTime = (BOARD_LED_LOWBAT_PERIOD_MS - BOARD_LED_LOWBAT_ON_MS), .config.runNum = 0, .ledEventHandler = led_keep_handler, }, [LED_EVENT_CHARGE] = { /* 充电红常亮,与待机绿不同通道 */ .event = LED_EVENT_CHARGE, .priority = PRIORITY_2, .config.ledMask = LED_CHANNEL(LED_CH_RED), .config.state = LED_LIGHT, .config.runNum = 0, .ledEventHandler = led_keep_handler, }, [LED_EVENT_CHARGE_FULL] = { /* 充满绿常亮(与充电红同优先级,互斥覆盖) */ .event = LED_EVENT_CHARGE_FULL, .priority = PRIORITY_2, .config.ledMask = LED_CHANNEL(LED_CH_GREEN), .config.state = LED_LIGHT, .config.runNum = 0, .ledEventHandler = led_keep_handler, }, [LED_EVENT_PAIRING] = { /* 配对绿快闪 */ .event = LED_EVENT_PAIRING, .priority = PRIORITY_3, .config.ledMask = LED_CHANNEL(LED_CH_GREEN), .config.state = LED_BLINKING, .config.blinkParams.orDer = 0, .config.blinkParams.onTime = BOARD_LED_FAST_ON_MS, .config.blinkParams.offTime = BOARD_LED_FAST_OFF_MS, .config.runNum = 0, .ledEventHandler = led_pairing_handler, }, [LED_EVENT_MODE] = { /* 切模式绿闪两下 */ .event = LED_EVENT_MODE, .priority = PRIORITY_4, .config.ledMask = LED_CHANNEL(LED_CH_GREEN), .config.state = LED_BLINKING, .config.blinkParams.orDer = 1, .config.blinkParams.onTime = BOARD_LED_MODE_ON_MS, .config.blinkParams.offTime = BOARD_LED_MODE_OFF_MS, .config.runNum = BOARD_LED_MODE_BLINK_N, .ledEventHandler = led_mode_handler, }, [LED_EVENT_PAIR_OK] = { /* 配对成功常绿若干秒 */ .event = LED_EVENT_PAIR_OK, .priority = PRIORITY_3, .config.ledMask = LED_CHANNEL(LED_CH_GREEN), .config.state = LED_LIGHT, .config.runNum = (uint16_t)((BOARD_LED_PAIR_OK_MS + 999u) / 1000u), .ledEventHandler = led_pair_ok_handler, }, [LED_EVENT_PAIR_FAIL] = { /* 配对失败红绿交替 */ .event = LED_EVENT_PAIR_FAIL, .priority = PRIORITY_3, .config.ledMask = (uint16_t)(LED_CHANNEL(LED_CH_RED) | LED_CHANNEL(LED_CH_GREEN)), .config.state = LED_ALTERNATING_BLINK, .config.alternatingBlinkParams.Group[0] = LED_CHANNEL(LED_CH_RED), .config.alternatingBlinkParams.Group[1] = LED_CHANNEL(LED_CH_GREEN), .config.alternatingBlinkParams.Cycle = (uint32_t)(BOARD_LED_ALT_MS * 2u), .config.runNum = (uint16_t)((BOARD_LED_PAIR_FAIL_MS + (BOARD_LED_ALT_MS * 2u) - 1u) / (BOARD_LED_ALT_MS * 2u)), .ledEventHandler = led_pair_fail_handler, }, [LED_EVENT_OTA] = { /* OTA:红绿交替一直闪,直到升级结束或 60s 复位 */ .event = LED_EVENT_OTA, .priority = PRIORITY_4, .config.ledMask = (uint16_t)(LED_CHANNEL(LED_CH_RED) | LED_CHANNEL(LED_CH_GREEN)), .config.state = LED_ALTERNATING_BLINK, .config.alternatingBlinkParams.Group[0] = LED_CHANNEL(LED_CH_RED), .config.alternatingBlinkParams.Group[1] = LED_CHANNEL(LED_CH_GREEN), .config.alternatingBlinkParams.Cycle = (uint32_t)(BOARD_LED_ALT_MS * 2u), .config.runNum = 0, /* 0=无限 */ .ledEventHandler = led_ota_handler, }, }; LED_SetStateInit(set_led_multi); SET_TimeGetInit((TIME_Get_t)timer_get_ms); LED_EventTableInit(led_event_category); bsp_led_all_off(); } /** * @brief 跑一轮 LED 事件 * @return 无 */ void user_led_handle(void) { LED_EventHandle(); }