#include "app_self_checking.h" #include "usr_config.h" #include "bsp_time.h" #include "system.h" #include "hal_ble_client.h" #include "hal_ble_host.h" #include "hal_mt.h" #include "nrf_delay.h" #include "app_charge.h" #include "hal_imu.h" #include "nrf_gpio.h" #include "hal_battery.h" #include "hal_ble_uart0.h" #include "hal_led.h" #include "ble_comm.h" #include "tool.h" #include "hal_mode_manage.h" #include "app_flash.h" #include "exception.h" #define TEST_SUCCESS 0 //测试成功 #define TEST_FAIL 1 //测试失败 #define TEST_UNKNOWN 2 //测试未知 #define TEST_ITEMS 4 //非人工测试项数(前脚传感器、后脚传感器、电量、充电电流) #define ENTER_SELF_CHECK 1 //进入自检标志位 #define QUITE_SELF_CHECK 0 //退出自检标志位 #define TEST_RESULT_LED_SUCCESS_GREEN 0 #define TEST_RESULT_LED_ERR_RED (TEST_RESULT_LED_SUCCESS_GREEN+0x01) #define TEST_RESULT_LED_ERR_BLUE (TEST_RESULT_LED_SUCCESS_GREEN+0x02) #define TEST_RESULT_LED_ERR_PURPLE (TEST_RESULT_LED_SUCCESS_GREEN+0x03) #define TEST_RESULT_LED_ERR_YELLOW (TEST_RESULT_LED_SUCCESS_GREEN+0x04) #define TEST_RESULT_LED_ERR_WHITE (TEST_RESULT_LED_SUCCESS_GREEN+0x05) #define APP_SELF_CHECKING_PROCESS_CYCLE 10 //线程周期,单位ms #define APP_SELF_CHECKING_READY_PROCESS_CYCLE 50 //线程周期,单位ms #define DISPLAY_TEST_RESULT_LED_TIME 1000 //用灯显示测试结果的时间,单位ms #define DISPLAY_TEST_RESULT_CONTINUE_TIME 3000 //显示测试结果的总时间,单位ms #define SELF_CHECK_RECIVE_ORDER_TIMES 1 //允许接受到的自检指令最大次数 #define BATTERY_TEST_VALUE 2500 //电池必须大于2.5V,否则算异常 #define BATTERY_CHARGE_CHANGE_VALUE 80 //自检前和自检期间的充电电压变化值,单位mv #define TRIGGER_MONITOR_ACC_Z 1500 //触发数据监测的加速度Z轴 #define ENTER_MONITOR_TIME (10000/StandByPower_Interval) //进入数据监测所需时间(10S) #define MONITOR_DURATION_TIME (60000/FullPower_Interval) //数据监测至少需要维持的时间 static uint8_t self_check_state = QUITE_SELF_CHECK; static uint8_t self_check_result_buff[TEST_ITEMS]; static uint8_t self_check_recive_order_times = 0; //允许接受到的自检指令最大次数 static int16_t before_check_charge_vol = 0; //自检前的充电电压 static uint32_t enter_monitor_times = ENTER_MONITOR_TIME; //进入数据监测所需时间 static uint8_t enter_monitor_flag = 0; //进入数据监测标志位 static uint32_t monitor_duration = MONITOR_DURATION_TIME; //数据监测至少需要维持的时间 /*-----------------以下属于数据监测线程的相关函数----------------------------*/ //监测前脚传感器数据(acc + gry + mag) static void monitor_except_front_acc_gry_mag(int16_t *monitor_acc, int16_t *monitor_gry, int16_t *monitor_mag) { #define MONITOR_FRONT_ACC_SUM 5 #define MONITOR_FRONT_GRY_SUM 5 #define MONITOR_FRONT_MAG_SUM 5 static uint8_t gry_err_sum, acc_err_sum, mag_err_sum; static int16_t last_gry[3], last_acc[3], last_mag[3]; // SEGGER_RTT_printf(0,"front last_gry[0]=%d, last_gry[1]=%d, last_gry[2]=%d\r\n",last_gry[0],last_gry[1],last_gry[2]); // SEGGER_RTT_printf(0,"front last_acc[0]=%d, last_acc[1]=%d, last_acc[2]=%d\r\n",last_acc[0],last_acc[1],last_acc[2]); // SEGGER_RTT_printf(0,"front last_mag[0]=%d, last_mag[1]=%d, last_mag[2]=%d\r\n",last_mag[0],last_mag[1],last_mag[2]); if(monitor_gry != NULL){ if(last_gry[0] == monitor_gry[0] && last_gry[1] == monitor_gry[1] && last_gry[2] == monitor_gry[2]){ gry_err_sum++; SEGGER_RTT_printf(0,"==>front gry_err_sum=%d\r\n",gry_err_sum); if(gry_err_sum >= MONITOR_FRONT_GRY_SUM){ Except_SaveExceptype(EXCEPT_DATA_FRONT_GRY); } }else{ gry_err_sum = 0; } last_gry[0] = monitor_gry[0]; last_gry[1] = monitor_gry[1]; last_gry[2] = monitor_gry[2]; } if(monitor_acc != NULL){ if(last_acc[0] == monitor_acc[0] && last_acc[1] == monitor_acc[1] && last_acc[2] == monitor_acc[2]){ acc_err_sum++; SEGGER_RTT_printf(0,"==>front acc_err_sum=%d\r\n",acc_err_sum); if(acc_err_sum >= MONITOR_FRONT_ACC_SUM){ Except_SaveExceptype(EXCEPT_DATA_FRONT_ACC); } }else{ acc_err_sum = 0; } last_acc[0] = monitor_acc[0]; last_acc[1] = monitor_acc[1]; last_acc[2] = monitor_acc[2]; } if(monitor_mag != NULL){ if(last_mag[0] == monitor_mag[0] && last_mag[1] == monitor_mag[1] && last_mag[2] == monitor_mag[2]){ mag_err_sum++; SEGGER_RTT_printf(0,"==>front mag_err_sum=%d\r\n",mag_err_sum); if(mag_err_sum >= MONITOR_FRONT_MAG_SUM){ Except_SaveExceptype(EXCEPT_DATA_FRONT_MAG); } }else{ mag_err_sum = 0; } last_mag[0] = monitor_mag[0]; last_mag[1] = monitor_mag[1]; last_mag[2] = monitor_mag[2]; acValBuffer.Sine6 = mag_err_sum; } } //监测后脚传感器数据(mag) static void monitor_except_back_mag(int16_t *monitor_mag) { #define MONITOR_BACK_MAG_SUM 5 static uint8_t mag_err_sum; static int16_t last_mag[3]; // SEGGER_RTT_printf(0,"back last_mag[0]=%d, last_mag[1]=%d, last_mag[2]=%d\r\n",last_mag[0],last_mag[1],last_mag[2]); if(monitor_mag != NULL){ if(last_mag[0] == monitor_mag[0] && last_mag[1] == monitor_mag[1] && last_mag[2] == monitor_mag[2]){ mag_err_sum++; SEGGER_RTT_printf(0,"==>back mag_err_sum=%d\r\n",mag_err_sum); if(mag_err_sum >= MONITOR_BACK_MAG_SUM){ Except_SaveExceptype(EXCEPT_DATA_BACK_MAG); } }else{ mag_err_sum = 0; } last_mag[0] = monitor_mag[0]; last_mag[1] = monitor_mag[1]; last_mag[2] = monitor_mag[2]; acValBuffer.Sine3 = mag_err_sum; } } void app_self_checking_monitor_Process(void) { int16_t group_num = 0; int16_t front_acc[3]; int16_t front_gry[3]; int16_t front_mag[3]; int16_t back_mag[3]; static uint32_t tim =0; if(!IMU_IsNoSignal())return; //配置期间不处理 switch(hal_mode_get()) { case HAL_MODE_SELF_CHECK: if(monitor_duration > 0 && enter_monitor_flag)monitor_duration--; case HAL_MODE_GAME: case HAL_MODE_REALSTEP: // 游戏模式 + 实时计步模式 + 自检模式 if(TIME_GetTicks()-tim>=FullPower_Interval){tim = TIME_GetTicks(); group_num = IMU_Get_Front_Data_Num(); for(int i=0;i=StandByPower_Interval){tim = TIME_GetTicks(); group_num = IMU_Get_Front_Data_Num(); for(int i=0;i=LowPower_Interval){tim = TIME_GetTicks(); group_num = IMU_Get_Front_Data_Num(); for(int i=0;i 4000))*check_result = TEST_FAIL; else if(monitor_duration)*check_result = TEST_UNKNOWN; } //测试充电电流是否正常 static void app_checking_charge(uint8_t *check_result) { int16_t cur_vol; cur_vol = ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL); cur_vol = ADC_RESULT_IN_MILLI_VOLTS(cur_vol); SEGGER_RTT_printf(0,"app_checking_charge cur_vol:%d before_check_charge_vol:%d cur_vol-before_check_charge_vol:%d\r\n",cur_vol,before_check_charge_vol,cur_vol-before_check_charge_vol); //当电池电量满了,不充电(经测试,哪怕电量满了,充电电压也有10+mv) //当电池电量没满,充电(经测试,电量没满的充电电压跟电池电压有关,最小充电电压100+mv) if((cur_vol-before_check_charge_vol)=StandByPower_Interval){tim = TIME_GetTicks(); int16_t front_acc[3]; if(IMU_Get_Front_Data_Num() >= 1)IMU_Get_Front_Data(IMU_Get_Front_Data_Num()-1, NULL, front_acc, NULL, NULL); // SEGGER_RTT_printf(0,"front_acc[0]=%d\r,front_acc[1]=%d\r,front_acc[2]=%d\r\n",front_acc[0],front_acc[1],front_acc[2]); if(front_acc[2] >= TRIGGER_MONITOR_ACC_Z){ if(enter_monitor_times == 0){ if(hal_mode_get() != HAL_MODE_SELF_CHECK){ hal_mode_set(HAL_MODE_SELF_CHECK); //维持一段时间,开启自检模式 enter_monitor_flag = 1; } enter_monitor_times = ENTER_MONITOR_TIME; }else{ enter_monitor_times--; } }else{ enter_monitor_times = ENTER_MONITOR_TIME; if(enter_monitor_flag && self_check_state != ENTER_SELF_CHECK){ enter_monitor_flag = 0; if(hal_mode_get() != HAL_MODE_NORMAL)hal_mode_set(HAL_MODE_NORMAL); //关闭自检模式 } } } } void app_self_checking_Process(void) { static uint8_t wait_times = 20 + 1; // 预防IMU初始化失败,重复几次才初始化成功的情况,所以等待时间为初始化失败上限+1 //触发自检配置用于监测数据变化,不需要通过串口发送结果。 app_self_checking_monitor_trigger(); //触发自检配置用于自检流程,需要通过串口发送结果。 if(self_check_state == ENTER_SELF_CHECK){ if(wait_times-- != 0)return; wait_times = 20 + 1; memset(self_check_result_buff,TEST_SUCCESS,TEST_ITEMS); if(app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT){ //如果插上充电,测试充电电流是否正常 app_checking_charge(&self_check_result_buff[3]); } if(hal_mode_get() == HAL_MODE_SELF_CHECK){ //测试前脚IMU和地磁是否正常 app_checking_front_sensor(&self_check_result_buff[0]); }else{ //前脚传感器损坏 self_check_result_buff[0] = TEST_FAIL; } //测试后脚地磁是否正常 app_checking_back_sensor(&self_check_result_buff[1]); //测试电量检测是否正常 app_checking_bat(&self_check_result_buff[2]); //发送非人工检测结果,只有在插上充电时,才配置串口 if(app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT){ app_self_check_send_result(self_check_result_buff, TEST_ITEMS); } //关闭自检模式 hal_mode_set(HAL_MODE_NORMAL); self_check_state = QUITE_SELF_CHECK; // self_check_result_buff[0] = TEST_FAIL; // self_check_result_buff[1] = TEST_FAIL; // self_check_result_buff[2] = TEST_FAIL; // self_check_result_buff[3] = TEST_FAIL; // self_check_result_buff[0] = TEST_SUCCESS; // self_check_result_buff[1] = TEST_SUCCESS; // self_check_result_buff[2] = TEST_SUCCESS; // self_check_result_buff[3] = TEST_SUCCESS; //开启需要人工去测试的线程 Process_Start(0,"app_self_checking_artificial",app_self_checking_artificial); }else if(app_charge_Getstate()==BLE_Client_T_CHARGE_PULLOUT){ //更新可接受的自检指令最大次数 self_check_recive_order_times = SELF_CHECK_RECIVE_ORDER_TIMES; //用于判断充电芯片和电池是否断线 int16_t temp_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL)); before_check_charge_vol = before_check_charge_vol > temp_vol ? temp_vol : before_check_charge_vol; } // //地磁触发自检 // else if((IMU_GetCurrentMode() == STATE_LOW_POWER_MODE) && app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT){ // int16_t mag[3]; // IMU_Get_Index_Front_Low_Power_Data(NULL, mag, NULL, IMU_Get_Front_Update_Data_GroupNum()); // int32_t front_mag_norm; // front_mag_norm = (int32_t)(sqrt((float) (mag[0] * mag[0] + mag[1] * mag[1] + mag[2] * mag[2]))); // if(front_mag_norm>=20000){ // IMU_SetSelfCheckMode(1); //开机,开启自检模式 // self_check_state = ENTER_SELF_CHECK; // } // } // //用于测量充电电压、电池电压、电量百分比 // int16_t bat; // int16_t vol; // if(app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT){ // bat = ADC_GetValue(PIN_ADC_BAT_CHANNEL); // bat = ADC_RESULT_IN_MILLI_VOLTS(bat)*5/3; // SEGGER_RTT_printf(0,"charge!!! %d %d %d\r\n",before_check_charge_vol,bat,GetBatteryPersent()); // }else{ // bat = ADC_GetValue(PIN_ADC_BAT_CHANNEL); // bat = ADC_RESULT_IN_MILLI_VOLTS(bat)*5/3; // SEGGER_RTT_printf(0,"no charge!!! %d %d %d\r\n",before_check_charge_vol,bat,GetBatteryPersent()); // } } void app_self_checking_ready_Process(void) { char advname_buf[100]; int adv_len; if(app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT && self_check_recive_order_times){ slave_get_advname_len(&adv_len); slave_get_advname(advname_buf, adv_len); uint32_t txd,rxd; UART0_GetPinConfig(&txd, &rxd); UART0_Initialize(PIN_TXD_BLE,UART0_INVALID_PIN,UART_HZ); UART0_Tx_Send(0,UART0_T_SELF_CHECK_RDY,(uint8_t*)advname_buf,adv_len); // SEGGER_RTT_printf(0,"advname_buf:%s len:%d\n",advname_buf,adv_len); UART0_Initialize(txd,rxd,UART_HZ); } } void cb_UART0_R_SELF_CHECK_ASK(void* handle) { if(self_check_recive_order_times){ hal_mode_set(HAL_MODE_SELF_CHECK); //串口接收自检指令,开启自检模式 self_check_state = ENTER_SELF_CHECK; self_check_recive_order_times--; } } void app_self_checking_Init(void) { UART0_Rx_Regist(UART0_R_SELF_CHECK_ASK,cb_UART0_R_SELF_CHECK_ASK); Process_Start(0,"app_self_checking_monitor_Process",app_self_checking_monitor_Process); Process_Start(APP_SELF_CHECKING_PROCESS_CYCLE,"app_self_checking_Process",app_self_checking_Process); Process_Start(APP_SELF_CHECKING_READY_PROCESS_CYCLE,"app_self_checking_ready_Process",app_self_checking_ready_Process); }