#include "app_config.h"
#include "asm/clock.h"
#include "asm/cpu.h"
#include "generic/typedef.h"
#include "generic/gpio.h"
#include "mpu9250.h"
#include "typedef.h"
#include "system/includes.h"
#include "media/includes.h"
#include "asm/iic_hw.h"
#include "asm/iic_soft.h"
#include "asm/timer.h"
#include "imuSensor_manage.h"

#if TCFG_TP_MPU9250_ENABLE

#undef LOG_TAG_CONST
#define LOG_TAG     "[mpu9250]"
#define LOG_ERROR_ENABLE
#define LOG_INFO_ENABLE
#include "debug.h"

#if TCFG_MPU9250_USER_IIC_TYPE
#define iic_init(iic)                       hw_iic_init(iic)
#define iic_uninit(iic)                     hw_iic_uninit(iic)
#define iic_start(iic)                      hw_iic_start(iic)
#define iic_stop(iic)                       hw_iic_stop(iic)
#define iic_tx_byte(iic, byte)              hw_iic_tx_byte(iic, byte)
#define iic_rx_byte(iic, ack)               hw_iic_rx_byte(iic, ack)
#define iic_read_buf(iic, buf, len)         hw_iic_read_buf(iic, buf, len)
#define iic_write_buf(iic, buf, len)        hw_iic_write_buf(iic, buf, len)
#define iic_suspend(iic)                    hw_iic_suspend(iic)
#define iic_resume(iic)                     hw_iic_resume(iic)
#else
#define iic_init(iic)                       soft_iic_init(iic)
#define iic_uninit(iic)                     soft_iic_uninit(iic)
#define iic_start(iic)                      soft_iic_start(iic)
#define iic_stop(iic)                       soft_iic_stop(iic)
#define iic_tx_byte(iic, byte)              soft_iic_tx_byte(iic, byte)
#define iic_rx_byte(iic, ack)               soft_iic_rx_byte(iic, ack)
#define iic_read_buf(iic, buf, len)         soft_iic_read_buf(iic, buf, len)
#define iic_write_buf(iic, buf, len)        soft_iic_write_buf(iic, buf, len)
#define iic_suspend(iic)                    soft_iic_suspend(iic)
#define iic_resume(iic)                     soft_iic_resume(iic)
#endif

static mpu9250_param *mpu9250_iic_info;
static mpu9250_data mpu9250_raw_data = {0};


#define MPU9250_INT_IO		(-1)//TCFG_TP_INT_IO //pg5
/* #define MPU9250_INT_IO		IO_PORTA_04 */
/* #define MPU9250_NCS_IO		IO_PORTA_05 */
/* #define MPU9250_FSYNC_IO	IO_PORTA_05 */
#define MPU9250_INT_R()   gpio_read(MPU9250_INT_IO)
static u8 mpu9250_int_pin = MPU9250_INT_IO;
static u8 mpu_i2c_buf_write(u8 slave_addr, u8 reg_addr,  u8 *buf, u8 len)
{
    u8 i;
    iic_start(mpu9250_iic_info->iic_hdl);
    if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, slave_addr)) {
        iic_stop(mpu9250_iic_info->iic_hdl);
        return 0;
    }
    udelay(mpu9250_iic_info->iic_delay);
    if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, reg_addr)) {
        iic_stop(mpu9250_iic_info->iic_hdl);
        return 0;
    }

    for (i = 0; i < len; i++) {
        udelay(mpu9250_iic_info->iic_delay);
        if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, buf[i])) {
            iic_stop(mpu9250_iic_info->iic_hdl);
            return 0;
        }
    }
    iic_stop(mpu9250_iic_info->iic_hdl);
    return i;
}


static u8 mpu_i2c_buf_read(u8 slave_addr, u8 reg_addr, u8 *buf, u8 len)
{
    u8 i;
    iic_start(mpu9250_iic_info->iic_hdl);
    if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, slave_addr)) {
        iic_stop(mpu9250_iic_info->iic_hdl);
        return 0;
    }
    udelay(mpu9250_iic_info->iic_delay);
    if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, reg_addr)) {
        iic_stop(mpu9250_iic_info->iic_hdl);
        return 0;
    }
    udelay(mpu9250_iic_info->iic_delay);

    iic_start(mpu9250_iic_info->iic_hdl);
    if (0 == iic_tx_byte(mpu9250_iic_info->iic_hdl, slave_addr + 1)) {
        iic_stop(mpu9250_iic_info->iic_hdl);
        return 0;
    }
    for (i = 0; i < len; i++) {
        udelay(mpu9250_iic_info->iic_delay);
        if (i == (len - 1)) {
            *buf++ = iic_rx_byte(mpu9250_iic_info->iic_hdl, 0);
        } else {
            *buf++ = iic_rx_byte(mpu9250_iic_info->iic_hdl, 1);
        }
    }
    iic_stop(mpu9250_iic_info->iic_hdl);

    return i;
}

