fml_imu.c 36 KB

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