3030#include "bt_connection_manager.h"
3131#include "bt_env.h"
3232#include "ulog.h"
33-
33+ #include "drv_gpio.h"
3434/* Common functions for RT-Thread based platform
3535 * -----------------------------------------------*/
3636/**
5858#define MAX_RECONNECT_ATTEMPTS 30 // 30次尝试,每次1秒,共30秒
5959#define XIAOZHI_UI_THREAD_STACK_SIZE (6144)
6060#define BATTERY_THREAD_STACK_SIZE (2048)
61+ #define LOW_BATTERY_THRESHOLD 5
6162
6263extern rt_tick_t last_listen_tick ;
6364extern xiaozhi_ws_t g_xz_ws ;
@@ -66,7 +67,7 @@ extern lv_obj_t *standby_screen;
6667extern lv_timer_t * ui_sleep_timer ;
6768extern lv_obj_t * shutdown_screen ;
6869extern lv_obj_t * sleep_screen ;
69-
70+ extern rt_mailbox_t g_ui_task_mb ;
7071
7172bt_app_t g_bt_app_env ;
7273rt_mailbox_t g_bt_app_mb ;
@@ -75,6 +76,8 @@ BOOL first_pan_connected = FALSE;
7576int first_reconnect_attempts = 0 ;
7677uint8_t Initiate_disconnection_flag = 0 ;//蓝牙主动断开标志
7778rt_mailbox_t g_battery_mb ;
79+ bool g_skip_startup = true;
80+ bool low_battery_shutdown_triggered = true;
7881
7982static rt_timer_t s_reconnect_timer = NULL ;
8083static rt_timer_t s_sleep_timer = NULL ;
@@ -83,6 +86,8 @@ static uint8_t g_sleep_enter_flag = 0; // 进入睡眠标志位
8386// UI线程和battery线程控制块
8487static struct rt_thread xiaozhi_ui_thread ;
8588static struct rt_thread battery_thread ;
89+
90+
8691//ui线程
8792#if defined(__CC_ARM ) || defined(__CLANG_ARM )
8893L2_RET_BSS_SECT_BEGIN (xiaozhi_ui_thread_stack ) //6000地址
@@ -182,14 +187,15 @@ void HAL_MspInit(void)
182187 BSP_IO_Init ();
183188 set_pinmux ();
184189}
190+
185191static void battery_level_task (void * parameter )
186192{
187- g_battery_mb = rt_mb_create ("battery_level" , 1 , RT_IPC_FLAG_FIFO );
188193 if (g_battery_mb == NULL )
189194 {
190195 rt_kprintf ("Failed to create mailbox g_battery_mb\n" );
191196 return ;
192197 }
198+ rt_uint8_t current_status ;
193199 while (1 )
194200 {
195201 rt_device_t battery_device = rt_device_find ("bat1" );
@@ -224,7 +230,29 @@ static void battery_level_task(void *parameter)
224230 }
225231
226232 rt_mb_send (g_battery_mb , battery_percentage );
227- rt_thread_mdelay (10000 );
233+ current_status = rt_pin_read (CHARGE_DETECT_PIN );
234+ rt_kprintf ("battery_percentage: %d, current_status: %d \n" , battery_percentage , current_status );
235+ //当电量低于阈值并且当前没有处于充电中并的时候
236+ if (battery_percentage < LOW_BATTERY_THRESHOLD && low_battery_shutdown_triggered && !current_status )
237+ {
238+ lv_obj_t * now_screen = lv_screen_active ();
239+ rt_kprintf ("now_screen address: %p, sleep_screen address: %p, standby_screen address: %p\n" ,
240+ now_screen , sleep_screen , standby_screen );
241+ low_battery_shutdown_triggered = false;
242+ rt_kprintf ("Low battery ,shutdown\n" );
243+ // 发送消息到UI线程显示低电量关机页面
244+ if (g_ui_task_mb != RT_NULL )
245+ {
246+ if (now_screen == sleep_screen && now_screen != NULL )
247+ {
248+ gui_pm_fsm (GUI_PM_ACTION_WAKEUP ); // 唤醒设备
249+ }
250+
251+ rt_thread_mdelay (100 );
252+ rt_mb_send (g_ui_task_mb , UI_EVENT_LOW_BATTERY_SHUTDOWN );
253+ }
254+ }
255+ rt_thread_mdelay (5000 );
228256 }
229257}
230258
@@ -490,6 +518,7 @@ static int bt_app_interface_event_handle(uint16_t type, uint16_t event_id,
490518 }
491519 rt_mb_send (g_bt_app_mb , BT_APP_CONNECT_PAN_SUCCESS );
492520 g_pan_connected = TRUE; // 更新PAN连接状态
521+
493522 }
494523 break ;
495524 case BT_NOTIFY_PAN_PROFILE_DISCONNECTED :
@@ -585,6 +614,64 @@ static int32_t Write_MAC(int argc, char **argv)
585614}
586615MSH_CMD_EXPORT (Write_MAC , write mac );
587616
617+ void check_low_power (void )
618+ {
619+ rt_device_t battery_device = rt_device_find ("bat1" );
620+ if (battery_device ) {
621+ rt_adc_cmd_read_arg_t read_arg ;
622+ read_arg .channel = 7 ;
623+ rt_adc_enable ((rt_adc_device_t )battery_device , read_arg .channel );
624+ rt_uint32_t battery_level = rt_adc_read ((rt_adc_device_t )battery_device , read_arg .channel );
625+ rt_adc_disable ((rt_adc_device_t )battery_device , read_arg .channel );
626+
627+ uint32_t battery_percentage = 0 ;
628+ if (battery_level < 36000 ) {
629+ battery_percentage = 0 ;
630+ } else if (battery_level > 42000 ) {
631+ battery_percentage = 100 ;
632+ } else {
633+ battery_percentage = ((battery_level - 36000 ) * 100 ) / (42000 - 36000 );
634+ }
635+
636+ // 检查充电状态
637+ rt_pin_mode (44 , PIN_MODE_INPUT );
638+ uint8_t charge_status = rt_pin_read (44 );
639+
640+ rt_kprintf ("Boot battery check: %d%%, charging: %d\n" , battery_percentage , charge_status );
641+
642+ // 如果低电量且未充电,进入低电量关机流程
643+ if (battery_percentage < LOW_BATTERY_THRESHOLD && !charge_status )
644+ {
645+ g_skip_startup = false;
646+ rt_kprintf ("电量不足,进入低电量关机流程,当前电量为%d%%\n" , battery_percentage );
647+ xz_set_lcd_brightness (LCD_BRIGHTNESS_DEFAULT );
648+ rt_err_t result = rt_thread_init (& xiaozhi_ui_thread ,
649+ "xz_ui" ,
650+ xiaozhi_ui_task ,
651+ NULL ,
652+ & xiaozhi_ui_thread_stack [0 ],
653+ XIAOZHI_UI_THREAD_STACK_SIZE ,
654+ 30 ,
655+ 10 );
656+ if (result == RT_EOK ) {
657+ rt_thread_startup (& xiaozhi_ui_thread );
658+ }
659+
660+ g_ui_task_mb = rt_mb_create ("ui_mb" , 8 , RT_IPC_FLAG_FIFO );
661+ rt_thread_mdelay (2000 );
662+ if (g_ui_task_mb != RT_NULL ) {
663+ rt_mb_send (g_ui_task_mb , UI_EVENT_LOW_BATTERY_WARNING );
664+ }
665+
666+ while (1 ) {
667+ rt_thread_mdelay (1000 );
668+
669+ }
670+ }
671+ rt_kprintf ("电量充足,正常开机\n" );
672+ }
673+ }
674+
588675int main (void )
589676{
590677 check_poweron_reason ();
@@ -595,6 +682,10 @@ int main(void)
595682 rt_kprintf ("Failed to create mailbox g_button_event_mb\n" );
596683 return 0 ;
597684 }
685+ //初始化电池邮箱
686+ g_battery_mb = rt_mb_create ("battery_level" , 1 , RT_IPC_FLAG_FIFO );
687+ check_low_power ();
688+
598689 rt_kprintf ("Xiaozhi start!!!\n" );
599690 audio_server_set_private_volume (AUDIO_TYPE_LOCAL_MUSIC , VOL_DEFAULE_LEVEL ); // 设置音量
600691 xz_set_lcd_brightness (LCD_BRIGHTNESS_DEFAULT );
@@ -624,8 +715,8 @@ int main(void)
624715 {
625716 rt_kprintf ("Failed to init xiaozhi UI thread\n" );
626717 }
627-
628718 // Connect BT PAN
719+
629720 g_bt_app_mb = rt_mb_create ("bt_app" , 8 , RT_IPC_FLAG_FIFO );
630721#ifdef BSP_BT_CONNECTION_MANAGER
631722 bt_cm_set_profile_target (BT_CM_HID , BT_LINK_PHONE , 1 );
@@ -652,7 +743,6 @@ int main(void)
652743 {
653744 rt_kprintf ("Failed to init battery thread\n" );
654745 }
655-
656746#ifdef BSP_USING_BOARD_SF32LB52_XTY_AI
657747 if (pulse_encoder_init () != RT_EOK )
658748 {
@@ -721,6 +811,7 @@ int main(void)
721811 xiaozhi_time_weather ();
722812 //xiaozhi_ui_chat_output("连接小智中...");
723813 xiaozhi_ui_standby_chat_output ("请按键连接小智..." );
814+ lv_display_trigger_activity (NULL );
724815
725816#ifdef XIAOZHI_USING_MQTT
726817 xiaozhi (0 ,NULL );
0 commit comments