1847 lines
70 KiB
C
1847 lines
70 KiB
C
|
|
#include "app_config.h"
|
|
#include "asm/clock.h"
|
|
#include "asm/cpu.h"
|
|
#include "generic/typedef.h"
|
|
#include "generic/gpio.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"
|
|
#include "qmi8658c.h"
|
|
|
|
// #include "spi1.h"
|
|
// #include "port_wkup.h"
|
|
|
|
|
|
|
|
#if TCFG_QMI8658_ENABLE
|
|
|
|
/*************Betterlife ic debug***********/
|
|
#undef LOG_TAG_CONST
|
|
#define LOG_TAG "[QMI8658]"
|
|
#define LOG_ERROR_ENABLE
|
|
#define LOG_INFO_ENABLE
|
|
#include "debug.h"
|
|
|
|
void delay(volatile u32 t);
|
|
void udelay(u32 us);
|
|
#define MDELAY(n) mdelay(n)
|
|
|
|
|
|
static qmi8658_param *qmi8658_info;
|
|
|
|
// static qmi8658_data qmi8658_raw_data={0};
|
|
|
|
/******************************************************************
|
|
* Description: I2C or SPI bus interface functions and delay time function
|
|
*
|
|
* Parameters:
|
|
* devAddr: I2C device address, modify the macro(QMI8658_ADDRESS @qmi8658.h) based on your I2C function.
|
|
* If SPI interface, please ingnore the parameter.
|
|
* regAddr: register address
|
|
* readLen: data length to read
|
|
* *readBuf: data buffer to read
|
|
* writeLen: data length to write
|
|
* *writeBuf: data buffer to write
|
|
*
|
|
******************************************************************/
|
|
|
|
#if (QMI8658_USER_INTERFACE==QMI8658_USE_I2C)
|
|
|
|
#if TCFG_QMI8658_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
|
|
//起止信号间隔:standard mode(100khz):4.7us; fast mode(400khz):1.3us
|
|
//return: readLen:ok, other:fail
|
|
u16 qmi8658_I2C_Read_NBytes(unsigned char devAddr,
|
|
unsigned char regAddr,
|
|
unsigned char *readBuf,
|
|
u16 readLen)
|
|
{
|
|
u16 i = 0;
|
|
local_irq_disable();
|
|
iic_start(qmi8658_info->iic_hdl);
|
|
if (0 == iic_tx_byte(qmi8658_info->iic_hdl, devAddr)) {
|
|
log_error("qmi8658 iic read err1");
|
|
goto __iic_exit_r;
|
|
}
|
|
delay(qmi8658_info->iic_delay);
|
|
/* if (0 == iic_tx_byte(qmi8658_info->iic_hdl, regAddr |0x80)) {//|0x80地址自动递增 */
|
|
if (0 == iic_tx_byte(qmi8658_info->iic_hdl, regAddr)) {//|0x80地址自动递增
|
|
log_error("qmi8658 iic read err2");
|
|
goto __iic_exit_r;
|
|
}
|
|
delay(qmi8658_info->iic_delay);
|
|
|
|
iic_start(qmi8658_info->iic_hdl);
|
|
if (0 == iic_tx_byte(qmi8658_info->iic_hdl, devAddr + 1)) {
|
|
log_error("qmi8658 iic read err3");
|
|
goto __iic_exit_r;
|
|
}
|
|
for (i = 0; i < readLen; i++) {
|
|
delay(qmi8658_info->iic_delay);
|
|
if (i == (readLen - 1)) {
|
|
*readBuf++ = iic_rx_byte(qmi8658_info->iic_hdl, 0);
|
|
} else {
|
|
*readBuf++ = iic_rx_byte(qmi8658_info->iic_hdl, 1);
|
|
}
|
|
/* if(i%100==0)wdt_clear(); */
|
|
}
|
|
__iic_exit_r:
|
|
iic_stop(qmi8658_info->iic_hdl);
|
|
local_irq_enable();
|
|
|
|
return i;
|
|
}
|
|
|
|
//起止信号间隔:standard mode(100khz):4.7us; fast mode(400khz):1.3us
|
|
//return:1:ok, 0:fail
|
|
unsigned char qmi8658_I2C_Write_Byte(unsigned char devAddr, //芯片支持1byte写
|
|
unsigned char regAddr,
|
|
unsigned char byte)
|
|
{
|
|
u8 ret = 1;
|
|
local_irq_disable();
|
|
iic_start(qmi8658_info->iic_hdl);
|
|
if (0 == iic_tx_byte(qmi8658_info->iic_hdl, devAddr)) {
|
|
log_error("qmi8658 iic write err1");
|
|
ret = 0;
|
|
goto __iic_exit_w;
|
|
}
|
|
delay(qmi8658_info->iic_delay);
|
|
if (0 == iic_tx_byte(qmi8658_info->iic_hdl, regAddr)) {
|
|
log_error("qmi8658 iic write err2");
|
|
ret = 0;
|
|
goto __iic_exit_w;
|
|
}
|
|
delay(qmi8658_info->iic_delay);
|
|
if (0 == iic_tx_byte(qmi8658_info->iic_hdl, byte)) {
|
|
log_error("qmi8658 iic write err3");
|
|
ret = 0;
|
|
goto __iic_exit_w;
|
|
}
|
|
__iic_exit_w:
|
|
iic_stop(qmi8658_info->iic_hdl);
|
|
local_irq_enable();
|
|
return ret;
|
|
}
|
|
//起止信号间隔:standard mode(100khz):4.7us; fast mode(400khz):1.3us
|
|
//return: readLen:ok, other:fail
|
|
unsigned char qmi8658_I2C_Write_NBytes(unsigned char devAddr, //芯片支持1byte写
|
|
unsigned char regAddr,
|
|
unsigned char *writeBuf,
|
|
u16 writeLen)
|
|
{
|
|
u16 i;
|
|
for (i = 0; i < writeLen; i++) {
|
|
if (qmi8658_I2C_Write_Byte(devAddr, regAddr + i, writeBuf[i]) == 0) {
|
|
log_error("qmi8658_I2C_Write_NBytes error N:%d", i);
|
|
return i;
|
|
}
|
|
udelay(5);//delay5us
|
|
}
|
|
return i;
|
|
}
|
|
IMU_read Qmi8658_read = qmi8658_I2C_Read_NBytes;
|
|
IMU_write Qmi8658_write = qmi8658_I2C_Write_Byte;
|
|
|
|
#elif (QMI8658_USER_INTERFACE==QMI8658_USE_SPI)
|
|
|
|
#define spi_cs_init() \
|
|
do { \
|
|
gpio_write(qmi8658_info->spi_cs_pin, 1); \
|
|
gpio_set_direction(qmi8658_info->spi_cs_pin, 0); \
|
|
gpio_set_die(qmi8658_info->spi_cs_pin, 1); \
|
|
} while (0)
|
|
#define spi_cs_uninit() \
|
|
do { \
|
|
gpio_set_die(qmi8658_info->spi_cs_pin, 0); \
|
|
gpio_set_direction(qmi8658_info->spi_cs_pin, 1); \
|
|
gpio_set_pull_up(qmi8658_info->spi_cs_pin, 0); \
|
|
gpio_set_pull_down(qmi8658_info->spi_cs_pin, 0); \
|
|
} while (0)
|
|
#define spi_cs_h() gpio_write(qmi8658_info->spi_cs_pin, 1)
|
|
#define spi_cs_l() gpio_write(qmi8658_info->spi_cs_pin, 0)
|
|
|
|
#define spi_read_byte() spi_recv_byte(qmi8658_info->spi_hdl, NULL)
|
|
#define spi_write_byte(x) spi_send_byte(qmi8658_info->spi_hdl, x)
|
|
#define spi_dma_read(x, y) spi_dma_recv(qmi8658_info->spi_hdl, x, y)
|
|
#define spi_dma_write(x, y) spi_dma_send(qmi8658_info->spi_hdl, x, y)
|
|
#define spi_set_width(x) spi_set_bit_mode(qmi8658_info->spi_hdl, x)
|
|
#define spi_init() spi_open(qmi8658_info->spi_hdl)
|
|
#define spi_closed() spi_close(qmi8658_info->spi_hdl)
|
|
#define spi_suspend() hw_spi_suspend(qmi8658_info->spi_hdl)
|
|
#define spi_resume() hw_spi_resume(qmi8658_info->spi_hdl)
|
|
|
|
u16 qmi8658_SPI_readNBytes(unsigned char devAddr,
|
|
unsigned char regAddr,
|
|
unsigned char *readBuf,
|
|
u16 readLen)
|
|
{
|
|
spi_cs_l();
|
|
spi_write_byte(regAddr | 0x80);//| 0x80:read mode
|
|
spi_dma_read(readBuf, readLen);
|
|
spi_cs_h();
|
|
//SPIRead((regAddr | 0x80), readBuf, readLen);
|
|
return (readLen);
|
|
}
|
|
unsigned char qmi8658_SPI_writeByte(unsigned char devAddr,
|
|
unsigned char regAddr,
|
|
unsigned char writebyte)
|
|
{
|
|
spi_cs_l();
|
|
spi_write_byte((regAddr) & 0x7F);
|
|
spi_write_byte(writebyte);
|
|
spi_cs_h();
|
|
udelay(5);//delay5us
|
|
return (1);
|
|
}
|
|
unsigned char qmi8658_SPI_writeNBytes(unsigned char devAddr,
|
|
unsigned char regAddr,
|
|
unsigned char *writeBuf,
|
|
u16 writeLen)
|
|
{
|
|
#if 0 //多字节dma写
|
|
spi_cs_l();
|
|
spi_write_byte(regAddr & 0x7F);
|
|
spi_dma_write(writeBuf, writeLen);
|
|
spi_cs_h();
|
|
#else
|
|
u16 i = 0;
|
|
for (; i < writeLen; i++) {
|
|
qmi8658_SPI_writeByte(devAddr, regAddr + i, writeBuf[i]);
|
|
}
|
|
#endif
|
|
//SPIWrite((regAddr & 0x7F), writeBuf, writeLen);
|
|
return (i);
|
|
}
|
|
|
|
IMU_read Qmi8658_read = qmi8658_SPI_readNBytes;
|
|
IMU_write Qmi8658_write = qmi8658_SPI_writeByte;
|
|
#else
|
|
//I3C
|
|
#endif
|
|
|
|
void Qmi8658_delay(int ms)
|
|
{
|
|
//your delay code(mSecond: millisecond):
|
|
MDELAY(ms);
|
|
}
|
|
|
|
static unsigned short acc_lsb_div = 0;
|
|
static unsigned short gyro_lsb_div = 0;
|
|
static unsigned short ae_q_lsb_div = (1 << 14);
|
|
static unsigned short ae_v_lsb_div = (1 << 10);
|
|
static unsigned int imu_timestamp = 0;
|
|
static struct Qmi8658Config qmi8658_config;
|
|
|
|
enum {
|
|
AXIS_X = 0,
|
|
AXIS_Y = 1,
|
|
AXIS_Z = 2,
|
|
|
|
AXIS_TOTAL
|
|
};
|
|
#if 0
|
|
typedef struct {
|
|
short sign[AXIS_TOTAL];
|
|
unsigned short map[AXIS_TOTAL];
|
|
} qst_imu_layout;
|
|
|
|
static qst_imu_layout imu_map;
|
|
|
|
void Qmi8658_set_layout(short layout)
|
|
{
|
|
if (layout == 0) {
|
|
imu_map.sign[AXIS_X] = 1;
|
|
imu_map.sign[AXIS_Y] = 1;
|
|
imu_map.sign[AXIS_Z] = 1;
|
|
imu_map.map[AXIS_X] = AXIS_X;
|
|
imu_map.map[AXIS_Y] = AXIS_Y;
|
|
imu_map.map[AXIS_Z] = AXIS_Z;
|
|
} else if (layout == 1) {
|
|
imu_map.sign[AXIS_X] = -1;
|
|
imu_map.sign[AXIS_Y] = 1;
|
|
imu_map.sign[AXIS_Z] = 1;
|
|
imu_map.map[AXIS_X] = AXIS_Y;
|
|
imu_map.map[AXIS_Y] = AXIS_X;
|
|
imu_map.map[AXIS_Z] = AXIS_Z;
|
|
} else if (layout == 2) {
|
|
imu_map.sign[AXIS_X] = -1;
|
|
imu_map.sign[AXIS_Y] = -1;
|
|
imu_map.sign[AXIS_Z] = 1;
|
|
imu_map.map[AXIS_X] = AXIS_X;
|
|
imu_map.map[AXIS_Y] = AXIS_Y;
|
|
imu_map.map[AXIS_Z] = AXIS_Z;
|
|
} else if (layout == 3) {
|
|
imu_map.sign[AXIS_X] = 1;
|
|
imu_map.sign[AXIS_Y] = -1;
|
|
imu_map.sign[AXIS_Z] = 1;
|
|
imu_map.map[AXIS_X] = AXIS_Y;
|
|
imu_map.map[AXIS_Y] = AXIS_X;
|
|
imu_map.map[AXIS_Z] = AXIS_Z;
|
|
} else if (layout == 4) {
|
|
imu_map.sign[AXIS_X] = -1;
|
|
imu_map.sign[AXIS_Y] = 1;
|
|
imu_map.sign[AXIS_Z] = -1;
|
|
imu_map.map[AXIS_X] = AXIS_X;
|
|
imu_map.map[AXIS_Y] = AXIS_Y;
|
|
imu_map.map[AXIS_Z] = AXIS_Z;
|
|
} else if (layout == 5) {
|
|
imu_map.sign[AXIS_X] = 1;
|
|
imu_map.sign[AXIS_Y] = 1;
|
|
imu_map.sign[AXIS_Z] = -1;
|
|
imu_map.map[AXIS_X] = AXIS_Y;
|
|
imu_map.map[AXIS_Y] = AXIS_X;
|
|
imu_map.map[AXIS_Z] = AXIS_Z;
|
|
} else if (layout == 6) {
|
|
imu_map.sign[AXIS_X] = 1;
|
|
imu_map.sign[AXIS_Y] = -1;
|
|
imu_map.sign[AXIS_Z] = -1;
|
|
imu_map.map[AXIS_X] = AXIS_X;
|
|
imu_map.map[AXIS_Y] = AXIS_Y;
|
|
imu_map.map[AXIS_Z] = AXIS_Z;
|
|
} else if (layout == 7) {
|
|
imu_map.sign[AXIS_X] = -1;
|
|
imu_map.sign[AXIS_Y] = -1;
|
|
imu_map.sign[AXIS_Z] = -1;
|
|
imu_map.map[AXIS_X] = AXIS_Y;
|
|
imu_map.map[AXIS_Y] = AXIS_X;
|
|
imu_map.map[AXIS_Z] = AXIS_Z;
|
|
} else {
|
|
imu_map.sign[AXIS_X] = 1;
|
|
imu_map.sign[AXIS_Y] = 1;
|
|
imu_map.sign[AXIS_Z] = 1;
|
|
imu_map.map[AXIS_X] = AXIS_X;
|
|
imu_map.map[AXIS_Y] = AXIS_Y;
|
|
imu_map.map[AXIS_Z] = AXIS_Z;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void Qmi8658_config_acc(enum Qmi8658_AccRange range, enum Qmi8658_AccOdr odr, enum Qmi8658_LpfConfig lpfEnable, enum Qmi8658_StConfig stEnable)
|
|
{
|
|
unsigned char ctl_dada;
|
|
|
|
switch (range) {
|
|
case Qmi8658AccRange_2g:
|
|
acc_lsb_div = (1 << 14);
|
|
break;
|
|
case Qmi8658AccRange_4g:
|
|
acc_lsb_div = (1 << 13);
|
|
break;
|
|
case Qmi8658AccRange_8g:
|
|
acc_lsb_div = (1 << 12);
|
|
break;
|
|
case Qmi8658AccRange_16g:
|
|
acc_lsb_div = (1 << 11);
|
|
break;
|
|
default:
|
|
range = Qmi8658AccRange_8g;
|
|
acc_lsb_div = (1 << 12);
|
|
}
|
|
if (stEnable == Qmi8658St_Enable) {
|
|
ctl_dada = (unsigned char)range | (unsigned char)odr | 0x80;
|
|
} else {
|
|
ctl_dada = (unsigned char)range | (unsigned char)odr;
|
|
}
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl2, ctl_dada);
|
|
// set LPF & HPF
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl5, &ctl_dada, 1);
|
|
ctl_dada &= 0xf0;
|
|
if (lpfEnable == Qmi8658Lpf_Enable) {
|
|
ctl_dada |= A_LSP_MODE_3;
|
|
ctl_dada |= 0x01;
|
|
} else {
|
|
ctl_dada &= ~0x01;
|
|
}
|
|
/* ctl_dada = 0x00; */
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl5, ctl_dada);
|
|
// set LPF & HPF
|
|
}
|
|
|
|
void Qmi8658_config_gyro(enum Qmi8658_GyrRange range, enum Qmi8658_GyrOdr odr, enum Qmi8658_LpfConfig lpfEnable, enum Qmi8658_StConfig stEnable)
|
|
{
|
|
// Set the CTRL3 register to configure dynamic range and ODR
|
|
unsigned char ctl_dada;
|
|
|
|
// Store the scale factor for use when processing raw data
|
|
switch (range) {
|
|
case Qmi8658GyrRange_16dps:
|
|
gyro_lsb_div = 2048;
|
|
break;
|
|
case Qmi8658GyrRange_32dps:
|
|
gyro_lsb_div = 1024;
|
|
break;
|
|
case Qmi8658GyrRange_64dps:
|
|
gyro_lsb_div = 512;
|
|
break;
|
|
case Qmi8658GyrRange_128dps:
|
|
gyro_lsb_div = 256;
|
|
break;
|
|
case Qmi8658GyrRange_256dps:
|
|
gyro_lsb_div = 128;
|
|
break;
|
|
case Qmi8658GyrRange_512dps:
|
|
gyro_lsb_div = 64;
|
|
break;
|
|
case Qmi8658GyrRange_1024dps:
|
|
gyro_lsb_div = 32;
|
|
break;
|
|
case Qmi8658GyrRange_2048dps:
|
|
gyro_lsb_div = 16;
|
|
break;
|
|
// case Qmi8658GyrRange_4096dps:
|
|
// gyro_lsb_div = 8;
|
|
// break;
|
|
default:
|
|
range = Qmi8658GyrRange_512dps;
|
|
gyro_lsb_div = 64;
|
|
break;
|
|
}
|
|
|
|
if (stEnable == Qmi8658St_Enable) {
|
|
ctl_dada = (unsigned char)range | (unsigned char)odr | 0x80;
|
|
} else {
|
|
ctl_dada = (unsigned char)range | (unsigned char)odr;
|
|
}
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl3, ctl_dada);
|
|
|
|
// Conversion from degrees/s to rad/s if necessary
|
|
// set LPF & HPF
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl5, &ctl_dada, 1);
|
|
ctl_dada &= 0x0f;
|
|
if (lpfEnable == Qmi8658Lpf_Enable) {
|
|
ctl_dada |= G_LSP_MODE_3;
|
|
ctl_dada |= 0x10;
|
|
} else {
|
|
ctl_dada &= ~0x10;
|
|
}
|
|
/* ctl_dada = 0x00; */
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl5, ctl_dada);
|
|
// set LPF & HPF
|
|
}
|
|
|
|
void Qmi8658_config_mag(enum Qmi8658_MagDev device, enum Qmi8658_MagOdr odr)
|
|
{
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl4, device | odr);
|
|
}
|
|
|
|
void Qmi8658_config_ae(enum Qmi8658_AeOdr odr)
|
|
{
|
|
//Qmi8658_config_acc(Qmi8658AccRange_8g, AccOdr_1000Hz, Lpf_Enable, St_Enable);
|
|
//Qmi8658_config_gyro(Qmi8658GyrRange_2048dps, GyrOdr_1000Hz, Lpf_Enable, St_Enable);
|
|
Qmi8658_config_acc(qmi8658_config.accRange, qmi8658_config.accOdr, Qmi8658Lpf_Enable, Qmi8658St_Disable);
|
|
Qmi8658_config_gyro(qmi8658_config.gyrRange, qmi8658_config.gyrOdr, Qmi8658Lpf_Enable, Qmi8658St_Disable);
|
|
Qmi8658_config_mag(qmi8658_config.magDev, qmi8658_config.magOdr);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl6, odr);
|
|
}
|
|
|
|
void Qmi8658_send_ctl9cmd(enum Qmi8658_Ctrl9Command cmd) //cmd=0x0d
|
|
{
|
|
unsigned char status1 = 0x00;
|
|
unsigned short count = 0;
|
|
//void* pi2c = qmi8658_i2c_init();
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl9, (unsigned char)cmd); // write commond to ctrl9
|
|
#if defined(QMI8658_HANDSHAKE_NEW)
|
|
#if defined(QMI8658_HANDSHAKE_TO_STATUS)
|
|
unsigned char status_reg = Qmi8658Register_StatusInt;
|
|
unsigned char cmd_done = 0x80;
|
|
#else
|
|
unsigned char status_reg = Qmi8658Register_Status1;// Qmi8658Register_Status1
|
|
unsigned char cmd_done = 0x01;
|
|
#endif
|
|
//count = 0;
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, status_reg, &status1, 1);
|
|
/* log_info("status1=%x\n",status1); */
|
|
while (((status1 & cmd_done) != cmd_done) && (count++ < 200)) { // read statusINT until bit7 is 1
|
|
Qmi8658_delay(1);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, status_reg, &status1, 1);
|
|
//log_info("first %d status_reg: 0x%x\n", count,status1);
|
|
}
|
|
/* log_info("Qmi8658_config_fifo ctrl9 done-1: %d\n", count); */
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl9, Qmi8658_Ctrl9_Cmd_NOP); // write commond 0x00 to ctrl9
|
|
count = 0;
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, status_reg, &status1, 1);
|
|
while (((status1 & cmd_done) == cmd_done) && (count++ < 200)) { // read statusINT until bit7 is 0
|
|
Qmi8658_delay(1);
|
|
/* log_info("second %d status_reg: 0x%x\n", count,status1); */
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, status_reg, &status1, 1);
|
|
}
|
|
/* log_info("ctrl9 done-2: %d\n", count); */
|
|
#else
|
|
while (((status1 & QMI8658_STATUS1_CMD_DONE) == 0) && (count++ < 200)) {
|
|
Qmi8658_delay(2);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Status1, &status1, sizeof(status1));
|
|
}
|
|
//log_info("fifo rst done : %d\n", count);
|
|
#endif
|
|
|
|
//qmi8658_i2c_deinit(pi2c);
|
|
|
|
}
|
|
|
|
|
|
#if (QMI8658_USE_FIFO_EN)
|
|
/*
|
|
* if mode=Qmi8658_Fifo_Stream then watermark <= size 否则不会输出中断信息
|
|
* */
|
|
void Qmi8658_config_fifo(uint8_t watermark, enum Qmi8658_FifoSize size, enum Qmi8658_FifoMode mode, enum Qmi8658_fifo_format format)
|
|
{
|
|
/* Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, 0x00); */
|
|
Qmi8658_delay(1);
|
|
#if (QMI8658_NEW_HANDSHAKE == 1)
|
|
u8 temp_data;
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, &temp_data, 1);
|
|
#if (QMI8658_FIFO_INT_OMAP_INT1 == 1)
|
|
temp_data |= BIT(2); //
|
|
#else
|
|
temp_data &= ~BIT(2); //
|
|
#endif
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, temp_data);
|
|
#endif
|
|
|
|
qmi8658_config.fifo_format = format; //QMI8658_FORMAT_12_BYTES;
|
|
qmi8658_config.fifo_ctrl = (uint8_t)size | (uint8_t)mode;
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_FifoCtrl, qmi8658_config.fifo_ctrl);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_FifoWmkTh, (unsigned char)watermark);
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_Rst_Fifo);
|
|
|
|
/* if(format == QMI8658_FORMAT_ACCEL_6_BYTES) */
|
|
/* Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, 0x01); */
|
|
/* else if(format == QMI8658_FORMAT_GYRO_6_BYTES) */
|
|
/* Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, 0x02); */
|
|
/* else if(format == QMI8658_FORMAT_12_BYTES) */
|
|
/* Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, 0x03); */
|
|
}
|
|
|
|
/*
|
|
*sensor data formal:
|
|
* 3 sensor:acc, gyro, mag
|
|
* AX_L[0] AX_H[0] AY_L[0] AY_H[0] AZ_L[0] AZ_H[0]
|
|
* GX_L[0] GX_H[0] GY_L[0] GY_H[0] GZ_L[0] GZ_H[0]
|
|
* MX_L[0] MX_H[0] MY_L[0] MY_H[0] MZ_L[0] MZ_H[0]
|
|
* AX_L[1] AX_H[1] ......
|
|
* 2 sensor:acc, gyro
|
|
* AX_L[0] AX_H[0] AY_L[0] AY_H[0] AZ_L[0] AZ_H[0]
|
|
* GX_L[0] GX_H[0] GY_L[0] GY_H[0] GZ_L[0] GZ_H[0]
|
|
* AX_L[1] AX_H[1] ......
|
|
* 1 sensor:acc or gyro
|
|
* AX_L[0] AX_H[0]] AY_L[0] AY_H[0] AZ_L [0] AZ_H[0] AX_L[1] ......
|
|
* */
|
|
unsigned short Qmi8658_read_fifo(unsigned char *data)
|
|
{
|
|
unsigned char fifo_status[2] = {0, 0};
|
|
unsigned short fifo_bytes = 0;
|
|
unsigned short fifo_level = 0;
|
|
//unsigned short i;
|
|
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_Req_Fifo);
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_FifoCount, fifo_status, 2);
|
|
fifo_bytes = (unsigned short)(((fifo_status[1] & 0x03) << 8) | fifo_status[0]);
|
|
fifo_bytes *= 2;
|
|
if ((qmi8658_config.fifo_format == QMI8658_FORMAT_ACCEL_6_BYTES) || (qmi8658_config.fifo_format == QMI8658_FORMAT_GYRO_6_BYTES) || (qmi8658_config.fifo_format == QMI8658_FORMAT_MAG_6_BYTES)) {
|
|
fifo_level = fifo_bytes / 6; // one sensor
|
|
fifo_bytes = fifo_level * 6;
|
|
} else if (qmi8658_config.fifo_format == QMI8658_FORMAT_12_BYTES) {
|
|
fifo_level = fifo_bytes / 12; // two sensor
|
|
fifo_bytes = fifo_level * 12;
|
|
} else if (qmi8658_config.fifo_format == QMI8658_FORMAT_18_BYTES) {
|
|
fifo_level = fifo_bytes / 18; // three sensor
|
|
fifo_bytes = fifo_level * 18;
|
|
}
|
|
/* log_info("fifo byte=%d level=%d\n", fifo_bytes, fifo_level); */
|
|
if (fifo_level > 0) {
|
|
#if 0
|
|
for (i = 1; i < fifo_level; i++) {
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_FifoData, data + i * 12, 12);
|
|
}
|
|
#else
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_FifoData, data, fifo_bytes);
|
|
#endif
|
|
}
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_FifoCtrl, qmi8658_config.fifo_ctrl);
|
|
|
|
return fifo_bytes;
|
|
}
|
|
|
|
|
|
void Qmi8658_get_fifo_format(enum Qmi8658_fifo_format *format)
|
|
{
|
|
if (format) {
|
|
*format = qmi8658_config.fifo_format;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* status0:46(0x2e)
|
|
* BIT: 7:4 3 2 1 0
|
|
* reserved AE(new data) mag gyro acc
|
|
*/
|
|
unsigned char Qmi8658_readStatus0(void)
|
|
{
|
|
unsigned char status[2];
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Status0, status, sizeof(status));
|
|
log_info("status[0:0x%x 1:0x%x]", status[0], status[1]);
|
|
|
|
return status[0];
|
|
}
|
|
/*!status1:47(0x2f)
|
|
* \brief Blocking read of data status register 1 (::Qmi8658Register_Status1).
|
|
* bit7~bit1: reserved
|
|
* bit0: Used to indicate ctrl9 Command was done.
|
|
* \returns Status byte \see STATUS1 for flag definitions.
|
|
*/
|
|
unsigned char Qmi8658_readStatus1(void)
|
|
{
|
|
unsigned char status;
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Status1, &status, sizeof(status));
|
|
/* log_info("status1[0x%x]\n",status); */
|
|
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* Sample time stamp. Count incremented by one for each sample
|
|
(x, y, z data set) from sensor with highest ODR (circular register
|
|
0x0-0xFFFFFF)
|
|
*/
|
|
unsigned char Qmi8658_read_time_stamp_reg(void)
|
|
{
|
|
unsigned char time_stamp[3];
|
|
u32 sample_time = 0;
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Timestamp_L, time_stamp, sizeof(time_stamp));
|
|
sample_time = (u32)(time_stamp[2] << 16) | (u32)(time_stamp[1] << 8) | time_stamp[0];
|
|
/* log_info("Sample time stamp =[0x%x]\n",sample_time); */
|
|
return sample_time;
|
|
}
|
|
/************************0x59地址文档未介绍*****************************/
|
|
unsigned char Qmi8658_read_temptap_reg(void)
|
|
{
|
|
unsigned char status;
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, 0x59, &status, sizeof(status));
|
|
log_info("tap_temp_reg =[0x%x]\n", status);
|
|
|
|
return status;
|
|
}
|
|
|
|
float Qmi8658_readTemp(void)
|
|
{
|
|
unsigned char buf[2];
|
|
short temp = 0;
|
|
float temp_f = 0;
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Tempearture_L, buf, 2);
|
|
temp = ((short)buf[1] << 8) | buf[0];
|
|
temp_f = (float)temp / 256.0f;
|
|
|
|
return temp_f;
|
|
}
|
|
|
|
void Qmi8658_read_acc_xyz(float acc_xyz[3])
|
|
{
|
|
unsigned char buf_reg[6];
|
|
short raw_acc_xyz[3];
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ax_L, buf_reg, 6); // 0x35, 53
|
|
raw_acc_xyz[0] = (short)((unsigned short)(buf_reg[1] << 8) | (buf_reg[0]));
|
|
raw_acc_xyz[1] = (short)((unsigned short)(buf_reg[3] << 8) | (buf_reg[2]));
|
|
raw_acc_xyz[2] = (short)((unsigned short)(buf_reg[5] << 8) | (buf_reg[4]));
|
|
|
|
acc_xyz[0] = (raw_acc_xyz[0] * ONE_G) / acc_lsb_div;
|
|
acc_xyz[1] = (raw_acc_xyz[1] * ONE_G) / acc_lsb_div;
|
|
acc_xyz[2] = (raw_acc_xyz[2] * ONE_G) / acc_lsb_div;
|
|
|
|
//log_info("fis210x acc: %f %f %f\n", acc_xyz[0], acc_xyz[1], acc_xyz[2]);
|
|
}
|
|
|
|
void Qmi8658_read_gyro_xyz(float gyro_xyz[3])
|
|
{
|
|
unsigned char buf_reg[6];
|
|
short raw_gyro_xyz[3];
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Gx_L, buf_reg, 6); // 0x3b, 59
|
|
raw_gyro_xyz[0] = (short)((unsigned short)(buf_reg[1] << 8) | (buf_reg[0]));
|
|
raw_gyro_xyz[1] = (short)((unsigned short)(buf_reg[3] << 8) | (buf_reg[2]));
|
|
raw_gyro_xyz[2] = (short)((unsigned short)(buf_reg[5] << 8) | (buf_reg[4]));
|
|
|
|
/* log_info("gyro: %d %d %d\n", raw_gyro_xyz[0], raw_gyro_xyz[1], raw_gyro_xyz[2]); */
|
|
|
|
gyro_xyz[0] = (raw_gyro_xyz[0] * 1.0f) / gyro_lsb_div;
|
|
gyro_xyz[1] = (raw_gyro_xyz[1] * 1.0f) / gyro_lsb_div;
|
|
gyro_xyz[2] = (raw_gyro_xyz[2] * 1.0f) / gyro_lsb_div;
|
|
|
|
//log_info("fis210x gyro: %f %f %f\n", gyro_xyz[0], gyro_xyz[1], gyro_xyz[2]);
|
|
}
|
|
|
|
/******
|
|
* tim_count: Sample time stamp. Count incremented by one for each sample
|
|
(x, y, z data set) from sensor with highest ODR (circular register
|
|
0x0-0xFFFFFF).
|
|
*****/
|
|
void Qmi8658_read_xyz(float acc[3], float gyro[3], unsigned int *tim_count)
|
|
{
|
|
unsigned char buf_reg[12];
|
|
short raw_acc_xyz[3];
|
|
short raw_gyro_xyz[3];
|
|
// float acc_t[3];
|
|
// float gyro_t[3];
|
|
|
|
if (tim_count) {
|
|
unsigned char buf[3];
|
|
unsigned int timestamp;
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Timestamp_L, buf, 3); // 0x18 24
|
|
timestamp = (unsigned int)(((unsigned int)buf[2] << 16) | ((unsigned int)buf[1] << 8) | buf[0]);
|
|
if (timestamp > imu_timestamp) {
|
|
imu_timestamp = timestamp;
|
|
} else {
|
|
imu_timestamp = (timestamp + 0x1000000 - imu_timestamp);
|
|
}
|
|
|
|
*tim_count = imu_timestamp;
|
|
}
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ax_L, buf_reg, 12); // 0x19, 25
|
|
raw_acc_xyz[0] = (short)((unsigned short)(buf_reg[1] << 8) | (buf_reg[0]));
|
|
raw_acc_xyz[1] = (short)((unsigned short)(buf_reg[3] << 8) | (buf_reg[2]));
|
|
raw_acc_xyz[2] = (short)((unsigned short)(buf_reg[5] << 8) | (buf_reg[4]));
|
|
|
|
raw_gyro_xyz[0] = (short)((unsigned short)(buf_reg[7] << 8) | (buf_reg[6]));
|
|
raw_gyro_xyz[1] = (short)((unsigned short)(buf_reg[9] << 8) | (buf_reg[8]));
|
|
raw_gyro_xyz[2] = (short)((unsigned short)(buf_reg[11] << 8) | (buf_reg[10]));
|
|
|
|
#if (QMI8658_UINT_MG_DPS)
|
|
// mg
|
|
acc[AXIS_X] = (float)(raw_acc_xyz[AXIS_X] * 1000.0f) / acc_lsb_div;
|
|
acc[AXIS_Y] = (float)(raw_acc_xyz[AXIS_Y] * 1000.0f) / acc_lsb_div;
|
|
acc[AXIS_Z] = (float)(raw_acc_xyz[AXIS_Z] * 1000.0f) / acc_lsb_div;
|
|
#else
|
|
// m/s2
|
|
acc[AXIS_X] = (float)(raw_acc_xyz[AXIS_X] * ONE_G) / acc_lsb_div;
|
|
acc[AXIS_Y] = (float)(raw_acc_xyz[AXIS_Y] * ONE_G) / acc_lsb_div;
|
|
acc[AXIS_Z] = (float)(raw_acc_xyz[AXIS_Z] * ONE_G) / acc_lsb_div;
|
|
#endif
|
|
// acc[AXIS_X] = imu_map.sign[AXIS_X]*acc_t[imu_map.map[AXIS_X]];
|
|
// acc[AXIS_Y] = imu_map.sign[AXIS_Y]*acc_t[imu_map.map[AXIS_Y]];
|
|
// acc[AXIS_Z] = imu_map.sign[AXIS_Z]*acc_t[imu_map.map[AXIS_Z]];
|
|
|
|
#if (QMI8658_UINT_MG_DPS)
|
|
// dps
|
|
gyro[0] = (float)(raw_gyro_xyz[0] * 1.0f) / gyro_lsb_div;
|
|
gyro[1] = (float)(raw_gyro_xyz[1] * 1.0f) / gyro_lsb_div;
|
|
gyro[2] = (float)(raw_gyro_xyz[2] * 1.0f) / gyro_lsb_div;
|
|
#else
|
|
// rad/s
|
|
gyro[AXIS_X] = (float)(raw_gyro_xyz[AXIS_X] * 0.01745f) / gyro_lsb_div; // *pi/180
|
|
gyro[AXIS_Y] = (float)(raw_gyro_xyz[AXIS_Y] * 0.01745f) / gyro_lsb_div;
|
|
gyro[AXIS_Z] = (float)(raw_gyro_xyz[AXIS_Z] * 0.01745f) / gyro_lsb_div;
|
|
#endif
|
|
// gyro[AXIS_X] = imu_map.sign[AXIS_X]*gyro_t[imu_map.map[AXIS_X]];
|
|
// gyro[AXIS_Y] = imu_map.sign[AXIS_Y]*gyro_t[imu_map.map[AXIS_Y]];
|
|
// gyro[AXIS_Z] = imu_map.sign[AXIS_Z]*gyro_t[imu_map.map[AXIS_Z]];
|
|
}
|
|
|
|
/******
|
|
* tim_count: Sample time stamp. Count incremented by one for each sample
|
|
(x, y, z data set) from sensor with highest ODR (circular register
|
|
0x0-0xFFFFFF).
|
|
*****/
|
|
void Qmi8658_read_xyz_raw(short raw_acc_xyz[3], short raw_gyro_xyz[3], unsigned int *tim_count)
|
|
{
|
|
unsigned char buf_reg[12];
|
|
|
|
if (tim_count) {
|
|
unsigned char buf[3];
|
|
unsigned int timestamp;
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Timestamp_L, buf, 3); // 0x18 24
|
|
timestamp = (unsigned int)(((unsigned int)buf[2] << 16) | ((unsigned int)buf[1] << 8) | buf[0]);
|
|
if (timestamp > imu_timestamp) {
|
|
imu_timestamp = timestamp;
|
|
} else {
|
|
imu_timestamp = (timestamp + 0x1000000 - imu_timestamp);
|
|
}
|
|
|
|
*tim_count = imu_timestamp;
|
|
}
|
|
if (raw_acc_xyz && raw_gyro_xyz) {
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ax_L, buf_reg, 12); // 0x19, 25
|
|
raw_acc_xyz[0] = (short)((unsigned short)(buf_reg[1] << 8) | (buf_reg[0]));
|
|
raw_acc_xyz[1] = (short)((unsigned short)(buf_reg[3] << 8) | (buf_reg[2]));
|
|
raw_acc_xyz[2] = (short)((unsigned short)(buf_reg[5] << 8) | (buf_reg[4]));
|
|
raw_gyro_xyz[0] = (short)((unsigned short)(buf_reg[7] << 8) | (buf_reg[6]));
|
|
raw_gyro_xyz[1] = (short)((unsigned short)(buf_reg[9] << 8) | (buf_reg[8]));
|
|
raw_gyro_xyz[2] = (short)((unsigned short)(buf_reg[11] << 8) | (buf_reg[10]));
|
|
} else if (raw_acc_xyz) {
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ax_L, buf_reg, 6); // 0x19, 25
|
|
raw_acc_xyz[0] = (short)((unsigned short)(buf_reg[1] << 8) | (buf_reg[0]));
|
|
raw_acc_xyz[1] = (short)((unsigned short)(buf_reg[3] << 8) | (buf_reg[2]));
|
|
raw_acc_xyz[2] = (short)((unsigned short)(buf_reg[5] << 8) | (buf_reg[4]));
|
|
} else if (raw_gyro_xyz) {
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Gx_L, buf_reg, 6); // 0x19, 25
|
|
raw_gyro_xyz[0] = (short)((unsigned short)(buf_reg[1] << 8) | (buf_reg[0]));
|
|
raw_gyro_xyz[1] = (short)((unsigned short)(buf_reg[3] << 8) | (buf_reg[2]));
|
|
raw_gyro_xyz[2] = (short)((unsigned short)(buf_reg[5] << 8) | (buf_reg[4]));
|
|
}
|
|
}
|
|
|
|
void Qmi8658_read_raw_acc_xyz(void *acc_data)
|
|
{
|
|
unsigned char buf_reg[8];
|
|
imu_axis_data_t *raw_acc_xyz = (imu_axis_data_t *)acc_data;
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ax_L, buf_reg, 6); // 53
|
|
raw_acc_xyz->x = (short)((unsigned short)(buf_reg[1] << 8) | (buf_reg[0]));
|
|
raw_acc_xyz->y = (short)((unsigned short)(buf_reg[3] << 8) | (buf_reg[2]));
|
|
raw_acc_xyz->z = (short)((unsigned short)(buf_reg[5] << 8) | (buf_reg[4]));
|
|
|
|
/* log_info("Qmi8658 acc: %d %d %d\n", raw_acc_xyz->x, raw_acc_xyz->y, raw_acc_xyz->z); */
|
|
}
|
|
void Qmi8658_read_raw_gyro_xyz(void *gyro_data)
|
|
{
|
|
unsigned char buf_reg[6];
|
|
imu_axis_data_t *raw_gyro_xyz = (imu_axis_data_t *)gyro_data;
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Gx_L, buf_reg, 6); // 53
|
|
raw_gyro_xyz->x = (short)((unsigned short)(buf_reg[1] << 8) | (buf_reg[0]));
|
|
raw_gyro_xyz->y = (short)((unsigned short)(buf_reg[3] << 8) | (buf_reg[2]));
|
|
raw_gyro_xyz->z = (short)((unsigned short)(buf_reg[5] << 8) | (buf_reg[4]));
|
|
|
|
/* log_info("Qmi8658 gyro: %d %d %d\n", raw_gyro_xyz->x, raw_gyro_xyz->y, raw_gyro_xyz->z); */
|
|
}
|
|
void Qmi8658_read_raw_acc_gyro_xyz(void *raw_data)
|
|
{
|
|
unsigned char buf_reg[14];
|
|
short temp = 0;
|
|
imu_sensor_data_t *raw_sensor_data = (imu_sensor_data_t *)raw_data;
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Tempearture_L, buf_reg, 14); // 0x3b, 59
|
|
temp = ((short)buf_reg[1] << 8) | buf_reg[0];
|
|
raw_sensor_data->acc.x = (short)((unsigned short)(buf_reg[3] << 8) | (buf_reg[2]));
|
|
raw_sensor_data->acc.y = (short)((unsigned short)(buf_reg[5] << 8) | (buf_reg[4]));
|
|
raw_sensor_data->acc.z = (short)((unsigned short)(buf_reg[7] << 8) | (buf_reg[6]));
|
|
|
|
raw_sensor_data->gyro.x = (short)((unsigned short)(buf_reg[9] << 8) | (buf_reg[8]));
|
|
raw_sensor_data->gyro.y = (short)((unsigned short)(buf_reg[11] << 8) | (buf_reg[10]));
|
|
raw_sensor_data->gyro.z = (short)((unsigned short)(buf_reg[13] << 8) | (buf_reg[12]));
|
|
raw_sensor_data->temp_data = (float)temp / 256.0f;
|
|
/* log_info("Qmi8658 raw:acc_x:%d acc_y:%d acc_z:%d gyro_x:%d gyro_y:%d gyro_z:%d", raw_sensor_data->acc.x, raw_sensor_data->acc.y, raw_sensor_data->acc.z, raw_sensor_data->gyro.x, raw_sensor_data->gyro.y, raw_sensor_data->gyro.z); */
|
|
/* log_info("Qmi8658 temp:%d.%d\n", (u16)(raw_sensor_data->temp_data), (u16)(((u16)((raw_sensor_data->temp_data)* 100)) % 100)); */
|
|
}
|
|
|
|
|
|
void Qmi8658_read_ae(float quat[4], float velocity[3])
|
|
{
|
|
unsigned char buf_reg[14];
|
|
short raw_q_xyz[4];
|
|
short raw_v_xyz[3];
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Q1_L, buf_reg, 14);
|
|
raw_q_xyz[0] = (short)((unsigned short)(buf_reg[1] << 8) | (buf_reg[0]));
|
|
raw_q_xyz[1] = (short)((unsigned short)(buf_reg[3] << 8) | (buf_reg[2]));
|
|
raw_q_xyz[2] = (short)((unsigned short)(buf_reg[5] << 8) | (buf_reg[4]));
|
|
raw_q_xyz[3] = (short)((unsigned short)(buf_reg[7] << 8) | (buf_reg[6]));
|
|
|
|
raw_v_xyz[1] = (short)((unsigned short)(buf_reg[9] << 8) | (buf_reg[8]));
|
|
raw_v_xyz[2] = (short)((unsigned short)(buf_reg[11] << 8) | (buf_reg[10]));
|
|
raw_v_xyz[2] = (short)((unsigned short)(buf_reg[13] << 8) | (buf_reg[12]));
|
|
|
|
quat[0] = (float)(raw_q_xyz[0] * 1.0f) / ae_q_lsb_div;
|
|
quat[1] = (float)(raw_q_xyz[1] * 1.0f) / ae_q_lsb_div;
|
|
quat[2] = (float)(raw_q_xyz[2] * 1.0f) / ae_q_lsb_div;
|
|
quat[3] = (float)(raw_q_xyz[3] * 1.0f) / ae_q_lsb_div;
|
|
|
|
velocity[0] = (float)(raw_v_xyz[0] * 1.0f) / ae_v_lsb_div;
|
|
velocity[1] = (float)(raw_v_xyz[1] * 1.0f) / ae_v_lsb_div;
|
|
velocity[2] = (float)(raw_v_xyz[2] * 1.0f) / ae_v_lsb_div;
|
|
}
|
|
|
|
void Qmi8658_enableWakeOnMotion(enum Qmi8658_Interrupt int_set, enum Qmi8658_WakeOnMotionThreshold threshold, unsigned char blankingTime)
|
|
{
|
|
unsigned char cal1_1_reg = (unsigned char)threshold;
|
|
unsigned char cal1_2_reg = (unsigned char)int_set | (blankingTime & 0x3F);
|
|
unsigned char status1 = 0;
|
|
int count = 0;
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, QMI8658_CTRL7_DISABLE_ALL);
|
|
Qmi8658_config_acc(Qmi8658AccRange_8g, Qmi8658AccOdr_LowPower_21Hz, Qmi8658Lpf_Disable, Qmi8658St_Disable);
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, cal1_1_reg);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, cal1_2_reg);
|
|
// ctrl9 wom setting
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_WoM_Setting);
|
|
// ctrl9 wom setting
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, QMI8658_CTRL7_ACC_ENABLE);
|
|
}
|
|
|
|
void Qmi8658_disableWakeOnMotion(void)
|
|
{
|
|
unsigned char status1 = 0;
|
|
int count = 0;
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, QMI8658_CTRL7_DISABLE_ALL);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, 0);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, 0);
|
|
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_WoM_Setting);
|
|
}
|
|
|
|
void Qmi8658_enableSensors(unsigned char enableFlags)
|
|
{
|
|
|
|
if (enableFlags & QMI8658_CONFIG_AE_ENABLE) {
|
|
enableFlags |= QMI8658_CTRL7_ACC_ENABLE | QMI8658_CTRL7_GYR_ENABLE;
|
|
}
|
|
#if (QMI8658_SYNC_SAMPLE_MODE)
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, enableFlags | 0x80);
|
|
#else
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, enableFlags & QMI8658_CTRL7_ENABLE_MASK);
|
|
#endif
|
|
}
|
|
|
|
|
|
void Qmi8658_enable_acc_Sensors(unsigned char enableFlags)
|
|
{
|
|
unsigned char ctrl7 = 0;
|
|
if (enableFlags) {
|
|
// Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Timestamp_L, &ctrl7, 1);//
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, &ctrl7, 1);
|
|
ctrl7 |= QMI8658_CTRL7_ACC_ENABLE;
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, ctrl7 & QMI8658_CTRL7_ENABLE_MASK);
|
|
} else { // close acc
|
|
// Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Timestamp_L, &ctrl7, 1);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, &ctrl7, 1);
|
|
ctrl7 &= (~QMI8658_CTRL7_ACC_ENABLE);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, ctrl7 & QMI8658_CTRL7_ENABLE_MASK);
|
|
}
|
|
|
|
}
|
|
|
|
void Qmi8658_enable_gyro_Sensors(unsigned char enableFlags)
|
|
{
|
|
unsigned char ctrl7 = 0;
|
|
if (enableFlags) {
|
|
// Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Timestamp_L, &ctrl7, 1);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, &ctrl7, 1);
|
|
ctrl7 |= QMI8658_CTRL7_GYR_ENABLE;
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, ctrl7 & QMI8658_CTRL7_ENABLE_MASK);
|
|
} else { // close gyro
|
|
// Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Timestamp_L, &ctrl7, 1);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, &ctrl7, 1);
|
|
ctrl7 &= (~QMI8658_CTRL7_GYR_ENABLE);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, ctrl7 & QMI8658_CTRL7_ENABLE_MASK);
|
|
}
|
|
|
|
}
|
|
|
|
/*************************************************
|
|
*************************************************
|
|
模式切换具体时间查数据手册(差异较大)
|
|
*************************************************
|
|
*************************************************/
|
|
//15ms 后完成
|
|
void Qmi8658_reset(void)//
|
|
{
|
|
log_info("qmi8658_soft_reset \n");
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Reset, 0xb0);//
|
|
Qmi8658_delay(20); // delay
|
|
}
|
|
|
|
//如果是spi3wire模式,执行powerdown后, 必须配置spi为3wire(Qmi8658Register_Ctrl1[bit7=1])
|
|
/* void Qmi8658_power_down(void)//??? */
|
|
/* { */
|
|
/* Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, 0);//clk disable??? */
|
|
/* Qmi8658_enableSensors(0); */
|
|
/* } */
|
|
//进入: 只能Power-On Default 进入该模式
|
|
//退出: 先soft reset再init
|
|
u8 Qmi8658_power_down(void)//
|
|
{
|
|
u8 temp_data = 0;
|
|
/* Qmi8658_reset(); */
|
|
log_info("qmi8658_power_down\n");
|
|
//sensorDisable
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, &temp_data, 1);
|
|
temp_data |= BIT(0); //sensorDisable
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, temp_data);//
|
|
//close acc,gyro,,
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, &temp_data, 1);
|
|
temp_data &= ~0x0f;
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, temp_data);//
|
|
|
|
Qmi8658_delay(10); // delay
|
|
return 1;
|
|
}
|
|
|
|
//进入: 只能Power-On Default, Low Power Accel Only进入该模式
|
|
//退出: 先soft reset再init
|
|
void Qmi8658_low_power(void)//
|
|
{
|
|
u8 temp_data = 0;
|
|
/* Qmi8658_reset(); */
|
|
log_info("qmi8658_low_power\n");
|
|
//sensorenable
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, &temp_data, 1);
|
|
temp_data &= ~BIT(0); //sensor enable
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, temp_data);//
|
|
//close acc,gyro,,
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, &temp_data, 1);
|
|
temp_data &= ~0x0f;
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, temp_data);//
|
|
//aODR = 11xx
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl2, &temp_data, 1);
|
|
temp_data |= 0x0f;
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl2, temp_data);//
|
|
|
|
Qmi8658_delay(10); // delay
|
|
}
|
|
|
|
|
|
/*
|
|
* spi set:
|
|
* ctrl1: bit7: 3_wire_en
|
|
* bit6: iic/spi_addr_auto_inc
|
|
* bit5: spi_read_big_endian_en
|
|
* 4:1 : reserved
|
|
* bit0: disable internal 2 MHz oscillator
|
|
*/
|
|
void Qmi8658_spi_mode_set(u8 spi_3_wire_en)//仅上电初始化调用
|
|
{
|
|
unsigned char ctrl1 = 0;
|
|
if (spi_3_wire_en) {
|
|
ctrl1 = 0xa0; //默认开大端模式
|
|
} else {
|
|
ctrl1 = 0x20;
|
|
}
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, ctrl1);
|
|
}
|
|
void Qmi8658_spi_mode_switch(u8 spi_3_wire_en)
|
|
{
|
|
unsigned char ctrl1 = 0;
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, &ctrl1, 1);
|
|
if (spi_3_wire_en) {
|
|
ctrl1 |= 0xa0; //默认开大端模式
|
|
} else {
|
|
ctrl1 &= ~0x80;
|
|
ctrl1 |= 0x20;
|
|
}
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, ctrl1);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Qmi8658_Config_apply(struct Qmi8658Config const *config)
|
|
{
|
|
unsigned char fisSensors = config->inputSelection;
|
|
|
|
Qmi8658_enableSensors(QMI8658_CTRL7_DISABLE_ALL);
|
|
if (fisSensors & QMI8658_CONFIG_AE_ENABLE) {
|
|
Qmi8658_config_ae(config->aeOdr);
|
|
} else {
|
|
if (config->inputSelection & QMI8658_CONFIG_ACC_ENABLE) {
|
|
Qmi8658_config_acc(config->accRange, config->accOdr, Qmi8658Lpf_Disable, Qmi8658St_Disable);
|
|
}
|
|
if (config->inputSelection & QMI8658_CONFIG_GYR_ENABLE) {
|
|
Qmi8658_config_gyro(config->gyrRange, config->gyrOdr, Qmi8658Lpf_Enable, Qmi8658St_Disable);
|
|
}
|
|
}
|
|
|
|
if (config->inputSelection & QMI8658_CONFIG_MAG_ENABLE) {
|
|
Qmi8658_config_mag(config->magDev, config->magOdr);
|
|
}
|
|
|
|
Qmi8658_enableSensors(fisSensors);
|
|
}
|
|
|
|
|
|
#if (QMI8658_USE_STEP_EN)
|
|
unsigned char stepConfig(unsigned short odr) //11hz=0x0 ???
|
|
{
|
|
unsigned short ped_fix_peak, ped_sample_cnt, ped_time_up, ped_fix_peak2peak;
|
|
unsigned char ped_time_low, ped_time_cnt_entry, ped_fix_precision, ped_sig_count, basedODR;
|
|
//void* pi2c = qmi8658_i2c_init();
|
|
|
|
float finalRate;
|
|
//finalRate = 100.0/odr;
|
|
finalRate = 100.0 / odr; //14.285
|
|
ped_sample_cnt = (unsigned short)(0x0032 / finalRate) ;//6;//(unsigned short)(0x0032 / finalRate) ;
|
|
ped_fix_peak2peak = 0x00CC;
|
|
ped_fix_peak = 0x00CC;
|
|
ped_time_up = (unsigned short)(200.0 / finalRate);
|
|
ped_time_low = (unsigned char)(20 / finalRate) ;
|
|
ped_time_cnt_entry = 1;
|
|
ped_fix_precision = 0;
|
|
ped_sig_count = 1;//?????
|
|
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, ped_sample_cnt & 0xFF);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, (ped_sample_cnt >> 8) & 0xFF);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, ped_fix_peak2peak & 0xFF);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, (ped_fix_peak2peak >> 8) & 0xFF);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, ped_fix_peak & 0xFF);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, (ped_fix_peak >> 8) & 0xFF);
|
|
//Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_L, 0x01);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_H, 0x01);
|
|
log_info("+");
|
|
|
|
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_EnablePedometer);
|
|
log_info(".");
|
|
///////////////////////////////
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, ped_time_up & 0xFF);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, (ped_time_up >> 8) & 0xFF);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, ped_time_low);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, ped_time_cnt_entry);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, ped_fix_precision);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, ped_sig_count);
|
|
//Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_L, 0x02 );
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_H, 0x02);
|
|
log_info("-");
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_EnablePedometer);
|
|
log_info("*");
|
|
// qmi8658_i2c_deinit(pi2c);
|
|
|
|
|
|
}
|
|
|
|
|
|
uint32_t Qmi8658_step_read_stepcounter(uint32_t *step)
|
|
{
|
|
uint8_t reg_data[3] = {0};
|
|
uint8_t reg_47 = 0;
|
|
uint32_t rslt;
|
|
|
|
#if 1
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_AccEl_X, reg_data, 3);
|
|
#else
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_AccEl_X, reg_data, 1);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_AccEl_Y, ®_data[1], 1);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_AccEl_Z, ®_data[2], 1);
|
|
#endif
|
|
|
|
rslt = reg_data[2] << 16 | reg_data[1] << 8 | reg_data[0];
|
|
*step = rslt;
|
|
|
|
return rslt;
|
|
}
|
|
|
|
void step_disable(void)
|
|
{
|
|
unsigned char ctrl8_data = 0x00;
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, &ctrl8_data, 1);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, ctrl8_data & (~0x10)); // 0xD0
|
|
|
|
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, 0x00);
|
|
//Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_L, 0x01);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_H, 0x01);
|
|
log_info("+");
|
|
|
|
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_Reset_Pedometer);
|
|
log_info(".");
|
|
///////////////////////////////
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, 0x00);
|
|
//Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_L, 0x02 );
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_H, 0x02);
|
|
log_info("-");
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_Reset_Pedometer);
|
|
log_info("*");
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
/*****************************
|
|
*********** any motion config ctrl9
|
|
First CTRL9 Command:
|
|
write to CAL1_L the value of AnyMotionXThr.
|
|
write to CAL1_H the value of AnyMotionYThr.
|
|
write to CAL2_L the value of AnyMotionZThr.
|
|
write to CAL2_H the value of NoMotionXThr.
|
|
write to CAL3_L the value of NoMotionYThr.
|
|
write to CAL3_H the value of NoMotionZThr.
|
|
write to CAL4_L the value of MOTION_MODE_CTRL
|
|
write to CAL4_H the value of 0x01
|
|
write to CTRL9 the value of 0x0E // CTRL_CMD_CONFIGURE_MOTION = 0x0E
|
|
|
|
Second CTRL9 Command:
|
|
write to CAL1_L the value of AnyMotionWindow.
|
|
write to CAL1_H the value of NoMotionWindow
|
|
write to CAL2_L the value of SigMotionWaitWindow[7:0]
|
|
write to CAL2_H the value of SigMotionWaitWindow [15:8]
|
|
write to CAL3_L the value of SigMotionConfirmWindow[7:0]
|
|
write to CAL3_H the value of SigMotionConfirmWindow[15:8]
|
|
write to CAL4_H the value of 0x02
|
|
write to CTRL9 the value of 0x0E // CTRL_CMD_CONFIGURE_MOTION 0x0E
|
|
|
|
************************************/
|
|
#if (QMI8658_USE_ANYMOTION_EN)
|
|
/*******/
|
|
/*motion_g_th is bit5~bit7 , 1 bit is 1G . such as : 001 is 1G, 111 is 7G . */
|
|
/*motion_mg_th is bit0 ~bit4, 1bit is 1/32G = 32.25mg; 00001 is 32.25mg , 00002 is 32.25*2mg . motion_mg_th set range is 0~ 31 */
|
|
/*****/
|
|
unsigned char anymotion_Config(enum Qmi8658_anymotion_G_TH motion_g_th, unsigned char motion_mg_th) //11hz=0x0 ?????
|
|
{
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, (motion_g_th + motion_mg_th)); //0x03 // any motion X threshold U 3.5 first three bit(uint 1g) last five bit (uint 1/32 g)
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, (motion_g_th + motion_mg_th)); //0x03 //the value of AnyMotionYThr.
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, (motion_g_th + motion_mg_th)); //0x03 //the value of AnyMotionZThr.
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, 0x03);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, 0x03);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, 0x03);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_L, 0x07);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_H, 0x01);
|
|
log_info("+");
|
|
|
|
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_Motion);
|
|
log_info(".");
|
|
///////////////////////////////
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, 0x03); //0x05
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, 0x1a);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, 0x2c);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, 0x01);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, 0x64);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_H, 0x02);
|
|
log_info("-");
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_Motion);
|
|
log_info("*");
|
|
return 1;
|
|
}
|
|
|
|
|
|
void anymotion_lowpwr_config(void)
|
|
{
|
|
qmi8658_config.inputSelection = QMI8658_CONFIG_ACC_ENABLE;//QMI8658_CONFIG_ACCGYR_ENABLE;
|
|
qmi8658_config.accRange = Qmi8658AccRange_8g;
|
|
qmi8658_config.accOdr = Qmi8658AccOdr_LowPower_11Hz;//Qmi8658AccOdr_LowPower_3Hz;//Qmi8658AccOdr_LowPower_11Hz;
|
|
qmi8658_config.gyrRange = Qmi8658GyrRange_1024dps; //Qmi8658GyrRange_2048dps Qmi8658GyrRange_1024dps
|
|
qmi8658_config.gyrOdr = Qmi8658GyrOdr_250Hz;
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, 0xc2); // 0xC2
|
|
anymotion_Config(Qmi8658_1G, 3) ; // th = 1.1g;
|
|
|
|
//Qmi8658_Config_apply(&qmi8658_config);
|
|
}
|
|
|
|
|
|
void anymotion_high_odr_enable(void)
|
|
{
|
|
unsigned char ctrl8_data = 0x00;
|
|
|
|
/*
|
|
qmi8658_config.inputSelection = QMI8658_CONFIG_ACC_ENABLE;//QMI8658_CONFIG_ACCGYR_ENABLE;
|
|
qmi8658_config.accRange = Qmi8658AccRange_8g;
|
|
qmi8658_config.accOdr = Qmi8658AccOdr_125Hz;
|
|
qmi8658_config.gyrRange = Qmi8658GyrRange_1024dps; //Qmi8658GyrRange_2048dps Qmi8658GyrRange_1024dps
|
|
qmi8658_config.gyrOdr = Qmi8658GyrOdr_125Hz;
|
|
// qmi8658_config.magOdr = Qmi8658MagOdr_125Hz;
|
|
// qmi8658_config.magDev = MagDev_AKM09918;
|
|
// qmi8658_config.aeOdr = Qmi8658AeOdr_128Hz;
|
|
*/
|
|
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, &ctrl8_data, 1);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, ctrl8_data | 0xC2); // 0xC2
|
|
anymotion_Config(Qmi8658_1G, 3) ; //// th = 1.1g;
|
|
|
|
//Qmi8658_Config_apply(&qmi8658_config);
|
|
}
|
|
|
|
|
|
void anymotion_disable(void)
|
|
{
|
|
unsigned char ctrl8_data = 0x00;
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, &ctrl8_data, 1);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, ctrl8_data & (~0x02)); // 0xC2
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, 0x23); //0x03 // any motion X threshold U 3.5 first three bit(uint 1g) last five bit (uint 1/32 g)
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, 0x23); //0x03 //the value of AnyMotionYThr.
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, 0x23); //0x03 //the value of AnyMotionZThr.
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, 0x03);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, 0x03);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, 0x03);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_L, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_H, 0x01);
|
|
log_info("+");
|
|
|
|
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_Motion);
|
|
log_info(".");
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, 0x03); //0x05
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, 0x1a);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, 0x2c);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, 0x01);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, 0x64);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_H, 0x02);
|
|
log_info("-");
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_Motion);
|
|
log_info("*");
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
/***********************************
|
|
First CTRL9 Command:
|
|
write to CAL1_L the value of peakWindow. //30表示, 30 ms at 1000 Hz .就是ODR的个数。
|
|
write to CAL1_H the value of priority.
|
|
write to CAL2_L the value of TapWindow low byte. //100表示, 100 ms at 1000 Hz 就是ODR的个数。
|
|
write to CAL2_H the value of TapWindow high byte.
|
|
write to CAL3_L the value of DTapWindow low byte.
|
|
write to CAL3_H the value of DTapWindow high byte.
|
|
write to CAL4_H the value of 0x01
|
|
write to CTRL9 the value of 0x0C // CTRL_CMD_CONFIGURE_TAP = 0x0C
|
|
|
|
Second CTRL9 Command:
|
|
write to CAL1_L the value of alpha. //更新下个数据的百分比
|
|
write to CAL1_H the value of gamma. //差值数据更新的百分比
|
|
write to CAL2_L the value of peakMagThr low byte. xyz 模值的阀值。 敲的力度阀值
|
|
write to CAL2_H the value of peakMagThr high byte.
|
|
write to CAL3_L the value of UDMThr low byte. //停止敲击的,阀值,gamma与其有关。值设置越大,越容易满足条件。
|
|
write to CAL3_H the value of UDMThr high byte.
|
|
write to CAL4_H the value of 0x02
|
|
write to CTRL9 the value of 0x0C // CTRL_CMD_CONFIGURE_TAP 0x0C
|
|
|
|
|
|
*************************************************/
|
|
|
|
#if (QMI8658_USE_TAP_EN)
|
|
unsigned char tap_Config(void) //11hz=0x0e ????
|
|
{
|
|
#if 1 //alpha tap param
|
|
uint8_t peakWindow = 0x0e; //0x1e 30ms at 1000hz ODR.
|
|
uint8_t priority = 0x04;
|
|
uint16_t TapWindow = 0x000c; //0x0016 //0x0064 100MS at 100hz odr
|
|
uint16_t DTapWindow = 0x0058; //
|
|
uint8_t alpha = 0x40; //0x40; //0x08; //0.065 //alpha 百分比 =alpha[7] + alpha[6~0]* (1/128)
|
|
uint8_t gamma = 0x20; //0x10; //0x20;//0x20; //0.25 //gamma 百分比 =gamma[7] + gamma[6~0]* (1/128)
|
|
uint16_t peakMagThr = 0x0069;//0x0200;//0x0599//0x0599; // 1.4g
|
|
uint16_t UDMThr = 0x0049; //0x0100; //0x0199; // 0.4g
|
|
#endif //
|
|
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, peakWindow); //0x1E
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, priority); //0x03
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, TapWindow & 0xff); //0x64
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, (TapWindow >> 8) & 0xff);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, DTapWindow & 0xff);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, (DTapWindow >> 8) & 0xff);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_H, 0x01);
|
|
log_info("+");
|
|
|
|
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_EnableTap);
|
|
log_info(".");
|
|
///////////////////////////////
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, alpha);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, gamma); //0x20
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, peakMagThr & 0xff);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, (peakMagThr >> 8) & 0xff); //0x05
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, UDMThr & 0xff);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, (UDMThr >> 8) & 0xff); //0x01
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal4_H, 0x02);
|
|
log_info("-");
|
|
Qmi8658_send_ctl9cmd(Qmi8658_Ctrl9_Cmd_EnableTap);
|
|
log_info("*");
|
|
|
|
}
|
|
|
|
void tap_enable(void)
|
|
{
|
|
unsigned char ctrl8_data = 0x00;
|
|
|
|
/*
|
|
qmi8658_config.inputSelection = QMI8658_CONFIG_ACCGYR_ENABLE;//QMI8658_CONFIG_ACCGYR_ENABLE;
|
|
qmi8658_config.accRange = Qmi8658AccRange_2g;
|
|
qmi8658_config.accOdr = Qmi8658AccOdr_125Hz;
|
|
qmi8658_config.gyrRange = Qmi8658GyrRange_1024dps; //Qmi8658GyrRange_2048dps Qmi8658GyrRange_1024dps
|
|
qmi8658_config.gyrOdr = Qmi8658GyrOdr_125Hz;
|
|
//qmi8658_config.magOdr = Qmi8658MagOdr_125Hz;
|
|
//qmi8658_config.magDev = MagDev_AKM09918;
|
|
//qmi8658_config.aeOdr = Qmi8658AeOdr_128Hz;
|
|
*/
|
|
|
|
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, &ctrl8_data, 1);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, ctrl8_data | 0xc1); // 0xC2
|
|
tap_Config() ;
|
|
|
|
//Qmi8658_Config_apply(&qmi8658_config);
|
|
}
|
|
#endif
|
|
#if (QMI8658_NEW_HANDSHAKE)
|
|
void qmi8658_on_demand_cali(void)
|
|
{
|
|
unsigned char cod_status = 0x00;
|
|
unsigned char cod_data[6];
|
|
|
|
log_info("qmi8658_on_demand_cali start");
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl9, (unsigned char)Qmi8658_Ctrl9_Cmd_On_Demand_Cali);
|
|
Qmi8658_delay(2200); // delay 2000ms above
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl9, 0x00);//qmi8658_Ctrl9_Cmd_Ack
|
|
Qmi8658_delay(10); // delay
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, 0x70/* Qmi8658Register_Cod_Status */, &cod_status, 1);
|
|
if (cod_status) {
|
|
log_info("qmi8658_on_demand_cali fail! status=0x%x", cod_status);
|
|
} else {
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Dvx_L, &cod_data[0], 6);//qmi8658_get_gyro_gain
|
|
log_info("qmi8658_on_demand_cali done! cod[%d %d %d]",
|
|
(unsigned short)(cod_data[1] << 8 | cod_data[0]),
|
|
(unsigned short)(cod_data[3] << 8 | cod_data[2]),
|
|
(unsigned short)(cod_data[5] << 8 | cod_data[4]));
|
|
}
|
|
}
|
|
void qmi8658_apply_gyr_gain(unsigned char cod_data[6])
|
|
{
|
|
u8 cod_data_temp[8];
|
|
|
|
/* Qmi8658_enableSensors(QMI8658_CTRL7_DISABLE_ALL); */
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_L, cod_data[0]);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal1_H, cod_data[1]);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_L, cod_data[2]);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal2_H, cod_data[3]);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_L, cod_data[4]);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Cal3_H, cod_data[5]);
|
|
|
|
Qmi8658_send_ctl9cmd(0xaa);//(qmi8658_Ctrl9_Cmd_Apply_Gyro_Gain);
|
|
/* Qmi8658_enableSensors(QMI8658_CONFIG_ACCGYR_ENABLE); */
|
|
}
|
|
#endif
|
|
unsigned char qmi8658_init(u8 demand_cali_en)
|
|
{
|
|
unsigned char qmi8658_chip_id = 0x00;
|
|
unsigned char qmi8658_revision_id = 0x00;
|
|
unsigned char iCount = 0;
|
|
|
|
unsigned char fw_version[3] = {0};
|
|
unsigned char usid_version[6] = {0};
|
|
#if (QMI8658_USER_INTERFACE==QMI8658_USE_SPI)
|
|
if (qmi8658_info->spi_work_mode) {
|
|
Qmi8658_spi_mode_set(1);//使能spi_3_wire
|
|
} else {
|
|
Qmi8658_spi_mode_set(0);//使能spi_4_wire
|
|
}
|
|
#endif
|
|
while ((qmi8658_chip_id == 0x00) && (iCount < 10)) {
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_WhoAmI, &qmi8658_chip_id, 1);
|
|
if (qmi8658_chip_id == 0x05) {
|
|
break;
|
|
}
|
|
iCount++;
|
|
mdelay(1);
|
|
}
|
|
|
|
/* Qmi8658_read(QMI8658_SLAVE_ADDRESS, 0x49, fw_version, 3); */
|
|
/* log_info("Qmi8658_fw_version(Quaternion Increment dQW?)=0x%x, 0x%x, 0x%x \n", fw_version[0],fw_version[1],fw_version[2]); */
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Revision, &qmi8658_revision_id, 1);
|
|
|
|
if (qmi8658_chip_id == 0x05) {
|
|
log_info("Qmi8658_init slave=0x%x Qmi8658Register_WhoAmI=0x%x 0x%x\n", QMI8658_SLAVE_ADDRESS, qmi8658_chip_id, qmi8658_revision_id);
|
|
|
|
/* Qmi8658_read(QMI8658_SLAVE_ADDRESS, 0x51, usid_version, 6); */
|
|
/* log_info("Qmi8658_usid_version(Velocity Increment along XYZ?)=0x%x, 0x%x, 0x%x ,0x%x, 0x%x, 0x%x \n", usid_version[0],usid_version[1],usid_version[2] ,usid_version[3],usid_version[4],usid_version[5]); */
|
|
|
|
#if (QMI8658_NEW_HANDSHAKE==0)
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, &iCount, 1);
|
|
iCount |= 0x60;
|
|
iCount &= ~ 0x01;
|
|
/* iCount |= 0x04; */
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, iCount);//bit7:1:spi_3_wire, bit6:addr_auto_inc, bit5:spi_read_big_endian(大端),bit0:0:clkosc
|
|
#else
|
|
/* Qmi8658_reset(); */
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, 0x60 | 0x08 | 0x10); // 另一种qmi8658
|
|
if (demand_cali_en) {
|
|
qmi8658_on_demand_cali();
|
|
/* printf("set cod"); */
|
|
} else {
|
|
/* qmi8658_apply_gyr_gain(cod_data_copy); */
|
|
/* printf("restore cod"); */
|
|
}
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, 0x00);
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, 0xc0);
|
|
#endif
|
|
qmi8658_config.inputSelection = QMI8658_CONFIG_ACCGYR_ENABLE;//QMI8658_CONFIG_ACCGYR_ENABLE;
|
|
qmi8658_config.accRange = Qmi8658AccRange_16g;
|
|
qmi8658_config.accOdr = Qmi8658AccOdr_125Hz;
|
|
qmi8658_config.gyrRange = Qmi8658GyrRange_2048dps; //Qmi8658GyrRange_2048dps Qmi8658GyrRange_1024dps
|
|
qmi8658_config.gyrOdr = Qmi8658GyrOdr_125Hz;
|
|
|
|
#if (QMI8658_USE_TAP_EN)
|
|
tap_enable();
|
|
#endif
|
|
|
|
#if (QMI8658_USE_ANYMOTION_EN)
|
|
//anymotion_high_odr_enable();
|
|
anymotion_lowpwr_config();
|
|
#endif
|
|
|
|
#if (QMI8658_USE_FIFO_EN)
|
|
Qmi8658_config_fifo(128, Qmi8658_Fifo_128, Qmi8658_Fifo_Stream, QMI8658_FORMAT_12_BYTES);
|
|
#endif
|
|
|
|
#if (QMI8658_USE_STEP_EN)
|
|
qmi8658_config.inputSelection = QMI8658_CONFIG_ACC_ENABLE;
|
|
qmi8658_config.accRange = Qmi8658AccRange_8g;
|
|
qmi8658_config.accOdr = Qmi8658AccOdr_LowPower_21Hz;//Qmi8658AccOdr_62_5Hz;//Qmi8658AccOdr_LowPower_21Hz;
|
|
qmi8658_config.gyrRange = Qmi8658GyrRange_1024dps; //Qmi8658GyrRange_2048dps Qmi8658GyrRange_1024dps
|
|
qmi8658_config.gyrOdr = Qmi8658GyrOdr_500Hz;
|
|
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, 0x00); //
|
|
Qmi8658_write(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl8, 0xD0);
|
|
stepConfig(21); //ODR = 21hz
|
|
//stepConfig(62); //ODR = 62.5HZ
|
|
#endif
|
|
|
|
Qmi8658_Config_apply(&qmi8658_config);
|
|
#if 0
|
|
unsigned char read_data = 0x00;
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl1, &read_data, 1);
|
|
log_info("Qmi8658Register_Ctrl1=0x%x \n", read_data);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl2, &read_data, 1);
|
|
log_info("Qmi8658Register_Ctrl2=0x%x \n", read_data);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl3, &read_data, 1);
|
|
log_info("Qmi8658Register_Ctrl3=0x%x \n", read_data);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl4, &read_data, 1);
|
|
log_info("Qmi8658Register_Ctrl4=0x%x \n", read_data);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl5, &read_data, 1);
|
|
log_info("Qmi8658Register_Ctrl5=0x%x \n", read_data);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl6, &read_data, 1);
|
|
log_info("Qmi8658Register_Ctrl6=0x%x \n", read_data);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_Ctrl7, &read_data, 1);
|
|
log_info("Qmi8658Register_Ctrl7=0x%x \n", read_data);
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, 77, &qmi8658_revision_id, 1);
|
|
log_info("teset:0x%x", qmi8658_revision_id);
|
|
#endif
|
|
// Qmi8658_set_layout(2);
|
|
return 1;
|
|
} else {
|
|
log_error("Qmi8658_init fail\n");
|
|
qmi8658_chip_id = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static u8 qmi8658_int_pin1 = IO_PORTB_04;
|
|
static u8 qmi8658_int_pin2 = IO_PORTB_03;
|
|
//return:0:fail, 1:ok
|
|
u8 qmi8658_sensor_init(void *priv)
|
|
{
|
|
if (priv == NULL) {
|
|
log_error("qmi8658 init fail(no param)\n");
|
|
return 0;
|
|
}
|
|
qmi8658_info = (qmi8658_param *)priv;
|
|
|
|
#if (QMI8658_USER_INTERFACE==QMI8658_USE_I2C) //iic interface
|
|
iic_init(qmi8658_info->iic_hdl);
|
|
#elif (QMI8658_USER_INTERFACE==QMI8658_USE_SPI)//spi interface
|
|
spi_cs_init();
|
|
spi_init();
|
|
#else
|
|
//I3C
|
|
#endif
|
|
gpio_set_die(qmi8658_int_pin1, 1);
|
|
gpio_set_direction(qmi8658_int_pin1, 1);
|
|
// gpio_set_pull_up(qmi8658_int_pin1,1);
|
|
gpio_set_die(qmi8658_int_pin2, 1);
|
|
gpio_set_direction(qmi8658_int_pin2, 1);
|
|
// gpio_set_pull_up(qmi8658_int_pin2,1);
|
|
return qmi8658_init(1);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static volatile u32 qmi8658_init_flag ;
|
|
static u8 imu_busy = 0;
|
|
static qmi8658_param qmi8658_info_data;
|
|
/* #define SENSORS_MPU_BUFF_LEN 14 */
|
|
/* u8 read_qmi8658_buf[SENSORS_MPU_BUFF_LEN]; */
|
|
#if (QMI8658_USE_FIFO_EN)
|
|
u8 fifo_data[1024];//size:Qmi8658_FifoSize * 6 * Number_of_enabled_sensors
|
|
#endif
|
|
void qmi8658_int_callback()
|
|
{
|
|
if (qmi8658_init_flag == 0) {
|
|
log_error("qmi8658 init fail!");
|
|
return ;
|
|
}
|
|
if (imu_busy) {
|
|
log_error("qmi8658 busy!");
|
|
return ;
|
|
}
|
|
imu_busy = 1;
|
|
|
|
imu_sensor_data_t raw_sensor_datas;
|
|
float TempData = 0.0;
|
|
u8 status_temp = 0;
|
|
#if (QMI8658_USE_FIFO_EN)
|
|
u16 fifo_level = 0;
|
|
fifo_level = Qmi8658_read_fifo(fifo_data);
|
|
TempData = Qmi8658_readTemp();
|
|
/* log_info("qmi8658 raw:acc_x:%d acc_y:%d acc_z:%d gyro_x:%d gyro_y:%d gyro_z:%d, tim_count:%d", (s16)(fifo_data[1]<<8|fifo_data[0]), (s16)(fifo_data[3]<<8|fifo_data[2]), (s16)(fifo_data[5]<<8|fifo_data[4]), (s16)(fifo_data[7]<<8|fifo_data[6]), (s16)(fifo_data[9]<<8|fifo_data[8]), (s16)(fifo_data[11]<<8|fifo_data[10]),fifo_level);//共fifo_level组数据, 只打印第一组数据 */
|
|
#else
|
|
status_temp = Qmi8658_readStatus0();
|
|
/* log_info("status:0x%x", status_temp); */
|
|
if (status_temp & 0x03) {
|
|
Qmi8658_read_raw_acc_gyro_xyz(&raw_sensor_datas);//获取原始值
|
|
/* TempData=Qmi8658_readTemp(); */
|
|
TempData = raw_sensor_datas.temp_data;
|
|
/* log_info("qmi8658 raw:acc_x:%d acc_y:%d acc_z:%d gyro_x:%d gyro_y:%d gyro_z:%d", raw_sensor_datas.acc.x, raw_sensor_datas.acc.y, raw_sensor_datas.acc.z, raw_sensor_datas.gyro.x, raw_sensor_datas.gyro.y, raw_sensor_datas.gyro.z); */
|
|
}
|
|
#endif
|
|
/* log_info("qmi8658 temp:%d.%d\n", (u16)TempData, (u16)(((u16)(TempData * 100)) % 100)); */
|
|
imu_busy = 0;
|
|
}
|
|
|
|
s8 qmi8658_dev_init(void *arg)
|
|
{
|
|
if (arg == NULL) {
|
|
log_error("qmi8658 init fail(no arg)\n");
|
|
return -1;
|
|
}
|
|
#if (QMI8658_USER_INTERFACE==QMI8658_USE_I2C)
|
|
qmi8658_info_data.iic_hdl = ((struct imusensor_platform_data *)arg)->peripheral_hdl;
|
|
qmi8658_info_data.iic_delay = ((struct imusensor_platform_data *)arg)->peripheral_param0; //这个延时并非影响iic的时钟频率,而是2Byte数据之间的延时
|
|
// u8 iic_clk; //iic_clk: <=400kHz
|
|
#elif (QMI8658_USER_INTERFACE==QMI8658_USE_SPI)
|
|
qmi8658_info_data.spi_hdl = ((struct imusensor_platform_data *)arg)->peripheral_hdl, //SPIx (role:master)
|
|
qmi8658_info_data.spi_cs_pin = ((struct imusensor_platform_data *)arg)->peripheral_param0; //IO_PORTA_05
|
|
qmi8658_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: <=15MHz (spi结构体)
|
|
#else
|
|
//I3C
|
|
#endif
|
|
qmi8658_int_pin2 = ((struct imusensor_platform_data *)arg)->imu_sensor_int_io;
|
|
qmi8658_int_pin1 = qmi8658_int_pin2;
|
|
if (imu_busy) {
|
|
log_error("qmi8658 busy!");
|
|
return -1;
|
|
}
|
|
imu_busy = 1;
|
|
if (qmi8658_sensor_init(&qmi8658_info_data)) {
|
|
#if (QMI8658_USE_INT_EN) //中断模式,暂不支持
|
|
log_info("int mode en!");
|
|
/* port_wkup_enable(qmi8658_int_pin2, 1, qmi8658_int_callback); //PA08-IO中断,1:下降沿触发,回调函数qmi8658_int_callback*/
|
|
#ifdef CONFIG_CPU_BR23
|
|
io_ext_interrupt_init(qmi8658_int_pin2, 1, qmi8658_int_callback);
|
|
#elif defined(CONFIG_CPU_BR28)
|
|
// br28外部中断回调函数,按照现在的外部中断注册方式
|
|
// io配置在板级,定义在板级头文件,这里只是注册回调函数
|
|
/* port_edge_wkup_set_callback_by_index(3, qmi8658_int_callback); // 序号需要和板级配置中的wk_param对应上 */
|
|
port_edge_wkup_set_callback(qmi8658_int_callback);
|
|
#elif defined(CONFIG_CPU_BR27)
|
|
port_edge_wkup_set_callback(qmi8658_int_callback);
|
|
#endif
|
|
#else //定时
|
|
|
|
#endif
|
|
qmi8658_init_flag = 1;
|
|
imu_busy = 0;
|
|
log_info("qmi8658 Device init success!%d\n", qmi8658_init_flag);
|
|
return 0;
|
|
} else {
|
|
log_info("qmi8658 Device init fail!\n");
|
|
imu_busy = 0;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
int qmi8658_dev_ctl(u8 cmd, void *arg);
|
|
REGISTER_IMU_SENSOR(qmi8658_sensor) = {
|
|
.logo = "qmi8658",
|
|
.imu_sensor_init = qmi8658_dev_init,
|
|
.imu_sensor_check = NULL,
|
|
.imu_sensor_ctl = qmi8658_dev_ctl,
|
|
};
|
|
|
|
int qmi8658_dev_ctl(u8 cmd, void *arg)
|
|
{
|
|
int ret = -1;
|
|
u8 status_temp = 0;
|
|
if (qmi8658_init_flag == 0) {
|
|
log_error("qmi8658 init fail!");
|
|
return ret;//0:ok,,<0:err
|
|
}
|
|
if (imu_busy) {
|
|
log_error("qmi8658 busy!");
|
|
return ret;//0:ok,,<0:err
|
|
}
|
|
imu_busy = 1;
|
|
switch (cmd) {
|
|
case IMU_GET_SENSOR_NAME:
|
|
memcpy((u8 *)arg, &(qmi8658_sensor.logo), 20);
|
|
ret = 0;
|
|
break;
|
|
case IMU_SENSOR_ENABLE: //enable demand cali
|
|
/* cbuf_init(&hrsensor_cbuf, hrsensorcbuf, 24 * sizeof(int)); */
|
|
qmi8658_init(1);
|
|
ret = 0;
|
|
break;
|
|
case IMU_SENSOR_DISABLE:
|
|
/* cbuf_clear(&hrsensor_cbuf); */
|
|
//close power
|
|
Qmi8658_power_down();
|
|
ret = 0;
|
|
break;
|
|
case IMU_SENSOR_RESET://reset后必须enable
|
|
Qmi8658_reset();
|
|
ret = 0;
|
|
break;
|
|
case IMU_SENSOR_SLEEP:
|
|
if (Qmi8658_power_down()) {
|
|
log_info("qmi8658 enter sleep ok!");
|
|
ret = 0;
|
|
} else {
|
|
log_error("qmi8658 enter sleep fail!");
|
|
}
|
|
break;
|
|
case IMU_SENSOR_WAKEUP: //disable demand cali
|
|
if (qmi8658_init(0)) {
|
|
log_info("qmi8658 wakeup ok!");
|
|
ret = 0;
|
|
} else {
|
|
log_error("qmi8658 wakeup fail!");
|
|
}
|
|
break;
|
|
case IMU_SENSOR_INT_DET://传感器中断状态检查
|
|
break;
|
|
case IMU_SENSOR_DATA_READY://传感器数据准备就绪待读
|
|
break;
|
|
case IMU_SENSOR_CHECK_DATA://检查传感器缓存buf是否存满
|
|
break;
|
|
case IMU_SENSOR_READ_DATA://默认读传感器所有数据
|
|
status_temp = Qmi8658_readStatus0();
|
|
/* log_info("status:0x%x", status_temp); */
|
|
if (status_temp & 0x03) {
|
|
Qmi8658_read_raw_acc_gyro_xyz(arg);//获取原始值
|
|
ret = 0;
|
|
}
|
|
break;
|
|
case IMU_GET_ACCEL_DATA://加速度数据
|
|
/* float TempData = 0.0; */
|
|
status_temp = Qmi8658_readStatus0();
|
|
/* log_info("status:0x%x", status_temp); */
|
|
if (status_temp & 0x01) {
|
|
Qmi8658_read_raw_acc_xyz(arg);//获取原始值
|
|
ret = 0;
|
|
/* TempData = Qmi8658_readTemp(); */
|
|
}
|
|
break;
|
|
case IMU_GET_GYRO_DATA://陀螺仪数据
|
|
status_temp = Qmi8658_readStatus0();
|
|
/* log_info("status:0x%x", status_temp); */
|
|
if (status_temp & 0x02) {
|
|
Qmi8658_read_raw_gyro_xyz(arg);//获取原始值
|
|
ret = 0;
|
|
}
|
|
break;
|
|
case IMU_GET_MAG_DATA://磁力计数据
|
|
log_error("qmi8658 have no mag!\n");
|
|
break;
|
|
case IMU_SENSOR_SEARCH://检查传感器id
|
|
Qmi8658_read(QMI8658_SLAVE_ADDRESS, Qmi8658Register_WhoAmI, (u8 *)arg, 1);
|
|
if (*(u8 *)arg == 0x05) {
|
|
ret = 0;
|
|
log_info("qmi8658 online!\n");
|
|
} else {
|
|
log_error("qmi8658 offline!\n");
|
|
}
|
|
break;
|
|
case IMU_GET_SENSOR_STATUS://获取传感器状态
|
|
status_temp = Qmi8658_readStatus0();
|
|
*(u8 *)arg = status_temp;
|
|
ret = 0;
|
|
break;
|
|
case IMU_SET_SENSOR_FIFO_CONFIG://配置传感器FIFO
|
|
#if (QMI8658_USE_FIFO_EN)
|
|
u8 *tmp = (u8 *)arg;
|
|
u8 wm_th = tmp[0];
|
|
u8 fifo_size = tmp[1];//Qmi8658_Fifo_64
|
|
u8 fifo_mode = tmp[2];//Qmi8658_Fifo_Stream
|
|
u8 fifo_format = tmp[3];//QMI8658_FORMAT_12_BYTES
|
|
Qmi8658_config_fifo(wm_th, fifo_size, fifo_mode, fifo_format);
|
|
ret = 0;
|
|
#endif
|
|
break;
|
|
case IMU_GET_SENSOR_READ_FIFO://读取传感器FIFO数据
|
|
#if (QMI8658_USE_FIFO_EN)
|
|
ret = Qmi8658_read_fifo((u8 *)arg);
|
|
#endif
|
|
break;
|
|
case IMU_SET_SENSOR_TEMP_DISABLE://温度传感器无法控制
|
|
u8 temp = *(u8 *)arg;
|
|
ret = 0;
|
|
break;
|
|
default:
|
|
log_error("--cmd err!\n");
|
|
break;
|
|
}
|
|
imu_busy = 0;
|
|
return ret;//0:ok,,<0:err
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|