Files

250 lines
7.3 KiB
C
Raw Permalink Normal View History

2026-04-23 14:02:03 +08:00
/* Includes ------------------------------------------------------------------*/
#include "lsm6dsl_app.h"
#include "lsm6dsl_reg.h"
#include <string.h>
#include <stdio.h>
#include "bsp.h"
#include "UartDebug.h"
#include "main.h"
#include "i2c.h"
#include "Algorithm.h"
dev_ctx_t dev_ctx;
static bool InitFlag;
#define ACC_COLL_CNT_MAX 4 //每组平均样本数,输出速率=ODR/4=13Hz
#define ACC_FIFO_WATERMASK (ACC_COLL_CNT_MAX * 6) //FIFO水印:4组 × (3陀螺+3加速度)=24
2026-04-23 14:02:03 +08:00
#define BOOT_TIME 15 //ms
typedef enum {
Acc_Idle,
Acc_Get_Data, //连续采集运行中
2026-04-23 14:02:03 +08:00
}AccStatusType_m;
static AccStatusType_m acc_status;
static uint32_t acc_cvttime;
static bool Lsm6dslWaterMarkFullIntFlag;
static bool Lsm6dslWakeupIntFlag;
static uint16_t Lsm6dslIntWatchdog; //无数据看门狗计数(1ms)
static bool Lsm6dslRecoverReq; //自恢复请求(1ms置位,主循环执行)
2026-04-23 14:02:03 +08:00
static float acceleration_mg[3][ACC_COLL_CNT_MAX];
static float angular_rate_mdps[3][ACC_COLL_CNT_MAX];
static uint8_t whoamI, rst;
static void platform_delay(uint32_t ms)
{
delay_ms(ms);
}
static void platform_write(uint8_t reg, uint8_t *bufp, uint32_t len)
{
uint16_t Selve_Add = LSM6DSL_I2C_ADD_L >> 1;
I2C_MasterWriteData(M0P_I2C0, Selve_Add, reg, bufp, len);
}
static void platform_read(uint8_t reg, uint8_t *bufp, uint32_t len)
{
uint16_t Selve_Add = LSM6DSL_I2C_ADD_L >> 1;
I2C_MasterReadData(M0P_I2C0, Selve_Add, reg, bufp, len);
}
/*****************************************************************************************
* 函数名称: Lsm6dsl_Config
* 功能描述: LSM6DSL寄存器配置,配置完成后开启连续采集(常开,不进入低功耗)
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
static void Lsm6dsl_Config(void)
2026-04-23 14:02:03 +08:00
{
/* Restore default configuration */
lsm6dsl_reset_set(&dev_ctx, PROPERTY_ENABLE);
do {
lsm6dsl_reset_get(&dev_ctx, &rst);
} while (rst);
/* 高性能模式(传感器常开,噪声最低) */
lsm6dsl_xl_power_mode_set(&dev_ctx, LSM6DSL_XL_HIGH_PERFORMANCE);
lsm6dsl_gy_power_mode_set(&dev_ctx, LSM6DSL_GY_HIGH_PERFORMANCE);
2026-04-23 14:02:03 +08:00
/* Enable Block Data Update */
lsm6dsl_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
/* Set full scale */
lsm6dsl_xl_full_scale_set(&dev_ctx, LSM6DSL_2g);
lsm6dsl_gy_full_scale_set(&dev_ctx, LSM6DSL_500dps);
2026-04-23 14:02:03 +08:00
/* Configure filtering chain(No aux interface) */
/* Accelerometer - analog filter */
lsm6dsl_xl_filter_analog_set(&dev_ctx, LSM6DSL_XL_ANA_BW_400Hz);
/* Accelerometer - LPF1 + LPF2 path */
lsm6dsl_xl_lp2_bandwidth_set(&dev_ctx, LSM6DSL_XL_LOW_NOISE_LP_ODR_DIV_9);
/* Gyroscope - filtering chain */
lsm6dsl_gy_band_pass_set(&dev_ctx, LSM6DSL_HP_260mHz_LP1_STRONG);
/* FIFO:连续流模式,存满水印触发中断但不停采 */
lsm6dsl_fifo_xl_batch_set(&dev_ctx, LSM6DSL_FIFO_XL_NO_DEC); //fifo加速度写入频率设置
lsm6dsl_fifo_gy_batch_set(&dev_ctx, LSM6DSL_FIFO_GY_NO_DEC); //fifo陀螺仪写入频率设置
lsm6dsl_fifo_data_rate_set(&dev_ctx, LSM6DSL_FIFO_52Hz); //FIFO ODR选择,与传感器ODR一致
lsm6dsl_fifo_watermark_set(&dev_ctx, ACC_FIFO_WATERMASK); //FIFO水印电平设置,4组数据
lsm6dsl_fifo_stop_on_wtm_set(&dev_ctx, 0); //存满水印后继续采集,不停
lsm6dsl_block_data_update_set(&dev_ctx, 1); //fifo模式ctrl3_c bdu必须为1
lsm6dsl_auto_increment_set(&dev_ctx, 1); //fifo模式ctrl3_c if_inc必须为1
/* 中断1:FIFO水印阈值中断 */
lsm6dsl_int1_route_t int1val ={0, 0, 0};
int1val.int1_fth = 1; //FIFO存储达到水印深度时触发
lsm6dsl_pin_int1_route_set(&dev_ctx, int1val);
/* 最后开启ODR和FIFO连续模式,保证先配置后采样 */
lsm6dsl_fifo_mode_set(&dev_ctx, LSM6DSL_STREAM_MODE);
lsm6dsl_xl_data_rate_set(&dev_ctx, LSM6DSL_XL_ODR_52Hz);
lsm6dsl_gy_data_rate_set(&dev_ctx, LSM6DSL_GY_ODR_52Hz);
}
static void Lsm6dsl_Init(void)
{
/* Initialize mems driver interface */
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.mdelay = platform_delay;
/* Wait sensor boot time */
platform_delay(BOOT_TIME);
/* Check device ID */
whoamI = 0;
lsm6dsl_device_id_get(&dev_ctx, &whoamI);
acc_cvttime = 100;
while(whoamI != LSM6DSL_ID){
if(acc_cvttime <= 0){
DBG_LOG("LSM6DS INIT Err...\r\n"); /*manage here device not found */
InitFlag = false;
return;
}
}
Lsm6dsl_Config();
2026-04-23 14:02:03 +08:00
if(InitFlag == false){
DBG_LOG("LSM6DS INIT OK...\r\n");
2026-04-23 14:02:03 +08:00
InitFlag = true;
}
2026-04-23 14:02:03 +08:00
}
extern void Lsm6dDataProcessCallBack(float *Acc, float *Gy);
static void Acc_IntHandler(void)
{
uint16_t DiffFifo;
uint16_t Sets;
uint8_t Cnt;
uint8_t Slot;
uint16_t i;
2026-04-23 14:02:03 +08:00
AccGyData_t AccGy;
float AverageAcc[XYZ], AverageGy[XYZ];
2026-04-23 14:02:03 +08:00
lsm6dsl_fifo_data_level_get(&dev_ctx, &DiffFifo);
if(DiffFifo < ACC_FIFO_WATERMASK) {
2026-04-23 14:02:03 +08:00
return;
}
Sets = DiffFifo / 6;
for(i = 0; i < Sets; i++) {
2026-04-23 14:02:03 +08:00
lsm6dsl_fifo_raw_data_get(&dev_ctx, (uint8_t *)&AccGy, sizeof(AccGy));
Slot = i % ACC_COLL_CNT_MAX; //环形缓存,始终保留最新ACC_COLL_CNT_MAX组
angular_rate_mdps[X][Slot] = lsm6dsl_from_fs500dps_to_mdps(AccGy.GyX);
angular_rate_mdps[Y][Slot] = lsm6dsl_from_fs500dps_to_mdps(AccGy.GyY);
angular_rate_mdps[Z][Slot] = lsm6dsl_from_fs500dps_to_mdps(AccGy.GyZ);
acceleration_mg[X][Slot] = lsm6dsl_from_fs2g_to_mg(AccGy.AccX);
acceleration_mg[Y][Slot] = lsm6dsl_from_fs2g_to_mg(AccGy.AccY);
acceleration_mg[Z][Slot] = lsm6dsl_from_fs2g_to_mg(AccGy.AccZ);
2026-04-23 14:02:03 +08:00
}
Cnt = (Sets >= ACC_COLL_CNT_MAX) ? ACC_COLL_CNT_MAX : (uint8_t)Sets;
AverageGy[X] = IntFilter_Float(angular_rate_mdps[0], Cnt, 0);
AverageGy[Y] = IntFilter_Float(angular_rate_mdps[1], Cnt, 0);
AverageGy[Z] = IntFilter_Float(angular_rate_mdps[2], Cnt, 0);
AverageAcc[X] = IntFilter_Float(acceleration_mg[0], Cnt, 0);
AverageAcc[Y] = IntFilter_Float(acceleration_mg[1], Cnt, 0);
AverageAcc[Z] = IntFilter_Float(acceleration_mg[2], Cnt, 0);
2026-04-23 14:02:03 +08:00
Lsm6dDataProcessCallBack(AverageAcc, AverageGy);
}
static void ReadWakeUpIntStatus(void)
{
lsm6dsl_wake_up_src_t wake_up_src;
if(Lsm6dslWakeupIntFlag) {
Lsm6dslWakeupIntFlag = false;
platform_read(LSM6DSL_WAKE_UP_SRC, (uint8_t *)&wake_up_src, sizeof(lsm6dsl_wake_up_src_t));
}
}
void Lsm6dslLoopHandler(void)
{
ReadWakeUpIntStatus();
if(acc_status != Acc_Get_Data) {
return;
}
if(Lsm6dslRecoverReq) {
Lsm6dslRecoverReq = false;
Lsm6dsl_Config(); //1秒无水印中断,重新配置FIFO/ODR自恢复
Lsm6dslIntWatchdog = 0;
return;
}
if(Lsm6dslWaterMarkFullIntFlag) {
Lsm6dslWaterMarkFullIntFlag = false;
Lsm6dslIntWatchdog = 0;
Acc_IntHandler();
2026-04-23 14:02:03 +08:00
}
}
void Lsm6dsl1mSRoutine(void)
{
if(acc_cvttime > 0)
acc_cvttime--;
if(acc_status == Acc_Get_Data) {
if(Lsm6dslIntWatchdog < 2000)
Lsm6dslIntWatchdog++;
if(Lsm6dslIntWatchdog >= 1000) { //连续1秒无FIFO水印中断
Lsm6dslIntWatchdog = 0;
Lsm6dslRecoverReq = true;
}
}
else {
Lsm6dslIntWatchdog = 0;
}
2026-04-23 14:02:03 +08:00
}
void Lsm6dslInit(void)
{
Lsm6dsl_Init();
}
void Lsm6dsStart(void)
{
if(acc_status == Acc_Get_Data) {
return; //已在连续采集,不重复配置
}
Lsm6dsl_Init(); //配置寄存器并开启连续采集
acc_status = Acc_Get_Data;
2026-04-23 14:02:03 +08:00
}
void Lsm6dsStop(void)
{
lsm6dsl_fifo_mode_set(&dev_ctx, LSM6DSL_BYPASS_MODE);
lsm6dsl_fifo_data_rate_set(&dev_ctx, LSM6DSL_FIFO_DISABLE);
2026-04-23 14:02:03 +08:00
lsm6dsl_xl_data_rate_set(&dev_ctx, LSM6DSL_XL_ODR_OFF);
lsm6dsl_gy_data_rate_set(&dev_ctx, LSM6DSL_GY_ODR_OFF);
acc_status = Acc_Idle;
}
void Lsm6dsInt1CallBack(void)
{
Lsm6dslWaterMarkFullIntFlag = true;
}
void Lsm6dsInt2CallBack(void)
{
Lsm6dslWakeupIntFlag = true;
//Tilt.Acc_IRQ_Status = true;
}