/* * kt_led7.c — 硬件扫描与段码 * * 与 kt_led7.h 中 L7~L14 的对应关系: * L7 → 本文件 kt_led7_scan() 六相状态机(case 0~5) * L8 → LED_NUMBER / LED_LARGE_LETTER / LED_SMALL_LETTER * L9~L12 → 由 kt_led7_show_* 填充缓冲后体现(当前为 stub,需与 kt_fan_ac 档位同步) * L13 → show_time / urgent / 闪烁(待与 disp_buf、策略层补全) * L14 → USB/电量/灯光等由上层调用 show 接口让路或关显 * * 说明:逻辑段与 PCB 段的映射见 case 内注释(如 L38-L47 段映射)。 */ #include "kt_led7.h" #include "system/includes.h" #include "system/timer.h" #include "app_power_manage.h" struct ui_led7_env { u8 init; u8 cnt; struct { u8 seg[3]; u8 dp1; u8 dp2; } disp_buf; }; static struct ui_led7_env _led7_env = {0}; #define __this (&_led7_env) /* 扫描里用 b[] 表示三位逻辑段码;闪烁关显时置位 */ static u8 blink_blank; #define b (__this->disp_buf.seg) #define KT_LED7_BAT_HOLD_SEC_DEFAULT 60u typedef enum { KT_LED7_MODE_OFF = 0, KT_LED7_MODE_BATTERY, KT_LED7_MODE_TEMP, } kt_led7_mode_t; static kt_led7_mode_t led7_ui_mode; static u32 led7_bat_sec_remain; static u32 led7_temp_sec_remain; static u16 led7_ui_1s_timer_id; static u8 led7_ui_1s_timer_armed; static void kt_led7_apply_blank(void); static void kt_led7_apply_battery_percent(void); static void kt_led7_ui_1s_tick(void *priv); static u8 kt_led7_seg_from_char(u8 c); const struct led7_pin6 led7_pin = { .pin = {IO_PORTC_00, IO_PORTC_01, IO_PORTC_02, IO_PORTC_03, IO_PORTC_04, IO_PORTC_05}}; /* 字模与 cpu/br23/ui_driver/LED_1888/LED1888.c 一致;scan 里用 LED_A..G 选段 */ static const u8 LED_NUMBER[10] = { (u8)(LED_A | LED_B | LED_C | LED_D | LED_E | LED_F), /* '0' */ (u8)(LED_B | LED_C), /* '1' */ (u8)(LED_A | LED_B | LED_D | LED_E | LED_G), /* '2' */ (u8)(LED_A | LED_B | LED_C | LED_D | LED_G), /* '3' */ (u8)(LED_B | LED_C | LED_F | LED_G), /* '4' */ (u8)(LED_A | LED_C | LED_D | LED_F | LED_G), /* '5' */ (u8)(LED_A | LED_C | LED_D | LED_E | LED_F | LED_G), /* '6' */ (u8)(LED_A | LED_B | LED_C), /* '7' */ (u8)(LED_A | LED_B | LED_C | LED_D | LED_E | LED_F | LED_G), /* '8' */ (u8)(LED_A | LED_B | LED_C | LED_D | LED_F | LED_G), /* '9' */ }; static const u8 LED_LARGE_LETTER[26] = { 0x77, 0x40, 0x39, 0x3f, 0x79, ///< ABCDE 0x71, 0x40, 0x76, 0x06, 0x40, ///< FGHIJ 0x40, 0x38, 0x40, 0x37, 0x3f, ///< KLMNO 0x73, 0x40, 0x50, 0x6d, 0x78, ///< PQRST 0x3e, 0x3e, 0x40, 0x76, 0x40, ///< UVWXY 0x40 ///< Z }; static const u8 LED_SMALL_LETTER[26] = { 0x77, 0x7c, 0x58, 0x5e, 0x79, ///< abcde 0x71, 0x40, 0x40, 0x40, 0x40, ///< fghij 0x40, 0x38, 0x40, 0x54, 0x5c, ///< klmno 0x73, 0x67, 0x50, 0x40, 0x78, ///< pqrst 0x3e, 0x3e, 0x40, 0x40, 0x40, ///< uvwxy 0x40 ///< z }; #define PIN1_H gpio_direction_output(led7_pin.pin[0], 1) #define PIN1_L gpio_direction_output(led7_pin.pin[0], 0) #define PIN2_H gpio_direction_output(led7_pin.pin[1], 1) #define PIN2_L gpio_direction_output(led7_pin.pin[1], 0) #define PIN3_H gpio_direction_output(led7_pin.pin[2], 1) #define PIN3_L gpio_direction_output(led7_pin.pin[2], 0) #define PIN4_H gpio_direction_output(led7_pin.pin[3], 1) #define PIN4_L gpio_direction_output(led7_pin.pin[3], 0) #define PIN5_H gpio_direction_output(led7_pin.pin[4], 1) #define PIN5_L gpio_direction_output(led7_pin.pin[4], 0) #define PIN6_H gpio_direction_output(led7_pin.pin[5], 1) #define PIN6_L gpio_direction_output(led7_pin.pin[5], 0) /* 与 LED1888_init() 相同:全部脚置为输入高阻,换相前消隐,避免输出全高仍串亮(全显) */ static void kt_led7_led_gpio_input_all(void) { u8 i; for (i = 0; i < 6; i++) { u8 port = led7_pin.pin[i]; if (port != 255) { gpio_set_pull_down(port, 0); gpio_set_pull_up(port, 0); gpio_set_direction(port, 1); /* 1=输入 */ } } } void hw_init(void) { kt_led7_led_gpio_input_all(); } void kt_led7_scan(void *param) { /* LED1888_6p_scan 在 switch 前调用 LED1888_init(),此处等同 */ kt_led7_led_gpio_input_all(); switch (__this->cnt) { case 0: PIN1_H; if (b[2] & LED_A) { PIN6_L; } if (b[2] & LED_G) { PIN5_L; } break; case 1: PIN2_H; if (b[0] & LED_A) { PIN3_L; } if (b[0] & LED_B) { PIN4_L; } if (b[0] & LED_D) { PIN6_L; } if (b[0] & LED_E) { PIN5_L; } if (b[0] & LED_H) //DP { PIN1_L; } break; case 2: PIN3_H; if (b[0] & LED_F) { PIN2_L; } if (b[1] & LED_B) { PIN5_L; } if (b[1] & LED_D) { PIN4_L; } if (b[2] & LED_B) { PIN6_L; } if (b[1] & LED_H) //DP { PIN1_L; } break; case 3: PIN4_H; if (b[0] & LED_G) { PIN2_L; } if (b[1] & LED_C) { PIN5_L; } if (b[1] & LED_F) { PIN3_L; } if (b[2] & LED_E) { PIN6_L; } break; case 4: PIN5_H; if (b[0] & LED_C) { PIN2_L; } if (b[1] & LED_A) { PIN4_L; } if (b[2] & LED_C) { PIN6_L; } if (b[2] & LED_G) { PIN3_L; } break; case 5: PIN6_H; if (b[1] & LED_E) { PIN3_L; } if (b[2] & LED_D) { PIN4_L; } if (b[2] & LED_F) { PIN5_L; } break; default: break; } __this->cnt++; if (__this->cnt == 6) { __this->cnt = 0; } } static void kt_led7_set_digits(u8 d0, u8 d1, u8 d2, u8 dp1, u8 dp2) { b[0] = LED_NUMBER[d0 % 10]; b[1] = LED_NUMBER[d1 % 10]; b[2] = LED_NUMBER[d2 % 10]; __this->disp_buf.dp1 = dp1; __this->disp_buf.dp2 = dp2; blink_blank = 0; } static void kt_led7_apply_blank(void) { b[0] = 0; b[1] = 0; b[2] = 0; __this->disp_buf.dp1 = 0; __this->disp_buf.dp2 = 0; blink_blank = 0; } static void kt_led7_apply_battery_percent(void) { u8 p = get_vbat_percent(); if (p > 100) { p = 100; } kt_led7_set_digits((u8)(p / 100), (u8)((p / 10) % 10), (u8)(p % 10), 0, 0); } static u8 kt_led7_seg_from_char(u8 c) { if (c == '-') { return LED_G; } if (c >= '0' && c <= '9') { return LED_NUMBER[c - '0']; } if (c >= 'A' && c <= 'Z') { return LED_LARGE_LETTER[c - 'A']; } if (c >= 'a' && c <= 'z') { return LED_SMALL_LETTER[c - 'a']; } return 0; } static void kt_led7_ui_1s_tick(void *priv) { (void)priv; if (led7_ui_mode == KT_LED7_MODE_TEMP) { if (led7_temp_sec_remain > 0) { led7_temp_sec_remain--; } if (led7_temp_sec_remain == 0) { led7_ui_mode = KT_LED7_MODE_BATTERY; led7_bat_sec_remain = KT_LED7_BAT_HOLD_SEC_DEFAULT; kt_led7_apply_battery_percent(); } } else if (led7_ui_mode == KT_LED7_MODE_BATTERY) { if (led7_bat_sec_remain > 0) { led7_bat_sec_remain--; kt_led7_apply_battery_percent(); } if (led7_bat_sec_remain == 0) { led7_ui_mode = KT_LED7_MODE_OFF; kt_led7_apply_blank(); } } } void kt_led7_battery_show_restart(void) { led7_ui_mode = KT_LED7_MODE_BATTERY; led7_bat_sec_remain = KT_LED7_BAT_HOLD_SEC_DEFAULT; kt_led7_apply_battery_percent(); } void kt_led7_temp_show_number(u16 number, u32 sec) { u32 s = sec ? sec : 1; u16 n = number % 1000; kt_led7_set_digits((u8)(n / 100), (u8)((n / 10) % 10), (u8)(n % 10), 0, 0); led7_ui_mode = KT_LED7_MODE_TEMP; led7_temp_sec_remain = s; } void kt_led7_temp_show_string(const u8 *str, u32 sec) { u32 s = sec ? sec : 1; u8 c0 = ' ', c1 = ' ', c2 = ' '; if (str) { if (str[0]) { c0 = str[0]; } if (str[1]) { c1 = str[1]; } if (str[2]) { c2 = str[2]; } } b[0] = kt_led7_seg_from_char(c0); b[1] = kt_led7_seg_from_char(c1); b[2] = kt_led7_seg_from_char(c2); __this->disp_buf.dp1 = 0; __this->disp_buf.dp2 = 0; blink_blank = 0; led7_ui_mode = KT_LED7_MODE_TEMP; led7_temp_sec_remain = s; } void kt_led7_show_number(u32 show_time, u8 urgent, u16 number, u8 dp1, u8 dp2) { (void)urgent; u32 sec = show_time ? show_time : 1; u16 n = number % 1000; kt_led7_set_digits((u8)(n / 100), (u8)((n / 10) % 10), (u8)(n % 10), dp1, dp2); led7_ui_mode = KT_LED7_MODE_TEMP; led7_temp_sec_remain = sec; } void kt_led7_show_string(u32 show_time, u8 urgent, const u8 *str, u8 dp1, u8 dp2) { (void)urgent; u32 sec = show_time ? show_time : 1; u8 c0 = ' ', c1 = ' ', c2 = ' '; if (str) { if (str[0]) { c0 = str[0]; } if (str[1]) { c1 = str[1]; } if (str[2]) { c2 = str[2]; } } b[2] = kt_led7_seg_from_char(c0); b[1] = kt_led7_seg_from_char(c1); b[0] = kt_led7_seg_from_char(c2); __this->disp_buf.dp1 = dp1; __this->disp_buf.dp2 = dp2; blink_blank = 0; led7_ui_mode = KT_LED7_MODE_TEMP; led7_temp_sec_remain = sec; } void kt_led7_show_u_volume(u8 vol_level, u32 show_time) { u8 buf[4]; u8 v = vol_level > 99 ? 99 : vol_level; buf[2] = 'U'; buf[1] = (u8)('0' + (v / 10)); buf[0] = (u8)('0' + (v % 10)); buf[3] = 0; kt_led7_show_string(show_time ? show_time : 1, 0, buf, 0, 0); } void kt_led7_init(void) { printf("kt_led7_init\n"); hw_init(); __this->cnt = 0; __this->init = 1; if (!led7_ui_1s_timer_armed) { led7_ui_1s_timer_id = sys_timer_add(NULL, kt_led7_ui_1s_tick, 1000); if (led7_ui_1s_timer_id) { led7_ui_1s_timer_armed = 1; } } /* 欢迎画面 5s,结束后由 kt_led7_ui_1s_tick 切回电量显示 */ kt_led7_temp_show_string((const u8 *)"HI", 5); sys_s_hi_timer_add(NULL, kt_led7_scan, 2); /* 2ms */ }