bll_imu.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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 20 //IMU能存储的最大数据组数
  10. #define BLL_IMU_REGISTER_CONFIG_PARAM_MAX 20 //IMU能存储的最大数据组数
  11. #define BLL_IMU_REGISTER_DATA_NOTIFY_MAX 20 //IMU能数据通知回调的最大数量
  12. #define BLL_IMU_GET_MAX(a,b) (((a) > (b)) ? (a) : (b)) //对比大小宏
  13. /*STRUCTION ------------------------------------------------------------------------------------------------------------------------------------*/
  14. typedef struct bll_imu_data_notify
  15. {
  16. int priority; //优先级
  17. bll_imu_data_notify_cb cb; //回调函数
  18. }Bll_Imu_Data_Notify_t;
  19. typedef struct bll_imu
  20. {
  21. /*private member*/
  22. 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_param_t highest_priority_config_param; //最高优先级配置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)
  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_param_t *out_param, bll_imu_param_t *int_param)
  58. {
  59. if(out_param == NULL || int_param == NULL)return -1;
  60. //前脚
  61. out_param->config_param[BLL_IMU_DIR_FRONT].acc_fs = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].acc_fs, int_param->config_param[BLL_IMU_DIR_FRONT].acc_fs);
  62. out_param->config_param[BLL_IMU_DIR_FRONT].acc_odr = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].acc_odr, int_param->config_param[BLL_IMU_DIR_FRONT].acc_odr);
  63. out_param->config_param[BLL_IMU_DIR_FRONT].acc_power_mode = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].acc_power_mode, int_param->config_param[BLL_IMU_DIR_FRONT].acc_power_mode);
  64. out_param->config_param[BLL_IMU_DIR_FRONT].fifo_odr = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].fifo_odr, int_param->config_param[BLL_IMU_DIR_FRONT].fifo_odr);
  65. out_param->config_param[BLL_IMU_DIR_FRONT].gry_fs = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].gry_fs, int_param->config_param[BLL_IMU_DIR_FRONT].gry_fs);
  66. out_param->config_param[BLL_IMU_DIR_FRONT].gry_odr = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].gry_odr, int_param->config_param[BLL_IMU_DIR_FRONT].gry_odr);
  67. out_param->config_param[BLL_IMU_DIR_FRONT].gry_power_mode = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].gry_power_mode, int_param->config_param[BLL_IMU_DIR_FRONT].gry_power_mode);
  68. out_param->config_param[BLL_IMU_DIR_FRONT].mag_fs = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].mag_fs, int_param->config_param[BLL_IMU_DIR_FRONT].mag_fs);
  69. out_param->config_param[BLL_IMU_DIR_FRONT].mag_odr = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].mag_odr, int_param->config_param[BLL_IMU_DIR_FRONT].mag_odr);
  70. out_param->config_param[BLL_IMU_DIR_FRONT].timestamp_resolution = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].timestamp_resolution, int_param->config_param[BLL_IMU_DIR_FRONT].timestamp_resolution);
  71. out_param->config_param[BLL_IMU_DIR_FRONT].timestamp_switch = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_FRONT].timestamp_switch, int_param->config_param[BLL_IMU_DIR_FRONT].timestamp_switch);
  72. //后脚
  73. out_param->config_param[BLL_IMU_DIR_BACK].acc_fs = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].acc_fs, int_param->config_param[BLL_IMU_DIR_BACK].acc_fs);
  74. out_param->config_param[BLL_IMU_DIR_BACK].acc_odr = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].acc_odr, int_param->config_param[BLL_IMU_DIR_BACK].acc_odr);
  75. out_param->config_param[BLL_IMU_DIR_BACK].acc_power_mode = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].acc_power_mode, int_param->config_param[BLL_IMU_DIR_BACK].acc_power_mode);
  76. out_param->config_param[BLL_IMU_DIR_BACK].fifo_odr = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].fifo_odr, int_param->config_param[BLL_IMU_DIR_BACK].fifo_odr);
  77. out_param->config_param[BLL_IMU_DIR_BACK].gry_fs = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].gry_fs, int_param->config_param[BLL_IMU_DIR_BACK].gry_fs);
  78. out_param->config_param[BLL_IMU_DIR_BACK].gry_odr = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].gry_odr, int_param->config_param[BLL_IMU_DIR_BACK].gry_odr);
  79. out_param->config_param[BLL_IMU_DIR_BACK].gry_power_mode = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].gry_power_mode, int_param->config_param[BLL_IMU_DIR_BACK].gry_power_mode);
  80. out_param->config_param[BLL_IMU_DIR_BACK].mag_fs = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].mag_fs, int_param->config_param[BLL_IMU_DIR_BACK].mag_fs);
  81. out_param->config_param[BLL_IMU_DIR_BACK].mag_odr = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].mag_odr, int_param->config_param[BLL_IMU_DIR_BACK].mag_odr);
  82. out_param->config_param[BLL_IMU_DIR_BACK].timestamp_resolution = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].timestamp_resolution, int_param->config_param[BLL_IMU_DIR_BACK].timestamp_resolution);
  83. out_param->config_param[BLL_IMU_DIR_BACK].timestamp_switch = BLL_IMU_GET_MAX(out_param->config_param[BLL_IMU_DIR_BACK].timestamp_switch, int_param->config_param[BLL_IMU_DIR_BACK].timestamp_switch);
  84. return 0;
  85. }
  86. /*API ------------------------------------------------------------------------------------------------------------------------------------*/
  87. /**
  88. @brief 初始化IMU业务逻辑层
  89. @param 无
  90. @return 错误代码 - [out] -1失败,0成功
  91. */
  92. int bll_imu_Init(void)
  93. {
  94. int ret = 0;
  95. //初始化imu服务
  96. if(fml_imu_Init() == -1)ret = -1;
  97. //重置模式管理服务结构体
  98. memset(&ob_bll_imu, 0, sizeof(ob_bll_imu));
  99. //默认配置完成
  100. ob_bll_imu.config_result |= (2 << 6);
  101. ob_bll_imu.config_result |= 0x3F;
  102. if(ret == -1)return -1;
  103. return 0;
  104. }
  105. /**
  106. @brief 注册IMU要进行配置的参数
  107. @param param - [in] IMU要进行配置的参数
  108. @return 返回该配置参数的句柄,-1返回失败,0~19返回成功。
  109. */
  110. int bll_imu_register_config_param(const bll_imu_param_t *param)
  111. {
  112. if(param == NULL)return -1;
  113. for(int i=0; i<BLL_IMU_REGISTER_CONFIG_PARAM_MAX; i++)
  114. {
  115. if(ob_bll_imu.register_config_param[i] != 0)
  116. {
  117. ob_bll_imu.register_config_param[i] = (bll_imu_param_t *)param;
  118. return i;
  119. }
  120. }
  121. return -1;
  122. }
  123. /**
  124. @brief 注销已注册的IMU配置参数
  125. @param handle - [in] IMU配置参数的句柄
  126. @return 错误代码 - [out] -1失败,0成功
  127. */
  128. int bll_imu_unregister_config_param(int handle)
  129. {
  130. if(handle < 0 || handle >=BLL_IMU_REGISTER_CONFIG_PARAM_MAX)return -1;
  131. ob_bll_imu.register_config_param[handle] = 0;
  132. return 0;
  133. }
  134. /**
  135. @brief 开始配置。根据已注册IMU参数筛选出最高优先级进行配置,且只配置一次。
  136. @param 无
  137. @return 错误代码 - [out] -1失败,0成功
  138. */
  139. int bll_imu_start_config(void)
  140. {
  141. int ret;
  142. //清除当前最高优先级配置参数
  143. memset(&ob_bll_imu.highest_priority_config_param,0,sizeof(ob_bll_imu.highest_priority_config_param));
  144. //获取最高优先级配置
  145. for(int i=0; i<BLL_IMU_REGISTER_CONFIG_PARAM_MAX; i++)
  146. {
  147. if(ob_bll_imu.register_config_param[i] != 0)
  148. {
  149. ret = bll_imu_get_highest_priority_config_param(&ob_bll_imu.highest_priority_config_param, ob_bll_imu.register_config_param[i]);
  150. if(ret == -1)return -1;
  151. }
  152. }
  153. //设置前脚要配置的参数
  154. ret = fml_imu_config_param((FML_IMU_DIR_e)BLL_IMU_DIR_FRONT, &ob_bll_imu.highest_priority_config_param.config_param[BLL_IMU_DIR_FRONT]);
  155. if(ret == -1)return -1;
  156. //设置后脚要配置的参数
  157. ret = fml_imu_config_param((FML_IMU_DIR_e)BLL_IMU_DIR_BACK, &ob_bll_imu.highest_priority_config_param.config_param[BLL_IMU_DIR_BACK]);
  158. if(ret == -1)return -1;
  159. //注册配置回调函数
  160. ret = fml_imu_register_config_callback(bll_imu_register_config_cb);
  161. if(ret == -1)return -1;
  162. //注册数据通知回调函数
  163. ret = fml_imu_register_data_notify_callback(bll_imu_register_data_notify_cb);
  164. if(ret == -1)return -1;
  165. //开始配置IMU
  166. ret = fml_imu_start_config();
  167. if(ret == 0)
  168. {
  169. //设置为配置中...
  170. ob_bll_imu.config_result = 0;
  171. ob_bll_imu.config_result |= (1 << 6);
  172. }
  173. return 0;
  174. }
  175. /**
  176. @brief 查询IMU配置参数是否准备好
  177. @param param - [in] 需要查询的IMU配置参数
  178. @return 查询结果 - [out] [7:6]是状态,0:失败,1:配置中,2:成功,3:当前最高配置参数与输入的配置参数不匹配; [0:5]是配置步骤.
  179. */
  180. uint8_t bll_imu_query_config_param_is_ready(bll_imu_param_t *param)
  181. {
  182. uint8_t result = 0;
  183. //当前最高配置参数与输入的配置参数不匹配
  184. if(memcmp(&ob_bll_imu.highest_priority_config_param,param,sizeof(bll_imu_param_t)) != 0)
  185. {
  186. result |= (3 << 6);
  187. }
  188. else
  189. {
  190. result = ob_bll_imu.config_result;
  191. }
  192. return result;
  193. }
  194. /**
  195. @brief 读取当前IMU数据的数量
  196. @param dir - [in] 方向
  197. @return 返回当前IMU数据的数量
  198. */
  199. int bll_imu_get_data_num(BLL_IMU_DIR_e dir)
  200. {
  201. return fml_imu_get_data_num((FML_IMU_DIR_e)dir);
  202. }
  203. /**
  204. @brief 获取当前IMU数据
  205. @param dir - [in] 方向
  206. @param index - [in] 数据索引
  207. @param pdata - [out] 返回的IMU数据指针
  208. @return 错误代码 - [out] -1失败,0成功
  209. */
  210. int bll_imu_get_data(BLL_IMU_DIR_e dir, int index, bll_imu_data_t *pdata)
  211. {
  212. return fml_imu_get_data((FML_IMU_DIR_e)dir, index, pdata);
  213. }
  214. /**
  215. @brief 注册IMU数据通知回调函数
  216. @param priority - [in] 回调优先级,最高是1,最低是0
  217. @param cb - [in] 回调函数
  218. @return 错误代码 - [out] -1失败,0成功
  219. */
  220. int bll_imu_register_data_notify_callback(BLL_IMU_DATA_NOTIFY_CB_PRIORITY_e priority, bll_imu_data_notify_cb cb)
  221. {
  222. if(cb == NULL || priority>=BLL_IMU_DATA_NOTIFY_CB_PRIORITY_NUM)return -1;
  223. for(int i=0; i<BLL_IMU_REGISTER_DATA_NOTIFY_MAX; i++)
  224. {
  225. if(ob_bll_imu.register_data_notify[i].cb != 0)
  226. {
  227. ob_bll_imu.register_data_notify[i].cb = cb;
  228. ob_bll_imu.register_data_notify[i].priority = priority;
  229. return i;
  230. }
  231. }
  232. return -1;
  233. }
  234. /**
  235. @brief 关闭IMU
  236. @return 错误代码 - [out] -1失败,0成功
  237. */
  238. int bll_imu_close(void)
  239. {
  240. int ret;
  241. //断电前后脚
  242. ret = fml_imu_close(FML_IMU_DIR_FRONT);
  243. if(ret == -1)return -1;
  244. ret = fml_imu_close(FML_IMU_DIR_BACK);
  245. if(ret == -1)return -1;
  246. return 0;
  247. }