//设置MPU9250陀螺仪传感器满量程范围
//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
//返回值:1,设置成功
//    0,设置失败
u8 mpu6500_set_full_scale_gyro_range(u8 fsr)//0x1b(bit34)
{
    u8 res = 0;
    u8 temp_data = 0;
    fsr &= 0x3;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_GYRO_CFG_REG, &temp_data, 1);
    if (res == 1) {
        if (((temp_data & 0x18) >> 3) != fsr) {
            SFR(temp_data, 3, 2, fsr);
            res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_GYRO_CFG_REG, &temp_data, 1);
        }
    }
    return res;
}
//设置MPU9250加速度传感器满量程范围
//fsr:0,±2g;1,±4g;2,±8g;3,±16g
//返回值:1,设置成功
//    0,设置失败
u8 mpu6500_set_full_scale_accel_range(u8 fsr)//0x1c(bit34)
{
    u8 res = 0;
    u8 temp_data = 0;
    fsr &= 0x3;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_ACCEL_CFG_REG, &temp_data, 1);
    if (res == 1) {
        if (((temp_data & 0x18) >> 3) != fsr) {
            SFR(temp_data, 3, 2, fsr);
            res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_ACCEL_CFG_REG, &temp_data, 1);
        }
    }
    return res;
}

/**
 *For the DLPF to be used, fchoice[1:0] must be set to 2’b11, fchoice_b[1:0] is 2’b00.
 See table 3 below.
The DLPF is configured by DLPF_CFG, when FCHOICE_B [1:0] = 2b’00. The gyroscope and
temperature sensor are filtered according to the value of DLPF_CFG and FCHOICE_B as shown in the table below. Note that FCHOICE mentioned in the table below is the inverted value of FCHOICE_B (e.g. FCHOICE=2b’00 is same as FCHOICE_B=2b’11).

//设置MPU9250gyroscope and temperature sensor的数字低通滤波器
//lpf:数字低通滤波频率(Hz)
//返回值:1,设置成功
//    0,设置失败
 * */
u8 mpu_set_dlpf(u16 lpf)//0x1a(bit012)
{
    u8 data = 0;
    if (lpf >= 188) {
        data = 1;
    } else if (lpf >= 98) {
        data = 2;
    } else if (lpf >= 42) {
        data = 3;
    } else if (lpf >= 20) {
        data = 4;
    } else if (lpf >= 10) {
        data = 5;
    } else {
        data = 6;
    }

    u8 res = 0;
    u8 temp_data = 0;
    data &= 0x07;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_CFG_REG, &temp_data, 1);
    if (res == 1) {
        if ((temp_data & 0x07) != data) {
            temp_data &= ~0x07;
            temp_data |= data;
            res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_CFG_REG, &temp_data, 1); //设置数字低通滤波器
        }
    }
    return res;
}

/*
 *Divides the internal sample rate (see register CONFIG) to generate the
 sample rate that controls sensor data output rate, FIFO sample rate.
NOTE: This register is only effective when Fchoice = 2’b11 (fchoice_b
register bits are 2’b00), and (0 < dlpf_cfg < 7), such that the average filter’s
output is selected (see chart below).
This is the update rate of sensor register.
	SAMPLE_RATE= Internal_Sample_Rate / (1 + SMPLRT_DIV)
Data should be sampled at or above sample rate; SMPLRT_DIV is only used for1kHz internal sampling.
//rate:4~1000(Hz)
//设置mpu9250gyroscope的采样率(假定 Fs=1KHz)
//返回值:1,设置成功
//    0,设置失败
 * */  //0x19
u8 mpu_set_rate(u16 rate)// 设置采样速率: 1000 / (1 + rate)
{
    u8 data;
    if (rate > 1000) {
        rate = 1000;
    }
    if (rate < 4) {
        rate = 4;
    }
    data = 1000 / rate - 1;
    mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_SAMPLE_RATE_REG, &data, 1);	//设置数字低通滤波器
    /* return mpu_set_dlpf(rate/2);	//自动设置LPF为采样率的一半 */
    return mpu_set_dlpf(98);
}

bool mpu6500_set_sleep_enabled(u8 enable);// 唤醒MPU6500
//返回值:1,成功
//    0,错误代码
u8 mpu9250_init1(void *param)//bypass模式读取ak8963数据
{
    u8 res = 0, temp_data = 0;
    if (param == NULL) {
        log_info("mpu9250 init fail(no param)\n");
        return false;
    }
    mpu9250_iic_info = (mpu9250_param *)param;

    temp_data = 0X80;
    mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1); //复位MPU9250
    mdelay(100);  //延时100ms
    temp_data = 0X00;
    mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1); //唤醒MPU9250
    mdelay(10);  //延时
    mpu6500_set_full_scale_gyro_range(MPU6500_GYRO_FS_2000);//陀螺仪传感器,±2000dps
    mpu6500_set_full_scale_accel_range(0);					       	 	//加速度传感器,±2g
    mpu_set_rate(50);						       	 	//设置采样率50Hz
    mpu6500_set_sleep_enabled(false);	// 唤醒MPU6500
    temp_data = 0X00;
    mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INT_EN_REG, &temp_data, 1); //关闭所有中断
    temp_data = 0X00;
    mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_USER_CTRL_REG, &temp_data, 1); //I2C主模式关闭
    temp_data = 0X00;
    mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_FIFO_EN_REG, &temp_data, 1);	//关闭FIFO
    temp_data = 0X82;
    mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INTBP_CFG_REG, &temp_data, 1); //INT引脚低电平有效，开启bypass模式，可以直接读取磁力计
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_DEVICE_ID_REG, &temp_data, 1); //读取MPU6500的ID
    if (temp_data == 0x71) { //器件ID正确
        log_info("read mpu id:0x%x", temp_data);
        temp_data = 0X01;
        mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);  	//设置CLKSEL,PLL X轴为参考
        temp_data = 0X00;
        mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT2_REG, &temp_data, 1);  	//加速度与陀螺仪都工作
        mpu_set_rate(50);						       	//设置采样率为50Hz
    } else {
        log_error("read mpu id(0x%x) fail!", temp_data);
        return false;
    }

    res = mpu_i2c_buf_read(MAG_IIC_ADDRESS_W, MAG_WHO_AM_I, &temp_data, 1);    			//读取AK8963 ID
    if (temp_data == 0x48) {
        log_info("read mag id:0x%x", temp_data);
        temp_data = 0X11;
        mpu_i2c_buf_write(MAG_IIC_ADDRESS_W, MAG_CNTL_1, &temp_data, 1);		//设置AK8963为单次测量模式
    } else {
        log_error("read mag id(0x%x) fail!", temp_data);
        /* return false; */
    }
    return true;
}

