app_self_checking.c 11 KB

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