fml_imu.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  1. /**
  2. 功耗:
  3. 闲置模式功耗为250+ua
  4. 低功耗模式1,若前后脚地磁开启,板子地磁不开启,且不读取数据,功耗为330+ua ; 若只是读取前后脚地磁,则功耗为450+ua, 若读取前后脚地磁后再reset + 配置,则功耗为700+ua
  5. 低功耗模式2,若只开启后脚地磁,板子地磁不开启,且不读取数据,功耗为300+ua ; 若只是读取后脚地磁,则功耗为370-390+ua, 若读取后脚地磁后再reset + 配置, 则功耗为500+ua
  6. //以上低功耗测试都是没开六轴,只开地磁的情况
  7. 游戏模式spi_lsm,8.5ma
  8. 游戏模式i2c_lsm,8.7ma
  9. 前脚地磁供电关闭,后脚地磁供电开启,因为sda(标准输出)线共用,当sda输出0时,前脚地磁的供电IO和sda导通,导致短路,功耗为11ma,且后脚地磁数据异常。
  10. 所以通过开关电源来复位地磁失败!!!
  11. 低功耗模式3,只开启后脚地磁,板子地磁不开启,读取完地磁和低功耗加速度后(都是用SPI读取),在睡眠前重新配置(不reset)后脚地磁,功耗为370 - 400ua
  12. PS:低功耗模式3中,读取低功耗加速度用SPI时,速度为152us,用模拟I2C读取,速度为457us,由于时间变长,功耗为400 - 430ua
  13. 更新时间:2021-10-12:
  14. 低功耗模式4,更改了结构板,将IMU移到前脚,同时I2C的SCL公用,SDA独立,取消每次读取地磁后reset+配置。
  15. 这时,低功耗模式(没跑算法)功耗为:350-380ua 、 闲置模式功耗为:180-270ua 、 游戏模式功耗为:12-13ma,若再扣去小板上的六轴挂起功耗(22ua)+地磁挂起功耗(9ua)的31ua,
  16. 则各个模式功耗为:低功耗模式(没跑算法)功耗为:319-349ua 、 闲置模式功耗为:149-239ua 、 游戏模式功耗为:12-13ma
  17. 更新时间:2021-11-25:
  18. IMU的FIFO读取地磁,会出现重复现象,目前猜测是IMU的HZ与地磁的HZ不同步,地磁是100HZ,IMU是104HZ,其次,地磁无出现数据0的现象。
  19. 更新时间:2021-11-29:
  20. 版本:1.9.1
  21. 板子本身功耗:12-14ua
  22. 测试,低功耗FIFO功耗(没跑日常计步算法):537-549ua
  23. 测试,低功耗FIFO功耗(没跑日常计步算法),不读取IMUFIFO数据:454-464ua
  24. 测试,单纯设置外设,不跑IMU线程,功耗:453-462ua
  25. 测试,单纯设置外设(断电后脚外设供电,虽然其本身就是设置完后就挂起),不跑IMU线程,功耗:433-444ua
  26. 测试,断电前后脚外设,不跑IMU线程,功耗:175-224ua
  27. 测试,开启维持一个串口,功耗增加为:473ua
  28. 结论:
  29. 低功耗FIFO模式(100ms唤醒)下,不跑日常计步算法,总功耗为:537-549ua
  30. 外设功耗为:后脚地磁挂起(20ua)+前脚外设的IMU_104HZ_acc_timestamp_sensorhub_slv0123(128ua)+前脚外设地磁100HZ(150ua)
  31. 线程功耗为:IMU线程(84ua->读取IMU的FIFO数据10组,耗时1.1~1.2ms)+bat线程(5ua)+其余线程和广播(170ua)
  32. 游戏模式下(没焊接单线灯)功耗为:
  33. 设备直接进入:7.4ma
  34. 链接右鞋后,手机下发游戏指令,进入:8.5-8.6ma
  35. 更新时间:2022-3-7
  36. 版本:2.1
  37. 待机模式(不穿鞋)功耗:270ua ~ 467ua
  38. 正常模式(穿鞋)功耗:570ua ~ 630u
  39. 游戏模式功耗:
  40. */
  41. /*Includes ----------------------------------------------*/
  42. #include "tool.h"
  43. #include "nrf_delay.h"
  44. #include "bsp_time.h"
  45. #include "exception.h"
  46. #include "system.h"
  47. #include "drv_qmc6310_v2.h"
  48. #include "drv_lsm6ds3tr_c.h"
  49. #include "fml_imu.h"
  50. /*Private macro ------------------------------------------------------------------------------------------------------------------------------------*/
  51. #define FML_IMU_DATA_GROUP_NUM_MAX 20 //IMU能存储的最大数据组数
  52. #define FML_IMU_MONITOR_DATA_ERR_SUM_MAX 200 //数据监测错误累计最大值
  53. /*STRUCTION ------------------------------------------------------------------------------------------------------------------------------------*/
  54. typedef enum {
  55. FML_IMU_CONFIG_STAGE_DONE, //配置完成阶段
  56. FML_IMU_CONFIG_STAGE_IN_PROGRESS, //配置进行阶段
  57. FML_IMU_CONFIG_STAGE_FAIL, //配置失败阶段
  58. } FML_IMU_CONFIG_STAGE_e;
  59. typedef union
  60. {
  61. drv_lsm_config_param_t lsm; //当前的LSM配置参数
  62. drv_qmc_config_param_t qmc; //当前的QMC配置参数
  63. } drv_param_u;
  64. typedef struct fml_imu
  65. {
  66. /*private member*/
  67. FML_IMU_CONFIG_STAGE_e stage; //配置流程状态
  68. drv_param_u drv_param[FML_IMU_DIR_NUM]; //驱动参数组
  69. fml_imu_param_t config_param[FML_IMU_DIR_NUM]; //配置参数组
  70. int cur_data_num[FML_IMU_DIR_NUM]; //当前的数据量
  71. fml_imu_data_t cur_data[FML_IMU_DIR_NUM][FML_IMU_DATA_GROUP_NUM_MAX]; //当前的IMU数据缓存区
  72. uint32_t config_flow; //配置流程
  73. fml_imu_config_cb config_cb; //配置回调
  74. fml_imu_data_notify_cb data_notify_cb; //数据通知回调
  75. int16_t last_f_acc[3]; //上一次的前脚加速度值
  76. int16_t last_f_gry[3]; //上一次的前脚陀螺仪值
  77. int16_t last_f_mag[3]; //上一次的前脚地磁计值
  78. int16_t last_b_mag[3]; //上一次的后脚地磁计值
  79. int16_t last_f_acc_err_sum; //上一次的前脚加速度值错误累计
  80. int16_t last_f_gry_err_sum; //上一次的前脚陀螺仪值错误累计
  81. int16_t last_f_mag_err_sum; //上一次的前脚地磁计值错误累计
  82. int16_t last_b_mag_err_sum; //上一次的后脚地磁计值错误累计
  83. int16_t except_data_occur_sum[FML_IMU_DIR_NUM]; //异常数据产生次数累计
  84. } Fml_Imu_t;
  85. /*Local Variable ------------------------------------------------------------------------------------------------------------------------------------*/
  86. static Fml_Imu_t ob_fml_imu;
  87. /*Local Functions ------------------------------------------------------------------------------------------------------------------------------------*/
  88. static void fml_imu_macro_conversion(FML_IMU_DIR_e dir, fml_imu_param_t *config_param, drv_param_u *drv_param)
  89. {
  90. switch(dir)
  91. {
  92. case FML_IMU_DIR_FRONT:
  93. //acc_odr
  94. switch(config_param->acc_odr)
  95. {
  96. case FML_IMU_ACC_ODR_OFF:
  97. drv_param->lsm.acc_odr = LSM_ACC_ODR_OFF;
  98. break;
  99. case FML_IMU_ACC_ODR_104HZ:
  100. drv_param->lsm.acc_odr = LSM_ACC_ODR_104HZ;
  101. break;
  102. case FML_IMU_ACC_ODR_12HZ5:
  103. drv_param->lsm.acc_odr = LSM_ACC_ODR_12HZ5;
  104. break;
  105. }
  106. //gry_odr
  107. switch(config_param->gry_odr)
  108. {
  109. case FML_IMU_GRY_ODR_OFF:
  110. drv_param->lsm.gry_odr = LSM_GRY_ODR_OFF;
  111. break;
  112. case FML_IMU_GRY_ODR_104HZ:
  113. drv_param->lsm.gry_odr = LSM_GRY_ODR_104HZ;
  114. break;
  115. case FML_IMU_GRY_ODR_12HZ5:
  116. drv_param->lsm.gry_odr = LSM_GRY_ODR_12HZ5;
  117. break;
  118. }
  119. //mag_odr
  120. switch(config_param->mag_odr)
  121. {
  122. case FML_IMU_MAG_ODR_OFF:
  123. drv_param->lsm.mag_odr = LSM_MAG_ODR_OFF;
  124. break;
  125. case FML_IMU_MAG_ODR_10HZ:
  126. drv_param->lsm.mag_odr = LSM_MAG_ODR_10HZ;
  127. break;
  128. case FML_IMU_MAG_ODR_100HZ:
  129. drv_param->lsm.mag_odr = LSM_MAG_ODR_100HZ;
  130. break;
  131. case FML_IMU_MAG_ODR_200HZ:
  132. drv_param->lsm.mag_odr = LSM_MAG_ODR_200HZ;
  133. break;
  134. }
  135. //fifo_odr
  136. switch(config_param->fifo_odr)
  137. {
  138. case FML_IMU_FIFO_ODR_OFF:
  139. drv_param->lsm.fifo_odr = LSM_FIFO_ODR_OFF;
  140. break;
  141. case FML_IMU_FIFO_ODR_104HZ:
  142. drv_param->lsm.fifo_odr = LSM_FIFO_ODR_104HZ;
  143. break;
  144. }
  145. //acc_power_mode
  146. switch(config_param->acc_power_mode)
  147. {
  148. case FML_IMU_ACC_POWER_MODE_HIGH_PERFORMANCE:
  149. drv_param->lsm.acc_power_mode = LSM_ACC_POWER_MODE_HIGH_PERFORMANCE;
  150. break;
  151. case FML_IMU_ACC_POWER_MODE_NORMAL:
  152. drv_param->lsm.acc_power_mode = LSM_ACC_POWER_MODE_NORMAL;
  153. break;
  154. }
  155. //gry_power_mode
  156. switch(config_param->gry_power_mode)
  157. {
  158. case FML_IMU_GRY_POWER_MODE_HIGH_PERFORMANCE:
  159. drv_param->lsm.gry_power_mode = LSM_GRY_POWER_MODE_HIGH_PERFORMANCE;
  160. break;
  161. case FML_IMU_GRY_POWER_MODE_NORMAL:
  162. drv_param->lsm.gry_power_mode = LSM_GRY_POWER_MODE_NORMAL;
  163. break;
  164. }
  165. //acc_fs
  166. switch(config_param->acc_fs)
  167. {
  168. case FML_IMU_ACC_FS_2G:
  169. drv_param->lsm.acc_fs = LSM_ACC_FS_2G;
  170. break;
  171. case FML_IMU_ACC_FS_16G:
  172. drv_param->lsm.acc_fs = LSM_ACC_FS_16G;
  173. break;
  174. }
  175. //gry_fs
  176. switch(config_param->gry_fs)
  177. {
  178. case FML_IMU_GRY_FS_250DPS:
  179. drv_param->lsm.gry_fs = LSM_GRY_FS_250DPS;
  180. break;
  181. case FML_IMU_GRY_FS_2000DPS:
  182. drv_param->lsm.gry_fs = LSM_GRY_FS_2000DPS;
  183. break;
  184. }
  185. //mag_fs
  186. switch(config_param->mag_fs)
  187. {
  188. case FML_IMU_MAG_FS_30GS:
  189. drv_param->lsm.mag_fs = LSM_MAG_FS_30GS;
  190. break;
  191. }
  192. //timestamp_resolution
  193. switch(config_param->timestamp_resolution)
  194. {
  195. case FML_IMU_TIMESTAMP_6MS4:
  196. drv_param->lsm.timestamp_resolution = LSM_TIMESTAMP_6MS4;
  197. break;
  198. case FML_IMU_TIMESTAMP_25US:
  199. drv_param->lsm.timestamp_resolution = LSM_TIMESTAMP_25US;
  200. break;
  201. }
  202. //timestamp_switch
  203. switch(config_param->timestamp_switch)
  204. {
  205. case FML_IMU_TIMESTAMP_OFF:
  206. drv_param->lsm.timestamp_switch = LSM_TIMESTAMP_OFF;
  207. break;
  208. case FML_IMU_TIMESTAMP_ON:
  209. drv_param->lsm.timestamp_switch = LSM_TIMESTAMP_ON;
  210. break;
  211. }
  212. break;
  213. case FML_IMU_DIR_BACK:
  214. //mag_odr
  215. switch(config_param->mag_odr)
  216. {
  217. case FML_IMU_MAG_ODR_OFF:
  218. drv_param->qmc.mag_odr = QMC_MAG_ODR_OFF;
  219. break;
  220. case FML_IMU_MAG_ODR_10HZ:
  221. drv_param->qmc.mag_odr = QMC_MAG_ODR_10HZ;
  222. break;
  223. case FML_IMU_MAG_ODR_100HZ:
  224. drv_param->qmc.mag_odr = QMC_MAG_ODR_100HZ;
  225. break;
  226. case FML_IMU_MAG_ODR_200HZ:
  227. drv_param->qmc.mag_odr = QMC_MAG_ODR_200HZ;
  228. break;
  229. }
  230. //mag_fs
  231. switch(config_param->mag_fs)
  232. {
  233. case FML_IMU_MAG_FS_30GS:
  234. drv_param->qmc.mag_fs = QMC_MAG_FS_30GS;
  235. break;
  236. }
  237. break;
  238. default:
  239. break;
  240. }
  241. }
  242. static int fml_imu_intergrated_setting(void)
  243. {
  244. int ret;
  245. int lsm_mag_flow = drv_lsm_get_mag_odr_flow();
  246. int qmc_mag_flow = drv_qmc6310_get_mag_odr_flow();
  247. drv_param_u lsm_drv_param;
  248. drv_param_u qmc_drv_param;
  249. static uint32_t tim = 0;
  250. switch(ob_fml_imu.config_flow)
  251. {
  252. case 0:
  253. //断电lsm
  254. ret = drv_lsm_power_off();
  255. if(ret != 0)return -1;
  256. //断电qmc
  257. ret = drv_qmc6310_power_off();
  258. if(ret != 0)return -1;
  259. //清空读取缓存
  260. ob_fml_imu.cur_data_num[FML_IMU_DIR_FRONT] = 0;
  261. //清空读取缓存
  262. ob_fml_imu.cur_data_num[FML_IMU_DIR_BACK] = 0;
  263. tim = 0;
  264. ob_fml_imu.config_flow = 1;
  265. break;
  266. case 1:
  267. //等待200ms
  268. if(tim == 0){
  269. tim = TIME_GetTicks();
  270. }else if(TIME_GetTicks()-tim>=200){
  271. tim = 0;
  272. ob_fml_imu.config_flow = 2;
  273. }
  274. break;
  275. case 2:
  276. //上电lsm
  277. ret = drv_lsm_power_on();
  278. if(ret != 0)return -1;
  279. //上电qmc
  280. ret = drv_qmc6310_power_on();
  281. if(ret != 0)return -1;
  282. tim = 0;
  283. ob_fml_imu.config_flow = 3;
  284. break;
  285. case 3:
  286. //等待200ms
  287. if(tim == 0){
  288. tim = TIME_GetTicks();
  289. }else if(TIME_GetTicks()-tim>=200){
  290. tim = 0;
  291. ob_fml_imu.config_flow = 4;
  292. }
  293. break;
  294. case 4:
  295. //lsm进行自检步骤1
  296. ret = drv_lsm_self_check_1();
  297. if(ret != 0)return -1;
  298. tim = 0;
  299. ob_fml_imu.config_flow = 5;
  300. break;
  301. case 5:
  302. //等待100ms
  303. if(tim == 0){
  304. tim = TIME_GetTicks();
  305. }else if(TIME_GetTicks()-tim>=100){
  306. tim = 0;
  307. ob_fml_imu.config_flow = 6;
  308. }
  309. break;
  310. case 6:
  311. //lsm进行自检步骤2
  312. ret = drv_lsm_self_check_2();
  313. if(ret != 0)return -1;
  314. tim = 0;
  315. ob_fml_imu.config_flow = 7;
  316. break;
  317. case 7:
  318. //等待100ms
  319. if(tim == 0){
  320. tim = TIME_GetTicks();
  321. }else if(TIME_GetTicks()-tim>=100){
  322. tim = 0;
  323. ob_fml_imu.config_flow = 8;
  324. }
  325. break;
  326. case 8:
  327. //lsm进行自检步骤3
  328. ret = drv_lsm_self_check_3();
  329. if(ret != 0)return -1;
  330. tim = 0;
  331. ob_fml_imu.config_flow = 9;
  332. break;
  333. case 9:
  334. //等待150ms
  335. if(tim == 0){
  336. tim = TIME_GetTicks();
  337. }else if(TIME_GetTicks()-tim>=150){
  338. tim = 0;
  339. ob_fml_imu.config_flow = 10;
  340. }
  341. break;
  342. case 10:
  343. //lsm进行自检步骤4
  344. ret = drv_lsm_self_check_4();
  345. if(ret != 0)return -1;
  346. tim = 0;
  347. ob_fml_imu.config_flow = 11;
  348. break;
  349. case 11:
  350. //等待50ms
  351. if(tim == 0){
  352. tim = TIME_GetTicks();
  353. }else if(TIME_GetTicks()-tim>=50){
  354. tim = 0;
  355. ob_fml_imu.config_flow = 12;
  356. }
  357. break;
  358. case 12:
  359. //lsm进行自检步骤5
  360. ret = drv_lsm_self_check_5();
  361. if(ret != 0)return -1;
  362. tim = 0;
  363. ob_fml_imu.config_flow = 13;
  364. break;
  365. case 13:
  366. //转换参数,用于配置驱动
  367. fml_imu_macro_conversion(FML_IMU_DIR_FRONT, &ob_fml_imu.config_param[FML_IMU_DIR_FRONT], &lsm_drv_param);
  368. fml_imu_macro_conversion(FML_IMU_DIR_BACK, &ob_fml_imu.config_param[FML_IMU_DIR_BACK], &qmc_drv_param);
  369. //配置lsm的地磁计采样频率
  370. if(ob_fml_imu.config_param[FML_IMU_DIR_FRONT].fifo_odr != FML_IMU_FIFO_ODR_OFF)
  371. {
  372. for(int i=1; i <=lsm_mag_flow;i++)
  373. {
  374. ret = drv_lsm_set_mag_odr(lsm_drv_param.lsm.mag_odr, 1, i);
  375. if(ret != 0)return -1;
  376. }
  377. tim = 0;
  378. ob_fml_imu.config_flow = 14;
  379. }
  380. else
  381. {
  382. for(int i=1; i <= lsm_mag_flow; i++)
  383. {
  384. ret = drv_lsm_set_mag_odr(lsm_drv_param.lsm.mag_odr, 0, i);
  385. if(ret != 0)return -1;
  386. }
  387. tim = 0;
  388. ob_fml_imu.config_flow = 14;
  389. }
  390. break;
  391. case 14:
  392. //转换参数,用于配置驱动
  393. fml_imu_macro_conversion(FML_IMU_DIR_FRONT, &ob_fml_imu.config_param[FML_IMU_DIR_FRONT], &lsm_drv_param);
  394. fml_imu_macro_conversion(FML_IMU_DIR_BACK, &ob_fml_imu.config_param[FML_IMU_DIR_BACK], &qmc_drv_param);
  395. //配置lsm的陀螺仪采样频率
  396. ret = drv_lsm_set_gry_odr(lsm_drv_param.lsm.gry_odr);
  397. if(ret != 0)return -1;
  398. //配置lsm的加速度采样频率
  399. ret = drv_lsm_set_acc_odr(lsm_drv_param.lsm.acc_odr);
  400. if(ret != 0)return -1;
  401. tim = 0;
  402. ob_fml_imu.config_flow = 15;
  403. break;
  404. case 15:
  405. //等待20ms
  406. if(tim == 0){
  407. tim = TIME_GetTicks();
  408. }else if(TIME_GetTicks()-tim>=20){
  409. tim = 0;
  410. ob_fml_imu.config_flow = 16;
  411. }
  412. break;
  413. case FML_IMU_CONFIG_FLOW_DONE:
  414. //配置完成才能进来此处。。。。。。。
  415. break;
  416. default:
  417. //转换参数,用于配置驱动
  418. fml_imu_macro_conversion(FML_IMU_DIR_FRONT, &ob_fml_imu.config_param[FML_IMU_DIR_FRONT], &lsm_drv_param);
  419. fml_imu_macro_conversion(FML_IMU_DIR_BACK, &ob_fml_imu.config_param[FML_IMU_DIR_BACK], &qmc_drv_param);
  420. //配置lsm的加速度工作模式
  421. ret = drv_lsm_set_acc_power_mode(lsm_drv_param.lsm.acc_power_mode);
  422. if(ret != 0)return -1;
  423. ob_fml_imu.config_flow++;
  424. //配置lsm的陀螺仪工作模式
  425. ret = drv_lsm_set_gry_power_mode(lsm_drv_param.lsm.gry_power_mode);
  426. if(ret != 0)return -1;
  427. ob_fml_imu.config_flow++;
  428. //配置lsm的加速度量程
  429. ret = drv_lsm_set_acc_fs(lsm_drv_param.lsm.acc_fs);
  430. if(ret != 0)return -1;
  431. ob_fml_imu.config_flow++;
  432. //配置lsm的陀螺仪量程
  433. ret = drv_lsm_set_gry_fs(lsm_drv_param.lsm.gry_fs);
  434. if(ret != 0)return -1;
  435. ob_fml_imu.config_flow++;
  436. //配置lsm的时间戳精度
  437. ret = drv_lsm_set_timestamp_resolution(lsm_drv_param.lsm.timestamp_resolution);
  438. if(ret != 0)return -1;
  439. ob_fml_imu.config_flow++;
  440. //配置lsm的时间戳开关
  441. ret = drv_lsm_set_timestamp_switch(lsm_drv_param.lsm.timestamp_switch);
  442. if(ret != 0)return -1;
  443. ob_fml_imu.config_flow++;
  444. //配置lsm的FIFO采样频率(必须以上都配置成功,才能配置FIFO)
  445. ret = drv_lsm_set_fifo_odr(lsm_drv_param.lsm.fifo_odr, \
  446. lsm_drv_param.lsm.acc_odr, \
  447. lsm_drv_param.lsm.gry_odr, \
  448. lsm_drv_param.lsm.mag_odr, \
  449. lsm_drv_param.lsm.timestamp_switch);
  450. if(ret != 0)return -1;
  451. ob_fml_imu.config_flow++;
  452. //配置qmc的地磁计采样频率
  453. for(int i = 1; i <=qmc_mag_flow; i++)
  454. {
  455. ret = drv_qmc6310_set_mag_odr(qmc_drv_param.qmc.mag_odr,i);
  456. if(ret != 0)return -1;
  457. ob_fml_imu.config_flow++;
  458. }
  459. //配置完成!
  460. ob_fml_imu.config_flow = FML_IMU_CONFIG_FLOW_DONE;
  461. break;
  462. }
  463. return 0;
  464. }
  465. static int fml_imu_read_data_lsm(void)
  466. {
  467. int i;
  468. int fifo_group_num;
  469. lsm_data_t temp_lsm_data;
  470. //读取FIFO数据
  471. if(ob_fml_imu.config_param[FML_IMU_DIR_FRONT].fifo_odr != FML_IMU_FIFO_ODR_OFF)
  472. {
  473. //获取当前fifo里存在多少组数据。
  474. fifo_group_num = drv_lsm_get_fifo_group_num();
  475. fifo_group_num = fifo_group_num <= FML_IMU_DATA_GROUP_NUM_MAX ? fifo_group_num : FML_IMU_DATA_GROUP_NUM_MAX;
  476. if(fifo_group_num > 0)
  477. {
  478. for(i=0; i<fifo_group_num; i++)
  479. {
  480. if(drv_lsm_get_fifo_data(&temp_lsm_data) != -1)
  481. {
  482. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[0] = temp_lsm_data.acc[0];
  483. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[1] = temp_lsm_data.acc[1];
  484. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[2] = temp_lsm_data.acc[2];
  485. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[0] = temp_lsm_data.gry[0];
  486. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[1] = temp_lsm_data.gry[1];
  487. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[2] = temp_lsm_data.gry[2];
  488. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[0] = temp_lsm_data.mag[0];
  489. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[1] = temp_lsm_data.mag[1];
  490. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[2] = temp_lsm_data.mag[2];
  491. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].fifo_timestamp = temp_lsm_data.fifo_timestamp;
  492. }
  493. else
  494. {
  495. break;
  496. }
  497. }
  498. }
  499. else
  500. {
  501. return 0;
  502. }
  503. return i;
  504. }
  505. //只读取ACC数据
  506. else if(ob_fml_imu.config_param[FML_IMU_DIR_FRONT].acc_odr != FML_IMU_ACC_ODR_OFF && \
  507. ob_fml_imu.config_param[FML_IMU_DIR_FRONT].gry_odr == FML_IMU_GRY_ODR_OFF && \
  508. ob_fml_imu.config_param[FML_IMU_DIR_FRONT].mag_odr == FML_IMU_MAG_ODR_OFF \
  509. )
  510. {
  511. if(drv_lsm_get_acc_data(&temp_lsm_data) != -1)
  512. {
  513. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][0].acc[0] = temp_lsm_data.acc[0];
  514. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][0].acc[1] = temp_lsm_data.acc[1];
  515. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][0].acc[2] = temp_lsm_data.acc[2];
  516. return 1;
  517. }
  518. }
  519. return 0;
  520. }
  521. static int fml_imu_read_data_qmc(void)
  522. {
  523. qmc_data_t temp_qmc_data;
  524. if(ob_fml_imu.config_param[FML_IMU_DIR_BACK].mag_odr != FML_IMU_MAG_ODR_OFF)
  525. {
  526. if(drv_qmc6310_get_mag_data(&temp_qmc_data) != -1)
  527. {
  528. ob_fml_imu.cur_data[FML_IMU_DIR_BACK][0].mag[0] = temp_qmc_data.mag[0];
  529. ob_fml_imu.cur_data[FML_IMU_DIR_BACK][0].mag[1] = temp_qmc_data.mag[1];
  530. ob_fml_imu.cur_data[FML_IMU_DIR_BACK][0].mag[2] = temp_qmc_data.mag[2];
  531. return 1;
  532. }
  533. }
  534. return 0;
  535. }
  536. static int hal_ser_imu_read_data(FML_IMU_DIR_e dir)
  537. {
  538. int ret = 0;
  539. switch(dir)
  540. {
  541. case FML_IMU_DIR_FRONT:
  542. ret = fml_imu_read_data_lsm();
  543. break;
  544. case FML_IMU_DIR_BACK:
  545. ret = fml_imu_read_data_qmc();
  546. break;
  547. default:
  548. break;
  549. }
  550. return ret;
  551. }
  552. static void monitor_sensor_data(int16_t *f_acc, int16_t *f_gry, int16_t *f_mag, int16_t *b_mag)
  553. {
  554. /*前脚加速度*/
  555. if(f_acc != NULL)
  556. {
  557. if(
  558. ob_fml_imu.last_f_acc[0] == f_acc[0] && \
  559. ob_fml_imu.last_f_acc[1] == f_acc[1] && \
  560. ob_fml_imu.last_f_acc[2] == f_acc[2]
  561. )
  562. {
  563. ob_fml_imu.last_f_acc_err_sum++;
  564. if(ob_fml_imu.last_f_acc_err_sum >= FML_IMU_MONITOR_DATA_ERR_SUM_MAX){
  565. Except_SetExceptype(EXCEPT_DATA_FRONT_ACC);
  566. }
  567. }else{
  568. ob_fml_imu.last_f_acc_err_sum = 0;
  569. }
  570. ob_fml_imu.last_f_acc[0] = f_acc[0];
  571. ob_fml_imu.last_f_acc[1] = f_acc[1];
  572. ob_fml_imu.last_f_acc[2] = f_acc[2];
  573. }
  574. /*前脚陀螺仪*/
  575. if(f_gry != NULL)
  576. {
  577. if(
  578. ob_fml_imu.last_f_gry[0] == f_gry[0] && \
  579. ob_fml_imu.last_f_gry[1] == f_gry[1] && \
  580. ob_fml_imu.last_f_gry[2] == f_gry[2]
  581. )
  582. {
  583. ob_fml_imu.last_f_gry_err_sum++;
  584. if(ob_fml_imu.last_f_gry_err_sum >= FML_IMU_MONITOR_DATA_ERR_SUM_MAX){
  585. Except_SetExceptype(EXCEPT_DATA_FRONT_GRY);
  586. }
  587. }else{
  588. ob_fml_imu.last_f_gry_err_sum = 0;
  589. }
  590. ob_fml_imu.last_f_gry[0] = f_gry[0];
  591. ob_fml_imu.last_f_gry[1] = f_gry[1];
  592. ob_fml_imu.last_f_gry[2] = f_gry[2];
  593. }
  594. /*前脚地磁计*/
  595. if(f_mag != NULL)
  596. {
  597. if(
  598. ob_fml_imu.last_f_mag[0] == f_mag[0] && \
  599. ob_fml_imu.last_f_mag[1] == f_mag[1] && \
  600. ob_fml_imu.last_f_mag[2] == f_mag[2]
  601. )
  602. {
  603. ob_fml_imu.last_f_mag_err_sum++;
  604. if(ob_fml_imu.last_f_mag_err_sum >= FML_IMU_MONITOR_DATA_ERR_SUM_MAX){
  605. Except_SetExceptype(EXCEPT_DATA_FRONT_MAG);
  606. }
  607. }else{
  608. ob_fml_imu.last_f_mag_err_sum = 0;
  609. }
  610. ob_fml_imu.last_f_mag[0] = f_mag[0];
  611. ob_fml_imu.last_f_mag[1] = f_mag[1];
  612. ob_fml_imu.last_f_mag[2] = f_mag[2];
  613. }
  614. /*后脚地磁计*/
  615. if(b_mag != NULL)
  616. {
  617. if(
  618. ob_fml_imu.last_b_mag[0] == b_mag[0] && \
  619. ob_fml_imu.last_b_mag[1] == b_mag[1] && \
  620. ob_fml_imu.last_b_mag[2] == b_mag[2]
  621. )
  622. {
  623. ob_fml_imu.last_b_mag_err_sum++;
  624. if(ob_fml_imu.last_b_mag_err_sum >= FML_IMU_MONITOR_DATA_ERR_SUM_MAX){
  625. Except_SetExceptype(EXCEPT_DATA_BACK_MAG);
  626. }
  627. }else{
  628. ob_fml_imu.last_b_mag_err_sum = 0;
  629. }
  630. ob_fml_imu.last_b_mag[0] = b_mag[0];
  631. ob_fml_imu.last_b_mag[1] = b_mag[1];
  632. ob_fml_imu.last_b_mag[2] = b_mag[2];
  633. }
  634. //监测到前脚数据异常
  635. if(Except_IsError(EXCEPT_DATA_FRONT_ACC) || Except_IsError(EXCEPT_DATA_FRONT_GRY) || Except_IsError(EXCEPT_DATA_FRONT_MAG))
  636. {
  637. ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_FRONT]++;
  638. if(ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_FRONT] > 1)
  639. {
  640. if(Except_IsError(EXCEPT_DATA_FRONT_ACC)){Except_TxError(EXCEPT_DATA_FRONT_ACC,"front_acc_data_error");DEBUG_LOG("front_acc_data_error\n");}
  641. if(Except_IsError(EXCEPT_DATA_FRONT_GRY)){Except_TxError(EXCEPT_DATA_FRONT_GRY,"front_gry_data_error");DEBUG_LOG("front_gry_data_error\n");}
  642. if(Except_IsError(EXCEPT_DATA_FRONT_MAG)){Except_TxError(EXCEPT_DATA_FRONT_MAG,"front_mag_data_error");DEBUG_LOG("front_mag_data_error\n");}
  643. }
  644. //重启前脚LSM(主要是复位结构体)
  645. drv_lsm_power_off();
  646. drv_lsm_power_on();
  647. //重新开始配置
  648. fml_imu_start_config();
  649. //清除异常
  650. Except_ClearExceptype(EXCEPT_DATA_FRONT_ACC);
  651. Except_ClearExceptype(EXCEPT_DATA_FRONT_GRY);
  652. Except_ClearExceptype(EXCEPT_DATA_FRONT_MAG);
  653. }
  654. else
  655. {
  656. ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_FRONT] = 0;
  657. //清除异常
  658. Except_ClearExceptype(EXCEPT_DATA_FRONT_ACC);
  659. Except_ClearExceptype(EXCEPT_DATA_FRONT_GRY);
  660. Except_ClearExceptype(EXCEPT_DATA_FRONT_MAG);
  661. }
  662. //监测到后脚数据异常
  663. if(Except_IsError(EXCEPT_DATA_BACK_MAG))
  664. {
  665. ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_BACK]++;
  666. if(ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_BACK] > 1)
  667. {
  668. if(Except_IsError(EXCEPT_DATA_BACK_MAG))Except_TxError(EXCEPT_DATA_BACK_MAG,"back_mag_data_error");
  669. }
  670. //重启后脚QMC(主要是复位结构体)
  671. drv_qmc6310_power_off();
  672. drv_qmc6310_power_on();
  673. //重新开始配置
  674. fml_imu_start_config();
  675. //清除异常
  676. Except_ClearExceptype(EXCEPT_DATA_BACK_MAG);
  677. }
  678. else
  679. {
  680. ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_BACK] = 0;
  681. //清除异常
  682. Except_ClearExceptype(EXCEPT_DATA_BACK_MAG);
  683. }
  684. }
  685. static void monitor_sensor_no_data(int cur_front_data_num, int cur_back_data_num)
  686. {
  687. static uint32_t front_no_data_tim = 0;
  688. static uint32_t back_no_data_tim = 0;
  689. static char buf[255];
  690. //数据异常检测——前脚没有数据
  691. if(cur_front_data_num == 0)
  692. {
  693. if(ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.acc_odr != LSM_ACC_ODR_OFF || \
  694. ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.gry_odr != LSM_GRY_ODR_OFF || \
  695. ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.mag_odr != LSM_MAG_ODR_OFF)
  696. {
  697. //持续1000ms没数据
  698. if(front_no_data_tim == 0){
  699. front_no_data_tim = TIME_GetTicks();
  700. }else if(TIME_GetTicks()-front_no_data_tim>=1000){
  701. sprintf(buf,"Front Sensor short circuit\r\n");
  702. Except_TxError(EXCEPT_IMU_SUSPEND_OVERFLOW,buf);
  703. front_no_data_tim = 0;
  704. //重启前脚LSM(主要是复位结构体)
  705. drv_lsm_power_off();
  706. drv_lsm_power_on();
  707. //重新开始配置
  708. fml_imu_start_config();
  709. }
  710. }
  711. }
  712. else front_no_data_tim = 0;
  713. //数据异常检测——后脚没有数据
  714. if(cur_back_data_num == 0)
  715. {
  716. if(ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc.mag_odr != QMC_MAG_ODR_OFF)
  717. {
  718. //持续1000ms没数据
  719. if(back_no_data_tim == 0){
  720. back_no_data_tim = TIME_GetTicks();
  721. }else if(TIME_GetTicks()-back_no_data_tim>=1000){
  722. sprintf(buf,"Back Sensor short circuit\r\n");
  723. Except_TxError(EXCEPT_IMU_SUSPEND_OVERFLOW,buf);
  724. back_no_data_tim = 0;
  725. //重启后脚QMC(主要是复位结构体)
  726. drv_qmc6310_power_off();
  727. drv_qmc6310_power_on();
  728. //重新开始配置
  729. fml_imu_start_config();
  730. }
  731. }
  732. }
  733. else back_no_data_tim = 0;
  734. }
  735. static void fml_imu_monitor_sensor_data_process(int cur_front_data_num, int cur_back_data_num)
  736. {
  737. int i = 0;
  738. int16_t group_num = 0;
  739. static int16_t f_acc[3];
  740. static int16_t f_gry[3];
  741. static int16_t f_mag[3];
  742. static int16_t b_mag[3];
  743. fml_imu_data_t data;
  744. static uint32_t last_tim = 0;
  745. //检测数据异常——没数据
  746. monitor_sensor_no_data(cur_front_data_num, cur_back_data_num);
  747. //检测数据异常——重复数据
  748. if(
  749. ob_fml_imu.stage == FML_IMU_CONFIG_STAGE_DONE && \
  750. ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.acc_odr == LSM_ACC_ODR_104HZ && \
  751. ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.gry_odr == LSM_GRY_ODR_104HZ && \
  752. (ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.mag_odr == LSM_MAG_ODR_200HZ || ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.mag_odr == LSM_MAG_ODR_100HZ)
  753. )
  754. {
  755. if(TIME_GetTicks()-last_tim >= FullPower_Interval) //监测前脚传感器数据(acc + gry + mag)+ 监测后脚传感器数据(mag)
  756. {
  757. last_tim = TIME_GetTicks();
  758. group_num = fml_imu_get_data_num(FML_IMU_DIR_FRONT);
  759. if(group_num > 0)
  760. {
  761. for(i=0;i<group_num;i++)
  762. {
  763. fml_imu_get_data(FML_IMU_DIR_FRONT, i, &data);
  764. f_gry[0] = data.gry[0];f_gry[1] = data.gry[1];f_gry[2] = data.gry[2];
  765. f_acc[0] = data.acc[0];f_acc[1] = data.acc[1];f_acc[2] = data.acc[2];
  766. f_mag[0] = data.mag[0];f_mag[1] = data.mag[1];f_mag[2] = data.mag[2];
  767. monitor_sensor_data(f_acc, f_gry, f_mag, NULL);
  768. }
  769. }
  770. if(fml_imu_get_data_num(FML_IMU_DIR_BACK) >= 1){
  771. fml_imu_get_data(FML_IMU_DIR_BACK, 0, &data);
  772. b_mag[0] = data.mag[0];b_mag[1] = data.mag[1];b_mag[2] = data.mag[2];
  773. monitor_sensor_data(NULL, NULL, NULL, b_mag);
  774. }
  775. }
  776. }
  777. else if(
  778. ob_fml_imu.stage == FML_IMU_CONFIG_STAGE_DONE && \
  779. ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.acc_odr == LSM_ACC_ODR_104HZ && \
  780. (ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.mag_odr == LSM_MAG_ODR_200HZ || ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.mag_odr == LSM_MAG_ODR_100HZ)
  781. )
  782. {
  783. if(TIME_GetTicks()-last_tim >= LowPower_Interval) //监测前脚传感器数据(acc + mag)
  784. {
  785. last_tim = TIME_GetTicks();
  786. group_num = fml_imu_get_data_num(FML_IMU_DIR_FRONT);
  787. if(group_num > 0)
  788. {
  789. for(i=0;i<group_num;i++)
  790. {
  791. fml_imu_get_data(FML_IMU_DIR_FRONT, i, &data);
  792. f_acc[0] = data.acc[0];f_acc[1] = data.acc[1];f_acc[2] = data.acc[2];
  793. f_mag[0] = data.mag[0];f_mag[1] = data.mag[1];f_mag[2] = data.mag[2];
  794. monitor_sensor_data(f_acc, NULL, f_mag, NULL);
  795. }
  796. }
  797. }
  798. }
  799. else if(ob_fml_imu.stage == FML_IMU_CONFIG_STAGE_DONE && ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.acc_odr == LSM_ACC_ODR_12HZ5)
  800. {
  801. if(TIME_GetTicks()-last_tim >= StandByPower_Interval) //监测前脚传感器数据(acc)
  802. {
  803. last_tim = TIME_GetTicks();
  804. group_num = fml_imu_get_data_num(FML_IMU_DIR_FRONT);
  805. if(group_num > 0)
  806. {
  807. for(i=0;i<group_num;i++)
  808. {
  809. fml_imu_get_data(FML_IMU_DIR_FRONT, i, &data);
  810. f_acc[0] = data.acc[0];f_acc[1] = data.acc[1];f_acc[2] = data.acc[2];
  811. monitor_sensor_data(f_acc, NULL, NULL, NULL);
  812. }
  813. }
  814. }
  815. }
  816. }
  817. static void fml_imu_Process(void)
  818. {
  819. int data_num[FML_IMU_DIR_NUM];
  820. uint32_t dir_bit;
  821. static char buf[255];
  822. static uint32_t config_err_report_tim = 0;
  823. switch(ob_fml_imu.stage)
  824. {
  825. case FML_IMU_CONFIG_STAGE_DONE: //配置完成阶段
  826. dir_bit = 0;
  827. //读取前脚IMU数据 + 更新前脚IMU数据量
  828. data_num[FML_IMU_DIR_FRONT] = hal_ser_imu_read_data(FML_IMU_DIR_FRONT);
  829. if(data_num[FML_IMU_DIR_FRONT] > 0){
  830. ob_fml_imu.cur_data_num[FML_IMU_DIR_FRONT] = data_num[FML_IMU_DIR_FRONT];
  831. dir_bit |= (1 << FML_IMU_DIR_FRONT);
  832. }
  833. //读取后脚IMU数据 + 更新后脚IMU数据量
  834. data_num[FML_IMU_DIR_BACK] = hal_ser_imu_read_data(FML_IMU_DIR_BACK);
  835. if(data_num[FML_IMU_DIR_BACK] > 0){
  836. ob_fml_imu.cur_data_num[FML_IMU_DIR_BACK] = data_num[FML_IMU_DIR_BACK];
  837. dir_bit |= (1 << FML_IMU_DIR_BACK);
  838. }
  839. //数据异常检测
  840. fml_imu_monitor_sensor_data_process(data_num[FML_IMU_DIR_FRONT], data_num[FML_IMU_DIR_BACK]);
  841. //数据回调通知
  842. if(dir_bit != 0 && ob_fml_imu.data_notify_cb != NULL)ob_fml_imu.data_notify_cb(dir_bit);
  843. break;
  844. case FML_IMU_CONFIG_STAGE_IN_PROGRESS: //配置进行阶段
  845. if(fml_imu_intergrated_setting() == -1)
  846. {
  847. //配置失败
  848. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_FAIL;
  849. //通知配置失败
  850. if(ob_fml_imu.config_cb != NULL)ob_fml_imu.config_cb(ob_fml_imu.config_flow);
  851. //上报异常
  852. sprintf(buf,"front_imu_suspend_overflow:0x%x\r\n",ob_fml_imu.config_flow);
  853. Except_TxError(EXCEPT_IMU_SUSPEND_OVERFLOW,buf);
  854. //断电前后脚
  855. fml_imu_close(FML_IMU_DIR_FRONT);
  856. fml_imu_close(FML_IMU_DIR_BACK);
  857. //解除全功率运行
  858. Process_SetHoldOn(fml_imu_Process,0);
  859. }
  860. else
  861. {
  862. if(ob_fml_imu.config_flow == FML_IMU_CONFIG_FLOW_DONE)
  863. {
  864. //配置成功
  865. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_DONE;
  866. //通知配置成功
  867. if(ob_fml_imu.config_cb != NULL)ob_fml_imu.config_cb(ob_fml_imu.config_flow);
  868. //更新驱动LSM配置参数
  869. drv_lsm_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm);
  870. //更新驱动LSM配置参数
  871. drv_qmc6310_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc);
  872. //解除全功率运行
  873. Process_SetHoldOn(fml_imu_Process,0);
  874. }
  875. }
  876. break;
  877. default:
  878. //间隔1000ms上报配置失败错误
  879. if(config_err_report_tim == 0){
  880. config_err_report_tim = TIME_GetTicks();
  881. }else if(TIME_GetTicks()-config_err_report_tim>=1000){
  882. sprintf(buf,"front_imu_suspend_overflow:0x%x\r\n",ob_fml_imu.config_flow);
  883. Except_TxError(EXCEPT_IMU_SUSPEND_OVERFLOW,buf);
  884. config_err_report_tim = 0;
  885. }
  886. break;
  887. }
  888. }
  889. /*API ------------------------------------------------------------------------------------------------------------------------------------*/
  890. /**
  891. @brief 初始化IMU功能模块
  892. @param 无
  893. @return 错误代码 - [out] -1失败,0成功
  894. */
  895. int fml_imu_Init(void)
  896. {
  897. int ret;
  898. /***************************************驱动层初始化***************************************************/
  899. //重置结构体
  900. memset(&ob_fml_imu,0,sizeof(ob_fml_imu));
  901. //初始化驱动LSM
  902. ret = drv_lsm_Init();
  903. //初始化驱动QMC
  904. ret += drv_qmc6310_Init();
  905. //获取驱动LSM配置参数
  906. drv_lsm_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm);
  907. //获取驱动LSM配置参数
  908. drv_qmc6310_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc);
  909. /***************************************业务逻辑层初始化***************************************************/
  910. //初始化IMU服务结构体
  911. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_DONE;
  912. //设置驱动配置线程
  913. Process_Start(0,"fml_imu_Process",fml_imu_Process);
  914. if(ret < 0)return -1;
  915. return 0;
  916. }
  917. /**
  918. @brief 设置需要配置IMU的参数
  919. @param param - [in] 设置IMU的参数
  920. @return 错误代码 - [out] -1失败,0成功
  921. */
  922. int fml_imu_config_param(FML_IMU_DIR_e dir, const fml_imu_param_t *param)
  923. {
  924. if(param == NULL || dir >= FML_IMU_DIR_NUM)return -1;
  925. memcpy(&ob_fml_imu.config_param[dir],param,sizeof(fml_imu_param_t));
  926. return 0;
  927. }
  928. /**
  929. @brief 注册IMU配置结果回调函数
  930. @param cb - [in] 回调函数
  931. @return 错误代码 - [out] -1失败,0成功
  932. */
  933. int fml_imu_register_config_callback(fml_imu_config_cb cb)
  934. {
  935. if(cb == NULL)return -1;
  936. ob_fml_imu.config_cb = cb;
  937. return 0;
  938. }
  939. /**
  940. @brief 注册IMU数据通知回调函数
  941. @param cb - [in] 回调函数
  942. @return 错误代码 - [out] -1失败,0成功
  943. */
  944. int fml_imu_register_data_notify_callback(fml_imu_data_notify_cb cb)
  945. {
  946. if(cb == NULL)return -1;
  947. ob_fml_imu.data_notify_cb = cb;
  948. return 0;
  949. }
  950. /**
  951. @brief 开始配置IMU
  952. @param param 无
  953. @return 返回配置状态: - [out] -1不需要重新配置,0需要重新配置
  954. */
  955. int fml_imu_start_config(void)
  956. {
  957. drv_param_u lsm_drv_param;
  958. drv_param_u qmc_drv_param;
  959. //获取驱动LSM配置参数
  960. drv_lsm_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm);
  961. //获取驱动QMC配置参数
  962. drv_qmc6310_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc);
  963. //转换参数
  964. fml_imu_macro_conversion(FML_IMU_DIR_FRONT, &ob_fml_imu.config_param[FML_IMU_DIR_FRONT], &lsm_drv_param);
  965. fml_imu_macro_conversion(FML_IMU_DIR_BACK, &ob_fml_imu.config_param[FML_IMU_DIR_BACK], &qmc_drv_param);
  966. //进行对比
  967. if((memcmp(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm,&lsm_drv_param.lsm,sizeof(lsm_drv_param.lsm)) != 0) || \
  968. (memcmp(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc,&qmc_drv_param.qmc,sizeof(qmc_drv_param.qmc)) != 0)
  969. )
  970. {
  971. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_IN_PROGRESS;
  972. ob_fml_imu.config_flow = 0;
  973. //全功率运行进行配置
  974. Process_SetHoldOn(fml_imu_Process,1);
  975. return 0;
  976. }
  977. return -1;
  978. }
  979. /**
  980. @brief 读取当前IMU数据的数量
  981. @param dir - [in] 方向
  982. @return 返回当前IMU数据的数量
  983. */
  984. int fml_imu_get_data_num(FML_IMU_DIR_e dir)
  985. {
  986. if(dir >= FML_IMU_DIR_NUM)return 0;
  987. return ob_fml_imu.cur_data_num[dir];
  988. }
  989. /**
  990. @brief 获取当前IMU数据
  991. @param dir - [in] 方向
  992. @param index - [in] 数据索引
  993. @param pdata - [out] 返回的IMU数据指针
  994. @return 错误代码 - [out] -1失败,0成功
  995. */
  996. int fml_imu_get_data(FML_IMU_DIR_e dir, int index, fml_imu_data_t *pdata)
  997. {
  998. if(index < 0 || pdata == NULL || dir >= FML_IMU_DIR_NUM)return -1;
  999. *pdata = ob_fml_imu.cur_data[dir][index];
  1000. return 0;
  1001. }
  1002. /**
  1003. @brief 关闭IMU
  1004. @param dir - [in] 方向
  1005. @return 错误代码 - [out] -1失败,0成功
  1006. */
  1007. int fml_imu_close(FML_IMU_DIR_e dir)
  1008. {
  1009. if(dir >= FML_IMU_DIR_NUM)return -1;
  1010. switch(dir)
  1011. {
  1012. case FML_IMU_DIR_FRONT:
  1013. drv_lsm_power_on(); //主要是复位结构体
  1014. drv_lsm_power_off();
  1015. memset(&ob_fml_imu.config_param[FML_IMU_DIR_FRONT],0,sizeof(ob_fml_imu.config_param[FML_IMU_DIR_FRONT]));
  1016. //获取驱动LSM配置参数
  1017. drv_lsm_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm);
  1018. //配置完成!
  1019. ob_fml_imu.config_flow = FML_IMU_CONFIG_FLOW_DONE;
  1020. break;
  1021. case FML_IMU_DIR_BACK:
  1022. drv_qmc6310_power_on(); //主要是复位结构体
  1023. drv_qmc6310_power_off();
  1024. memset(&ob_fml_imu.config_param[FML_IMU_DIR_BACK],0,sizeof(ob_fml_imu.config_param[FML_IMU_DIR_BACK]));
  1025. //获取驱动LSM配置参数
  1026. drv_qmc6310_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc);
  1027. //配置完成!
  1028. ob_fml_imu.config_flow = FML_IMU_CONFIG_FLOW_DONE;
  1029. break;
  1030. default:
  1031. break;
  1032. }
  1033. return 0;
  1034. }