2162 lines
72 KiB
C
2162 lines
72 KiB
C
/******************************************************************
|
|
* Senodia 6D IMU(Gyroscope+Accelerometer) SH3001 driver, By Senodia AE;
|
|
*
|
|
*
|
|
* 1. unsigned char SH3001_init(void) : SH3001 initialize function
|
|
* 2. void SH3001_GetImuData( ... ): SH3001 read gyro and accel data function
|
|
* 3. float SH3001_GetTempData(void)£ºSH3001 read termperature function
|
|
* 4. void SH3001_pre_INT_config(void): Before using other INT config functions, need to call the function
|
|
*
|
|
* For example: set accelerometer data ready INT
|
|
* SH3001_pre_INT_config();
|
|
*
|
|
* SH3001_INT_Config( SH3001_INT0_LEVEL_HIGH,
|
|
* SH3001_INT_NO_LATCH,
|
|
* SH3001_INT1_LEVEL_HIGH,
|
|
* SH3001_INT_CLEAR_STATUS,
|
|
* SH3001_INT1_NORMAL,
|
|
* SH3001_INT0_NORMAL,
|
|
* 3);
|
|
*
|
|
* SH3001_INT_Enable( SH3001_INT_ACC_READY,
|
|
* SH3001_INT_ENABLE,
|
|
* SH3001_INT_MAP_INT);
|
|
*
|
|
* 5. void SH3001_INT_Flat_Config( unsigned char flatTimeTH, unsigned char flatTanHeta2)£º
|
|
* If using the function, need to config SH3001_INT_Orient_Config( ... ) function.
|
|
*
|
|
* 6. delay_ms(x): delay x millisecond.
|
|
*
|
|
* 7. New version SH3001: SH3001_CHIP_ID1(0xDF) = 0x61;
|
|
* SH3001_CompInit(... ): initialize compensation coefficients;
|
|
* SH3001_GetImuCompData( ... ): SH3001 read gyro and accel compensation data function
|
|
*
|
|
*
|
|
******************************************************************/
|
|
#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 "sh3001.h"
|
|
#include "imuSensor_manage.h"
|
|
|
|
|
|
#if TCFG_SH3001_ENABLE
|
|
|
|
|
|
/*************Betterlife ic debug***********/
|
|
#undef LOG_TAG_CONST
|
|
#define LOG_TAG "[sh3001]"
|
|
#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 sh3001_param *sh3001_info;
|
|
|
|
// static SH3001_data SH3001_raw_data={0};
|
|
|
|
/******************************************************************
|
|
* Description: I2C or SPI bus interface functions and delay time function
|
|
*
|
|
* Parameters:
|
|
* devAddr: I2C device address, modify the macro(SH3001_ADDRESS @SH3001.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 (SH3001_USER_INTERFACE==0)
|
|
|
|
#if TCFG_SH3001_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
|
|
|
|
//return: readLen:ok, other:fail
|
|
unsigned char I2C_Read_NBytes(unsigned char devAddr,
|
|
unsigned char regAddr,
|
|
unsigned char readLen,
|
|
unsigned char *readBuf)
|
|
{
|
|
u8 i = 0;
|
|
iic_start(sh3001_info->iic_hdl);
|
|
if (0 == iic_tx_byte(sh3001_info->iic_hdl, devAddr)) {
|
|
log_error("sh3001 iic read err1");
|
|
iic_stop(sh3001_info->iic_hdl);
|
|
return 0;
|
|
}
|
|
delay(sh3001_info->iic_delay);
|
|
if (0 == iic_tx_byte(sh3001_info->iic_hdl, regAddr)) {
|
|
log_error("sh3001 iic read err2");
|
|
iic_stop(sh3001_info->iic_hdl);
|
|
return 0;
|
|
}
|
|
delay(sh3001_info->iic_delay);
|
|
|
|
iic_start(sh3001_info->iic_hdl);
|
|
if (0 == iic_tx_byte(sh3001_info->iic_hdl, devAddr + 1)) {
|
|
log_error("sh3001 iic read err3");
|
|
iic_stop(sh3001_info->iic_hdl);
|
|
return 0;
|
|
}
|
|
for (i = 0; i < readLen; i++) {
|
|
delay(sh3001_info->iic_delay);
|
|
if (i == (readLen - 1)) {
|
|
*readBuf++ = iic_rx_byte(sh3001_info->iic_hdl, 0);
|
|
} else {
|
|
*readBuf++ = iic_rx_byte(sh3001_info->iic_hdl, 1);
|
|
}
|
|
}
|
|
iic_stop(sh3001_info->iic_hdl);
|
|
|
|
return i;
|
|
}
|
|
|
|
unsigned char I2C_Write_NBytes(unsigned char devAddr,
|
|
unsigned char regAddr,
|
|
unsigned char writeLen,
|
|
unsigned char *writeBuf)
|
|
{
|
|
u8 i;
|
|
iic_start(sh3001_info->iic_hdl);
|
|
if (0 == iic_tx_byte(sh3001_info->iic_hdl, devAddr)) {
|
|
log_error("sh3001 iic write err1");
|
|
iic_stop(sh3001_info->iic_hdl);
|
|
return 0;
|
|
}
|
|
delay(sh3001_info->iic_delay);
|
|
if (0 == iic_tx_byte(sh3001_info->iic_hdl, regAddr)) {
|
|
log_error("sh3001 iic write err2");
|
|
iic_stop(sh3001_info->iic_hdl);
|
|
return 0;
|
|
}
|
|
|
|
for (i = 0; i < writeLen; i++) {
|
|
delay(sh3001_info->iic_delay);
|
|
if (0 == iic_tx_byte(sh3001_info->iic_hdl, writeBuf[i])) {
|
|
log_error("sh3001 iic write err3:%d", i);
|
|
iic_stop(sh3001_info->iic_hdl);
|
|
return 0;
|
|
}
|
|
}
|
|
iic_stop(sh3001_info->iic_hdl);
|
|
return i;
|
|
}
|
|
|
|
IMU_read SH3001_read = I2C_Read_NBytes;
|
|
IMU_write SH3001_write = I2C_Write_NBytes;
|
|
|
|
#else
|
|
|
|
#define spi_cs_init() \
|
|
do { \
|
|
gpio_write(sh3001_info->spi_cs_pin, 1); \
|
|
gpio_set_direction(sh3001_info->spi_cs_pin, 0); \
|
|
gpio_set_die(sh3001_info->spi_cs_pin, 1); \
|
|
} while (0)
|
|
#define spi_cs_uninit() \
|
|
do { \
|
|
gpio_set_die(sh3001_info->spi_cs_pin, 0); \
|
|
gpio_set_direction(sh3001_info->spi_cs_pin, 1); \
|
|
gpio_set_pull_up(sh3001_info->spi_cs_pin, 0); \
|
|
gpio_set_pull_down(sh3001_info->spi_cs_pin, 0); \
|
|
} while (0)
|
|
#define spi_cs_h() gpio_write(sh3001_info->spi_cs_pin, 1)
|
|
#define spi_cs_l() gpio_write(sh3001_info->spi_cs_pin, 0)
|
|
|
|
#define spi_read_byte() spi_recv_byte(sh3001_info->spi_hdl, NULL)
|
|
#define spi_write_byte(x) spi_send_byte(sh3001_info->spi_hdl, x)
|
|
#define spi_dma_read(x, y) spi_dma_recv(sh3001_info->spi_hdl, x, y)
|
|
#define spi_dma_write(x, y) spi_dma_send(sh3001_info->spi_hdl, x, y)
|
|
#define spi_set_width(x) spi_set_bit_mode(sh3001_info->spi_hdl, x)
|
|
#define spi_init() spi_open(sh3001_info->spi_hdl)
|
|
#define spi_closed() spi_close(sh3001_info->spi_hdl)
|
|
#define spi_suspend() hw_spi_suspend(sh3001_info->spi_hdl)
|
|
#define spi_resume() hw_spi_resume(sh3001_info->spi_hdl)
|
|
|
|
unsigned char SPI_readNBytes(unsigned char devAddr,
|
|
unsigned char regAddr,
|
|
unsigned char readLen,
|
|
unsigned char *readBuf)
|
|
{
|
|
unsigned char data;
|
|
data = (regAddr > 0x7F) ? 0x01 : 0x00;
|
|
spi_cs_l();
|
|
spi_write_byte(SH3001_SPI_REG_ACCESS);
|
|
spi_write_byte(data);
|
|
spi_cs_h();
|
|
delay(60);
|
|
|
|
spi_cs_l();
|
|
spi_write_byte(regAddr | 0x80);
|
|
spi_dma_read(readBuf, readLen);
|
|
spi_cs_h();
|
|
//SPIWrite(SH3001_SPI_REG_ACCESS, &u8Data, 1);
|
|
//SPIRead((regAddr | 0x80), readBuf, readLen);
|
|
return (SH3001_TRUE);
|
|
}
|
|
|
|
unsigned char SPI_writeNBytes(unsigned char devAddr,
|
|
unsigned char regAddr,
|
|
unsigned char writeLen,
|
|
unsigned char *writeBuf)
|
|
{
|
|
unsigned char data;
|
|
data = (regAddr > 0x7F) ? 0x01 : 0x00;
|
|
spi_cs_l();
|
|
spi_write_byte(SH3001_SPI_REG_ACCESS);
|
|
spi_write_byte(data);
|
|
spi_cs_h();
|
|
delay(60);
|
|
|
|
spi_cs_l();
|
|
spi_write_byte(regAddr & 0x7F);
|
|
spi_dma_write(writeBuf, writeLen);
|
|
spi_cs_h();
|
|
//SPIWrite(SH3001_SPI_REG_ACCESS, &u8Data, 1);
|
|
//SPIWrite((regAddr & 0x7F), writeBuf, writeLen);
|
|
return (SH3001_TRUE);
|
|
}
|
|
|
|
IMU_read SH3001_read = SPI_readNBytes;
|
|
IMU_write SH3001_write = SPI_writeNBytes;
|
|
|
|
#endif
|
|
|
|
|
|
void delay_ms(unsigned char mSecond)
|
|
{
|
|
//your delay code(mSecond: millisecond):
|
|
MDELAY(mSecond);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: Local Variable
|
|
******************************************************************/
|
|
static compCoefType compCoef;
|
|
static unsigned char storeAccODR;
|
|
|
|
|
|
/******************************************************************
|
|
* Description: Local Function Prototypes
|
|
******************************************************************/
|
|
static void SH3001_SoftReset(void);
|
|
static void SH3001_ADCReset(void);
|
|
static void SH3001_CVAReset(void);
|
|
static void SH3001_DriveStart(void);
|
|
static void SH3001_ModuleReset(void);
|
|
|
|
static void SH3001_Acc_Config(unsigned char accODR,
|
|
unsigned char accRange,
|
|
unsigned char accCutOffRreq,
|
|
unsigned char accFilterEnble);
|
|
|
|
static void SH3001_Gyro_Config(unsigned char gyroODR,
|
|
unsigned char gyroRangeX,
|
|
unsigned char gyroRangeY,
|
|
unsigned char gyroRangeZ,
|
|
unsigned char gyroCutOffRreq,
|
|
unsigned char gyroFilterEnble);
|
|
|
|
static void SH3001_Temp_Config(unsigned char tempODR,
|
|
unsigned char tempEnable);
|
|
|
|
static void SH3001_CompInit(compCoefType *compCoef);
|
|
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: reset Register;
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
static void SH3001_SoftReset(void)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
regData = 0x84;
|
|
SH3001_write(SH3001_ADDRESS, 0xD4, 1, ®Data);
|
|
delay_ms(1);
|
|
regData = 0x04;
|
|
SH3001_write(SH3001_ADDRESS, 0xD4, 1, ®Data);
|
|
delay_ms(1);
|
|
regData = 0x08;
|
|
SH3001_write(SH3001_ADDRESS, 0x2F, 1, ®Data);
|
|
delay_ms(1);
|
|
regData = 0x73;
|
|
SH3001_write(SH3001_ADDRESS, 0x00, 1, ®Data);
|
|
delay_ms(50);
|
|
}
|
|
|
|
/******************************************************************
|
|
* Description: SH3001_DriveStart function;
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
static void SH3001_DriveStart(void)
|
|
{
|
|
unsigned char regAddr[3] = {0x2E, 0xC0, 0xC1};
|
|
unsigned char regData[3] = {0};
|
|
unsigned char regDataBack[3] = {0};
|
|
unsigned char i = 0;
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
SH3001_read(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
|
|
regDataBack[0] = 0xBF;
|
|
regDataBack[1] = 0x38;
|
|
regDataBack[2] = 0xFF;
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
SH3001_write(SH3001_ADDRESS, regAddr[i], 1, ®DataBack[i]);
|
|
}
|
|
|
|
delay_ms(100);
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
SH3001_write(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);;
|
|
}
|
|
|
|
delay_ms(50);
|
|
}
|
|
|
|
/******************************************************************
|
|
* Description: reset ADC;
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
static void SH3001_ADCReset(void)
|
|
{
|
|
unsigned char regAddr[2] = {0xD3, 0xD5};
|
|
unsigned char regData[2] = {0};
|
|
unsigned char i = 0;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
SH3001_read(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
|
|
regData[0] = (regData[0] & 0xFC) | 0x01;
|
|
regData[1] = (regData[1] & 0xF9) | 0x02;
|
|
SH3001_write(SH3001_ADDRESS, 0xD5, 1, ®Data[1]);
|
|
SH3001_write(SH3001_ADDRESS, 0xD3, 1, ®Data[0]);
|
|
delay_ms(1);
|
|
regData[0] = (regData[0] & 0xFC) | 0x02;
|
|
SH3001_write(SH3001_ADDRESS, 0xD3, 1, ®Data[0]);
|
|
delay_ms(1);
|
|
regData[1] = (regData[1] & 0xF9);
|
|
SH3001_write(SH3001_ADDRESS, 0xD5, 1, ®Data[1]);
|
|
delay_ms(50);
|
|
}
|
|
|
|
/******************************************************************
|
|
* Description: reset CVA;
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
static void SH3001_CVAReset(void)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, 0xD4, 1, ®Data);
|
|
regData |= 0x08;
|
|
SH3001_write(SH3001_ADDRESS, 0xD4, 1, ®Data);
|
|
delay_ms(10);
|
|
regData &= 0xF7;
|
|
SH3001_write(SH3001_ADDRESS, 0xD4, 1, ®Data);
|
|
}
|
|
|
|
/******************************************************************
|
|
* Description: reset some internal modules;
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
static void SH3001_ModuleReset(void)
|
|
{
|
|
//unsigned char regData = 0;
|
|
|
|
SH3001_SoftReset();
|
|
|
|
#if (SH3001_USER_INTERFACE)
|
|
if (sh3001_info->spi_work_mode) {
|
|
SH3001_SPI_Config(SH3001_SPI_3_WIRE);
|
|
} else {
|
|
SH3001_SPI_Config(SH3001_SPI_4_WIRE);
|
|
}
|
|
#endif
|
|
|
|
SH3001_DriveStart();
|
|
|
|
SH3001_ADCReset();
|
|
|
|
SH3001_CVAReset();
|
|
|
|
//set INT and INT1 Pin to Open-drain, in order to measure chip current
|
|
//regData = 0x00;
|
|
//SH3001_write(SH3001_ADDRESS, 0x44, 1, ®Data);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.Switch SH3001 power mode;
|
|
* 2.Normal mode: 1.65mA; Sleep mode: 162uA; Acc normal mode:393uA;
|
|
*
|
|
* Parameters: powerMode
|
|
* SH3001_NORMAL_MODE
|
|
* SH3001_SLEEP_MODE
|
|
* SH3001_POWERDOWN_MODE
|
|
* SH3001_ACC_NORMAL_MODE
|
|
*
|
|
* return: SH3001_FALSE or SH3001_TRUE
|
|
*
|
|
******************************************************************/
|
|
unsigned char SH3001_SwitchPowerMode(unsigned char powerMode)
|
|
{
|
|
unsigned char regAddr[11] = {0xCF, 0x22, 0x2F, 0xCB, 0xCE, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8};
|
|
unsigned char regData[11] = {0};
|
|
unsigned char i = 0;
|
|
unsigned char accODR = SH3001_ODR_1000HZ;
|
|
|
|
if ((powerMode != SH3001_NORMAL_MODE)
|
|
&& (powerMode != SH3001_SLEEP_MODE)
|
|
&& (powerMode != SH3001_POWERDOWN_MODE)
|
|
&& (powerMode != SH3001_ACC_NORMAL_MODE)) {
|
|
return (SH3001_FALSE);
|
|
}
|
|
|
|
|
|
for (i = 0; i < 11; i++) {
|
|
SH3001_read(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
|
|
switch (powerMode) {
|
|
case SH3001_NORMAL_MODE:
|
|
// restore accODR
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACC_CONF1, 1, &storeAccODR);
|
|
|
|
regData[0] = (regData[0] & 0xF8);
|
|
regData[1] = (regData[1] & 0x7F);
|
|
regData[2] = (regData[2] & 0xF7);
|
|
regData[3] = (regData[3] & 0xF7);
|
|
regData[4] = (regData[4] & 0xFE);
|
|
regData[5] = (regData[5] & 0xFC) | 0x02;
|
|
regData[6] = (regData[6] & 0x9F);
|
|
regData[7] = (regData[7] & 0xF9);
|
|
regData[10] = (regData[10] & 0xF7);
|
|
for (i = 0; i < 8; i++) {
|
|
SH3001_write(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
SH3001_write(SH3001_ADDRESS, regAddr[10], 1, ®Data[10]);
|
|
|
|
regData[7] = (regData[7] & 0x87);
|
|
regData[8] = (regData[8] & 0x1F);
|
|
regData[9] = (regData[9] & 0x03);
|
|
regData[10] = (regData[10] & 0x1F);
|
|
for (i = 7; i < 11; i++) {
|
|
SH3001_write(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
SH3001_DriveStart();
|
|
SH3001_ADCReset();
|
|
SH3001_CVAReset();
|
|
return (SH3001_TRUE);
|
|
|
|
case SH3001_SLEEP_MODE:
|
|
// store current acc ODR
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ACC_CONF1, 1, &storeAccODR);
|
|
// set acc ODR=1000Hz
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACC_CONF1, 1, &accODR);
|
|
|
|
regData[0] = (regData[0] & 0xF8) | 0x07;
|
|
regData[1] = (regData[1] & 0x7F) | 0x80;
|
|
regData[2] = (regData[2] & 0xF7) | 0x08;
|
|
regData[3] = (regData[3] & 0xF7) | 0x08;
|
|
regData[4] = (regData[4] & 0xFE);
|
|
regData[5] = (regData[5] & 0xFC) | 0x01;
|
|
regData[6] = (regData[6] & 0x9F);
|
|
regData[7] = (regData[7] & 0xF9) | 0x06;
|
|
regData[10] = (regData[10] & 0xF7);
|
|
for (i = 0; i < 8; i++) {
|
|
SH3001_write(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
SH3001_write(SH3001_ADDRESS, regAddr[10], 1, ®Data[10]);
|
|
|
|
regData[7] = (regData[7] & 0x87);
|
|
regData[8] = (regData[8] & 0x1F);
|
|
regData[9] = (regData[9] & 0x03);
|
|
regData[10] = (regData[10] & 0x1F);
|
|
for (i = 7; i < 11; i++) {
|
|
SH3001_write(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
return (SH3001_TRUE);
|
|
|
|
case SH3001_POWERDOWN_MODE:
|
|
regData[0] = (regData[0] & 0xF8);
|
|
regData[1] = (regData[1] & 0x7F) | 0x80;
|
|
regData[2] = (regData[2] & 0xF7) | 0x08;
|
|
regData[3] = (regData[3] & 0xF7) | 0x08;
|
|
regData[4] = (regData[4] & 0xFE);
|
|
regData[5] = (regData[5] & 0xFC) | 0x01;
|
|
regData[6] = (regData[6] & 0x9F) | 0x60;
|
|
regData[7] = (regData[7] & 0xF9) | 0x06;
|
|
regData[10] = (regData[10] & 0xF7);
|
|
for (i = 0; i < 8; i++) {
|
|
SH3001_write(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
SH3001_write(SH3001_ADDRESS, regAddr[10], 1, ®Data[10]);
|
|
|
|
regData[7] = (regData[7] & 0x87);
|
|
regData[8] = (regData[8] & 0x1F);
|
|
regData[9] = (regData[9] & 0x03);
|
|
regData[10] = (regData[10] & 0x1F) | 0xE0;
|
|
for (i = 7; i < 11; i++) {
|
|
SH3001_write(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
return (SH3001_TRUE);
|
|
|
|
case SH3001_ACC_NORMAL_MODE:
|
|
regData[0] = (regData[0] & 0xF8);
|
|
regData[1] = (regData[1] & 0x7F);
|
|
regData[2] = (regData[2] & 0xF7);
|
|
regData[3] = (regData[3] & 0xF7);
|
|
regData[4] = (regData[4] | 0x01);
|
|
regData[5] = (regData[5] & 0xFC) | 0x01;
|
|
regData[6] = (regData[6] & 0x9F);
|
|
regData[7] = (regData[7] & 0xF9) | 0x06;
|
|
regData[10] = (regData[10] & 0xF7);
|
|
for (i = 0; i < 8; i++) {
|
|
SH3001_write(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
SH3001_write(SH3001_ADDRESS, regAddr[10], 1, ®Data[10]);
|
|
|
|
regData[7] = (regData[7] & 0x87) | 0x78;
|
|
regData[8] = (regData[8] & 0x1F) | 0xE0;
|
|
regData[9] = (regData[9] & 0x03) | 0xFC;
|
|
regData[10] = (regData[10] & 0x1F);
|
|
for (i = 7; i < 11; i++) {
|
|
SH3001_write(SH3001_ADDRESS, regAddr[i], 1, ®Data[i]);
|
|
}
|
|
return (SH3001_TRUE);
|
|
|
|
default:
|
|
return (SH3001_FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.set accelerometer parameters;
|
|
* 2.accCutOffRreq = accODR * 0.40 or accODR * 0.25 or accODR * 0.11 or accODR * 0.04;
|
|
*
|
|
* Parameters: accODR accRange accCutOffFreq accFilterEnble
|
|
* SH3001_ODR_1000HZ SH3001_ACC_RANGE_16G SH3001_ACC_ODRX040 SH3001_ACC_FILTER_EN
|
|
* SH3001_ODR_500HZ SH3001_ACC_RANGE_8G SH3001_ACC_ODRX025 SH3001_ACC_FILTER_DIS
|
|
* SH3001_ODR_250HZ SH3001_ACC_RANGE_4G SH3001_ACC_ODRX011
|
|
* SH3001_ODR_125HZ SH3001_ACC_RANGE_2G SH3001_ACC_ODRX004
|
|
* SH3001_ODR_63HZ
|
|
* SH3001_ODR_31HZ
|
|
* SH3001_ODR_16HZ
|
|
* SH3001_ODR_2000HZ
|
|
* SH3001_ODR_4000HZ
|
|
* SH3001_ODR_8000HZ
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
static void SH3001_Acc_Config(unsigned char accODR,
|
|
unsigned char accRange,
|
|
unsigned char accCutOffFreq,
|
|
unsigned char accFilterEnble)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
// enable acc digital filter
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ACC_CONF0, 1, ®Data);
|
|
regData |= 0x01;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACC_CONF0, 1, ®Data);
|
|
|
|
// set acc ODR
|
|
storeAccODR = accODR;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACC_CONF1, 1, &accODR);
|
|
|
|
// set acc Range
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACC_CONF2, 1, &accRange);
|
|
|
|
// bypass acc low pass filter or not
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ACC_CONF3, 1, ®Data);
|
|
regData &= 0x17;
|
|
regData |= (accCutOffFreq | accFilterEnble);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACC_CONF3, 1, ®Data);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.set gyroscope parameters;
|
|
* 2.gyroCutOffRreq is at Page 32 of SH3001 datasheet.
|
|
*
|
|
* Parameters: gyroODR gyroRangeX,Y,Z gyroCutOffFreq gyroFilterEnble
|
|
* SH3001_ODR_1000HZ SH3001_GYRO_RANGE_125 SH3001_GYRO_ODRX00 SH3001_GYRO_FILTER_EN
|
|
* SH3001_ODR_500HZ SH3001_GYRO_RANGE_250 SH3001_GYRO_ODRX01 SH3001_GYRO_FILTER_DIS
|
|
* SH3001_ODR_250HZ SH3001_GYRO_RANGE_500 SH3001_GYRO_ODRX02
|
|
* SH3001_ODR_125HZ SH3001_GYRO_RANGE_1000 SH3001_GYRO_ODRX03
|
|
* SH3001_ODR_63HZ SH3001_GYRO_RANGE_2000
|
|
* SH3001_ODR_31HZ
|
|
* SH3001_ODR_16HZ
|
|
* SH3001_ODR_2000HZ
|
|
* SH3001_ODR_4000HZ
|
|
* SH3001_ODR_8000HZ
|
|
* SH3001_ODR_16000HZ
|
|
* SH3001_ODR_32000HZ
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
static void SH3001_Gyro_Config(unsigned char gyroODR,
|
|
unsigned char gyroRangeX,
|
|
unsigned char gyroRangeY,
|
|
unsigned char gyroRangeZ,
|
|
unsigned char gyroCutOffFreq,
|
|
unsigned char gyroFilterEnble)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
// enable gyro digital filter
|
|
SH3001_read(SH3001_ADDRESS, SH3001_GYRO_CONF0, 1, ®Data);
|
|
regData |= 0x01;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_GYRO_CONF0, 1, ®Data);
|
|
|
|
// set gyro ODR
|
|
SH3001_write(SH3001_ADDRESS, SH3001_GYRO_CONF1, 1, &gyroODR);
|
|
|
|
// set gyro X\Y\Z range
|
|
SH3001_write(SH3001_ADDRESS, SH3001_GYRO_CONF3, 1, &gyroRangeX);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_GYRO_CONF4, 1, &gyroRangeY);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_GYRO_CONF5, 1, &gyroRangeZ);
|
|
|
|
// bypass gyro low pass filter or not
|
|
SH3001_read(SH3001_ADDRESS, SH3001_GYRO_CONF2, 1, ®Data);
|
|
regData &= 0xE3;
|
|
regData |= (gyroCutOffFreq | gyroFilterEnble);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_GYRO_CONF2, 1, ®Data);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: set temperature parameters;
|
|
*
|
|
* Parameters: tempODR tempEnable
|
|
* SH3001_TEMP_ODR_500 SH3001_TEMP_EN
|
|
* SH3001_TEMP_ODR_250 SH3001_TEMP_DIS
|
|
* SH3001_TEMP_ODR_125
|
|
* SH3001_TEMP_ODR_63
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
static void SH3001_Temp_Config(unsigned char tempODR,
|
|
unsigned char tempEnable)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
// enable temperature, set ODR
|
|
SH3001_read(SH3001_ADDRESS, SH3001_TEMP_CONF0, 1, ®Data);
|
|
regData &= 0x4F;
|
|
regData |= (tempODR | tempEnable);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_TEMP_CONF0, 1, ®Data);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: read temperature parameters;
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: temperature data(deg);
|
|
*
|
|
******************************************************************/
|
|
float SH3001_GetTempData(void)
|
|
{
|
|
unsigned char regData[2] = {0};
|
|
unsigned short int tempref[2] = {0};
|
|
|
|
// read temperature data, unsigned 12bits; SH3001_TEMP_CONF0..SH3001_TEMP_CONF1
|
|
SH3001_read(SH3001_ADDRESS, SH3001_TEMP_CONF0, 2, ®Data[0]);
|
|
tempref[0] = ((unsigned short int)(regData[0] & 0x0F) << 8) | regData[1];
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_TEMP_ZL, 2, ®Data[0]);
|
|
tempref[1] = ((unsigned short int)(regData[1] & 0x0F) << 8) | regData[0];
|
|
|
|
return ((((float)(tempref[1] - tempref[0])) / 16.0f) + 25.0f);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: enable or disable INT, mapping interrupt to INT pin or INT1 pin
|
|
*
|
|
* Parameters: intType intEnable intPinSel
|
|
* SH3001_INT_LOWG SH3001_INT_ENABLE SH3001_INT_MAP_INT
|
|
* SH3001_INT_HIGHG SH3001_INT_DISABLE SH3001_INT_MAP_INT1
|
|
* SH3001_INT_INACT
|
|
* SH3001_INT_ACT
|
|
* SH3001_INT_DOUBLE_TAP
|
|
* SH3001_INT_SINGLE_TAP
|
|
* SH3001_INT_FLAT
|
|
* SH3001_INT_ORIENTATION
|
|
* SH3001_INT_FIFO_GYRO
|
|
* SH3001_INT_GYRO_READY
|
|
* SH3001_INT_ACC_FIFO
|
|
* SH3001_INT_ACC_READY
|
|
* SH3001_INT_FREE_FALL
|
|
* SH3001_INT_UP_DOWN_Z
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_INT_Enable(unsigned short int intType,
|
|
unsigned char intEnable,
|
|
unsigned char intPinSel)
|
|
{
|
|
unsigned char regData[2] = {0};
|
|
unsigned short int u16IntVal = 0, u16IntTemp = 0;
|
|
|
|
// Z axis change between UP to DOWN
|
|
if ((intType & 0x0040) == SH3001_INT_UP_DOWN_Z) {
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ORIEN_INTCONF0, 1, ®Data[0]);
|
|
regData[0] = (intEnable == SH3001_INT_ENABLE) \
|
|
? (regData[0] | 0x40) : (regData[0] & 0xBF);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INTCONF0, 1, ®Data[0]);
|
|
}
|
|
|
|
if ((intType & 0xFF1F)) {
|
|
// enable or disable INT
|
|
SH3001_read(SH3001_ADDRESS, SH3001_INT_ENABLE0, 2, ®Data[0]);
|
|
u16IntVal = ((unsigned short int)regData[0] << 8) | regData[1];
|
|
|
|
u16IntVal = (intEnable == SH3001_INT_ENABLE) \
|
|
? (u16IntVal | intType) : (u16IntVal & ~intType);
|
|
|
|
regData[0] = (unsigned char)(u16IntVal >> 8);
|
|
regData[1] = (unsigned char)(u16IntVal);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INT_ENABLE0, 1, ®Data[0]);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INT_ENABLE1, 1, ®Data[1]);
|
|
|
|
|
|
// mapping interrupt to INT pin or INT1 pin
|
|
SH3001_read(SH3001_ADDRESS, SH3001_INT_PIN_MAP0, 2, ®Data[0]);
|
|
u16IntVal = ((unsigned short int)regData[0] << 8) | regData[1];
|
|
|
|
u16IntTemp = (intType << 1) & 0xE03E;
|
|
u16IntTemp = u16IntTemp | (intType & 0x0F00);
|
|
if (intType & SH3001_INT_LOWG) {
|
|
u16IntTemp |= 0x0001;
|
|
}
|
|
|
|
u16IntVal = (intPinSel == SH3001_INT_MAP_INT1) \
|
|
? (u16IntVal | u16IntTemp) : (u16IntVal & ~u16IntTemp);
|
|
|
|
regData[0] = (unsigned char)(u16IntVal >> 8);
|
|
regData[1] = (unsigned char)(u16IntVal);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INT_PIN_MAP0, 1, ®Data[0]);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INT_PIN_MAP1, 1, ®Data[1]);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.config INT function
|
|
* 2.intCount is valid only when intLatch is equal to SH3001_INT_NO_LATCH;
|
|
*
|
|
* Parameters: int0Level intLatch int1Level intClear
|
|
* SH3001_INT0_LEVEL_HIGH SH3001_INT_NO_LATCH SH3001_INT1_LEVEL_HIGH SH3001_INT_CLEAR_ANY
|
|
* SH3001_INT0_LEVEL_LOW SH3001_INT_LATCH SH3001_INT1_LEVEL_LOW SH3001_INT_CLEAR_STATUS
|
|
*
|
|
*
|
|
* int1Mode int0Mode intTime
|
|
* SH3001_INT1_NORMAL SH3001_INT0_NORMAL Unit: 2mS
|
|
* SH3001_INT1_OD SH3001_INT0_OD
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_INT_Config(unsigned char int0Level,
|
|
unsigned char intLatch,
|
|
unsigned char int1Level,
|
|
unsigned char intClear,
|
|
unsigned char int1Mode,
|
|
unsigned char int0Mode,
|
|
unsigned char intTime)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_INT_CONF, 1, ®Data);
|
|
|
|
regData = (int0Level == SH3001_INT0_LEVEL_LOW) \
|
|
? (regData | SH3001_INT0_LEVEL_LOW) : (regData & SH3001_INT0_LEVEL_HIGH);
|
|
|
|
regData = (intLatch == SH3001_INT_NO_LATCH) \
|
|
? (regData | SH3001_INT_NO_LATCH) : (regData & SH3001_INT_LATCH);
|
|
|
|
regData = (int1Level == SH3001_INT1_LEVEL_LOW) \
|
|
? (regData | SH3001_INT1_LEVEL_LOW) : (regData & SH3001_INT1_LEVEL_HIGH);
|
|
|
|
regData = (intClear == SH3001_INT_CLEAR_ANY) \
|
|
? (regData | SH3001_INT_CLEAR_ANY) : (regData & SH3001_INT_CLEAR_STATUS);
|
|
|
|
regData = (int1Mode == SH3001_INT1_NORMAL) \
|
|
? (regData | SH3001_INT1_NORMAL) : (regData & SH3001_INT1_OD);
|
|
|
|
regData = (int0Mode == SH3001_INT0_NORMAL) \
|
|
? (regData | SH3001_INT0_NORMAL) : (regData & SH3001_INT0_OD);
|
|
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INT_CONF, 1, ®Data);
|
|
|
|
if (intLatch == SH3001_INT_NO_LATCH) {
|
|
if (intTime != 0) {
|
|
regData = intTime;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INT_LIMIT, 1, ®Data);
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************
|
|
* Description: 1.lowG INT config;
|
|
* 2.lowGThres: x=0.5mG@2G or x=1mG@4G or x=2mG@8G or x=4mG@16G
|
|
*
|
|
* Parameters: lowGEnDisIntAll lowGThres lowGTimsMs
|
|
* SH3001_LOWG_ALL_INT_EN Unit: x mG Unit: 2mS
|
|
* SH3001_LOWG_ALL_INT_DIS
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_INT_LowG_Config(unsigned char lowGEnDisIntAll,
|
|
unsigned char lowGThres,
|
|
unsigned char lowGTimsMs)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_HIGHLOW_G_INT_CONF, 1, ®Data);
|
|
regData &= 0xFE;
|
|
regData |= lowGEnDisIntAll;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_HIGHLOW_G_INT_CONF, 1, ®Data);
|
|
|
|
regData = lowGThres;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_LOWG_INT_THRESHOLD, 1, ®Data);
|
|
|
|
regData = lowGTimsMs;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_LOWG_INT_TIME, 1, ®Data);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.highG INT config;
|
|
* 2.highGThres: x=0.5mG@2G, x=1mG@4G, x=2mG@8G, x=4mG@16G
|
|
*
|
|
* Parameters: highGEnDisIntX highGEnDisIntY highGEnDisIntZ
|
|
* SH3001_HIGHG_X_INT_EN SH3001_HIGHG_Y_INT_EN SH3001_HIGHG_Z_INT_EN
|
|
* SH3001_HIGHG_X_INT_DIS SH3001_HIGHG_Y_INT_DIS SH3001_HIGHG_Z_INT_DIS
|
|
*
|
|
*
|
|
* highGEnDisIntAll highGThres highGTimsMs
|
|
* SH3001_HIGHG_ALL_INT_EN Unit: x mG Unit: 2mS
|
|
* SH3001_HIGHG_ALL_INT_DIS
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_INT_HighG_Config(unsigned char highGEnDisIntX,
|
|
unsigned char highGEnDisIntY,
|
|
unsigned char highGEnDisIntZ,
|
|
unsigned char highGEnDisIntAll,
|
|
unsigned char highGThres,
|
|
unsigned char highGTimsMs)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_HIGHLOW_G_INT_CONF, 1, ®Data);
|
|
regData &= 0x0F;
|
|
regData |= highGEnDisIntX | highGEnDisIntY | highGEnDisIntZ | highGEnDisIntAll;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_HIGHLOW_G_INT_CONF, 1, ®Data);
|
|
|
|
regData = highGThres;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_HIGHG_INT_THRESHOLD, 1, ®Data);
|
|
|
|
regData = highGTimsMs;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_HIGHG_INT_TIME, 1, ®Data);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: inactivity INT config;
|
|
*
|
|
* Parameters: inactEnDisIntX inactEnDisIntY inactEnDisIntZ
|
|
* SH3001_INACT_X_INT_EN SH3001_INACT_Y_INT_EN SH3001_INACT_Z_INT_EN
|
|
* SH3001_INACT_X_INT_DIS SH3001_INACT_Y_INT_DIS SH3001_INACT_Z_INT_DIS
|
|
*
|
|
*
|
|
* inactIntMode inactLinkStatus inactTimeS
|
|
* SH3001_INACT_AC_MODE SH3001_LINK_PRE_STA Unit: S
|
|
* SH3001_INACT_DC_MODE SH3001_LINK_PRE_STA_NO
|
|
*
|
|
*
|
|
* inactIntThres inactG1
|
|
* (3 Bytes)
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_INT_Inact_Config(unsigned char inactEnDisIntX,
|
|
unsigned char inactEnDisIntY,
|
|
unsigned char inactEnDisIntZ,
|
|
unsigned char inactIntMode,
|
|
unsigned char inactLinkStatus,
|
|
unsigned char inactTimeS,
|
|
unsigned int inactIntThres,
|
|
unsigned short int inactG1)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ACT_INACT_INT_CONF, 1, ®Data);
|
|
regData &= 0xF0;
|
|
regData |= inactEnDisIntX | inactEnDisIntY | inactEnDisIntZ | inactIntMode;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACT_INACT_INT_CONF, 1, ®Data);
|
|
|
|
regData = (unsigned char)inactIntThres;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INACT_INT_THRESHOLDL, 1, ®Data);
|
|
regData = (unsigned char)(inactIntThres >> 8);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INACT_INT_THRESHOLDM, 1, ®Data);
|
|
regData = (unsigned char)(inactIntThres >> 16);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INACT_INT_THRESHOLDH, 1, ®Data);
|
|
|
|
regData = inactTimeS;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INACT_INT_TIME, 1, ®Data);
|
|
|
|
regData = (unsigned char)inactG1;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INACT_INT_1G_REFL, 1, ®Data);
|
|
regData = (unsigned char)(inactG1 >> 8);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_INACT_INT_1G_REFH, 1, ®Data);
|
|
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ACT_INACT_INT_LINK, 1, ®Data);
|
|
regData &= 0xFE;
|
|
regData |= inactLinkStatus;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACT_INACT_INT_LINK, 1, ®Data);
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: activity INT config;
|
|
* actIntThres: 1 LSB is 0.24mg@+/-2G, 0.48mg@+/-4G, 0.97mg@+/-8G, 1.95mg@+/-16G
|
|
*
|
|
* Parameters: actEnDisIntX actEnDisIntY actEnDisIntZ
|
|
* SH3001_ACT_X_INT_EN SH3001_ACT_Y_INT_EN SH3001_ACT_Z_INT_EN
|
|
* SH3001_ACT_X_INT_DIS SH3001_ACT_Y_INT_DIS SH3001_ACT_Z_INT_DIS
|
|
*
|
|
*
|
|
* actIntMode actTimeNum actIntThres actLinkStatus
|
|
* SH3001_ACT_AC_MODE (1 Byte) (1 Byte) SH3001_LINK_PRE_STA
|
|
* SH3001_ACT_DC_MODE SH3001_LINK_PRE_STA_NO
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_INT_Act_Config(unsigned char actEnDisIntX,
|
|
unsigned char actEnDisIntY,
|
|
unsigned char actEnDisIntZ,
|
|
unsigned char actIntMode,
|
|
unsigned char actTimeNum,
|
|
unsigned char actIntThres,
|
|
unsigned char actLinkStatus)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ACT_INACT_INT_CONF, 1, ®Data);
|
|
regData &= 0x0F;
|
|
regData |= actEnDisIntX | actEnDisIntY | actEnDisIntZ | actIntMode;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACT_INACT_INT_CONF, 1, ®Data);
|
|
|
|
regData = actIntThres;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACT_INT_THRESHOLD, 1, ®Data);
|
|
|
|
regData = actTimeNum;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACT_INT_TIME, 1, ®Data);
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ACT_INACT_INT_LINK, 1, ®Data);
|
|
regData &= 0xFE;
|
|
regData |= actLinkStatus;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACT_INACT_INT_LINK, 1, ®Data);
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.tap INT config;
|
|
* 2.tapWaitTimeWindowMs is more than tapWaitTimeMs;
|
|
*
|
|
* Parameters: tapEnDisIntX tapEnDisIntY tapEnDisIntZ
|
|
* SH3001_TAP_X_INT_EN SH3001_TAP_Y_INT_EN SH3001_TAP_Z_INT_EN
|
|
* SH3001_TAP_X_INT_DIS SH3001_TAP_Y_INT_DIS SH3001_TAP_Z_INT_DIS
|
|
*
|
|
*
|
|
* tapIntThres tapTimeMs tapWaitTimeMs tapWaitTimeWindowMs
|
|
* (1 Byte) Unit: mS Unit: mS Unit: mS
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_INT_Tap_Config(unsigned char tapEnDisIntX,
|
|
unsigned char tapEnDisIntY,
|
|
unsigned char tapEnDisIntZ,
|
|
unsigned char tapIntThres,
|
|
unsigned char tapTimeMs,
|
|
unsigned char tapWaitTimeMs,
|
|
unsigned char tapWaitTimeWindowMs)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ACT_INACT_INT_LINK, 1, ®Data);
|
|
regData &= 0xF1;
|
|
regData |= tapEnDisIntX | tapEnDisIntY | tapEnDisIntZ;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ACT_INACT_INT_LINK, 1, ®Data);
|
|
|
|
regData = tapIntThres;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_TAP_INT_THRESHOLD, 1, ®Data);
|
|
|
|
regData = tapTimeMs;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_TAP_INT_DURATION, 1, ®Data);
|
|
|
|
regData = tapWaitTimeMs;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_TAP_INT_LATENCY, 1, ®Data);
|
|
|
|
regData = tapWaitTimeWindowMs;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_DTAP_INT_WINDOW, 1, ®Data);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: flat INT time threshold, unit: mS;
|
|
*
|
|
* Parameters: flatTimeTH flatTanHeta2
|
|
* SH3001_FLAT_TIME_500MS 0 ~ 63
|
|
* SH3001_FLAT_TIME_1000MS
|
|
* SH3001_FLAT_TIME_2000MS
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_INT_Flat_Config(unsigned char flatTimeTH, unsigned char flatTanHeta2)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
//SH3001_read(SH3001_ADDRESS, SH3001_FLAT_INT_CONF, 1, ®Data);
|
|
regData = (flatTimeTH & 0xC0) | (flatTanHeta2 & 0x3F);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_FLAT_INT_CONF, 1, ®Data);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: orientation config;
|
|
*
|
|
* Parameters: orientBlockMode orientMode orientTheta
|
|
* SH3001_ORIENT_BLOCK_MODE0 SH3001_ORIENT_SYMM (1 Byte)
|
|
* SH3001_ORIENT_BLOCK_MODE1 SH3001_ORIENT_HIGH_ASYMM
|
|
* SH3001_ORIENT_BLOCK_MODE2 SH3001_ORIENT_LOW_ASYMM
|
|
* SH3001_ORIENT_BLOCK_MODE3
|
|
*
|
|
* orientG1point5 orientSlope orientHyst
|
|
* (2 Bytes) (2 Bytes) (2 Bytes)
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_INT_Orient_Config(unsigned char orientBlockMode,
|
|
unsigned char orientMode,
|
|
unsigned char orientTheta,
|
|
unsigned short orientG1point5,
|
|
unsigned short orientSlope,
|
|
unsigned short orientHyst)
|
|
{
|
|
unsigned char regData[2] = {0};
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ORIEN_INTCONF0, 1, ®Data[0]);
|
|
regData[0] |= (regData[0] & 0xC0) | (orientTheta & 0x3F);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INTCONF0, 1, ®Data[0]);
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ORIEN_INTCONF1, 1, ®Data[0]);
|
|
regData[0] &= 0xF0;
|
|
regData[0] |= (orientBlockMode & 0x0C) | (orientMode & 0x03);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INTCONF1, 1, ®Data[0]);
|
|
|
|
regData[0] = (unsigned char)orientG1point5;
|
|
regData[1] = (unsigned char)(orientG1point5 >> 8);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INT_LOW, 1, ®Data[0]);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INT_HIGH, 1, ®Data[1]);
|
|
|
|
regData[0] = (unsigned char)orientSlope;
|
|
regData[1] = (unsigned char)(orientSlope >> 8);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INT_SLOPE_LOW, 1, ®Data[0]);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INT_SLOPE_HIGH, 1, ®Data[1]);
|
|
|
|
regData[0] = (unsigned char)orientHyst;
|
|
regData[1] = (unsigned char)(orientHyst >> 8);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INT_HYST_LOW, 1, ®Data[0]);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INT_HYST_HIGH, 1, ®Data[1]);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.freeFall INT config;
|
|
* 2.freeFallThres: x=0.5mG@2G or x=1mG@4G or x=2mG@8G or x=4mG@16G
|
|
*
|
|
* Parameters: freeFallThres freeFallTimsMs
|
|
* Unit: x mG Unit: 2mS
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_INT_FreeFall_Config(unsigned char freeFallThres,
|
|
unsigned char freeFallTimsMs)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
regData = freeFallThres;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_FREEFALL_INT_THRES, 1, ®Data);
|
|
|
|
regData = freeFallTimsMs;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_FREEFALL_INT_TIME, 1, ®Data);
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.read INT status0
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: unsigned short
|
|
* bit 11: Acc Data Ready Interrupt status
|
|
* bit 10: Acc FIFO Watermark Interrupt status
|
|
* bit 9: Gyro Ready Interrupt status
|
|
* bit 8: Gyro FIFO Watermark Interrupt status
|
|
* bit 7: Free-fall Interrupt status
|
|
* bit 6: Orientation Interrupt status
|
|
* bit 5: Flat Interrupt status
|
|
* bit 4: Tap Interrupt status
|
|
* bit 3: Single Tap Interrupt status
|
|
* bit 2: Double Tap Interrupt status
|
|
* bit 1: Activity Interrupt status
|
|
* bit 0: Inactivity Interrupt status
|
|
* 0: Not Active
|
|
* 1: Active
|
|
*
|
|
******************************************************************/
|
|
unsigned short SH3001_INT_Read_Status0(void)
|
|
{
|
|
unsigned char regData[2] = {0};
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_INT_STA0, 2, ®Data[0]);
|
|
|
|
return (((unsigned short)(regData[1] & 0x0F) << 8) | regData[0]);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.read INT status2
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: unsigned char
|
|
* bit 7: Sign of acceleration that trigger High-G Interrupt
|
|
* 0: Positive
|
|
* 1: Negative
|
|
* bit 6: Whether High-G Interrupt is triggered by X axis
|
|
* bit 5: Whether High-G Interrupt is triggered by Y axis
|
|
* bit 4: Whether High-G Interrupt is triggered by Z axis
|
|
* 0: No
|
|
* 1: Yes
|
|
* bit 3: Reserved
|
|
* bit 2: Reserved
|
|
* bit 1: Reserved
|
|
* bit 0: Low-G Interrupt status
|
|
* 0: Not Active
|
|
* 1: Active
|
|
*
|
|
******************************************************************/
|
|
unsigned char SH3001_INT_Read_Status2(void)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_INT_STA2, 1, ®Data);
|
|
|
|
return ((regData & 0xF1));
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.read INT status3
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: unsigned char
|
|
* bit 7: Sign of acceleration that trigger Activity or Inactivity Interrupt
|
|
* 0: Positive
|
|
* 1: Negative
|
|
* bit 6: Whether Activity or Inactivity Interrupt is triggered by X axis
|
|
* bit 5: Whether Activity or Inactivity Interrupt is triggered by Y axis
|
|
* bit 4: Whether Activity or Inactivity Interrupt is triggered by Z axis
|
|
* 0: No
|
|
* 1: Yes
|
|
* bit 3: Sign of acceleration that trigger Single or Double Tap Interrup
|
|
* 0: Positive
|
|
* 1: Negative
|
|
* bit 2: Whether Single or Double Tap Interrupt is triggered by X axis
|
|
* bit 1: Whether Single or Double Tap Interrupt is triggered by Y axis
|
|
* bit 0: Whether Single or Double Tap Interrupt is triggered by Z axis
|
|
* 0: No
|
|
* 1: Yes
|
|
******************************************************************/
|
|
unsigned char SH3001_INT_Read_Status3(void)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_INT_STA3, 1, ®Data);
|
|
|
|
return (regData);
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.read INT status4
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: unsigned char
|
|
* bit 7: Reserved
|
|
* bit 6: Reserved
|
|
* bit 5: Reserved
|
|
* bit 4: Reserved
|
|
* bit 3: Reserved
|
|
* bit 2: Orientation Interrupt Value of Z-axis
|
|
* 0: Upward
|
|
* 1: Downward
|
|
* bit 1..0: Orientation Interrupt Value of X and Y-axis
|
|
* 00: Landscape left
|
|
* 01: Landscape right
|
|
* 10: Portrait upside down
|
|
* 11: Portrait upright
|
|
*
|
|
******************************************************************/
|
|
unsigned char SH3001_INT_Read_Status4(void)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_INT_STA4, 1, ®Data);
|
|
|
|
return (regData & 0x07);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: Before running other INT config functions, need to call SH3001_pre_INT_config();
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: void
|
|
*
|
|
*
|
|
******************************************************************/
|
|
void SH3001_pre_INT_config(void)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
regData = 0x20;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INTCONF0, 1, ®Data);
|
|
|
|
regData = 0x0A;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INTCONF1, 1, ®Data);
|
|
|
|
regData = 0x01;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_ORIEN_INT_HYST_HIGH, 1, ®Data);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: reset FIFO controller;
|
|
*
|
|
* Parameters: fifoMode
|
|
* SH3001_FIFO_MODE_DIS
|
|
* SH3001_FIFO_MODE_FIFO
|
|
* SH3001_FIFO_MODE_STREAM
|
|
* SH3001_FIFO_MODE_TRIGGER
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_FIFO_Reset(unsigned char fifoMode)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_FIFO_CONF0, 1, ®Data);
|
|
regData |= 0x80;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_FIFO_CONF0, 1, ®Data);
|
|
regData &= 0x7F;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_FIFO_CONF0, 1, ®Data);
|
|
|
|
regData = fifoMode & 0x03;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_FIFO_CONF0, 1, ®Data);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.FIFO down sample frequency config;
|
|
* 2.fifoAccFreq: accODR*1/2, *1/4, *1/8, *1/16, *1/32, *1/64, *1/128, *1/256
|
|
* 3.fifoGyroFreq: gyroODR*1/2, *1/4, *1/8, *1/16, *1/32, *1/64, *1/128, *1/256
|
|
*
|
|
* Parameters: fifoAccDownSampleEnDis fifoAccFreq/fifoGyroFreq fifoGyroDownSampleEnDis
|
|
* SH3001_FIFO_ACC_DOWNS_EN SH3001_FIFO_FREQ_X1_2 SH3001_FIFO_GYRO_DOWNS_EN
|
|
* SH3001_FIFO_ACC_DOWNS_DIS SH3001_FIFO_FREQ_X1_4 SH3001_FIFO_GYRO_DOWNS_DIS
|
|
* SH3001_FIFO_FREQ_X1_8
|
|
* SH3001_FIFO_FREQ_X1_16
|
|
* SH3001_FIFO_FREQ_X1_32
|
|
* SH3001_FIFO_FREQ_X1_64
|
|
* SH3001_FIFO_FREQ_X1_128
|
|
* SH3001_FIFO_FREQ_X1_256
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_FIFO_Freq_Config(unsigned char fifoAccDownSampleEnDis,
|
|
unsigned char fifoAccFreq,
|
|
unsigned char fifoGyroDownSampleEnDis,
|
|
unsigned char fifoGyroFreq)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
regData |= fifoAccDownSampleEnDis | fifoGyroDownSampleEnDis;
|
|
regData |= (fifoAccFreq << 4) | fifoGyroFreq;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_FIFO_CONF4, 1, ®Data);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.data type config in FIFO;
|
|
* 2.fifoWaterMarkLevel is less than or equal to 1024;
|
|
*
|
|
* Parameters: fifoMode fifoWaterMarkLevel
|
|
* SH3001_FIFO_EXT_Z_EN <=1024
|
|
* SH3001_FIFO_EXT_Y_EN
|
|
* SH3001_FIFO_EXT_X_EN
|
|
* SH3001_FIFO_TEMPERATURE_EN
|
|
* SH3001_FIFO_GYRO_Z_EN
|
|
* SH3001_FIFO_GYRO_Y_EN
|
|
* SH3001_FIFO_GYRO_X_EN
|
|
* SH3001_FIFO_ACC_Z_EN
|
|
* SH3001_FIFO_ACC_Y_EN
|
|
* SH3001_FIFO_ACC_X_EN
|
|
* SH3001_FIFO_ALL_DIS
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_FIFO_Data_Config(unsigned short fifoMode,
|
|
unsigned short fifoWaterMarkLevel)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
if (fifoWaterMarkLevel > 1024) {
|
|
fifoWaterMarkLevel = 1024;
|
|
}
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_FIFO_CONF2, 1, ®Data);
|
|
regData = (regData & 0xC8) \
|
|
| ((unsigned char)(fifoMode >> 8) & 0x30) \
|
|
| (((unsigned char)(fifoWaterMarkLevel >> 8)) & 0x07);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_FIFO_CONF2, 1, ®Data);
|
|
|
|
regData = (unsigned char)fifoMode;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_FIFO_CONF3, 1, ®Data);
|
|
|
|
regData = (unsigned char)fifoWaterMarkLevel;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_FIFO_CONF1, 1, ®Data);
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1. read Fifo status and fifo entries count
|
|
*
|
|
* Parameters: *fifoEntriesCount, store fifo entries count, less than or equal to 1024;
|
|
*
|
|
*
|
|
* return: unsigned char
|
|
* bit 7: 0
|
|
* bit 6: 0
|
|
* bit 5: Whether FIFO Watermark has been reached
|
|
* bit 4: Whether FIFO is full
|
|
* bit 3: Whether FIFO is empty
|
|
* 0: No
|
|
* 1: Yes
|
|
* bit 2: 0
|
|
* bit 1: 0
|
|
* bit 0: 0
|
|
*
|
|
*
|
|
******************************************************************/
|
|
unsigned char SH3001_FIFO_Read_Status(unsigned short int *fifoEntriesCount)
|
|
{
|
|
unsigned char regData[2] = {0};
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_FIFO_STA0, 2, ®Data[0]);
|
|
*fifoEntriesCount = ((unsigned short int)(regData[1] & 0x07) << 8) | regData[0];
|
|
|
|
return (regData[1] & 0x38);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1. read Fifo data
|
|
*
|
|
* Parameters: *fifoReadData fifoDataLength
|
|
* data data length
|
|
*
|
|
* return: void
|
|
*
|
|
*
|
|
******************************************************************/
|
|
void SH3001_FIFO_Read_Data(unsigned char *fifoReadData, unsigned short int fifoDataLength)
|
|
{
|
|
if (fifoDataLength > 1024) {
|
|
fifoDataLength = 1024;
|
|
}
|
|
|
|
while (fifoDataLength--) {
|
|
SH3001_read(SH3001_ADDRESS, SH3001_FIFO_DATA, 1, fifoReadData);
|
|
fifoReadData++;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: reset Mater I2C;
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_MI2C_Reset(void)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
regData |= 0x80;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
regData &= 0x7F;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
|
|
}
|
|
|
|
/******************************************************************
|
|
* Description: 1.master I2C config;
|
|
* 2.master I2C clock frequency is (1MHz/(6+3*mi2cFreq));19.6k ~ 166.666k
|
|
* 3.mi2cSlaveAddr: slave device address, 7 bits;
|
|
*
|
|
*
|
|
* Parameters: mi2cReadMode mi2cODR mi2cFreq
|
|
* SH3001_MI2C_READ_MODE_AUTO SH3001_MI2C_READ_ODR_200HZ <=15
|
|
* SH3001_MI2C_READ_MODE_MANUAL SH3001_MI2C_READ_ODR_100HZ
|
|
* SH3001_MI2C_READ_ODR_50HZ
|
|
* SH3001_MI2C_READ_ODR_25HZ
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_MI2C_Bus_Config(unsigned char mi2cReadMode,
|
|
unsigned char mi2cODR,
|
|
unsigned char mi2cFreq)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
if (mi2cFreq > 15) {
|
|
mi2cFreq = 15;
|
|
}
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_MI2C_CONF1, 1, ®Data);
|
|
regData = (regData & 0xC0) | (mi2cODR & 0x30) | mi2cFreq;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_MI2C_CONF1, 1, ®Data);
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
regData = (regData & 0xBF) | mi2cReadMode;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.master I2C address and command config;
|
|
* 2.mi2cSlaveAddr: slave device address, 7 bits;
|
|
*
|
|
* Parameters: mi2cSlaveAddr mi2cSlaveCmd mi2cReadMode
|
|
* (1 Byte) (1 Byte) SH3001_MI2C_READ_MODE_AUTO
|
|
* SH3001_MI2C_READ_MODE_MANUAL
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_MI2C_Cmd_Config(unsigned char mi2cSlaveAddr,
|
|
unsigned char mi2cSlaveCmd,
|
|
unsigned char mi2cReadMode)
|
|
{
|
|
unsigned char regData = 0;
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
regData = (regData & 0xBF) | mi2cReadMode;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
|
|
regData = mi2cSlaveAddr << 1;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_MI2C_CMD0, 1, ®Data);
|
|
SH3001_write(SH3001_ADDRESS, SH3001_MI2C_CMD1, 1, &mi2cSlaveCmd);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.master I2C write data fucntion;
|
|
* 2.mi2cWriteData: write data;
|
|
*
|
|
* Parameters: mi2cWriteData
|
|
*
|
|
* return: SH3001_TRUE or SH3001_FALSE
|
|
*
|
|
******************************************************************/
|
|
unsigned char SH3001_MI2C_Write(unsigned char mi2cWriteData)
|
|
{
|
|
unsigned char regData = 0;
|
|
unsigned char i = 0;
|
|
|
|
SH3001_write(SH3001_ADDRESS, SH3001_MI2C_WR, 1, &mi2cWriteData);
|
|
|
|
//Master I2C enable, write-operation
|
|
SH3001_read(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
regData = (regData & 0xFC) | 0x02;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
|
|
// wait write-operation to end
|
|
while (i++ < 20) {
|
|
SH3001_read(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
if (regData & 0x30) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((regData & 0x30) == SH3001_MI2C_SUCCESS) {
|
|
return (SH3001_TRUE);
|
|
} else {
|
|
return (SH3001_FALSE);
|
|
}
|
|
}
|
|
|
|
/******************************************************************
|
|
* Description: 1.master I2C read data fucntion;
|
|
* 2.*mi2cReadData: read data;
|
|
*
|
|
* Parameters: *mi2cReadData
|
|
*
|
|
* return: SH3001_TRUE or SH3001_FALSE
|
|
*
|
|
******************************************************************/
|
|
unsigned char SH3001_MI2C_Read(unsigned char *mi2cReadData)
|
|
{
|
|
unsigned char regData = 0;
|
|
unsigned char i = 0;
|
|
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
if ((regData & 0x40) == 0) {
|
|
//Master I2C enable, read-operation
|
|
regData |= 0x03;
|
|
SH3001_write(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
}
|
|
|
|
// wait read-operation to end
|
|
while (i++ < 20) {
|
|
SH3001_read(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
if (regData & 0x30) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_MI2C_CONF0, 1, ®Data);
|
|
if ((regData & 0x30) == SH3001_MI2C_SUCCESS) {
|
|
SH3001_read(SH3001_ADDRESS, SH3001_MI2C_RD, 1, ®Data);
|
|
*mi2cReadData = regData;
|
|
|
|
return (SH3001_TRUE);
|
|
} else {
|
|
return (SH3001_FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.SPI interface config; Default: SH3001_SPI_4_WIRE
|
|
*
|
|
* Parameters: spiInterfaceMode
|
|
* SH3001_SPI_3_WIRE
|
|
* SH3001_SPI_4_WIRE
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_SPI_Config(unsigned char spiInterfaceMode)
|
|
{
|
|
unsigned char regData = spiInterfaceMode;
|
|
|
|
SH3001_write(SH3001_ADDRESS, SH3001_SPI_CONF, 1, ®Data);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: read some compensation coefficients
|
|
*
|
|
* Parameters: compCoefType
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
static void SH3001_CompInit(compCoefType *compCoef)
|
|
{
|
|
unsigned char coefData[2] = {0};
|
|
|
|
// Acc Cross
|
|
SH3001_read(SH3001_ADDRESS, 0x81, 2, coefData);
|
|
compCoef->cYX = (signed char)coefData[0];
|
|
compCoef->cZX = (signed char)coefData[1];
|
|
SH3001_read(SH3001_ADDRESS, 0x91, 2, coefData);
|
|
compCoef->cXY = (signed char)coefData[0];
|
|
compCoef->cZY = (signed char)coefData[1];
|
|
SH3001_read(SH3001_ADDRESS, 0xA1, 2, coefData);
|
|
compCoef->cXZ = (signed char)coefData[0];
|
|
compCoef->cYZ = (signed char)coefData[1];
|
|
|
|
// Gyro Zero
|
|
SH3001_read(SH3001_ADDRESS, 0x60, 1, coefData);
|
|
compCoef->jX = (signed char)coefData[0];
|
|
SH3001_read(SH3001_ADDRESS, 0x68, 1, coefData);
|
|
compCoef->jY = (signed char)coefData[0];
|
|
SH3001_read(SH3001_ADDRESS, 0x70, 1, coefData);
|
|
compCoef->jZ = (signed char)coefData[0];
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_GYRO_CONF3, 1, coefData);
|
|
coefData[0] = coefData[0] & 0x07;
|
|
compCoef->xMulti = ((coefData[0] < 2) || (coefData[0] >= 7)) ? 1 : (1 << (6 - coefData[0]));
|
|
SH3001_read(SH3001_ADDRESS, SH3001_GYRO_CONF4, 1, coefData);
|
|
coefData[0] = coefData[0] & 0x07;
|
|
compCoef->yMulti = ((coefData[0] < 2) || (coefData[0] >= 7)) ? 1 : (1 << (6 - coefData[0]));
|
|
SH3001_read(SH3001_ADDRESS, SH3001_GYRO_CONF5, 1, coefData);
|
|
coefData[0] = coefData[0] & 0x07;
|
|
compCoef->zMulti = ((coefData[0] < 2) || (coefData[0] >= 7)) ? 1 : (1 << (6 - coefData[0]));
|
|
|
|
SH3001_read(SH3001_ADDRESS, 0x2E, 1, coefData);
|
|
compCoef->paramP0 = coefData[0] & 0x1F;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: SH3001 initialization function
|
|
*
|
|
* Parameters: void
|
|
*
|
|
* return: SH3001_TRUE or SH3001_FALSE
|
|
*
|
|
******************************************************************/
|
|
unsigned char SH3001_init(void) //no fifo no int
|
|
{
|
|
unsigned char regData = 0;
|
|
unsigned char i = 0;
|
|
|
|
#if (SH3001_USER_INTERFACE)
|
|
if (sh3001_info->spi_work_mode) {
|
|
SH3001_SPI_Config(SH3001_SPI_3_WIRE);
|
|
} else {
|
|
SH3001_SPI_Config(SH3001_SPI_4_WIRE);
|
|
}
|
|
#endif
|
|
|
|
// SH3001 chipID = 0x61;
|
|
while ((regData != 0x61) && (i++ < 3)) {
|
|
SH3001_read(SH3001_ADDRESS, SH3001_CHIP_ID, 1, ®Data);
|
|
if ((i == 3) && (regData != 0x61)) {
|
|
log_error("SH3001 init fail 0x%x\n", regData);
|
|
return SH3001_FALSE;
|
|
}
|
|
}
|
|
|
|
// reset internal module
|
|
SH3001_ModuleReset();
|
|
|
|
// 500Hz, 16G, cut off Freq(BW)=500*0.25Hz=125Hz, enable filter;
|
|
SH3001_Acc_Config(SH3001_ODR_500HZ,
|
|
SH3001_ACC_RANGE_16G,
|
|
SH3001_ACC_ODRX025,
|
|
SH3001_ACC_FILTER_EN);
|
|
|
|
// 500Hz, X\Y\Z 2000deg/s, cut off Freq(BW)=181Hz, enable filter;
|
|
SH3001_Gyro_Config(SH3001_ODR_500HZ,
|
|
SH3001_GYRO_RANGE_2000,
|
|
SH3001_GYRO_RANGE_2000,
|
|
SH3001_GYRO_RANGE_2000,
|
|
SH3001_GYRO_ODRX00,
|
|
SH3001_GYRO_FILTER_EN);
|
|
|
|
// temperature ODR is 63Hz, enable temperature measurement
|
|
SH3001_Temp_Config(SH3001_TEMP_ODR_63, SH3001_TEMP_EN);
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_CHIP_ID1, 1, ®Data);
|
|
if (regData == 0x61) {
|
|
// read compensation coefficient
|
|
SH3001_CompInit(&compCoef);
|
|
}
|
|
|
|
return SH3001_TRUE;
|
|
}
|
|
static u8 sh3001_int_pin = -1;
|
|
//return:0:fail, 1:ok
|
|
u8 SH3001_sensor_init(void *priv)
|
|
{
|
|
if (priv == NULL) {
|
|
log_error("sh3001 init fail(no param)\n");
|
|
return SH3001_FALSE;
|
|
}
|
|
sh3001_info = (sh3001_param *)priv;
|
|
|
|
#if (SH3001_USER_INTERFACE==0) //iic interface
|
|
iic_init(sh3001_info->iic_hdl);
|
|
#else//spi interface
|
|
spi_cs_init();
|
|
spi_init();
|
|
#endif
|
|
//int module io init
|
|
gpio_set_die(sh3001_int_pin, 1);
|
|
gpio_set_direction(sh3001_int_pin, 1);
|
|
/* gpio_set_pull_up(sh3001_int_pin, 1); */
|
|
/* gpio_set_pull_down(sh3001_int_pin, 0); */
|
|
gpio_set_die(SH3001_INT_IO2, 1);
|
|
gpio_set_direction(SH3001_INT_IO2, 1);
|
|
/* gpio_set_pull_up(SH3001_INT_IO2, 1); */
|
|
/* gpio_set_pull_down(SH3001_INT_IO2, 0); */
|
|
return SH3001_init();
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
* Description: Read SH3001 gyroscope and accelerometer data
|
|
*
|
|
* Parameters: accData[3]: acc X,Y,Z; gyroData[3]: gyro X,Y,Z;
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_GetImuData(short accData[3], short gyroData[3])
|
|
{
|
|
unsigned char regData[12] = {0};
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ACC_XL, 12, regData);
|
|
accData[0] = ((short)regData[1] << 8) | regData[0];
|
|
accData[1] = ((short)regData[3] << 8) | regData[2];
|
|
accData[2] = ((short)regData[5] << 8) | regData[4];
|
|
|
|
gyroData[0] = ((short)regData[7] << 8) | regData[6];
|
|
gyroData[1] = ((short)regData[9] << 8) | regData[8];
|
|
gyroData[2] = ((short)regData[11] << 8) | regData[10];
|
|
|
|
log_info("sh3001:acc_x:%d acc_y:%d acc_z:%d gyro_x:%d gyro_y:%d gyro_z:%d", accData[0], accData[1], accData[2], gyroData[0], gyroData[1], gyroData[2]);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
* Description: 1.Read SH3001 gyroscope and accelerometer data after compensation
|
|
* 2.Only When the chipID is 0x61 at register 0xDF, can use SH3001_GetImuCompData() to get sensor data;
|
|
*
|
|
* Parameters: accData[3]: acc X,Y,Z; gyroData[3]: gyro X,Y,Z;
|
|
*
|
|
*
|
|
* return: void
|
|
*
|
|
******************************************************************/
|
|
void SH3001_GetImuCompData(short accData[3], short gyroData[3])
|
|
{
|
|
unsigned char regData[15] = {0};
|
|
unsigned char paramP;
|
|
int accTemp[3], gyroTemp[3];
|
|
|
|
SH3001_read(SH3001_ADDRESS, SH3001_ACC_XL, 15, regData);
|
|
accData[0] = ((short)regData[1] << 8) | regData[0];
|
|
accData[1] = ((short)regData[3] << 8) | regData[2];
|
|
accData[2] = ((short)regData[5] << 8) | regData[4];
|
|
gyroData[0] = ((short)regData[7] << 8) | regData[6];
|
|
gyroData[1] = ((short)regData[9] << 8) | regData[8];
|
|
gyroData[2] = ((short)regData[11] << 8) | regData[10];
|
|
paramP = regData[14] & 0x1F;
|
|
|
|
// Acc Cross
|
|
accTemp[0] = (int)(accData[0] + \
|
|
accData[1] * ((float)compCoef.cXY / 1024.0f) + \
|
|
accData[2] * ((float)compCoef.cXZ / 1024.0f));
|
|
|
|
accTemp[1] = (int)(accData[0] * ((float)compCoef.cYX / 1024.0f) + \
|
|
accData[1] + \
|
|
accData[2] * ((float)compCoef.cYZ / 1024.0f));
|
|
|
|
accTemp[2] = (int)(accData[0] * ((float)compCoef.cZX / 1024.0f) + \
|
|
accData[1] * ((float)compCoef.cZY / 1024.0f) + \
|
|
accData[2]);
|
|
|
|
if (accTemp[0] > 32767) {
|
|
accTemp[0] = 32767;
|
|
} else if (accTemp[0] < -32768) {
|
|
accTemp[0] = -32768;
|
|
}
|
|
if (accTemp[1] > 32767) {
|
|
accTemp[1] = 32767;
|
|
} else if (accTemp[1] < -32768) {
|
|
accTemp[1] = -32768;
|
|
}
|
|
if (accTemp[2] > 32767) {
|
|
accTemp[2] = 32767;
|
|
} else if (accTemp[2] < -32768) {
|
|
accTemp[2] = -32768;
|
|
}
|
|
accData[0] = (short)accTemp[0];
|
|
accData[1] = (short)accTemp[1];
|
|
accData[2] = (short)accTemp[2];
|
|
|
|
gyroTemp[0] = gyroData[0] - (paramP - compCoef.paramP0) * compCoef.jX * compCoef.xMulti;
|
|
gyroTemp[1] = gyroData[1] - (paramP - compCoef.paramP0) * compCoef.jY * compCoef.yMulti;
|
|
gyroTemp[2] = gyroData[2] - (paramP - compCoef.paramP0) * compCoef.jZ * compCoef.zMulti;
|
|
if (gyroTemp[0] > 32767) {
|
|
gyroTemp[0] = 32767;
|
|
} else if (gyroTemp[0] < -32768) {
|
|
gyroTemp[0] = -32768;
|
|
}
|
|
if (gyroTemp[1] > 32767) {
|
|
gyroTemp[1] = 32767;
|
|
} else if (gyroTemp[1] < -32768) {
|
|
gyroTemp[1] = -32768;
|
|
}
|
|
if (gyroTemp[2] > 32767) {
|
|
gyroTemp[2] = 32767;
|
|
} else if (gyroTemp[2] < -32768) {
|
|
gyroTemp[2] = -32768;
|
|
}
|
|
|
|
// Gyro Zero
|
|
gyroData[0] = (short)gyroTemp[0];
|
|
gyroData[1] = (short)gyroTemp[1];
|
|
gyroData[2] = (short)gyroTemp[2];
|
|
|
|
/* log_info("sh3001:acc_x:%d acc_y:%d acc_z:%d gyro_x:%d gyro_y:%d gyro_z:%d", accData[0], accData[1], accData[2], gyroData[0], gyroData[1], gyroData[2]); */
|
|
}
|
|
|
|
static u8 init_flag = 0;
|
|
static u8 imu_busy = 0;
|
|
static sh3001_param sh3001_info_data;
|
|
/********************int test*******************/
|
|
// For example: set accelerometer data ready INT
|
|
void sh3001_int_mode()
|
|
{
|
|
SH3001_pre_INT_config();
|
|
SH3001_INT_Config(SH3001_INT0_LEVEL_HIGH, //低有效
|
|
SH3001_INT_NO_LATCH, //锁住中断,只有清中断才恢复
|
|
SH3001_INT1_LEVEL_HIGH, //高有效
|
|
SH3001_INT_CLEAR_STATUS, //读任意寄存器清中断
|
|
SH3001_INT1_NORMAL, //int pin 普通输出
|
|
SH3001_INT0_NORMAL,
|
|
3);
|
|
SH3001_INT_Enable(SH3001_INT_ACC_READY, //
|
|
SH3001_INT_ENABLE,
|
|
SH3001_INT_MAP_INT); //该中断映射到INT0 PIN
|
|
}
|
|
void sh3001_int_callback()
|
|
{
|
|
if (init_flag == 0) {
|
|
log_error("sh3001 init fail!");
|
|
return ;
|
|
}
|
|
if (imu_busy) {
|
|
log_error("sh3001 busy!");
|
|
return ;
|
|
}
|
|
imu_busy = 1;
|
|
|
|
short accData[3], gyroData[3];
|
|
float TempData;
|
|
SH3001_GetImuCompData(accData, gyroData);
|
|
TempData = SH3001_GetTempData();
|
|
/* SH3001_INT_Read_Status0(); */
|
|
imu_busy = 0;
|
|
log_info("sh3001:acc_x:%d acc_y:%d acc_z:%d gyro_x:%d gyro_y:%d gyro_z:%d", accData[0], accData[1], accData[2], gyroData[0], gyroData[1], gyroData[2]);
|
|
log_info("temp:%d.%d\n", (u16)TempData, (u16)(((u16)(TempData * 100)) % 100));
|
|
}
|
|
|
|
s8 sh3001_dev_init(void *arg)
|
|
{
|
|
if (arg == NULL) {
|
|
log_error("sh3001 init fail(no arg)\n");
|
|
return -1;
|
|
}
|
|
#if (SH3001_USER_INTERFACE==0)
|
|
sh3001_info_data.iic_hdl = ((struct imusensor_platform_data *)arg)->peripheral_hdl;
|
|
sh3001_info_data.iic_delay = ((struct imusensor_platform_data *)arg)->peripheral_param0; //这个延时并非影响iic的时钟频率,而是2Byte数据之间的延时
|
|
// u8 iic_clk; //iic_clk: <=400kHz
|
|
#else
|
|
sh3001_info_data.spi_hdl = ((struct imusensor_platform_data *)arg)->peripheral_hdl, //SPIx (role:master)
|
|
sh3001_info_data.spi_cs_pin = ((struct imusensor_platform_data *)arg)->peripheral_param0; //IO_PORTA_05
|
|
sh3001_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
|
|
|
|
sh3001_int_pin = ((struct imusensor_platform_data *)arg)->imu_sensor_int_io;
|
|
if (imu_busy) {
|
|
log_error("sh3001 busy!");
|
|
return -1;
|
|
}
|
|
imu_busy = 1;
|
|
|
|
if (SH3001_sensor_init(&sh3001_info_data)) { //no fifo
|
|
log_info("sh3001 init success!\n");
|
|
|
|
#if (TCFG_SH3001_USER_INT_EN==0) //定时读
|
|
//注册定时:sh3001_int_callback()
|
|
#else //中断读
|
|
//开中断
|
|
sh3001_int_mode();
|
|
log_info("int mode en!");
|
|
/* port_wkup_enable(sh3001_int_pin, 0, sh3001_int_callback); //PA08-IO中断,0:上降沿触发,回调函数sh3001_int_callback*/
|
|
#ifdef CONFIG_CPU_BR23
|
|
io_ext_interrupt_init(sh3001_int_pin, 1, sh3001_int_callback);
|
|
#elif defined(CONFIG_CPU_BR28)
|
|
// br28外部中断回调函数,按照现在的外部中断注册方式
|
|
// io配置在板级,定义在板级头文件,这里只是注册回调函数
|
|
/* port_edge_wkup_set_callback_by_index(3, sh3001_int_callback); // 序号需要和板级配置中的wk_param对应上 */
|
|
port_edge_wkup_set_callback(sh3001_int_callback);
|
|
#elif defined(CONFIG_CPU_BR27)
|
|
port_edge_wkup_set_callback(sh3001_int_callback);
|
|
#endif
|
|
|
|
#endif
|
|
init_flag = 1;
|
|
imu_busy = 0;
|
|
return 0;
|
|
} else {
|
|
log_error("sh3001 init fail!\n");
|
|
imu_busy = 0;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
int sh3001_dev_ctl(u8 cmd, void *arg);
|
|
REGISTER_IMU_SENSOR(sh3001_sensor) = {
|
|
.logo = "sh3001",
|
|
.imu_sensor_init = sh3001_dev_init,
|
|
.imu_sensor_check = NULL,
|
|
.imu_sensor_ctl = sh3001_dev_ctl,
|
|
};
|
|
|
|
int sh3001_dev_ctl(u8 cmd, void *arg)
|
|
{
|
|
int ret = -1;
|
|
if (init_flag == 0) {
|
|
log_error("sh3001 init fail!");
|
|
return ret;//0:ok,,<0:err
|
|
}
|
|
if (imu_busy) {
|
|
log_error("sh3001 busy!");
|
|
return ret;//0:ok,,<0:err
|
|
}
|
|
imu_busy = 1;
|
|
|
|
switch (cmd) {
|
|
case IMU_GET_SENSOR_NAME:
|
|
memcpy((u8 *)arg, &(sh3001_sensor.logo), 20);
|
|
break;
|
|
case IMU_SENSOR_ENABLE:
|
|
/* cbuf_init(&hrsensor_cbuf, hrsensorcbuf, 24 * sizeof(int)); */
|
|
SH3001_init();
|
|
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://传感器数据准备就绪待读
|
|
sh3001_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
|
|
SH3001_read(SH3001_ADDRESS, SH3001_CHIP_ID, 1, (u8 *)arg);
|
|
if (*(u8 *)arg == 0x61) {
|
|
ret = 0;
|
|
log_info("sh3001 online!\n");
|
|
} else {
|
|
log_error("sh3001 offline!\n");
|
|
}
|
|
break;
|
|
default:
|
|
log_error("--cmd err!\n");
|
|
break;
|
|
}
|
|
imu_busy = 0;
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***************************sh3001 test*******************************/
|
|
|
|
#if 0 //测试
|
|
static sh3001_param sh3001_info_test = {
|
|
#if (SH3001_USER_INTERFACE==0)
|
|
.iic_hdl = 0,
|
|
.iic_delay = 0, //这个延时并非影响iic的时钟频率,而是2Byte数据之间的延时
|
|
// u8 iic_clk; //iic_clk: <=400kHz
|
|
#else
|
|
.spi_hdl = 1, //SPIx (role:master)
|
|
.spi_cs_pin = IO_PORTA_05, //
|
|
.spi_work_mode = 1, //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
|
|
};
|
|
void sh3001_test()
|
|
{
|
|
short accData[3], gyroData[3];
|
|
float TempData;
|
|
if (SH3001_sensor_init(&sh3001_info_test)) { //no fifo no int
|
|
log_info("sh3001 init success!\n");
|
|
MDELAY(10);
|
|
#if (TCFG_SH3001_USER_INT_EN==0) //定时读
|
|
SH3001_GetImuCompData(accData, gyroData);
|
|
TempData = SH3001_GetTempData();
|
|
log_info("sh3001 temp:%d.%d", (u16)TempData, (u16)(((u16)(TempData * 100)) % 100));
|
|
#else //中断读
|
|
//开中断
|
|
sh3001_int_mode();
|
|
log_info("-------------------port wkup isr---------------------------");
|
|
/* port_wkup_enable(sh3001_int_pin, 0, sh3001_int_callback); //PA08-IO中断,0:上降沿触发,回调函数sh3001_int_callback*/
|
|
#ifdef CONFIG_CPU_BR23
|
|
io_ext_interrupt_init(sh3001_int_pin, 1, sh3001_int_callback);
|
|
#elif defined(CONFIG_CPU_BR28)
|
|
// br28外部中断回调函数,按照现在的外部中断注册方式
|
|
// io配置在板级,定义在板级头文件,这里只是注册回调函数
|
|
/* port_edge_wkup_set_callback_by_index(3, sh3001_int_callback); // 序号需要和板级配置中的wk_param对应上 */
|
|
port_edge_wkup_set_callback(sh3001_int_callback);
|
|
#elif defined(CONFIG_CPU_BR27)
|
|
port_edge_wkup_set_callback(sh3001_int_callback);
|
|
#endif
|
|
|
|
#endif
|
|
} else {
|
|
log_error("sh3001 init fail!\n");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|