//得到温度值
//temp温度值
//返回值:2,成功
//    其他,错误代码
u8 mpu_get_temperature(float *temp)
{
    u8 buf[2], res;
    short raw;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_TEMP_OUTH_REG, buf, 2);
    if (res == 2) {
        raw = ((s16)buf[0] << 8) | buf[1];
        *temp = 21 + (raw) / 333.87;
    }
    return res;
}
//得到陀螺仪值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:6,成功
//    其他,错误代码
u8 mpu_get_gyroscope(short *gx, short *gy, short *gz)
{
    u8 buf[6], res;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_GYRO_XOUTH_REG, buf, 6);
    if (res == 6) {
        *gx = ((u16)buf[0] << 8) | buf[1];
        *gy = ((u16)buf[2] << 8) | buf[3];
        *gz = ((u16)buf[4] << 8) | buf[5];
    }
    return res;
}
//得到加速度值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:6,成功
//    其他,错误代码
u8 mpu_get_accelerometer(short *ax, short *ay, short *az)
{
    u8 buf[6], res;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_ACCEL_XOUTH_REG, buf, 6);
    if (res == 6) {
        *ax = ((u16)buf[0] << 8) | buf[1];
        *ay = ((u16)buf[2] << 8) | buf[3];
        *az = ((u16)buf[4] << 8) | buf[5];
    }
    return res;
}

//得到磁力计值(原始值)
//mx,my,mz:磁力计x,y,z轴的原始读数(带符号)
//返回值:6,成功
//    其他,错误代码
u8 mpu_get_magnetometer(short *mx, short *my, short *mz)
{
    u8 buf[6], res;
    res = mpu_i2c_buf_read(MAG_IIC_ADDRESS_W, MAG_XOUT_L, buf, 6);
    if (res == 6) {
        *mx = ((u16)buf[1] << 8) | buf[0];
        *my = ((u16)buf[3] << 8) | buf[2];
        *mz = ((u16)buf[5] << 8) | buf[4];
    }
    buf[0] = 0X11;
    mpu_i2c_buf_write(MAG_IIC_ADDRESS_W, MAG_CNTL_1, buf, 1); //AK8963每次读完以后都需要重新设置为单次测量模式
    return res;
}

//iic scl:<=400KHz


#if 0

static mpu9250_param mpu9250_iic_info_test1 = {
    .iic_hdl = 0,
    .iic_delay = 0, //字节间延时，单位us
};

void mpu9250_test1()
{
    iic_init(mpu9250_iic_info_test1.iic_hdl);
    gpio_set_direction(mpu9250_int_pin, 1);
    gpio_set_die(mpu9250_int_pin, 1);
    /* gpio_set_pull_up(mpu9250_int_pin, 1); */
    /* gpio_set_pull_down(mpu9250_int_pin, 0); */

    if (mpu9250_init1(&mpu9250_iic_info_test1)) {
        log_info("mpu9250 Device init pass!\n");

        while (1) {
            mpu_get_temperature(&mpu9250_raw_data.temp_data);
            mpu_get_gyroscope(&mpu9250_raw_data.gyro_data.x_data, &mpu9250_raw_data.gyro_data.y_data, &mpu9250_raw_data.gyro_data.z_data);
            mpu_get_accelerometer(&mpu9250_raw_data.accel_data.x_data, &mpu9250_raw_data.accel_data.y_data, &mpu9250_raw_data.accel_data.z_data);
            mpu_get_magnetometer(&mpu9250_raw_data.mag_data.x_data, &mpu9250_raw_data.mag_data.y_data, &mpu9250_raw_data.mag_data.z_data);
            log_info("mpu9250_raw_data.accel_data:X:%d,Y:%d,Z:%d", mpu9250_raw_data.accel_data.x_data, mpu9250_raw_data.accel_data.y_data, mpu9250_raw_data.accel_data.z_data);
            log_info("mpu9250_raw_data.gyro_data:X:%d,Y:%d,Z:%d", mpu9250_raw_data.gyro_data.x_data, mpu9250_raw_data.gyro_data.y_data, mpu9250_raw_data.gyro_data.z_data);
            log_info("mpu9250_raw_data.mag_data:X:%d,Y:%d,Z:%d", mpu9250_raw_data.mag_data.x_data, mpu9250_raw_data.mag_data.y_data, mpu9250_raw_data.mag_data.z_data);
            log_info("mpu9250_raw_data.temp_data:%d", (s16)mpu9250_raw_data.temp_data);
            wdt_clear();
            mdelay(10);
        }
    } else {
        log_info("mpu9250 Device init fail!\n");
    }
}

#endif




/******************************mpu6500 config****************************/
//return:1:ok, 0:fail
bool mpu6500_reset()// 复位MPU6500
{
    u8 res = 0;
    u8 temp_data = 0;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
    if (res == 1) {
        temp_data |= BIT(7);
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
    }
    return res;
}
//return:1:ok, 0:fail
bool mpu6500_set_sleep_enabled(u8 enable)// 唤醒MPU6500
{
    u8 res = 0;
    u8 temp_data = 0;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
    if (res == 1) {
        if (enable) {
            temp_data |= BIT(6);
        } else {
            temp_data &= ~ BIT(6);
        }
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
    }
    return res;
}

