app_self_checking.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #include "app_self_checking.h"
  2. #include "usr_config.h"
  3. #include "bsp_time.h"
  4. #include "system.h"
  5. #include "hal_ble_client.h"
  6. #include "hal_ble_host.h"
  7. #include "hal_mt.h"
  8. #include "nrf_delay.h"
  9. #include "app_charge.h"
  10. #include "hal_imu.h"
  11. #include "nrf_gpio.h"
  12. #include "hal_battery.h"
  13. #include "hal_ble_uart0.h"
  14. #include "hal_led.h"
  15. #include "ble_comm.h"
  16. #include "tool.h"
  17. #define TEST_SUCCESS 0 //测试成功
  18. #define TEST_FAIL 1 //测试失败
  19. #define TEST_ITEMS 4 //非人工测试项数(前脚传感器、后脚传感器、电量、充电电流)
  20. #define ENTER_SELF_CHECK 1 //进入自检标志位
  21. #define QUITE_SELF_CHECK 0 //退出自检标志位
  22. #define TEST_RESULT_LED_SUCCESS_GREEN 0
  23. #define TEST_RESULT_LED_ERR_RED (TEST_RESULT_LED_SUCCESS_GREEN+0x01)
  24. #define TEST_RESULT_LED_ERR_BLUE (TEST_RESULT_LED_SUCCESS_GREEN+0x02)
  25. #define TEST_RESULT_LED_ERR_PURPLE (TEST_RESULT_LED_SUCCESS_GREEN+0x03)
  26. #define TEST_RESULT_LED_ERR_YELLOW (TEST_RESULT_LED_SUCCESS_GREEN+0x04)
  27. #define DISPLAY_TEST_RESULT_LED_TIME 1000 //用灯显示测试结果的时间,单位ms
  28. #define DISPLAY_TEST_RESULT_CONTINUE_TIME 3000 //显示测试结果的总时间,单位ms
  29. #define SELF_CHECK_RECIVE_ORDER_TIMES 1 //允许接受到的自检指令最大次数
  30. #define BATTERY_TEST_VALUE 2500 //电池必须大于2.5V,否则算异常
  31. #define BATTERY_CHARGE_CHANGE_VALUE 80 //自检前和自检期间的充电电压变化值,单位mv
  32. static uint8_t self_check_state = QUITE_SELF_CHECK;
  33. static uint8_t self_check_result_buff[TEST_ITEMS];
  34. static uint8_t self_check_recive_order_times = 0; //允许接受到的自检指令最大次数
  35. static int16_t before_check_charge_vol = 0; //自检前的充电电压
  36. //发送非人工检测结果,只有在插上充电时,才配置串口
  37. static void app_self_check_send_result(uint8_t *buf, uint8_t datalen)
  38. {
  39. uint32_t txd,rxd;
  40. UART0_GetPinConfig(&txd, &rxd);
  41. UART0_Initialize(PIN_TXD_BLE,PIN_RXD_BLE,9600);
  42. UART0_Tx_Send(0,UART0_T_SELF_CHECK_ACK,buf,datalen);
  43. UART0_Initialize(txd,rxd,9600);
  44. }
  45. static void app_self_checking_ack_process(void)
  46. {
  47. app_self_check_send_result(self_check_result_buff, TEST_ITEMS);
  48. // SEGGER_RTT_printf(0,"app_self_checking_ack_process\n");
  49. }
  50. static void app_self_checking_err_led_process(void)
  51. {
  52. nrf_gpio_pin_toggle(PIN_LED_RUN);
  53. }
  54. static void app_self_checking_artificial(void) //人工测试(电机、指示灯)
  55. {
  56. uint32_t temp_result = 0;
  57. static uint8_t state = 0;
  58. static uint32_t display_times = 0;
  59. switch(state){
  60. case 0:
  61. Process_SetHoldOn(app_self_checking_artificial,1);
  62. //测试电机是否正常
  63. MT_Run(100);
  64. //显示其余的非人工测试结果
  65. for(int i=0;i<TEST_ITEMS;i++)temp_result +=self_check_result_buff[i];
  66. // SEGGER_RTT_printf(0,"temp_result=%d\n",temp_result);
  67. if(temp_result == TEST_SUCCESS){ //如果全部测试通过
  68. LED_SetColor(LED_SELF_CHECK,COLOR_GREEN);
  69. LED_Start(LED_SELF_CHECK);
  70. nrf_gpio_pin_write(PIN_LED_RUN,LED_SMALL_ENABLE);
  71. Process_UpdatePeroid(app_self_checking_artificial,DISPLAY_TEST_RESULT_LED_TIME);
  72. state = 1;
  73. break;
  74. }else{ //没有全部通过
  75. static uint8_t loop = 0;
  76. if(self_check_result_buff[loop++] != TEST_SUCCESS){
  77. switch(loop)
  78. {
  79. case TEST_RESULT_LED_ERR_RED:
  80. LED_SetColor(LED_SELF_CHECK,COLOR_RED);
  81. break;
  82. case TEST_RESULT_LED_ERR_BLUE:
  83. LED_SetColor(LED_SELF_CHECK,COLOR_BLUE);
  84. break;
  85. case TEST_RESULT_LED_ERR_PURPLE:
  86. LED_SetColor(LED_SELF_CHECK,COLOR_PURPLE);
  87. break;
  88. case TEST_RESULT_LED_ERR_YELLOW:
  89. LED_SetColor(LED_SELF_CHECK,COLOR_YELLOW);
  90. break;
  91. }
  92. Process_UpdatePeroid(app_self_checking_artificial,DISPLAY_TEST_RESULT_LED_TIME);
  93. LED_Start(LED_SELF_CHECK);
  94. // //开启外设损坏小灯闪烁线程,100ms翻转一次
  95. // Process_Start(100,"app_self_checking_err_led_process",app_self_checking_err_led_process);
  96. }else{
  97. Process_UpdatePeroid(app_self_checking_artificial,0); //通过的某项就跳过等待时间。
  98. }
  99. if(loop == TEST_ITEMS){
  100. loop = 0;
  101. state = 1;
  102. }
  103. }
  104. break;
  105. case 1:
  106. for(int i=0;i<TEST_ITEMS;i++)temp_result +=self_check_result_buff[i];
  107. temp_result = (temp_result == 0) ? DISPLAY_TEST_RESULT_LED_TIME : (temp_result * DISPLAY_TEST_RESULT_LED_TIME);//跑完一次case0的时间
  108. if((temp_result * ++display_times) <= DISPLAY_TEST_RESULT_CONTINUE_TIME){
  109. state = 0;
  110. break;
  111. }
  112. display_times = 0;
  113. Process_UpdatePeroid(app_self_checking_artificial,0);
  114. LED_Stop(LED_SELF_CHECK);
  115. nrf_gpio_pin_write(PIN_LED_RUN,LED_SMALL_DISABLE);
  116. state = 0;
  117. Process_SetHoldOn(app_self_checking_artificial,0);
  118. Process_Stop(app_self_checking_artificial);
  119. Process_Stop(app_self_checking_err_led_process);
  120. break;
  121. default:state=0;Process_UpdatePeroid(app_self_checking_artificial,0);break;
  122. }
  123. }
  124. //测试前脚IMU和地磁是否正常
  125. static void app_checking_front_sensor(uint8_t *check_result)
  126. {
  127. static int16_t acc_front[IMU_BUFF_SIZE][3];
  128. static int16_t gry_front[IMU_BUFF_SIZE][3];
  129. static int16_t mag6310_front[IMU_BUFF_SIZE][3];
  130. static int32_t timestamp_front[IMU_BUFF_SIZE];
  131. int16_t group_num = 0;
  132. int16_t front_index = 0;
  133. group_num = IMU_Get_Front_Update_Data_GroupNum();
  134. group_num = group_num >= IMU_BUFF_SIZE?IMU_BUFF_SIZE:group_num;
  135. front_index = IMU_Get_Front_Full_Power_Data((int16_t*)gry_front, (int16_t*)acc_front, (int16_t*)mag6310_front, timestamp_front, group_num);
  136. for(int i=0; i < front_index; i++)
  137. {
  138. if( (gry_front[i][0] == 0 && gry_front[i][1] == 0 && gry_front[i][2] == 0) || \
  139. (acc_front[i][0] == 0 && acc_front[i][1] == 0 && acc_front[i][2] == 0) || \
  140. (mag6310_front[i][0] == 0 && mag6310_front[i][1] == 0 && mag6310_front[i][2] == 0) ||
  141. (timestamp_front[i] == 0))
  142. {
  143. *check_result = TEST_FAIL;
  144. }
  145. }
  146. }
  147. //测试后脚地磁是否正常
  148. static void app_checking_back_sensor(uint8_t *check_result)
  149. {
  150. static int16_t mag6310_back[3];
  151. IMU_Get_Back_Mag(mag6310_back);
  152. if(mag6310_back[0] == 0 && mag6310_back[1] == 0 && mag6310_back[2] == 0)*check_result = TEST_FAIL;
  153. }
  154. //测试电量检测是否正常
  155. static void app_checking_bat(uint8_t *check_result)
  156. {
  157. int16_t cur_vol;
  158. int16_t bat;
  159. cur_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
  160. bat = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_BAT_CHANNEL))*5/3;
  161. SEGGER_RTT_printf(0,"app_checking_bat 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);
  162. //电池小于2.5V或充电电压变化小于阈值且电池电压大于4V
  163. if(bat <= BATTERY_TEST_VALUE || ((cur_vol-before_check_charge_vol)<BATTERY_CHARGE_CHANGE_VALUE && bat > 4000))*check_result = TEST_FAIL;
  164. }
  165. //测试充电电流是否正常
  166. static void app_checking_charge(uint8_t *check_result)
  167. {
  168. int16_t cur_vol;
  169. cur_vol = ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL);
  170. cur_vol = ADC_RESULT_IN_MILLI_VOLTS(cur_vol);
  171. 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);
  172. //当电池电量满了,不充电(经测试,哪怕电量满了,充电电压也有10+mv)
  173. //当电池电量没满,充电(经测试,电量没满的充电电压跟电池电压有关,最小充电电压100+mv)
  174. if((cur_vol-before_check_charge_vol)<BATTERY_CHARGE_CHANGE_VALUE)*check_result = TEST_FAIL;
  175. }
  176. void app_self_checking_Process(void)
  177. {
  178. static uint8_t wait_times = IMU_INIT_TIMES + 1; // 预防IMU初始化失败,重复几次才初始化成功的情况,所以等待时间为初始化失败上限+1
  179. if(self_check_state == ENTER_SELF_CHECK){
  180. if(wait_times-- != 0)return;
  181. wait_times = IMU_INIT_TIMES + 1;
  182. memset(self_check_result_buff,TEST_SUCCESS,TEST_ITEMS);
  183. if(app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT){
  184. //如果插上充电,测试充电电流是否正常
  185. app_checking_charge(&self_check_result_buff[3]);
  186. }
  187. if(IMU_GetCurrentMode() == STATE_SELF_CHECK_MODE){
  188. //测试前脚IMU和地磁是否正常
  189. app_checking_front_sensor(&self_check_result_buff[0]);
  190. }else{
  191. //前脚传感器损坏
  192. self_check_result_buff[0] = TEST_FAIL;
  193. }
  194. //测试后脚地磁是否正常
  195. app_checking_back_sensor(&self_check_result_buff[1]);
  196. //测试电量检测是否正常
  197. app_checking_bat(&self_check_result_buff[2]);
  198. //发送非人工检测结果,只有在插上充电时,才配置串口
  199. if(app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT){
  200. Process_Start(50,"app_self_checking_ack_process",app_self_checking_ack_process);
  201. }
  202. //关闭自检模式
  203. IMU_SetSelfCheckMode(0);
  204. self_check_state = QUITE_SELF_CHECK;
  205. // self_check_result_buff[0] = TEST_FAIL;
  206. // self_check_result_buff[1] = TEST_FAIL;
  207. // self_check_result_buff[2] = TEST_FAIL;
  208. // self_check_result_buff[3] = TEST_FAIL;
  209. // self_check_result_buff[0] = TEST_SUCCESS;
  210. // self_check_result_buff[1] = TEST_SUCCESS;
  211. // self_check_result_buff[2] = TEST_SUCCESS;
  212. // self_check_result_buff[3] = TEST_SUCCESS;
  213. /*-----------------上面是不需要人工检测的项目,正常亮小灯,下面的只能靠人工来观察是否正常----------------------------*/
  214. //开启需要人工去测试的线程
  215. Process_Start(0,"app_self_checking_artificial",app_self_checking_artificial);
  216. }
  217. else if(app_charge_Getstate()==BLE_Client_T_CHARGE_PULLOUT){
  218. //更新可接受的自检指令最大次数
  219. self_check_recive_order_times = SELF_CHECK_RECIVE_ORDER_TIMES;
  220. //用于判断充电芯片和电池是否断线
  221. int16_t temp_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
  222. before_check_charge_vol = before_check_charge_vol > temp_vol ? temp_vol : before_check_charge_vol;
  223. //发送自检结果线程停止
  224. Process_Stop(app_self_checking_ack_process);
  225. }
  226. //地磁触发自检
  227. else if((IMU_GetCurrentMode() == STATE_LOW_POWER_MODE) && app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT){
  228. int16_t mag[3];
  229. IMU_Get_Index_Front_Low_Power_Data(NULL, mag, NULL, IMU_Get_Front_Update_Data_GroupNum());
  230. int32_t front_mag_norm;
  231. front_mag_norm = (int32_t)(sqrt((float) (mag[0] * mag[0] + mag[1] * mag[1] + mag[2] * mag[2])));
  232. if(front_mag_norm>=20000){
  233. IMU_SetSelfCheckMode(1); //开机,开启自检模式
  234. self_check_state = ENTER_SELF_CHECK;
  235. }
  236. }
  237. // //用于测量充电电压、电池电压、电量百分比
  238. // int16_t bat;
  239. // int16_t vol;
  240. // if(app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT){
  241. // bat = ADC_GetValue(PIN_ADC_BAT_CHANNEL);
  242. // bat = ADC_RESULT_IN_MILLI_VOLTS(bat)*5/3;
  243. // SEGGER_RTT_printf(0,"charge!!! %d %d %d\r\n",before_check_charge_vol,bat,GetBatteryPersent());
  244. // }else{
  245. // bat = ADC_GetValue(PIN_ADC_BAT_CHANNEL);
  246. // bat = ADC_RESULT_IN_MILLI_VOLTS(bat)*5/3;
  247. // SEGGER_RTT_printf(0,"no charge!!! %d %d %d\r\n",before_check_charge_vol,bat,GetBatteryPersent());
  248. // }
  249. }
  250. void app_self_checking_ready_Process(void)
  251. {
  252. char advname_buf[100];
  253. int adv_len;
  254. if(app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT && self_check_recive_order_times){
  255. slave_get_advname_len(&adv_len);
  256. slave_get_advname(advname_buf, adv_len);
  257. uint32_t txd,rxd;
  258. UART0_GetPinConfig(&txd, &rxd);
  259. UART0_Initialize(PIN_TXD_BLE,UART0_INVALID_PIN,9600);
  260. UART0_Tx_Send(0,UART0_T_SELF_CHECK_RDY,(uint8_t*)advname_buf,adv_len);
  261. // SEGGER_RTT_printf(0,"advname_buf:%s len:%d\n",advname_buf,adv_len);
  262. UART0_Initialize(txd,rxd,9600);
  263. }
  264. }
  265. void cb_UART0_R_SELF_CHECK_ASK(void* handle)
  266. {
  267. if(self_check_recive_order_times){
  268. IMU_SetSelfCheckMode(1); //串口接收自检指令,开启自检模式
  269. self_check_state = ENTER_SELF_CHECK;
  270. self_check_recive_order_times--;
  271. }
  272. }
  273. void cb_UART0_R_SELF_CHECK_END(void* handle)
  274. {
  275. Process_Stop(app_self_checking_ack_process); //发送自检结果线程停止
  276. }
  277. void app_self_checking_Init(void)
  278. {
  279. UART0_Rx_Regist(UART0_R_SELF_CHECK_ASK,cb_UART0_R_SELF_CHECK_ASK);
  280. UART0_Rx_Regist(UART0_R_SELF_CHECK_END,cb_UART0_R_SELF_CHECK_END);
  281. Process_Start(10,"app_self_checking_Process",app_self_checking_Process);
  282. Process_Start(50,"app_self_checking_ready_Process",app_self_checking_ready_Process);
  283. }