bll_imu - 副本.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. /*Includes ----------------------------------------------*/
  2. #include "tool.h"
  3. #include "nrf_delay.h"
  4. #include "bsp_time.h"
  5. #include "exception.h"
  6. #include "system.h"
  7. #include "bll_imu.h"
  8. /*Private macro ------------------------------------------------------------------------------------------------------------------------------------*/
  9. #define BLL_IMU_DATA_GROUP_NUM_MAX 12 //IMU能存储的最大数据组数
  10. #define BLL_IMU_REGISTER_CONFIG_PARAM_MAX 12 //IMU能存储的最大数据组数
  11. #define BLL_IMU_REGISTER_DATA_NOTIFY_MAX 5 //IMU能数据通知回调的最大数量
  12. #define BLL_IMU_GET_MAX(a,b) (((a) > (b)) ? (a) : (b)) //对比大小宏
  13. /*STRUCTION ------------------------------------------------------------------------------------------------------------------------------------*/
  14. typedef struct bll_imu_data_notify
  15. {
  16. uint8_t priority; //优先级
  17. bll_imu_data_notify_cb cb; //回调函数
  18. }Bll_Imu_Data_Notify_t;
  19. typedef struct bll_imu
  20. {
  21. /*private member*/
  22. const bll_imu_param_t *register_config_param[BLL_IMU_REGISTER_CONFIG_PARAM_MAX]; //已注册的IMU配置参数地址
  23. Bll_Imu_Data_Notify_t register_data_notify[BLL_IMU_REGISTER_DATA_NOTIFY_MAX]; //已注册的IMU数据通知回调
  24. bll_imu_one_way_param_t highest_priority_config_param[BLL_IMU_DIR_NUM]; //最高优先级配置IMU参数
  25. uint8_t config_result; //配置结果
  26. } Bll_Imu_t;
  27. /*Local Variable ------------------------------------------------------------------------------------------------------------------------------------*/
  28. static Bll_Imu_t ob_bll_imu;
  29. /*Local Functions ------------------------------------------------------------------------------------------------------------------------------------*/
  30. static void bll_imu_register_config_cb(uint32_t conf_result)
  31. {
  32. ob_bll_imu.config_result = 0;
  33. if(conf_result == FML_IMU_CONFIG_FLOW_DONE) //配置成功
  34. {
  35. ob_bll_imu.config_result |= (2 << 6);
  36. }
  37. else //配置失败
  38. {
  39. ob_bll_imu.config_result = conf_result;
  40. ob_bll_imu.config_result |= (0 << 6);
  41. }
  42. }
  43. static void bll_imu_register_data_notify_cb(uint32_t dir_bit)
  44. {
  45. //从最高优先级开始筛选
  46. for(int i=BLL_IMU_DATA_NOTIFY_CB_PRIORITY_NUM - 1; i >= 0; i--)
  47. {
  48. for(int j=0; j<BLL_IMU_REGISTER_DATA_NOTIFY_MAX;j++)
  49. {
  50. if(ob_bll_imu.register_data_notify[j].priority == i && ob_bll_imu.register_data_notify[j].cb != NULL)
  51. {
  52. ob_bll_imu.register_data_notify[j].cb(dir_bit);
  53. }
  54. }
  55. }
  56. }
  57. static int bll_imu_get_highest_priority_config_param(bll_imu_one_way_param_t out_param[], const bll_imu_one_way_param_t int_param[])
  58. {
  59. if(out_param == NULL || int_param == NULL)return -1;
  60. for(uint8_t i=0; i<BLL_IMU_DIR_NUM; i++){
  61. out_param[i].acc_fs = BLL_IMU_GET_MAX(out_param[i].acc_fs, int_param[i].acc_fs);
  62. out_param[i].acc_odr = BLL_IMU_GET_MAX(out_param[i].acc_odr, int_param[i].acc_odr);
  63. out_param[i].acc_power_mode = BLL_IMU_GET_MAX(out_param[i].acc_power_mode,int_param[i].acc_power_mode);
  64. out_param[i].fifo_odr = BLL_IMU_GET_MAX(out_param[i].fifo_odr,int_param[i].fifo_odr);
  65. out_param[i].gry_fs = BLL_IMU_GET_MAX(out_param[i].gry_fs,int_param[i].gry_fs);
  66. out_param[i].gry_odr = BLL_IMU_GET_MAX(out_param[i].gry_odr,int_param[i].gry_odr);
  67. out_param[i].gry_power_mode = BLL_IMU_GET_MAX(out_param[i].gry_power_mode,int_param[i].gry_power_mode);
  68. out_param[i].mag_fs = BLL_IMU_GET_MAX(out_param[i].mag_fs,int_param[i].mag_fs);
  69. out_param[i].mag_odr = BLL_IMU_GET_MAX(out_param[i].mag_odr,int_param[i].mag_odr);
  70. out_param[i].timestamp_resolution = BLL_IMU_GET_MAX(out_param[i].timestamp_resolution,int_param[i].timestamp_resolution);
  71. out_param[i].timestamp_switch = BLL_IMU_GET_MAX(out_param[i].timestamp_switch,int_param[i].timestamp_switch);
  72. }
  73. return 0;
  74. }
  75. /*API ------------------------------------------------------------------------------------------------------------------------------------*/
  76. /**
  77. @brief 初始化IMU业务逻辑层
  78. @param 无
  79. @return 错误代码 - [out] -1失败,0成功
  80. */
  81. static const fml_imu_param_t standby_front_param={
  82. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //前脚 - 加速度正常模式
  83. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //前脚 - 陀螺仪正常模式
  84. .fifo_odr = FML_IMU_FIFO_ODR_OFF, //前脚 - FIFO采样频率 - 104HZ
  85. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //前脚 - 时间戳25US精度
  86. .timestamp_switch = FML_IMU_TIMESTAMP_OFF, //前脚 - 时间戳关闭
  87. .acc_odr = FML_IMU_ACC_ODR_12HZ5, //前脚 - 加速度采样频率 - 12.5HZ
  88. .gry_odr = FML_IMU_GRY_ODR_OFF, //前脚 - 陀螺仪采样频率 - 关闭
  89. .mag_odr = FML_IMU_MAG_ODR_OFF, //前脚 - 地磁计采样频率 - 关闭
  90. .acc_fs = FML_IMU_ACC_FS_16G, //前脚 - 加速度量程 - 16G
  91. .gry_fs = FML_IMU_GRY_FS_2000DPS, //前脚 - 陀螺仪量程 - 2000DPS
  92. .mag_fs = FML_IMU_MAG_FS_30GS, //前脚 - 地磁计量程 - 30GS
  93. };
  94. static const fml_imu_param_t standby_back_param={
  95. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //后脚 - 加速度正常模式
  96. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //后脚 - 陀螺仪正常模式
  97. .fifo_odr = FML_IMU_FIFO_ODR_OFF, //后脚 - FIFO采样频率 - 关闭
  98. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //后脚 - 时间戳25US精度
  99. .timestamp_switch = FML_IMU_TIMESTAMP_OFF, //后脚 - 时间戳关闭
  100. .acc_odr = FML_IMU_ACC_ODR_OFF, //后脚 - 加速度采样频率 - 关闭
  101. .gry_odr = FML_IMU_GRY_ODR_OFF, //后脚 - 陀螺仪采样频率 - 关闭
  102. .mag_odr = FML_IMU_MAG_ODR_10HZ, //后脚 - 地磁计采样频率 - 10HZ
  103. .acc_fs = FML_IMU_ACC_FS_16G, //后脚 - 加速度量程 - 16G
  104. .gry_fs = FML_IMU_GRY_FS_2000DPS, //后脚 - 陀螺仪量程 - 2000DPS
  105. .mag_fs = FML_IMU_MAG_FS_30GS, //后脚 - 地磁计量程 - 30GS
  106. };
  107. static const bll_imu_param_t standby_imu_param_t={
  108. .config_param[FML_IMU_DIR_FRONT] = &standby_front_param,
  109. .config_param[FML_IMU_DIR_BACK] = &standby_back_param,
  110. };
  111. int bll_imu_Init(void)
  112. {
  113. int ret = 0;
  114. //初始化imu服务
  115. if(fml_imu_Init() == -1)ret = -1;
  116. //重置模式管理服务结构体
  117. memset(&ob_bll_imu, 0, sizeof(ob_bll_imu));
  118. //默认配置完成
  119. ob_bll_imu.config_result |= (2 << 6);
  120. //指向最高优先级配置IMU参数
  121. bll_imu_get_highest_priority_config_param(ob_bll_imu.highest_priority_config_param,*standby_imu_param_t.config_param);
  122. if(ret == -1)return -1;
  123. return 0;
  124. }
  125. /**
  126. @brief 注册IMU要进行配置的参数
  127. @param param - [in] IMU要进行配置的参数地址
  128. @return 错误代码 - [out] 0失败,成功返回参数地址
  129. */
  130. const bll_imu_param_t* bll_imu_register_config_param(const bll_imu_param_t *param)
  131. {
  132. if(param == NULL)return 0;
  133. //若已存在,则返回该指针的地址作为句柄返回
  134. for(int i=0; i<BLL_IMU_REGISTER_CONFIG_PARAM_MAX; i++)
  135. {
  136. if(ob_bll_imu.register_config_param[i] == param)return param;
  137. }
  138. //若不存在,则存储起来,且将该指针的地址作为句柄返回
  139. for(int i=0; i<BLL_IMU_REGISTER_CONFIG_PARAM_MAX; i++)
  140. {
  141. if(ob_bll_imu.register_config_param[i] == 0)
  142. {
  143. ob_bll_imu.register_config_param[i] = param;
  144. return param;
  145. }
  146. }
  147. return 0;
  148. }
  149. /**
  150. @brief 注销已注册的IMU配置参数
  151. @param param - [in] IMU配置参数的地址
  152. @return 错误代码 - [out] 0成功,-1地址异常,-2没有该注册的IMU配置参数
  153. */
  154. int bll_imu_unregister_config_param(const bll_imu_param_t* param)
  155. {
  156. if(param == NULL)return -1;
  157. for(int i=0; i<BLL_IMU_REGISTER_CONFIG_PARAM_MAX; i++)
  158. {
  159. if(ob_bll_imu.register_config_param[i] == param)
  160. {
  161. ob_bll_imu.register_config_param[i] = 0;
  162. return 0;
  163. }
  164. }
  165. return -2;
  166. }
  167. /**
  168. @brief 注册IMU数据通知回调函数
  169. @param priority - [in] 回调优先级
  170. @param cb - [in] 回调函数
  171. @return 错误代码 - [out] -1失败,0成功
  172. */
  173. int bll_imu_register_data_notify_callback(BLL_IMU_DATA_NOTIFY_CB_PRIORITY_e priority, bll_imu_data_notify_cb cb)
  174. {
  175. if(cb == NULL || priority>=BLL_IMU_DATA_NOTIFY_CB_PRIORITY_NUM)return -1;
  176. //若是已存在,更新优先级
  177. for(int i=0; i<BLL_IMU_REGISTER_DATA_NOTIFY_MAX; i++)
  178. {
  179. //已存在回调函数
  180. if(ob_bll_imu.register_data_notify[i].cb == cb)
  181. {
  182. //更新优先级
  183. ob_bll_imu.register_data_notify[i].priority = priority;
  184. return 0;
  185. }
  186. }
  187. //若是不存在
  188. for(int i=0; i<BLL_IMU_REGISTER_DATA_NOTIFY_MAX; i++)
  189. {
  190. //找到空位,进行赋值
  191. if(ob_bll_imu.register_data_notify[i].cb == 0)
  192. {
  193. ob_bll_imu.register_data_notify[i].cb = cb;
  194. ob_bll_imu.register_data_notify[i].priority = priority;
  195. return 0;
  196. }
  197. }
  198. //满了
  199. return -1;
  200. }
  201. /**
  202. @brief 开始配置。根据已注册IMU参数筛选出最高优先级进行配置,且只配置一次。
  203. @param 无
  204. @return 错误代码 - [out] -1失败,0成功
  205. */
  206. int bll_imu_start_config(void)
  207. {
  208. int ret= 0xff;
  209. uint8_t i=0;
  210. //清除当前最高优先级配置参数
  211. for(i=0; i<BLL_IMU_DIR_NUM; i++)
  212. memset(&ob_bll_imu.highest_priority_config_param[i],0,sizeof(bll_imu_one_way_param_t));
  213. //获取前脚和后脚最高优先级配置
  214. for(i=0; i<BLL_IMU_REGISTER_CONFIG_PARAM_MAX; i++){
  215. if(ob_bll_imu.register_config_param[i] != 0)
  216. {
  217. DEBUG_LOG("!!!!!!!!!loop i \n");
  218. ret = bll_imu_get_highest_priority_config_param(ob_bll_imu.highest_priority_config_param, *ob_bll_imu.register_config_param[i]->config_param);
  219. if(ret == -1)return -1;
  220. }
  221. }
  222. if(0xff == ret){//参数列表无数据,变成默认值
  223. bll_imu_get_highest_priority_config_param(ob_bll_imu.highest_priority_config_param,*standby_imu_param_t.config_param);
  224. }
  225. DEBUG_LOG("config param front :%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
  226. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].acc_power_mode,
  227. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].gry_power_mode,
  228. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].timestamp_resolution,
  229. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].timestamp_switch,
  230. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].acc_fs,
  231. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].gry_fs,
  232. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].mag_fs,
  233. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].acc_odr,
  234. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].gry_odr,
  235. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].mag_odr,
  236. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT].fifo_odr
  237. );
  238. DEBUG_LOG("config param back :%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
  239. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].acc_power_mode,
  240. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].gry_power_mode,
  241. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].timestamp_resolution,
  242. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].timestamp_switch,
  243. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].acc_fs,
  244. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].gry_fs,
  245. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].mag_fs,
  246. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].acc_odr,
  247. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].gry_odr,
  248. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].mag_odr,
  249. ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK].fifo_odr
  250. );
  251. //设置前脚要配置的参数
  252. ret = fml_imu_config_param((FML_IMU_DIR_e)BLL_IMU_DIR_FRONT, &ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT]);
  253. if(ret == -1)return -1;
  254. //设置后脚要配置的参数
  255. ret = fml_imu_config_param((FML_IMU_DIR_e)BLL_IMU_DIR_BACK, &ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK]);
  256. if(ret == -1)return -1;
  257. //注册配置回调函数
  258. ret = fml_imu_register_config_callback(bll_imu_register_config_cb);
  259. if(ret == -1)return -1;
  260. //注册数据通知回调函数
  261. ret = fml_imu_register_data_notify_callback(bll_imu_register_data_notify_cb);
  262. if(ret == -1)return -1;
  263. //开始配置IMU
  264. ret = fml_imu_start_config();
  265. if(ret == 0)
  266. {
  267. //设置为配置中...
  268. ob_bll_imu.config_result = 0;
  269. ob_bll_imu.config_result |= (1 << 6);
  270. }
  271. return 0;
  272. }
  273. /**
  274. @brief 查询IMU配置参数是否准备好
  275. @param dir - [in] 方向
  276. @param param - [in] 需要查询的IMU配置参数
  277. @return 查询结果 - [out] [7:6]是状态,0:失败,1:配置中,2:成功,3:当前最高配置参数小于输入的配置参数或方向不符合; [0:5]是配置步骤.
  278. */
  279. uint8_t bll_imu_query_config_param_is_ready(BLL_IMU_DIR_e dir, const bll_imu_param_t *param)
  280. {
  281. uint8_t result = 0;
  282. if(param == NULL || dir >= BLL_IMU_DIR_NUM)
  283. {
  284. result |= (3 << 6);
  285. return result;
  286. }
  287. const bll_imu_one_way_param_t *front_bll = param->config_param[BLL_IMU_DIR_FRONT];
  288. const bll_imu_one_way_param_t *back_bll = param->config_param[BLL_IMU_DIR_BACK];
  289. const bll_imu_one_way_param_t *highest_front_bll = &ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_FRONT];
  290. const bll_imu_one_way_param_t *highest_back_bll = &ob_bll_imu.highest_priority_config_param[BLL_IMU_DIR_BACK];
  291. //当前最高配置参数小于输入的配置参数
  292. switch(dir)
  293. {
  294. case BLL_IMU_DIR_FRONT:
  295. //前脚
  296. if(front_bll->acc_fs > highest_front_bll->acc_fs)return result |= (3 << 6);
  297. if(front_bll->acc_odr > highest_front_bll->acc_odr)return result |= (3 << 6);
  298. if(front_bll->acc_power_mode > highest_front_bll->acc_power_mode)return result |= (3 << 6);
  299. if(front_bll->fifo_odr > highest_front_bll->fifo_odr)return result |= (3 << 6);
  300. if(front_bll->gry_fs > highest_front_bll->gry_fs)return result |= (3 << 6);
  301. if(front_bll->gry_odr > highest_front_bll->gry_odr)return result |= (3 << 6);
  302. if(front_bll->gry_power_mode > highest_front_bll->gry_power_mode)return result |= (3 << 6);
  303. if(front_bll->mag_fs > highest_front_bll->mag_fs)return result |= (3 << 6);
  304. if(front_bll->mag_odr > highest_front_bll->mag_odr)return result |= (3 << 6);
  305. if(front_bll->timestamp_resolution > highest_front_bll->timestamp_resolution)return result |= (3 << 6);
  306. if(front_bll->timestamp_switch > highest_front_bll->timestamp_switch)return result |= (3 << 6);
  307. break;
  308. case BLL_IMU_DIR_BACK:
  309. //后脚
  310. if(back_bll->acc_fs > highest_back_bll->acc_fs)return result |= (3 << 6);
  311. if(back_bll->acc_odr > highest_back_bll->acc_odr)return result |= (3 << 6);
  312. if(back_bll->acc_power_mode > highest_back_bll->acc_power_mode)return result |= (3 << 6);
  313. if(back_bll->fifo_odr > highest_back_bll->fifo_odr)return result |= (3 << 6);
  314. if(back_bll->gry_fs > highest_back_bll->gry_fs)return result |= (3 << 6);
  315. if(back_bll->gry_odr > highest_back_bll->gry_odr)return result |= (3 << 6);
  316. if(back_bll->gry_power_mode > highest_back_bll->gry_power_mode)return result |= (3 << 6);
  317. if(back_bll->mag_fs > highest_back_bll->mag_fs)return result |= (3 << 6);
  318. if(back_bll->mag_odr > highest_back_bll->mag_odr)return result |= (3 << 6);
  319. if(back_bll->timestamp_resolution > highest_back_bll->timestamp_resolution)return result |= (3 << 6);
  320. if(back_bll->timestamp_switch > highest_back_bll->timestamp_switch)return result |= (3 << 6);
  321. break;
  322. default:
  323. break;
  324. }
  325. result = ob_bll_imu.config_result;
  326. return result;
  327. }
  328. /**
  329. @brief 读取当前IMU数据的数量
  330. @param dir - [in] 方向
  331. @return 返回当前IMU数据的数量
  332. */
  333. int bll_imu_get_data_num(BLL_IMU_DIR_e dir)
  334. {
  335. return fml_imu_get_data_num((FML_IMU_DIR_e)dir);
  336. }
  337. /**
  338. @brief 获取当前IMU数据
  339. @param dir - [in] 方向
  340. @param index - [in] 数据索引
  341. @param pdata - [out] 返回的IMU数据指针
  342. @return 错误代码 - [out] -1失败,0成功
  343. */
  344. int bll_imu_get_data(BLL_IMU_DIR_e dir, int index, bll_imu_data_t *pdata)
  345. {
  346. return fml_imu_get_data((FML_IMU_DIR_e)dir, index, pdata);
  347. }
  348. /**
  349. @brief 关闭IMU
  350. @return 错误代码 - [out] -1失败,0成功
  351. */
  352. int bll_imu_close(void)
  353. {
  354. int ret;
  355. //断电前后脚
  356. ret = fml_imu_close(FML_IMU_DIR_FRONT);
  357. if(ret == -1)return -1;
  358. ret = fml_imu_close(FML_IMU_DIR_BACK);
  359. if(ret == -1)return -1;
  360. //重置模式管理服务结构体
  361. memset(&ob_bll_imu, 0, sizeof(ob_bll_imu));
  362. //默认配置完成
  363. ob_bll_imu.config_result |= (2 << 6);
  364. return 0;
  365. }