fml_imu.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298
  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. //读取后脚传感器ID
  326. ret = drv_qmc6310_get_mag_id();
  327. if(ret != 0)return -1;
  328. tim = 0;
  329. ob_fml_imu.config_flow = 5;
  330. break;
  331. case 5:
  332. //读取前脚传感器六轴ID
  333. ret = drv_lsm_get_lsm_id();
  334. if(ret != 0)return -1;
  335. tim = 0;
  336. ob_fml_imu.config_flow = 6;
  337. break;
  338. case 6:
  339. //读取前脚传感器地磁ID
  340. ret = drv_lsm_get_mag_id();
  341. if(ret != 0)return -1;
  342. tim = 0;
  343. ob_fml_imu.config_flow = 7;
  344. break;
  345. case 7:
  346. //lsm进行自检步骤1
  347. ret = drv_lsm_self_check_1();
  348. if(ret != 0)return -1;
  349. tim = 0;
  350. ob_fml_imu.config_flow = 8;
  351. break;
  352. case 8:
  353. //等待100ms
  354. if(tim == 0){
  355. tim = TIME_GetTicks();
  356. }else if(TIME_GetTicks()-tim>=100){
  357. tim = 0;
  358. ob_fml_imu.config_flow = 9;
  359. }
  360. break;
  361. case 9:
  362. //lsm进行自检步骤2
  363. ret = drv_lsm_self_check_2();
  364. if(ret != 0)return -1;
  365. tim = 0;
  366. ob_fml_imu.config_flow = 10;
  367. break;
  368. case 10:
  369. //等待100ms
  370. if(tim == 0){
  371. tim = TIME_GetTicks();
  372. }else if(TIME_GetTicks()-tim>=100){
  373. tim = 0;
  374. ob_fml_imu.config_flow = 11;
  375. }
  376. break;
  377. case 11:
  378. //lsm进行自检步骤3
  379. ret = drv_lsm_self_check_3();
  380. if(ret != 0)return -1;
  381. tim = 0;
  382. ob_fml_imu.config_flow = 12;
  383. break;
  384. case 12:
  385. //等待150ms
  386. if(tim == 0){
  387. tim = TIME_GetTicks();
  388. }else if(TIME_GetTicks()-tim>=150){
  389. tim = 0;
  390. ob_fml_imu.config_flow = 13;
  391. }
  392. break;
  393. case 13:
  394. //lsm进行自检步骤4
  395. ret = drv_lsm_self_check_4();
  396. if(ret != 0)return -1;
  397. tim = 0;
  398. ob_fml_imu.config_flow = 14;
  399. break;
  400. case 14:
  401. //等待50ms
  402. if(tim == 0){
  403. tim = TIME_GetTicks();
  404. }else if(TIME_GetTicks()-tim>=50){
  405. tim = 0;
  406. ob_fml_imu.config_flow = 15;
  407. }
  408. break;
  409. case 15:
  410. //lsm进行自检步骤5
  411. ret = drv_lsm_self_check_5();
  412. if(ret != 0)return -1;
  413. tim = 0;
  414. ob_fml_imu.config_flow = 16;
  415. break;
  416. case 16:
  417. //转换参数,用于配置驱动
  418. fml_imu_macro_conversion(FML_IMU_DIR_FRONT, &ob_fml_imu.config_param[FML_IMU_DIR_FRONT], &lsm_drv_param);
  419. fml_imu_macro_conversion(FML_IMU_DIR_BACK, &ob_fml_imu.config_param[FML_IMU_DIR_BACK], &qmc_drv_param);
  420. //配置lsm的地磁计采样频率
  421. if(ob_fml_imu.config_param[FML_IMU_DIR_FRONT].fifo_odr != FML_IMU_FIFO_ODR_OFF)
  422. {
  423. for(int i=1; i <=lsm_mag_flow;i++)
  424. {
  425. ret = drv_lsm_set_mag_odr(lsm_drv_param.lsm.mag_odr, 1, i);
  426. if(ret != 0)return -1;
  427. }
  428. tim = 0;
  429. ob_fml_imu.config_flow = 17;
  430. }
  431. else
  432. {
  433. for(int i=1; i <= lsm_mag_flow; i++)
  434. {
  435. ret = drv_lsm_set_mag_odr(lsm_drv_param.lsm.mag_odr, 0, i);
  436. if(ret != 0)return -1;
  437. }
  438. tim = 0;
  439. ob_fml_imu.config_flow = 17;
  440. }
  441. break;
  442. case 17:
  443. //转换参数,用于配置驱动
  444. fml_imu_macro_conversion(FML_IMU_DIR_FRONT, &ob_fml_imu.config_param[FML_IMU_DIR_FRONT], &lsm_drv_param);
  445. fml_imu_macro_conversion(FML_IMU_DIR_BACK, &ob_fml_imu.config_param[FML_IMU_DIR_BACK], &qmc_drv_param);
  446. //配置lsm的陀螺仪采样频率
  447. ret = drv_lsm_set_gry_odr(lsm_drv_param.lsm.gry_odr);
  448. if(ret != 0)return -1;
  449. //配置lsm的加速度采样频率
  450. ret = drv_lsm_set_acc_odr(lsm_drv_param.lsm.acc_odr);
  451. if(ret != 0)return -1;
  452. tim = 0;
  453. ob_fml_imu.config_flow = 18;
  454. break;
  455. case 18:
  456. //等待20ms
  457. if(tim == 0){
  458. tim = TIME_GetTicks();
  459. }else if(TIME_GetTicks()-tim>=20){
  460. tim = 0;
  461. ob_fml_imu.config_flow = 19;
  462. }
  463. break;
  464. case FML_IMU_CONFIG_FLOW_DONE:
  465. //配置完成才能进来此处。。。。。。。
  466. break;
  467. default:
  468. //转换参数,用于配置驱动
  469. fml_imu_macro_conversion(FML_IMU_DIR_FRONT, &ob_fml_imu.config_param[FML_IMU_DIR_FRONT], &lsm_drv_param);
  470. fml_imu_macro_conversion(FML_IMU_DIR_BACK, &ob_fml_imu.config_param[FML_IMU_DIR_BACK], &qmc_drv_param);
  471. //配置lsm的加速度工作模式
  472. ret = drv_lsm_set_acc_power_mode(lsm_drv_param.lsm.acc_power_mode);
  473. if(ret != 0)return -1;
  474. ob_fml_imu.config_flow++;
  475. //配置lsm的陀螺仪工作模式
  476. ret = drv_lsm_set_gry_power_mode(lsm_drv_param.lsm.gry_power_mode);
  477. if(ret != 0)return -1;
  478. ob_fml_imu.config_flow++;
  479. //配置lsm的加速度量程
  480. ret = drv_lsm_set_acc_fs(lsm_drv_param.lsm.acc_fs);
  481. if(ret != 0)return -1;
  482. ob_fml_imu.config_flow++;
  483. //配置lsm的陀螺仪量程
  484. ret = drv_lsm_set_gry_fs(lsm_drv_param.lsm.gry_fs);
  485. if(ret != 0)return -1;
  486. ob_fml_imu.config_flow++;
  487. //配置lsm的时间戳精度
  488. ret = drv_lsm_set_timestamp_resolution(lsm_drv_param.lsm.timestamp_resolution);
  489. if(ret != 0)return -1;
  490. ob_fml_imu.config_flow++;
  491. //配置lsm的时间戳开关
  492. ret = drv_lsm_set_timestamp_switch(lsm_drv_param.lsm.timestamp_switch);
  493. if(ret != 0)return -1;
  494. ob_fml_imu.config_flow++;
  495. //配置lsm的FIFO采样频率(必须以上都配置成功,才能配置FIFO)
  496. ret = drv_lsm_set_fifo_odr(lsm_drv_param.lsm.fifo_odr, \
  497. lsm_drv_param.lsm.acc_odr, \
  498. lsm_drv_param.lsm.gry_odr, \
  499. lsm_drv_param.lsm.mag_odr, \
  500. lsm_drv_param.lsm.timestamp_switch);
  501. if(ret != 0)return -1;
  502. ob_fml_imu.config_flow++;
  503. //配置qmc的地磁计采样频率
  504. for(int i = 1; i <=qmc_mag_flow; i++)
  505. {
  506. ret = drv_qmc6310_set_mag_odr(qmc_drv_param.qmc.mag_odr,i);
  507. if(ret != 0)return -1;
  508. ob_fml_imu.config_flow++;
  509. }
  510. //配置完成!
  511. ob_fml_imu.config_flow = FML_IMU_CONFIG_FLOW_DONE;
  512. break;
  513. }
  514. return 0;
  515. }
  516. static int fml_imu_read_data_lsm(void)
  517. {
  518. int i;
  519. int fifo_group_num;
  520. lsm_data_t temp_lsm_data;
  521. //读取FIFO数据
  522. if(ob_fml_imu.config_param[FML_IMU_DIR_FRONT].fifo_odr != FML_IMU_FIFO_ODR_OFF)
  523. {
  524. //获取当前fifo里存在多少组数据。
  525. fifo_group_num = drv_lsm_get_fifo_group_num();
  526. fifo_group_num = fifo_group_num <= FML_IMU_DATA_GROUP_NUM_MAX ? fifo_group_num : FML_IMU_DATA_GROUP_NUM_MAX;
  527. if(fifo_group_num > 0)
  528. {
  529. for(i=0; i<fifo_group_num; i++)
  530. {
  531. if(drv_lsm_get_fifo_data(&temp_lsm_data) != -1)
  532. {
  533. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[0] = temp_lsm_data.acc[0];
  534. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[1] = temp_lsm_data.acc[1];
  535. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[2] = temp_lsm_data.acc[2];
  536. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[0] = temp_lsm_data.gry[0];
  537. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[1] = temp_lsm_data.gry[1];
  538. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[2] = temp_lsm_data.gry[2];
  539. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[0] = temp_lsm_data.mag[0];
  540. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[1] = temp_lsm_data.mag[1];
  541. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[2] = temp_lsm_data.mag[2];
  542. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].fifo_timestamp = temp_lsm_data.fifo_timestamp;
  543. // 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], \
  544. // ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[1], \
  545. // ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].acc[2], \
  546. // ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[0], \
  547. // ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[1], \
  548. // ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].gry[2], \
  549. // ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[0], \
  550. // ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[1], \
  551. // ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].mag[2], \
  552. // ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][i].fifo_timestamp);
  553. }
  554. else
  555. {
  556. break;
  557. }
  558. }
  559. }
  560. else if(fifo_group_num == -1) //异常,fifo溢出
  561. {
  562. return 0;
  563. }
  564. else
  565. {
  566. return 0;
  567. }
  568. return i;
  569. }
  570. //只读取ACC数据
  571. else if(ob_fml_imu.config_param[FML_IMU_DIR_FRONT].acc_odr != FML_IMU_ACC_ODR_OFF && \
  572. ob_fml_imu.config_param[FML_IMU_DIR_FRONT].gry_odr == FML_IMU_GRY_ODR_OFF && \
  573. ob_fml_imu.config_param[FML_IMU_DIR_FRONT].mag_odr == FML_IMU_MAG_ODR_OFF \
  574. )
  575. {
  576. if(drv_lsm_get_acc_data(&temp_lsm_data) != -1)
  577. {
  578. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][0].acc[0] = temp_lsm_data.acc[0];
  579. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][0].acc[1] = temp_lsm_data.acc[1];
  580. ob_fml_imu.cur_data[FML_IMU_DIR_FRONT][0].acc[2] = temp_lsm_data.acc[2];
  581. return 1;
  582. }
  583. }
  584. return 0;
  585. }
  586. static int fml_imu_read_data_qmc(void)
  587. {
  588. qmc_data_t temp_qmc_data;
  589. if(ob_fml_imu.config_param[FML_IMU_DIR_BACK].mag_odr != FML_IMU_MAG_ODR_OFF)
  590. {
  591. if(drv_qmc6310_get_mag_data(&temp_qmc_data) != -1)
  592. {
  593. ob_fml_imu.cur_data[FML_IMU_DIR_BACK][0].mag[0] = temp_qmc_data.mag[0];
  594. ob_fml_imu.cur_data[FML_IMU_DIR_BACK][0].mag[1] = temp_qmc_data.mag[1];
  595. ob_fml_imu.cur_data[FML_IMU_DIR_BACK][0].mag[2] = temp_qmc_data.mag[2];
  596. return 1;
  597. }
  598. }
  599. return 0;
  600. }
  601. static int hal_ser_imu_read_data(FML_IMU_DIR_e dir)
  602. {
  603. int ret = 0;
  604. switch(dir)
  605. {
  606. case FML_IMU_DIR_FRONT:
  607. ret = fml_imu_read_data_lsm();
  608. break;
  609. case FML_IMU_DIR_BACK:
  610. ret = fml_imu_read_data_qmc();
  611. break;
  612. default:
  613. break;
  614. }
  615. return ret;
  616. }
  617. static void monitor_sensor_data(int16_t *f_acc, int16_t *f_gry, int16_t *f_mag, int16_t *b_mag)
  618. {
  619. /*前脚加速度*/
  620. if(f_acc != NULL)
  621. {
  622. if(
  623. ob_fml_imu.last_f_acc[0] == f_acc[0] && \
  624. ob_fml_imu.last_f_acc[1] == f_acc[1] && \
  625. ob_fml_imu.last_f_acc[2] == f_acc[2]
  626. )
  627. {
  628. ob_fml_imu.last_f_acc_err_sum++;
  629. if(ob_fml_imu.last_f_acc_err_sum >= FML_IMU_MONITOR_DATA_ERR_SUM_MAX){
  630. Except_SetExceptype(EXCEPT_DATA_FRONT_ACC);
  631. }
  632. }else{
  633. ob_fml_imu.last_f_acc_err_sum = 0;
  634. }
  635. ob_fml_imu.last_f_acc[0] = f_acc[0];
  636. ob_fml_imu.last_f_acc[1] = f_acc[1];
  637. ob_fml_imu.last_f_acc[2] = f_acc[2];
  638. }
  639. /*前脚陀螺仪*/
  640. if(f_gry != NULL)
  641. {
  642. if(
  643. ob_fml_imu.last_f_gry[0] == f_gry[0] && \
  644. ob_fml_imu.last_f_gry[1] == f_gry[1] && \
  645. ob_fml_imu.last_f_gry[2] == f_gry[2]
  646. )
  647. {
  648. ob_fml_imu.last_f_gry_err_sum++;
  649. if(ob_fml_imu.last_f_gry_err_sum >= FML_IMU_MONITOR_DATA_ERR_SUM_MAX){
  650. Except_SetExceptype(EXCEPT_DATA_FRONT_GRY);
  651. }
  652. }else{
  653. ob_fml_imu.last_f_gry_err_sum = 0;
  654. }
  655. ob_fml_imu.last_f_gry[0] = f_gry[0];
  656. ob_fml_imu.last_f_gry[1] = f_gry[1];
  657. ob_fml_imu.last_f_gry[2] = f_gry[2];
  658. }
  659. /*前脚地磁计*/
  660. if(f_mag != NULL)
  661. {
  662. if(
  663. ob_fml_imu.last_f_mag[0] == f_mag[0] && \
  664. ob_fml_imu.last_f_mag[1] == f_mag[1] && \
  665. ob_fml_imu.last_f_mag[2] == f_mag[2]
  666. )
  667. {
  668. ob_fml_imu.last_f_mag_err_sum++;
  669. if(ob_fml_imu.last_f_mag_err_sum >= FML_IMU_MONITOR_DATA_ERR_SUM_MAX){
  670. Except_SetExceptype(EXCEPT_DATA_FRONT_MAG);
  671. }
  672. }else{
  673. ob_fml_imu.last_f_mag_err_sum = 0;
  674. }
  675. ob_fml_imu.last_f_mag[0] = f_mag[0];
  676. ob_fml_imu.last_f_mag[1] = f_mag[1];
  677. ob_fml_imu.last_f_mag[2] = f_mag[2];
  678. }
  679. /*后脚地磁计*/
  680. if(b_mag != NULL)
  681. {
  682. if(
  683. ob_fml_imu.last_b_mag[0] == b_mag[0] && \
  684. ob_fml_imu.last_b_mag[1] == b_mag[1] && \
  685. ob_fml_imu.last_b_mag[2] == b_mag[2]
  686. )
  687. {
  688. ob_fml_imu.last_b_mag_err_sum++;
  689. if(ob_fml_imu.last_b_mag_err_sum >= FML_IMU_MONITOR_DATA_ERR_SUM_MAX){
  690. Except_SetExceptype(EXCEPT_DATA_BACK_MAG);
  691. }
  692. }else{
  693. ob_fml_imu.last_b_mag_err_sum = 0;
  694. }
  695. ob_fml_imu.last_b_mag[0] = b_mag[0];
  696. ob_fml_imu.last_b_mag[1] = b_mag[1];
  697. ob_fml_imu.last_b_mag[2] = b_mag[2];
  698. }
  699. //监测到前脚数据异常
  700. if(Except_IsError(EXCEPT_DATA_FRONT_ACC) || Except_IsError(EXCEPT_DATA_FRONT_GRY) || Except_IsError(EXCEPT_DATA_FRONT_MAG))
  701. {
  702. ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_FRONT]++;
  703. if(ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_FRONT] > 1)
  704. {
  705. if(Except_IsError(EXCEPT_DATA_FRONT_ACC)){Except_TxError(EXCEPT_DATA_FRONT_ACC,"front_acc_data_error");DEBUG_LOG("front_acc_data_error\n");}
  706. if(Except_IsError(EXCEPT_DATA_FRONT_GRY)){Except_TxError(EXCEPT_DATA_FRONT_GRY,"front_gry_data_error");DEBUG_LOG("front_gry_data_error\n");}
  707. if(Except_IsError(EXCEPT_DATA_FRONT_MAG)){Except_TxError(EXCEPT_DATA_FRONT_MAG,"front_mag_data_error");DEBUG_LOG("front_mag_data_error\n");}
  708. }
  709. //重启前脚LSM(主要是复位结构体)
  710. drv_lsm_power_off();
  711. drv_lsm_power_on();
  712. //重新开始配置
  713. fml_imu_start_config();
  714. //清除异常
  715. Except_ClearExceptype(EXCEPT_DATA_FRONT_ACC);
  716. Except_ClearExceptype(EXCEPT_DATA_FRONT_GRY);
  717. Except_ClearExceptype(EXCEPT_DATA_FRONT_MAG);
  718. }
  719. else
  720. {
  721. ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_FRONT] = 0;
  722. //清除异常
  723. Except_ClearExceptype(EXCEPT_DATA_FRONT_ACC);
  724. Except_ClearExceptype(EXCEPT_DATA_FRONT_GRY);
  725. Except_ClearExceptype(EXCEPT_DATA_FRONT_MAG);
  726. }
  727. //监测到后脚数据异常
  728. if(Except_IsError(EXCEPT_DATA_BACK_MAG))
  729. {
  730. ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_BACK]++;
  731. if(ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_BACK] > 1)
  732. {
  733. if(Except_IsError(EXCEPT_DATA_BACK_MAG))Except_TxError(EXCEPT_DATA_BACK_MAG,"back_mag_data_error");
  734. }
  735. //重启后脚QMC(主要是复位结构体)
  736. drv_qmc6310_power_off();
  737. drv_qmc6310_power_on();
  738. //重新开始配置
  739. fml_imu_start_config();
  740. //清除异常
  741. Except_ClearExceptype(EXCEPT_DATA_BACK_MAG);
  742. }
  743. else
  744. {
  745. ob_fml_imu.except_data_occur_sum[FML_IMU_DIR_BACK] = 0;
  746. //清除异常
  747. Except_ClearExceptype(EXCEPT_DATA_BACK_MAG);
  748. }
  749. }
  750. static void monitor_sensor_no_data(int cur_front_data_num, int cur_back_data_num)
  751. {
  752. static uint32_t front_no_data_tim = 0;
  753. static uint32_t back_no_data_tim = 0;
  754. static char buf[255];
  755. //数据异常检测——前脚没有数据
  756. if(cur_front_data_num == 0)
  757. {
  758. if(ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.acc_odr != LSM_ACC_ODR_OFF || \
  759. ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.gry_odr != LSM_GRY_ODR_OFF || \
  760. ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.mag_odr != LSM_MAG_ODR_OFF)
  761. {
  762. //持续1000ms没数据
  763. if(front_no_data_tim == 0){
  764. front_no_data_tim = TIME_GetTicks();
  765. }else if(TIME_GetTicks()-front_no_data_tim>=1000){
  766. sprintf(buf,"Front Sensor short circuit\r\n");
  767. Except_TxError(EXCEPT_IMU_SUSPEND_OVERFLOW,buf);
  768. front_no_data_tim = 0;
  769. //重启前脚LSM(主要是复位结构体)
  770. drv_lsm_power_off();
  771. drv_lsm_power_on();
  772. //重新开始配置
  773. fml_imu_start_config();
  774. }
  775. }
  776. }
  777. else front_no_data_tim = 0;
  778. //数据异常检测——后脚没有数据
  779. if(cur_back_data_num == 0)
  780. {
  781. if(ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc.mag_odr != QMC_MAG_ODR_OFF)
  782. {
  783. //持续1000ms没数据
  784. if(back_no_data_tim == 0){
  785. back_no_data_tim = TIME_GetTicks();
  786. }else if(TIME_GetTicks()-back_no_data_tim>=1000){
  787. sprintf(buf,"Back Sensor short circuit\r\n");
  788. Except_TxError(EXCEPT_IMU_SUSPEND_OVERFLOW,buf);
  789. back_no_data_tim = 0;
  790. //重启后脚QMC(主要是复位结构体)
  791. drv_qmc6310_power_off();
  792. drv_qmc6310_power_on();
  793. //重新开始配置
  794. fml_imu_start_config();
  795. }
  796. }
  797. }
  798. else back_no_data_tim = 0;
  799. }
  800. static void fml_imu_monitor_sensor_data_process(int cur_front_data_num, int cur_back_data_num)
  801. {
  802. int i = 0;
  803. int16_t group_num = 0;
  804. static int16_t f_acc[3];
  805. static int16_t f_gry[3];
  806. static int16_t f_mag[3];
  807. static int16_t b_mag[3];
  808. fml_imu_data_t data;
  809. static uint32_t last_tim = 0;
  810. //检测数据异常——没数据
  811. monitor_sensor_no_data(cur_front_data_num, cur_back_data_num);
  812. //检测数据异常——重复数据
  813. if(
  814. ob_fml_imu.stage == FML_IMU_CONFIG_STAGE_DONE && \
  815. ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.acc_odr == LSM_ACC_ODR_104HZ && \
  816. ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.gry_odr == LSM_GRY_ODR_104HZ && \
  817. (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)
  818. )
  819. {
  820. if(TIME_GetTicks()-last_tim >= FullPower_Interval) //监测前脚传感器数据(acc + gry + mag)+ 监测后脚传感器数据(mag)
  821. {
  822. last_tim = TIME_GetTicks();
  823. group_num = fml_imu_get_data_num(FML_IMU_DIR_FRONT);
  824. if(group_num > 0)
  825. {
  826. for(i=0;i<group_num;i++)
  827. {
  828. fml_imu_get_data(FML_IMU_DIR_FRONT, i, &data);
  829. f_gry[0] = data.gry[0];f_gry[1] = data.gry[1];f_gry[2] = data.gry[2];
  830. f_acc[0] = data.acc[0];f_acc[1] = data.acc[1];f_acc[2] = data.acc[2];
  831. f_mag[0] = data.mag[0];f_mag[1] = data.mag[1];f_mag[2] = data.mag[2];
  832. monitor_sensor_data(f_acc, f_gry, f_mag, NULL);
  833. }
  834. }
  835. if(fml_imu_get_data_num(FML_IMU_DIR_BACK) >= 1){
  836. fml_imu_get_data(FML_IMU_DIR_BACK, 0, &data);
  837. b_mag[0] = data.mag[0];b_mag[1] = data.mag[1];b_mag[2] = data.mag[2];
  838. monitor_sensor_data(NULL, NULL, NULL, b_mag);
  839. }
  840. }
  841. }
  842. else if(
  843. ob_fml_imu.stage == FML_IMU_CONFIG_STAGE_DONE && \
  844. ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm.acc_odr == LSM_ACC_ODR_104HZ && \
  845. (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)
  846. )
  847. {
  848. if(TIME_GetTicks()-last_tim >= LowPower_Interval) //监测前脚传感器数据(acc + mag)
  849. {
  850. last_tim = TIME_GetTicks();
  851. group_num = fml_imu_get_data_num(FML_IMU_DIR_FRONT);
  852. if(group_num > 0)
  853. {
  854. for(i=0;i<group_num;i++)
  855. {
  856. fml_imu_get_data(FML_IMU_DIR_FRONT, i, &data);
  857. f_acc[0] = data.acc[0];f_acc[1] = data.acc[1];f_acc[2] = data.acc[2];
  858. f_mag[0] = data.mag[0];f_mag[1] = data.mag[1];f_mag[2] = data.mag[2];
  859. monitor_sensor_data(f_acc, NULL, f_mag, NULL);
  860. }
  861. }
  862. }
  863. }
  864. 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)
  865. {
  866. if(TIME_GetTicks()-last_tim >= StandByPower_Interval) //监测前脚传感器数据(acc)
  867. {
  868. last_tim = TIME_GetTicks();
  869. group_num = fml_imu_get_data_num(FML_IMU_DIR_FRONT);
  870. if(group_num > 0)
  871. {
  872. for(i=0;i<group_num;i++)
  873. {
  874. fml_imu_get_data(FML_IMU_DIR_FRONT, i, &data);
  875. f_acc[0] = data.acc[0];f_acc[1] = data.acc[1];f_acc[2] = data.acc[2];
  876. monitor_sensor_data(f_acc, NULL, NULL, NULL);
  877. }
  878. }
  879. }
  880. }
  881. }
  882. static void fml_imu_Process(void)
  883. {
  884. int data_num[FML_IMU_DIR_NUM];
  885. uint32_t dir_bit;
  886. static char buf[255];
  887. static uint32_t config_err_report_tim = 0;
  888. switch(ob_fml_imu.stage)
  889. {
  890. case FML_IMU_CONFIG_STAGE_DONE: //配置完成阶段
  891. dir_bit = 0;
  892. //读取前脚IMU数据 + 更新前脚IMU数据量
  893. data_num[FML_IMU_DIR_FRONT] = hal_ser_imu_read_data(FML_IMU_DIR_FRONT);
  894. if(data_num[FML_IMU_DIR_FRONT] > 0){
  895. ob_fml_imu.cur_data_num[FML_IMU_DIR_FRONT] = data_num[FML_IMU_DIR_FRONT];
  896. dir_bit |= (1 << FML_IMU_DIR_FRONT);
  897. }
  898. //读取后脚IMU数据 + 更新后脚IMU数据量
  899. data_num[FML_IMU_DIR_BACK] = hal_ser_imu_read_data(FML_IMU_DIR_BACK);
  900. if(data_num[FML_IMU_DIR_BACK] > 0){
  901. ob_fml_imu.cur_data_num[FML_IMU_DIR_BACK] = data_num[FML_IMU_DIR_BACK];
  902. dir_bit |= (1 << FML_IMU_DIR_BACK);
  903. }
  904. //数据异常检测
  905. fml_imu_monitor_sensor_data_process(data_num[FML_IMU_DIR_FRONT], data_num[FML_IMU_DIR_BACK]);
  906. //数据回调通知
  907. if(dir_bit != 0 && ob_fml_imu.data_notify_cb != NULL)ob_fml_imu.data_notify_cb(dir_bit);
  908. break;
  909. case FML_IMU_CONFIG_STAGE_IN_PROGRESS: //配置进行阶段
  910. if(fml_imu_intergrated_setting() == -1)
  911. {
  912. //配置失败
  913. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_FAIL;
  914. //通知配置失败
  915. if(ob_fml_imu.config_cb != NULL)ob_fml_imu.config_cb(ob_fml_imu.config_flow);
  916. //上报异常
  917. sprintf(buf,"front_imu_suspend_overflow:0x%x\r\n",ob_fml_imu.config_flow);
  918. Except_TxError(EXCEPT_IMU_SUSPEND_OVERFLOW,buf);
  919. //断电前后脚
  920. fml_imu_close(FML_IMU_DIR_FRONT);
  921. fml_imu_close(FML_IMU_DIR_BACK);
  922. //解除全功率运行
  923. Process_SetHoldOn(fml_imu_Process,0);
  924. }
  925. else
  926. {
  927. if(ob_fml_imu.config_flow == FML_IMU_CONFIG_FLOW_DONE)
  928. {
  929. //配置成功
  930. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_DONE;
  931. //通知配置成功
  932. if(ob_fml_imu.config_cb != NULL)ob_fml_imu.config_cb(ob_fml_imu.config_flow);
  933. //更新驱动LSM配置参数
  934. drv_lsm_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm);
  935. //更新驱动LSM配置参数
  936. drv_qmc6310_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc);
  937. //解除全功率运行
  938. Process_SetHoldOn(fml_imu_Process,0);
  939. }
  940. }
  941. break;
  942. default:
  943. //间隔1000ms上报配置失败错误
  944. if(config_err_report_tim == 0){
  945. config_err_report_tim = TIME_GetTicks();
  946. }else if(TIME_GetTicks()-config_err_report_tim>=1000){
  947. sprintf(buf,"front_imu_suspend_overflow:0x%x\r\n",ob_fml_imu.config_flow);
  948. Except_TxError(EXCEPT_IMU_SUSPEND_OVERFLOW,buf);
  949. config_err_report_tim = 0;
  950. }
  951. break;
  952. }
  953. }
  954. /*API ------------------------------------------------------------------------------------------------------------------------------------*/
  955. /**
  956. @brief 初始化IMU功能模块
  957. @param 无
  958. @return 错误代码 - [out] -1失败,0成功
  959. */
  960. int fml_imu_Init(void)
  961. {
  962. int ret;
  963. /***************************************驱动层初始化***************************************************/
  964. //重置结构体
  965. memset(&ob_fml_imu,0,sizeof(ob_fml_imu));
  966. //初始化驱动LSM
  967. ret = drv_lsm_Init();
  968. //初始化驱动QMC
  969. ret += drv_qmc6310_Init();
  970. //获取驱动LSM配置参数
  971. drv_lsm_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm);
  972. //获取驱动LSM配置参数
  973. drv_qmc6310_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc);
  974. /***************************************业务逻辑层初始化***************************************************/
  975. //初始化IMU服务结构体
  976. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_DONE;
  977. //设置驱动配置线程
  978. Process_Start(0,"fml_imu_Process",fml_imu_Process);
  979. if(ret < 0)return -1;
  980. return 0;
  981. }
  982. /**
  983. @brief 设置需要配置IMU的参数
  984. @param param - [in] 设置IMU的参数
  985. @return 错误代码 - [out] -1失败,0成功
  986. */
  987. int fml_imu_config_param(FML_IMU_DIR_e dir, const fml_imu_param_t *param)
  988. {
  989. if(param == NULL || dir >= FML_IMU_DIR_NUM)return -1;
  990. memcpy(&ob_fml_imu.config_param[dir],param,sizeof(fml_imu_param_t));
  991. return 0;
  992. }
  993. /**
  994. @brief 获取配置IMU的参数
  995. @param param - [in] 返回的地址
  996. @return 错误代码 - [out] -1失败,0成功
  997. */
  998. int fml_imu_get_config_param(FML_IMU_DIR_e dir, fml_imu_param_t *param)
  999. {
  1000. if(param == NULL || dir >= FML_IMU_DIR_NUM)return -1;
  1001. memcpy(param,&ob_fml_imu.config_param[dir],sizeof(fml_imu_param_t));
  1002. return 0;
  1003. }
  1004. /**
  1005. @brief 注册IMU配置结果回调函数
  1006. @param cb - [in] 回调函数
  1007. @return 错误代码 - [out] -1失败,0成功
  1008. */
  1009. int fml_imu_register_config_callback(fml_imu_config_cb cb)
  1010. {
  1011. if(cb == NULL)return -1;
  1012. ob_fml_imu.config_cb = cb;
  1013. return 0;
  1014. }
  1015. /**
  1016. @brief 注册IMU数据通知回调函数
  1017. @param cb - [in] 回调函数
  1018. @return 错误代码 - [out] -1失败,0成功
  1019. */
  1020. int fml_imu_register_data_notify_callback(fml_imu_data_notify_cb cb)
  1021. {
  1022. if(cb == NULL)return -1;
  1023. ob_fml_imu.data_notify_cb = cb;
  1024. return 0;
  1025. }
  1026. /**
  1027. @brief 开始配置IMU
  1028. @param param 无
  1029. @return 返回配置状态: - [out] -1不需要重新配置,0需要重新配置
  1030. */
  1031. int fml_imu_start_config(void)
  1032. {
  1033. drv_param_u lsm_drv_param;
  1034. drv_param_u qmc_drv_param;
  1035. //获取驱动LSM配置参数
  1036. drv_lsm_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm);
  1037. //获取驱动QMC配置参数
  1038. drv_qmc6310_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc);
  1039. //转换参数
  1040. fml_imu_macro_conversion(FML_IMU_DIR_FRONT, &ob_fml_imu.config_param[FML_IMU_DIR_FRONT], &lsm_drv_param);
  1041. fml_imu_macro_conversion(FML_IMU_DIR_BACK, &ob_fml_imu.config_param[FML_IMU_DIR_BACK], &qmc_drv_param);
  1042. //进行对比
  1043. if((memcmp(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm,&lsm_drv_param.lsm,sizeof(lsm_drv_param.lsm)) != 0) || \
  1044. (memcmp(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc,&qmc_drv_param.qmc,sizeof(qmc_drv_param.qmc)) != 0)
  1045. )
  1046. {
  1047. ob_fml_imu.stage = FML_IMU_CONFIG_STAGE_IN_PROGRESS;
  1048. ob_fml_imu.config_flow = 0;
  1049. //全功率运行进行配置
  1050. Process_SetHoldOn(fml_imu_Process,1);
  1051. return 0;
  1052. }
  1053. return -1;
  1054. }
  1055. /**
  1056. @brief 读取当前IMU数据的数量
  1057. @param dir - [in] 方向
  1058. @return 返回当前IMU数据的数量
  1059. */
  1060. int fml_imu_get_data_num(FML_IMU_DIR_e dir)
  1061. {
  1062. if(dir >= FML_IMU_DIR_NUM)return 0;
  1063. return ob_fml_imu.cur_data_num[dir];
  1064. }
  1065. /**
  1066. @brief 获取当前IMU数据
  1067. @param dir - [in] 方向
  1068. @param index - [in] 数据索引
  1069. @param pdata - [out] 返回的IMU数据指针
  1070. @return 错误代码 - [out] -1失败,0成功
  1071. */
  1072. int fml_imu_get_data(FML_IMU_DIR_e dir, int index, fml_imu_data_t *pdata)
  1073. {
  1074. if(index < 0 || pdata == NULL || dir >= FML_IMU_DIR_NUM)return -1;
  1075. *pdata = ob_fml_imu.cur_data[dir][index];
  1076. return 0;
  1077. }
  1078. /**
  1079. @brief 关闭IMU
  1080. @param dir - [in] 方向
  1081. @return 错误代码 - [out] -1失败,0成功
  1082. */
  1083. int fml_imu_close(FML_IMU_DIR_e dir)
  1084. {
  1085. if(dir >= FML_IMU_DIR_NUM)return -1;
  1086. switch(dir)
  1087. {
  1088. case FML_IMU_DIR_FRONT:
  1089. drv_lsm_power_on(); //主要是复位结构体
  1090. drv_lsm_power_off();
  1091. memset(&ob_fml_imu.config_param[FML_IMU_DIR_FRONT],0,sizeof(ob_fml_imu.config_param[FML_IMU_DIR_FRONT]));
  1092. //获取驱动LSM配置参数
  1093. drv_lsm_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_FRONT].lsm);
  1094. //配置完成!
  1095. ob_fml_imu.config_flow = FML_IMU_CONFIG_FLOW_DONE;
  1096. break;
  1097. case FML_IMU_DIR_BACK:
  1098. drv_qmc6310_power_on(); //主要是复位结构体
  1099. drv_qmc6310_power_off();
  1100. memset(&ob_fml_imu.config_param[FML_IMU_DIR_BACK],0,sizeof(ob_fml_imu.config_param[FML_IMU_DIR_BACK]));
  1101. //获取驱动LSM配置参数
  1102. drv_qmc6310_get_config_param(&ob_fml_imu.drv_param[FML_IMU_DIR_BACK].qmc);
  1103. //配置完成!
  1104. ob_fml_imu.config_flow = FML_IMU_CONFIG_FLOW_DONE;
  1105. break;
  1106. default:
  1107. break;
  1108. }
  1109. return 0;
  1110. }