/** Set clock source setting.
 * An internal 8MHz oscillator, gyroscope based clock, or external sources c&= ~ * be selected as the MPU-60X0 clock source. When the internal 8 MHz oscillat|= * or an external source is chosen as the clock source, the MPU-60X0 can operate in low power modes with the gyroscopes disabled.
 *
 * Upon power up, the MPU-60X0 clock source defaults to the internal oscillator.
 * However, it is highly recommended that the device be configured to use one of the gyroscopes (or an external clock source) as the clock reference f|= * improved stability. The clock source can be selected according to the following table:
 * CLK_SEL | Clock Source
 * --------+--------------------------------------
 * 0       | Internal oscillat|= * 1       | PLL with X Gyro reference
 * 2       | PLL with Y Gyro reference
 * 3       | PLL with Z Gyro reference
 * 4       | PLL with external 32.768kHz reference
 * 5       | PLL with external 19.2MHz reference
 * 6       | Reserved
 * 7       | Stops the clock and keeps the timing generator in reset
 * */
//return:1:ok, 0:fail
bool mpu6500_set_clocksource(u8 clocksource)// 设置X轴陀螺作为时钟
{
    u8 res = 0;
    u8 temp_data = 0;
    clocksource &= 0x07;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
    if (res == 1) {
        if ((temp_data & 0x07) != clocksource) {
            temp_data &= ~0x07;
            temp_data |= clocksource;
            res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
        }
    }
    return res;
}

//return:1:ok, 0:fail
bool mpu6500_set_temp_enabled(u8 enable)// 使能温度传感器
{
    u8 res = 0;
    u8 temp_data = 0;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
    if (res == 1) {
        if (enable) {
            temp_data &= ~ BIT(3);
        } else {
            temp_data |= BIT(3);
        }
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_PWR_MGMT1_REG, &temp_data, 1);
    }
    return res;
}

//return:1:ok, 0:fail
bool mpu6500_set_int_enabled(u8 int_data)// 关闭中断
{
    u8 res = 0;
    u8 temp_data = int_data;
    res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INT_EN_REG, &temp_data, 1);
    return res;
}
//return:1:ok, 0:fail
//数据就绪中断使能
// This event occurs each time a write operation to all of the sensor registers has been completed. Will be set 0 for disabled, 1 for enabled.
bool mpu6500SetIntDataReadyEnabled(u8 enable)//0x38(bit0)
{
    u8 res = 0;
    u8 temp_data = 0;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_INT_EN_REG, &temp_data, 1);
    if (res == 1) {
        if (enable) {
            temp_data |= BIT(0);
        } else {
            temp_data &= ~ BIT(0);
        }
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INT_EN_REG, &temp_data, 1);
    }
    return res;
}

//return:1:ok, 0:fail
bool mpu6500_set_iic_MST_enabled(u8 enable)//I2C主模式开关
{
    u8 res = 0;
    u8 temp_data = 0;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_USER_CTRL_REG, &temp_data, 1);
    if (res == 1) {
        if (enable) {
            temp_data |= BIT(5);
        } else {
            temp_data &= ~ BIT(5);
        }
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_USER_CTRL_REG, &temp_data, 1);
    }
    return res;
}

//return:1:ok, 0:fail
// I2C_MST_EN (Register 106 bit[5]) has to be equal to 0
// 1:旁路模式，磁力计和其它连接到主IIC ; 0:主机模式
bool mpu6500_set_iic_bypass_enabled(u8 enable)//0x37(bit1)
{
    u8 res = 0;
    u8 temp_data = 0;
    /* mpu6500_set_iic_MST_enabled(false)//I2C主模式关 */
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_INTBP_CFG_REG, &temp_data, 1);
    if (res == 1) {
        if (enable) {
            temp_data |= BIT(1);
        } else {
            temp_data &= ~ BIT(1);
        }
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INTBP_CFG_REG, &temp_data, 1);
    }
    return res;
}

//默认0x00:rate4k
//return:1:ok, 0:fail
bool mpu6500_set_accel_DLPF(u8 dlpf_data)// 设置加速计数字低通滤波
{
    u8 res = 0;
    u8 temp_data = 0;
    dlpf_data &= 0x07;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_ACCEL_CFG_REG_2, &temp_data, 1);
    if (res == 1) {
        if ((temp_data & 0x07) != dlpf_data) {
            temp_data &= ~0x07;
            temp_data |= dlpf_data;
            temp_data |= BIT(3);//bit3=1,dlpf才才有效
            res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_ACCEL_CFG_REG_2, &temp_data, 1);
        }
    }
    return res;
}


//return:1:ok, 0:fail
// 从机读取速率: 100Hz = (1000Hz / (1 + slave_delay))
bool mpu6500SetSlave4MasterDelay(u8 slave_delay)//0x34(bit0~4)
{
    u8 res = 0;
    u8 temp_data = 0;
    slave_delay &= 0x1f;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CSLV4_CTRL_REG, &temp_data, 1);
    if (res == 1) {
        if ((temp_data & 0x1f) != slave_delay) {
            temp_data &= ~0x1f;
            temp_data |= slave_delay;
            res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CSLV4_CTRL_REG, &temp_data, 1);
        }
    }
    return res;
}

