hal_ser_imu.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. /*Includes ----------------------------------------------*/
  2. #include "system.h"
  3. #include "hal_ser_imu.h"
  4. /*Private macro ------------------------------------------------------------------------------------------------------------------------------------*/
  5. #define SER_IMU_HANDLE_NUM_MAX 10 //允许最大的句柄数量
  6. #define INVALID_HANDLE 0x00 //无效句柄
  7. #define VALID_HANDLE 0x01 //有效句柄
  8. #define MAX(a,b) (((a) > (b)) ? (a) : (b)) //对比大小宏
  9. #define IS_EQUAL(a,b) (((a) == (b)) ? true : false) //对比相等宏
  10. #define SER_IMU_DATA_GROUP_NUM_MAX 20 //服务IMU最大数据组数
  11. /*STRUCTION ------------------------------------------------------------------------------------------------------------------------------------*/
  12. typedef enum {
  13. IMU_CONFIG_STAGE_DONE, //配置完成阶段
  14. IMU_CONFIG_STAGE_IN_PROGRESS, //配置进行阶段
  15. } IMU_CONFIG_STAGE_e;
  16. typedef struct
  17. {
  18. int id; //句柄id
  19. char *name; //句柄名称
  20. ser_imu_config_param_t op_param[SER_IMU_DIR_NUM]; //操作的IMU配置参数副本
  21. } ser_imu_handle_t;
  22. typedef union
  23. {
  24. drv_lsm_config_param_t lsm; //当前的LSM配置参数
  25. drv_qmc_config_param_t qmc; //当前的QMC配置参数
  26. } drv_param_u;
  27. typedef struct ser_imu
  28. {
  29. /*private member*/
  30. IMU_CONFIG_STAGE_e stage; //配置流程状态
  31. bool is_need_config[SER_IMU_DIR_NUM]; //各个方位的IMU是否需要配置
  32. ser_imu_handle_t handle[SER_IMU_HANDLE_NUM_MAX]; //句柄组
  33. drv_param_u drv_param[SER_IMU_DIR_NUM]; //驱动配置参数组
  34. ser_imu_config_param_t compre_drv_param[SER_IMU_DIR_NUM]; //综合的驱动配置参数
  35. int cur_data_num[SER_IMU_DIR_NUM]; //当前的数据量
  36. ser_imu_data_t cur_data[SER_IMU_DIR_NUM][SER_IMU_DATA_GROUP_NUM_MAX]; //当前的IMU数据缓存区
  37. } Ser_Imu_t;
  38. /*Local Variable ------------------------------------------------------------------------------------------------------------------------------------*/
  39. static Ser_Imu_t ob_ser_imu;
  40. /*Local Functions ------------------------------------------------------------------------------------------------------------------------------------*/
  41. static int hal_ser_imu_macro_conversion_acc_odr(SER_IMU_DIR_e dir, SER_IMU_ACC_ODR_e acc_odr)
  42. {
  43. int ret = 0;
  44. if(dir == SER_IMU_DIR_FRONT)
  45. {
  46. switch(acc_odr)
  47. {
  48. case SER_IMU_ACC_ODR_OFF:
  49. ret = LSM_ACC_ODR_OFF;
  50. break;
  51. case SER_IMU_ACC_ODR_104HZ:
  52. ret = LSM_ACC_ODR_104HZ;
  53. break;
  54. case SER_IMU_ACC_ODR_12HZ5:
  55. ret = LSM_ACC_ODR_12HZ5;
  56. break;
  57. }
  58. }
  59. return ret;
  60. }
  61. static int hal_ser_imu_macro_conversion_gry_odr(SER_IMU_DIR_e dir, SER_IMU_GRY_ODR_e gry_odr)
  62. {
  63. int ret = 0;
  64. if(dir == SER_IMU_DIR_FRONT)
  65. {
  66. switch(gry_odr)
  67. {
  68. case SER_IMU_GRY_ODR_OFF:
  69. ret = LSM_GRY_ODR_OFF;
  70. break;
  71. case SER_IMU_GRY_ODR_104HZ:
  72. ret = LSM_GRY_ODR_104HZ;
  73. break;
  74. case SER_IMU_GRY_ODR_12HZ5:
  75. ret = LSM_GRY_ODR_12HZ5;
  76. break;
  77. }
  78. }
  79. return ret;
  80. }
  81. static int hal_ser_imu_macro_conversion_mag_odr(SER_IMU_DIR_e dir, SER_IMU_MAG_ODR_e mag_odr)
  82. {
  83. int ret = 0;
  84. if(dir == SER_IMU_DIR_FRONT)
  85. {
  86. switch(mag_odr)
  87. {
  88. case SER_IMU_MAG_ODR_OFF:
  89. ret = LSM_MAG_ODR_OFF;
  90. break;
  91. case SER_IMU_MAG_ODR_10HZ:
  92. ret = LSM_MAG_ODR_10HZ;
  93. break;
  94. case SER_IMU_MAG_ODR_100HZ:
  95. ret = LSM_MAG_ODR_100HZ;
  96. break;
  97. case SER_IMU_MAG_ODR_200HZ:
  98. ret = LSM_MAG_ODR_200HZ;
  99. break;
  100. }
  101. }
  102. if(dir == SER_IMU_DIR_BACK)
  103. {
  104. switch(mag_odr)
  105. {
  106. case SER_IMU_MAG_ODR_OFF:
  107. ret = QMC_MAG_ODR_OFF;
  108. break;
  109. case SER_IMU_MAG_ODR_10HZ:
  110. ret = QMC_MAG_ODR_10HZ;
  111. break;
  112. case SER_IMU_MAG_ODR_100HZ:
  113. ret = QMC_MAG_ODR_100HZ;
  114. break;
  115. case SER_IMU_MAG_ODR_200HZ:
  116. ret = QMC_MAG_ODR_200HZ;
  117. break;
  118. }
  119. }
  120. return ret;
  121. }
  122. static int hal_ser_imu_macro_conversion_fifo_odr(SER_IMU_DIR_e dir, SER_IMU_FIFO_ODR_e fifo_odr)
  123. {
  124. int ret = 0;
  125. if(dir == SER_IMU_DIR_FRONT)
  126. {
  127. switch(fifo_odr)
  128. {
  129. case SER_IMU_FIFO_ODR_OFF:
  130. ret = LSM_FIFO_ODR_OFF;
  131. break;
  132. case SER_IMU_FIFO_ODR_104HZ:
  133. ret = LSM_FIFO_ODR_104HZ;
  134. break;
  135. }
  136. }
  137. return ret;
  138. }
  139. static int hal_ser_imu_macro_conversion_acc_power_mode(SER_IMU_DIR_e dir, SER_IMU_ACC_POWER_MODE_e acc_power_mode)
  140. {
  141. int ret = 0;
  142. if(dir == SER_IMU_DIR_FRONT)
  143. {
  144. switch(acc_power_mode)
  145. {
  146. case SER_IMU_ACC_POWER_MODE_HIGH_PERFORMANCE:
  147. ret = LSM_ACC_POWER_MODE_HIGH_PERFORMANCE;
  148. break;
  149. case SER_IMU_ACC_POWER_MODE_NORMAL:
  150. ret = LSM_ACC_POWER_MODE_NORMAL;
  151. break;
  152. }
  153. }
  154. return ret;
  155. }
  156. static int hal_ser_imu_macro_conversion_gry_power_mode(SER_IMU_DIR_e dir, SER_IMU_GRY_POWER_MODE_e gry_power_mode)
  157. {
  158. int ret = 0;
  159. if(dir == SER_IMU_DIR_FRONT)
  160. {
  161. switch(gry_power_mode)
  162. {
  163. case SER_IMU_GRY_POWER_MODE_HIGH_PERFORMANCE:
  164. ret = LSM_GRY_POWER_MODE_HIGH_PERFORMANCE;
  165. break;
  166. case SER_IMU_GRY_POWER_MODE_NORMAL:
  167. ret = LSM_GRY_POWER_MODE_NORMAL;
  168. break;
  169. }
  170. }
  171. return ret;
  172. }
  173. static int hal_ser_imu_macro_conversion_acc_fs(SER_IMU_DIR_e dir, SER_IMU_ACC_FS_e acc_fs)
  174. {
  175. int ret = 0;
  176. if(dir == SER_IMU_DIR_FRONT)
  177. {
  178. switch(acc_fs)
  179. {
  180. case SER_IMU_ACC_FS_2G:
  181. ret = LSM_ACC_FS_2G;
  182. break;
  183. case SER_IMU_ACC_FS_16G:
  184. ret = LSM_ACC_FS_16G;
  185. break;
  186. }
  187. }
  188. return ret;
  189. }
  190. static int hal_ser_imu_macro_conversion_gry_fs(SER_IMU_DIR_e dir, SER_IMU_GRY_FS_e gry_fs)
  191. {
  192. int ret = 0;
  193. if(dir == SER_IMU_DIR_FRONT)
  194. {
  195. switch(gry_fs)
  196. {
  197. case SER_IMU_GRY_FS_250DPS:
  198. ret = LSM_GRY_FS_250DPS;
  199. break;
  200. case SER_IMU_GRY_FS_2000DPS:
  201. ret = LSM_GRY_FS_2000DPS;
  202. break;
  203. }
  204. }
  205. return ret;
  206. }
  207. static int hal_ser_imu_macro_conversion_mag_fs(SER_IMU_DIR_e dir, SER_IMU_MAG_FS_e mag_fs)
  208. {
  209. int ret = 0;
  210. if(dir == SER_IMU_DIR_FRONT)
  211. {
  212. switch(mag_fs)
  213. {
  214. case SER_IMU_MAG_FS_30GS:
  215. ret = LSM_MAG_FS_30GS;
  216. break;
  217. }
  218. }
  219. if(dir == SER_IMU_DIR_BACK)
  220. {
  221. switch(mag_fs)
  222. {
  223. case SER_IMU_MAG_FS_30GS:
  224. ret = QMC_MAG_FS_30GS;
  225. break;
  226. }
  227. }
  228. return ret;
  229. }
  230. static int hal_ser_imu_macro_conversion_timestamp_resolution(SER_IMU_DIR_e dir, SER_IMU_TIMESTAMP_RESOLUTION_e timestamp_resolution)
  231. {
  232. int ret = 0;
  233. if(dir == SER_IMU_DIR_FRONT)
  234. {
  235. switch(timestamp_resolution)
  236. {
  237. case SER_IMU_TIMESTAMP_6MS4:
  238. ret = LSM_TIMESTAMP_6MS4;
  239. break;
  240. case SER_IMU_TIMESTAMP_25US:
  241. ret = LSM_TIMESTAMP_25US;
  242. break;
  243. }
  244. }
  245. return ret;
  246. }
  247. static int hal_ser_imu_macro_conversion_timestamp_switch(SER_IMU_DIR_e dir, SER_IMU_TIMESTAMP_SWITCH_e timestamp_switch)
  248. {
  249. int ret = 0;
  250. if(dir == SER_IMU_DIR_FRONT)
  251. {
  252. switch(timestamp_switch)
  253. {
  254. case SER_IMU_TIMESTAMP_OFF:
  255. ret = LSM_TIMESTAMP_OFF;
  256. break;
  257. case SER_IMU_TIMESTAMP_ON:
  258. ret = LSM_TIMESTAMP_ON;
  259. break;
  260. }
  261. }
  262. return ret;
  263. }
  264. static void hal_ser_imu_get_compre_param(ser_imu_config_param_t *compre_drv_param, ser_imu_config_param_t *op_param)
  265. {
  266. compre_drv_param->acc_fs = MAX(compre_drv_param->acc_fs, op_param->acc_fs);
  267. compre_drv_param->acc_odr = MAX(compre_drv_param->acc_odr, op_param->acc_odr);
  268. compre_drv_param->acc_power_mode = MAX(compre_drv_param->acc_power_mode, op_param->acc_power_mode);
  269. compre_drv_param->fifo_odr = MAX(compre_drv_param->fifo_odr, op_param->fifo_odr);
  270. compre_drv_param->gry_fs = MAX(compre_drv_param->gry_fs, op_param->gry_fs);
  271. compre_drv_param->gry_odr = MAX(compre_drv_param->gry_odr, op_param->gry_odr);
  272. compre_drv_param->gry_power_mode = MAX(compre_drv_param->gry_power_mode, op_param->gry_power_mode);
  273. compre_drv_param->mag_fs = MAX(compre_drv_param->mag_fs, op_param->mag_fs);
  274. compre_drv_param->mag_odr = MAX(compre_drv_param->mag_odr, op_param->mag_odr);
  275. compre_drv_param->timestamp_resolution = MAX(compre_drv_param->timestamp_resolution, op_param->timestamp_resolution);
  276. compre_drv_param->timestamp_switch = MAX(compre_drv_param->timestamp_switch, op_param->timestamp_switch);
  277. }
  278. static bool hal_ser_imu_param_is_equal_drv_param_lsm(ser_imu_config_param_t *compre_drv_param, drv_param_u *drv_param)
  279. {
  280. if(IS_EQUAL(compre_drv_param->acc_fs,drv_param->lsm.acc_fs) == false){return false;}
  281. if(IS_EQUAL(compre_drv_param->acc_odr,drv_param->lsm.acc_odr) == false){return false;}
  282. if(IS_EQUAL(compre_drv_param->acc_power_mode,drv_param->lsm.acc_power_mode) == false){return false;}
  283. if(IS_EQUAL(compre_drv_param->fifo_odr,drv_param->lsm.fifo_odr) == false){return false;}
  284. if(IS_EQUAL(compre_drv_param->gry_fs,drv_param->lsm.gry_fs) == false){return false;}
  285. if(IS_EQUAL(compre_drv_param->gry_odr,drv_param->lsm.gry_odr) == false){return false;}
  286. if(IS_EQUAL(compre_drv_param->gry_power_mode,drv_param->lsm.gry_power_mode) == false){return false;}
  287. if(IS_EQUAL(compre_drv_param->mag_fs,drv_param->lsm.mag_fs) == false){return false;}
  288. if(IS_EQUAL(compre_drv_param->mag_odr,drv_param->lsm.mag_odr) == false){return false;}
  289. if(IS_EQUAL(compre_drv_param->timestamp_resolution,drv_param->lsm.timestamp_resolution) == false){return false;}
  290. if(IS_EQUAL(compre_drv_param->timestamp_switch,drv_param->lsm.timestamp_switch) == false){return false;}
  291. return true;
  292. }
  293. static bool hal_ser_imu_param_is_equal_drv_param_qmc(ser_imu_config_param_t *compre_drv_param, drv_param_u *drv_param)
  294. {
  295. if(IS_EQUAL(compre_drv_param->mag_fs, drv_param->qmc.mag_fs) == false){return false;}
  296. if(IS_EQUAL(compre_drv_param->mag_odr, drv_param->qmc.mag_odr) == false){return false;}
  297. return true;
  298. }
  299. static bool hal_ser_imu_is_need_config(void)
  300. {
  301. int i;
  302. //重新获取综合的前脚配置,根据优先级来判定
  303. memset(&ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT],0,sizeof(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT]));
  304. for(i=0; i<SER_IMU_HANDLE_NUM_MAX; i++)
  305. {
  306. if(ob_ser_imu.handle[i].id == VALID_HANDLE)
  307. {
  308. hal_ser_imu_get_compre_param(&ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT], &ob_ser_imu.handle[i].op_param[SER_IMU_DIR_FRONT]);
  309. }
  310. }
  311. //重新获取驱动LSM配置参数
  312. drv_lsm_get_config_param(&ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm);
  313. //判断综合的前脚配置与当前的驱动配置是否一致
  314. if(hal_ser_imu_param_is_equal_drv_param_lsm(&ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT], &ob_ser_imu.drv_param[SER_IMU_DIR_FRONT]) == false)
  315. {
  316. ob_ser_imu.is_need_config[SER_IMU_DIR_FRONT] = true;
  317. }
  318. /************************************************************************************************************************************************/
  319. //重新获取综合的后脚配置,根据优先级来判定
  320. memset(&ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK],0,sizeof(ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK]));
  321. for(i=0; i<SER_IMU_HANDLE_NUM_MAX; i++)
  322. {
  323. if(ob_ser_imu.handle[i].id == VALID_HANDLE)
  324. {
  325. hal_ser_imu_get_compre_param(&ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK], &ob_ser_imu.handle[i].op_param[SER_IMU_DIR_BACK]);
  326. }
  327. }
  328. //重新获取驱动QMC配置参数
  329. drv_qmc6310_get_config_param(&ob_ser_imu.drv_param[SER_IMU_DIR_BACK].qmc);
  330. //判断综合的前脚配置与当前的驱动配置是否一致
  331. if(hal_ser_imu_param_is_equal_drv_param_qmc(&ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK], &ob_ser_imu.drv_param[SER_IMU_DIR_BACK]) == false)
  332. {
  333. ob_ser_imu.is_need_config[SER_IMU_DIR_BACK] = true;
  334. }
  335. /************************************************************************************************************************************************/
  336. for(i=0; i<SER_IMU_DIR_NUM; i++)
  337. {
  338. if(ob_ser_imu.is_need_config[i] == true){
  339. return true;
  340. }
  341. }
  342. return false;
  343. }
  344. static bool hal_ser_imu_config_dir_front(void)
  345. {
  346. int ret = 0;
  347. static int imu_config_flow_ctl = 0; //配置流程控制
  348. switch(imu_config_flow_ctl)
  349. {
  350. case 0:
  351. //配置lsm挂起
  352. if(drv_lsm_suspend() == 0){imu_config_flow_ctl = 1;}
  353. break;
  354. case 1:
  355. //配置lsm的地磁计采样频率
  356. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].fifo_odr != SER_IMU_FIFO_ODR_OFF)
  357. {
  358. //使用hub
  359. if(drv_lsm_set_mag_odr((LSM_MAG_ODR_e)hal_ser_imu_macro_conversion_mag_odr(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_odr), 1)){
  360. imu_config_flow_ctl = 2;
  361. }
  362. }
  363. else
  364. {
  365. //不使用hub
  366. if(drv_lsm_set_mag_odr((LSM_MAG_ODR_e)hal_ser_imu_macro_conversion_mag_odr(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_odr), 0)){
  367. imu_config_flow_ctl = 2;
  368. }
  369. }
  370. break;
  371. case 2:
  372. //配置lsm的加速度工作模式
  373. ret += drv_lsm_set_acc_power_mode((LSM_ACC_POWER_MODE_e)hal_ser_imu_macro_conversion_acc_power_mode(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_power_mode));
  374. //配置lsm的陀螺仪工作模式
  375. ret += drv_lsm_set_gry_power_mode((LSM_GRY_POWER_MODE_e)hal_ser_imu_macro_conversion_gry_power_mode(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_power_mode));
  376. //配置lsm的加速度量程
  377. ret += drv_lsm_set_acc_fs((LSM_ACC_FS_e)hal_ser_imu_macro_conversion_acc_fs(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_fs));
  378. //配置lsm的陀螺仪量程
  379. ret += drv_lsm_set_gry_fs((LSM_GRY_FS_e)hal_ser_imu_macro_conversion_gry_fs(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_fs));
  380. //配置lsm的时间戳精度
  381. ret += drv_lsm_set_timestamp_resolution((LSM_TIMESTAMP_RESOLUTION_e)hal_ser_imu_macro_conversion_timestamp_resolution(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_resolution));
  382. //配置lsm的时间戳开关
  383. ret += drv_lsm_set_timestamp_switch((LSM_TIMESTAMP_SWITCH_e)hal_ser_imu_macro_conversion_timestamp_switch(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_switch));
  384. //配置lsm的FIFO采样频率
  385. ret += drv_lsm_set_fifo_odr((LSM_FIFO_ODR_e)hal_ser_imu_macro_conversion_fifo_odr(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].fifo_odr));
  386. if(ret != -1)
  387. {
  388. imu_config_flow_ctl = 3;
  389. }
  390. break;
  391. case 3:
  392. //配置lsm的加速度采样频率
  393. ret += drv_lsm_set_acc_odr((LSM_ACC_ODR_e)hal_ser_imu_macro_conversion_acc_odr(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_odr));
  394. //配置lsm的陀螺仪采样频率
  395. ret += drv_lsm_set_gry_odr((LSM_GRY_ODR_e)hal_ser_imu_macro_conversion_gry_odr(SER_IMU_DIR_FRONT,ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_odr));
  396. if(ret != -1)
  397. {
  398. return true;
  399. }
  400. break;
  401. }
  402. return false;
  403. }
  404. static bool hal_ser_imu_config_dir_back(void)
  405. {
  406. int ret = 0;
  407. static int imu_config_flow_ctl = 0; //配置流程控制
  408. switch(imu_config_flow_ctl)
  409. {
  410. case 0:
  411. //配置qmc挂起
  412. if(drv_qmc6310_suspend() == 0){imu_config_flow_ctl = 1;}
  413. break;
  414. case 1:
  415. //配置qmc的地磁计采样频率
  416. ret += drv_qmc6310_set_mag_odr((QMC_MAG_ODR_e)hal_ser_imu_macro_conversion_mag_odr(SER_IMU_DIR_BACK,ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_odr));
  417. if(ret != -1)
  418. {
  419. return true;
  420. }
  421. break;
  422. }
  423. return false;
  424. }
  425. static bool hal_ser_imu_is_config_done(SER_IMU_DIR_e dir)
  426. {
  427. bool ret = true;
  428. switch(dir)
  429. {
  430. case SER_IMU_DIR_FRONT:
  431. ret = hal_ser_imu_config_dir_front();
  432. break;
  433. case SER_IMU_DIR_BACK:
  434. ret = hal_ser_imu_config_dir_back();
  435. break;
  436. default:
  437. break;
  438. }
  439. return ret;
  440. }
  441. static int hal_ser_imu_read_data_lsm(void)
  442. {
  443. int i;
  444. int fifo_group_num;
  445. lsm_data_t temp_lsm_data;
  446. //读取FIFO数据
  447. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].fifo_odr != SER_IMU_FIFO_ODR_OFF)
  448. {
  449. fifo_group_num = drv_lsm_get_fifo_group_num();
  450. for(i=0; i<fifo_group_num; i++)
  451. {
  452. if(drv_lsm_get_fifo_data(&temp_lsm_data) != -1)
  453. {
  454. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].acc[0] = temp_lsm_data.acc[0];
  455. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].acc[1] = temp_lsm_data.acc[1];
  456. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].acc[2] = temp_lsm_data.acc[2];
  457. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].gry[0] = temp_lsm_data.gry[0];
  458. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].gry[1] = temp_lsm_data.gry[1];
  459. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].gry[2] = temp_lsm_data.gry[2];
  460. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].mag[0] = temp_lsm_data.mag[0];
  461. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].mag[1] = temp_lsm_data.mag[1];
  462. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].mag[2] = temp_lsm_data.mag[2];
  463. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].fifo_timestamp = temp_lsm_data.fifo_timestamp;
  464. }
  465. }
  466. return fifo_group_num;
  467. }
  468. //只读取ACC数据
  469. else if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_odr != SER_IMU_ACC_ODR_OFF && \
  470. ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_odr == SER_IMU_GRY_ODR_OFF && \
  471. ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_odr == SER_IMU_MAG_ODR_OFF \
  472. )
  473. {
  474. if(drv_lsm_get_acc_data(&temp_lsm_data) != -1)
  475. {
  476. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][0].acc[0] = temp_lsm_data.acc[0];
  477. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][0].acc[1] = temp_lsm_data.acc[1];
  478. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][0].acc[2] = temp_lsm_data.acc[2];
  479. return 1;
  480. }
  481. }
  482. return 0;
  483. }
  484. static int hal_ser_imu_read_data_qmc(void)
  485. {
  486. qmc_data_t temp_qmc_data;
  487. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_odr != SER_IMU_MAG_ODR_OFF)
  488. {
  489. if(drv_qmc6310_get_mag_data(&temp_qmc_data) != -1)
  490. {
  491. ob_ser_imu.cur_data[SER_IMU_DIR_BACK][0].mag[0] = temp_qmc_data.mag[0];
  492. ob_ser_imu.cur_data[SER_IMU_DIR_BACK][0].mag[1] = temp_qmc_data.mag[1];
  493. ob_ser_imu.cur_data[SER_IMU_DIR_BACK][0].mag[2] = temp_qmc_data.mag[2];
  494. return 1;
  495. }
  496. }
  497. return 0;
  498. }
  499. static int hal_ser_imu_read_data(SER_IMU_DIR_e dir)
  500. {
  501. int ret = 0;
  502. switch(dir)
  503. {
  504. case SER_IMU_DIR_FRONT:
  505. ret = hal_ser_imu_read_data_lsm();
  506. break;
  507. case SER_IMU_DIR_BACK:
  508. ret = hal_ser_imu_read_data_qmc();
  509. break;
  510. default:
  511. break;
  512. }
  513. return ret;
  514. }
  515. static void hal_ser_imu_drv_config_Process(void)
  516. {
  517. switch(ob_ser_imu.stage)
  518. {
  519. case IMU_CONFIG_STAGE_DONE: //配置完成阶段
  520. if(hal_ser_imu_is_need_config()) //判断是否需要配置
  521. {
  522. ob_ser_imu.stage = IMU_CONFIG_STAGE_IN_PROGRESS; //进入配置进行阶段
  523. Process_SetHoldOn(hal_ser_imu_drv_config_Process,1); //全功率配置
  524. }
  525. else //读数据
  526. {
  527. //读取前脚IMU数据 + 更新前脚IMU数据量
  528. ob_ser_imu.cur_data_num[SER_IMU_DIR_FRONT] = hal_ser_imu_read_data(SER_IMU_DIR_FRONT);
  529. //读取后脚IMU数据 + 更新前脚IMU数据量
  530. ob_ser_imu.cur_data_num[SER_IMU_DIR_BACK] = hal_ser_imu_read_data(SER_IMU_DIR_BACK);
  531. }
  532. break;
  533. case IMU_CONFIG_STAGE_IN_PROGRESS: //配置进行阶段
  534. if(ob_ser_imu.is_need_config[SER_IMU_DIR_FRONT]) //判断前脚是否需要配置
  535. {
  536. if(hal_ser_imu_is_config_done(SER_IMU_DIR_FRONT))
  537. {
  538. ob_ser_imu.is_need_config[SER_IMU_DIR_FRONT] = false;
  539. }
  540. }
  541. else if(ob_ser_imu.is_need_config[SER_IMU_DIR_BACK]) //判断后脚是否需要配置
  542. {
  543. if(hal_ser_imu_is_config_done(SER_IMU_DIR_BACK))
  544. {
  545. ob_ser_imu.is_need_config[SER_IMU_DIR_BACK] = false;
  546. }
  547. }
  548. else
  549. {
  550. if(!hal_ser_imu_is_need_config()) //若是在配置期间,操作的IMU配置参数副本更改,需要重新配置。
  551. {
  552. ob_ser_imu.stage = IMU_CONFIG_STAGE_DONE; //配置完成
  553. //读数据
  554. Process_SetHoldOn(hal_ser_imu_drv_config_Process,0); //解放线程
  555. }
  556. }
  557. break;
  558. }
  559. }
  560. /*API ------------------------------------------------------------------------------------------------------------------------------------*/
  561. /**
  562. @brief 初始化IMU服务
  563. @param 无
  564. @return 错误代码 - [out] -1失败,0成功
  565. */
  566. int hal_ser_imu_Init(void)
  567. {
  568. int i;
  569. int ret;
  570. /***************************************驱动层初始化***************************************************/
  571. //初始化驱动LSM
  572. ret = drv_lsm_Init();
  573. if(ret == -1)return -1;
  574. //获取驱动LSM配置参数
  575. drv_lsm_get_config_param(&ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm);
  576. //初始化驱动QMC
  577. ret = drv_qmc6310_Init();
  578. if(ret == -1)return -1;
  579. //获取驱动LSM配置参数
  580. drv_qmc6310_get_config_param(&ob_ser_imu.drv_param[SER_IMU_DIR_BACK].qmc);
  581. /***************************************业务逻辑层初始化***************************************************/
  582. //重置结构体
  583. memset(&ob_ser_imu,0,sizeof(ob_ser_imu));
  584. //初始化IMU服务结构体
  585. ob_ser_imu.stage = IMU_CONFIG_STAGE_DONE;
  586. for(i=0; i<SER_IMU_HANDLE_NUM_MAX; i++)
  587. {
  588. ob_ser_imu.handle[i].id = INVALID_HANDLE;
  589. ob_ser_imu.handle[i].name = NULL;
  590. }
  591. for(i=0; i<SER_IMU_DIR_NUM; i++)
  592. {
  593. ob_ser_imu.is_need_config[i] = false;
  594. }
  595. //设置驱动配置线程
  596. Process_Start(0,"hal_ser_imu_drv_config_Process",hal_ser_imu_drv_config_Process);
  597. return 0;
  598. }
  599. /**
  600. @brief 获取IMU服务句柄
  601. @param p_name - [in] 为服务句柄设置的名字
  602. @param p_handle_id - [out] 返回的服务句柄ID
  603. @return 错误代码 - [out] -1失败,0成功
  604. */
  605. int hal_ser_imu_get_handle(char *p_name, int *p_handle_id)
  606. {
  607. for(int i=0; i<SER_IMU_HANDLE_NUM_MAX; i++)
  608. {
  609. //判断是否有空余的句柄
  610. if(ob_ser_imu.handle[i].id == INVALID_HANDLE)
  611. {
  612. //设置该句柄的名字
  613. ob_ser_imu.handle[i].name = p_name;
  614. //该句柄使能有效
  615. ob_ser_imu.handle[i].id = VALID_HANDLE;
  616. //返回服务句柄ID
  617. *p_handle_id = i;
  618. return 0;
  619. }
  620. }
  621. return -1;
  622. }
  623. /**
  624. @brief 设置IMU需要的配置参数
  625. @param handle - [in] 操作的IMU服务句柄
  626. @param foot - [in] IMU方向 - 前/后脚
  627. @param param - [in] IMU配置参数
  628. @return 错误代码 - [out] -1失败,0成功
  629. */
  630. int hal_ser_imu_set_required_param(int handle_id, SER_IMU_DIR_e dir, ser_imu_config_param_t *param)
  631. {
  632. //无效句柄返回
  633. if(handle_id < 0 || ob_ser_imu.handle[handle_id].id == INVALID_HANDLE)return -1;
  634. //更新操作的配置参数副本
  635. memcpy(&ob_ser_imu.handle[handle_id].op_param[dir], param ,sizeof(ob_ser_imu.handle[handle_id].op_param[dir]));
  636. return 0;
  637. }
  638. /**
  639. @brief IMU配置参数是否准备好
  640. @param foot - [in] IMU方向 - 前/后脚
  641. @param param - [in] IMU配置参数
  642. @return 错误代码 - [out] -1失败,0成功
  643. */
  644. int hal_ser_imu_is_param_get_ready(SER_IMU_DIR_e dir, ser_imu_config_param_t *param)
  645. {
  646. int ret = 0;
  647. //查看是否需要进行配置
  648. hal_ser_imu_drv_config_Process();
  649. //判断驱动配置是否准备好
  650. if(ob_ser_imu.stage == IMU_CONFIG_STAGE_IN_PROGRESS)
  651. {
  652. return -1;
  653. }
  654. //判断当前配置是否满足
  655. switch(dir)
  656. {
  657. case SER_IMU_DIR_FRONT:
  658. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_fs < param->acc_fs){ret = -1;break;}
  659. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_odr < param->acc_odr){ret = -1;break;}
  660. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_power_mode < param->acc_power_mode){ret = -1;break;}
  661. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].fifo_odr < param->fifo_odr){ret = -1;break;}
  662. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_fs < param->gry_fs){ret = -1;break;}
  663. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_odr < param->gry_odr){ret = -1;break;}
  664. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_power_mode < param->gry_power_mode){ret = -1;break;}
  665. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_fs < param->mag_fs){ret = -1;break;}
  666. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_odr < param->mag_odr){ret = -1;break;}
  667. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_resolution < param->timestamp_resolution){ret = -1;break;}
  668. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_switch < param->timestamp_switch){ret = -1;break;}
  669. break;
  670. case SER_IMU_DIR_BACK:
  671. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_fs < param->mag_fs){ret = -1;break;}
  672. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_odr < param->mag_odr){ret = -1;break;}
  673. break;
  674. default:
  675. break;
  676. }
  677. return ret;
  678. }
  679. /**
  680. @brief 获取IMU当前数据数量
  681. @param dir - [in] IMU方向 - 前/后脚
  682. @return 错误代码 - [out] 返回数据数量
  683. */
  684. int hal_ser_imu_get_data_num(SER_IMU_DIR_e dir)
  685. {
  686. int ret = 0;
  687. switch(dir)
  688. {
  689. case SER_IMU_DIR_FRONT:
  690. ret = ob_ser_imu.cur_data_num[SER_IMU_DIR_FRONT];
  691. break;
  692. case SER_IMU_DIR_BACK:
  693. ret = ob_ser_imu.cur_data_num[SER_IMU_DIR_BACK];
  694. break;
  695. default:
  696. break;
  697. }
  698. return ret;
  699. }
  700. /**
  701. @brief 获取IMU数据
  702. @param dir - [in] IMU方向 - 前/后脚
  703. @param index - [in] 第几组数据
  704. @param pdata - [out] IMU数据
  705. @return 错误代码 - [out] -1失败,0成功
  706. */
  707. int hal_ser_imu_get_data(SER_IMU_DIR_e dir, int index, ser_imu_data_t *pdata)
  708. {
  709. if(index < 0)return -1;
  710. *pdata = ob_ser_imu.cur_data[dir][index];
  711. return 0;
  712. }