fml_imu.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  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 "exception.h"
  43. #include "system.h"
  44. #include "drv_qmc6310_v2.h"
  45. #include "drv_lsm6ds3tr_c.h"
  46. #include "fml_imu.h"
  47. /*Private macro ------------------------------------------------------------------------------------------------------------------------------------*/
  48. #define FML_IMU_DATA_GROUP_NUM_MAX 20 //IMU能存储的最大数据组数
  49. /*STRUCTION ------------------------------------------------------------------------------------------------------------------------------------*/
  50. typedef enum {
  51. FML_IMU_CONFIG_STAGE_DONE, //配置完成阶段
  52. FML_IMU_CONFIG_STAGE_IN_PROGRESS, //配置进行阶段
  53. FML_IMU_CONFIG_STAGE_FAIL, //配置失败阶段
  54. } FML_IMU_CONFIG_STAGE_e;
  55. typedef union
  56. {
  57. drv_lsm_config_param_t lsm; //当前的LSM配置参数
  58. drv_qmc_config_param_t qmc; //当前的QMC配置参数
  59. } drv_param_u;
  60. typedef struct fml_imu
  61. {
  62. /*private member*/
  63. FML_IMU_CONFIG_STAGE_e stage; //配置流程状态
  64. drv_param_u drv_param[FML_IMU_DIR_NUM]; //驱动参数组
  65. fml_imu_param_t config_param[FML_IMU_DIR_NUM]; //配置参数组
  66. int cur_data_num[FML_IMU_DIR_NUM]; //当前的数据量
  67. fml_imu_data_t cur_data[FML_IMU_DIR_NUM][FML_IMU_DATA_GROUP_NUM_MAX]; //当前的IMU数据缓存区
  68. uint32_t config_flow; //配置流程
  69. fml_imu_config_cb config_cb; //配置回调
  70. fml_imu_data_notify_cb data_notify_cb; //数据通知回调
  71. } Fml_Imu_t;
  72. /*Local Variable ------------------------------------------------------------------------------------------------------------------------------------*/
  73. static Fml_Imu_t ob_fml_imu;
  74. /*Local Functions ------------------------------------------------------------------------------------------------------------------------------------*/
  75. static void fml_imu_macro_conversion(FML_IMU_DIR_e dir, fml_imu_param_t *config_param, drv_param_u *drv_param)
  76. {
  77. switch(dir)
  78. {
  79. case FML_IMU_DIR_FRONT:
  80. //acc_odr
  81. switch(config_param->acc_odr)
  82. {
  83. case FML_IMU_ACC_ODR_OFF:
  84. drv_param->lsm.acc_odr = LSM_ACC_ODR_OFF;
  85. break;
  86. case FML_IMU_ACC_ODR_104HZ:
  87. drv_param->lsm.acc_odr = LSM_ACC_ODR_104HZ;
  88. break;
  89. case FML_IMU_ACC_ODR_12HZ5:
  90. drv_param->lsm.acc_odr = LSM_ACC_ODR_12HZ5;
  91. break;
  92. }
  93. //gry_odr
  94. switch(config_param->gry_odr)
  95. {
  96. case FML_IMU_GRY_ODR_OFF:
  97. drv_param->lsm.gry_odr = LSM_GRY_ODR_OFF;
  98. break;
  99. case FML_IMU_GRY_ODR_104HZ:
  100. drv_param->lsm.gry_odr = LSM_GRY_ODR_104HZ;
  101. break;
  102. case FML_IMU_GRY_ODR_12HZ5:
  103. drv_param->lsm.gry_odr = LSM_GRY_ODR_12HZ5;
  104. break;
  105. }
  106. //mag_odr
  107. switch(config_param->mag_odr)
  108. {
  109. case FML_IMU_MAG_ODR_OFF:
  110. drv_param->lsm.mag_odr = LSM_MAG_ODR_OFF;
  111. break;
  112. case FML_IMU_MAG_ODR_10HZ:
  113. drv_param->lsm.mag_odr = LSM_MAG_ODR_10HZ;
  114. break;
  115. case FML_IMU_MAG_ODR_100HZ:
  116. drv_param->lsm.mag_odr = LSM_MAG_ODR_100HZ;
  117. break;
  118. case FML_IMU_MAG_ODR_200HZ:
  119. drv_param->lsm.mag_odr = LSM_MAG_ODR_200HZ;
  120. break;
  121. }
  122. //fifo_odr
  123. switch(config_param->fifo_odr)
  124. {
  125. case FML_IMU_FIFO_ODR_OFF:
  126. drv_param->lsm.fifo_odr = LSM_FIFO_ODR_OFF;
  127. break;
  128. case FML_IMU_FIFO_ODR_104HZ:
  129. drv_param->lsm.fifo_odr = LSM_FIFO_ODR_104HZ;
  130. break;
  131. }
  132. //acc_power_mode
  133. switch(config_param->acc_power_mode)
  134. {
  135. case FML_IMU_ACC_POWER_MODE_HIGH_PERFORMANCE:
  136. drv_param->lsm.acc_power_mode = LSM_ACC_POWER_MODE_HIGH_PERFORMANCE;
  137. break;
  138. case FML_IMU_ACC_POWER_MODE_NORMAL:
  139. drv_param->lsm.acc_power_mode = LSM_ACC_POWER_MODE_NORMAL;
  140. break;
  141. }
  142. //gry_power_mode
  143. switch(config_param->gry_power_mode)
  144. {
  145. case FML_IMU_GRY_POWER_MODE_HIGH_PERFORMANCE:
  146. drv_param->lsm.gry_power_mode = LSM_GRY_POWER_MODE_HIGH_PERFORMANCE;
  147. break;
  148. case FML_IMU_GRY_POWER_MODE_NORMAL:
  149. drv_param->lsm.gry_power_mode = LSM_GRY_POWER_MODE_NORMAL;
  150. break;
  151. }
  152. //acc_fs
  153. switch(config_param->acc_fs)
  154. {
  155. case FML_IMU_ACC_FS_2G:
  156. drv_param->lsm.acc_fs = LSM_ACC_FS_2G;
  157. break;
  158. case FML_IMU_ACC_FS_16G:
  159. drv_param->lsm.acc_fs = LSM_ACC_FS_16G;
  160. break;
  161. }
  162. //gry_fs
  163. switch(config_param->gry_fs)
  164. {
  165. case FML_IMU_GRY_FS_250DPS:
  166. drv_param->lsm.gry_fs = LSM_GRY_FS_250DPS;
  167. break;
  168. case FML_IMU_GRY_FS_2000DPS:
  169. drv_param->lsm.gry_fs = LSM_GRY_FS_2000DPS;
  170. break;
  171. }
  172. //mag_fs
  173. switch(config_param->mag_fs)
  174. {
  175. case FML_IMU_MAG_FS_30GS:
  176. drv_param->lsm.mag_fs = LSM_MAG_FS_30GS;
  177. break;
  178. }
  179. //timestamp_resolution
  180. switch(config_param->timestamp_resolution)
  181. {
  182. case FML_IMU_TIMESTAMP_6MS4:
  183. drv_param->lsm.timestamp_resolution = LSM_TIMESTAMP_6MS4;
  184. break;
  185. case FML_IMU_TIMESTAMP_25US:
  186. drv_param->lsm.timestamp_resolution = LSM_TIMESTAMP_25US;
  187. break;
  188. }
  189. //timestamp_switch
  190. switch(config_param->timestamp_switch)
  191. {
  192. case FML_IMU_TIMESTAMP_OFF:
  193. drv_param->lsm.timestamp_switch = LSM_TIMESTAMP_OFF;
  194. break;
  195. case FML_IMU_TIMESTAMP_ON:
  196. drv_param->lsm.timestamp_switch = LSM_TIMESTAMP_ON;
  197. break;
  198. }
  199. break;
  200. case FML_IMU_DIR_BACK:
  201. //mag_odr
  202. switch(config_param->mag_odr)
  203. {
  204. case FML_IMU_MAG_ODR_OFF:
  205. drv_param->qmc.mag_odr = QMC_MAG_ODR_OFF;
  206. break;
  207. case FML_IMU_MAG_ODR_10HZ:
  208. drv_param->qmc.mag_odr = QMC_MAG_ODR_10HZ;
  209. break;
  210. case FML_IMU_MAG_ODR_100HZ:
  211. drv_param->qmc.mag_odr = QMC_MAG_ODR_100HZ;
  212. break;
  213. case FML_IMU_MAG_ODR_200HZ:
  214. drv_param->qmc.mag_odr = QMC_MAG_ODR_200HZ;
  215. break;
  216. }
  217. //mag_fs
  218. switch(config_param->mag_fs)
  219. {
  220. case FML_IMU_MAG_FS_30GS:
  221. drv_param->qmc.mag_fs = QMC_MAG_FS_30GS;
  222. break;
  223. }
  224. break;
  225. default:
  226. break;
  227. }
  228. }
  229. static int fml_imu_intergrated_setting(void)
  230. {
  231. int ret;
  232. int lsm_mag_flow = drv_lsm_get_mag_odr_flow();
  233. int qmc_mag_flow = drv_qmc6310_get_mag_odr_flow();
  234. drv_param_u drv_param;
  235. switch(ob_fml_imu.config_flow)
  236. {
  237. case 0:
  238. //断电lsm
  239. ret = drv_lsm_power_off();
  240. if(ret != 0)return -1;
  241. //断电qmc
  242. ret = drv_qmc6310_power_off();
  243. if(ret != 0)return -1;
  244. //清空读取缓存
  245. ob_fml_imu.cur_data_num[FML_IMU_DIR_FRONT] = 0;
  246. //清空读取缓存
  247. ob_fml_imu.cur_data_num[FML_IMU_DIR_BACK] = 0;
  248. ob_fml_imu.config_flow = 1;
  249. break;
  250. case 1:
  251. //上电lsm
  252. ret = drv_lsm_power_on();
  253. if(ret != 0)return -1;
  254. //上电qmc
  255. ret = drv_qmc6310_power_on();
  256. if(ret != 0)return -1;
  257. ob_fml_imu.config_flow = 2;
  258. break;
  259. case FML_IMU_CONFIG_FLOW_DONE:
  260. //配置完成才能进来此处。。。。。。。
  261. break;
  262. default:
  263. //转换参数,用于配置驱动
  264. fml_imu_macro_conversion(FML_IMU_DIR_FRONT, &ob_fml_imu.config_param[FML_IMU_DIR_FRONT], &drv_param);
  265. fml_imu_macro_conversion(FML_IMU_DIR_BACK, &ob_fml_imu.config_param[FML_IMU_DIR_BACK], &drv_param);
  266. //配置lsm的地磁计采样频率
  267. if(ob_fml_imu.config_param[FML_IMU_DIR_FRONT].fifo_odr != FML_IMU_FIFO_ODR_OFF)
  268. {
  269. for(int i=1; i <=lsm_mag_flow;i++)
  270. {
  271. ret = drv_lsm_set_mag_odr(drv_param.lsm.mag_odr, 1, i);
  272. if(ret != 0)return -1;
  273. ob_fml_imu.config_flow++;
  274. }
  275. }
  276. else
  277. {
  278. for(int i=1; i <= lsm_mag_flow; i++)
  279. {
  280. ret = drv_lsm_set_mag_odr(drv_param.lsm.mag_odr, 0, i);
  281. if(ret != 0)return -1;
  282. ob_fml_imu.config_flow++;
  283. }
  284. }
  285. //配置lsm的加速度工作模式
  286. ret = drv_lsm_set_acc_power_mode(drv_param.lsm.acc_power_mode);
  287. if(ret != 0)return -1;
  288. ob_fml_imu.config_flow++;
  289. //配置lsm的陀螺仪工作模式
  290. ret = drv_lsm_set_gry_power_mode(drv_param.lsm.gry_power_mode);
  291. if(ret != 0)return -1;
  292. ob_fml_imu.config_flow++;
  293. //配置lsm的加速度量程
  294. ret = drv_lsm_set_acc_fs(drv_param.lsm.acc_fs);
  295. if(ret != 0)return -1;
  296. ob_fml_imu.config_flow++;
  297. //配置lsm的陀螺仪量程
  298. ret = drv_lsm_set_gry_fs(drv_param.lsm.gry_fs);
  299. if(ret != 0)return -1;
  300. ob_fml_imu.config_flow++;
  301. //配置lsm的时间戳精度
  302. ret = drv_lsm_set_timestamp_resolution(drv_param.lsm.timestamp_resolution);
  303. if(ret != 0)return -1;
  304. ob_fml_imu.config_flow++;
  305. //配置lsm的时间戳开关
  306. ret = drv_lsm_set_timestamp_switch(drv_param.lsm.timestamp_switch);
  307. if(ret != 0)return -1;
  308. ob_fml_imu.config_flow++;
  309. //配置lsm的FIFO采样频率(必须以上都配置成功,才能配置FIFO)
  310. ret = drv_lsm_set_fifo_odr(drv_param.lsm.fifo_odr, \
  311. drv_param.lsm.acc_odr, \
  312. drv_param.lsm.gry_odr, \
  313. drv_param.lsm.mag_odr, \
  314. drv_param.lsm.timestamp_switch);
  315. if(ret != 0)return -1;
  316. ob_fml_imu.config_flow++;
  317. //配置lsm的加速度采样频率
  318. ret = drv_lsm_set_acc_odr(drv_param.lsm.acc_odr);
  319. if(ret != 0)return -1;
  320. ob_fml_imu.config_flow++;
  321. //配置lsm的陀螺仪采样频率
  322. ret = drv_lsm_set_gry_odr(drv_param.lsm.gry_odr);
  323. if(ret != 0)return -1;
  324. ob_fml_imu.config_flow++;
  325. //配置qmc的地磁计采样频率
  326. for(int i = 1; i <=qmc_mag_flow; i++)
  327. {
  328. ret = drv_qmc6310_set_mag_odr(drv_param.qmc.mag_odr,i);
  329. if(ret != 0)return -1;
  330. ob_fml_imu.config_flow++;
  331. }
  332. //配置完成!
  333. ob_fml_imu.config_flow = FML_IMU_CONFIG_FLOW_DONE;
  334. break;
  335. }
  336. return 0;
  337. }
  338. static int fml_imu_read_data_lsm(void)
  339. {
  340. int i;
  341. int fifo_group_num;
  342. lsm_data_t temp_lsm_data;
  343. //读取FIFO数据
  344. if(ob_fml_imu.config_param[FML_IMU_DIR_FRONT].fifo_odr != FML_IMU_FIFO_ODR_OFF)
  345. {
  346. //获取当前fifo里存在多少组数据。
  347. fifo_group_num = drv_lsm_get_fifo_group_num();
  348. fifo_group_num = fifo_group_num <= FML_IMU_DATA_GROUP_NUM_MAX ? fifo_group_num : FML_IMU_DATA_GROUP_NUM_MAX;
  349. if(fifo_group_num > 0)
  350. {
  351. for(i=0; i<fifo_group_num; i++)
  352. {
  353. if(drv_lsm_get_fifo_data(&temp_lsm_data) != -1)
  354. {
  355. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[0] = temp_lsm_data.acc[0];
  356. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[1] = temp_lsm_data.acc[1];
  357. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[2] = temp_lsm_data.acc[2];
  358. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[0] = temp_lsm_data.gry[0];
  359. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[1] = temp_lsm_data.gry[1];
  360. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[2] = temp_lsm_data.gry[2];
  361. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[0] = temp_lsm_data.mag[0];
  362. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[1] = temp_lsm_data.mag[1];
  363. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[2] = temp_lsm_data.mag[2];
  364. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].fifo_timestamp = temp_lsm_data.fifo_timestamp;
  365. }
  366. else
  367. {
  368. break;
  369. }
  370. }
  371. }
  372. else
  373. {
  374. return 0;
  375. }
  376. return i;
  377. }
  378. //只读取ACC数据
  379. else if(ob_fml_imu.config_param[FML_IMU_DIR_FRONT].acc_odr != FML_IMU_ACC_ODR_OFF && \
  380. ob_fml_imu.config_param[FML_IMU_DIR_FRONT].gry_odr == FML_IMU_GRY_ODR_OFF && \
  381. ob_fml_imu.config_param[FML_IMU_DIR_FRONT].mag_odr == FML_IMU_MAG_ODR_OFF \
  382. )
  383. {
  384. if(drv_lsm_get_acc_data(&temp_lsm_data) != -1)
  385. {
  386. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][0].acc[0] = temp_lsm_data.acc[0];
  387. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][0].acc[1] = temp_lsm_data.acc[1];
  388. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][0].acc[2] = temp_lsm_data.acc[2];
  389. return 1;
  390. }
  391. }
  392. return 0;
  393. }
  394. static int fml_imu_read_data_qmc(void)
  395. {
  396. qmc_data_t temp_qmc_data;
  397. if(ob_fml_imu.config_param[FML_IMU_DIR_BACK].mag_odr != FML_IMU_MAG_ODR_OFF)
  398. {
  399. if(drv_qmc6310_get_mag_data(&temp_qmc_data) != -1)
  400. {
  401. ob_fml_imu.cur_data[FML_IMU_DIR_BACK][0].mag[0] = temp_qmc_data.mag[0];
  402. ob_fml_imu.cur_data[FML_IMU_DIR_BACK][0].mag[1] = temp_qmc_data.mag[1];
  403. ob_fml_imu.cur_data[FML_IMU_DIR_BACK][0].mag[2] = temp_qmc_data.mag[2];
  404. return 1;
  405. }
  406. }
  407. return 0;
  408. }
  409. static int hal_ser_imu_read_data(FML_IMU_DIR_e dir)
  410. {
  411. int ret = 0;
  412. switch(dir)
  413. {
  414. case FML_IMU_DIR_FRONT:
  415. ret = fml_imu_read_data_lsm();
  416. break;
  417. case FML_IMU_DIR_BACK:
  418. ret = fml_imu_read_data_qmc();
  419. break;
  420. default:
  421. break;
  422. }
  423. return ret;
  424. }
  425. static void fml_imu_Process(void)
  426. {
  427. int data_num[FML_IMU_DIR_NUM];
  428. uint32_t dir_bit;
  429. switch(ob_fml_imu.stage)
  430. {
  431. case FML_IMU_CONFIG_STAGE_DONE: //配置完成阶段
  432. dir_bit = 0;
  433. //读取前脚IMU数据 + 更新前脚IMU数据量
  434. data_num[FML_IMU_DIR_FRONT] = hal_ser_imu_read_data(FML_IMU_DIR_FRONT);
  435. if(data_num[FML_IMU_DIR_FRONT] > 0){
  436. ob_fml_imu.cur_data_num[FML_IMU_DIR_FRONT] = data_num[FML_IMU_DIR_FRONT];
  437. dir_bit |= (1 << FML_IMU_DIR_FRONT);
  438. }
  439. //读取后脚IMU数据 + 更新后脚IMU数据量
  440. data_num[FML_IMU_DIR_BACK] = hal_ser_imu_read_data(FML_IMU_DIR_BACK);
  441. if(data_num[FML_IMU_DIR_BACK] > 0){
  442. ob_fml_imu.cur_data_num[FML_IMU_DIR_BACK] = data_num[FML_IMU_DIR_BACK];
  443. dir_bit |= (1 << FML_IMU_DIR_BACK);
  444. }
  445. //数据回调通知
  446. if(dir_bit != 0)ob_fml_imu.data_notify_cb(dir_bit);
  447. break;
  448. case FML_IMU_CONFIG_STAGE_IN_PROGRESS: //配置进行阶段
  449. if(fml_imu_intergrated_setting() == -1)
  450. {
  451. //配置失败
  452. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_FAIL;
  453. //断电前后脚
  454. fml_imu_close(FML_IMU_DIR_FRONT);
  455. fml_imu_close(FML_IMU_DIR_BACK);
  456. //通知配置失败
  457. ob_fml_imu.config_cb(ob_fml_imu.config_flow);
  458. }
  459. else
  460. {
  461. if(ob_fml_imu.config_flow == FML_IMU_CONFIG_FLOW_DONE)
  462. {
  463. //配置成功
  464. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_DONE;
  465. //通知配置成功
  466. ob_fml_imu.config_cb(ob_fml_imu.config_flow);
  467. }
  468. }
  469. break;
  470. default:
  471. break;
  472. }
  473. }
  474. /*API ------------------------------------------------------------------------------------------------------------------------------------*/
  475. /**
  476. @brief 初始化IMU功能模块
  477. @param 无
  478. @return 错误代码 - [out] -1失败,0成功
  479. */
  480. int fml_imu_Init(void)
  481. {
  482. int ret;
  483. /***************************************驱动层初始化***************************************************/
  484. //重置结构体
  485. memset(&ob_fml_imu,0,sizeof(ob_fml_imu));
  486. //初始化驱动LSM
  487. ret = drv_lsm_Init();
  488. //初始化驱动QMC
  489. ret += drv_qmc6310_Init();
  490. //获取驱动LSM配置参数
  491. drv_lsm_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm);
  492. //获取驱动LSM配置参数
  493. drv_qmc6310_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc);
  494. /***************************************业务逻辑层初始化***************************************************/
  495. //初始化IMU服务结构体
  496. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_DONE;
  497. //设置驱动配置线程
  498. Process_Start(0,"fml_imu_Process",fml_imu_Process);
  499. if(ret < 0)return -1;
  500. return 0;
  501. }
  502. /**
  503. @brief 设置需要配置IMU的参数
  504. @param param - [in] 设置IMU的参数
  505. @return 错误代码 - [out] -1失败,0成功
  506. */
  507. int fml_imu_config_param(FML_IMU_DIR_e dir, fml_imu_param_t *param)
  508. {
  509. if(param == NULL || dir >= FML_IMU_DIR_NUM)return -1;
  510. memcpy(&ob_fml_imu.config_param[dir],param,sizeof(fml_imu_param_t));
  511. return 0;
  512. }
  513. /**
  514. @brief 开始配置IMU
  515. @param param 无
  516. @return 错误代码 - [out] -1失败,0成功
  517. */
  518. int fml_imu_start_config(void)
  519. {
  520. drv_param_u drv_param;
  521. //获取驱动LSM配置参数
  522. drv_lsm_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm);
  523. //获取驱动LSM配置参数
  524. drv_qmc6310_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc);
  525. //转换参数
  526. fml_imu_macro_conversion(FML_IMU_DIR_FRONT, &ob_fml_imu.config_param[FML_IMU_DIR_FRONT], &drv_param);
  527. fml_imu_macro_conversion(FML_IMU_DIR_BACK, &ob_fml_imu.config_param[FML_IMU_DIR_BACK], &drv_param);
  528. //进行对比
  529. if((memcmp(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm,&drv_param.lsm,sizeof(drv_param.lsm)) == 0) || \
  530. (memcmp(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc,&drv_param.qmc,sizeof(drv_param.qmc)) == 0)
  531. )
  532. {
  533. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_IN_PROGRESS;
  534. ob_fml_imu.config_flow = 0;
  535. }
  536. return 0;
  537. }
  538. /**
  539. @brief 注册IMU配置结果回调函数
  540. @param cb - [in] 回调函数
  541. @return 错误代码 - [out] -1失败,0成功
  542. */
  543. int fml_imu_register_config_callback(fml_imu_config_cb cb)
  544. {
  545. if(cb == NULL)return -1;
  546. ob_fml_imu.config_cb = cb;
  547. return 0;
  548. }
  549. /**
  550. @brief 注册IMU数据通知回调函数
  551. @param cb - [in] 回调函数
  552. @return 错误代码 - [out] -1失败,0成功
  553. */
  554. int fml_imu_register_data_notify_callback(fml_imu_data_notify_cb cb)
  555. {
  556. if(cb == NULL)return -1;
  557. ob_fml_imu.data_notify_cb = cb;
  558. return 0;
  559. }
  560. /**
  561. @brief 读取当前IMU数据的数量
  562. @param dir - [in] 方向
  563. @return 返回当前IMU数据的数量
  564. */
  565. int fml_imu_get_data_num(FML_IMU_DIR_e dir)
  566. {
  567. if(dir >= FML_IMU_DIR_NUM)return 0;
  568. return ob_fml_imu.cur_data_num[dir];
  569. }
  570. /**
  571. @brief 获取当前IMU数据
  572. @param dir - [in] 方向
  573. @param index - [in] 数据索引
  574. @param pdata - [out] 返回的IMU数据指针
  575. @return 错误代码 - [out] -1失败,0成功
  576. */
  577. int fml_imu_get_data(FML_IMU_DIR_e dir, int index, fml_imu_data_t *pdata)
  578. {
  579. if(index < 0 || pdata == NULL || dir >= FML_IMU_DIR_NUM)return -1;
  580. *pdata = ob_fml_imu.cur_data[dir][index];
  581. return 0;
  582. }
  583. /**
  584. @brief 关闭IMU
  585. @param dir - [in] 方向
  586. @return 错误代码 - [out] -1失败,0成功
  587. */
  588. int fml_imu_close(FML_IMU_DIR_e dir)
  589. {
  590. if(dir >= FML_IMU_DIR_NUM)return -1;
  591. switch(dir)
  592. {
  593. case FML_IMU_DIR_FRONT:
  594. drv_lsm_power_on(); //主要是复位结构体
  595. drv_lsm_power_off();
  596. break;
  597. case FML_IMU_DIR_BACK:
  598. drv_qmc6310_power_on(); //主要是复位结构体
  599. drv_qmc6310_power_off();
  600. break;
  601. default:
  602. break;
  603. }
  604. return 0;
  605. }