//return:1:ok, 0:fail
//Set wait-for-external-sensor-data enabled value.
bool mpu6500SetWaitForExternalSensorEnabled(u8 enable)//0x24(bit6)
{
    u8 res = 0;
    u8 temp_data = 0;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
    if (res == 1) {
        if (enable) {
            temp_data |= BIT(6);
        } else {
            temp_data &= ~ BIT(6);
        }
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
    }
    return res;
}

//return:1:ok, 0:fail
//This bit controls the I2C Master’s transition from one slave read to the next
//slave read. If 0, there is a restart between reads. If 1, there is a stop between
//reads.
bool mpu6500SetSlaveReadWriteTransitionEnabled(u8 enable)
{
    u8 res = 0;
    u8 temp_data = 0;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
    if (res == 1) {
        if (enable) {
            temp_data |= BIT(4);
        } else {
            temp_data &= ~ BIT(4);
        }
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
    }
    return res;
}

//return:1:ok, 0:fail
//Set I2C master clock speed.
bool mpu6500SetMasterClockSpeed(u8 iic_master_rate)
{
    u8 res = 0;
    u8 temp_data = 0;
    iic_master_rate &= 0x0f;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
    if (res == 1) {
        temp_data &= ~ 0x0f;
        temp_data |= iic_master_rate;
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CMST_CTRL_REG, &temp_data, 1);
    }
    return res;
}

//return:1:ok, 0:fail
//bit7: Set interrupt logic level mode.(0=active-high, 1=active-low)
//bit6: Set interrupt drive mode.(0=push-pull, 1=open-drain)
//bit5: Set interrupt latch mode.(0=50us-pulse, 1=latch-until-int-cleared)
//bit4: Set interrupt latch clear mode.(0=status-read-only, 1=any-register-read)
bool mpu6500SetInterruptMode(u8 int_cfg)
{
    u8 res = 0;
    u8 temp_data = 0;
    int_cfg &= 0xf0;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_INTBP_CFG_REG, &temp_data, 1);
    if (res == 1) {
        temp_data &= ~ 0xf0;
        temp_data |= int_cfg;
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_INTBP_CFG_REG, &temp_data, 1);
    }
    return res;
}

//return:1:ok, 0:fail
bool mpu6500SetSlaveAddress(u8 num, u8 addr)
{
    u8 temp_data = 0;
    if (num > 3) {
        return false;
    }
    temp_data = addr;
    return mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CSLV0_ADDR_REG + num * 3, &temp_data, 1);
}
//return:1:ok, 0:fail
bool mpu6500SetSlaveRegister(u8 num, u8 reg)
{
    u8 temp_data = 0;
    if (num > 3) {
        return false;
    }
    temp_data = reg;
    return mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CSLV0_REG + num * 3, &temp_data, 1);
}
//return:1:ok, 0:fail
bool mpu6500SetSlaveDataLength(u8 num, u8 length)
{
    u8 res = 0;
    u8 temp_data = 0;
    if (num > 3) {
        return false;
    }
    length &= 0x0f;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CSLV0_CTRL_REG + num * 3, &temp_data, 1);
    if (res == 1) {
        temp_data &= ~ 0x0f;
        temp_data |= length;
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CSLV0_CTRL_REG + num * 3, &temp_data, 1);
    }
    return res;
}
//return:1:ok, 0:fail
bool mpu6500SetSlaveEnabled(u8 num, u8 enable)
{
    u8 res = 0;
    u8 temp_data = 0;
    if (num > 3) {
        return false;
    }
    enable &= 0x0f;
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CSLV0_CTRL_REG + num * 3, &temp_data, 1);
    if (res == 1) {
        if (enable) {
            temp_data |= BIT(7);
        } else {
            temp_data &= ~ BIT(7);
        }
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CSLV0_CTRL_REG + num * 3, &temp_data, 1);
    }
    return res;
}

//return:1:ok, 0:fail
bool mpu6500SetSlaveDelayEnabled(u8 num, u8 enable)
{
    u8 res = 0;
    u8 temp_data = 0;
    if (num > 4) {
        return false;
    }
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_I2CMST_DELAY_REG, &temp_data, 1);
    if (res == 1) {
        if (enable) {
            temp_data |= BIT(num);
        } else {
            temp_data &= ~ BIT(num);
        }
        res = mpu_i2c_buf_write(MPU9250_ADDRESS_W, MPU_I2CMST_DELAY_REG, &temp_data, 1);
    }
    return res;
}

/*设置传感器从模式读取*/
static void sensors_setup_slave_read(void)
{
    mpu6500SetSlave4MasterDelay(9);// 从机读取速率: 100Hz = (1000Hz / (1 + 9))//zxb

    mpu6500_set_iic_bypass_enabled(false);	//主机模式
    mpu6500SetWaitForExternalSensorEnabled(true);
    mpu6500SetInterruptMode(0x90);//中断低电平有效 推挽输出 中断锁存模式(0=50us-pulse) 中断清除模式(1=any-register-read)
    mpu6500SetSlaveReadWriteTransitionEnabled(false); // 关闭从机间读写结束位的传输
    mpu6500SetMasterClockSpeed(13); 	// 设置i2c速度400kHz

#if MAG_AK8963_ENABLE
    // 设置MPU6500主机要读取的寄存器
    mpu6500SetSlaveAddress(0, 0x80 | MAG_IIC_ADDRESS); 	// 设置磁力计为0号从机
    mpu6500SetSlaveRegister(0, MAG_STATE_1); 			// 从机0需要读取的寄存器
    mpu6500SetSlaveDataLength(0, SENSORS_MAG_BUFF_LEN); // 读取8个字节(ST1, x, y, z heading, ST2 (overflow check))
    mpu6500SetSlaveDelayEnabled(0, true);
    mpu6500SetSlaveEnabled(0, true);
#endif
    mpu6500_set_iic_MST_enabled(true);	//使能mpu6500主机模式
    mpu6500SetIntDataReadyEnabled(true);	//数据就绪中断使能
}



