hal_ser_imu.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  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(hal_ser_imu_macro_conversion_acc_fs(SER_IMU_DIR_FRONT, compre_drv_param->acc_fs),drv_param->lsm.acc_fs) == false){return false;}
  281. if(IS_EQUAL(hal_ser_imu_macro_conversion_acc_odr(SER_IMU_DIR_FRONT, compre_drv_param->acc_odr),drv_param->lsm.acc_odr) == false){return false;}
  282. if(IS_EQUAL(hal_ser_imu_macro_conversion_acc_power_mode(SER_IMU_DIR_FRONT, compre_drv_param->acc_power_mode),drv_param->lsm.acc_power_mode) == false){return false;}
  283. if(IS_EQUAL(hal_ser_imu_macro_conversion_fifo_odr(SER_IMU_DIR_FRONT, compre_drv_param->fifo_odr),drv_param->lsm.fifo_odr) == false){return false;}
  284. if(IS_EQUAL(hal_ser_imu_macro_conversion_gry_fs(SER_IMU_DIR_FRONT, compre_drv_param->gry_fs),drv_param->lsm.gry_fs) == false){return false;}
  285. if(IS_EQUAL(hal_ser_imu_macro_conversion_gry_odr(SER_IMU_DIR_FRONT, compre_drv_param->gry_odr),drv_param->lsm.gry_odr) == false){return false;}
  286. if(IS_EQUAL(hal_ser_imu_macro_conversion_gry_power_mode(SER_IMU_DIR_FRONT, compre_drv_param->gry_power_mode),drv_param->lsm.gry_power_mode) == false){return false;}
  287. if(IS_EQUAL(hal_ser_imu_macro_conversion_mag_fs(SER_IMU_DIR_FRONT, compre_drv_param->mag_fs),drv_param->lsm.mag_fs) == false){return false;}
  288. if(IS_EQUAL(hal_ser_imu_macro_conversion_mag_odr(SER_IMU_DIR_FRONT, compre_drv_param->mag_odr),drv_param->lsm.mag_odr) == false){return false;}
  289. if(IS_EQUAL(hal_ser_imu_macro_conversion_timestamp_resolution(SER_IMU_DIR_FRONT, compre_drv_param->timestamp_resolution),drv_param->lsm.timestamp_resolution) == false){return false;}
  290. if(IS_EQUAL(hal_ser_imu_macro_conversion_timestamp_switch(SER_IMU_DIR_FRONT, 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(hal_ser_imu_macro_conversion_mag_fs(SER_IMU_DIR_BACK, compre_drv_param->mag_fs), drv_param->qmc.mag_fs) == false){return false;}
  296. if(IS_EQUAL(hal_ser_imu_macro_conversion_mag_odr(SER_IMU_DIR_BACK, 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) != -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) != -1){
  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. imu_config_flow_ctl = 0;
  399. return true;
  400. }
  401. break;
  402. }
  403. return false;
  404. }
  405. static bool hal_ser_imu_config_dir_back(void)
  406. {
  407. int ret = 0;
  408. static int imu_config_flow_ctl = 0; //配置流程控制
  409. switch(imu_config_flow_ctl)
  410. {
  411. case 0:
  412. //配置qmc挂起
  413. if(drv_qmc6310_suspend() == 0){imu_config_flow_ctl = 1;}
  414. break;
  415. case 1:
  416. //配置qmc的地磁计采样频率
  417. 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));
  418. if(ret != -1)
  419. {
  420. imu_config_flow_ctl = 0;
  421. return true;
  422. }
  423. break;
  424. }
  425. return false;
  426. }
  427. static bool hal_ser_imu_is_config_done(SER_IMU_DIR_e dir)
  428. {
  429. bool ret = true;
  430. switch(dir)
  431. {
  432. case SER_IMU_DIR_FRONT:
  433. ret = hal_ser_imu_config_dir_front();
  434. break;
  435. case SER_IMU_DIR_BACK:
  436. ret = hal_ser_imu_config_dir_back();
  437. break;
  438. default:
  439. break;
  440. }
  441. return ret;
  442. }
  443. static int hal_ser_imu_read_data_lsm(void)
  444. {
  445. int i;
  446. int fifo_group_num;
  447. lsm_data_t temp_lsm_data;
  448. //读取FIFO数据
  449. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].fifo_odr != SER_IMU_FIFO_ODR_OFF)
  450. {
  451. fifo_group_num = drv_lsm_get_fifo_group_num();
  452. fifo_group_num = fifo_group_num <= SER_IMU_DATA_GROUP_NUM_MAX ? fifo_group_num : SER_IMU_DATA_GROUP_NUM_MAX;
  453. for(i=0; i<fifo_group_num; i++)
  454. {
  455. if(drv_lsm_get_fifo_data(&temp_lsm_data) != -1)
  456. {
  457. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].acc[0] = temp_lsm_data.acc[0];
  458. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].acc[1] = temp_lsm_data.acc[1];
  459. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].acc[2] = temp_lsm_data.acc[2];
  460. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].gry[0] = temp_lsm_data.gry[0];
  461. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].gry[1] = temp_lsm_data.gry[1];
  462. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].gry[2] = temp_lsm_data.gry[2];
  463. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].mag[0] = temp_lsm_data.mag[0];
  464. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].mag[1] = temp_lsm_data.mag[1];
  465. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].mag[2] = temp_lsm_data.mag[2];
  466. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][i].fifo_timestamp = temp_lsm_data.fifo_timestamp;
  467. }
  468. }
  469. return fifo_group_num;
  470. }
  471. //只读取ACC数据
  472. else if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_odr != SER_IMU_ACC_ODR_OFF && \
  473. ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_odr == SER_IMU_GRY_ODR_OFF && \
  474. ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_odr == SER_IMU_MAG_ODR_OFF \
  475. )
  476. {
  477. if(drv_lsm_get_acc_data(&temp_lsm_data) != -1)
  478. {
  479. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][0].acc[0] = temp_lsm_data.acc[0];
  480. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][0].acc[1] = temp_lsm_data.acc[1];
  481. ob_ser_imu.cur_data[SER_IMU_DIR_FRONT][0].acc[2] = temp_lsm_data.acc[2];
  482. return 1;
  483. }
  484. }
  485. return 0;
  486. }
  487. static int hal_ser_imu_read_data_qmc(void)
  488. {
  489. qmc_data_t temp_qmc_data;
  490. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_odr != SER_IMU_MAG_ODR_OFF)
  491. {
  492. if(drv_qmc6310_get_mag_data(&temp_qmc_data) != -1)
  493. {
  494. ob_ser_imu.cur_data[SER_IMU_DIR_BACK][0].mag[0] = temp_qmc_data.mag[0];
  495. ob_ser_imu.cur_data[SER_IMU_DIR_BACK][0].mag[1] = temp_qmc_data.mag[1];
  496. ob_ser_imu.cur_data[SER_IMU_DIR_BACK][0].mag[2] = temp_qmc_data.mag[2];
  497. return 1;
  498. }
  499. }
  500. return 0;
  501. }
  502. static int hal_ser_imu_read_data(SER_IMU_DIR_e dir)
  503. {
  504. int ret = 0;
  505. switch(dir)
  506. {
  507. case SER_IMU_DIR_FRONT:
  508. ret = hal_ser_imu_read_data_lsm();
  509. break;
  510. case SER_IMU_DIR_BACK:
  511. ret = hal_ser_imu_read_data_qmc();
  512. break;
  513. default:
  514. break;
  515. }
  516. return ret;
  517. }
  518. static void hal_ser_imu_drv_config_Process(void)
  519. {
  520. switch(ob_ser_imu.stage)
  521. {
  522. case IMU_CONFIG_STAGE_DONE: //配置完成阶段
  523. if(hal_ser_imu_is_need_config()) //判断是否需要配置
  524. {
  525. ob_ser_imu.stage = IMU_CONFIG_STAGE_IN_PROGRESS; //进入配置进行阶段
  526. Process_SetHoldOn(hal_ser_imu_drv_config_Process,1); //全功率配置
  527. }
  528. else //读数据
  529. {
  530. //读取前脚IMU数据 + 更新前脚IMU数据量
  531. ob_ser_imu.cur_data_num[SER_IMU_DIR_FRONT] = hal_ser_imu_read_data(SER_IMU_DIR_FRONT);
  532. //读取后脚IMU数据 + 更新前脚IMU数据量
  533. ob_ser_imu.cur_data_num[SER_IMU_DIR_BACK] = hal_ser_imu_read_data(SER_IMU_DIR_BACK);
  534. }
  535. break;
  536. case IMU_CONFIG_STAGE_IN_PROGRESS: //配置进行阶段
  537. if(ob_ser_imu.is_need_config[SER_IMU_DIR_FRONT]) //判断前脚是否需要配置
  538. {
  539. if(hal_ser_imu_is_config_done(SER_IMU_DIR_FRONT))
  540. {
  541. ob_ser_imu.is_need_config[SER_IMU_DIR_FRONT] = false;
  542. }
  543. }
  544. else if(ob_ser_imu.is_need_config[SER_IMU_DIR_BACK]) //判断后脚是否需要配置
  545. {
  546. if(hal_ser_imu_is_config_done(SER_IMU_DIR_BACK))
  547. {
  548. ob_ser_imu.is_need_config[SER_IMU_DIR_BACK] = false;
  549. }
  550. }
  551. else
  552. {
  553. if(!hal_ser_imu_is_need_config()) //若是在配置期间,操作的IMU配置参数副本更改,需要重新配置。
  554. {
  555. ob_ser_imu.stage = IMU_CONFIG_STAGE_DONE; //配置完成
  556. //读数据
  557. Process_SetHoldOn(hal_ser_imu_drv_config_Process,0); //解放线程
  558. }
  559. }
  560. break;
  561. }
  562. }
  563. static void hal_ser_imu_printf_Process(void)
  564. {
  565. SEGGER_RTT_printf(0,"hal_ser_imu----------------------------------------------------------------->\n");
  566. SEGGER_RTT_printf(0,"stage:0x%x\r",ob_ser_imu.stage);
  567. SEGGER_RTT_printf(0,"is_need_config[SER_IMU_DIR_FRONT]:0x%x\n",ob_ser_imu.is_need_config[SER_IMU_DIR_FRONT]);
  568. SEGGER_RTT_printf(0,"is_need_config[SER_IMU_DIR_BACK]:0x%x\n",ob_ser_imu.is_need_config[SER_IMU_DIR_BACK]);
  569. // SEGGER_RTT_printf(0,"df acc_fs:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.acc_fs);
  570. SEGGER_RTT_printf(0,"df acc_odr:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.acc_odr);
  571. // SEGGER_RTT_printf(0,"df acc_power_mode:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.acc_power_mode);
  572. SEGGER_RTT_printf(0,"df fifo_odr:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.fifo_odr);
  573. // SEGGER_RTT_printf(0,"df gry_fs:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.gry_fs);
  574. SEGGER_RTT_printf(0,"df gry_odr:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.gry_odr);
  575. // SEGGER_RTT_printf(0,"df gry_power_mode:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.gry_power_mode);
  576. // SEGGER_RTT_printf(0,"df mag_fs:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.mag_fs);
  577. SEGGER_RTT_printf(0,"df mag_odr:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.mag_odr);
  578. // SEGGER_RTT_printf(0,"f timestamp_resolution:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.timestamp_resolution);
  579. // SEGGER_RTT_printf(0,"df timestamp_switch:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.timestamp_switch);
  580. SEGGER_RTT_printf(0,"db mag_odr:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_BACK].qmc.mag_odr);
  581. // SEGGER_RTT_printf(0,"cf acc_fs:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_fs);
  582. SEGGER_RTT_printf(0,"cf acc_odr:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_odr);
  583. // SEGGER_RTT_printf(0,"cf acc_power_mode:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_power_mode);
  584. SEGGER_RTT_printf(0,"cf fifo_odr:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].fifo_odr);
  585. // SEGGER_RTT_printf(0,"cf gry_fs:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_fs);
  586. SEGGER_RTT_printf(0,"cf gry_odr:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_odr);
  587. // SEGGER_RTT_printf(0,"cf gry_power_mode:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_power_mode);
  588. // SEGGER_RTT_printf(0,"cf mag_fs:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_fs);
  589. SEGGER_RTT_printf(0,"cf mag_odr:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_odr);
  590. // SEGGER_RTT_printf(0,"cf timestamp_resolution:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_resolution);
  591. // SEGGER_RTT_printf(0,"cf timestamp_switch:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_switch);
  592. SEGGER_RTT_printf(0,"cb mag_odr:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_odr);
  593. SEGGER_RTT_printf(0,"ob_ser_imu.cur_data_num[SER_IMU_DIR_FRONT]:0x%x\n",ob_ser_imu.cur_data_num[SER_IMU_DIR_FRONT]);
  594. SEGGER_RTT_printf(0,"ob_ser_imu.cur_data_num[SER_IMU_DIR_BACK]:0x%x\n",ob_ser_imu.cur_data_num[SER_IMU_DIR_BACK]);
  595. SEGGER_RTT_printf(0,"<-----------------------------------------------------------------hal_ser_imu\n");
  596. }
  597. /*API ------------------------------------------------------------------------------------------------------------------------------------*/
  598. /**
  599. @brief 初始化IMU服务
  600. @param 无
  601. @return 错误代码 - [out] -1失败,0成功
  602. */
  603. int hal_ser_imu_Init(void)
  604. {
  605. int i;
  606. int ret;
  607. /***************************************驱动层初始化***************************************************/
  608. //初始化驱动LSM
  609. ret = drv_lsm_Init();
  610. if(ret == -1)return -1;
  611. //获取驱动LSM配置参数
  612. drv_lsm_get_config_param(&ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm);
  613. //初始化驱动QMC
  614. ret = drv_qmc6310_Init();
  615. if(ret == -1)return -1;
  616. //获取驱动LSM配置参数
  617. drv_qmc6310_get_config_param(&ob_ser_imu.drv_param[SER_IMU_DIR_BACK].qmc);
  618. /***************************************业务逻辑层初始化***************************************************/
  619. //重置结构体
  620. memset(&ob_ser_imu,0,sizeof(ob_ser_imu));
  621. //初始化IMU服务结构体
  622. ob_ser_imu.stage = IMU_CONFIG_STAGE_DONE;
  623. for(i=0; i<SER_IMU_HANDLE_NUM_MAX; i++)
  624. {
  625. ob_ser_imu.handle[i].id = INVALID_HANDLE;
  626. ob_ser_imu.handle[i].name = NULL;
  627. }
  628. for(i=0; i<SER_IMU_DIR_NUM; i++)
  629. {
  630. ob_ser_imu.is_need_config[i] = false;
  631. }
  632. //设置驱动配置线程
  633. Process_Start(0,"hal_ser_imu_drv_config_Process",hal_ser_imu_drv_config_Process);
  634. Process_Start(1000,"hal_ser_imu_printf_Process",hal_ser_imu_printf_Process);
  635. return 0;
  636. }
  637. /**
  638. @brief 获取IMU服务句柄
  639. @param p_name - [in] 为服务句柄设置的名字
  640. @param p_handle_id - [out] 返回的服务句柄ID
  641. @return 错误代码 - [out] -1失败,0成功
  642. */
  643. int hal_ser_imu_get_handle(char *p_name, int *p_handle_id)
  644. {
  645. for(int i=0; i<SER_IMU_HANDLE_NUM_MAX; i++)
  646. {
  647. //判断是否有空余的句柄
  648. if(ob_ser_imu.handle[i].id == INVALID_HANDLE)
  649. {
  650. //设置该句柄的名字
  651. ob_ser_imu.handle[i].name = p_name;
  652. //该句柄使能有效
  653. ob_ser_imu.handle[i].id = VALID_HANDLE;
  654. //返回服务句柄ID
  655. *p_handle_id = i;
  656. return 0;
  657. }
  658. }
  659. return -1;
  660. }
  661. /**
  662. @brief 设置IMU需要的配置参数
  663. @param handle - [in] 操作的IMU服务句柄
  664. @param foot - [in] IMU方向 - 前/后脚
  665. @param param - [in] IMU配置参数
  666. @return 错误代码 - [out] -1失败,0成功
  667. */
  668. int hal_ser_imu_set_required_param(int handle_id, SER_IMU_DIR_e dir, ser_imu_config_param_t *param)
  669. {
  670. //无效句柄返回
  671. if(handle_id < 0 || ob_ser_imu.handle[handle_id].id == INVALID_HANDLE)return -1;
  672. //更新操作的配置参数副本
  673. memcpy(&ob_ser_imu.handle[handle_id].op_param[dir], param ,sizeof(ob_ser_imu.handle[handle_id].op_param[dir]));
  674. return 0;
  675. }
  676. /**
  677. @brief IMU配置参数是否准备好
  678. @param foot - [in] IMU方向 - 前/后脚
  679. @param param - [in] IMU配置参数
  680. @return 错误代码 - [out] -1失败,0成功
  681. */
  682. int hal_ser_imu_is_param_get_ready(SER_IMU_DIR_e dir, ser_imu_config_param_t *param)
  683. {
  684. int ret = 0;
  685. //查看是否需要进行配置
  686. if(hal_ser_imu_is_need_config())
  687. {
  688. return -1;
  689. }
  690. //判断当前配置是否满足
  691. switch(dir)
  692. {
  693. case SER_IMU_DIR_FRONT:
  694. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_fs < param->acc_fs){ret = -1;break;}
  695. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_odr < param->acc_odr){ret = -1;break;}
  696. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_power_mode < param->acc_power_mode){ret = -1;break;}
  697. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].fifo_odr < param->fifo_odr){ret = -1;break;}
  698. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_fs < param->gry_fs){ret = -1;break;}
  699. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_odr < param->gry_odr){ret = -1;break;}
  700. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_power_mode < param->gry_power_mode){ret = -1;break;}
  701. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_fs < param->mag_fs){ret = -1;break;}
  702. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_odr < param->mag_odr){ret = -1;break;}
  703. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_resolution < param->timestamp_resolution){ret = -1;break;}
  704. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_switch < param->timestamp_switch){ret = -1;break;}
  705. break;
  706. case SER_IMU_DIR_BACK:
  707. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_fs < param->mag_fs){ret = -1;break;}
  708. if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_odr < param->mag_odr){ret = -1;break;}
  709. break;
  710. default:
  711. break;
  712. }
  713. return ret;
  714. }
  715. /**
  716. @brief 获取IMU当前数据数量
  717. @param dir - [in] IMU方向 - 前/后脚
  718. @return 错误代码 - [out] 返回数据数量
  719. */
  720. int hal_ser_imu_get_data_num(SER_IMU_DIR_e dir)
  721. {
  722. int ret = 0;
  723. switch(dir)
  724. {
  725. case SER_IMU_DIR_FRONT:
  726. ret = ob_ser_imu.cur_data_num[SER_IMU_DIR_FRONT];
  727. break;
  728. case SER_IMU_DIR_BACK:
  729. ret = ob_ser_imu.cur_data_num[SER_IMU_DIR_BACK];
  730. break;
  731. default:
  732. break;
  733. }
  734. return ret;
  735. }
  736. /**
  737. @brief 获取IMU数据
  738. @param dir - [in] IMU方向 - 前/后脚
  739. @param index - [in] 第几组数据
  740. @param pdata - [out] IMU数据
  741. @return 错误代码 - [out] -1失败,0成功
  742. */
  743. int hal_ser_imu_get_data(SER_IMU_DIR_e dir, int index, ser_imu_data_t *pdata)
  744. {
  745. if(index < 0)return -1;
  746. *pdata = ob_ser_imu.cur_data[dir][index];
  747. return 0;
  748. }