selfcheck.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953
  1. /*Includes ----------------------------------------------*/
  2. #include "tool.h"
  3. #include "hal_MahonyAHRS.h"
  4. #include "ble_comm.h"
  5. #include "nrf_delay.h"
  6. #include "bsp_pwm.h"
  7. #include "bsp_time.h"
  8. #include "fml_adc.h"
  9. #include "bsp_wdt.h"
  10. #include "exception.h"
  11. #include "selfcheck.h"
  12. #include "system.h"
  13. #include "drv_qma7981.h"
  14. #include "hal_led.h"
  15. #include "hal_battery.h"
  16. #include "bll_imu.h"
  17. #include "app_flash.h"
  18. #include "system.h"
  19. #include "hal_mahonyAHRS.h"
  20. #include "app_detectIsHost.h"
  21. /*Private macro ------------------------------------------------------------------------------------------------------------------------------------*/
  22. #define SELFCHECK_SCAN_DEVICE_RSSI_MIN_THRESHOLD -60 //需要扫描的设备的RSSI最小阈值,-76
  23. #define SELFCHECK_CHARGE_CHIP_PIN_ADC_MIN_THRESHOLD 80 //充电芯片引脚的最小ADC阈值
  24. #define SELFCHECK_BATTERY_PIN_ADC_MIN_THRESHOLD 3300 //电池分压电阻的最小ADC阈值
  25. #define SELFCHECK_BATTERY_PIN_ADC_MAX_THRESHOLD 4300 //电池分压电阻的最大ADC阈值,拆掉电阻后,原始值为3721,换算为5.49V
  26. #define SELFCHECK_MIDDLE_ACC_PROS_ROLL_MIN_THRESHOLD 0 //中间加速度正向ROLL值最小阈值
  27. #define SELFCHECK_MIDDLE_ACC_PROS_ROLL_MAX_THRESHOLD 35 //中间加速度正向ROLL值最大阈值
  28. #define SELFCHECK_MIDDLE_ACC_CONS_ROLL_MIN_THRESHOLD 160 //中间加速度反向ROLL值最小阈值
  29. #define SELFCHECK_MIDDLE_ACC_CONS_ROLL_MAX_THRESHOLD 180 //中间加速度反向ROLL值最大阈值
  30. #define SELFCHECK_WEAR_INSOLE_MAG_NORM_MIN_THRESHOLD 5000 //穿鞋垫的地磁norm值最小阈值
  31. #define SELFCHECK_SENSOR_MAG_SHAKE_TRIGGER_THRESHOLD 18000 //地磁抖动触发检测
  32. #define SELFCHECK_SENSOR_MAG_NO_WELDING_CAPACITOR_MIN_THRESHOLD 200 //地磁传感器没焊接电容的最小阈值
  33. #define SELFCHECK_SENSOR_MAG_SHAKE_THRESHOLD 200 //地磁抖动阈值
  34. #define SELFCHECK_LED_DISPLAY_CYCLE_THRESHOLD 200 //自检灯显示周期时间,单位ms
  35. #define SELFCHECK_MIDDLE_ACC_CHECK_MT_MIN_THRESHOLD 1500 //中间加速度检测电机最小差值,不震动的差值是129,有个能震动的差值是1800+
  36. #define SELFCHECK_IMU_MONITOR_DATA_ERR_SUM_MAX 416 //数据监测错误累计最大值
  37. /*STRUCTION ------------------------------------------------------------------------------------------------------------------------------------*/
  38. typedef enum {
  39. SELFCHECK_RESULT_SUCCESS = 0, //自检成功
  40. SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_SIX_AXIS_ID, //自检失败——前脚传感器配置六轴ID
  41. SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_MAG_ID, //自检失败——前脚传感器配置地磁ID
  42. SELFCHECK_RESULT_ERR_BACK_SENSOR_CONFIG_ID, //自检失败——后脚传感器配置地磁ID
  43. SELFCHECK_RESULT_ERR_CHARGE_CHIP_PIN_ADC, //自检失败——充电芯片引脚ADC
  44. SELFCHECK_RESULT_ERR_BATTERY_PIN_ADC, //自检失败——电池分压电阻ADC
  45. SELFCHECK_RESULT_ERR_RSSI, //自检失败——RSSI
  46. SELFCHECK_RESULT_ERR_MT, //自检失败——震动电机
  47. SELFCHECK_RESULT_ERR_FRONT_IMU_REVERSE, //自检失败——前脚传感器装反
  48. SELFCHECK_RESULT_ERR_FRONT_MAG_DATA_TO_SMALL, //自检失败——前脚传感器地磁数据过小
  49. SELFCHECK_RESULT_ERR_FRONT_MAG_DATA_SHAKE, //自检失败——前脚传感器地磁数据抖动
  50. SELFCHECK_RESULT_ERR_BACK_DATA_TO_SMALL, //自检失败——后脚传感器地磁数据过小
  51. SELFCHECK_RESULT_ERR_BACK_DATA_SHAKE, //自检失败——后脚传感器地磁数据抖动
  52. SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_SIX_AXIS, //自检失败——前脚传感器配置六轴
  53. SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_MAG, //自检失败——前脚传感器配置地磁
  54. SELFCHECK_RESULT_ERR_FRONT_SIX_AXIS_NO_DATA, //自检失败——前脚传感器六轴没数据
  55. SELFCHECK_RESULT_ERR_FRONT_SIX_AXIS_EXCP_DATA, //自检失败——前脚传感器六轴数据异常(数据持续相等)
  56. SELFCHECK_RESULT_ERR_FRONT_MAG_NO_DATA, //自检失败——前脚传感器地磁没数据
  57. SELFCHECK_RESULT_ERR_FRONT_MAG_EXCP_DATA, //自检失败——前脚传感器地磁数据异常(数据持续相等)
  58. SELFCHECK_RESULT_ERR_BACK_SENSOR_CONFIG, //自检失败——后脚传感器配置
  59. SELFCHECK_RESULT_ERR_BACK_NO_DATA, //自检失败——后脚传感器没数据
  60. SELFCHECK_RESULT_ERR_BACK_EXCP_DATA, //自检失败——后脚传感器数据异常(数据持续相等)
  61. SELFCHECK_RESULT_ERR_MIDDLE_SENSOR_CONFIG, //自检失败——中间传感器配置
  62. SELFCHECK_RESULT_ERR_MIDDLE_NO_DATA_OR_EXCP_DATA, //自检失败——中间传感器没数据或数据异常
  63. } SELFCHECK_RESULT_e;
  64. typedef struct _selfcheck
  65. {
  66. uint32_t selfcheck_result; //自检结果
  67. uint32_t selfcheck_result_led_color; //自检结果的led灯颜色
  68. uint32_t selfcheck_result_flash_num; //自检结果闪烁次数
  69. int16_t max_rssi; //最大的RSSI值
  70. fml_imu_data_t f_data; //前脚传感器数据
  71. fml_imu_data_t b_data; //后脚传感器数据
  72. qma_data_t m_data; //中间传感器数据
  73. bool f_is_read_data; //前脚传感器是否读到数据标志位
  74. bool b_is_read_data; //后脚传感器是否读到数据标志位
  75. char order; //指令
  76. } SelfCheck_t;
  77. /*Local Variable ------------------------------------------------------------------------------------------------------------------------------------*/
  78. static SelfCheck_t ob_selfcheck;
  79. static const bll_imu_one_way_param_t game_front_param={
  80. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //前脚 - 加速度正常模式
  81. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //前脚 - 陀螺仪正常模式
  82. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //前脚 - 时间戳25US精度
  83. .timestamp_switch = FML_IMU_TIMESTAMP_ON, //前脚 - 时间戳开启
  84. .acc_fs = FML_IMU_ACC_FS_16G, //前脚 - 加速度量程 - 16G
  85. .gry_fs = FML_IMU_GRY_FS_2000DPS, //前脚 - 陀螺仪量程 - 2000DPS
  86. .mag_fs = FML_IMU_MAG_FS_30GS, //前脚 - 地磁计量程 - 30GS
  87. .acc_odr = FML_IMU_ACC_ODR_416HZ, //前脚 - 加速度采样频率 - 104HZ
  88. .gry_odr = FML_IMU_GRY_ODR_416HZ, //前脚 - 陀螺仪采样频率 - 104HZ
  89. .mag_odr = FML_IMU_MAG_ODR_200HZ, //前脚 - 地磁计采样频率 - 200HZ
  90. .fifo_odr = FML_IMU_FIFO_ODR_416HZ,
  91. };
  92. static const bll_imu_one_way_param_t game_back_param={
  93. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //后脚 - 加速度正常模式
  94. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //后脚 - 陀螺仪正常模式
  95. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //后脚 - 时间戳25US精度
  96. .timestamp_switch = FML_IMU_TIMESTAMP_OFF, //后脚 - 时间戳关闭
  97. .acc_fs = FML_IMU_ACC_FS_16G, //后脚 - 加速度量程 - 16G
  98. .gry_fs = FML_IMU_GRY_FS_2000DPS, //后脚 - 陀螺仪量程 - 2000DPS
  99. .mag_fs = FML_IMU_MAG_FS_30GS, //后脚 - 地磁计量程 - 30GS
  100. .acc_odr = FML_IMU_ACC_ODR_OFF, //后脚 - 加速度采样频率 - 关闭
  101. .gry_odr = FML_IMU_GRY_ODR_OFF, //后脚 - 陀螺仪采样频率 - 关闭
  102. .mag_odr = FML_IMU_MAG_ODR_200HZ, //后脚 - 地磁计采样频率 - 200HZ
  103. .fifo_odr = FML_IMU_FIFO_ODR_OFF,
  104. };
  105. static const bll_imu_param_t game_bll_imu_param_t={
  106. .config_param[FML_IMU_DIR_FRONT] = &game_front_param,
  107. .config_param[FML_IMU_DIR_BACK] = &game_back_param,
  108. };
  109. static MahonyAHRS_t Self_Mind_Mahony={0};
  110. static MahonyAHRS_t Self_Front_Mahony={0};
  111. /*Local Functions ------------------------------------------------------------------------------------------------------------------------------------*/
  112. static void monitor_sensor_data(int16_t *f_acc, int16_t *f_gry, int16_t *f_mag, int16_t *b_mag)
  113. {
  114. static int16_t last_f_acc[3]; //上一次的前脚加速度值
  115. static int16_t last_f_gry[3]; //上一次的前脚陀螺仪值
  116. static int16_t last_f_mag[3]; //上一次的前脚地磁计值
  117. static int16_t last_b_mag[3]; //上一次的后脚地磁计值
  118. static int16_t last_f_acc_err_sum; //上一次的前脚加速度值错误累计
  119. static int16_t last_f_gry_err_sum; //上一次的前脚陀螺仪值错误累计
  120. static int16_t last_f_mag_err_sum; //上一次的前脚地磁计值错误累计
  121. static int16_t last_b_mag_err_sum; //上一次的后脚地磁计值错误累计
  122. /*前脚加速度*/
  123. if(f_acc != NULL)
  124. {
  125. if(
  126. last_f_acc[0] == f_acc[0] && \
  127. last_f_acc[1] == f_acc[1] && \
  128. last_f_acc[2] == f_acc[2]
  129. )
  130. {
  131. last_f_acc_err_sum++;
  132. if(last_f_acc_err_sum >= SELFCHECK_IMU_MONITOR_DATA_ERR_SUM_MAX){
  133. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_SIX_AXIS_EXCP_DATA);
  134. }
  135. }else{
  136. last_f_acc_err_sum = 0;
  137. }
  138. last_f_acc[0] = f_acc[0];
  139. last_f_acc[1] = f_acc[1];
  140. last_f_acc[2] = f_acc[2];
  141. }
  142. /*前脚陀螺仪*/
  143. if(f_gry != NULL)
  144. {
  145. if(
  146. last_f_gry[0] == f_gry[0] && \
  147. last_f_gry[1] == f_gry[1] && \
  148. last_f_gry[2] == f_gry[2]
  149. )
  150. {
  151. last_f_gry_err_sum++;
  152. if(last_f_gry_err_sum >= SELFCHECK_IMU_MONITOR_DATA_ERR_SUM_MAX){
  153. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_SIX_AXIS_EXCP_DATA);
  154. }
  155. }else{
  156. last_f_gry_err_sum = 0;
  157. }
  158. last_f_gry[0] = f_gry[0];
  159. last_f_gry[1] = f_gry[1];
  160. last_f_gry[2] = f_gry[2];
  161. }
  162. /*前脚地磁计*/
  163. if(f_mag != NULL)
  164. {
  165. if(
  166. last_f_mag[0] == f_mag[0] && \
  167. last_f_mag[1] == f_mag[1] && \
  168. last_f_mag[2] == f_mag[2]
  169. )
  170. {
  171. last_f_mag_err_sum++;
  172. if(last_f_mag_err_sum >= SELFCHECK_IMU_MONITOR_DATA_ERR_SUM_MAX){
  173. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_MAG_EXCP_DATA);
  174. }
  175. }else{
  176. last_f_mag_err_sum = 0;
  177. }
  178. last_f_mag[0] = f_mag[0];
  179. last_f_mag[1] = f_mag[1];
  180. last_f_mag[2] = f_mag[2];
  181. }
  182. /*后脚地磁计*/
  183. if(b_mag != NULL)
  184. {
  185. if(
  186. last_b_mag[0] == b_mag[0] && \
  187. last_b_mag[1] == b_mag[1] && \
  188. last_b_mag[2] == b_mag[2]
  189. )
  190. {
  191. last_b_mag_err_sum++;
  192. if(last_b_mag_err_sum >= (SELFCHECK_IMU_MONITOR_DATA_ERR_SUM_MAX/2)){
  193. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BACK_EXCP_DATA);
  194. }
  195. }else{
  196. last_b_mag_err_sum = 0;
  197. }
  198. last_b_mag[0] = b_mag[0];
  199. last_b_mag[1] = b_mag[1];
  200. last_b_mag[2] = b_mag[2];
  201. }
  202. }
  203. static void fb_data_notify_cb(uint32_t dir_bit)
  204. {
  205. int data_len;
  206. if((dir_bit >> BLL_IMU_DIR_FRONT) & 0x01)
  207. {
  208. memset(&ob_selfcheck.f_data,0,sizeof(ob_selfcheck.f_data));
  209. data_len = bll_imu_get_data_num(BLL_IMU_DIR_FRONT);
  210. for(int i=0; i<data_len;i++)
  211. {
  212. bll_imu_get_data(BLL_IMU_DIR_FRONT, i, &ob_selfcheck.f_data);
  213. }
  214. monitor_sensor_data(ob_selfcheck.f_data.acc, ob_selfcheck.f_data.gry, ob_selfcheck.f_data.mag, NULL);
  215. Mahony_update(&Self_Front_Mahony,0,0,0,ob_selfcheck.f_data.acc[0],ob_selfcheck.f_data.acc[1],ob_selfcheck.f_data.acc[2],0,0,0);
  216. }
  217. if((dir_bit >> BLL_IMU_DIR_BACK) & 0x01)
  218. {
  219. memset(&ob_selfcheck.b_data,0,sizeof(ob_selfcheck.b_data));
  220. data_len = bll_imu_get_data_num(BLL_IMU_DIR_BACK);
  221. for(int i=0; i<data_len;i++)
  222. {
  223. bll_imu_get_data(BLL_IMU_DIR_BACK, i, &ob_selfcheck.b_data);
  224. }
  225. monitor_sensor_data(NULL, NULL, NULL, ob_selfcheck.b_data.mag);
  226. }
  227. if(((dir_bit >> BLL_IMU_DIR_FRONT) & 0x01))
  228. {
  229. ob_selfcheck.f_is_read_data = true;
  230. }
  231. if((dir_bit >> BLL_IMU_DIR_BACK))
  232. {
  233. ob_selfcheck.b_is_read_data = true;
  234. }
  235. }
  236. static void scan_report_cb(ble_gap_evt_adv_report_t const * p_adv_report)
  237. {
  238. ob_selfcheck.max_rssi = (ob_selfcheck.max_rssi > p_adv_report->rssi)?ob_selfcheck.max_rssi:p_adv_report->rssi;
  239. }
  240. static void selfcheck_result_display_process(void)
  241. {
  242. static uint32_t led_display_count = 0;
  243. //根据自检结果显示结果:
  244. //前脚传感器——红色(前脚六轴配置问题闪烁1下,前脚地磁配置问题闪烁2下,前脚六轴数据读取失败或数据异常闪烁3下,前脚地磁数据读取失败或数据异常闪烁4下)
  245. //后脚传感器——红色(后脚地磁配置问题闪烁5下,后脚地磁数据读取失败或数据异常闪烁6下)
  246. //中间传感器——红色(中间加速度配置问题闪烁7下,加速度roll值不在范围内闪烁8下)
  247. //充电芯片和电池分压电阻和蓝牙天线rssi——红色(充电芯片问题闪烁9下,电池分压电阻闪烁10下,蓝牙天线rssi问题闪烁11下)
  248. //中间加速度检测震动电机(待定)
  249. //上述检测通过,蓝色(1秒周期,500ms亮,500ms灭(断电源线)),若检测到鞋垫,则绿色(1秒周期,500ms亮,500ms灭(断电源线))。
  250. //LED电源引脚亮灯拉高,灭灯拉低。(4秒周期,40ms亮,160ms灭(断电源线)一组)
  251. //喂狗
  252. feed_watchdog();
  253. Process_UpdatePeroid(selfcheck_result_display_process,SELFCHECK_LED_DISPLAY_CYCLE_THRESHOLD);
  254. led_display_count++;
  255. if(led_display_count % 2 == 0)
  256. {
  257. WS2812_DisplayDot(COLOR_BLACK);WS2812_Pwm_Play();
  258. }
  259. else
  260. {
  261. WS2812_DisplayDot(ob_selfcheck.selfcheck_result_led_color);WS2812_Pwm_Play();
  262. }
  263. if(led_display_count >= ob_selfcheck.selfcheck_result_flash_num * 2)
  264. {
  265. led_display_count = 0;
  266. WS2812_DisplayDot(COLOR_BLACK);WS2812_Pwm_Play();
  267. Process_UpdatePeroid(selfcheck_result_display_process,SELFCHECK_LED_DISPLAY_CYCLE_THRESHOLD * 3);
  268. }
  269. }
  270. static void selfcheck_led_process(void)
  271. {
  272. //喂狗
  273. feed_watchdog();
  274. static uint8_t flow = 0;
  275. switch(flow)
  276. {
  277. case 0:
  278. WS2812_DisplayDot(COLOR_RED);WS2812_Pwm_Play();
  279. flow = 1;
  280. break;
  281. case 1:
  282. WS2812_DisplayDot(COLOR_GREEN);WS2812_Pwm_Play();
  283. flow = 2;
  284. break;
  285. case 2:
  286. WS2812_DisplayDot(COLOR_BLUE);WS2812_Pwm_Play();
  287. flow = 0;
  288. break;
  289. }
  290. nrf_gpio_pin_write(PIN_MT_EN,1);//这样有200ms的时间获取静止状态下的中间acc的z轴
  291. }
  292. static void selfcheck_mt_process(void)
  293. {
  294. static int16_t max_acc_z = 0;
  295. static int16_t min_acc_z = 32767;
  296. int16_t acc_z = 0;
  297. //喂狗
  298. feed_watchdog();
  299. //检测震动是否达标
  300. //读取中间传感器数据,计算加速度roll值
  301. if(ob_selfcheck.order == 0x52)
  302. {
  303. memset(&ob_selfcheck.m_data,0,sizeof(ob_selfcheck.m_data));
  304. if(drv_qma_get_acc_data(&ob_selfcheck.m_data) == 0)
  305. {
  306. if(ob_selfcheck.m_data.acc[0]==0 && ob_selfcheck.m_data.acc[1]==0 && ob_selfcheck.m_data.acc[2]==0)return;
  307. if(ob_selfcheck.m_data.acc[0]==-1 && ob_selfcheck.m_data.acc[1]==-1 && ob_selfcheck.m_data.acc[2]==-1)return;
  308. if(ob_selfcheck.m_data.acc[2] < 0)acc_z = ob_selfcheck.m_data.acc[2]*-1;
  309. else acc_z = ob_selfcheck.m_data.acc[2];
  310. max_acc_z = (max_acc_z > acc_z)?max_acc_z:acc_z;
  311. min_acc_z = (min_acc_z > acc_z)?acc_z:min_acc_z;
  312. if((max_acc_z - min_acc_z) < SELFCHECK_MIDDLE_ACC_CHECK_MT_MIN_THRESHOLD)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_MT);
  313. else ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_MT);
  314. // SEGGER_RTT_printf(0,"middle acc %d,%d,%d acc_z:%d,max:%d,min:%d,%d\r\n",ob_selfcheck.m_data.acc[0],ob_selfcheck.m_data.acc[1],ob_selfcheck.m_data.acc[2],acc_z,max_acc_z,min_acc_z,max_acc_z-min_acc_z);
  315. }
  316. }
  317. }
  318. #define N 10 //N > 3
  319. int data[N];
  320. int middleFilter(int in_data)
  321. {
  322. int sum = 0;
  323. int temp[N];
  324. int change;
  325. int i,j;
  326. //记录数据
  327. for(i=0; i<(N-1); i++)
  328. {
  329. data[i]=data[i+1];
  330. }
  331. data[N-1] = in_data;
  332. //复制数据
  333. for(i=0; i<N; i++)
  334. temp[i] = data[i];
  335. //冒泡法排序
  336. for(i=1; i<N; i++)
  337. for(j=0; j<N-i; j++)
  338. {
  339. if(temp[i] > temp[i+1])
  340. {
  341. change = temp[i];
  342. temp[i] = temp[i+1];
  343. temp[i+1] = change;
  344. }
  345. }
  346. //求和
  347. for(i=1; i<(N-1); i++)
  348. sum = sum + temp[i];
  349. //返回平均值
  350. return(sum/((N-2)));
  351. }
  352. static void selfcheck_process(void)
  353. {
  354. BLL_IMU_CONFIG_RESULT f_config_result,b_config_result;
  355. int16_t adc_value = 0;
  356. uint16_t front_mag_norm;
  357. uint16_t back_mag_norm;
  358. int16_t roll;
  359. uint8_t buf[256];
  360. uint8_t L=0;
  361. char mac_buf[16];
  362. static uint32_t charge_chip_adc_max = 0;
  363. static int16_t battery_adc_max = 0;
  364. static uint32_t t_count = 0;
  365. static uint32_t battery_adc_t_count = 0;
  366. static uint32_t roll_t_count = 0;
  367. static uint32_t sensor_t_count = 0;
  368. static uint32_t last_tim = 0;
  369. static uint32_t continue_trigger = 0;
  370. static uint32_t front_mag_norm_max = 0;
  371. static uint32_t back_mag_norm_max = 0;
  372. static uint32_t front_mag_norm_min = 0xffffffff;
  373. static uint32_t back_mag_norm_min = 0xffffffff;
  374. static bool front_mag_shake_trigger = false;
  375. static bool back_mag_shake_trigger = false;
  376. t_count++;
  377. //喂狗
  378. feed_watchdog();
  379. //读取中间传感器数据,计算加速度roll值
  380. memset(&ob_selfcheck.m_data,0,sizeof(ob_selfcheck.m_data));
  381. if(drv_qma_get_acc_data(&ob_selfcheck.m_data) != 0)
  382. {
  383. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_MIDDLE_NO_DATA_OR_EXCP_DATA);
  384. //重新配置
  385. drv_qma_set_acc_odr(QMA_ACC_ODR_104HZ);
  386. }
  387. Mahony_update(&Self_Mind_Mahony,0,0,0,ob_selfcheck.m_data.acc[0],ob_selfcheck.m_data.acc[1],ob_selfcheck.m_data.acc[2],0,0,0);
  388. //筛选最大的电池分压后的电压
  389. fml_adc_get_value(PIN_ADC_BAT_CHANNEL,&adc_value);
  390. adc_value = ADC_RESULT_IN_MILLI_VOLTS(adc_value) * 5 / 3;
  391. battery_adc_max = middleFilter(adc_value);
  392. //每3秒读取ADC,以5V电压测试电池分压电阻是否焊接,不考虑阻值,设置自检结果。
  393. if(t_count - battery_adc_t_count > (3000/100))
  394. {
  395. if(!(SELFCHECK_BATTERY_PIN_ADC_MIN_THRESHOLD < battery_adc_max && battery_adc_max < SELFCHECK_BATTERY_PIN_ADC_MAX_THRESHOLD))ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BATTERY_PIN_ADC);
  396. else ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_BATTERY_PIN_ADC);
  397. //更新计时
  398. battery_adc_t_count = t_count;
  399. }
  400. //充电芯片检测
  401. fml_adc_get_value(PIN_ADC_CHARGMEASURE_CHANNEL,&adc_value);
  402. if(SELFCHECK_CHARGE_CHIP_PIN_ADC_MIN_THRESHOLD < adc_value)
  403. {
  404. charge_chip_adc_max++;
  405. }
  406. if(charge_chip_adc_max >= 5)
  407. {
  408. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_CHARGE_CHIP_PIN_ADC);
  409. }
  410. else
  411. {
  412. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_CHARGE_CHIP_PIN_ADC);
  413. }
  414. //每3秒检测加速度roll值,设置自检结果。
  415. if(t_count - roll_t_count > (3000/100))
  416. {
  417. roll = (int16_t)(Self_Mind_Mahony.roll*100);
  418. if(roll < 0)roll *= -1;
  419. roll = (roll > 0 && roll < 100)?1:roll/100;
  420. if(!( \
  421. (SELFCHECK_MIDDLE_ACC_PROS_ROLL_MIN_THRESHOLD < roll && roll < SELFCHECK_MIDDLE_ACC_PROS_ROLL_MAX_THRESHOLD) || \
  422. (SELFCHECK_MIDDLE_ACC_CONS_ROLL_MIN_THRESHOLD < roll && roll < SELFCHECK_MIDDLE_ACC_CONS_ROLL_MAX_THRESHOLD) \
  423. ))ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_MIDDLE_NO_DATA_OR_EXCP_DATA);
  424. else
  425. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_MIDDLE_NO_DATA_OR_EXCP_DATA);
  426. //更新计时
  427. roll_t_count = t_count;
  428. }
  429. //每1秒查看前后传感器是否配置且读取成功(至少要1秒才有结果)且值本身是否正常(如地磁没有焊接电容),设置自检结果。
  430. if(t_count - sensor_t_count > (1000/100))
  431. {
  432. //前脚传感器判断
  433. f_config_result = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_FRONT,&game_bll_imu_param_t);
  434. if(f_config_result != BLL_IMU_CONFIG_FINISH)
  435. {
  436. if(f_config_result == BLL_IMU_CONFIG_FAIL_FRONT_SIX_AXIS_GET_ID)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_SIX_AXIS_ID);
  437. if(f_config_result == BLL_IMU_CONFIG_FAIL_FRONT_MAG_GET_ID)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_MAG_ID);
  438. if(f_config_result == BLL_IMU_CONFIG_FAIL_FRONT_MAG)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_MAG);
  439. if(f_config_result == BLL_IMU_CONFIG_FAIL_FRONT_SIX_AXIS)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_SIX_AXIS);
  440. }
  441. else
  442. {
  443. //配置没问题
  444. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_MAG);
  445. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_SIX_AXIS);
  446. if(ob_selfcheck.f_is_read_data != true)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_SIX_AXIS_NO_DATA);
  447. else
  448. {
  449. //数据没问题
  450. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_FRONT_SIX_AXIS_NO_DATA);
  451. ob_selfcheck.f_is_read_data = false;
  452. front_mag_norm = sqrt((double)(ob_selfcheck.f_data.mag[0]*ob_selfcheck.f_data.mag[0]) + (double)(ob_selfcheck.f_data.mag[1]*ob_selfcheck.f_data.mag[1]) + (double)(ob_selfcheck.f_data.mag[2]*ob_selfcheck.f_data.mag[2]));
  453. //前脚传感器地磁没焊接电容
  454. if(front_mag_norm < SELFCHECK_SENSOR_MAG_NO_WELDING_CAPACITOR_MIN_THRESHOLD)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_MAG_DATA_TO_SMALL);
  455. else ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_FRONT_MAG_DATA_TO_SMALL);
  456. }
  457. }
  458. //后脚传感器判断
  459. b_config_result = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_BACK,&game_bll_imu_param_t);
  460. if(b_config_result != BLL_IMU_CONFIG_FINISH)
  461. {
  462. if(b_config_result == BLL_IMU_CONFIG_FAIL_BACK_MAG_GET_ID)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BACK_SENSOR_CONFIG_ID);
  463. else ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BACK_SENSOR_CONFIG);
  464. }
  465. else
  466. {
  467. //配置没问题
  468. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_BACK_SENSOR_CONFIG);
  469. if(ob_selfcheck.b_is_read_data != true)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BACK_NO_DATA);
  470. else
  471. {
  472. //数据没问题
  473. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_BACK_NO_DATA);
  474. ob_selfcheck.b_is_read_data = false;
  475. back_mag_norm = sqrt((double)(ob_selfcheck.b_data.mag[0]*ob_selfcheck.b_data.mag[0]) + (double)(ob_selfcheck.b_data.mag[1]*ob_selfcheck.b_data.mag[1]) + (double)(ob_selfcheck.b_data.mag[2]*ob_selfcheck.b_data.mag[2]));
  476. //后脚传感器地磁没焊接电容
  477. if(back_mag_norm < SELFCHECK_SENSOR_MAG_NO_WELDING_CAPACITOR_MIN_THRESHOLD)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BACK_DATA_TO_SMALL);
  478. else ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_BACK_DATA_TO_SMALL);
  479. }
  480. }
  481. //任意传感器配置失败,重新配置
  482. if(f_config_result != BLL_IMU_CONFIG_FINISH || b_config_result != BLL_IMU_CONFIG_FINISH || ob_selfcheck.b_is_read_data != true || ob_selfcheck.f_is_read_data != true)
  483. {
  484. bll_imu_Resume_config_param(&game_bll_imu_param_t);
  485. }
  486. //更新计时-
  487. sensor_t_count = t_count;
  488. }
  489. //第二秒之后前后脚地磁检测抖动
  490. if(t_count > (2000/100))
  491. {
  492. front_mag_norm = sqrt((double)(ob_selfcheck.f_data.mag[0]*ob_selfcheck.f_data.mag[0]) + (double)(ob_selfcheck.f_data.mag[1]*ob_selfcheck.f_data.mag[1]) + (double)(ob_selfcheck.f_data.mag[2]*ob_selfcheck.f_data.mag[2]));
  493. back_mag_norm = sqrt((double)(ob_selfcheck.b_data.mag[0]*ob_selfcheck.b_data.mag[0]) + (double)(ob_selfcheck.b_data.mag[1]*ob_selfcheck.b_data.mag[1]) + (double)(ob_selfcheck.b_data.mag[2]*ob_selfcheck.b_data.mag[2]));
  494. if(front_mag_norm >= SELFCHECK_SENSOR_MAG_SHAKE_TRIGGER_THRESHOLD)
  495. {
  496. //get max
  497. front_mag_norm_max = (front_mag_norm_max > front_mag_norm)?front_mag_norm_max:front_mag_norm;
  498. //get min
  499. front_mag_norm_min = (front_mag_norm_min > front_mag_norm)?front_mag_norm:front_mag_norm_min;
  500. front_mag_shake_trigger = true;
  501. }
  502. if(back_mag_norm >= SELFCHECK_SENSOR_MAG_SHAKE_TRIGGER_THRESHOLD)
  503. {
  504. //get max
  505. back_mag_norm_max = (back_mag_norm_max > back_mag_norm)?back_mag_norm_max:back_mag_norm;
  506. //get min
  507. back_mag_norm_min = (back_mag_norm_min > back_mag_norm)?back_mag_norm:back_mag_norm_min;
  508. back_mag_shake_trigger = true;
  509. }
  510. // SEGGER_RTT_printf(0,"front_mag_norm_max:%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",front_mag_norm,back_mag_norm,front_mag_norm_max,back_mag_norm_max, \
  511. // front_mag_norm_min,back_mag_norm_min,front_mag_norm_max - front_mag_norm_min, \
  512. // back_mag_norm_max - back_mag_norm_min,front_mag_shake_trigger,back_mag_shake_trigger);
  513. if(t_count >= (3000/100))
  514. {
  515. if(front_mag_norm_max - front_mag_norm_min >= SELFCHECK_SENSOR_MAG_SHAKE_THRESHOLD && front_mag_shake_trigger)
  516. {
  517. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_MAG_DATA_SHAKE);
  518. }
  519. if(back_mag_norm_max - back_mag_norm_min >= SELFCHECK_SENSOR_MAG_SHAKE_THRESHOLD && back_mag_shake_trigger)
  520. {
  521. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BACK_DATA_SHAKE);
  522. }
  523. }
  524. }
  525. //第3秒获取前脚是否装反
  526. if(t_count == (3000/100) && ob_selfcheck.order == 0x52)
  527. {
  528. roll = (int16_t)(Self_Front_Mahony.roll*100);
  529. if(roll < 0)roll *= -1;
  530. roll = (roll > 0 && roll < 100)?1:roll/100;
  531. if(!(roll >=SELFCHECK_MIDDLE_ACC_CONS_ROLL_MIN_THRESHOLD && roll <= SELFCHECK_MIDDLE_ACC_CONS_ROLL_MAX_THRESHOLD))
  532. {
  533. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_IMU_REVERSE);
  534. }
  535. // SEGGER_RTT_printf(0,"front roll:%d\r\n",roll);
  536. }
  537. //第3秒查看能否读取到任意广播名字,且最小的RSSI是否满足条件,设置自检结果。
  538. if(t_count == (3000/100))
  539. {
  540. if(SELFCHECK_SCAN_DEVICE_RSSI_MIN_THRESHOLD >= ob_selfcheck.max_rssi)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_RSSI);
  541. }
  542. //第3秒关闭100毫秒震动电机自检线程
  543. if(t_count == (3000/100))
  544. {
  545. Process_Stop(selfcheck_mt_process);
  546. Process_Stop(selfcheck_led_process);
  547. WS2812_DisplayDot(COLOR_BLACK);WS2812_Pwm_Play();
  548. nrf_gpio_pin_write(PIN_MT_EN,0);
  549. }
  550. //第3+SELFCHECK_LED_DISPLAY_CYCLE_THRESHOLD秒初始化自检显示结果线程,设置holdon,全功率运行。
  551. if(t_count == ((3000 + SELFCHECK_LED_DISPLAY_CYCLE_THRESHOLD)/100))
  552. {
  553. //根据自检结果设置灯
  554. if(ob_selfcheck.selfcheck_result == 0)
  555. {
  556. front_mag_norm = sqrt((double)(ob_selfcheck.f_data.mag[0]*ob_selfcheck.f_data.mag[0]) + (double)(ob_selfcheck.f_data.mag[1]*ob_selfcheck.f_data.mag[1]) + (double)(ob_selfcheck.f_data.mag[2]*ob_selfcheck.f_data.mag[2]));
  557. if(SELFCHECK_WEAR_INSOLE_MAG_NORM_MIN_THRESHOLD <= front_mag_norm)
  558. {
  559. ob_selfcheck.selfcheck_result_led_color = COLOR_GREEN;
  560. ob_selfcheck.selfcheck_result_flash_num = 1;
  561. }
  562. else
  563. {
  564. ob_selfcheck.selfcheck_result_led_color = COLOR_CYAN;
  565. ob_selfcheck.selfcheck_result_flash_num = 1;
  566. }
  567. }
  568. else
  569. {
  570. ob_selfcheck.selfcheck_result_led_color = COLOR_RED;
  571. for(int i=0;i<sizeof(ob_selfcheck.selfcheck_result)*8;i++)
  572. {
  573. if((ob_selfcheck.selfcheck_result & (1 << i)) != 0)
  574. {
  575. ob_selfcheck.selfcheck_result_flash_num = i;
  576. break;
  577. }
  578. }
  579. }
  580. Process_Start(SELFCHECK_LED_DISPLAY_CYCLE_THRESHOLD,"selfcheck_result_display_process",selfcheck_result_display_process);
  581. Process_SetHoldOn(selfcheck_result_display_process,1);
  582. }
  583. //上报中间传感器的加速度值和roll值
  584. L=0;
  585. int16_t rol = (int16_t)(Mahony_M_GetRoll()*100);
  586. int16_t pitch = (int16_t)(Mahony_M_GetPitch()*100);
  587. int16_t yaw = (int16_t)(Mahony_M_GetYaw()*100);
  588. buf[L++] = (uint8_t)(rol>>8);
  589. buf[L++] = (uint8_t)(rol>>0);
  590. buf[L++] = (uint8_t)(pitch>>8);
  591. buf[L++] = (uint8_t)(pitch>>0);
  592. buf[L++] = (uint8_t)(yaw>>8);
  593. buf[L++] = (uint8_t)(yaw>>0);
  594. buf[L++] = 0;
  595. buf[L++] = 0;
  596. buf[L++] = 0;
  597. buf[L++] = 0;
  598. buf[L++] = 0;
  599. buf[L++] = 0;
  600. buf[L++] = 0;
  601. Mahony_send_ANO(0x01,buf,L);
  602. L=0;
  603. int32_t middle_acc_x = ob_selfcheck.m_data.acc[2];
  604. int32_t middle_acc_y = ob_selfcheck.m_data.acc[1];
  605. int16_t middle_acc_z = ob_selfcheck.m_data.acc[0];
  606. middle_acc_x *= 100;
  607. middle_acc_y *= 100;
  608. middle_acc_z *= 10;
  609. buf[L++] = (uint8_t)(middle_acc_x>>24);
  610. buf[L++] = (uint8_t)(middle_acc_x>>16);
  611. buf[L++] = (uint8_t)(middle_acc_x>>8);
  612. buf[L++] = (uint8_t)(middle_acc_x>>0);
  613. buf[L++] = (uint8_t)(middle_acc_y>>24);
  614. buf[L++] = (uint8_t)(middle_acc_y>>16);
  615. buf[L++] = (uint8_t)(middle_acc_y>>8);
  616. buf[L++] = (uint8_t)(middle_acc_y>>0);
  617. buf[L++] = (uint8_t)(middle_acc_z>>8);
  618. buf[L++] = (uint8_t)(middle_acc_z>>0);
  619. Mahony_send_ANO(0x07,buf,L);
  620. //上报前脚传感器的加速度数据、陀螺仪数据、地磁计开平方和数据
  621. //上报后脚传感器的地磁计开平方和数据
  622. //上报扫描到的任意广播的rssi值
  623. if(TIME_GetTicks()-last_tim >= 1000)
  624. {
  625. last_tim = TIME_GetTicks();
  626. ob_selfcheck.max_rssi = -120;
  627. }
  628. L=0;
  629. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[0]>>8);
  630. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[0]>>0);
  631. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[1]>>8);
  632. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[1]>>0);
  633. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[2]>>8);
  634. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[2]>>0);
  635. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[0]>>8);
  636. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[0]>>0);
  637. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[1]>>8);
  638. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[1]>>0);
  639. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[2]>>8);
  640. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[2]>>0);
  641. front_mag_norm = sqrt((double)(ob_selfcheck.f_data.mag[0]*ob_selfcheck.f_data.mag[0]) + (double)(ob_selfcheck.f_data.mag[1]*ob_selfcheck.f_data.mag[1]) + (double)(ob_selfcheck.f_data.mag[2]*ob_selfcheck.f_data.mag[2]));
  642. back_mag_norm = sqrt((double)(ob_selfcheck.b_data.mag[0]*ob_selfcheck.b_data.mag[0]) + (double)(ob_selfcheck.b_data.mag[1]*ob_selfcheck.b_data.mag[1]) + (double)(ob_selfcheck.b_data.mag[2]*ob_selfcheck.b_data.mag[2]));
  643. buf[L++] = (uint8_t)(front_mag_norm>>8);
  644. buf[L++] = (uint8_t)(front_mag_norm>>0);
  645. buf[L++] = (uint8_t)(back_mag_norm>>8);
  646. buf[L++] = (uint8_t)(back_mag_norm>>0);
  647. buf[L++] = (uint8_t)(ob_selfcheck.max_rssi>> 8);
  648. buf[L++] = (uint8_t)(ob_selfcheck.max_rssi>>0);
  649. Mahony_send_ANO(0x02,buf,L);
  650. fml_adc_get_value(PIN_CHARGING_CHANNEL,&adc_value);
  651. if(adc_value >= 2000)
  652. {
  653. if(continue_trigger <= 50)continue_trigger++;
  654. }
  655. else
  656. {
  657. if(continue_trigger != 0)continue_trigger--;
  658. }
  659. // SEGGER_RTT_printf(0,"continue_trigger:%d,%d\r\n",continue_trigger,adc_value);
  660. // SEGGER_RTT_printf(0,"front mag:%d,%d,%d,%d\r\n",ob_selfcheck.f_data.mag[0],ob_selfcheck.f_data.mag[1],ob_selfcheck.f_data.mag[2],front_mag_norm);
  661. // SEGGER_RTT_printf(0,"back mag:%d,%d,%d,%d\r\n",ob_selfcheck.b_data.mag[0],ob_selfcheck.b_data.mag[1],ob_selfcheck.b_data.mag[2],back_mag_norm);
  662. //第30秒重启
  663. if(t_count >= (30000/100) && !slave_isconnect() && continue_trigger==0)
  664. {
  665. memset(mac_buf, 0, sizeof(mac_buf));
  666. sprintf(mac_buf, "%02X%02X%02X%02X%02X%02X", mFlash.macHost[0], mFlash.macHost[1], mFlash.macHost[2], mFlash.mClient.macAddr[3], mFlash.mClient.macAddr[4], mFlash.mClient.macAddr[5]);
  667. ST_scan_stop();
  668. host_set_scan_name(mac_buf, strlen(mac_buf));
  669. Flash_DeleteAllInfor();
  670. Flash_DeleteAllStep();
  671. Flash_DeleteAllBackup();
  672. //恢复出厂信息
  673. memset(&mFlash,0xFF,sizeof(mFlash));
  674. memset(&mBackup,0xFF,sizeof(mBackup));
  675. //保存数据到flash
  676. if(Flash_SaveStep() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_Power,"save step fail");
  677. extern battercb_t battery_record;
  678. // extern void printbatter_cb(battercb_t *c,unsigned char *buff);
  679. memcpy(&mFlash.mbattercb_t,&battery_record,sizeof(battercb_t));
  680. mBackup.RestartCnt =0;
  681. if(Flash_SaveBackup() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_Power,"pwr save backup fail");
  682. if(Flash_SaveInfomation() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_Power,"pwr save information fail");
  683. NVIC_SystemReset();
  684. }
  685. }
  686. static void adc_callback(uint32_t sample_point, Fml_Adc_All_Channel_Adc_Value_t all_adc_value)
  687. {
  688. //纯粹做覆盖
  689. }
  690. /*API ------------------------------------------------------------------------------------------------------------------------------------*/
  691. /**
  692. @brief 自检触发回调
  693. @param order - [in] 回调触发的指令
  694. @return 无
  695. */
  696. void selfcheck_trigger_callback(char order)
  697. {
  698. int error;
  699. uint32_t last_tim = TIME_GetTicks();
  700. //喂狗
  701. feed_watchdog();
  702. //初始化结构体,自检结果为成功
  703. memset(&ob_selfcheck,0,sizeof(ob_selfcheck));
  704. ob_selfcheck.max_rssi = -120;
  705. ob_selfcheck.selfcheck_result = SELFCHECK_RESULT_SUCCESS;
  706. ob_selfcheck.selfcheck_result_led_color = COLOR_BLACK;
  707. ob_selfcheck.f_is_read_data = false;
  708. ob_selfcheck.b_is_read_data = false;
  709. ob_selfcheck.order = order;
  710. //关闭所有线程,初始化0毫秒自检线程,设置holdon,全功率运行。
  711. Process_All_Stop();
  712. Process_Start(100,"selfcheck_process",selfcheck_process);
  713. Process_SetHoldOn(selfcheck_process,1);
  714. //关闭扫描,设置任意设备扫描回调,开启扫描
  715. while(TIME_GetTicks() - last_tim <= 1000)
  716. {
  717. host_disconnect();
  718. if(host_isconnect() == 0)break;
  719. }
  720. nrf_ble_scan_stop();
  721. host_set_scan_name((char *)"***********",sizeof("***********"));
  722. advdata_report_Evt_Regist(scan_report_cb);
  723. error = ST_scan_start();
  724. if(error != APP_SUCCESS)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_RSSI);
  725. //配置LED电源引脚为输出SOD1
  726. nrf_gpio_cfg(
  727. PIN_LED_ENABLE,
  728. NRF_GPIO_PIN_DIR_OUTPUT,
  729. NRF_GPIO_PIN_INPUT_DISCONNECT,
  730. NRF_GPIO_PIN_NOPULL,
  731. NRF_GPIO_PIN_S0D1,
  732. NRF_GPIO_PIN_NOSENSE);
  733. //配置震动电机引脚为输出SOS1
  734. nrf_gpio_cfg_output(PIN_MT_EN);
  735. nrf_gpio_pin_write(PIN_MT_EN,0);
  736. //配置led灯电源引脚为输出
  737. nrf_gpio_pin_write(PIN_LED_ENABLE,LED_ENABLE);
  738. //重新初始化ADC,配置所有通道。
  739. ADC_SetPinChannel(PIN_ADC_CHARGMEASURE, PIN_ADC_CHARGMEASURE_CHANNEL,NRF_GPIO_PIN_NOPULL);
  740. ADC_SetPinChannel(PIN_ADC_BAT_IN, PIN_ADC_BAT_CHANNEL,NRF_GPIO_PIN_NOPULL);
  741. ADC_SetPinChannel(PIN_CHARGING, PIN_CHARGING_CHANNEL,NRF_GPIO_PIN_NOPULL);
  742. fml_adc_sample_update_notify_register(adc_callback);
  743. //配置前脚传感器、中间传感器、后脚传感器
  744. bll_imu_Init();
  745. bll_imu_register_data_notify_callback(BLL_IMU_DATA_NOTIFY_CB_PRIORITY_1, fb_data_notify_cb);
  746. bll_imu_Resume_config_param(&game_bll_imu_param_t);
  747. error = drv_qma_Init();
  748. if(error == -1)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_MIDDLE_SENSOR_CONFIG);
  749. nrf_delay_ms(20);
  750. error = drv_qma_set_acc_odr(QMA_ACC_ODR_104HZ);
  751. if(error == -1)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_MIDDLE_SENSOR_CONFIG);
  752. //初始化震动电机自检线程
  753. Process_Start(0,"selfcheck_mt_process",selfcheck_mt_process);
  754. Process_SetHoldOn(selfcheck_mt_process,1);
  755. //初始化LED自检线程
  756. Process_Start(SELFCHECK_LED_DISPLAY_CYCLE_THRESHOLD,"selfcheck_led_process",selfcheck_led_process);
  757. Process_SetHoldOn(selfcheck_led_process,1);
  758. //初始化计算roll值算法
  759. Mahony_Init(&Self_Mind_Mahony,104);
  760. Mahony_Init(&Self_Front_Mahony,416);
  761. //喂狗
  762. feed_watchdog();
  763. }