Files
99_7018_lmx/cpu/br28/spatial_effect/spatial_imu_trim.c

419 lines
11 KiB
C
Raw Normal View History

2025-10-29 13:10:02 +08:00
#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*/