/******************************ak8963 config****************************/
//return:1:ok, 0:fail
bool ak8963_check_connection()
{
    u8 res = 0;
    u8 temp_data = 0;
    mpu_i2c_buf_read(MAG_IIC_ADDRESS_W, MAG_WHO_AM_I, &temp_data, 1); //读取AK8963 ID
    if (temp_data == 0x48) {
        log_info("read mag id:0x%x ok!", temp_data);
    } else {
        log_error("read mag id(0x%x) fail!", temp_data);
        return false;
    }
    return true;

}
/* bool ak8963_check_connection() */
/* { */
/* 	u8 res=0; */
/* 	u8 temp_data=0; */
/* 	while(1){ */
/* 		if(res==0xfe)return false; */
/* 		mpu_i2c_buf_read(res,MAG_WHO_AM_I,&temp_data,1); //读取AK8963 ID */
/* 		if(temp_data==0x48) */
/* 		{ */
/* 			log_info("read mag id:0x%x ok!",temp_data); */
/* 		}else { */
/* 			log_error("read mag id(0x%x) fail!",temp_data); */
/* 			res +=2; */
/* 			temp_data=0; */
/* 			#<{(| return false; |)}># */
/* 		} */
/* 		mdelay(10); */
/* 	} */
/* 	return true; */
/*  */
/* } */

//return:1:ok, 0:fail
bool ak8963_set_mode(u8 data)
{
    u8 temp_data = data;
    return mpu_i2c_buf_write(MAG_IIC_ADDRESS_W, MAG_CNTL_1, &temp_data, 1);
}

//return:1:ok, 0:fail
bool ak8963Reset()
{
    u8 res = 0;
    u8 temp_data = 0;
    res = mpu_i2c_buf_read(MAG_IIC_ADDRESS_W, MAG_CNTL_1, &temp_data, 1);
    if (res == 1) {
        temp_data &= ~0x0f;
        res = mpu_i2c_buf_write(MAG_IIC_ADDRESS_W, MAG_CNTL_1, &temp_data, 1);
    }
    return res;
}


bool mpu9250_init2(void *param)//主模式获取ak8963
{
    u8 res = 0, temp_data = 0;
    if (param == NULL) {
        log_info("mpu9250 init fail(no param)\n");
        return false;
    }
    mpu9250_iic_info = (mpu9250_param *)param;

    mdelay(10);
    mpu6500_reset();	// 复位MPU6500
    mdelay(20);
    res = mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_DEVICE_ID_REG, &temp_data, 1); //读取MPU6500的ID
    if (temp_data == 0x71) { //器件ID正确
        log_info("read mpu id:0x%x ok!", temp_data);
    } else {
        log_error("read mpu id(0x%x) fail!", temp_data);
        return false;
    }
    mpu6500_set_sleep_enabled(false);	// 唤醒MPU6500
    mdelay(10);
    mpu6500_set_clocksource(MPU6500_CLOCK_PLL_XGYRO);// 设置X轴陀螺作为时钟
    mdelay(10);// 延时等待时钟稳定
    mpu6500_set_temp_enabled(true);// 使能温度传感器
    mpu6500_set_int_enabled(0x00);// 关闭中断

    mpu6500_set_iic_MST_enabled(false);//I2C主模式关//zxb
    mpu6500_set_iic_bypass_enabled(true);// 旁路模式，磁力计和气压连接到主IICnot sure//zxb

    mpu6500_set_full_scale_gyro_range(MPU6500_GYRO_FS_2000);	// 设置陀螺量程
    mpu6500_set_full_scale_accel_range(MPU6500_ACCEL_FS_16);// 设置加速计量程
    /* mpu6500_set_accel_DLPF(MPU6500_ACCEL_DLPF_BW_41);		// 设置加速计数字低通滤波 */

    mpu_set_rate(MPU6500_DATA_SAMPLE_RATE);//设置采样速率: 1000Hz(max)//zxb

#if MAG_AK8963_ENABLE
    if (ak8963_check_connection() == true) {
        ak8963_set_mode(AK8963_MODE_16BIT | AK8963_MODE_CONT2); // 16bit 100Hz
        log_info("AK8963 I2C connection [OK].\n");
    }	else {
        log_error("AK8963 I2C connection [FAIL].\n");
        return false;
    }
#endif

//外部中断
    mdelay(150);
    sensors_setup_slave_read();
    return true;
}



static mpu9250_param mpu9250_info_data;
volatile u8 mpu9250_int_flag = 0;
#if MAG_AK8963_ENABLE
#define SENSORS_MPU_BUFF_LEN (SENSORS_MPU6500_BUFF_LEN + SENSORS_MAG_BUFF_LEN)
#else
#define SENSORS_MPU_BUFF_LEN SENSORS_MPU6500_BUFF_LEN
#endif
u8 read_mpu_buf[SENSORS_MPU_BUFF_LEN];

void mpu9250_int_callback()
{
    mpu9250_int_flag = 1;
    mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_ACCEL_XOUTH_REG, read_mpu_buf, SENSORS_MPU_BUFF_LEN);
