/*Includes ----------------------------------------------*/ #include "system.h" #include "hal_ser_imu.h" /*Private macro ------------------------------------------------------------------------------------------------------------------------------------*/ #define SER_IMU_HANDLE_NUM_MAX 10 //允许最大的句柄数量 #define INVALID_HANDLE 0x00 //无效句柄 #define VALID_HANDLE 0x01 //有效句柄 #define MAX(a,b) (((a) > (b)) ? (a) : (b)) //对比大小宏 #define IS_EQUAL(a,b) (((a) == (b)) ? true : false) //对比相等宏 #define SER_IMU_DATA_GROUP_NUM_MAX 20 //服务IMU最大数据组数 /*STRUCTION ------------------------------------------------------------------------------------------------------------------------------------*/ typedef enum { IMU_CONFIG_STAGE_DONE, //配置完成阶段 IMU_CONFIG_STAGE_IN_PROGRESS, //配置进行阶段 } IMU_CONFIG_STAGE_e; typedef struct { int id; //句柄id char *name; //句柄名称 ser_imu_config_param_t op_param[SER_IMU_DIR_NUM]; //操作的IMU配置参数副本 } ser_imu_handle_t; typedef union { drv_lsm_config_param_t lsm; //当前的LSM配置参数 drv_qmc_config_param_t qmc; //当前的QMC配置参数 } drv_param_u; typedef struct ser_imu { /*private member*/ IMU_CONFIG_STAGE_e stage; //配置流程状态 bool is_need_config[SER_IMU_DIR_NUM]; //各个方位的IMU是否需要配置 ser_imu_handle_t handle[SER_IMU_HANDLE_NUM_MAX]; //句柄组 drv_param_u drv_param[SER_IMU_DIR_NUM]; //驱动配置参数组 ser_imu_config_param_t compre_drv_param[SER_IMU_DIR_NUM]; //综合的驱动配置参数 int cur_data_num[SER_IMU_DIR_NUM]; //当前的数据量 ser_imu_data_t cur_data[SER_IMU_DIR_NUM][SER_IMU_DATA_GROUP_NUM_MAX]; //当前的IMU数据缓存区 } Ser_Imu_t; /*Local Variable ------------------------------------------------------------------------------------------------------------------------------------*/ static Ser_Imu_t ob_ser_imu; /*Local Functions ------------------------------------------------------------------------------------------------------------------------------------*/ static int hal_ser_imu_macro_conversion_acc_odr(SER_IMU_DIR_e dir, SER_IMU_ACC_ODR_e acc_odr) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(acc_odr) { case SER_IMU_ACC_ODR_OFF: ret = LSM_ACC_ODR_OFF; break; case SER_IMU_ACC_ODR_104HZ: ret = LSM_ACC_ODR_104HZ; break; case SER_IMU_ACC_ODR_12HZ5: ret = LSM_ACC_ODR_12HZ5; break; } } return ret; } static int hal_ser_imu_macro_conversion_gry_odr(SER_IMU_DIR_e dir, SER_IMU_GRY_ODR_e gry_odr) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(gry_odr) { case SER_IMU_GRY_ODR_OFF: ret = LSM_GRY_ODR_OFF; break; case SER_IMU_GRY_ODR_104HZ: ret = LSM_GRY_ODR_104HZ; break; case SER_IMU_GRY_ODR_12HZ5: ret = LSM_GRY_ODR_12HZ5; break; } } return ret; } static int hal_ser_imu_macro_conversion_mag_odr(SER_IMU_DIR_e dir, SER_IMU_MAG_ODR_e mag_odr) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(mag_odr) { case SER_IMU_MAG_ODR_OFF: ret = LSM_MAG_ODR_OFF; break; case SER_IMU_MAG_ODR_10HZ: ret = LSM_MAG_ODR_10HZ; break; case SER_IMU_MAG_ODR_100HZ: ret = LSM_MAG_ODR_100HZ; break; case SER_IMU_MAG_ODR_200HZ: ret = LSM_MAG_ODR_200HZ; break; } } if(dir == SER_IMU_DIR_BACK) { switch(mag_odr) { case SER_IMU_MAG_ODR_OFF: ret = QMC_MAG_ODR_OFF; break; case SER_IMU_MAG_ODR_10HZ: ret = QMC_MAG_ODR_10HZ; break; case SER_IMU_MAG_ODR_100HZ: ret = QMC_MAG_ODR_100HZ; break; case SER_IMU_MAG_ODR_200HZ: ret = QMC_MAG_ODR_200HZ; break; } } return ret; } static int hal_ser_imu_macro_conversion_fifo_odr(SER_IMU_DIR_e dir, SER_IMU_FIFO_ODR_e fifo_odr) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(fifo_odr) { case SER_IMU_FIFO_ODR_OFF: ret = LSM_FIFO_ODR_OFF; break; case SER_IMU_FIFO_ODR_104HZ: ret = LSM_FIFO_ODR_104HZ; break; } } return ret; } static int hal_ser_imu_macro_conversion_acc_power_mode(SER_IMU_DIR_e dir, SER_IMU_ACC_POWER_MODE_e acc_power_mode) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(acc_power_mode) { case SER_IMU_ACC_POWER_MODE_HIGH_PERFORMANCE: ret = LSM_ACC_POWER_MODE_HIGH_PERFORMANCE; break; case SER_IMU_ACC_POWER_MODE_NORMAL: ret = LSM_ACC_POWER_MODE_NORMAL; break; } } return ret; } static int hal_ser_imu_macro_conversion_gry_power_mode(SER_IMU_DIR_e dir, SER_IMU_GRY_POWER_MODE_e gry_power_mode) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(gry_power_mode) { case SER_IMU_GRY_POWER_MODE_HIGH_PERFORMANCE: ret = LSM_GRY_POWER_MODE_HIGH_PERFORMANCE; break; case SER_IMU_GRY_POWER_MODE_NORMAL: ret = LSM_GRY_POWER_MODE_NORMAL; break; } } return ret; } static int hal_ser_imu_macro_conversion_acc_fs(SER_IMU_DIR_e dir, SER_IMU_ACC_FS_e acc_fs) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(acc_fs) { case SER_IMU_ACC_FS_2G: ret = LSM_ACC_FS_2G; break; case SER_IMU_ACC_FS_16G: ret = LSM_ACC_FS_16G; break; } } return ret; } static int hal_ser_imu_macro_conversion_gry_fs(SER_IMU_DIR_e dir, SER_IMU_GRY_FS_e gry_fs) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(gry_fs) { case SER_IMU_GRY_FS_250DPS: ret = LSM_GRY_FS_250DPS; break; case SER_IMU_GRY_FS_2000DPS: ret = LSM_GRY_FS_2000DPS; break; } } return ret; } static int hal_ser_imu_macro_conversion_mag_fs(SER_IMU_DIR_e dir, SER_IMU_MAG_FS_e mag_fs) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(mag_fs) { case SER_IMU_MAG_FS_30GS: ret = LSM_MAG_FS_30GS; break; } } if(dir == SER_IMU_DIR_BACK) { switch(mag_fs) { case SER_IMU_MAG_FS_30GS: ret = QMC_MAG_FS_30GS; break; } } return ret; } static int hal_ser_imu_macro_conversion_timestamp_resolution(SER_IMU_DIR_e dir, SER_IMU_TIMESTAMP_RESOLUTION_e timestamp_resolution) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(timestamp_resolution) { case SER_IMU_TIMESTAMP_6MS4: ret = LSM_TIMESTAMP_6MS4; break; case SER_IMU_TIMESTAMP_25US: ret = LSM_TIMESTAMP_25US; break; } } return ret; } static int hal_ser_imu_macro_conversion_timestamp_switch(SER_IMU_DIR_e dir, SER_IMU_TIMESTAMP_SWITCH_e timestamp_switch) { int ret = 0; if(dir == SER_IMU_DIR_FRONT) { switch(timestamp_switch) { case SER_IMU_TIMESTAMP_OFF: ret = LSM_TIMESTAMP_OFF; break; case SER_IMU_TIMESTAMP_ON: ret = LSM_TIMESTAMP_ON; break; } } return ret; } static void hal_ser_imu_get_compre_param(ser_imu_config_param_t *compre_drv_param, ser_imu_config_param_t *op_param) { compre_drv_param->acc_fs = MAX(compre_drv_param->acc_fs, op_param->acc_fs); compre_drv_param->acc_odr = MAX(compre_drv_param->acc_odr, op_param->acc_odr); compre_drv_param->acc_power_mode = MAX(compre_drv_param->acc_power_mode, op_param->acc_power_mode); compre_drv_param->fifo_odr = MAX(compre_drv_param->fifo_odr, op_param->fifo_odr); compre_drv_param->gry_fs = MAX(compre_drv_param->gry_fs, op_param->gry_fs); compre_drv_param->gry_odr = MAX(compre_drv_param->gry_odr, op_param->gry_odr); compre_drv_param->gry_power_mode = MAX(compre_drv_param->gry_power_mode, op_param->gry_power_mode); compre_drv_param->mag_fs = MAX(compre_drv_param->mag_fs, op_param->mag_fs); compre_drv_param->mag_odr = MAX(compre_drv_param->mag_odr, op_param->mag_odr); compre_drv_param->timestamp_resolution = MAX(compre_drv_param->timestamp_resolution, op_param->timestamp_resolution); compre_drv_param->timestamp_switch = MAX(compre_drv_param->timestamp_switch, op_param->timestamp_switch); } static bool hal_ser_imu_param_is_equal_drv_param_lsm(ser_imu_config_param_t *compre_drv_param, drv_param_u *drv_param) { if(IS_EQUAL(hal_ser_imu_macro_conversion_acc_fs(SER_IMU_DIR_FRONT, compre_drv_param->acc_fs),drv_param->lsm.acc_fs) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_acc_odr(SER_IMU_DIR_FRONT, compre_drv_param->acc_odr),drv_param->lsm.acc_odr) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_acc_power_mode(SER_IMU_DIR_FRONT, compre_drv_param->acc_power_mode),drv_param->lsm.acc_power_mode) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_fifo_odr(SER_IMU_DIR_FRONT, compre_drv_param->fifo_odr),drv_param->lsm.fifo_odr) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_gry_fs(SER_IMU_DIR_FRONT, compre_drv_param->gry_fs),drv_param->lsm.gry_fs) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_gry_odr(SER_IMU_DIR_FRONT, compre_drv_param->gry_odr),drv_param->lsm.gry_odr) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_gry_power_mode(SER_IMU_DIR_FRONT, compre_drv_param->gry_power_mode),drv_param->lsm.gry_power_mode) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_mag_fs(SER_IMU_DIR_FRONT, compre_drv_param->mag_fs),drv_param->lsm.mag_fs) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_mag_odr(SER_IMU_DIR_FRONT, compre_drv_param->mag_odr),drv_param->lsm.mag_odr) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_timestamp_resolution(SER_IMU_DIR_FRONT, compre_drv_param->timestamp_resolution),drv_param->lsm.timestamp_resolution) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_timestamp_switch(SER_IMU_DIR_FRONT, compre_drv_param->timestamp_switch),drv_param->lsm.timestamp_switch) == false){return false;} return true; } static bool hal_ser_imu_param_is_equal_drv_param_qmc(ser_imu_config_param_t *compre_drv_param, drv_param_u *drv_param) { if(IS_EQUAL(hal_ser_imu_macro_conversion_mag_fs(SER_IMU_DIR_BACK, compre_drv_param->mag_fs), drv_param->qmc.mag_fs) == false){return false;} if(IS_EQUAL(hal_ser_imu_macro_conversion_mag_odr(SER_IMU_DIR_BACK, compre_drv_param->mag_odr), drv_param->qmc.mag_odr) == false){return false;} return true; } static bool hal_ser_imu_is_need_config(void) { int i; //重新获取综合的前脚配置,根据优先级来判定 memset(&ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT],0,sizeof(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT])); for(i=0; i\n"); SEGGER_RTT_printf(0,"stage:0x%x\r",ob_ser_imu.stage); SEGGER_RTT_printf(0,"is_need_config[SER_IMU_DIR_FRONT]:0x%x\n",ob_ser_imu.is_need_config[SER_IMU_DIR_FRONT]); SEGGER_RTT_printf(0,"is_need_config[SER_IMU_DIR_BACK]:0x%x\n",ob_ser_imu.is_need_config[SER_IMU_DIR_BACK]); // SEGGER_RTT_printf(0,"df acc_fs:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.acc_fs); SEGGER_RTT_printf(0,"df acc_odr:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.acc_odr); // SEGGER_RTT_printf(0,"df acc_power_mode:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.acc_power_mode); SEGGER_RTT_printf(0,"df fifo_odr:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.fifo_odr); // SEGGER_RTT_printf(0,"df gry_fs:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.gry_fs); SEGGER_RTT_printf(0,"df gry_odr:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.gry_odr); // SEGGER_RTT_printf(0,"df gry_power_mode:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.gry_power_mode); // SEGGER_RTT_printf(0,"df mag_fs:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.mag_fs); SEGGER_RTT_printf(0,"df mag_odr:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.mag_odr); // SEGGER_RTT_printf(0,"f timestamp_resolution:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.timestamp_resolution); // SEGGER_RTT_printf(0,"df timestamp_switch:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm.timestamp_switch); SEGGER_RTT_printf(0,"db mag_odr:0x%x\n",ob_ser_imu.drv_param[SER_IMU_DIR_BACK].qmc.mag_odr); // SEGGER_RTT_printf(0,"cf acc_fs:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_fs); SEGGER_RTT_printf(0,"cf acc_odr:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_odr); // SEGGER_RTT_printf(0,"cf acc_power_mode:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_power_mode); SEGGER_RTT_printf(0,"cf fifo_odr:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].fifo_odr); // SEGGER_RTT_printf(0,"cf gry_fs:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_fs); SEGGER_RTT_printf(0,"cf gry_odr:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_odr); // SEGGER_RTT_printf(0,"cf gry_power_mode:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_power_mode); // SEGGER_RTT_printf(0,"cf mag_fs:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_fs); SEGGER_RTT_printf(0,"cf mag_odr:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_odr); // SEGGER_RTT_printf(0,"cf timestamp_resolution:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_resolution); // SEGGER_RTT_printf(0,"cf timestamp_switch:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_switch); SEGGER_RTT_printf(0,"cb mag_odr:0x%x\n",ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_odr); SEGGER_RTT_printf(0,"ob_ser_imu.cur_data_num[SER_IMU_DIR_FRONT]:0x%x\n",ob_ser_imu.cur_data_num[SER_IMU_DIR_FRONT]); SEGGER_RTT_printf(0,"ob_ser_imu.cur_data_num[SER_IMU_DIR_BACK]:0x%x\n",ob_ser_imu.cur_data_num[SER_IMU_DIR_BACK]); SEGGER_RTT_printf(0,"<-----------------------------------------------------------------hal_ser_imu\n"); } /*API ------------------------------------------------------------------------------------------------------------------------------------*/ /** @brief 初始化IMU服务 @param 无 @return 错误代码 - [out] -1失败,0成功 */ int hal_ser_imu_Init(void) { int i; int ret; /***************************************驱动层初始化***************************************************/ //初始化驱动LSM ret = drv_lsm_Init(); if(ret == -1)return -1; //获取驱动LSM配置参数 drv_lsm_get_config_param(&ob_ser_imu.drv_param[SER_IMU_DIR_FRONT].lsm); //初始化驱动QMC ret = drv_qmc6310_Init(); if(ret == -1)return -1; //获取驱动LSM配置参数 drv_qmc6310_get_config_param(&ob_ser_imu.drv_param[SER_IMU_DIR_BACK].qmc); /***************************************业务逻辑层初始化***************************************************/ //重置结构体 memset(&ob_ser_imu,0,sizeof(ob_ser_imu)); //初始化IMU服务结构体 ob_ser_imu.stage = IMU_CONFIG_STAGE_DONE; for(i=0; iacc_fs){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_odr < param->acc_odr){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].acc_power_mode < param->acc_power_mode){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].fifo_odr < param->fifo_odr){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_fs < param->gry_fs){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_odr < param->gry_odr){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].gry_power_mode < param->gry_power_mode){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_fs < param->mag_fs){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].mag_odr < param->mag_odr){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_resolution < param->timestamp_resolution){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_FRONT].timestamp_switch < param->timestamp_switch){ret = -1;break;} break; case SER_IMU_DIR_BACK: if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_fs < param->mag_fs){ret = -1;break;} if(ob_ser_imu.compre_drv_param[SER_IMU_DIR_BACK].mag_odr < param->mag_odr){ret = -1;break;} break; default: break; } return ret; } /** @brief 获取IMU当前数据数量 @param dir - [in] IMU方向 - 前/后脚 @return 错误代码 - [out] 返回数据数量 */ int hal_ser_imu_get_data_num(SER_IMU_DIR_e dir) { int ret = 0; switch(dir) { case SER_IMU_DIR_FRONT: ret = ob_ser_imu.cur_data_num[SER_IMU_DIR_FRONT]; break; case SER_IMU_DIR_BACK: ret = ob_ser_imu.cur_data_num[SER_IMU_DIR_BACK]; break; default: break; } return ret; } /** @brief 获取IMU数据 @param dir - [in] IMU方向 - 前/后脚 @param index - [in] 第几组数据 @param pdata - [out] IMU数据 @return 错误代码 - [out] -1失败,0成功 */ int hal_ser_imu_get_data(SER_IMU_DIR_e dir, int index, ser_imu_data_t *pdata) { if(index < 0)return -1; *pdata = ob_ser_imu.cur_data[dir][index]; return 0; }