mirror of
https://gitee.com/dlmu-cone/tronone-h7-scaffold
synced 2026-07-24 03:27:45 +08:00
add new drv but not benefit stm32h723vg
This commit is contained in:
66
User_Code/bsp/gpio/bsp_gpio.c
Normal file
66
User_Code/bsp/gpio/bsp_gpio.c
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "bsp_gpio.h"
|
||||
#include "memory.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
static uint8_t idx;
|
||||
static GPIOInstance *gpio_instance[GPIO_MX_DEVICE_NUM] = {NULL};
|
||||
|
||||
/**
|
||||
* @brief EXTI中断回调函数,根据GPIO_Pin找到对应的GPIOInstance,并调用模块回调函数(如果有)
|
||||
* @note 如何判断具体是哪一个GPIO的引脚连接到这个EXTI中断线上?
|
||||
* 一个EXTI中断线只能连接一个GPIO引脚,因此可以通过GPIO_Pin来判断,PinX对应EXTIX
|
||||
* 一个Pin号只会对应一个EXTI,详情见gpio.md
|
||||
* @param GPIO_Pin 发生中断的GPIO_Pin
|
||||
*/
|
||||
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
||||
{
|
||||
// 如有必要,可以根据pinstate和HAL_GPIO_ReadPin来判断是上升沿还是下降沿/rise&fall等
|
||||
GPIOInstance *gpio;
|
||||
for (size_t i = 0; i < idx; i++)
|
||||
{
|
||||
gpio = gpio_instance[i];
|
||||
if (gpio->GPIO_Pin == GPIO_Pin && gpio->gpio_model_callback != NULL)
|
||||
{
|
||||
gpio->gpio_model_callback(gpio);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GPIOInstance *GPIORegister(GPIO_Init_Config_s *GPIO_config)
|
||||
{
|
||||
GPIOInstance *ins = (GPIOInstance *) malloc(sizeof(GPIOInstance));
|
||||
memset(ins, 0, sizeof(GPIOInstance));
|
||||
|
||||
ins->GPIOx = GPIO_config->GPIOx;
|
||||
ins->GPIO_Pin = GPIO_config->GPIO_Pin;
|
||||
ins->pin_state = GPIO_config->pin_state;
|
||||
ins->exti_mode = GPIO_config->exti_mode;
|
||||
ins->id = GPIO_config->id;
|
||||
ins->gpio_model_callback = GPIO_config->gpio_model_callback;
|
||||
gpio_instance[idx++] = ins;
|
||||
return ins;
|
||||
}
|
||||
|
||||
// ----------------- GPIO API -----------------
|
||||
// 都是对HAL的形式上的封装,后续考虑增加GPIO state变量,可以直接读取state
|
||||
|
||||
void GPIOToggel(GPIOInstance *_instance)
|
||||
{
|
||||
HAL_GPIO_TogglePin(_instance->GPIOx, _instance->GPIO_Pin);
|
||||
}
|
||||
|
||||
void GPIOSet(GPIOInstance *_instance)
|
||||
{
|
||||
HAL_GPIO_WritePin(_instance->GPIOx, _instance->GPIO_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void GPIOReset(GPIOInstance *_instance)
|
||||
{
|
||||
HAL_GPIO_WritePin(_instance->GPIOx, _instance->GPIO_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
GPIO_PinState GPIORead(GPIOInstance *_instance)
|
||||
{
|
||||
return HAL_GPIO_ReadPin(_instance->GPIOx, _instance->GPIO_Pin);
|
||||
}
|
||||
87
User_Code/bsp/gpio/bsp_gpio.h
Normal file
87
User_Code/bsp/gpio/bsp_gpio.h
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "gpio.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#define GPIO_MX_DEVICE_NUM 10
|
||||
|
||||
/**
|
||||
* @brief 用于判断中断来源,注意和CUBEMX中配置一致
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GPIO_EXTI_MODE_RISING,
|
||||
GPIO_EXTI_MODE_FALLING,
|
||||
GPIO_EXTI_MODE_RISING_FALLING,
|
||||
GPIO_EXTI_MODE_NONE,
|
||||
} GPIO_EXTI_MODE_e;
|
||||
|
||||
/**
|
||||
* @brief GPIO实例结构体定义
|
||||
*
|
||||
*/
|
||||
typedef struct tmpgpio
|
||||
{
|
||||
GPIO_TypeDef *GPIOx; // GPIOA,GPIOB,GPIOC...
|
||||
GPIO_PinState pin_state; // 引脚状态,Set,Reset;not frequently used
|
||||
GPIO_EXTI_MODE_e exti_mode; // 外部中断模式 not frequently used
|
||||
uint16_t GPIO_Pin; // 引脚号,
|
||||
// 这些引脚是stm32f4xx_hal_gpio.h中定义的宏!!! 一定要注意
|
||||
// 随便取个名字当临时声明
|
||||
void (*gpio_model_callback)(struct tmpgpio *); // exti中断回调函数
|
||||
void *id; // 区分不同的GPIO实例
|
||||
|
||||
} GPIOInstance;
|
||||
|
||||
/**
|
||||
* @brief GPIO初始化配置结构体定义
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
GPIO_TypeDef *GPIOx; // GPIOA,GPIOB,GPIOC...
|
||||
GPIO_PinState pin_state; // 引脚状态,Set,Reset not frequently used
|
||||
GPIO_EXTI_MODE_e exti_mode; // 外部中断模式 not frequently used
|
||||
uint16_t GPIO_Pin; // 引脚号,@note 这里的引脚号是GPIO_PIN_0,GPIO_PIN_1...
|
||||
// 这些引脚是stm32f4xx_hal_gpio.h中定义的宏!!! 一定要注意
|
||||
|
||||
void (*gpio_model_callback)(GPIOInstance *); // exti中断回调函数
|
||||
void *id; // 区分不同的GPIO实例
|
||||
|
||||
} GPIO_Init_Config_s;
|
||||
|
||||
/**
|
||||
* @brief 注册GPIO实例
|
||||
*
|
||||
* @param GPIO_config
|
||||
* @return GPIOInstance*
|
||||
*/
|
||||
GPIOInstance *GPIORegister(GPIO_Init_Config_s *GPIO_config);
|
||||
|
||||
/**
|
||||
* @brief GPIO API,切换GPIO电平
|
||||
*
|
||||
* @param _instance
|
||||
*/
|
||||
void GPIOToggel(GPIOInstance *_instance);
|
||||
|
||||
/**
|
||||
* @brief 设置GPIO电平
|
||||
*
|
||||
* @param _instance
|
||||
*/
|
||||
void GPIOSet(GPIOInstance *_instance);
|
||||
|
||||
/**
|
||||
* @brief 复位GPIO电平
|
||||
*
|
||||
* @param _instance
|
||||
*/
|
||||
void GPIOReset(GPIOInstance *_instance);
|
||||
|
||||
/**
|
||||
* @brief 读取GPIO电平
|
||||
*
|
||||
* @param _instance
|
||||
* @return GPIO_PinState
|
||||
*/
|
||||
GPIO_PinState GPIORead(GPIOInstance *_instance);
|
||||
18
User_Code/bsp/gpio/bsp_gpio.md
Normal file
18
User_Code/bsp/gpio/bsp_gpio.md
Normal file
@@ -0,0 +1,18 @@
|
||||
可以作为io接口,也可以处理外部中断.
|
||||
|
||||
使用示例
|
||||
|
||||
```c
|
||||
//在app层只需要设置前三个,callback由module自动设置
|
||||
|
||||
GPIO_Init_Config_s gpio_init = {
|
||||
.exti_mode = GPIO_EXTI_MODE_FALLING, // 注意和CUBEMX的配置一致
|
||||
.GPIO_Pin = GPIO_PIN_6, // GPIO引脚
|
||||
.GPIOx = GPIOG, // GPIO外设
|
||||
.gpio_model_callback = NULL, // EXTI回调函数
|
||||
},
|
||||
|
||||
GPIOInstance* test_example = GPIORegister(&gpio_init);
|
||||
GPIOSet(test_example);
|
||||
// GPIOxxx(test_exmaple, ...);
|
||||
```
|
||||
113
User_Code/bsp/pwm/bsp_pwm.c
Normal file
113
User_Code/bsp/pwm/bsp_pwm.c
Normal file
@@ -0,0 +1,113 @@
|
||||
// #include "bsp_pwm.h"
|
||||
// #include "stdlib.h"
|
||||
// #include "memory.h"
|
||||
//
|
||||
// // 配合中断以及初始化
|
||||
// static uint8_t idx;
|
||||
// static PWMInstance *pwm_instance[PWM_DEVICE_CNT] = {NULL}; // 所有的pwm instance保存于此,用于callback时判断中断来源
|
||||
// static uint32_t PWMSelectTclk(TIM_HandleTypeDef *htim);
|
||||
//
|
||||
// /**
|
||||
// * @brief pwm dma传输完成回调函数
|
||||
// *
|
||||
// * @param htim 发生中断的定时器句柄
|
||||
// */
|
||||
// void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
|
||||
// {
|
||||
// for (uint8_t i = 0; i < idx; i++)
|
||||
// {
|
||||
// // 来自同一个定时器的中断且通道相同
|
||||
// if (pwm_instance[i]->htim == htim && htim->Channel == (1 << (pwm_instance[i]->channel / 4)))
|
||||
// {
|
||||
// if (pwm_instance[i]->callback) // 如果有回调函数
|
||||
// pwm_instance[i]->callback(pwm_instance[i]);
|
||||
// return; // 一次只能有一个通道的中断,所以直接返回
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// PWMInstance *PWMRegister(PWM_Init_Config_s *config)
|
||||
// {
|
||||
// if (idx >= PWM_DEVICE_CNT) // 超过最大实例数,考虑增加或查看是否有内存泄漏
|
||||
// while (1);
|
||||
// PWMInstance *pwm = (PWMInstance *) malloc(sizeof(PWMInstance));
|
||||
// memset(pwm, 0, sizeof(PWMInstance));
|
||||
//
|
||||
// pwm->htim = config->htim;
|
||||
// pwm->channel = config->channel;
|
||||
// pwm->period = config->period;
|
||||
// pwm->dutyratio = config->dutyratio;
|
||||
// pwm->callback = config->callback;
|
||||
// pwm->id = config->id;
|
||||
// pwm->tclk = PWMSelectTclk(pwm->htim);
|
||||
// // 启动PWM
|
||||
// HAL_TIM_PWM_Start(pwm->htim, pwm->channel);
|
||||
// PWMSetPeriod(pwm, pwm->period);
|
||||
// PWMSetDutyRatio(pwm, pwm->dutyratio);
|
||||
// pwm_instance[idx++] = pwm;
|
||||
// return pwm;
|
||||
// }
|
||||
//
|
||||
// /* 只是对HAL的函数进行了形式上的封装 */
|
||||
// void PWMStart(PWMInstance *pwm)
|
||||
// {
|
||||
// HAL_TIM_PWM_Start(pwm->htim, pwm->channel);
|
||||
// }
|
||||
//
|
||||
// /* 只是对HAL的函数进行了形式上的封装 */
|
||||
// void PWMStop(PWMInstance *pwm)
|
||||
// {
|
||||
// HAL_TIM_PWM_Stop(pwm->htim, pwm->channel);
|
||||
// }
|
||||
//
|
||||
// /*
|
||||
// * @brief 设置pwm周期
|
||||
// *
|
||||
// * @param pwm pwm实例
|
||||
// * @param period 周期 单位 s
|
||||
// */
|
||||
// void PWMSetPeriod(PWMInstance *pwm, float period)
|
||||
// {
|
||||
// __HAL_TIM_SetAutoreload(pwm->htim, period * ((pwm->tclk) / (pwm->htim->Init.Prescaler + 1)));
|
||||
// }
|
||||
//
|
||||
// /*
|
||||
// * @brief 设置pwm占空比
|
||||
// *
|
||||
// * @param pwm pwm实例
|
||||
// * @param dutyratio 占空比 0~1
|
||||
// */
|
||||
// void PWMSetDutyRatio(PWMInstance *pwm, float dutyratio)
|
||||
// {
|
||||
// __HAL_TIM_SetCompare(pwm->htim, pwm->channel, dutyratio * (pwm->htim->Instance->ARR));
|
||||
// }
|
||||
//
|
||||
// /* 只是对HAL的函数进行了形式上的封装 */
|
||||
// void PWMStartDMA(PWMInstance *pwm, uint32_t *pData, uint32_t Size)
|
||||
// {
|
||||
// HAL_TIM_PWM_Start_DMA(pwm->htim, pwm->channel, pData, Size);
|
||||
// }
|
||||
//
|
||||
// // 设置pwm对应定时器时钟源频率
|
||||
// //tim2~7,12~14:APB1 tim1,8~11:APB2
|
||||
// static uint32_t PWMSelectTclk(TIM_HandleTypeDef *htim)
|
||||
// {
|
||||
// uintptr_t tclk_temp = ((uintptr_t) ((htim)->Instance));
|
||||
// if (
|
||||
// (tclk_temp <= (APB1PERIPH_BASE + 0x2000UL)) &&
|
||||
// (tclk_temp >= (APB1PERIPH_BASE + 0x0000UL)))
|
||||
// {
|
||||
// return (HAL_RCC_GetPCLK1Freq() * (
|
||||
// APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] == 0 ? 1 : 2));
|
||||
// }
|
||||
// if (
|
||||
// ((tclk_temp <= (APB2PERIPH_BASE + 0x0400UL)) &&
|
||||
// (tclk_temp >= (APB2PERIPH_BASE + 0x0000UL))) ||
|
||||
// ((tclk_temp <= (APB2PERIPH_BASE + 0x4800UL)) &&
|
||||
// (tclk_temp >= (APB2PERIPH_BASE + 0x4000UL))))
|
||||
// {
|
||||
// return (HAL_RCC_GetPCLK2Freq() * (
|
||||
// APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] == 0 ? 1 : 2));
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
93
User_Code/bsp/pwm/bsp_pwm.h
Normal file
93
User_Code/bsp/pwm/bsp_pwm.h
Normal file
@@ -0,0 +1,93 @@
|
||||
// /**
|
||||
// * @file bsp_pwm.h
|
||||
// * @author TuxMonkey
|
||||
// * @brief
|
||||
// * @version 0.1
|
||||
// * @date 2023-02-14
|
||||
// *
|
||||
// * @copyright Copyright (c) 2023
|
||||
// *
|
||||
// */
|
||||
//
|
||||
// #ifndef BSP_PWM_H
|
||||
// #define BSP_PWM_H
|
||||
//
|
||||
// #include "tim.h"
|
||||
// #include "stdint.h"
|
||||
// #include "stm32h7xx_hal_rcc.h"
|
||||
// #include "stm32h723xx.h"
|
||||
// #define PWM_DEVICE_CNT 16 // 最大支持的PWM实例数量
|
||||
//
|
||||
// /* pwm实例结构体 */
|
||||
// typedef struct pwm_ins_temp
|
||||
// {
|
||||
// TIM_HandleTypeDef *htim; // TIM句柄
|
||||
// uint32_t channel; // 通道
|
||||
// uint32_t tclk; // 时钟频率
|
||||
// float period; // 周期
|
||||
// float dutyratio; // 占空比
|
||||
// void (*callback)(struct pwm_ins_temp *); // DMA传输完成回调函数
|
||||
// void *id; // 实例ID
|
||||
// } PWMInstance;
|
||||
//
|
||||
// typedef struct
|
||||
// {
|
||||
// TIM_HandleTypeDef *htim; // TIM句柄
|
||||
// uint32_t channel; // 通道
|
||||
// float period; // 周期
|
||||
// float dutyratio; // 占空比
|
||||
// void (*callback)(PWMInstance *); // DMA传输完成回调函数
|
||||
// void *id; // 实例ID
|
||||
// } PWM_Init_Config_s;
|
||||
//
|
||||
// /**
|
||||
// * @brief 注册一个pwm实例
|
||||
// *
|
||||
// * @param config 初始化配置
|
||||
// * @return PWMInstance*
|
||||
// */
|
||||
// PWMInstance *PWMRegister(PWM_Init_Config_s *config);
|
||||
//
|
||||
// /**
|
||||
// * @brief 启动pwm
|
||||
// *
|
||||
// * @param pwm pwm实例
|
||||
// */
|
||||
// void PWMStart(PWMInstance *pwm);
|
||||
//
|
||||
// /**
|
||||
// * @brief 设置pwm占空比
|
||||
// *
|
||||
// * @param pwm pwm实例
|
||||
// * @param dutyratio 占空比 0~1
|
||||
// */
|
||||
//
|
||||
// void PWMSetDutyRatio(PWMInstance *pwm, float dutyratio);
|
||||
//
|
||||
// /**
|
||||
// * @brief 停止pwm
|
||||
// *
|
||||
// * @param pwm pwm实例
|
||||
// */
|
||||
// void PWMStop(PWMInstance *pwm);
|
||||
//
|
||||
// /**
|
||||
// * @brief 设置pwm周期
|
||||
// *
|
||||
// * @param pwm pwm实例
|
||||
// * @param period 周期 单位 s
|
||||
// */
|
||||
// void PWMSetPeriod(PWMInstance *pwm, float period);
|
||||
//
|
||||
// /**
|
||||
// * @brief 启动pwm dma传输
|
||||
// *
|
||||
// * @param pwm pwm实例
|
||||
// * @param pData 数据首地址指针,注意数据的位数必须和CubeMX配置的DMA传输位数(字长)一致
|
||||
// * @param Size 数据长度
|
||||
// * @note 如果使用此函数,则需要在CubeMX中配置DMA传输位数为对应位数
|
||||
// * 例如:使用16位数据,则需要配置DMA传输位数为16位(half word),配置错误会导致指针越界或数据错误
|
||||
// */
|
||||
// void PWMStartDMA(PWMInstance *pwm, uint32_t *pData, uint32_t Size);
|
||||
//
|
||||
// #endif // BSP_PWM_H
|
||||
7
User_Code/bsp/pwm/bsp_pwm.md
Normal file
7
User_Code/bsp/pwm/bsp_pwm.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# bsp pwm
|
||||
|
||||
> 暂未适配H723
|
||||
|
||||
同一定时器下的pwm通道更改周期时请注意该定时器下是否有其他pwm示例,如果有请注意不要影响其他pwm通道的周期。
|
||||
使用pwm dma传输中断时注意占空比的设置,设为0将不会进入中断函数
|
||||
默认tim psc已在cubemx设置好,详情可参考cubemx配置文件
|
||||
@@ -0,0 +1,101 @@
|
||||
# BMI088
|
||||
|
||||
> 新驱动 暂未适配H723
|
||||
|
||||
## 示例
|
||||
|
||||
```c
|
||||
BMI088_Init_Config_s imu_config = {
|
||||
.spi_acc_config={
|
||||
.GPIOx=GPIOA,
|
||||
.GPIOx=GPIO_PIN_4,
|
||||
.spi_handle=&hspi1,
|
||||
},
|
||||
.spi_gyro_config={
|
||||
.GPIOx=GPIOB,
|
||||
.GPIOx=GPIO_PIN_0,
|
||||
.spi_handle=&hspi1,
|
||||
},
|
||||
.acc_int_config={
|
||||
.exti_mode=EXTI_TRIGGER_FALLING,
|
||||
.GPIO_Pin=GPIO_PIN_4,
|
||||
.GPIOx=GPIOC,
|
||||
},
|
||||
.gyro_int_config={
|
||||
.exti_mode=EXTI_TRIGGER_FALLING,
|
||||
.GPIO_Pin=GPIO_PIN_5,
|
||||
.GPIOx=GPIOC,
|
||||
},
|
||||
.heat_pid_config={
|
||||
.Kp=0.0f,
|
||||
.Kd=0.0f,
|
||||
.Ki=0.0f,
|
||||
.MaxOut=0.0f,
|
||||
.DeadBand=0.0f,
|
||||
},
|
||||
.heat_pwm_config={
|
||||
.channel=TIM_CHANNEL_1,
|
||||
.htim=&htim1,
|
||||
},
|
||||
.cali_mode=BMI088_CALIBRATE_ONLINE_MODE,
|
||||
.work_mode=BMI088_BLOCK_PERIODIC_MODE,
|
||||
};
|
||||
|
||||
BMI088Instance* imu=BMI088Register(&imu_config);
|
||||
```
|
||||
|
||||
## IT非阻塞模式下BMI088读取流程
|
||||
|
||||
数据准备完成标志位:`uint8_t BMI088_READY_FLAG` 总共8个位 也可以用位域可读性更高
|
||||
|
||||
1. 当accel int中断发生,开启DMA SPI传输,完成后将acc ready置位
|
||||
2. 当gyro int中断发生,开启DMA SPI传输,完成后将gyro ready置位
|
||||
3. 当温度数据中断(温度传感器在accel内部,也是accel int)发生,开启DMA传输,完成后将温度标志位置位
|
||||
|
||||
> 由于DMA传输非阻塞,启动传输后只有到传输完成时才会拉高片选结束SPI transfer,因此需要在callback中加入标志位置位的操作.
|
||||
> 这可以通过条件编译完成.
|
||||
|
||||
温度数据不需要和accel和gyro同步,它不参与姿态解算,可以不用管.
|
||||
|
||||
当加速度数据和陀螺仪数据都准备完成之后,唤醒姿态解算任务INs_taSk,进行一次解算.唤醒可以通过软件开启EXTI中断,在中断中调用实时系统的vTaskNotifyFromISR()
|
||||
完成,也可以将任务ready标志位置位,当运行到对应位置时检查标志位判断是否要进行任务.时间间隔不是大问题,inS_TAsK中有dwt用于计算两次任务执行的间隔,它将会自动处理好bias的大小
|
||||
|
||||
`__HAL_GPIO_EXTI_GENERATE_SWIT()` `HAL_EXTI_GENERATE_SWI()` 可以触发软件中断
|
||||
|
||||
of course,两者的数据更新实际上可以异步进行,这里为了方便起见当两者数据都准备好以后再行融合
|
||||
|
||||
## 数据读写规则(so called 16-bit protocol)
|
||||
|
||||
加速度计读取read:
|
||||
|
||||
1. bit 0 :1 bit 1-7: reg address
|
||||
2. dummy read,加速度计此时返回的数据无效
|
||||
3. 真正的数据从第三个字节开始.
|
||||
|
||||
通过SPI传输三个字节(分三次)
|
||||
byte1: 1(读)+7位寄存器地址
|
||||
byte2: 没用
|
||||
byte3: 读取到的数据
|
||||
|
||||
write写入:
|
||||
|
||||
1. bit 0: 0 bit1-7: reg address
|
||||
2. 要写入寄存器的数据(注意没有dummy byte)
|
||||
|
||||
---
|
||||
|
||||
**注意,陀螺仪和加速度计的读取不同**
|
||||
|
||||
陀螺仪gyro读取read:
|
||||
|
||||
1. bit 0 :1 bit1-7: reg address
|
||||
2. 读回的数据
|
||||
|
||||
通过SPI传输两个字节(分两次)
|
||||
byte1: 1(读)+7位寄存器地址
|
||||
byte2: 读取到的数据
|
||||
|
||||
write写入:
|
||||
|
||||
1. bit0 : 0 bit1-7 : reg address
|
||||
2. 写入的数据
|
||||
454
User_Code/module/periph/imu/BMI088(newer_support)/bmi088.c
Normal file
454
User_Code/module/periph/imu/BMI088(newer_support)/bmi088.c
Normal file
@@ -0,0 +1,454 @@
|
||||
// #include "bmi088_regNdef.h"
|
||||
// #include "bmi088.h"
|
||||
// #include "user_lib.h"
|
||||
//
|
||||
// // ---------------------------以下私有函数,用于读写BMI088寄存器封装,blocking--------------------------------//
|
||||
// /**
|
||||
// * @brief 读取BMI088寄存器Accel. BMI088要求在不释放CS的情况下连续读取
|
||||
// *
|
||||
// * @param bmi088 待读取的BMI088实例
|
||||
// * @param reg 待读取的寄存器地址
|
||||
// * @param dataptr 读取到的数据存放的指针
|
||||
// * @param len 读取长度
|
||||
// */
|
||||
// static void BMI088AccelRead(BMI088Instance *bmi088, uint8_t reg, uint8_t *dataptr, uint8_t len)
|
||||
// {
|
||||
// if (len > 6)
|
||||
// while (1);
|
||||
// // 一次读取最多6个字节,加上两个dummy data 第一个字节的第一个位是读写位,1为读,0为写,1-7bit是寄存器地址
|
||||
// static uint8_t tx[8]; // 读取,第一个字节为0x80|reg ,第二个是dummy data,后面的没用都是dummy write
|
||||
// static uint8_t rx[8]; // 前两个字节是dummy data,第三个开始是真正的数据
|
||||
// tx[0] = 0x80 | reg; // 静态变量每次进来还是上次的值,所以要每次都要给tx[0]赋值0x80
|
||||
// SPITransRecv(bmi088->spi_acc, rx, tx, len + 2);
|
||||
// memcpy(dataptr, rx + 2, len); // @todo : memcpy有额外开销,后续可以考虑优化,在SPI中加入接口或模式,使得在一次传输结束后不释放CS,直接接着传输
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @brief 读取BMI088寄存器Gyro, BMI088要求在不释放CS的情况下连续读取
|
||||
// *
|
||||
// * @param bmi088 待读取的BMI088实例
|
||||
// * @param reg 待读取的寄存器地址
|
||||
// * @param dataptr 读取到的数据存放的指针
|
||||
// * @param len 读取长度
|
||||
// */
|
||||
// static void BMI088GyroRead(BMI088Instance *bmi088, uint8_t reg, uint8_t *dataptr, uint8_t len)
|
||||
// {
|
||||
// if (len > 6)
|
||||
// while (1);
|
||||
// // 一次读取最多6个字节,加上一个dummy data ,第一个字节的第一个位是读写位,1为读,0为写,1-7bit是寄存器地址
|
||||
// static uint8_t tx[7] = {0x80}; // 读取,第一个字节为0x80 | reg ,之后是dummy data
|
||||
// static uint8_t rx[7]; // 第一个是dummy data,第三个开始是真正的数据
|
||||
// tx[0] = 0x80 | reg;
|
||||
// SPITransRecv(bmi088->spi_gyro, rx, tx, len + 1);
|
||||
// memcpy(dataptr, rx + 1, len); // @todo : memcpy有额外开销,后续可以考虑优化,在SPI中加入接口或模式,使得在一次传输结束后不释放CS,直接接着传输
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @brief 写accel寄存器.对spitransmit形式上的封装
|
||||
// * @attention 只会向目标reg写入一个字节,因为只有1个字节所以直接传值(指针是32位反而浪费)
|
||||
// *
|
||||
// * @param bmi088 待写入的BMI088实例
|
||||
// * @param reg 待写入的寄存器地址
|
||||
// * @param data 待写入的数据(注意不是指针)
|
||||
// */
|
||||
// static void BMI088AccelWriteSingleReg(BMI088Instance *bmi088, uint8_t reg, uint8_t data)
|
||||
// {
|
||||
// uint8_t tx[2] = {reg, data};
|
||||
// SPITransmit(bmi088->spi_acc, tx, 2);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @brief 写gyro寄存器.形式上的封装
|
||||
// * @attention 只会向目标reg写入一个字节,因为只有1个字节所以直接传值(指针是32位反而浪费)
|
||||
// *
|
||||
// * @param bmi088 待写入的BMI088实例
|
||||
// * @param reg 待写入的寄存器地址
|
||||
// * @param data 待写入的数据(注意不是指针)
|
||||
// */
|
||||
// static void BMI088GyroWriteSingleReg(BMI088Instance *bmi088, uint8_t reg, uint8_t data)
|
||||
// {
|
||||
// uint8_t tx[2] = {reg, data};
|
||||
// SPITransmit(bmi088->spi_gyro, tx, 2);
|
||||
// }
|
||||
//
|
||||
// // -------------------------以上为私有函数,封装了BMI088寄存器读写函数,blocking--------------------------------//
|
||||
//
|
||||
// // -------------------------以下为私有函数,用于初始化BMI088acc和gyro的硬件和配置--------------------------------//
|
||||
// #define BMI088REG 0
|
||||
// #define BMI088DATA 1
|
||||
// #define BMI088ERROR 2
|
||||
// // BMI088初始化配置数组for accel,第一列为reg地址,第二列为写入的配置值,第三列为错误码(如果出错)
|
||||
// static uint8_t BMI088_Accel_Init_Table[BMI088_WRITE_ACCEL_REG_NUM][3] =
|
||||
// {
|
||||
// {BMI088_ACC_PWR_CTRL, BMI088_ACC_ENABLE_ACC_ON, BMI088_ACC_PWR_CTRL_ERROR},
|
||||
// {BMI088_ACC_PWR_CONF, BMI088_ACC_PWR_ACTIVE_MODE, BMI088_ACC_PWR_CONF_ERROR},
|
||||
// {BMI088_ACC_CONF, BMI088_ACC_NORMAL | BMI088_ACC_800_HZ | BMI088_ACC_CONF_MUST_Set, BMI088_ACC_CONF_ERROR},
|
||||
// {BMI088_ACC_RANGE, BMI088_ACC_RANGE_6G, BMI088_ACC_RANGE_ERROR},
|
||||
// {BMI088_INT1_IO_CTRL, BMI088_ACC_INT1_IO_ENABLE | BMI088_ACC_INT1_GPIO_PP | BMI088_ACC_INT1_GPIO_LOW,
|
||||
// BMI088_INT1_IO_CTRL_ERROR},
|
||||
// {BMI088_INT_MAP_DATA, BMI088_ACC_INT1_DRDY_INTERRUPT, BMI088_INT_MAP_DATA_ERROR}};
|
||||
// // BMI088初始化配置数组for gyro,第一列为reg地址,第二列为写入的配置值,第三列为错误码(如果出错)
|
||||
// static uint8_t BMI088_Gyro_Init_Table[BMI088_WRITE_GYRO_REG_NUM][3] =
|
||||
// {
|
||||
// {BMI088_GYRO_RANGE, BMI088_GYRO_2000, BMI088_GYRO_RANGE_ERROR},
|
||||
// {BMI088_GYRO_BANDWIDTH, BMI088_GYRO_2000_230_HZ | BMI088_GYRO_BANDWIDTH_MUST_Set, BMI088_GYRO_BANDWIDTH_ERROR},
|
||||
// {BMI088_GYRO_LPM1, BMI088_GYRO_NORMAL_MODE, BMI088_GYRO_LPM1_ERROR},
|
||||
// {BMI088_GYRO_CTRL, BMI088_DRDY_ON, BMI088_GYRO_CTRL_ERROR},
|
||||
// {BMI088_GYRO_INT3_INT4_IO_CONF, BMI088_GYRO_INT3_GPIO_PP | BMI088_GYRO_INT3_GPIO_LOW,
|
||||
// BMI088_GYRO_INT3_INT4_IO_CONF_ERROR},
|
||||
// {BMI088_GYRO_INT3_INT4_IO_MAP, BMI088_GYRO_DRDY_IO_INT3, BMI088_GYRO_INT3_INT4_IO_MAP_ERROR}};
|
||||
// // @attention : 以上两个数组配合各自的初始化函数使用. 若要修改请参照BMI088 datasheet
|
||||
//
|
||||
// /**
|
||||
// * @brief 初始化BMI088加速度计,提高可读性分拆功能
|
||||
// *
|
||||
// * @param bmi088 待初始化的BMI088实例
|
||||
// * @return uint8_t BMI088ERROR CODE if any problems here
|
||||
// */
|
||||
// static uint8_t BMI088AccelInit(BMI088Instance *bmi088)
|
||||
// {
|
||||
// uint8_t whoami_check = 0;
|
||||
//
|
||||
// // 加速度计以I2C模式启动,需要一次上升沿来切换到SPI模式,因此进行一次fake write
|
||||
// BMI088AccelRead(bmi088, BMI088_ACC_CHIP_ID, &whoami_check, 1);
|
||||
// DWT_Delay(0.001);
|
||||
//
|
||||
// BMI088AccelWriteSingleReg(bmi088, BMI088_ACC_SOFTRESET, BMI088_ACC_SOFTRESET_VALUE); // 软复位
|
||||
// DWT_Delay(BMI088_COM_WAIT_SENSOR_TIME / 1000);
|
||||
//
|
||||
// // 检查ID,如果不是0x1E(bmi088 whoami寄存器值),则返回错误
|
||||
// BMI088AccelRead(bmi088, BMI088_ACC_CHIP_ID, &whoami_check, 1);
|
||||
// if (whoami_check != BMI088_ACC_CHIP_ID_VALUE)
|
||||
// return BMI088_NO_SENSOR;
|
||||
// DWT_Delay(0.001);
|
||||
// // 初始化寄存器,提高可读性
|
||||
// uint8_t reg = 0, data = 0;
|
||||
// BMI088_ERORR_CODE_e error = 0;
|
||||
// // 使用sizeof而不是magic number,这样如果修改了数组大小,不用修改这里的代码;或者使用宏定义
|
||||
// for (uint8_t i = 0; i < sizeof(BMI088_Accel_Init_Table) / sizeof(BMI088_Accel_Init_Table[0]); i++)
|
||||
// {
|
||||
// reg = BMI088_Accel_Init_Table[i][BMI088REG];
|
||||
// data = BMI088_Accel_Init_Table[i][BMI088DATA];
|
||||
// BMI088AccelWriteSingleReg(bmi088, reg, data); // 写入寄存器
|
||||
// DWT_Delay(0.01);
|
||||
// BMI088AccelRead(bmi088, reg, &data, 1); // 写完之后立刻读回检查
|
||||
// DWT_Delay(0.01);
|
||||
// if (data != BMI088_Accel_Init_Table[i][BMI088DATA])
|
||||
// error |= BMI088_Accel_Init_Table[i][BMI088ERROR];
|
||||
// //{i--;} 可以设置retry次数,如果retry次数用完了,则返回error
|
||||
// }
|
||||
// return error;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @brief 初始化BMI088陀螺仪,提高可读性分拆功能
|
||||
// *
|
||||
// * @param bmi088 待初始化的BMI088实例
|
||||
// * @return uint8_t BMI088ERROR CODE
|
||||
// */
|
||||
// static uint8_t BMI088GyroInit(BMI088Instance *bmi088)
|
||||
// {
|
||||
// // 后续添加reset和通信检查?
|
||||
// // code to go here ...
|
||||
// BMI088GyroWriteSingleReg(bmi088, BMI088_GYRO_SOFTRESET, BMI088_GYRO_SOFTRESET_VALUE); // 软复位
|
||||
// DWT_Delay(0.08);
|
||||
//
|
||||
// // 检查ID,如果不是0x0F(bmi088 whoami寄存器值),则返回错误
|
||||
// uint8_t whoami_check = 0;
|
||||
// BMI088GyroRead(bmi088, BMI088_GYRO_CHIP_ID, &whoami_check, 1);
|
||||
// if (whoami_check != BMI088_GYRO_CHIP_ID_VALUE)
|
||||
// return BMI088_NO_SENSOR;
|
||||
// DWT_Delay(0.001);
|
||||
//
|
||||
// // 初始化寄存器,提高可读性
|
||||
// uint8_t reg = 0, data = 0;
|
||||
// BMI088_ERORR_CODE_e error = 0;
|
||||
// // 使用sizeof而不是magic number,这样如果修改了数组大小,不用修改这里的代码;或者使用宏定义
|
||||
// for (uint8_t i = 0; i < sizeof(BMI088_Gyro_Init_Table) / sizeof(BMI088_Gyro_Init_Table[0]); i++)
|
||||
// {
|
||||
// reg = BMI088_Gyro_Init_Table[i][BMI088REG];
|
||||
// data = BMI088_Gyro_Init_Table[i][BMI088DATA];
|
||||
// BMI088GyroWriteSingleReg(bmi088, reg, data); // 写入寄存器
|
||||
// DWT_Delay(0.001);
|
||||
// BMI088GyroRead(bmi088, reg, &data, 1); // 写完之后立刻读回对应寄存器检查是否写入成功
|
||||
// DWT_Delay(0.001);
|
||||
// if (data != BMI088_Gyro_Init_Table[i][BMI088DATA])
|
||||
// error |= BMI088_Gyro_Init_Table[i][BMI088ERROR];
|
||||
// //{i--;} 可以设置retry次数,尝试重新写入.如果retry次数用完了,则返回error
|
||||
// }
|
||||
//
|
||||
// return error;
|
||||
// }
|
||||
//
|
||||
// // -------------------------以上为私有函数,用于初始化BMI088acc和gyro的硬件和配置--------------------------------//
|
||||
//
|
||||
// // -------------------------以下为私有函数,private用于IT模式下的中断处理---------------------------------//
|
||||
//
|
||||
// /**
|
||||
// * @brief 待编写,很快!
|
||||
// *
|
||||
// */
|
||||
// static void BMI088AccSPIFinishCallback(SPIInstance *spi)
|
||||
// {
|
||||
// // static BMI088Instance *bmi088;
|
||||
// // bmi088 = (BMI088Instance *)(spi->id);
|
||||
// // 若第一次读取加速度,则在这里启动温度读取
|
||||
// // 如果使用异步姿态更新,此处唤醒量测更新的任务
|
||||
// }
|
||||
//
|
||||
// static void BMI088GyroSPIFinishCallback(SPIInstance *spi)
|
||||
// {
|
||||
// // static BMI088Instance *bmi088;
|
||||
// // bmi088 = (BMI088Instance *)(spi->id);
|
||||
// // 若不是异步,啥也不做;否则启动姿态的预测步(propagation)
|
||||
// }
|
||||
//
|
||||
// static void BMI088AccINTCallback(GPIOInstance *gpio)
|
||||
// {
|
||||
// // static BMI088Instance *bmi088;
|
||||
// // bmi088 = (BMI088Instance *)(gpio->id);
|
||||
// // 启动加速度计数据读取(和温度读取,如果有必要),并转换为实际值
|
||||
// // 读取完毕会调用BMI088AccSPIFinishCallback
|
||||
// }
|
||||
//
|
||||
// static void BMI088GyroINTCallback(GPIOInstance *gpio)
|
||||
// {
|
||||
// // static BMI088Instance *bmi088;
|
||||
// // bmi088 = (BMI088Instance *)(gpio->id);
|
||||
// // 启动陀螺仪数据读取,并转换为实际值
|
||||
// // 读取完毕会调用BMI088GyroSPIFinishCallback
|
||||
// }
|
||||
//
|
||||
// // -------------------------以上为私有函数,private用于IT模式下的中断处理---------------------------------//
|
||||
//
|
||||
// // -------------------------以下为公有函数,用于注册BMI088,标定和数据读取--------------------------------//
|
||||
//
|
||||
// /**
|
||||
// * @brief
|
||||
// * @todo 现在要考虑一下数据返回的方式,指针还是结构体?
|
||||
// *
|
||||
// * @param bmi088
|
||||
// * @return BMI088_Data_t
|
||||
// */
|
||||
// uint8_t BMI088Acquire(BMI088Instance *bmi088, BMI088_Data_t *data_store)
|
||||
// {
|
||||
// // 如果是blocking模式,则主动触发一次读取并返回数据
|
||||
// if (bmi088->work_mode == BMI088_BLOCK_PERIODIC_MODE)
|
||||
// {
|
||||
// static uint8_t buf[6] = {0}; // 最多读取6个byte(gyro/acc,temp是2)
|
||||
// // 读取accel的x轴数据首地址,bmi088内部自增读取地址 // 3* sizeof(int16_t)
|
||||
// BMI088AccelRead(bmi088, BMI088_ACCEL_XOUT_L, buf, 6);
|
||||
// for (uint8_t i = 0; i < 3; i++)
|
||||
// data_store->acc[i] = bmi088->acc_coef * (float) (int16_t) (((buf[2 * i + 1]) << 8) | buf[2 * i]);
|
||||
// BMI088GyroRead(bmi088, BMI088_GYRO_X_L, buf, 6); // 连续读取3个(3*2=6)轴的角速度
|
||||
// for (uint8_t i = 0; i < 3; i++)
|
||||
// data_store->gyro[i] = bmi088->BMI088_GYRO_SEN * (float) (int16_t) (((buf[2 * i + 1]) << 8) | buf[2 * i]);
|
||||
// BMI088AccelRead(bmi088, BMI088_TEMP_M, buf, 2); // 读温度,温度传感器在accel上
|
||||
// data_store->temperature = (float) (int16_t) (((buf[0] << 3) | (buf[1] >> 5))) * BMI088_TEMP_FACTOR +
|
||||
// BMI088_TEMP_OFFSET;
|
||||
//
|
||||
// return 1;
|
||||
// }
|
||||
//
|
||||
// // 如果是IT模式,则检查标志位.当传感器数据准备好会触发外部中断,中断服务函数会将标志位置1
|
||||
// if (bmi088->work_mode == BMI088_BLOCK_TRIGGER_MODE && bmi088->update_flag.imu_ready == 1)
|
||||
// {
|
||||
// memcpy(data_store, &bmi088->gyro, sizeof(BMI088_Data_t));
|
||||
// bmi088->update_flag.imu_ready = 0;
|
||||
// return 1;
|
||||
// }
|
||||
//
|
||||
// // 如果数据还没准备好,则返回空数据?或者返回上一次的数据?或者返回错误码? @todo
|
||||
// if (bmi088->update_flag.imu_ready == 0)
|
||||
// return 0;
|
||||
// return 1;
|
||||
// }
|
||||
//
|
||||
// /* pre calibrate parameter to go here */
|
||||
// #pragma message "REMEMBER TO SET PRE CALIBRATE PARAMETER IF YOU CHOOSE NOT TO CALIBRATE"
|
||||
// #define BMI088_PRE_CALI_ACC_X_OFFSET 0.0f
|
||||
// #define BMI088_PRE_CALI_ACC_Y_OFFSET 0.0f
|
||||
// #define BMI088_PRE_CALI_ACC_Z_OFFSET 0.0f
|
||||
// #define BMI088_PRE_CALI_G_NORM 9.805f
|
||||
// /**
|
||||
// * @brief BMI088 acc gyro 标定
|
||||
// * @note 标定后的数据存储在bmi088->bias和gNorm中,用于后续数据消噪和单位转换归一化
|
||||
// * @attention 不管工作模式是blocking还是IT,标定时都是blocking模式,所以不用担心中断关闭后无法标定(RobotInit关闭了全局中断)
|
||||
// * @attention 标定精度和等待时间有关,目前使用线性回归.后续考虑引入非线性回归
|
||||
// * @todo 将标定次数(等待时间)变为参数供设定
|
||||
// * @section 整体流程为1.累加加速度数据计算gNrom() 2.累加陀螺仪数据计算零飘
|
||||
// * 3. 如果标定过程运动幅度过大,重新标定 4.保存标定参数
|
||||
// *
|
||||
// * @param _bmi088 待标定的BMI088实例
|
||||
// */
|
||||
// void BMI088CalibrateIMU(BMI088Instance *_bmi088)
|
||||
// {
|
||||
// if (_bmi088->cali_mode == BMI088_CALIBRATE_ONLINE_MODE) // 性感bmi088在线标定,耗时6s
|
||||
// {
|
||||
// _bmi088->acc_coef = BMI088_ACCEL_6G_SEN; // 标定完后要乘以9.805/gNorm
|
||||
// _bmi088->BMI088_GYRO_SEN = BMI088_GYRO_2000_SEN; // 后续改为从initTable中获取
|
||||
// // 一次性参数用完就丢,不用static
|
||||
// float startTime; // 开始标定时间,用于确定是否超时
|
||||
// uint16_t CaliTimes = 6000; // 标定次数(6s)
|
||||
// float gyroMax[3], gyroMin[3]; // 保存标定过程中读取到的数据最大值判断是否满足标定环境
|
||||
// float gNormTemp, gNormMax, gNormMin; // 同上,计算矢量范数(模长)
|
||||
// float gyroDiff[3], gNormDiff; // 每个轴的最大角速度跨度及其模长
|
||||
//
|
||||
// BMI088_Data_t raw_data;
|
||||
// startTime = DWT_GetTimeline_s();
|
||||
// // 循环继续的条件为标定环境不满足
|
||||
// do // 用do while至少执行一次,省得对上面的参数进行初始化
|
||||
// {
|
||||
// // 标定超时,直接使用预标定参数(如果有)
|
||||
// if (DWT_GetTimeline_s() - startTime > 12.01)
|
||||
// {
|
||||
// // 两次都没有成功就切换标定模式,丢给下一个if处理,使用预标定参数
|
||||
// _bmi088->cali_mode = BMI088_LOAD_PRE_CALI_MODE;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// DWT_Delay(0.0005);
|
||||
// _bmi088->gNorm = 0;
|
||||
// for (uint8_t i = 0; i < 3; i++) // 重置gNorm和零飘
|
||||
// _bmi088->gyro_offset[i] = 0;
|
||||
//
|
||||
// // @todo : 这里也有获取bmi088数据的操作,后续与BMI088Acquire合并.注意标定时的工作模式是阻塞,且offset和acc_coef要初始化成0和1,标定完成后再设定为标定值
|
||||
// for (uint16_t i = 0; i < CaliTimes; ++i) // 提前计算,优化
|
||||
// {
|
||||
// BMI088Acquire(_bmi088, &raw_data);
|
||||
// gNormTemp = NormOf3d(raw_data.acc);
|
||||
// _bmi088->gNorm += gNormTemp; // 计算范数并累加,最后除以calib times获取单次值
|
||||
// for (uint8_t i = 0; i < 3; i++)
|
||||
// _bmi088->gyro_offset[i] += raw_data.gyro[i]; // 因为标定时传感器静止,所以采集到的值就是漂移,累加当前值,最后除以calib times获得零飘
|
||||
//
|
||||
// if (i == 0) // 避免未定义的行为(else中)
|
||||
// {
|
||||
// gNormMax = gNormMin = gNormTemp; // 初始化成当前的重力加速度模长
|
||||
// for (uint8_t j = 0; j < 3; ++j)
|
||||
// {
|
||||
// gyroMax[j] = raw_data.gyro[j];
|
||||
// gyroMin[j] = raw_data.gyro[j];
|
||||
// }
|
||||
// }
|
||||
// else // 更新gNorm的Min Max和gyro的minmax
|
||||
// {
|
||||
// gNormMax = gNormMax > gNormTemp ? gNormMax : gNormTemp;
|
||||
// gNormMin = gNormMin < gNormTemp ? gNormMin : gNormTemp;
|
||||
// for (uint8_t j = 0; j < 3; ++j)
|
||||
// {
|
||||
// gyroMax[j] = gyroMax[j] > _bmi088->gyro[j] ? gyroMax[j] : _bmi088->gyro[j];
|
||||
// gyroMin[j] = gyroMin[j] < _bmi088->gyro[j] ? gyroMin[j] : _bmi088->gyro[j];
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// gNormDiff = gNormMax - gNormMin; // 最大值和最小值的差
|
||||
// for (uint8_t j = 0; j < 3; ++j)
|
||||
// gyroDiff[j] = gyroMax[j] - gyroMin[j]; // 分别计算三轴
|
||||
// if (gNormDiff > 0.5f ||
|
||||
// gyroDiff[0] > 0.15f ||
|
||||
// gyroDiff[1] > 0.15f ||
|
||||
// gyroDiff[2] > 0.15f)
|
||||
// break; // 超出范围了,重开! remake到while循环,外面还有一层
|
||||
// DWT_Delay(0.0005); // 休息一会再开始下一轮数据获取,IMU准备数据需要时间
|
||||
// }
|
||||
// _bmi088->gNorm /= (float) CaliTimes; // 加速度范数重力
|
||||
// for (uint8_t i = 0; i < 3; ++i)
|
||||
// _bmi088->gyro_offset[i] /= (float) CaliTimes; // 三轴零飘
|
||||
// // 这里直接存到temperature,可以另外增加BMI088Instance的成员变量TempWhenCalib
|
||||
// _bmi088->temperature = raw_data.temperature * BMI088_TEMP_FACTOR + BMI088_TEMP_OFFSET;
|
||||
// // 保存标定时的温度,如果已知温度和零飘的关系
|
||||
// // caliTryOutCount++; 保存已经尝试的标定次数?由你.
|
||||
// }
|
||||
// while (gNormDiff > 0.5f ||
|
||||
// fabsf(_bmi088->gNorm - 9.8f) > 0.5f ||
|
||||
// gyroDiff[0] > 0.15f ||
|
||||
// gyroDiff[1] > 0.15f ||
|
||||
// gyroDiff[2] > 0.15f ||
|
||||
// fabsf(_bmi088->gyro_offset[0]) > 0.01f ||
|
||||
// fabsf(_bmi088->gyro_offset[1]) > 0.01f ||
|
||||
// fabsf(_bmi088->gyro_offset[2]) > 0.01f); // 满足条件说明标定环境不好
|
||||
// }
|
||||
//
|
||||
// // 离线标定
|
||||
// if (_bmi088->cali_mode == BMI088_LOAD_PRE_CALI_MODE) // 如果标定失败也会进来,直接使用离线数据
|
||||
// {
|
||||
// _bmi088->gyro_offset[0] = BMI088_PRE_CALI_ACC_X_OFFSET;
|
||||
// _bmi088->gyro_offset[1] = BMI088_PRE_CALI_ACC_Y_OFFSET;
|
||||
// _bmi088->gyro_offset[2] = BMI088_PRE_CALI_ACC_Z_OFFSET;
|
||||
// _bmi088->gNorm = BMI088_PRE_CALI_G_NORM;
|
||||
// }
|
||||
// _bmi088->acc_coef *= 9.805 / _bmi088->gNorm;
|
||||
// }
|
||||
//
|
||||
// // 考虑阻塞模式和非阻塞模式的兼容性,通过条件编译(则需要在编译前修改宏定义)或runtime参数判断
|
||||
// // runtime的开销不大(一次性判断),但是需要修改函数原型,增加参数,代码长度增加(但不多)
|
||||
// // runtime如何修改callback?根据参数选择是否给spi传入callback,如果是阻塞模式,则不传入callback,如果是非阻塞模式,则传入callback(bsp会检查是否NULL)
|
||||
// // 条件编译的开销小,但是需要修改宏定义,增加编译时间,同时人力介入
|
||||
// // 根据实际情况选择(说了和没说一样!)
|
||||
//
|
||||
// BMI088Instance *BMI088Register(BMI088_Init_Config_s *config)
|
||||
// {
|
||||
// // 申请内存
|
||||
// BMI088Instance *bmi088_instance = (BMI088Instance *) zmalloc(sizeof(BMI088Instance));
|
||||
// // 从右向左赋值,让bsp instance保存指向bmi088_instance的指针(父指针),便于在底层中断中访问bmi088_instance
|
||||
// config->acc_int_config.id =
|
||||
// config->gyro_int_config.id =
|
||||
// config->spi_acc_config.id =
|
||||
// config->spi_gyro_config.id =
|
||||
// config->heat_pwm_config.id = bmi088_instance;
|
||||
// // @todo:
|
||||
// // 目前只实现了!!!阻塞读取模式!!!.如果需要使用IT模式,则需要修改这里的代码,为spi和gpio注册callback(默认为NULL)
|
||||
// // 还需要设置SPI的传输模式为DMA模式或IT模式(默认为blocking)
|
||||
// // 可以通过conditional compilation或者runtime参数判断
|
||||
// // code to go here ...
|
||||
//
|
||||
// // INT_ACC EXTI CALLBACK: 检查是否有传输正在进行,如果没有则开启SPI DMA传输,有则置位wait标志位;
|
||||
// // 第一次是加速度计,第二次是温度.
|
||||
//
|
||||
// // INT_GYRO EXTI CALLBACK: 开启SPI DMA传输,不会出现等待传输的情况
|
||||
// // SPI_GYRO DMA CALLBACK: 解算陀螺仪数据,
|
||||
// // SPI_ACC DMA CALLBACK: 解算加速度计数据,清除温度wait标志位并启动温度传输,第二次进入中断时解算温度数据
|
||||
//
|
||||
// // 还有其他方案可用,比如阻塞等待传输完成,但是比较笨.
|
||||
//
|
||||
// // 根据参数选择工作模式
|
||||
// if (config->work_mode == BMI088_BLOCK_PERIODIC_MODE)
|
||||
// {
|
||||
// config->spi_acc_config.spi_work_mode = SPI_BLOCK_MODE;
|
||||
// config->spi_gyro_config.spi_work_mode = SPI_BLOCK_MODE;
|
||||
// // callbacks are all NULL
|
||||
// }
|
||||
// else if (config->work_mode == BMI088_BLOCK_TRIGGER_MODE)
|
||||
// {
|
||||
// config->spi_gyro_config.spi_work_mode = SPI_DMA_MODE; // 如果DMA资源不够,可以用SPI_IT_MODE
|
||||
// config->spi_gyro_config.spi_work_mode = SPI_DMA_MODE;
|
||||
// // 设置回调函数
|
||||
// config->spi_acc_config.callback = BMI088AccSPIFinishCallback;
|
||||
// config->spi_gyro_config.callback = BMI088GyroSPIFinishCallback;
|
||||
// config->acc_int_config.gpio_model_callback = BMI088AccINTCallback;
|
||||
// config->gyro_int_config.gpio_model_callback = BMI088GyroINTCallback;
|
||||
// bmi088_instance->acc_int = GPIORegister(&config->acc_int_config); // 只有在非阻塞模式下才需要注册中断
|
||||
// bmi088_instance->gyro_int = GPIORegister(&config->gyro_int_config);
|
||||
// } // 注册实例
|
||||
// bmi088_instance->spi_acc = SPIRegister(&config->spi_acc_config);
|
||||
// bmi088_instance->spi_gyro = SPIRegister(&config->spi_gyro_config);
|
||||
// bmi088_instance->heat_pwm = PWMRegister(&config->heat_pwm_config);
|
||||
// PIDInit(&bmi088_instance->heat_pid, &config->heat_pid_config);
|
||||
//
|
||||
// // 初始化acc和gyro
|
||||
// BMI088_ERORR_CODE_e error = BMI088_NO_ERROR;
|
||||
// do
|
||||
// {
|
||||
// error = BMI088_NO_ERROR;
|
||||
// error |= BMI088AccelInit(bmi088_instance);
|
||||
// error |= BMI088GyroInit(bmi088_instance);
|
||||
// // 可以增加try out times,超出次数则返回错误
|
||||
// }
|
||||
// while (error != 0);
|
||||
//
|
||||
// bmi088_instance->work_mode = BMI088_BLOCK_PERIODIC_MODE; // 临时设置为阻塞模式
|
||||
// BMI088CalibrateIMU(bmi088_instance); // 标定acc和gyro
|
||||
// bmi088_instance->work_mode = config->work_mode; // 恢复工作模式
|
||||
//
|
||||
// return bmi088_instance;
|
||||
// }
|
||||
117
User_Code/module/periph/imu/BMI088(newer_support)/bmi088.h
Normal file
117
User_Code/module/periph/imu/BMI088(newer_support)/bmi088.h
Normal file
@@ -0,0 +1,117 @@
|
||||
// #ifndef __BMI088_H__ // 防止重复包含
|
||||
// #define __BMI088_H__
|
||||
//
|
||||
// #include "bsp_spi.h"
|
||||
// #include "bsp_gpio.h"
|
||||
// #include "controller.h"
|
||||
// #include "bsp_pwm.h"
|
||||
// #include "stdint.h"
|
||||
//
|
||||
// // bmi088工作模式枚举
|
||||
// typedef enum
|
||||
// {
|
||||
// BMI088_BLOCK_PERIODIC_MODE = 0, // 阻塞模式,周期性读取
|
||||
// BMI088_BLOCK_TRIGGER_MODE, // 阻塞模式,触发读取(中断)
|
||||
// } BMI088_Work_Mode_e;
|
||||
//
|
||||
// // bmi088标定方式枚举,若使用预设标定参数,注意修改预设参数
|
||||
// typedef enum
|
||||
// {
|
||||
// BMI088_CALIBRATE_ONLINE_MODE = 0, // 初始化时进行标定
|
||||
// BMI088_LOAD_PRE_CALI_MODE, // 使用预设标定参数,
|
||||
// } BMI088_Calibrate_Mode_e;
|
||||
//
|
||||
// #pragma pack(1) // 1字节对齐
|
||||
// /* BMI088数据*/
|
||||
// typedef struct
|
||||
// {
|
||||
// float gyro[3]; // 陀螺仪数据,xyz
|
||||
// float acc[3]; // 加速度计数据,xyz
|
||||
// float temperature; // 温度
|
||||
//
|
||||
// // float timestamp; // 时间戳,单位为ms,用于计算两次采样的时间间隔,同时给视觉提供timeline
|
||||
// // uint32_t count; // 第count次采样,用于对齐时间戳
|
||||
// } BMI088_Data_t;
|
||||
// #pragma pack() // 恢复默认对齐,需要传输的结构体务必开启1字节对齐
|
||||
//
|
||||
// /* BMI088实例结构体定义 */
|
||||
// typedef struct
|
||||
// {
|
||||
// // 传输模式和工作模式控制
|
||||
// BMI088_Work_Mode_e work_mode;
|
||||
// BMI088_Calibrate_Mode_e cali_mode;
|
||||
// // SPI接口
|
||||
// SPIInstance *spi_gyro; // 注意,SPIInstnace内部也有一个GPIOInstance,用于控制片选CS
|
||||
// SPIInstance *spi_acc; // 注意,SPIInstnace内部也有一个GPIOInstance,用于控制片选CS
|
||||
// // EXTI GPIO,如果BMI088工作在中断模式,则需要配置中断引脚(有数据产生时触发解算)
|
||||
// GPIOInstance *gyro_int;
|
||||
// GPIOInstance *acc_int;
|
||||
// // 温度控制
|
||||
// PIDInstance heat_pid; // 恒温PID
|
||||
// PWMInstance *heat_pwm; // 加热PWM
|
||||
// // IMU数据
|
||||
// float gyro[3]; // 陀螺仪数据,xyz
|
||||
// float acc[3]; // 加速度计数据,xyz
|
||||
// float temperature; // 温度
|
||||
// // 标定数据
|
||||
// float gyro_offset[3]; // 陀螺仪零偏
|
||||
// float gNorm; // 重力加速度模长,从标定获取
|
||||
// float acc_coef; // 加速度计原始数据转换系数
|
||||
// // 传感器灵敏度,用于计算实际值(regNdef.h中定义)
|
||||
// float BMI088_ACCEL_SEN;
|
||||
// float BMI088_GYRO_SEN;
|
||||
// // 用于计算两次采样的时间间隔
|
||||
// uint32_t bias_dwt_cnt;
|
||||
//
|
||||
// // 数据更新标志位
|
||||
// struct // 位域,节省空间提高可读性
|
||||
// {
|
||||
// uint8_t gyro: 1; // 1:有新数据,0:无新数据
|
||||
// uint8_t acc: 1;
|
||||
// uint8_t temp: 1;
|
||||
// uint8_t gyro_overrun: 1; // 1:数据溢出,0:无溢出
|
||||
// uint8_t acc_overrun: 1;
|
||||
// uint8_t temp_overrun: 1;
|
||||
// uint8_t imu_ready: 1; // 1:IMU数据准备好,0:IMU数据未准备好(gyro+acc)
|
||||
// // 后续可添加其他标志位,不够用可以扩充16or32,太多可以删
|
||||
// } update_flag;
|
||||
// } BMI088Instance;
|
||||
//
|
||||
// /* BMI088初始化配置 */
|
||||
// typedef struct
|
||||
// {
|
||||
// BMI088_Work_Mode_e work_mode;
|
||||
// BMI088_Calibrate_Mode_e cali_mode;
|
||||
// SPI_Init_Config_s spi_gyro_config;
|
||||
// SPI_Init_Config_s spi_acc_config;
|
||||
// GPIO_Init_Config_s gyro_int_config;
|
||||
// GPIO_Init_Config_s acc_int_config;
|
||||
// PID_Init_Config_s heat_pid_config;
|
||||
// PWM_Init_Config_s heat_pwm_config;
|
||||
// } BMI088_Init_Config_s;
|
||||
//
|
||||
// /**
|
||||
// * @brief 初始化BMI088,返回BMI088实例指针
|
||||
// * @note 一般一个开发板只有一个BMI088,所以这里就叫BMI088Init而不是Register
|
||||
// *
|
||||
// * @param config bmi088初始化配置
|
||||
// * @return BMI088Instance* 实例指针
|
||||
// */
|
||||
// BMI088Instance *BMI088Register(BMI088_Init_Config_s *config);
|
||||
//
|
||||
// /**
|
||||
// * @brief 读取BMI088数据
|
||||
// * @param bmi088 BMI088实例指针
|
||||
// * @return BMI088_Data_t 读取到的数据
|
||||
// */
|
||||
// uint8_t BMI088Acquire(BMI088Instance *bmi088, BMI088_Data_t *data_store);
|
||||
//
|
||||
// /**
|
||||
// * @brief 标定传感器.BMI088在初始化的时候会调用此函数. 提供接口方便标定离线数据
|
||||
// * @attention @todo 注意,当操作系统开始运行后,此函数会和INS_Task冲突.目前不允许在运行时调用此函数,后续加入标志位判断以提供运行时重新的标定功能
|
||||
// *
|
||||
// * @param _bmi088 待标定的实例
|
||||
// */
|
||||
// void BMI088CalibrateIMU(BMI088Instance *_bmi088);
|
||||
//
|
||||
// #endif // !__BMI088_H__
|
||||
@@ -0,0 +1,234 @@
|
||||
#ifndef BMI088REG_H
|
||||
#define BMI088REG_H
|
||||
|
||||
/*------- BMI088寄存器地址及其存放的内容-------*/
|
||||
|
||||
#define BMI088_ACC_CHIP_ID 0x00 // the register is " Who am I "
|
||||
#define BMI088_ACC_CHIP_ID_VALUE 0x1E
|
||||
|
||||
#define BMI088_ACC_ERR_REG 0x02
|
||||
#define BMI088_ACCEL_CONGIF_ERROR_SHFITS 0x2
|
||||
#define BMI088_ACCEL_CONGIF_ERROR (1 << BMI088_ACCEL_CONGIF_ERROR_SHFITS)
|
||||
#define BMI088_FATAL_ERROR_SHFITS 0x0
|
||||
#define BMI088_FATAL_ERROR (1 << BMI088_FATAL_ERROR)
|
||||
|
||||
#define BMI088_ACC_STATUS 0x03
|
||||
#define BMI088_ACCEL_DRDY_SHFITS 0x7
|
||||
#define BMI088_ACCEL_DRDY (1 << BMI088_ACCEL_DRDY_SHFITS)
|
||||
|
||||
#define BMI088_ACCEL_XOUT_L 0x12
|
||||
#define BMI088_ACCEL_XOUT_M 0x13
|
||||
#define BMI088_ACCEL_YOUT_L 0x14
|
||||
#define BMI088_ACCEL_YOUT_M 0x15
|
||||
#define BMI088_ACCEL_ZOUT_L 0x16
|
||||
#define BMI088_ACCEL_ZOUT_M 0x17
|
||||
|
||||
#define BMI088_SENSORTIME_DATA_L 0x18
|
||||
#define BMI088_SENSORTIME_DATA_M 0x19
|
||||
#define BMI088_SENSORTIME_DATA_H 0x1A
|
||||
|
||||
#define BMI088_ACC_INT_STAT_1 0x1D
|
||||
#define BMI088_ACCEL_DRDY_INTERRUPT_SHFITS 0x7
|
||||
#define BMI088_ACCEL_DRDY_INTERRUPT (1 << BMI088_ACCEL_DRDY_INTERRUPT_SHFITS)
|
||||
|
||||
#define BMI088_TEMP_M 0x22
|
||||
|
||||
#define BMI088_TEMP_L 0x23
|
||||
|
||||
#define BMI088_ACC_CONF 0x40
|
||||
#define BMI088_ACC_CONF_MUST_Set 0x80
|
||||
#define BMI088_ACC_BWP_SHFITS 0x4
|
||||
#define BMI088_ACC_OSR4 (0x0 << BMI088_ACC_BWP_SHFITS)
|
||||
#define BMI088_ACC_OSR2 (0x1 << BMI088_ACC_BWP_SHFITS)
|
||||
#define BMI088_ACC_NORMAL (0x2 << BMI088_ACC_BWP_SHFITS)
|
||||
|
||||
#define BMI088_ACC_ODR_SHFITS 0x0
|
||||
#define BMI088_ACC_12_5_HZ (0x5 << BMI088_ACC_ODR_SHFITS)
|
||||
#define BMI088_ACC_25_HZ (0x6 << BMI088_ACC_ODR_SHFITS)
|
||||
#define BMI088_ACC_50_HZ (0x7 << BMI088_ACC_ODR_SHFITS)
|
||||
#define BMI088_ACC_100_HZ (0x8 << BMI088_ACC_ODR_SHFITS)
|
||||
#define BMI088_ACC_200_HZ (0x9 << BMI088_ACC_ODR_SHFITS)
|
||||
#define BMI088_ACC_400_HZ (0xA << BMI088_ACC_ODR_SHFITS)
|
||||
#define BMI088_ACC_800_HZ (0xB << BMI088_ACC_ODR_SHFITS)
|
||||
#define BMI088_ACC_1600_HZ (0xC << BMI088_ACC_ODR_SHFITS)
|
||||
|
||||
#define BMI088_ACC_RANGE 0x41
|
||||
|
||||
#define BMI088_ACC_RANGE_SHFITS 0x0
|
||||
#define BMI088_ACC_RANGE_3G (0x0 << BMI088_ACC_RANGE_SHFITS)
|
||||
#define BMI088_ACC_RANGE_6G (0x1 << BMI088_ACC_RANGE_SHFITS)
|
||||
#define BMI088_ACC_RANGE_12G (0x2 << BMI088_ACC_RANGE_SHFITS)
|
||||
#define BMI088_ACC_RANGE_24G (0x3 << BMI088_ACC_RANGE_SHFITS)
|
||||
|
||||
#define BMI088_INT1_IO_CTRL 0x53
|
||||
#define BMI088_ACC_INT1_IO_ENABLE_SHFITS 0x3
|
||||
#define BMI088_ACC_INT1_IO_ENABLE (0x1 << BMI088_ACC_INT1_IO_ENABLE_SHFITS)
|
||||
#define BMI088_ACC_INT1_GPIO_MODE_SHFITS 0x2
|
||||
#define BMI088_ACC_INT1_GPIO_PP (0x0 << BMI088_ACC_INT1_GPIO_MODE_SHFITS)
|
||||
#define BMI088_ACC_INT1_GPIO_OD (0x1 << BMI088_ACC_INT1_GPIO_MODE_SHFITS)
|
||||
#define BMI088_ACC_INT1_GPIO_LVL_SHFITS 0x1
|
||||
#define BMI088_ACC_INT1_GPIO_LOW (0x0 << BMI088_ACC_INT1_GPIO_LVL_SHFITS)
|
||||
#define BMI088_ACC_INT1_GPIO_HIGH (0x1 << BMI088_ACC_INT1_GPIO_LVL_SHFITS)
|
||||
|
||||
#define BMI088_INT2_IO_CTRL 0x54
|
||||
#define BMI088_ACC_INT2_IO_ENABLE_SHFITS 0x3
|
||||
#define BMI088_ACC_INT2_IO_ENABLE (0x1 << BMI088_ACC_INT2_IO_ENABLE_SHFITS)
|
||||
#define BMI088_ACC_INT2_GPIO_MODE_SHFITS 0x2
|
||||
#define BMI088_ACC_INT2_GPIO_PP (0x0 << BMI088_ACC_INT2_GPIO_MODE_SHFITS)
|
||||
#define BMI088_ACC_INT2_GPIO_OD (0x1 << BMI088_ACC_INT2_GPIO_MODE_SHFITS)
|
||||
#define BMI088_ACC_INT2_GPIO_LVL_SHFITS 0x1
|
||||
#define BMI088_ACC_INT2_GPIO_LOW (0x0 << BMI088_ACC_INT2_GPIO_LVL_SHFITS)
|
||||
#define BMI088_ACC_INT2_GPIO_HIGH (0x1 << BMI088_ACC_INT2_GPIO_LVL_SHFITS)
|
||||
|
||||
#define BMI088_INT_MAP_DATA 0x58
|
||||
#define BMI088_ACC_INT2_DRDY_INTERRUPT_SHFITS 0x6
|
||||
#define BMI088_ACC_INT2_DRDY_INTERRUPT (0x1 << BMI088_ACC_INT2_DRDY_INTERRUPT_SHFITS)
|
||||
#define BMI088_ACC_INT1_DRDY_INTERRUPT_SHFITS 0x2
|
||||
#define BMI088_ACC_INT1_DRDY_INTERRUPT (0x1 << BMI088_ACC_INT1_DRDY_INTERRUPT_SHFITS)
|
||||
|
||||
#define BMI088_ACC_SELF_TEST 0x6D
|
||||
#define BMI088_ACC_SELF_TEST_OFF 0x00
|
||||
#define BMI088_ACC_SELF_TEST_POSITIVE_SIGNAL 0x0D
|
||||
#define BMI088_ACC_SELF_TEST_NEGATIVE_SIGNAL 0x09
|
||||
|
||||
#define BMI088_ACC_PWR_CONF 0x7C
|
||||
#define BMI088_ACC_PWR_SUSPEND_MODE 0x03
|
||||
#define BMI088_ACC_PWR_ACTIVE_MODE 0x00
|
||||
|
||||
#define BMI088_ACC_PWR_CTRL 0x7D
|
||||
#define BMI088_ACC_ENABLE_ACC_OFF 0x00
|
||||
#define BMI088_ACC_ENABLE_ACC_ON 0x04
|
||||
|
||||
#define BMI088_ACC_SOFTRESET 0x7E
|
||||
#define BMI088_ACC_SOFTRESET_VALUE 0xB6
|
||||
|
||||
#define BMI088_GYRO_CHIP_ID 0x00
|
||||
#define BMI088_GYRO_CHIP_ID_VALUE 0x0F
|
||||
|
||||
#define BMI088_GYRO_X_L 0x02
|
||||
#define BMI088_GYRO_X_H 0x03
|
||||
#define BMI088_GYRO_Y_L 0x04
|
||||
#define BMI088_GYRO_Y_H 0x05
|
||||
#define BMI088_GYRO_Z_L 0x06
|
||||
#define BMI088_GYRO_Z_H 0x07
|
||||
|
||||
#define BMI088_GYRO_INT_STAT_1 0x0A
|
||||
#define BMI088_GYRO_DYDR_SHFITS 0x7
|
||||
#define BMI088_GYRO_DYDR (0x1 << BMI088_GYRO_DYDR_SHFITS)
|
||||
|
||||
#define BMI088_GYRO_RANGE 0x0F
|
||||
#define BMI088_GYRO_RANGE_SHFITS 0x0
|
||||
#define BMI088_GYRO_2000 (0x0 << BMI088_GYRO_RANGE_SHFITS)
|
||||
#define BMI088_GYRO_1000 (0x1 << BMI088_GYRO_RANGE_SHFITS)
|
||||
#define BMI088_GYRO_500 (0x2 << BMI088_GYRO_RANGE_SHFITS)
|
||||
#define BMI088_GYRO_250 (0x3 << BMI088_GYRO_RANGE_SHFITS)
|
||||
#define BMI088_GYRO_125 (0x4 << BMI088_GYRO_RANGE_SHFITS)
|
||||
|
||||
#define BMI088_GYRO_BANDWIDTH 0x10
|
||||
// the first num means Output data rate, the second num means bandwidth
|
||||
#define BMI088_GYRO_BANDWIDTH_MUST_Set 0x80
|
||||
#define BMI088_GYRO_2000_532_HZ 0x00
|
||||
#define BMI088_GYRO_2000_230_HZ 0x01
|
||||
#define BMI088_GYRO_1000_116_HZ 0x02
|
||||
#define BMI088_GYRO_400_47_HZ 0x03
|
||||
#define BMI088_GYRO_200_23_HZ 0x04
|
||||
#define BMI088_GYRO_100_12_HZ 0x05
|
||||
#define BMI088_GYRO_200_64_HZ 0x06
|
||||
#define BMI088_GYRO_100_32_HZ 0x07
|
||||
|
||||
#define BMI088_GYRO_LPM1 0x11
|
||||
#define BMI088_GYRO_NORMAL_MODE 0x00
|
||||
#define BMI088_GYRO_SUSPEND_MODE 0x80
|
||||
#define BMI088_GYRO_DEEP_SUSPEND_MODE 0x20
|
||||
|
||||
#define BMI088_GYRO_SOFTRESET 0x14
|
||||
#define BMI088_GYRO_SOFTRESET_VALUE 0xB6
|
||||
|
||||
#define BMI088_GYRO_CTRL 0x15
|
||||
#define BMI088_DRDY_OFF 0x00
|
||||
#define BMI088_DRDY_ON 0x80
|
||||
|
||||
#define BMI088_GYRO_INT3_INT4_IO_CONF 0x16
|
||||
#define BMI088_GYRO_INT4_GPIO_MODE_SHFITS 0x3
|
||||
#define BMI088_GYRO_INT4_GPIO_PP (0x0 << BMI088_GYRO_INT4_GPIO_MODE_SHFITS)
|
||||
#define BMI088_GYRO_INT4_GPIO_OD (0x1 << BMI088_GYRO_INT4_GPIO_MODE_SHFITS)
|
||||
#define BMI088_GYRO_INT4_GPIO_LVL_SHFITS 0x2
|
||||
#define BMI088_GYRO_INT4_GPIO_LOW (0x0 << BMI088_GYRO_INT4_GPIO_LVL_SHFITS)
|
||||
#define BMI088_GYRO_INT4_GPIO_HIGH (0x1 << BMI088_GYRO_INT4_GPIO_LVL_SHFITS)
|
||||
#define BMI088_GYRO_INT3_GPIO_MODE_SHFITS 0x1
|
||||
#define BMI088_GYRO_INT3_GPIO_PP (0x0 << BMI088_GYRO_INT3_GPIO_MODE_SHFITS)
|
||||
#define BMI088_GYRO_INT3_GPIO_OD (0x1 << BMI088_GYRO_INT3_GPIO_MODE_SHFITS)
|
||||
#define BMI088_GYRO_INT3_GPIO_LVL_SHFITS 0x0
|
||||
#define BMI088_GYRO_INT3_GPIO_LOW (0x0 << BMI088_GYRO_INT3_GPIO_LVL_SHFITS)
|
||||
#define BMI088_GYRO_INT3_GPIO_HIGH (0x1 << BMI088_GYRO_INT3_GPIO_LVL_SHFITS)
|
||||
|
||||
#define BMI088_GYRO_INT3_INT4_IO_MAP 0x18
|
||||
|
||||
#define BMI088_GYRO_DRDY_IO_OFF 0x00
|
||||
#define BMI088_GYRO_DRDY_IO_INT3 0x01
|
||||
#define BMI088_GYRO_DRDY_IO_INT4 0x80
|
||||
#define BMI088_GYRO_DRDY_IO_BOTH (BMI088_GYRO_DRDY_IO_INT3 | BMI088_GYRO_DRDY_IO_INT4)
|
||||
|
||||
#define BMI088_GYRO_SELF_TEST 0x3C
|
||||
#define BMI088_GYRO_RATE_OK_SHFITS 0x4
|
||||
#define BMI088_GYRO_RATE_OK (0x1 << BMI088_GYRO_RATE_OK_SHFITS)
|
||||
#define BMI088_GYRO_BIST_FAIL_SHFITS 0x2
|
||||
#define BMI088_GYRO_BIST_FAIL (0x1 << BMI088_GYRO_BIST_FAIL_SHFITS)
|
||||
#define BMI088_GYRO_BIST_RDY_SHFITS 0x1
|
||||
#define BMI088_GYRO_BIST_RDY (0x1 << BMI088_GYRO_BIST_RDY_SHFITS)
|
||||
#define BMI088_GYRO_TRIG_BIST_SHFITS 0x0
|
||||
#define BMI088_GYRO_TRIG_BIST (0x1 << BMI088_GYRO_TRIG_BIST_SHFITS)
|
||||
|
||||
/* -------BMI088 配置和传感器灵敏度换算系数等------- */
|
||||
|
||||
#define BMI088_TEMP_FACTOR 0.125f
|
||||
#define BMI088_TEMP_OFFSET 23.0f
|
||||
|
||||
#define BMI088_WRITE_ACCEL_REG_NUM 6
|
||||
#define BMI088_WRITE_GYRO_REG_NUM 6
|
||||
|
||||
#define BMI088_GYRO_DATA_READY_BIT 0
|
||||
#define BMI088_ACCEL_DATA_READY_BIT 1
|
||||
#define BMI088_ACCEL_TEMP_DATA_READY_BIT 2
|
||||
|
||||
#define BMI088_LONG_DELAY_TIME 80
|
||||
#define BMI088_COM_WAIT_SENSOR_TIME 150
|
||||
|
||||
#define BMI088_ACCEL_IIC_ADDRESSE (0x18 << 1)
|
||||
#define BMI088_GYRO_IIC_ADDRESSE (0x68 << 1)
|
||||
|
||||
#define BMI088_ACCEL_3G_SEN 0.0008974358974f
|
||||
#define BMI088_ACCEL_6G_SEN 0.00179443359375f
|
||||
#define BMI088_ACCEL_12G_SEN 0.0035888671875f
|
||||
#define BMI088_ACCEL_24G_SEN 0.007177734375f
|
||||
|
||||
#define BMI088_GYRO_2000_SEN 0.00106526443603169529841533860381f
|
||||
#define BMI088_GYRO_1000_SEN 0.00053263221801584764920766930190693f
|
||||
#define BMI088_GYRO_500_SEN 0.00026631610900792382460383465095346f
|
||||
#define BMI088_GYRO_250_SEN 0.00013315805450396191230191732547673f
|
||||
#define BMI088_GYRO_125_SEN 0.000066579027251980956150958662738366f
|
||||
|
||||
/* BMI088错误码枚举 */
|
||||
typedef enum
|
||||
{
|
||||
BMI088_NO_ERROR = 0x00,
|
||||
BMI088_ACC_PWR_CTRL_ERROR = 0x01,
|
||||
BMI088_ACC_PWR_CONF_ERROR = 0x02,
|
||||
BMI088_ACC_CONF_ERROR = 0x03,
|
||||
BMI088_ACC_SELF_TEST_ERROR = 0x04,
|
||||
BMI088_ACC_RANGE_ERROR = 0x05,
|
||||
BMI088_INT1_IO_CTRL_ERROR = 0x06,
|
||||
BMI088_INT_MAP_DATA_ERROR = 0x07,
|
||||
BMI088_GYRO_RANGE_ERROR = 0x08,
|
||||
BMI088_GYRO_BANDWIDTH_ERROR = 0x09,
|
||||
BMI088_GYRO_LPM1_ERROR = 0x0A,
|
||||
BMI088_GYRO_CTRL_ERROR = 0x0B,
|
||||
BMI088_GYRO_INT3_INT4_IO_CONF_ERROR = 0x0C,
|
||||
BMI088_GYRO_INT3_INT4_IO_MAP_ERROR = 0x0D,
|
||||
|
||||
BMI088_SELF_TEST_ACCEL_ERROR = 0x80,
|
||||
BMI088_SELF_TEST_GYRO_ERROR = 0x40,
|
||||
BMI088_NO_SENSOR = 0xFF,
|
||||
} BMI088_ERORR_CODE_e;
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,7 @@
|
||||
#define __INS_TASK_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "BMI088driver.h"
|
||||
#include "BMI088/BMI088driver.h"
|
||||
#include "QuaternionEKF.h"
|
||||
|
||||
#define X 0
|
||||
|
||||
Reference in New Issue
Block a user