selfcheck.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  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. /*STRUCTION ------------------------------------------------------------------------------------------------------------------------------------*/
  35. typedef enum {
  36. SELFCHECK_RESULT_SUCCESS = 0, //自检成功
  37. SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_SIX_AXIS, //自检失败——前脚传感器配置六轴
  38. SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_MAG, //自检失败——前脚传感器配置地磁
  39. SELFCHECK_RESULT_ERR_FRONT_SIX_AXIS_NO_DATA_OR_EXCP_DATA, //自检失败——前脚传感器六轴没数据或数据异常
  40. SELFCHECK_RESULT_ERR_FRONT_MAG_NO_DATA_OR_EXCP_DATA, //自检失败——前脚传感器地磁没数据或数据异常
  41. SELFCHECK_RESULT_ERR_BACK_SENSOR_CONFIG, //自检失败——后脚传感器配置
  42. SELFCHECK_RESULT_ERR_BACK_NO_DATA_OR_EXCP_DATA, //自检失败——后脚传感器没数据或数据异常
  43. SELFCHECK_RESULT_ERR_MIDDLE_SENSOR_CONFIG, //自检失败——中间传感器配置
  44. SELFCHECK_RESULT_ERR_MIDDLE_NO_DATA_OR_EXCP_DATA, //自检失败——中间传感器没数据或数据异常
  45. SELFCHECK_RESULT_ERR_CHARGE_CHIP_PIN_ADC, //自检失败——充电芯片引脚ADC
  46. SELFCHECK_RESULT_ERR_BATTERY_PIN_ADC, //自检失败——电池分压电阻ADC
  47. SELFCHECK_RESULT_ERR_RSSI, //自检失败——RSSI
  48. } SELFCHECK_RESULT_e;
  49. typedef struct _selfcheck
  50. {
  51. uint32_t selfcheck_result; //自检结果
  52. uint32_t selfcheck_result_led_color; //自检结果的led灯颜色
  53. uint32_t selfcheck_result_flash_num; //自检结果闪烁次数
  54. bool selfcheck_is_led_display; //自检结果led灯是否显示中
  55. int16_t max_rssi; //最大的RSSI值
  56. fml_imu_data_t f_data; //前脚传感器数据
  57. fml_imu_data_t b_data; //后脚传感器数据
  58. qma_data_t m_data; //中间传感器数据
  59. bool f_is_read_data; //前脚传感器是否读到数据标志位
  60. bool b_is_read_data; //后脚传感器是否读到数据标志位
  61. } SelfCheck_t;
  62. /*Local Variable ------------------------------------------------------------------------------------------------------------------------------------*/
  63. static SelfCheck_t ob_selfcheck;
  64. static const bll_imu_one_way_param_t game_front_param={
  65. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //前脚 - 加速度正常模式
  66. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //前脚 - 陀螺仪正常模式
  67. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //前脚 - 时间戳25US精度
  68. .timestamp_switch = FML_IMU_TIMESTAMP_ON, //前脚 - 时间戳开启
  69. .acc_fs = FML_IMU_ACC_FS_16G, //前脚 - 加速度量程 - 16G
  70. .gry_fs = FML_IMU_GRY_FS_2000DPS, //前脚 - 陀螺仪量程 - 2000DPS
  71. .mag_fs = FML_IMU_MAG_FS_30GS, //前脚 - 地磁计量程 - 30GS
  72. .acc_odr = FML_IMU_ACC_ODR_416HZ, //前脚 - 加速度采样频率 - 104HZ
  73. .gry_odr = FML_IMU_GRY_ODR_416HZ, //前脚 - 陀螺仪采样频率 - 104HZ
  74. .mag_odr = FML_IMU_MAG_ODR_200HZ, //前脚 - 地磁计采样频率 - 200HZ
  75. .fifo_odr = FML_IMU_FIFO_ODR_416HZ,
  76. };
  77. static const bll_imu_one_way_param_t game_back_param={
  78. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //后脚 - 加速度正常模式
  79. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //后脚 - 陀螺仪正常模式
  80. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //后脚 - 时间戳25US精度
  81. .timestamp_switch = FML_IMU_TIMESTAMP_OFF, //后脚 - 时间戳关闭
  82. .acc_fs = FML_IMU_ACC_FS_16G, //后脚 - 加速度量程 - 16G
  83. .gry_fs = FML_IMU_GRY_FS_2000DPS, //后脚 - 陀螺仪量程 - 2000DPS
  84. .mag_fs = FML_IMU_MAG_FS_30GS, //后脚 - 地磁计量程 - 30GS
  85. .acc_odr = FML_IMU_ACC_ODR_OFF, //后脚 - 加速度采样频率 - 关闭
  86. .gry_odr = FML_IMU_GRY_ODR_OFF, //后脚 - 陀螺仪采样频率 - 关闭
  87. .mag_odr = FML_IMU_MAG_ODR_200HZ, //后脚 - 地磁计采样频率 - 200HZ
  88. .fifo_odr = FML_IMU_FIFO_ODR_OFF,
  89. };
  90. static const bll_imu_param_t game_bll_imu_param_t={
  91. .config_param[FML_IMU_DIR_FRONT] = &game_front_param,
  92. .config_param[FML_IMU_DIR_BACK] = &game_back_param,
  93. };
  94. /*Local Functions ------------------------------------------------------------------------------------------------------------------------------------*/
  95. static void fb_data_notify_cb(uint32_t dir_bit)
  96. {
  97. int data_len;
  98. if((dir_bit >> BLL_IMU_DIR_FRONT) & 0x01)
  99. {
  100. memset(&ob_selfcheck.f_data,0,sizeof(ob_selfcheck.f_data));
  101. data_len = bll_imu_get_data_num(BLL_IMU_DIR_FRONT);
  102. for(int i=0; i<data_len;i++)
  103. {
  104. bll_imu_get_data(BLL_IMU_DIR_FRONT, i, &ob_selfcheck.f_data);
  105. }
  106. }
  107. if((dir_bit >> BLL_IMU_DIR_BACK) & 0x01)
  108. {
  109. memset(&ob_selfcheck.b_data,0,sizeof(ob_selfcheck.b_data));
  110. data_len = bll_imu_get_data_num(BLL_IMU_DIR_BACK);
  111. for(int i=0; i<data_len;i++)
  112. {
  113. bll_imu_get_data(BLL_IMU_DIR_BACK, i, &ob_selfcheck.b_data);
  114. }
  115. }
  116. if(((dir_bit >> BLL_IMU_DIR_FRONT) & 0x01))
  117. {
  118. ob_selfcheck.f_is_read_data = true;
  119. }
  120. if((dir_bit >> BLL_IMU_DIR_BACK))
  121. {
  122. ob_selfcheck.b_is_read_data = true;
  123. }
  124. }
  125. static void scan_report_cb(uint8_t *adv_data, uint16_t adv_data_len,int8_t rssi)
  126. {
  127. ob_selfcheck.max_rssi = (ob_selfcheck.max_rssi > rssi)?ob_selfcheck.max_rssi:rssi;
  128. }
  129. static void selfcheck_led_display_process(void)
  130. {
  131. static uint32_t cur_flash_num = 0;
  132. static uint8_t level = LED_ENABLE;
  133. static uint8_t red_off_led_count = 0;
  134. static uint32_t tim = 0;
  135. //喂狗
  136. feed_watchdog();
  137. //led display
  138. if(ob_selfcheck.selfcheck_is_led_display == true)
  139. {
  140. if(cur_flash_num == 0)tim = TIME_GetTicks();
  141. //判断是否结束
  142. if(level == LED_ENABLE)cur_flash_num++;
  143. if(cur_flash_num > ob_selfcheck.selfcheck_result_flash_num)
  144. {
  145. nrf_gpio_pin_write(PIN_LED_ENABLE,LED_DISABLE);
  146. if(ob_selfcheck.selfcheck_result_led_color == COLOR_RED && (TIME_GetTicks() - tim < 5000))return;
  147. cur_flash_num = 0;
  148. level = LED_ENABLE;
  149. red_off_led_count = 0;
  150. ob_selfcheck.selfcheck_is_led_display = false;
  151. Process_Stop(selfcheck_led_display_process);
  152. return;
  153. }
  154. if(ob_selfcheck.selfcheck_result_led_color == COLOR_RED)
  155. {
  156. Process_Start(50,"selfcheck_led_display_process",selfcheck_led_display_process);
  157. nrf_gpio_pin_write(PIN_LED_ENABLE,level);nrf_delay_ms(5);
  158. if(level == LED_ENABLE){WS2812_DisplayDot(ob_selfcheck.selfcheck_result_led_color);WS2812_Pwm_Play();}
  159. }
  160. else
  161. {
  162. Process_Start(500,"selfcheck_led_display_process",selfcheck_led_display_process);
  163. nrf_gpio_pin_write(PIN_LED_ENABLE,level);nrf_delay_ms(5);
  164. if(level == LED_ENABLE){WS2812_DisplayDot(ob_selfcheck.selfcheck_result_led_color);WS2812_Pwm_Play();}
  165. }
  166. //周期翻转
  167. if(ob_selfcheck.selfcheck_result_led_color == COLOR_RED)
  168. {
  169. if(level == LED_ENABLE){level = LED_DISABLE;red_off_led_count = 0;}
  170. if(level == LED_DISABLE){red_off_led_count++;if(red_off_led_count >= 6)level = LED_ENABLE;}
  171. }
  172. else
  173. {
  174. level = (level == LED_ENABLE)?LED_DISABLE:LED_ENABLE;
  175. }
  176. }
  177. }
  178. static void selfcheck_result_display_process(void)
  179. {
  180. uint16_t front_mag_norm;
  181. //喂狗
  182. feed_watchdog();
  183. if(ob_selfcheck.selfcheck_is_led_display == false)
  184. {
  185. //根据自检结果显示结果:
  186. //前脚传感器——红色(前脚六轴配置问题闪烁1下,前脚地磁配置问题闪烁2下,前脚六轴数据读取失败或数据异常闪烁3下,前脚地磁数据读取失败或数据异常闪烁4下)
  187. //后脚传感器——红色(后脚地磁配置问题闪烁5下,后脚地磁数据读取失败或数据异常闪烁6下)
  188. //中间传感器——红色(中间加速度配置问题闪烁7下,加速度roll值不在范围内闪烁8下)
  189. //充电芯片和电池分压电阻和蓝牙天线rssi——红色(充电芯片问题闪烁9下,电池分压电阻闪烁10下,蓝牙天线rssi问题闪烁11下)
  190. //中间加速度检测震动电机(待定)
  191. //上述检测通过,蓝色(1秒周期,500ms亮,500ms灭(断电源线)),若检测到鞋垫,则绿色(1秒周期,500ms亮,500ms灭(断电源线))。
  192. //LED电源引脚亮灯拉高,灭灯拉低。(4秒周期,40ms亮,160ms灭(断电源线)一组)
  193. //获取颜色+闪烁次数+周期
  194. if(ob_selfcheck.selfcheck_result == 0)
  195. {
  196. 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]));
  197. if(SELFCHECK_WEAR_INSOLE_MAG_NORM_MIN_THRESHOLD <= front_mag_norm)
  198. {
  199. ob_selfcheck.selfcheck_result_led_color = COLOR_GREEN;
  200. ob_selfcheck.selfcheck_result_flash_num = 1;
  201. }
  202. else
  203. {
  204. ob_selfcheck.selfcheck_result_led_color = COLOR_BLUE;
  205. ob_selfcheck.selfcheck_result_flash_num = 1;
  206. }
  207. }
  208. else
  209. {
  210. ob_selfcheck.selfcheck_result_led_color = COLOR_RED;
  211. for(int i=0;i<sizeof(ob_selfcheck.selfcheck_result)*8;i++)
  212. {
  213. if((ob_selfcheck.selfcheck_result & (1 << i)) != 0)
  214. {
  215. ob_selfcheck.selfcheck_result_flash_num = i;
  216. break;
  217. }
  218. }
  219. }
  220. Process_Start(0,"selfcheck_led_display_process",selfcheck_led_display_process);
  221. ob_selfcheck.selfcheck_is_led_display = true;
  222. }
  223. }
  224. static void selfcheck_mt_process(void)
  225. {
  226. //喂狗
  227. feed_watchdog();
  228. nrf_gpio_pin_toggle(PIN_MT_EN);
  229. }
  230. static MahonyAHRS_t Self_Mind_Mahony={0};
  231. static void selfcheck_process(void)
  232. {
  233. BLL_IMU_CONFIG_RESULT f_config_result,b_config_result;
  234. int16_t adc_value = 0;
  235. uint16_t front_mag_norm;
  236. uint16_t back_mag_norm;
  237. int16_t roll;
  238. uint8_t buf[256];
  239. uint8_t L=0;
  240. char mac_buf[16];
  241. static uint32_t charge_chip_adc_max = 0;
  242. static int16_t battery_adc_max = 0;
  243. static uint32_t t_count = 0;
  244. static uint32_t battery_adc_t_count = 0;
  245. static uint32_t roll_t_count = 0;
  246. static uint32_t sensor_t_count = 0;
  247. static uint32_t last_tim = 0;
  248. static uint32_t continue_trigger = 0;
  249. static uint32_t front_mag_norm_max = 0;
  250. static uint32_t back_mag_norm_max = 0;
  251. static uint32_t front_mag_norm_min = 0xffffffff;
  252. static uint32_t back_mag_norm_min = 0xffffffff;
  253. static bool front_mag_shake_trigger = false;
  254. static bool back_mag_shake_trigger = false;
  255. t_count++;
  256. //喂狗
  257. feed_watchdog();
  258. //读取中间传感器数据,计算加速度roll值
  259. memset(&ob_selfcheck.m_data,0,sizeof(ob_selfcheck.m_data));
  260. if(drv_qma_get_acc_data(&ob_selfcheck.m_data) != 0)
  261. {
  262. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_MIDDLE_NO_DATA_OR_EXCP_DATA);
  263. //重新配置
  264. drv_qma_set_acc_odr(QMA_ACC_ODR_104HZ);
  265. }
  266. 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);
  267. //筛选最大的电池分压后的电压
  268. fml_adc_get_value(PIN_ADC_BAT_CHANNEL,&adc_value);
  269. adc_value = ADC_RESULT_IN_MILLI_VOLTS(adc_value) * 5 / 3;
  270. battery_adc_max = adc_value;
  271. //每3秒读取ADC,以5V电压测试电池分压电阻是否焊接,不考虑阻值,设置自检结果。
  272. if(t_count - battery_adc_t_count > (3000/100))
  273. {
  274. 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);
  275. else ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_BATTERY_PIN_ADC);
  276. //更新计时
  277. battery_adc_t_count = t_count;
  278. }
  279. //充电芯片检测
  280. fml_adc_get_value(PIN_ADC_CHARGMEASURE_CHANNEL,&adc_value);
  281. if(SELFCHECK_CHARGE_CHIP_PIN_ADC_MIN_THRESHOLD < adc_value)
  282. {
  283. charge_chip_adc_max++;
  284. }
  285. if(charge_chip_adc_max > 10)
  286. {
  287. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_CHARGE_CHIP_PIN_ADC);
  288. }
  289. else
  290. {
  291. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_CHARGE_CHIP_PIN_ADC);
  292. }
  293. //每3秒检测加速度roll值,设置自检结果。
  294. if(t_count - roll_t_count > (3000/100))
  295. {
  296. roll = (int16_t)(Mahony_M_GetRoll()*100);
  297. if(roll < 0)roll *= -1;
  298. roll = (roll > 0 && roll < 100)?1:roll/100;
  299. if(!( \
  300. (SELFCHECK_MIDDLE_ACC_PROS_ROLL_MIN_THRESHOLD < roll && roll < SELFCHECK_MIDDLE_ACC_PROS_ROLL_MAX_THRESHOLD) || \
  301. (SELFCHECK_MIDDLE_ACC_CONS_ROLL_MIN_THRESHOLD < roll && roll < SELFCHECK_MIDDLE_ACC_CONS_ROLL_MAX_THRESHOLD) \
  302. ))ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_MIDDLE_NO_DATA_OR_EXCP_DATA);
  303. else
  304. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_MIDDLE_NO_DATA_OR_EXCP_DATA);
  305. //更新计时
  306. roll_t_count = t_count;
  307. }
  308. //每1秒查看前后传感器是否配置且读取成功(至少要1秒才有结果)且值本身是否正常(如地磁没有焊接电容),设置自检结果。
  309. if(t_count - sensor_t_count > (1000/100))
  310. {
  311. //前脚传感器判断
  312. f_config_result = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_FRONT,&game_bll_imu_param_t);
  313. if(f_config_result != BLL_IMU_CONFIG_FINISH)
  314. {
  315. if(f_config_result == BLL_IMU_CONFIG_FAIL_FRONT_MAG)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_MAG);
  316. if(f_config_result == BLL_IMU_CONFIG_FAIL_FRONT_SIX_AXIS)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_SIX_AXIS);
  317. }
  318. else
  319. {
  320. //配置没问题
  321. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_MAG);
  322. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_FRONT_SENSOR_CONFIG_SIX_AXIS);
  323. if(ob_selfcheck.f_is_read_data != true)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_SIX_AXIS_NO_DATA_OR_EXCP_DATA);
  324. else
  325. {
  326. //数据没问题
  327. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_FRONT_SIX_AXIS_NO_DATA_OR_EXCP_DATA);
  328. ob_selfcheck.f_is_read_data = false;
  329. 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]));
  330. //前脚传感器地磁没焊接电容
  331. if(front_mag_norm < SELFCHECK_SENSOR_MAG_NO_WELDING_CAPACITOR_MIN_THRESHOLD)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_MAG_NO_DATA_OR_EXCP_DATA);
  332. else ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_FRONT_MAG_NO_DATA_OR_EXCP_DATA);
  333. }
  334. }
  335. //后脚传感器判断
  336. b_config_result = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_BACK,&game_bll_imu_param_t);
  337. if(b_config_result != BLL_IMU_CONFIG_FINISH)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BACK_SENSOR_CONFIG);
  338. else
  339. {
  340. //配置没问题
  341. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_BACK_SENSOR_CONFIG);
  342. if(ob_selfcheck.b_is_read_data != true)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BACK_NO_DATA_OR_EXCP_DATA);
  343. else
  344. {
  345. //数据没问题
  346. ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_BACK_NO_DATA_OR_EXCP_DATA);
  347. ob_selfcheck.b_is_read_data = false;
  348. 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]));
  349. //后脚传感器地磁没焊接电容
  350. if(back_mag_norm < SELFCHECK_SENSOR_MAG_NO_WELDING_CAPACITOR_MIN_THRESHOLD)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BACK_NO_DATA_OR_EXCP_DATA);
  351. else ob_selfcheck.selfcheck_result &= ~(1 << SELFCHECK_RESULT_ERR_BACK_NO_DATA_OR_EXCP_DATA);
  352. }
  353. }
  354. //任意传感器配置失败,重新配置
  355. 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)
  356. {
  357. bll_imu_Resume_config_param(&game_bll_imu_param_t);
  358. }
  359. //更新计时
  360. sensor_t_count = t_count;
  361. }
  362. //fornt back mag data check shake
  363. if(t_count > (2000/100))
  364. {
  365. 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]));
  366. 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]));
  367. if(front_mag_norm >= SELFCHECK_SENSOR_MAG_SHAKE_TRIGGER_THRESHOLD)
  368. {
  369. //get max
  370. front_mag_norm_max = (front_mag_norm_max > front_mag_norm)?front_mag_norm_max:front_mag_norm;
  371. //get min
  372. front_mag_norm_min = (front_mag_norm_min > front_mag_norm)?front_mag_norm:front_mag_norm_min;
  373. front_mag_shake_trigger = true;
  374. }
  375. if(back_mag_norm >= SELFCHECK_SENSOR_MAG_SHAKE_TRIGGER_THRESHOLD)
  376. {
  377. //get max
  378. back_mag_norm_max = (back_mag_norm_max > back_mag_norm)?back_mag_norm_max:back_mag_norm;
  379. //get min
  380. back_mag_norm_min = (back_mag_norm_min > back_mag_norm)?back_mag_norm:back_mag_norm_min;
  381. back_mag_shake_trigger = true;
  382. }
  383. DEBUG_LOG("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, \
  384. front_mag_norm_min,back_mag_norm_min,front_mag_norm_max - front_mag_norm_min, \
  385. back_mag_norm_max - back_mag_norm_min,front_mag_shake_trigger,back_mag_shake_trigger);
  386. if(t_count >= (5000/100))
  387. {
  388. if(front_mag_norm_max - front_mag_norm_min >= SELFCHECK_SENSOR_MAG_SHAKE_THRESHOLD && front_mag_shake_trigger)
  389. {
  390. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_FRONT_MAG_NO_DATA_OR_EXCP_DATA);
  391. }
  392. if(back_mag_norm_max - back_mag_norm_min >= SELFCHECK_SENSOR_MAG_SHAKE_THRESHOLD && back_mag_shake_trigger)
  393. {
  394. ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_BACK_NO_DATA_OR_EXCP_DATA);
  395. }
  396. }
  397. }
  398. //第5秒查看能否读取到任意广播名字,且最小的RSSI是否满足条件,设置自检结果。
  399. if(t_count == (5000/100))
  400. {
  401. if(SELFCHECK_SCAN_DEVICE_RSSI_MIN_THRESHOLD >= ob_selfcheck.max_rssi)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_RSSI);
  402. }
  403. //第5秒关闭100毫秒震动电机自检线程,初始化40毫秒自检显示结果线程,设置holdon,全功率运行。
  404. if(t_count == (5000/100))
  405. {
  406. nrf_gpio_pin_write(PIN_MT_EN,0);
  407. Process_Stop(selfcheck_mt_process);
  408. Process_Start(0,"selfcheck_result_display_process",selfcheck_result_display_process);
  409. Process_SetHoldOn(selfcheck_result_display_process,1);
  410. }
  411. //上报中间传感器的加速度值和roll值
  412. L=0;
  413. int16_t rol = (int16_t)(Mahony_M_GetRoll()*100);
  414. int16_t pitch = (int16_t)(Mahony_M_GetPitch()*100);
  415. int16_t yaw = (int16_t)(Mahony_M_GetYaw()*100);
  416. buf[L++] = (uint8_t)(rol>>8);
  417. buf[L++] = (uint8_t)(rol>>0);
  418. buf[L++] = (uint8_t)(pitch>>8);
  419. buf[L++] = (uint8_t)(pitch>>0);
  420. buf[L++] = (uint8_t)(yaw>>8);
  421. buf[L++] = (uint8_t)(yaw>>0);
  422. buf[L++] = 0;
  423. buf[L++] = 0;
  424. buf[L++] = 0;
  425. buf[L++] = 0;
  426. buf[L++] = 0;
  427. buf[L++] = 0;
  428. buf[L++] = 0;
  429. Mahony_send_ANO(0x01,buf,L);
  430. L=0;
  431. int32_t middle_acc_x = ob_selfcheck.m_data.acc[0];
  432. int32_t middle_acc_y = ob_selfcheck.m_data.acc[1];
  433. int16_t middle_acc_z = ob_selfcheck.m_data.acc[2];
  434. middle_acc_x *= 100;
  435. middle_acc_y *= 100;
  436. middle_acc_z *= 10;
  437. buf[L++] = (uint8_t)(middle_acc_x>>24);
  438. buf[L++] = (uint8_t)(middle_acc_x>>16);
  439. buf[L++] = (uint8_t)(middle_acc_x>>8);
  440. buf[L++] = (uint8_t)(middle_acc_x>>0);
  441. buf[L++] = (uint8_t)(middle_acc_y>>24);
  442. buf[L++] = (uint8_t)(middle_acc_y>>16);
  443. buf[L++] = (uint8_t)(middle_acc_y>>8);
  444. buf[L++] = (uint8_t)(middle_acc_y>>0);
  445. buf[L++] = (uint8_t)(middle_acc_z>>8);
  446. buf[L++] = (uint8_t)(middle_acc_z>>0);
  447. Mahony_send_ANO(0x07,buf,L);
  448. //上报前脚传感器的加速度数据、陀螺仪数据、地磁计开平方和数据
  449. //上报后脚传感器的地磁计开平方和数据
  450. //上报扫描到的任意广播的rssi值
  451. if(TIME_GetTicks()-last_tim >= 1000)
  452. {
  453. last_tim = TIME_GetTicks();
  454. ob_selfcheck.max_rssi = -120;
  455. }
  456. L=0;
  457. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[0]>>8);
  458. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[0]>>0);
  459. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[1]>>8);
  460. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[1]>>0);
  461. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[2]>>8);
  462. buf[L++] = (uint8_t)(ob_selfcheck.f_data.acc[2]>>0);
  463. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[0]>>8);
  464. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[0]>>0);
  465. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[1]>>8);
  466. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[1]>>0);
  467. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[2]>>8);
  468. buf[L++] = (uint8_t)(ob_selfcheck.f_data.gry[2]>>0);
  469. 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]));
  470. 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]));
  471. buf[L++] = (uint8_t)(front_mag_norm>>8);
  472. buf[L++] = (uint8_t)(front_mag_norm>>0);
  473. buf[L++] = (uint8_t)(back_mag_norm>>8);
  474. buf[L++] = (uint8_t)(back_mag_norm>>0);
  475. buf[L++] = (uint8_t)(ob_selfcheck.max_rssi>> 8);
  476. buf[L++] = (uint8_t)(ob_selfcheck.max_rssi>>0);
  477. Mahony_send_ANO(0x02,buf,L);
  478. fml_adc_get_value(PIN_CHARGING_CHANNEL,&adc_value);
  479. if(adc_value >= 2000)
  480. {
  481. if(continue_trigger <= 50)continue_trigger++;
  482. }
  483. else
  484. {
  485. if(continue_trigger != 0)continue_trigger--;
  486. }
  487. //第30秒重启
  488. if(t_count >= (30000/100) && !slave_isconnect() && continue_trigger==0)
  489. {
  490. memset(mac_buf, 0, sizeof(mac_buf));
  491. 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]);
  492. ST_scan_stop();
  493. host_set_scan_name(mac_buf, strlen(mac_buf));
  494. //保存数据到flash
  495. if(Flash_SaveStep() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_Power,"save step fail");
  496. extern battercb_t battery_record;
  497. // extern void printbatter_cb(battercb_t *c,unsigned char *buff);
  498. memcpy(&mFlash.mbattercb_t,&battery_record,sizeof(battercb_t));
  499. mBackup.RestartCnt =0;
  500. if(Flash_SaveBackup() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_Power,"pwr save backup fail");
  501. if(Flash_SaveInfomation() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_Power,"pwr save information fail");
  502. NVIC_SystemReset();
  503. }
  504. }
  505. static void adc_callback(uint32_t sample_point, Fml_Adc_All_Channel_Adc_Value_t all_adc_value)
  506. {
  507. //纯粹做覆盖
  508. }
  509. /*API ------------------------------------------------------------------------------------------------------------------------------------*/
  510. /**
  511. @brief 自检触发回调
  512. @param order - [in] 回调触发的指令
  513. @return 无
  514. */
  515. void selfcheck_trigger_callback(char order)
  516. {
  517. int error;
  518. uint32_t last_tim = TIME_GetTicks();
  519. //喂狗
  520. feed_watchdog();
  521. //初始化结构体,自检结果为成功
  522. memset(&ob_selfcheck,0,sizeof(ob_selfcheck));
  523. ob_selfcheck.max_rssi = -120;
  524. ob_selfcheck.selfcheck_result = SELFCHECK_RESULT_SUCCESS;
  525. ob_selfcheck.selfcheck_result_led_color = COLOR_BLACK;
  526. ob_selfcheck.f_is_read_data = false;
  527. ob_selfcheck.b_is_read_data = false;
  528. ob_selfcheck.selfcheck_is_led_display = false;
  529. //关闭所有线程,初始化0毫秒自检线程,设置holdon,全功率运行。
  530. Process_All_Stop();
  531. Process_Start(100,"selfcheck_process",selfcheck_process);
  532. Process_SetHoldOn(selfcheck_process,1);
  533. //关闭扫描,设置任意设备扫描回调,开启扫描
  534. while(TIME_GetTicks() - last_tim <= 1000)
  535. {
  536. host_disconnect();
  537. if(host_isconnect() == 0)break;
  538. }
  539. ST_scan_stop();
  540. host_set_scan_name((char *)"***********",sizeof("***********"));
  541. advdata_report_Evt_Regist(scan_report_cb);
  542. error = ST_scan_start();
  543. if(error != APP_SUCCESS)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_RSSI);
  544. //配置LED电源引脚为输出SOD1
  545. nrf_gpio_cfg(
  546. PIN_LED_ENABLE,
  547. NRF_GPIO_PIN_DIR_OUTPUT,
  548. NRF_GPIO_PIN_INPUT_DISCONNECT,
  549. NRF_GPIO_PIN_NOPULL,
  550. NRF_GPIO_PIN_S0D1,
  551. NRF_GPIO_PIN_NOSENSE);
  552. //配置震动电机引脚为输出SOS1
  553. nrf_gpio_cfg_output(PIN_MT_EN);
  554. nrf_gpio_pin_write(PIN_MT_EN,0);
  555. //重新初始化ADC,配置所有通道。
  556. ADC_SetPinChannel(PIN_ADC_CHARGMEASURE, PIN_ADC_CHARGMEASURE_CHANNEL,NRF_GPIO_PIN_NOPULL);
  557. ADC_SetPinChannel(PIN_ADC_BAT_IN, PIN_ADC_BAT_CHANNEL,NRF_GPIO_PIN_NOPULL);
  558. ADC_SetPinChannel(PIN_CHARGING, PIN_CHARGING_CHANNEL,NRF_GPIO_PIN_NOPULL);
  559. fml_adc_sample_update_notify_register(adc_callback);
  560. //配置前脚传感器、中间传感器、后脚传感器
  561. bll_imu_Init();
  562. bll_imu_register_data_notify_callback(BLL_IMU_DATA_NOTIFY_CB_PRIORITY_1, fb_data_notify_cb);
  563. bll_imu_Resume_config_param(&game_bll_imu_param_t);
  564. error = drv_qma_Init();
  565. if(error == -1)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_MIDDLE_SENSOR_CONFIG);
  566. nrf_delay_ms(20);
  567. error = drv_qma_set_acc_odr(QMA_ACC_ODR_104HZ);
  568. if(error == -1)ob_selfcheck.selfcheck_result |= (1 << SELFCHECK_RESULT_ERR_MIDDLE_SENSOR_CONFIG);
  569. //初始化500ms震动电机自检线程,拉高震动电机引脚500ms然后拉低500ms(周期)
  570. Process_Start(500,"selfcheck_mt_process",selfcheck_mt_process);
  571. Process_SetHoldOn(selfcheck_mt_process,1);
  572. //初始化计算roll值算法
  573. Mahony_Init(&Self_Mind_Mahony,104);
  574. //喂狗
  575. feed_watchdog();
  576. }