Files
99_7018_lmx/cpu/br28/spatial_effect/spatial_imu_trim.c
2025-10-29 13:10:02 +08:00

419 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "spatial_imu_trim.h"
#include "spatial_effect_imu.h"
/* #include "imuSensor_manage.h" */
#include "tech_lib/SpatialAudio_api.h"
#include "tech_lib/SensorCalib_api.h"
#include "system/includes.h"
#include "asm/timer.h"
#include "app_config.h"
#include "task.h"
#include "event.h"
#if TCFG_AUDIO_SPATIAL_EFFECT_ENABLE
/*校准时间配置*/
#define IMU_TRIM_TIME 10
#if TCFG_MPU6887P_ENABLE
/*icm42607p*/
static info_spa_t info_spa = {
.fs = 99.f,
.len = 6,
.sensitivity = 16.4f,
.range = 16,//+-16g量程
};
static spatial_config_t conf = {
.beta = 0.1f,
.cel_val = 0.14f,
.SerialTime = 0.2f,
.time = 1.0f,
.val = 0.02f,
.sensval = 0.01f,
};
#elif TCFG_MPU6887P_ENABLE
/*mpu6887*/
static info_spa_t info_spa = {
.fs = 100.f,
.len = 6,
.sensitivity = 16.4f,
.range = 16,//+-16g量程
};
static spatial_config_t conf = {
.beta = 0.1f,
.cel_val = 0.08f,
.SerialTime = 0.2f,
.time = 1.0f,
.val = 0.02f,
.sensval = 0.01f,
};
#else
/*lsm6dsl*/
static info_spa_t info_spa = {
.fs = 104.f,
.len = 6,
.sensitivity = 14.28f,
.range = 16,
};
static spatial_config_t conf = {
.beta = 0.1f,
.cel_val = 0.12f,
.SerialTime = 0.24f,
.time = 1.f,
.val = 0.02f,
.sensval = 0.01f
};
#endif
static Thval_t Thval = {
.thv1 = 0.85f,
.thv2 = 1.2f,
};
//以上参数取值以实际为例
typedef struct {
acc_cel_t acc_cel;
char *Accbuf;
gyro_cel_t gyro_cel;
char *Gyrobuf;
tranval_t tranval;
s16 in_buf[512];
void *sensor;
} imu_trim_hdl_t;
static imu_trim_hdl_t *imu_trim_hdl = NULL;
/*获取校准传感器的状态
* 0未校准
* 1校准成功
* -1校准中
* -2校准失败
*/
static int global_imu_trim_state = 0;
int get_imu_trim_state()
{
return global_imu_trim_state;
}
typedef struct {
u8 cmd; //命令
u8 magic_code[4]; //"csmr"
u8 data_len; //LTV结构总长度
u8 len0; //L : 数据长度
u8 type0; //T : 数据类型
u8 diaplay[20]; //V : 数据内容
u8 len1; //L : 数据长度
u8 type1; //T : 数据类型
u8 notice; //V : 数据内容
} testbox_data_hdl_t;
static testbox_data_hdl_t testbox_data = {
.cmd = 0x01,
/* .magic_code[] = "csmr", */
.data_len = 25,
.len0 = 21,
.type0 = 0x01, //显示内容
/* .diaplay[20] = " ", */
.len1 = 2,
.type1 = 0x02, //提示音
.notice = 0,
};
static u8 notice_flag = 1;
int testbox_imu_trim_run(u8 *send_buf)
{
int state = get_imu_trim_state();
char csmr[] = "csmr";
char imu_trim_start[] = " trim start !";
char imu_trim_fail[] = " trim fail !";
char imu_trim_succ[] = " trim succ !";
char imu_trim_run[] = " trim run...";
/* printf("state %d", state); */
memcpy(testbox_data.magic_code, csmr, 4);
if (state == 0) {
/*还没有校准时,校准一遍*/
spatial_imu_trim_start();
memcpy(testbox_data.diaplay, imu_trim_start, sizeof(imu_trim_start));
testbox_data.notice = 1; //开始校准 di一声
} else if (state == 1) {
/*校准成功了,不再做校准了*/
memcpy(testbox_data.diaplay, imu_trim_succ, sizeof(imu_trim_succ));
if (notice_flag) {
notice_flag = 0;
testbox_data.notice = 2; //校准成功 didi两声
} else {
testbox_data.notice = 0;
}
} else if (state == -1) {
/*正在校准中*/
putchar('.');
memcpy(testbox_data.diaplay, imu_trim_run, sizeof(imu_trim_run));
testbox_data.notice = 0;
} else if (state == -2) {
/*校准失败*/
memcpy(testbox_data.diaplay, imu_trim_fail, sizeof(imu_trim_fail));
if (notice_flag) {
notice_flag = 0;
testbox_data.notice = 3; //校准失败 dididi三声
} else {
testbox_data.notice = 0;
}
}
memcpy(&send_buf[2], &testbox_data, sizeof(testbox_data_hdl_t));
return sizeof(testbox_data_hdl_t);
}
void testbox_trim_flag_reset()
{
global_imu_trim_state = 0;
notice_flag = 1;
}
/*校准资源初始化*/
static int spatial_imu_trim_init()
{
printf("%sn", __func__);
if (imu_trim_hdl) {
printf("imu trim is alreadly init !!!");
return -1;
}
imu_trim_hdl = zalloc(sizeof(imu_trim_hdl_t));
if (imu_trim_hdl == NULL) {
printf("imu_trim_hdl zalloc fail !!!");
return -1;
}
int Accsize = AccCelBuff();//加速度计校准buf大小
printf("AccCelBuff size %d", Accsize);
imu_trim_hdl->Accbuf = (char *)zalloc(Accsize);
AccCelInit(imu_trim_hdl->Accbuf, &info_spa, IMU_TRIM_TIME);//加速度计校准参数初始化
int Gyrosize = GroCelBuff();//陀螺仪计校准buf大小
printf("GroCelBuff size %d", Accsize);
imu_trim_hdl->Gyrobuf = (char *)zalloc(Gyrosize);
GroCelInit(imu_trim_hdl->Gyrobuf, &info_spa, IMU_TRIM_TIME);//校准参数初始化
/*imu初始化*/
if (imu_trim_hdl->sensor == NULL) {
imu_trim_hdl->sensor = space_motion_detect_open();
}
if (imu_trim_hdl->sensor == NULL) {
printf("sensor open fail !!!");
return -1;
}
global_imu_trim_state = -1;//校准中
return 0;
}
/*重启传感器,等待数据稳定 mpu6887p*/
static int spatial_imu_restart()
{
if (imu_trim_hdl) {
if (imu_trim_hdl->sensor) {
os_time_dly(10);
space_motion_detect_close(imu_trim_hdl->sensor);
imu_trim_hdl->sensor = NULL;
}
/*imu初始化*/
if (imu_trim_hdl->sensor == NULL) {
os_time_dly(10);
imu_trim_hdl->sensor = space_motion_detect_open();
}
}
return 0;
}
/*释放校准资源*/
static int spatial_imu_trim_exit()
{
printf("%s\n", __func__);
if (imu_trim_hdl) {
if (imu_trim_hdl->Accbuf) {
free(imu_trim_hdl->Accbuf);
imu_trim_hdl->Accbuf = NULL;
}
if (imu_trim_hdl->Gyrobuf) {
free(imu_trim_hdl->Gyrobuf);
imu_trim_hdl->Gyrobuf = NULL;
}
if (imu_trim_hdl->sensor) {
space_motion_detect_close(imu_trim_hdl->sensor);
imu_trim_hdl->sensor = NULL;
}
free(imu_trim_hdl);
imu_trim_hdl = NULL;
}
return 0;
}
extern void put_float(double fv);
/*校准传感器*/
static int spatial_imu_trim_acc_gyro()
{
printf("%s\n", __func__);
if (imu_trim_hdl == NULL) {
return 0;
}
int data_len = 0;
int i = 0;
int flag_A = 0;
int flag_G = 0;
int mode = 0;
global_imu_trim_state = -1;//校准中
do {
i = 0;
os_time_dly(10);
data_len = space_motion_data_read(imu_trim_hdl->sensor, imu_trim_hdl->in_buf, 1024);
/* printf("data_len %d", data_len); */
putchar('.');
while (data_len) {
data_len -= 12;
flag_A = Acc_Calibration(imu_trim_hdl->Accbuf,
&imu_trim_hdl->in_buf[i],
&info_spa,
&imu_trim_hdl->acc_cel,
&Thval);
if (flag_A == 1) {
printf("imu_trim_acc succ!!!");
printf("acc_cel:x:");
put_float(imu_trim_hdl->acc_cel.acc_offx);
printf("acc_cel:y:");
put_float(imu_trim_hdl->acc_cel.acc_offy);
printf("acc_cel:z:");
put_float(imu_trim_hdl->acc_cel.acc_offz);
int ret = syscfg_write(CFG_IMU_ACC_OFFEST_ID, &imu_trim_hdl->acc_cel, sizeof(acc_cel_t));
if (ret != sizeof(acc_cel_t)) {
printf("acc_cel write vm fail %d !!!", ret);
}
/* return 0; */
} else if (flag_A == -2) {
printf("imu_trim_acc fail!!!");
global_imu_trim_state = -2;//校准失败
return -2;
}
flag_G = Gro_Calibration(imu_trim_hdl->Gyrobuf,
&imu_trim_hdl->in_buf[i],
&info_spa,
&imu_trim_hdl->tranval,
mode,
&imu_trim_hdl->gyro_cel);//计算mode=0完成陀螺仪校准完成返回0否则返回-1
if (flag_G == mode) {
printf("imu_trim_gyro succ!!!");
printf("gyro_cel:x:");
put_float(imu_trim_hdl->gyro_cel.gyro_x);
printf("gyro_cel:y:");
put_float(imu_trim_hdl->gyro_cel.gyro_y);
printf("gyro_cel:z:");
put_float(imu_trim_hdl->gyro_cel.gyro_z);
int ret = syscfg_write(CFG_IMU_GYRO_OFFEST_ID, &imu_trim_hdl->gyro_cel, sizeof(gyro_cel_t));
if (ret != sizeof(gyro_cel_t)) {
printf("gyro_cel write vm fail %d !!!", ret);
}
global_imu_trim_state = 1;//校准成功
return 0;
} else if (flag_G == -2) {
printf("imu_trim_gyro fail!!!");
global_imu_trim_state = -2;//校准失败
return -2;
}
global_imu_trim_state = -1;//校准中
i += 6;
}
} while (1);
return 0;
}
/*开始校准*/
int spatial_imu_trim_start()
{
struct sys_event e;
e.type = SYS_AUD_EVENT;
e.arg = (void *)AUDIO_EVENT_TRIM_IMU_START;
sys_event_notify(&e);
}
/*关闭校准*/
int spatial_imu_trim_stop()
{
struct sys_event e;
e.type = SYS_AUD_EVENT;
e.arg = (void *)AUDIO_EVENT_TRIM_IMU_STOP;
sys_event_notify(&e);
}
/*校准任务*/
static void spatial_imu_trim_task(void *p)
{
int ret = 0;
/*初始化传感器*/
ret = spatial_imu_trim_init();
if (ret != 0) {
global_imu_trim_state = -2;//校准失败
goto err0;
}
/*等待传感器数据稳定*/
spatial_imu_restart();
/*校准传感器*/
ret = spatial_imu_trim_acc_gyro();
/*判断是否校准成功0校准成功-2校准失败*/
if (ret == -2) {
global_imu_trim_state = -2;//校准失败
}
err0 :
/*关闭传感器*/
spatial_imu_trim_exit();
/*关闭校准任务*/
spatial_imu_trim_stop();
}
/*创建校准任务*/
int spatial_imu_trim_task_start()
{
int err = 0;
err = task_create(spatial_imu_trim_task, imu_trim_hdl, "imu_trim");
if (err != OS_NO_ERR) {
printf("imu_trim task create fail : %d !!!", err);
}
return err;
}
/*删除校准任务和校准资源*/
int spatial_imu_trim_task_stop()
{
int err = 0;
err = task_kill("imu_trim");
if (err != OS_NO_ERR) {
printf("imu_trim task kill fail : %d !!!", err);
}
/*释放校准资源*/
spatial_imu_trim_exit();
return err;
}
static u8 spatial_imu_trim_idle_query(void)
{
return ((imu_trim_hdl == NULL) ? 1 : 0);
}
REGISTER_LP_TARGET(spatial_imu_trim_lp_target) = {
.name = "spatial_imu_trim",
.is_idle = spatial_imu_trim_idle_query,
};
#endif /*TCFG_AUDIO_SPATIAL_EFFECT_ENABLE*/