#if 1
    s16 x = 0, y = 0, z = 0;
    if (mpu9250_int_flag) {/*{{{*/
        x = (((s16) read_mpu_buf[0]) << 8) | read_mpu_buf[1];
        y = ((((s16) read_mpu_buf[2]) << 8) | read_mpu_buf[3]);
        z = (((s16) read_mpu_buf[4]) << 8) | read_mpu_buf[5];
        log_info("mpu9250_raw_data.accel_data:X:%d,Y:%d,Z:%d", x, y, z);
        x = (((s16) read_mpu_buf[8]) << 8) | read_mpu_buf[9];
        y = (((s16) read_mpu_buf[10]) << 8) | read_mpu_buf[11];
        z = (((s16) read_mpu_buf[12]) << 8) | read_mpu_buf[13];
        log_info("mpu9250_raw_data.gyro_data:X:%d,Y:%d,Z:%d", x, y, z);
#if MAG_AK8963_ENABLE
        if (read_mpu_buf[0 + SENSORS_MPU6500_BUFF_LEN]&BIT(0)) {
            x = (((s16) read_mpu_buf[2 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[1 + SENSORS_MPU6500_BUFF_LEN ];
            y = (((s16) read_mpu_buf[4 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[3 + SENSORS_MPU6500_BUFF_LEN ];
            z = (((s16) read_mpu_buf[6 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[5 + SENSORS_MPU6500_BUFF_LEN ];
            log_info("mpu9250_raw_data.mag_data:X:%d,Y:%d,Z:%d", x, y, z);
        }
#endif
        x = (((s16) read_mpu_buf[6]) << 8) | read_mpu_buf[7];
        x = 21 + (s16)((float)(x) / 333.87);
        log_info("mpu9250_raw_data.temp_data:%d", x);

        mpu9250_int_flag = 0;
    }/*}}}*/
#endif

}

u8 mpu9250_dev_init(void *arg)
{
    if (arg == NULL) {
        log_error("mpu9250 init fail(no arg)\n");
        return 0;
    }
#if 1//MPU9250_USER_INTERFACE_I2C
    mpu9250_info_data.iic_hdl = ((struct imusensor_platform_data *)arg)->peripheral_hdl;
    mpu9250_info_data.iic_delay = ((struct imusensor_platform_data *)arg)->peripheral_param0;   //这个延时并非影响iic的时钟频率，而是2Byte数据之间的延时
    // u8 iic_clk;      //iic_clk: <=400kHz
#else
    mpu9250_info_data.spi_hdl = ((struct imusensor_platform_data *)arg)->peripheral_hdl,     //SPIx (role:master)
                      mpu9250_info_data.spi_cs_pin = ((struct imusensor_platform_data *)arg)->peripheral_param0; //IO_PORTA_05
    mpu9250_info_data.spi_work_mode = ((struct imusensor_platform_data *)arg)->peripheral_param1; //1:3wire(SPI_MODE_UNIDIR_1BIT) or 0:4wire(SPI_MODE_BIDIR_1BIT) (与spi结构体一样)
    // u8 port;         //SPIx group:A,B,C,D (spi结构体)
    // U8 spi_clk;      //spi_clk: <=1MHz (spi结构体)
#endif
    iic_init(mpu9250_info_data.iic_hdl);
//int module io init
    mpu9250_int_pin = ((struct imusensor_platform_data *)arg)->imu_sensor_int_io;
    gpio_set_direction(mpu9250_int_pin, 1);
    gpio_set_die(mpu9250_int_pin, 1);
    /* gpio_set_pull_up(mpu9250_int_pin, 1); */
    /* gpio_set_pull_down(mpu9250_int_pin, 0); */

    if (mpu9250_init2(&mpu9250_info_data)) {
        log_info("mpu9250 Device init success!\n");
        log_info("int mode en!");
        /* port_wkup_enable(mpu9250_int_pin, 1, mpu9250_int_callback); //PA08-IO中断，1:下降沿触发，回调函数mpu9250_int_callback*/
#ifdef CONFIG_CPU_BR23
        io_ext_interrupt_init(mpu9250_int_pin, 1, mpu9250_int_callback);
#elif defined(CONFIG_CPU_BR28)
        // br28外部中断回调函数，按照现在的外部中断注册方式
        // io配置在板级，定义在板级头文件，这里只是注册回调函数
        port_edge_wkup_set_callback_by_index(4, mpu9250_int_callback); // 序号需要和板级配置中的wk_param对应上
#elif defined(CONFIG_CPU_BR27)
        port_edge_wkup_set_callback(mpu9250_int_callback);
#endif
        return 1;
    } else {
        log_info("mpu9250 Device init fail!\n");
        return 0;
    }
}


int mpu9250_dev_ctl(u8 cmd, void *arg);
REGISTER_IMU_SENSOR(mpu9250_sensor) = {
    .logo = "mpu9250",
    .imu_sensor_init = mpu9250_dev_init,
    .imu_sensor_check = NULL,
    .imu_sensor_ctl = mpu9250_dev_ctl,
};

int mpu9250_dev_ctl(u8 cmd, void *arg)
{
    int ret = -1;
    switch (cmd) {
    case IMU_GET_SENSOR_NAME:
        memcpy((u8 *)arg, &(mpu9250_sensor.logo), 20);
        break;
    case IMU_SENSOR_ENABLE:
        /* cbuf_init(&hrsensor_cbuf, hrsensorcbuf, 24 * sizeof(int)); */
        mpu9250_init2(&mpu9250_info_data);
        break;
    case IMU_SENSOR_DISABLE:
        /* cbuf_clear(&hrsensor_cbuf); */
        break;
    case IMU_SENSOR_RESET:
        break;
    case IMU_SENSOR_SLEEP:
        break;
    case IMU_SENSOR_WAKEUP:
        break;
    case IMU_SENSOR_INT_DET://传感器中断状态检查
        break;
    case IMU_SENSOR_DATA_READY://传感器数据准备就绪待读
        mpu9250_int_callback();
        break;
    case IMU_SENSOR_CHECK_DATA://检查传感器缓存buf是否存满
        break;
    case IMU_SENSOR_READ_DATA://默认读传感器所有数据
        break;
    case IMU_GET_ACCEL_DATA://加速度数据
        break;
    case IMU_GET_GYRO_DATA://陀螺仪数据
        break;
    case IMU_GET_MAG_DATA://磁力计数据
        break;
    case IMU_SENSOR_SEARCH://检查传感器id
        mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_DEVICE_ID_REG, (u8 *)arg, 1); //读取MPU9250的ID
        if (*(u8 *)arg == 0x71) {
            ret = 0;
            log_info("mpu9250 online!\n");
        } else {
            log_error("mpu9250 offline!\n");
        }
        break;
    default:
        log_error("--cmd err!\n");
        break;
    }
    return ret;

}


/***************************mpu9250 test*******************************/
#if 0

static mpu9250_param mpu9250_iic_info_test2 = {
    .iic_hdl = 1,
    .iic_delay = 0, //iic字节间间隔，单位us
};

void port_wkup_irq_cbfun_test(u8 index, u8 gpio)
{
    mpu9250_int_flag = 1;
    mpu_i2c_buf_read(MPU9250_ADDRESS_W, MPU_ACCEL_XOUTH_REG, read_mpu_buf, SENSORS_MPU_BUFF_LEN);
}
void read_mpu_all_reg();
void mpu9250_test2()
{
    s16 x = 0, y = 0, z = 0;
    iic_init(mpu9250_iic_info_test2.iic_hdl);
    if (mpu9250_init2(&mpu9250_iic_info_test2)) {
        log_info("mpu9250 Device init pass!\n");
        log_info("-------------------port wkup isr---------------------------");
        /* port_wkup_enable(mpu9250_int_pin, 1, port_wkup_irq_cbfun_test); //PA08-IO中断，1:下降沿触发，回调函数port_wkup_irq_cbfun_test */
#ifdef CONFIG_CPU_BR23
        io_ext_interrupt_init(mpu9250_int_pin, 1, port_wkup_irq_cbfun_test);
#elif defined(CONFIG_CPU_BR28)
        // br28外部中断回调函数，按照现在的外部中断注册方式
        // io配置在板级，定义在板级头文件，这里只是注册回调函数
        port_edge_wkup_set_callback_by_index(4, port_wkup_irq_cbfun_test); // 序号需要和板级配置中的wk_param对应上
#elif defined(CONFIG_CPU_BR27)
        port_edge_wkup_set_callback(port_wkup_irq_cbfun_test);
#endif

        /* read_mpu_all_reg(); */
        while (1) {
            if (mpu9250_int_flag) {
                x = (((s16) read_mpu_buf[0]) << 8) | read_mpu_buf[1];
                y = ((((s16) read_mpu_buf[2]) << 8) | read_mpu_buf[3]);
                z = (((s16) read_mpu_buf[4]) << 8) | read_mpu_buf[5];
                log_info("mpu9250_raw_data.accel_data:X:%d,Y:%d,Z:%d", x, y, z);
                x = (((s16) read_mpu_buf[8]) << 8) | read_mpu_buf[9];
                y = (((s16) read_mpu_buf[10]) << 8) | read_mpu_buf[11];
                z = (((s16) read_mpu_buf[12]) << 8) | read_mpu_buf[13];
                log_info("mpu9250_raw_data.gyro_data:X:%d,Y:%d,Z:%d", x, y, z);
#if MAG_AK8963_ENABLE
                if (read_mpu_buf[0 + SENSORS_MPU6500_BUFF_LEN]&BIT(0)) {
                    x = (((s16) read_mpu_buf[2 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[1 + SENSORS_MPU6500_BUFF_LEN ];
                    y = (((s16) read_mpu_buf[4 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[3 + SENSORS_MPU6500_BUFF_LEN ];
                    z = (((s16) read_mpu_buf[6 + SENSORS_MPU6500_BUFF_LEN ]) << 8) | read_mpu_buf[5 + SENSORS_MPU6500_BUFF_LEN ];
                    log_info("mpu9250_raw_data.mag_data:X:%d,Y:%d,Z:%d", x, y, z);
                }
#endif
                x = (((s16) read_mpu_buf[6]) << 8) | read_mpu_buf[7];
                x = 21 + (s16)((float)(x) / 333.87);
                log_info("mpu9250_raw_data.temp_data:%d", x);

                mpu9250_int_flag = 0;
            }
            wdt_clear();
            mdelay(10);
        }
    } else {
        log_info("mpu9250 Device init fail!\n");
    }
}

void read_mpu_all_reg()
{
    u8 addr_tab[62] = {0, 1, 2, 13, 14, 15, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 114, 115, 116, 117, 119, 120, 122, 123, 125, 126};
    u8 ii = 0;
    u8 temp1_data[62];
    for (ii = 0; ii < 62; ii++) {
        mpu_i2c_buf_read(MPU9250_ADDRESS_W, addr_tab[ii], &temp1_data[ii], 1);
    }
    log_info("addr:%d", addr_tab[61]);
    log_info_hexdump(temp1_data, 62);
    log_info("id:0x%x", temp1_data[55]);
}

#endif


#endif




