feat: Add rfid feature and .gitignore file

This commit is contained in:
lmx
2025-11-28 16:25:35 +08:00
parent 818e8c3778
commit ade4b0a1f8
1244 changed files with 342105 additions and 0 deletions

View File

@ -0,0 +1,64 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2015-2015 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software”) is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/** @defgroup InvError Error code
* @brief Common error code
*
* @ingroup EmbUtils
* @{
*/
#ifndef _INV_ERROR_H_
#define _INV_ERROR_H_
/** @brief Common error code definition
*/
enum inv_error {
INV_ERROR_SUCCESS = 0, /**< no error */
INV_ERROR = -1, /**< unspecified error */
INV_ERROR_NIMPL = -2, /**< function not implemented for given
arguments */
INV_ERROR_TRANSPORT = -3, /**< error occurred at transport level */
INV_ERROR_TIMEOUT = -4, /**< action did not complete in the expected
time window */
INV_ERROR_SIZE = -5, /**< size/length of given arguments is not
suitable to complete requested action */
INV_ERROR_OS = -6, /**< error related to OS */
INV_ERROR_IO = -7, /**< error related to IO operation */
INV_ERROR_MEM = -9, /**< not enough memory to complete requested
action */
INV_ERROR_HW = -10, /**< error at HW level */
INV_ERROR_BAD_ARG = -11, /**< provided arguments are not good to
perform requested action */
INV_ERROR_UNEXPECTED = -12, /**< something unexpected happened */
INV_ERROR_FILE = -13, /**< cannot access file or unexpected format */
INV_ERROR_PATH = -14, /**< invalid file path */
INV_ERROR_IMAGE_TYPE = -15, /**< error when image type is not managed */
INV_ERROR_WATCHDOG = -16, /**< error when device doesn't respond
to ping */
};
#endif /* _INV_ERROR_H_ */
/** @} */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,129 @@
#ifndef _ICM_42670P_H_
#define _ICM_42670P_H_
#include "typedef.h"
#define ICM42670P
#if TCFG_ICM42670P_ENABLE
/*打开这个宏后fifo读到的数据为
(6(acc[s16])+6(gyro[s16]))
*/
#define ICM42670P_FIFO_DATA_FIT 1
/******************************************************************
* user config ICM42670P Macro Definition
******************************************************************/
#define ICM42670P_USE_I2C 0 /*IIC.(<=1MHz) */
#define ICM42670P_USE_SPI 1 /*SPI.(<=24MHz) */
#define ICM42670P_USER_INTERFACE TCFG_ICM42670P_INTERFACE_TYPE//ICM42670P_USE_I2C
// #define ICM42670P_USER_INTERFACE ICM42670P_USE_SPI
#define ICM42670P_SA0_IIC_ADDR 1 //1:iic模式SA0接VCC, 0:iic模式SA0接GND
//int io config
// #define ICM42670P_INT_IO1 IO_PORTB_03//TCFG_IOKEY_POWER_ONE_PORT //
// #define ICM42670P_INT_IO1 IO_PORTA_06 //
// #define ICM42670P_INT_READ_IO1() gpio_read(ICM42670P_INT_IO1)
// #define ICM42670P_USE_FIFO_EN 1 //0:disable fifo 1:enable fifo(fifo size:512 bytes)
#define ICM42670P_USE_INT_EN 0 //0:disable //中断方式不成功,疑硬件问题
// #define ICM42670P_USE_WOM_EN 0 //0:disable
// #define ICM42670P_USE_FSYNC_EN 0 //0:disable
#define SCALED_DATA_G_DPS 0 //1:output decode data; 0:Output raw data
//解码后数据: 8(timer[u64])+12(acc[float])+12(gyro[float])+4(temp[float])
//原始数据 : 8(timer[u64])+12(acc[int32])+12(gyro[int32])+2(temp[int16])
/******************************************************************
* ICM42670P I2C address Macro Definition
* (7bit): (0x37)011 0111@SDO=1; (0x36)011 0110@SDO=0;
******************************************************************/
#if ICM42670P_SA0_IIC_ADDR
#define ICM42670P_SLAVE_ADDRESS (0x69<<1)//0XD0
#else
#define ICM42670P_SLAVE_ADDRESS (0x68<<1)//0XD2
#endif
typedef u32(*IMU_read)(unsigned char devAddr,
unsigned char regAddr,
unsigned char *readBuf,
u32 readLen);
typedef u32(*IMU_write)(unsigned char devAddr,
unsigned char regAddr,
unsigned char *writeBuf,
u32 writeLen);
typedef struct {
// u8 comms; //0:IIC; 1:SPI //改为宏控制
#if (ICM42670P_USER_INTERFACE==ICM42670P_USE_I2C)
u8 iic_hdl;
u8 iic_delay; //这个延时并非影响iic的时钟频率而是2Byte数据之间的延时
// u8 iic_clk; //iic_clk: <=400kHz
#elif (ICM42670P_USER_INTERFACE==ICM42670P_USE_SPI)
u8 spi_hdl; //SPIx (role:master)
u8 spi_cs_pin; //
//u8 spi_work_mode;//icm42670p only suspport 4wire(SPI_MODE_BIDIR_1BIT) (与spi结构体一样)
// u8 port; //SPIx group:A,B,C,D (spi结构体)
// U8 spi_clk; //spi_clk: <=8MHz (spi结构体)
#endif
} icm42670p_param;
/*
* Select communication link between SmartMotion and IMU
*/
#if (ICM42670P_USER_INTERFACE==ICM42670P_USE_I2C)
#define SERIF_TYPE UI_I2C
#elif (ICM42670P_USER_INTERFACE==ICM42670P_USE_SPI)
#define SERIF_TYPE UI_SPI4
// #define SERIF_TYPE UI_SPI3
#endif
/*
* Set power mode flag
* Set this flag to run example in low-noise mode.
* Reset this flag to run example in low-power mode.
* Note: low-noise mode is not available with sensor data frequencies less than 12.5Hz.
*/
#define USE_LOW_NOISE_MODE 1
/*
* Select Fifo resolution Mode (default is low resolution mode)
* Low resolution mode: 16 bits data format
* High resolution mode: 20 bits data format
* Warning: Enabling High Res mode will force FSR to 16g and 2000dps
*/
#define USE_HIGH_RES_MODE 0
/*
* Select to use FIFO or to read data from registers
*/
#define USE_FIFO 1
enum inv_msg_level {
INV_MSG_LEVEL_OFF = 0,
INV_MSG_LEVEL_ERROR,
INV_MSG_LEVEL_WARNING,
INV_MSG_LEVEL_INFO,
INV_MSG_LEVEL_VERBOSE,
INV_MSG_LEVEL_DEBUG,
INV_MSG_LEVEL_MAX
};
#endif /*TCFG_ICM42670P_ENABLE*/
#endif /*_ICM_42670P_H_*/

View File

@ -0,0 +1,374 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2017 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively "Software") is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
#include "inv_imu_defs.h"
#include "inv_imu_extfunc.h"
#include "inv_imu_driver.h"
#include "inv_imu_apex.h"
int inv_imu_apex_enable_ff(struct inv_imu_device *s)
{
int status = 0;
uint8_t value;
status |= inv_imu_start_dmp(s);
status |= inv_imu_read_reg(s, APEX_CONFIG1, 1, &value);
value &= ~APEX_CONFIG1_FF_ENABLE_MASK;
value |= (uint8_t)APEX_CONFIG1_FF_ENABLE_EN;
status |= inv_imu_write_reg(s, APEX_CONFIG1, 1, &value);
return status;
}
int inv_imu_apex_disable_ff(struct inv_imu_device *s)
{
int status = 0;
uint8_t value;
status |= inv_imu_read_reg(s, APEX_CONFIG1, 1, &value);
value &= ~APEX_CONFIG1_FF_ENABLE_MASK;
value |= (uint8_t)APEX_CONFIG1_FF_ENABLE_DIS;
status |= inv_imu_write_reg(s, APEX_CONFIG1, 1, &value);
return status;
}
int inv_imu_apex_enable_smd(struct inv_imu_device *s)
{
int status = 0;
uint8_t value;
status |= inv_imu_start_dmp(s);
status |= inv_imu_read_reg(s, APEX_CONFIG1, 1, &value);
value &= ~APEX_CONFIG1_SMD_ENABLE_MASK;
value |= (uint8_t)APEX_CONFIG1_SMD_ENABLE_EN;
status |= inv_imu_write_reg(s, APEX_CONFIG1, 1, &value);
return status;
}
int inv_imu_apex_disable_smd(struct inv_imu_device *s)
{
int status = 0;
uint8_t value;
status |= inv_imu_read_reg(s, APEX_CONFIG1, 1, &value);
value &= ~APEX_CONFIG1_SMD_ENABLE_MASK;
value |= (uint8_t)APEX_CONFIG1_SMD_ENABLE_DIS;
status |= inv_imu_write_reg(s, APEX_CONFIG1, 1, &value);
return status;
}
int inv_imu_apex_init_parameters_struct(struct inv_imu_device *s, inv_imu_apex_parameters_t *apex_inputs)
{
int status = 0;
(void)s;
/* Default parameters at POR */
apex_inputs->pedo_amp_th = APEX_CONFIG3_PEDO_AMP_TH_62_MG;
apex_inputs->pedo_step_cnt_th = 0x5;
apex_inputs->pedo_step_det_th = 0x2;
apex_inputs->pedo_sb_timer_th = APEX_CONFIG4_PEDO_SB_TIMER_TH_150_SAMPLES;
apex_inputs->pedo_hi_enrgy_th = APEX_CONFIG4_PEDO_HI_ENRGY_TH_104_MG;
apex_inputs->tilt_wait_time = APEX_CONFIG5_TILT_WAIT_TIME_4_S;
apex_inputs->power_save_time = APEX_CONFIG2_DMP_POWER_SAVE_TIME_SEL_8_S;
apex_inputs->power_save = APEX_CONFIG0_DMP_POWER_SAVE_EN;
apex_inputs->sensitivity_mode = APEX_CONFIG9_SENSITIVITY_MODE_NORMAL;
apex_inputs->low_energy_amp_th = APEX_CONFIG2_LOW_ENERGY_AMP_TH_SEL_80_MG;
apex_inputs->smd_sensitivity = APEX_CONFIG9_SMD_SENSITIVITY_0;
apex_inputs->ff_debounce_duration = APEX_CONFIG9_FF_DEBOUNCE_DURATION_2000_MS;
apex_inputs->ff_max_duration_cm = APEX_CONFIG12_FF_MAX_DURATION_204_CM;
apex_inputs->ff_min_duration_cm = APEX_CONFIG12_FF_MIN_DURATION_10_CM;
apex_inputs->lowg_peak_th = APEX_CONFIG10_LOWG_PEAK_TH_563_MG;
apex_inputs->lowg_peak_hyst = APEX_CONFIG5_LOWG_PEAK_TH_HYST_156_MG;
apex_inputs->lowg_samples_th = APEX_CONFIG10_LOWG_TIME_TH_1_SAMPLE;
apex_inputs->highg_peak_th = APEX_CONFIG11_HIGHG_PEAK_TH_2500_MG;
apex_inputs->highg_peak_hyst = APEX_CONFIG5_HIGHG_PEAK_TH_HYST_156_MG;
apex_inputs->highg_samples_th = APEX_CONFIG11_HIGHG_TIME_TH_1_SAMPLE;
return status;
}
int inv_imu_apex_configure_parameters(struct inv_imu_device *s, const inv_imu_apex_parameters_t *apex_inputs)
{
int status = 0;
uint8_t data;
uint8_t apexConfig[7];
APEX_CONFIG1_PED_ENABLE_t pedo_state;
APEX_CONFIG1_TILT_ENABLE_t tilt_state;
APEX_CONFIG1_FF_ENABLE_t ff_state;
APEX_CONFIG1_SMD_ENABLE_t smd_state;
/* DMP cannot be configured if it is running, hence make sure all APEX algorithms are off */
status |= inv_imu_read_reg(s, APEX_CONFIG1, 1, &data);
pedo_state = (APEX_CONFIG1_PED_ENABLE_t)(data & APEX_CONFIG1_PED_ENABLE_MASK);
tilt_state = (APEX_CONFIG1_TILT_ENABLE_t)(data & APEX_CONFIG1_TILT_ENABLE_MASK);
ff_state = (APEX_CONFIG1_FF_ENABLE_t)(data & APEX_CONFIG1_FF_ENABLE_MASK);
smd_state = (APEX_CONFIG1_SMD_ENABLE_t)(data & APEX_CONFIG1_SMD_ENABLE_MASK);
if (pedo_state == APEX_CONFIG1_PED_ENABLE_EN) {
return INV_ERROR;
}
if (tilt_state == APEX_CONFIG1_TILT_ENABLE_EN) {
return INV_ERROR;
}
if (ff_state == APEX_CONFIG1_FF_ENABLE_EN) {
return INV_ERROR;
}
if (smd_state == APEX_CONFIG1_SMD_ENABLE_EN) {
return INV_ERROR;
}
status |= inv_imu_switch_on_mclk(s);
/* Power Save mode and low energy amplitude threshold (for Pedometer in Slow Walk mode) */
/* APEX_CONFIG2_MREG1 */
apexConfig[0] = (uint8_t)apex_inputs->power_save_time
| (uint8_t)apex_inputs->low_energy_amp_th;
/* Pedometer parameters */
/* APEX_CONFIG3_MREG1 */
apexConfig[1] = (uint8_t)apex_inputs->pedo_amp_th
| (apex_inputs->pedo_step_cnt_th & APEX_CONFIG3_PED_STEP_CNT_TH_SEL_MASK);
/* APEX_CONFIG4_MREG1 */
apexConfig[2] = ((apex_inputs->pedo_step_det_th << APEX_CONFIG4_PED_STEP_DET_TH_SEL_POS)
& APEX_CONFIG4_PED_STEP_DET_TH_SEL_MASK)
| (uint8_t)apex_inputs->pedo_sb_timer_th
| (uint8_t)apex_inputs->pedo_hi_enrgy_th;
/* Tilt, Lowg and highg parameters */
/* APEX_CONFIG5_MREG1 */
apexConfig[3] = (uint8_t)apex_inputs->tilt_wait_time
| (uint8_t)apex_inputs->lowg_peak_hyst
| (uint8_t)apex_inputs->highg_peak_hyst;
status |= inv_imu_write_reg(s, APEX_CONFIG2_MREG1, 4, &apexConfig[0]);
/* APEX_CONFIG0 */
status |= inv_imu_read_reg(s, APEX_CONFIG0, 1, &apexConfig[0]);
apexConfig[0] &= ~APEX_CONFIG0_DMP_POWER_SAVE_EN_MASK;
apexConfig[0] |= apex_inputs->power_save;
status |= inv_imu_write_reg(s, APEX_CONFIG0, 1, &apexConfig[0]);
/* free fall parameter, SMD parameter and parameters for Pedometer in Slow Walk mode */
/* APEX_CONFIG9_MREG1 */
apexConfig[0] = (uint8_t)apex_inputs->ff_debounce_duration
| (uint8_t)apex_inputs->smd_sensitivity
| (uint8_t)apex_inputs->sensitivity_mode;
/* Lowg and highg parameters and free fall parameters */
/* APEX_CONFIG10_MREG1 */
apexConfig[1] = (uint8_t)apex_inputs->lowg_peak_th
| (uint8_t)apex_inputs->lowg_samples_th;
/* APEX_CONFIG11_MREG1 */
apexConfig[2] = (uint8_t)apex_inputs->highg_peak_th
| (uint8_t)apex_inputs->highg_samples_th;
status |= inv_imu_write_reg(s, APEX_CONFIG9_MREG1, 3, &apexConfig[0]);
/* APEX_CONFIG12_MREG1 */
apexConfig[0] = (uint8_t)apex_inputs->ff_max_duration_cm
| (uint8_t)apex_inputs->ff_min_duration_cm;
status |= inv_imu_write_reg(s, APEX_CONFIG12_MREG1, 1, &apexConfig[0]);
status |= inv_imu_switch_off_mclk(s);
return status;
}
int inv_imu_apex_get_parameters(struct inv_imu_device *s, inv_imu_apex_parameters_t *apex_params)
{
int status = 0;
uint8_t data[7];
uint8_t value;
status |= inv_imu_read_reg(s, APEX_CONFIG0, 1, &value);
apex_params->power_save = (APEX_CONFIG0_DMP_POWER_SAVE_t)(value & APEX_CONFIG0_DMP_POWER_SAVE_EN_MASK);
/* Access continuous config registers (CONFIG2-CONFIG11) */
status |= inv_imu_read_reg(s, APEX_CONFIG2_MREG1, sizeof(data), &data[0]);
/* Get params from apex_config2 : dmp_power_save_time and low_energy_amp_th */
apex_params->power_save_time = (APEX_CONFIG2_DMP_POWER_SAVE_TIME_t)
(data[0] & APEX_CONFIG2_DMP_POWER_SAVE_TIME_SEL_MASK);
apex_params->low_energy_amp_th = (APEX_CONFIG2_LOW_ENERGY_AMP_TH_t)
(data[0] & APEX_CONFIG2_LOW_ENERGY_AMP_TH_SEL_MASK);
/* Get params from apex_config3 : pedo_amp_th and pedo_step_cnt_th */
apex_params->pedo_amp_th = (APEX_CONFIG3_PEDO_AMP_TH_t)
(data[1] & APEX_CONFIG3_PED_AMP_TH_SEL_MASK);
apex_params->pedo_step_cnt_th = (data[1] & APEX_CONFIG3_PED_STEP_CNT_TH_SEL_MASK)
>> APEX_CONFIG3_PED_STEP_CNT_TH_SEL_POS;
/* Get params from apex_config4 : pedo_step_det_th, pedo_sb_timer_th and pedo_hi_enrgy_th */
apex_params->pedo_step_det_th = (data[2] & APEX_CONFIG4_PED_STEP_DET_TH_SEL_MASK)
>> APEX_CONFIG4_PED_STEP_DET_TH_SEL_POS;
apex_params->pedo_sb_timer_th = (APEX_CONFIG4_PEDO_SB_TIMER_TH_t)
(data[2] & APEX_CONFIG4_PED_SB_TIMER_TH_SEL_MASK);
apex_params->pedo_hi_enrgy_th = (APEX_CONFIG4_PEDO_HI_ENRGY_TH_t)
(data[2] & APEX_CONFIG4_PED_HI_EN_TH_SEL_MASK);
/* Get params from apex_config5 : tilt_wait_time, lowg_peak_hyst and highg_peak_hyst */
apex_params->tilt_wait_time = (APEX_CONFIG5_TILT_WAIT_TIME_t)
(data[3] & APEX_CONFIG5_TILT_WAIT_TIME_SEL_MASK);
apex_params->lowg_peak_hyst = (APEX_CONFIG5_LOWG_PEAK_TH_HYST_t)
(data[3] & APEX_CONFIG5_LOWG_PEAK_TH_HYST_SEL_MASK);
apex_params->highg_peak_hyst = (APEX_CONFIG5_HIGHG_PEAK_TH_HYST_t)
(data[3] & APEX_CONFIG5_HIGHG_PEAK_TH_HYST_SEL_MASK);
/* Get params from apex_config9 : ff_debounce_duration, smd_sensitivity and sensitivity_mode */
apex_params->ff_debounce_duration = (APEX_CONFIG9_FF_DEBOUNCE_DURATION_t)
(data[4] & APEX_CONFIG9_FF_DEBOUNCE_DURATION_SEL_MASK);
apex_params->smd_sensitivity = (APEX_CONFIG9_SMD_SENSITIVITY_t)
(data[4] & APEX_CONFIG9_SMD_SENSITIVITY_SEL_MASK);
apex_params->sensitivity_mode = (APEX_CONFIG9_SENSITIVITY_MODE_t)
(data[4] & APEX_CONFIG9_SENSITIVITY_MODE_MASK);
/* Get params from apex_config10 : lowg_peak_th and lowg_samples_th */
apex_params->lowg_peak_th = (APEX_CONFIG10_LOWG_PEAK_TH_t)
(data[5] & APEX_CONFIG10_LOWG_PEAK_TH_SEL_MASK);
apex_params->lowg_samples_th = (APEX_CONFIG10_LOWG_TIME_TH_SAMPLES_t)
(data[5] & APEX_CONFIG10_LOWG_TIME_TH_SEL_MASK);
/* Get params from apex_config11 : highg_peak_th and highg_samples_th */
apex_params->highg_peak_th = (APEX_CONFIG11_HIGHG_PEAK_TH_t)
(data[6] & APEX_CONFIG11_HIGHG_PEAK_TH_SEL_MASK);
apex_params->highg_samples_th = (APEX_CONFIG11_HIGHG_TIME_TH_SAMPLES_t)
(data[6] & APEX_CONFIG11_HIGHG_TIME_TH_SEL_MASK);
/* Access apex reg 12 */
status |= inv_imu_read_reg(s, APEX_CONFIG12_MREG1, 1, &data[0]);
/* Get params from apex_config12 : ff_max_duration_cm and ff_min_duration_cm */
apex_params->ff_max_duration_cm = (APEX_CONFIG12_FF_MAX_DURATION_t)
(data[0] & APEX_CONFIG12_FF_MAX_DURATION_SEL_MASK);
apex_params->ff_min_duration_cm = (APEX_CONFIG12_FF_MIN_DURATION_t)
(data[0] & APEX_CONFIG12_FF_MIN_DURATION_SEL_MASK);
return status;
}
int inv_imu_apex_set_frequency(struct inv_imu_device *s, const APEX_CONFIG1_DMP_ODR_t frequency)
{
uint8_t value;
int status = 0;
status |= inv_imu_read_reg(s, APEX_CONFIG1, 1, &value);
value &= ~APEX_CONFIG1_DMP_ODR_MASK;
value |= frequency;
status |= inv_imu_write_reg(s, APEX_CONFIG1, 1, &value);
return status;
}
int inv_imu_apex_enable_pedometer(struct inv_imu_device *s)
{
int status = 0;
uint8_t value;
status |= inv_imu_start_dmp(s);
/* Enable Pedometer */
status |= inv_imu_read_reg(s, APEX_CONFIG1, 1, &value);
value &= ~APEX_CONFIG1_PED_ENABLE_MASK;
value |= (uint8_t)APEX_CONFIG1_PED_ENABLE_EN;
status |= inv_imu_write_reg(s, APEX_CONFIG1, 1, &value);
return status;
}
int inv_imu_apex_disable_pedometer(struct inv_imu_device *s)
{
int status = 0;
uint8_t value;
/* Disable Pedometer */
status |= inv_imu_read_reg(s, APEX_CONFIG1, 1, &value);
value &= ~APEX_CONFIG1_PED_ENABLE_MASK;
value |= (uint8_t)APEX_CONFIG1_PED_ENABLE_DIS;
status |= inv_imu_write_reg(s, APEX_CONFIG1, 1, &value);
return status;
}
int inv_imu_apex_enable_tilt(struct inv_imu_device *s)
{
int status = 0;
uint8_t value;
status |= inv_imu_start_dmp(s);
/* Enable Tilt */
status |= inv_imu_read_reg(s, APEX_CONFIG1, 1, &value);
value &= ~APEX_CONFIG1_TILT_ENABLE_MASK;
value |= (uint8_t)APEX_CONFIG1_TILT_ENABLE_EN;
status |= inv_imu_write_reg(s, APEX_CONFIG1, 1, &value);
return status;
}
int inv_imu_apex_disable_tilt(struct inv_imu_device *s)
{
int status = 0;
uint8_t value;
/* Disable Tilt */
status |= inv_imu_read_reg(s, APEX_CONFIG1, 1, &value);
value &= ~APEX_CONFIG1_TILT_ENABLE_MASK;
value |= (uint8_t)APEX_CONFIG1_TILT_ENABLE_DIS;
status |= inv_imu_write_reg(s, APEX_CONFIG1, 1, &value);
return status;
}
int inv_imu_apex_get_data_activity(struct inv_imu_device *s, inv_imu_apex_step_activity_t *apex_activity)
{
uint8_t data[4];
int status = inv_imu_read_reg(s, APEX_DATA0, 4, data);
apex_activity->step_cnt = data[1] << 8 | data[0];
apex_activity->step_cadence = data[2];
apex_activity->activity_class = data[3] & APEX_DATA3_ACTIVITY_CLASS_MASK;
return status;
}
int inv_imu_apex_get_data_free_fall(struct inv_imu_device *s, uint16_t *freefall_duration)
{
uint8_t data[2];
int status = inv_imu_read_reg(s, APEX_DATA4, 2, &data[0]);
*freefall_duration = (data[1] << 8) | data[0];
return status;
}

View File

@ -0,0 +1,186 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2017 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively "Software") is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/** @defgroup DriverApex IMU driver high level functions related to APEX and the DMP
* @brief High-level function to setup an IMU device
* @ingroup Driver
* @{
*/
/** @file inv_imu_apex.h
* High-level function to setup an IMU device
*/
#ifndef _INV_IMU_APEX_H_
#define _INV_IMU_APEX_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "inv_imu_defs.h"
#include "InvError.h"
#include <stdint.h>
#include <string.h>
/* Forward declarations */
struct inv_imu_device;
/** @brief IMU APEX inputs parameters definition
*/
typedef struct {
APEX_CONFIG3_PEDO_AMP_TH_t pedo_amp_th;
uint8_t pedo_step_cnt_th;
uint8_t pedo_step_det_th;
APEX_CONFIG4_PEDO_SB_TIMER_TH_t pedo_sb_timer_th;
APEX_CONFIG4_PEDO_HI_ENRGY_TH_t pedo_hi_enrgy_th;
APEX_CONFIG5_TILT_WAIT_TIME_t tilt_wait_time;
APEX_CONFIG2_DMP_POWER_SAVE_TIME_t power_save_time;
APEX_CONFIG0_DMP_POWER_SAVE_t power_save;
APEX_CONFIG9_SENSITIVITY_MODE_t sensitivity_mode;
APEX_CONFIG2_LOW_ENERGY_AMP_TH_t low_energy_amp_th;
APEX_CONFIG9_SMD_SENSITIVITY_t smd_sensitivity;
APEX_CONFIG9_FF_DEBOUNCE_DURATION_t ff_debounce_duration;
APEX_CONFIG12_FF_MAX_DURATION_t ff_max_duration_cm;
APEX_CONFIG12_FF_MIN_DURATION_t ff_min_duration_cm;
APEX_CONFIG10_LOWG_PEAK_TH_t lowg_peak_th;
APEX_CONFIG5_LOWG_PEAK_TH_HYST_t lowg_peak_hyst;
APEX_CONFIG10_LOWG_TIME_TH_SAMPLES_t lowg_samples_th;
APEX_CONFIG11_HIGHG_PEAK_TH_t highg_peak_th;
APEX_CONFIG5_HIGHG_PEAK_TH_HYST_t highg_peak_hyst;
APEX_CONFIG11_HIGHG_TIME_TH_SAMPLES_t highg_samples_th;
} inv_imu_apex_parameters_t;
/** @brief APEX pedometer outputs
*/
typedef struct inv_imu_apex_step_activity {
uint16_t step_cnt; /**< Number of steps taken */
uint8_t step_cadence; /**< Walk/run cadence in number of samples.
Format is u6.2. E.g, At 50Hz and 2Hz walk frequency, if the cadency is 25 samples.
The register will output 100. */
uint8_t activity_class; /**< Detected activity unknown (0), walk (1) or run (2) */
} inv_imu_apex_step_activity_t;
/** @brief Enable Free Fall.
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_enable_ff(struct inv_imu_device *s);
/** @brief Disable Free Fall.
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_disable_ff(struct inv_imu_device *s);
/** @brief Enable Significant Motion Detection.
* note : SMD requests to have the accelerometer enabled to work.
* To have good performance, it's recommended to set accelerometer ODR (Output Data Rate) to 20ms
* and the accelerometer in Low Power Mode.
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_enable_smd(struct inv_imu_device *s);
/** @brief Disable Significant Motion Detection.
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_disable_smd(struct inv_imu_device *s);
/** @brief Fill the APEX parameters structure with all the default parameters for APEX algorithms (pedometer, tilt)
* @param[out] apex_inputs Default input parameters. See @sa inv_imu_apex_parameters_t
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_init_parameters_struct(struct inv_imu_device *s, inv_imu_apex_parameters_t *apex_inputs);
/** @brief Configures DMP parameters for APEX algorithms (pedometer, tilt, lowg, highg).
* This programmable parameters will be decoded and propagate to the SRAM to be executed at DMP start.
* @param[in] apex_inputs The requested input parameters. See @sa inv_imu_apex_parameters_t
* @warning APEX inputs can't change on the fly, this API should be called before enabling any APEX features.
* @warning APEX configuration can't be done too frequently, but only once every 10ms.
* Otherwise it can create unknown behavior.
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_configure_parameters(struct inv_imu_device *s, const inv_imu_apex_parameters_t *apex_inputs);
/** @brief Returns current DMP parameters for APEX algorithms (pedometer, tilt).
* @param[out] apex_params The current parameter, fetched from registers. See @sa inv_imu_apex_parameters_t
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_get_parameters(struct inv_imu_device *s, inv_imu_apex_parameters_t *apex_params);
/** @brief Configure DMP Output Data Rate for APEX algorithms (pedometer, tilt)
* @param[in] frequency The requested frequency.
* @sa APEX_CONFIG1_DMP_ODR_t
* @warning DMP_ODR can change on the fly, and the DMP code will accommodate necessary modifications
* @warning The user needs to take care to set Accel frequency >= DMP frequency. This is a hard constraint
since HW will not handle incorrect setting.
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_set_frequency(struct inv_imu_device *s, const APEX_CONFIG1_DMP_ODR_t frequency);
/** @brief Enable APEX algorithm Pedometer.
* note : Pedometer request to have the accelerometer enabled to works
* with accelerometer frequency less than dmp frequency.
* @return 0 on success, negative value on error.
* @warning Pedometer must be turned OFF to reconfigure it
*/
int inv_imu_apex_enable_pedometer(struct inv_imu_device *s);
/** @brief Disable APEX algorithm Pedometer.
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_disable_pedometer(struct inv_imu_device *s);
/** @brief Enable APEX algorithm Tilt.
* note : Tilt request to have the accelerometer enabled to works
* with accelerometer frequency less than dmp frequency.
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_enable_tilt(struct inv_imu_device *s);
/** @brief Disable APEX algorithm Tilt.
* @return 0 on success, negative value on error.
*/
int inv_imu_apex_disable_tilt(struct inv_imu_device *s);
/** @brief Retrieve APEX pedometer outputs and format them
* @param[out] apex_activity Apex step and activity data value.
* @return 0 in case of success, negative value on error. See enum inv_error
*/
int inv_imu_apex_get_data_activity(struct inv_imu_device *s, inv_imu_apex_step_activity_t *apex_activity);
/** @brief Retrieve APEX free fall outputs and format them
* @param[out] Free fall duration in number of sample.
* @return 0 in case of success, negative value on error. See enum inv_error
*/
int inv_imu_apex_get_data_free_fall(struct inv_imu_device *s, uint16_t *freefall_duration);
#ifdef __cplusplus
}
#endif
#endif /* _INV_IMU_APEX_H_ */
/** @} */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,533 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2017 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively "Software") is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/** @defgroup Driver IMU driver high level functions
* @brief High-level function to setup an IMU device
* @ingroup DriverIcm
* @{
*/
/** @file inv_imu_driver.h
* High-level function to setup an IMU device
*/
#ifndef _INV_IMU_DRIVER_H_
#define _INV_IMU_DRIVER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "inv_imu_defs.h"
#include "inv_imu_transport.h"
#include "InvError.h"
#include <stdint.h>
#include <string.h>
/** @brief IMU max FSR values for accel and gyro
* Dependent on chip
*/
#define ACCEL_CONFIG0_FS_SEL_MAX ACCEL_CONFIG0_FS_SEL_16g
#define GYRO_CONFIG0_FS_SEL_MAX GYRO_CONFIG0_FS_SEL_2000dps
#define ACCEL_OFFUSER_MAX_MG 1000
#define GYRO_OFFUSER_MAX_DPS 64
/** @brief IMU maximum buffer size mirrored from FIFO at polling time
* @warning fifo_idx type variable must be large enough to parse the FIFO_MIRRORING_SIZE
*/
#define FIFO_MIRRORING_SIZE 16 * 258 // packet size * max_count = 4kB
/** @brief IMU Accelerometer start-up time before having correct data
*/
#define ACC_STARTUP_TIME_US 10000
/** @brief IMU Gyroscope start-up time before having correct data
*/
#define GYR_STARTUP_TIME_US 70000
/** @brief IMU Gyroscope power off to power on duration
*/
#define GYR_POWER_OFF_DUR_US 20000
/** @brief Sensor identifier for UI control function
*/
enum inv_imu_sensor {
INV_SENSOR_ACCEL, /**< Accelerometer */
INV_SENSOR_GYRO, /**< Gyroscope */
INV_SENSOR_FSYNC_EVENT, /**< FSYNC */
INV_SENSOR_TEMPERATURE, /**< Chip temperature */
INV_SENSOR_DMP_PEDOMETER_EVENT, /**< Pedometer: step detected */
INV_SENSOR_DMP_PEDOMETER_COUNT, /**< Pedometer: step counter */
INV_SENSOR_DMP_TILT, /**< Tilt */
INV_SENSOR_DMP_FF, /**< FreeFall */
INV_SENSOR_DMP_LOWG, /**< Low G */
INV_SENSOR_DMP_SMD, /**< Significant Motion Detection */
INV_SENSOR_MAX
};
/** @brief Configure Fifo usage
*/
typedef enum {
INV_IMU_FIFO_DISABLED = 0, /**< Fifo is disabled and data source is sensors registers */
INV_IMU_FIFO_ENABLED = 1, /**< Fifo is used as data source */
} INV_IMU_FIFO_CONFIG_t;
/** @brief Sensor event structure definition
*/
typedef struct {
int sensor_mask;
uint16_t timestamp_fsync;
int16_t accel[3];
int16_t gyro[3];
int16_t temperature;
int8_t accel_high_res[3];
int8_t gyro_high_res[3];
} inv_imu_sensor_event_t;
/** @brief IMU driver states definition
*/
struct inv_imu_device {
struct inv_imu_transport transport; /**< Transport layer
Must be the first one of struct inv_imu_device */
void (*sensor_event_cb)(inv_imu_sensor_event_t *event); /**< callback executed by:
inv_imu_get_data_from_fifo (if FIFO is used)
inv_imu_get_data_from_registers (if FIFO isn't used)
May be NULL if above API are not used by application */
uint8_t fifo_data[FIFO_MIRRORING_SIZE]; /**< FIFO mirroring memory area */
uint8_t dmp_is_on; /**< DMP started status */
uint8_t endianness_data; /**< Data endianness configuration */
uint8_t fifo_highres_enabled; /**< Highres mode configuration */
INV_IMU_FIFO_CONFIG_t fifo_is_used; /**< FIFO configuration */
uint64_t gyro_start_time_us; /**< Gyro start time used to discard first samples */
uint64_t accel_start_time_us; /**< Accel start time used to discard first samples */
uint64_t gyro_power_off_tmst; /**< Gyro power off time */
};
/* Interrupt enum state for INT1, INT2, and IBI */
typedef enum {
INV_IMU_DISABLE = 0,
INV_IMU_ENABLE
} inv_imu_interrupt_value;
/** @brief Interrupt definition
*/
typedef struct {
inv_imu_interrupt_value INV_UI_FSYNC;
inv_imu_interrupt_value INV_UI_DRDY;
inv_imu_interrupt_value INV_FIFO_THS;
inv_imu_interrupt_value INV_FIFO_FULL;
inv_imu_interrupt_value INV_SMD;
inv_imu_interrupt_value INV_WOM_X;
inv_imu_interrupt_value INV_WOM_Y;
inv_imu_interrupt_value INV_WOM_Z;
inv_imu_interrupt_value INV_FF;
inv_imu_interrupt_value INV_LOWG;
inv_imu_interrupt_value INV_STEP_DET;
inv_imu_interrupt_value INV_STEP_CNT_OVFL;
inv_imu_interrupt_value INV_TILT_DET;
} inv_imu_interrupt_parameter_t;
/** @brief Configure the serial interface used to access the device and execute hardware initialization.
*
* This functions first configures serial interface passed in parameter to make sure device
* is accessible both in read and write. Thus no serial access should be done before
* successfully executing the present function.
*
* Then if requested serial interface is a primary interface (aka UI interface or AP
* interface), this function initializes the device using the following hardware settings:
* - set timestamp resolution to 16us
* - enable FIFO mechanism with the following configuration:
* - FIFO record mode i.e FIFO count unit is packet
* - FIFO snapshot mode i.e drop the data when the FIFO overflows
* - Timestamp is logged in FIFO
* - Little Endian fifo_count and fifo_data
* - generate FIFO threshold interrupt when packet count reaches FIFO watermark
* - set FIFO watermark to 1 packet
* - enable temperature and timestamp data to go to FIFO
*
*
* @param[in] s driver structure. Note that first field of this structure MUST be a struct
* inv_imu_serif.
*
* @param[in] serif pointer on serial interface structure to be used to access inv_device.
*
* @param[in] sensor_event_cb callback executed by inv_imu_get_data_from_fifo function
* each time it extracts some valid data from fifo. Or inv_imu_get_data_from_registers read data
* from register. Thus this parameter is optional as long
* as inv_imu_get_data_from_fifo/inv_imu_get_data_from_registers function is not used.
*
* @return 0 on success, negative value on error.
*/
int inv_imu_init(struct inv_imu_device *s,
struct inv_imu_serif *serif,
void (*sensor_event_cb)(inv_imu_sensor_event_t *event));
/** @brief Perform a soft reset of the device
* @return 0 on success, negative value on error.
*/
int inv_imu_device_reset(struct inv_imu_device *s);
/** @brief return WHOAMI value
* @param[out] who_am_i WHOAMI for device
* @return 0 on success, negative value on error
*/
int inv_imu_get_who_am_i(struct inv_imu_device *s, uint8_t *who_am_i);
/** @brief Enable/put accel in low power mode
* @return 0 on success, negative value on error.
* @details
* It enables accel and gyro data in the FIFO (so
* the packet format is 16 bytes). If called first,
* the configuration will be applied, otherwise it
* will be ignored if the FIFO is not empty (but since
* the new configuration is identical it is not a issue).
* @warning inv_device::register_cache::pwr_mgmt0_reg is modified by this function
*/
int inv_imu_enable_accel_low_power_mode(struct inv_imu_device *s);
/** @brief Enable/put accel in low noise mode
* @return 0 on success, negative value on error.
* @details
* It enables accel and gyro data in the FIFO (so
* the packet format is 16 bytes). If called first,
* the configuration will be applied, otherwise it
* will be ignored if the FIFO is not empty (but since
* the new configuration is identical it is not a issue).
* @warning inv_device::register_cache::pwr_mgmt0_reg is modified by this function
*/
int inv_imu_enable_accel_low_noise_mode(struct inv_imu_device *s);
/** @brief Disable all 3 axes of accel
* @return 0 on success, negative value on error.
* @details
* If both accel and gyro are turned off as a result of this
* function, they will also be removed from the FIFO and a
* FIFO reset will be performed (to guarantee no side effects
* until the next enable sensor call)
* @warning inv_device::register_cache::pwr_mgmt0_reg is modified by this function
*/
int inv_imu_disable_accel(struct inv_imu_device *s);
/** @brief Enable/put gyro in low noise mode
* @return 0 on success, negative value on error.
* @details
* It enables gyro and accel data in the FIFO (so
* the packet format is 16 bytes). If called first,
* the configuration will be applied, otherwise it
* will be ignored if the FIFO is not empty (but since
* the new configuration is identical it is not a issue).
* @warning inv_device::register_cache::pwr_mgmt0_reg is modified by this function
*/
int inv_imu_enable_gyro_low_noise_mode(struct inv_imu_device *s);
/** @brief Disable all 3 axes of gyro
* @return 0 on success, negative value on error.
* @details
* If both accel and gyro are turned off as a result of this
* function, they will also be removed from the FIFO and a
* FIFO reset will be performed (to guarantee no side effects
* until the next enable sensor call)
* @warning inv_device::register_cache::pwr_mgmt0_reg is modified by this function
*/
int inv_imu_disable_gyro(struct inv_imu_device *s);
/** @brief Enable fsync tagging functionality.
* In details it:
* - enables fsync
* - enables timestamp to registers. Once fsync is enabled fsync counter is pushed to
* fifo instead of timestamp. So timestamp is made available in registers. Note that
* this increase power consumption.
* - enables fsync related interrupt
* @return 0 on success, negative value on error.
*/
int inv_imu_enable_fsync(struct inv_imu_device *s);
/** @brief Disable fsync tagging functionality.
* In details it:
* - disables fsync
* - disables timestamp to registers. Once fsync is disabled timestamp is pushed to fifo
* instead of fsync counter. So in order to decrease power consumption, timestamp is no
* more available in registers.
* - disables fsync related interrupt
* @return 0 on success, negative value on error.
*/
int inv_imu_disable_fsync(struct inv_imu_device *s);
/** @brief Configure which interrupt source can trigger INT1.
* @param[in] interrupt_to_configure structure with the corresponding state to manage INT1.
* @return 0 on success, negative value on error.
*/
int inv_imu_set_config_int1(struct inv_imu_device *s,
inv_imu_interrupt_parameter_t *interrupt_to_configure);
/** @brief Retrieve interrupts configuration.
* @param[in] interrupt_to_configure structure with the corresponding state to manage INT1.
* @return 0 on success, negative value on error.
*/
int inv_imu_get_config_int1(struct inv_imu_device *s,
inv_imu_interrupt_parameter_t *interrupt_to_configure);
/** @brief Configure which interrupt source can trigger INT2.
* @param[in] interrupt_to_configure structure with the corresponding state to INT2.
* @return 0 on success, negative value on error.
*/
int inv_imu_set_config_int2(struct inv_imu_device *s,
inv_imu_interrupt_parameter_t *interrupt_to_configure);
/** @brief Retrieve interrupts configuration.
* @param[in] interrupt_to_configure structure with the corresponding state to manage INT2.
* @return 0 on success, negative value on error.
*/
int inv_imu_get_config_int2(struct inv_imu_device *s,
inv_imu_interrupt_parameter_t *interrupt_to_configure);
/** @brief Read all registers containing data (temperature, accelerometer and gyroscope). Then it calls
* sensor_event_cb function passed in parameter of inv_imu_init function for each packet
* @return 0 on success, negative value on error.
*/
int inv_imu_get_data_from_registers(struct inv_imu_device *s);
/** @brief Read all available packets from the FIFO. For each packet function builds a
* sensor event containing packet data and validity information. Then it calls
* sensor_event_cb funtion passed in parameter of inv_imu_init function for each
* packet.
* @return number of valid packets read on success, negative value on error.
*/
int inv_imu_get_data_from_fifo(struct inv_imu_device *s);
/** @brief Converts ACCEL_CONFIG0_ODR_t or GYRO_CONFIG0_ODR_t enums to period expressed in us
* @param[in] odr_bitfield An ACCEL_CONFIG0_ODR_t or GYRO_CONFIG0_ODR_t enum
* @return The corresponding period expressed in us
*/
uint32_t inv_imu_convert_odr_bitfield_to_us(uint32_t odr_bitfield);
/** @brief Configure accel Output Data Rate
* @param[in] frequency The requested frequency.
* @sa ACCEL_CONFIG0_ODR_t
* @return 0 on success, negative value on error.
* @warning inv_device::register_cache::accel_config0_reg is modified by this function
*/
int inv_imu_set_accel_frequency(struct inv_imu_device *s,
const ACCEL_CONFIG0_ODR_t frequency);
/** @brief Configure gyro Output Data Rate
* @param[in] frequency The requested frequency.
* @sa GYRO_CONFIG0_ODR_t
* @return 0 on success, negative value on error.
* @warning inv_device::register_cache::gyro_config0_reg is modified by this function
*/
int inv_imu_set_gyro_frequency(struct inv_imu_device *s,
const GYRO_CONFIG0_ODR_t frequency);
/** @brief Set accel full scale range
* @param[in] accel_fsr_g requested full scale range.
* @sa ACCEL_CONFIG0_FS_SEL_t.
* @return 0 on success, negative value on error.
* @warning inv_device::register_cache::accel_config0_reg is modified by this function
*/
int inv_imu_set_accel_fsr(struct inv_imu_device *s,
ACCEL_CONFIG0_FS_SEL_t accel_fsr_g);
/** @brief Access accel full scale range
* @param[out] accel_fsr_g current full scale range.
* @sa ACCEL_CONFIG0_FS_SEL_t.
* @return 0 on success, negative value on error.
* @warning inv_device::register_cache::accel_config0_reg is relied upon by this function
*/
int inv_imu_get_accel_fsr(struct inv_imu_device *s,
ACCEL_CONFIG0_FS_SEL_t *accel_fsr_g);
/** @brief Set gyro full scale range
* @param[in] gyro_fsr_dps requested full scale range.
* @sa GYRO_CONFIG0_FS_SEL_t.
* @return 0 on success, negative value on error.
* @warning inv_device::register_cache::gyro_config0_reg is modified by this function
*/
int inv_imu_set_gyro_fsr(struct inv_imu_device *s,
GYRO_CONFIG0_FS_SEL_t gyro_fsr_dps);
/** @brief Access gyro full scale range
* @param[out] gyro_fsr_dps current full scale range.
* @sa GYRO_CONFIG0_FS_SEL_t.
* @return 0 on success, negative value on error.
* @warning inv_device::register_cache::gyro_config0_reg is relied upon by this function
*/
int inv_imu_get_gyro_fsr(struct inv_imu_device *s,
GYRO_CONFIG0_FS_SEL_t *gyro_fsr_dps);
/** @brief Set accel Low-Power averaging value
* @param[in] acc_avg requested averaging value
* @sa ACCEL_CONFIG1_ACCEL_FILT_AVG_t
* @return 0 on success, negative value on error.
*/
int inv_imu_set_accel_lp_avg(struct inv_imu_device *s,
ACCEL_CONFIG1_ACCEL_FILT_AVG_t acc_avg);
/** @brief Set accel Low-Noise bandwidth value
* @param[in] acc_bw requested averaging value
* @sa ACCEL_CONFIG1_ACCEL_FILT_BW_t
* @return 0 on success, negative value on error.
*/
int inv_imu_set_accel_ln_bw(struct inv_imu_device *s,
ACCEL_CONFIG1_ACCEL_FILT_BW_t acc_bw);
/** @brief Set gyro Low-Noise bandwidth value
* @param[in] gyr_bw requested averaging value
* @sa GYRO_CONFIG1_GYRO_FILT_BW_t
* @return 0 on success, negative value on error.
*/
int inv_imu_set_gyro_ln_bw(struct inv_imu_device *s,
GYRO_CONFIG1_GYRO_FILT_BW_t gyr_bw);
/** @brief Set timestamp resolution
* @param[in] timestamp_resol requested timestamp resolution
* @sa TMST_CONFIG1_RESOL_t
* @return 0 on success, negative value on error.
*/
int inv_imu_set_timestamp_resolution(struct inv_imu_device *s,
const TMST_CONFIG1_RESOL_t timestamp_resol);
/** @brief reset IMU fifo
* @return 0 on success, negative value on error.
*/
int inv_imu_reset_fifo(struct inv_imu_device *s);
/** @brief Enable 20 bits raw acc and raw gyr data in fifo.
* @return 0 on success, negative return code otherwise
*/
int inv_imu_enable_high_resolution_fifo(struct inv_imu_device *s);
/** @brief Disable 20 bits raw acc and raw gyr data in fifo.
* @return 0 on success, negative return code otherwise
*/
int inv_imu_disable_high_resolution_fifo(struct inv_imu_device *s);
/** @brief Configure Fifo
* @param[in] fifo_config Fifo configuration method :
* if FIFO is enabled, data are pushed to FIFO and FIFO THS interrupt is set
* if FIFO is disabled, data are not pused to FIFO and DRDY interrupt is set
* @sa INV_IMU_FIFO_CONFIG_t
*/
int inv_imu_configure_fifo(struct inv_imu_device *s,
INV_IMU_FIFO_CONFIG_t fifo_config);
/** @brief Get FIFO timestamp resolution
* @return the timestamp resolution in us as a q24 or 0 in case of error
*/
uint32_t inv_imu_get_fifo_timestamp_resolution_us_q24(struct inv_imu_device *s);
/** @brief Get register timestamp resolution
* @return the timestamp resolution in us as a q24 or 0 in case of error
*/
uint32_t inv_imu_get_reg_timestamp_resolution_us_q24(struct inv_imu_device *s);
/** @brief Enable Wake On Motion.
* @param[in] wom_x_th threshold value for the Wake on Motion Interrupt for X-axis accelerometer.
* @param[in] wom_y_th threshold value for the Wake on Motion Interrupt for Y-axis accelerometer.
* @param[in] wom_z_th threshold value for the Wake on Motion Interrupt for Z-axis accelerometer.
* @param[in] wom_int select which mode between AND/OR is used to generate interrupt.
* @param[in] wom_dur select the number of overthreshold event to wait before generating interrupt.
* @return 0 on success, negative value on error.
*/
int inv_imu_configure_wom(struct inv_imu_device *s,
const uint8_t wom_x_th,
const uint8_t wom_y_th,
const uint8_t wom_z_th,
WOM_CONFIG_WOM_INT_MODE_t wom_int,
WOM_CONFIG_WOM_INT_DUR_t wom_dur);
/** @brief Enable Wake On Motion.
* note : WoM requests to have the accelerometer enabled to work.
* As a consequence Fifo water-mark interrupt is disabled to only trigger WoM interrupts.
* To have good performance, it's recommended to set accelerometer ODR (Output Data Rate) to 20ms
* and the accelerometer in Low Power Mode.
* @return 0 on success, negative value on error.
*/
int inv_imu_enable_wom(struct inv_imu_device *s);
/** @brief Disable Wake On Motion.
* note : Fifo water-mark interrupt is re-enabled when WoM is disabled.
* @return 0 on success, negative value on error.
*/
int inv_imu_disable_wom(struct inv_imu_device *s);
/** @brief Start DMP for APEX algorithms and selftest
* @return 0 on success, negative value on error.
*/
int inv_imu_start_dmp(struct inv_imu_device *s);
/** @brief Reset DMP for APEX algorithms and selftest
* @return 0 on success, negative value on error.
*/
int inv_imu_reset_dmp(struct inv_imu_device *s,
const APEX_CONFIG0_DMP_MEM_RESET_t sram_reset);
/** @breif Set the UI endianness and set the inv_device endianness field
* @return 0 on success, negative value on error.
*/
int inv_imu_set_endianness(struct inv_imu_device *s,
INTF_CONFIG0_DATA_ENDIAN_t endianness);
/** @breif Read the UI endianness and set the inv_device endianness field
* @return 0 on success, negative value on error.
*/
int inv_imu_get_endianness(struct inv_imu_device *s);
//The device powers up in sleep mode.
//any time change
//Sleep mode, and Accelerometer low power mode with WUOSC do not support MREG1, MREG2 or MREG3 access.
//need power on the RC oscillator using register field IDLE from register PWR_MGMT0.
int inv_imu_enter_sleep(struct inv_imu_device *s);
//power on:
//After powering the gyroscope off, a period of > 20ms should be allowed to elapse before it is powered back on.
//Accelerometer Startup Time From sleep mode to valid data:10ms.
//gpro need >45ms
int inv_imu_exit_sleep(struct inv_imu_device *s);
/** @brief Configure Fifo decimation
* @param[in] requested decimation factor value from 2 to 256
* @return 0 on success, negative value on error.
*/
int inv_imu_configure_fifo_data_rate(struct inv_imu_device *s,
FDR_CONFIG_FDR_SEL_t dec_factor);
/** @brief Return driver version x.y.z-suffix as a char array
* @retval driver version a char array "x.y.z-suffix"
*/
const char *inv_imu_get_version(void);
#ifdef __cplusplus
}
#endif
#endif /* _INV_IMU_DRIVER_H_ */
/** @} */

View File

@ -0,0 +1,65 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2017 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively "Software") is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/** @defgroup DriverExt IMU driver extern functions
* @brief Extern functions for IMU devices
* @ingroup Driver
* @{
*/
/** @file inv_imu_extfunc.h
* Extern functions for IMU devices
*/
#ifndef _INV_IMU_EXTFUNC_H_
#define _INV_IMU_EXTFUNC_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Hook for low-level high res system sleep() function to be implemented by upper layer
* ~100us resolution is sufficient
* @param[in] us number of us the calling thread should sleep
*/
extern void inv_imu_sleep_us(uint32_t us);
/** @brief Hook for low-level high res system get_time() function to be implemented by upper layer
* Value shall be on 64bit with a 1 us resolution
* @return The current time in us
*/
extern uint64_t inv_imu_get_time_us(void);
#ifdef __cplusplus
}
#endif
#endif /* _INV_IMU_EXTFUNC_H_ */
/** @} */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,275 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2015-2015 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively "Software") is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
#include "inv_imu_extfunc.h"
#include "inv_imu_transport.h"
#include "inv_imu_regmap.h"
#include "InvError.h"
/* Function definition */
static uint8_t *get_register_cache_addr(struct inv_imu_device *s, uint32_t reg);
static int write_sreg(struct inv_imu_device *s, uint8_t reg, uint32_t len, const uint8_t *buf);
static int read_sreg(struct inv_imu_device *s, uint8_t reg, uint32_t len, uint8_t *buf);
static int write_mclk_reg(struct inv_imu_device *s, uint16_t regaddr, uint8_t wr_cnt, const uint8_t *buf);
static int read_mclk_reg(struct inv_imu_device *s, uint16_t regaddr, uint8_t rd_cnt, uint8_t *buf);
int inv_imu_init_transport(struct inv_imu_device *s)
{
int status = 0;
struct inv_imu_transport *t = (struct inv_imu_transport *)s;
status |= read_sreg(s, (uint8_t)PWR_MGMT0, 1, &(t->register_cache.pwr_mgmt0_reg));
status |= read_sreg(s, (uint8_t)GYRO_CONFIG0, 1, &(t->register_cache.gyro_config0_reg));
status |= read_sreg(s, (uint8_t)ACCEL_CONFIG0, 1, &(t->register_cache.accel_config0_reg));
status |= read_mclk_reg(s, (TMST_CONFIG1_MREG1 & 0xFFFF), 1, &(t->register_cache.tmst_config1_reg));
t->need_mclk_cnt = 0;
return status;
}
int inv_imu_read_reg(struct inv_imu_device *s, uint32_t reg, uint32_t len, uint8_t *buf)
{
uint32_t i;
int rc = 0;
for (i = 0; i < len; i++) {
uint8_t *cache_addr = get_register_cache_addr(s, reg + i);
if (cache_addr) {
buf[i] = *cache_addr;
} else {
if (!(reg & 0x10000)) {
rc |= read_mclk_reg(s, ((reg + i) & 0xFFFF), 1, &buf[i]);
} else {
rc |= read_sreg(s, (uint8_t)reg + i, len - i, &buf[i]);
break;
}
}
}
return rc;
}
int inv_imu_write_reg(struct inv_imu_device *s, uint32_t reg, uint32_t len, const uint8_t *buf)
{
uint32_t i;
int rc = 0;
for (i = 0; i < len; i++) {
uint8_t *cache_addr = get_register_cache_addr(s, reg + i);
if (cache_addr) {
*cache_addr = buf[i];
}
if (!(reg & 0x10000)) {
rc |= write_mclk_reg(s, ((reg + i) & 0xFFFF), 1, &buf[i]);
}
}
if (reg & 0x10000) {
rc |= write_sreg(s, (uint8_t)reg, len, buf);
}
return rc;
}
int inv_imu_switch_on_mclk(struct inv_imu_device *s)
{
int status = 0;
uint8_t data;
struct inv_imu_transport *t = (struct inv_imu_transport *)s;
/* set IDLE bit only if it is not set yet */
if (t->need_mclk_cnt == 0) {
status |= inv_imu_read_reg(s, PWR_MGMT0, 1, &data);
data |= PWR_MGMT0_IDLE_MASK;
status |= inv_imu_write_reg(s, PWR_MGMT0, 1, &data);
if (status) {
return status;
}
/* Check if MCLK is ready */
do {
status = inv_imu_read_reg(s, MCLK_RDY, 1, &data);
} while ((status != 0) || !(data & MCLK_RDY_MCLK_RDY_MASK));
} else {
/* Make sure it is already on */
status |= inv_imu_read_reg(s, PWR_MGMT0, 1, &data);
if (0 == (data &= PWR_MGMT0_IDLE_MASK)) {
status |= INV_ERROR;
}
}
/* Increment the counter to keep track of number of MCLK requesters */
t->need_mclk_cnt++;
return status;
}
int inv_imu_switch_off_mclk(struct inv_imu_device *s)
{
int status = 0;
uint8_t data;
struct inv_imu_transport *t = (struct inv_imu_transport *)s;
/* Reset the IDLE but only if there is one requester left */
if (t->need_mclk_cnt == 1) {
status |= inv_imu_read_reg(s, PWR_MGMT0, 1, &data);
data &= ~PWR_MGMT0_IDLE_MASK;
status |= inv_imu_write_reg(s, PWR_MGMT0, 1, &data);
} else {
/* Make sure it is still on */
status |= inv_imu_read_reg(s, PWR_MGMT0, 1, &data);
if (0 == (data &= PWR_MGMT0_IDLE_MASK)) {
status |= INV_ERROR;
}
}
/* Decrement the counter */
t->need_mclk_cnt--;
return status;
}
/* Static function */
static uint8_t *get_register_cache_addr(struct inv_imu_device *s, uint32_t reg)
{
struct inv_imu_transport *t = (struct inv_imu_transport *)s;
switch (reg) {
case PWR_MGMT0:
return &(t->register_cache.pwr_mgmt0_reg);
case GYRO_CONFIG0:
return &(t->register_cache.gyro_config0_reg);
case ACCEL_CONFIG0:
return &(t->register_cache.accel_config0_reg);
case TMST_CONFIG1_MREG1:
return &(t->register_cache.tmst_config1_reg);
default:
return (uint8_t *)0; // Not found
}
}
static int read_sreg(struct inv_imu_device *s, uint8_t reg, uint32_t len, uint8_t *buf)
{
struct inv_imu_serif *serif = (struct inv_imu_serif *)s;
if (len > serif->max_read) {
return INV_ERROR_SIZE;
}
if (serif->read_reg(serif, reg, buf, len) != 0) {
return INV_ERROR_TRANSPORT;
}
return 0;
}
static int write_sreg(struct inv_imu_device *s, uint8_t reg, uint32_t len, const uint8_t *buf)
{
struct inv_imu_serif *serif = (struct inv_imu_serif *)s;
if (len > serif->max_write) {
return INV_ERROR_SIZE;
}
if (serif->write_reg(serif, reg, buf, len) != 0) {
return INV_ERROR_TRANSPORT;
}
return 0;
}
static int read_mclk_reg(struct inv_imu_device *s, uint16_t regaddr, uint8_t rd_cnt, uint8_t *buf)
{
uint8_t data;
uint8_t blk_sel = (regaddr & 0xFF00) >> 8;
int status = 0;
// Have IMU not in IDLE mode to access MCLK domain
status |= inv_imu_switch_on_mclk(s);
// optimize by changing BLK_SEL only if not NULL
if (blk_sel) {
status |= write_sreg(s, (uint8_t)BLK_SEL_R & 0xff, 1, &blk_sel);
}
data = (regaddr & 0x00FF);
status |= write_sreg(s, (uint8_t)MADDR_R, 1, &data);
inv_imu_sleep_us(10);
status |= read_sreg(s, (uint8_t)M_R, rd_cnt, buf);
inv_imu_sleep_us(10);
if (blk_sel) {
data = 0;
status |= write_sreg(s, (uint8_t)BLK_SEL_R, 1, &data);
}
// switch OFF MCLK if needed
status |= inv_imu_switch_off_mclk(s);
return status;
}
static int write_mclk_reg(struct inv_imu_device *s, uint16_t regaddr, uint8_t wr_cnt, const uint8_t *buf)
{
uint8_t data;
uint8_t blk_sel = (regaddr & 0xFF00) >> 8;
int status = 0;
// Have IMU not in IDLE mode to access MCLK domain
status |= inv_imu_switch_on_mclk(s);
// optimize by changing BLK_SEL only if not NULL
if (blk_sel) {
status |= write_sreg(s, (uint8_t)BLK_SEL_W, 1, &blk_sel);
}
data = (regaddr & 0x00FF);
status |= write_sreg(s, (uint8_t)MADDR_W, 1, &data);
for (uint8_t i = 0; i < wr_cnt; i++) {
status |= write_sreg(s, (uint8_t)M_W, 1, &buf[i]);
inv_imu_sleep_us(10);
}
if (blk_sel) {
data = 0;
status = write_sreg(s, (uint8_t)BLK_SEL_W, 1, &data);
}
status |= inv_imu_switch_off_mclk(s);
return status;
}

View File

@ -0,0 +1,122 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2015-2015 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively "Software") is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
/** @defgroup Transport IMU transport
* @brief Low-level IMU SCLK register access
* @ingroup Driver
* @{
*/
/** @file inv_imu_transport.h
* Low-level IMU SCLK register access
*/
#ifndef _INV_IMU_TRANSPORT_H_
#define _INV_IMU_TRANSPORT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/* forward declaration */
struct inv_imu_device;
/** @brief enumeration of serial interfaces available on IMU */
typedef enum {
UI_I2C,
UI_SPI4,
UI_SPI3
} SERIAL_IF_TYPE_t;
/** @brief basesensor serial interface
*/
struct inv_imu_serif {
void *context;
int (*read_reg)(struct inv_imu_serif *serif, uint8_t reg, uint8_t *buf, uint32_t len);
int (*write_reg)(struct inv_imu_serif *serif, uint8_t reg, const uint8_t *buf, uint32_t len);
int (*configure)(struct inv_imu_serif *serif);
uint32_t max_read;
uint32_t max_write;
SERIAL_IF_TYPE_t serif_type;
};
/** @brief transport interface
*/
struct inv_imu_transport {
struct inv_imu_serif serif; /**< Warning : this field MUST be the first one of struct inv_imu_transport */
/** @brief Contains mirrored values of some IP registers */
struct register_cache {
uint8_t pwr_mgmt0_reg; /**< PWR_MGMT0, Bank: 0 */
uint8_t gyro_config0_reg; /**< GYRO_CONFIG0, Bank: 0 */
uint8_t accel_config0_reg; /**< ACCEL_CONFIG0, Bank: 0 */
uint8_t tmst_config1_reg; /**< TMST_CONFIG1, Bank: MREG_TOP1 */
} register_cache; /**< Store mostly used register values on SRAM */
uint8_t need_mclk_cnt; /**< internal counter to keep track of everyone that needs MCLK */
};
/** @brief Init cache variable.
* @return 0 in case of success, -1 for any error
*/
int inv_imu_init_transport(struct inv_imu_device *s);
/** @brief Reads data from a register on IMU.
* @param[in] reg register address to be read
* @param[in] len number of byte to be read
* @param[out] buf output data from the register
* @return 0 in case of success, -1 for any error
*/
int inv_imu_read_reg(struct inv_imu_device *s, uint32_t reg, uint32_t len, uint8_t *buf);
/** @brief Writes data to a register on IMU.
* @param[in] reg register address to be written
* @param[in] len number of byte to be written
* @param[in] buf input data to write
* @return 0 in case of success, -1 for any error
*/
int inv_imu_write_reg(struct inv_imu_device *s, uint32_t reg, uint32_t len, const uint8_t *buf);
/** @brief Enable MCLK so that MREG are clocked and system beyond SOI can be safely accessed
* @return 0 in case of success, -1 for any error
*/
int inv_imu_switch_on_mclk(struct inv_imu_device *s);
/** @brief Disable MCLK so that MREG are not clocked anymore, hence reducing power consumption
* @return 0 in case of success, -1 for any error
*/
int inv_imu_switch_off_mclk(struct inv_imu_device *s);
#ifdef __cplusplus
}
#endif
#endif /* _INV_IMU_TRANSPORT_H_ */
/** @} */

View File

@ -0,0 +1,38 @@
/*
* ________________________________________________________________________________________________________
* Copyright (c) 2019 InvenSense Inc. All rights reserved.
*
* This software, related documentation and any modifications thereto (collectively “Software”) is subject
* to InvenSense and its licensors' intellectual property rights under U.S. and international copyright
* and other intellectual property rights laws.
*
* InvenSense and its licensors retain all intellectual property and proprietary rights in and to the Software
* and any use, reproduction, disclosure or distribution of the Software without an express license agreement
* from InvenSense is strictly prohibited.
*
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, THE SOFTWARE IS
* PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* EXCEPT AS OTHERWISE PROVIDED IN A LICENSE AGREEMENT BETWEEN THE PARTIES, IN NO EVENT SHALL
* INVENSENSE BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THE SOFTWARE.
* ________________________________________________________________________________________________________
*/
#ifndef _INV_IMU_VERSION_H_
#define _INV_IMU_VERSION_H_
#ifdef __cplusplus
extern "C" {
#endif
#define INV_IMU_VERSION_STRING "2.0.4"
#ifdef __cplusplus
}
#endif
#endif /* _INV_IMU_VERSION_H_ */

View File

@ -0,0 +1,238 @@
#include "imuSensor_manage.h"
/* #include "asm/iic_hw.h" */
/* #include "asm/iic_soft.h" */
#if TCFG_IMUSENSOR_ENABLE
#undef LOG_TAG_CONST
#define LOG_TAG "[imu]"
#define LOG_ERROR_ENABLE
#define LOG_INFO_ENABLE
#include "debug.h"
static struct imusensor_platform_data *platform_data;
IMU_SENSOR_INTERFACE *imuSensor_hdl = NULL;
u8 imu_sensor_cnt = 0;
#if 0/*{{{*/
u8 imusensor_write_nbyte(u8 w_chip_id, u8 register_address, u8 *buf, u8 data_len)
{
u8 write_len = 0;
u8 i;
iic_start(imuSensor_info->iic_hdl);
if (0 == iic_tx_byte(imuSensor_info->iic_hdl, w_chip_id)) {
write_len = 0;
r_printf("\n imuSensor iic w err 0\n");
goto __wend;
}
delay(imuSensor_info->iic_delay);
if (0 == iic_tx_byte(imuSensor_info->iic_hdl, register_address)) {
write_len = 0;
r_printf("\n imuSensor iic w err 1\n");
goto __wend;
}
for (i = 0; i < data_len; i++) {
delay(imuSensor_info->iic_delay);
if (0 == iic_tx_byte(imuSensor_info->iic_hdl, buf[i])) {
write_len = 0;
r_printf("\n imuSensor iic w err 2\n");
goto __wend;
}
write_len++;
}
__wend:
iic_stop(imuSensor_info->iic_hdl);
return write_len;
}
u8 imusensor_read_nbyte(u8 r_chip_id, u8 register_address, u8 *buf, u8 data_len)
{
u8 read_len = 0;
iic_start(imuSensor_info->iic_hdl);
if (0 == iic_tx_byte(imuSensor_info->iic_hdl, r_chip_id - 1)) {
r_printf("\n imuSensor iic r err 0\n");
read_len = 0;
goto __rend;
}
delay(imuSensor_info->iic_delay);
if (0 == iic_tx_byte(imuSensor_info->iic_hdl, register_address)) {
r_printf("\n imuSensor iic r err 1\n");
read_len = 0;
goto __rend;
}
iic_start(imuSensor_info->iic_hdl);
if (0 == iic_tx_byte(imuSensor_info->iic_hdl, r_chip_id)) {
r_printf("\n imuSensor iic r err 2\n");
read_len = 0;
goto __rend;
}
delay(imuSensor_info->iic_delay);
for (; data_len > 1; data_len--) {
*buf++ = iic_rx_byte(imuSensor_info->iic_hdl, 1);
read_len ++;
}
*buf = iic_rx_byte(imuSensor_info->iic_hdl, 0);
read_len ++;
__rend:
iic_stop(imuSensor_info->iic_hdl);
delay(imuSensor_info->iic_delay);
return read_len;
}
#endif/*}}}*/
extern char *strchrnul(const char *__s, int __c)
__THROW __attribute_pure__ __nonnull((1));
int imu_sensor_io_ctl(u8 *sensor_name, enum OPERATION_SENSOR cmd, void *arg)
{
int retval = -1;
list_for_each_imusensor(imuSensor_hdl) {
/* log_info("%s?=%s", sensor_name, imuSensor_hdl->logo); */
if ((sensor_name == NULL) && (cmd == IMU_GET_SENSOR_NAME)) {
log_info("get name:%s", imuSensor_hdl->logo);
retval = 1;
continue;
}
if (!memcmp(imuSensor_hdl->logo, sensor_name, strlen(imuSensor_hdl->logo))) {
/* if (!memcmp(imuSensor_hdl->logo, sensor_name, sizeof(imuSensor_hdl->logo))) { */
if ((strchrnul(sensor_name, '\0') - (u32)sensor_name) != (strrchr(imuSensor_hdl->logo, '\0') - (u32)(imuSensor_hdl->logo))) {
goto __imu_exit;
}
retval = imuSensor_hdl->imu_sensor_ctl(cmd, arg);
return retval;//1:ok
}
}
__imu_exit:
if (retval < 0) {
log_e(">>>sensor_name(%s) io_ctl fail: sensor_name err\n", sensor_name);
}
return retval;//1:ok
}
int imu_sensor_init(void *_data, u16 _data_size)
{
int retval = -1;
u8 data_len = _data_size / sizeof(struct imusensor_platform_data);
if (data_len < 1) {
log_error("_data_size:%d\n", _data_size);
return retval;
}
platform_data = (const struct imusensor_platform_data *)_data;
/* log_info("-----imusensor_dev_begin:0x%x,imusensor_dev_end:0x%x", imusensor_dev_begin, imusensor_dev_end); */
for (u8 i = 0; i < data_len; i++) {
retval = -1;
list_for_each_imusensor(imuSensor_hdl) {
/* log_info("%s?=%s", platform_data[i].imu_sensor_name, imuSensor_hdl->logo); */
if (!memcmp(imuSensor_hdl->logo, platform_data[i].imu_sensor_name, sizeof(platform_data[i].imu_sensor_name))) {
retval = -1;
if (imuSensor_hdl->imu_sensor_init(&platform_data[i]) == 0) {
g_printf(">>>>imuSensor(%s)_Init SUCC\n", platform_data[i].imu_sensor_name);
imu_sensor_cnt++;
retval = 1;
} else {
g_printf(">>>>imuSensor(%s)_Init ERROR\n", platform_data[i].imu_sensor_name);
retval = 0;
}
break;
}
}
if (retval < 0) {
log_e(">>>imuSensor(%s) init fail: logo err\n", platform_data[i].imu_sensor_name);
}
}
return retval;//1:ok
}
/**********************test***********************/
#if 0
u8 test_buf[36 * 20]; //(8+12+12+4)*60=
void imu_test()
{
u8 name_test[20] = "sh3011";
u8 arg_data;
/* imu_sensor_init(); */
imu_sensor_io_ctl(name_test, 0xff, NULL);
imu_sensor_io_ctl(NULL, IMU_GET_SENSOR_NAME, name_test);
memset(name_test, 0, 20);
memcpy(name_test, "sh3001", 6);
imu_sensor_io_ctl(name_test, 0xff, NULL);
imu_sensor_io_ctl(name_test, IMU_SENSOR_SEARCH, &arg_data);
memset(name_test, 0, 20);
memcpy(name_test, "mpu9250", 7);
imu_sensor_io_ctl(name_test, 0xff, NULL);
imu_sensor_io_ctl(name_test, IMU_SENSOR_SEARCH, &arg_data);
memset(name_test, 0, 20);
memcpy(name_test, "mpu6887p", 8);
imu_sensor_io_ctl(name_test, 0xff, NULL);
imu_sensor_io_ctl(name_test, IMU_SENSOR_SEARCH, &arg_data);
imu_sensor_io_ctl("mpu6887p1", IMU_SENSOR_SEARCH, &arg_data);
memset(name_test, 0, 20);
memcpy(name_test, "qmi8658", 7);
imu_sensor_io_ctl(name_test, 0xff, NULL);
imu_sensor_io_ctl(name_test, IMU_SENSOR_SEARCH, &arg_data);
memset(name_test, 0, 20);
memcpy(name_test, "lsm6dsl", 7);
imu_sensor_io_ctl(name_test, IMU_SENSOR_SEARCH, &arg_data);
memcpy(name_test, "icm42670p", 9);
imu_sensor_io_ctl(name_test, 0xff, NULL);
imu_sensor_io_ctl(name_test, IMU_SENSOR_SEARCH, &arg_data);
imu_axis_data_t raw_acc_xyz;
imu_axis_data_t raw_gyro_xyz;
imu_sensor_data_t raw_sensor_datas;
memset((u8 *)&raw_acc_xyz, 0, sizeof(imu_axis_data_t));
memset((u8 *)&raw_gyro_xyz, 0, sizeof(imu_axis_data_t));
memset((u8 *)&raw_sensor_datas, 0, sizeof(imu_sensor_data_t));
uint64_t timestamp;
float accel_g[3];
float gyro_dps[3];
float temp_degc;
int pack_len = 0;
while (1) {
pack_len = imu_sensor_io_ctl(name_test, IMU_GET_SENSOR_READ_FIFO, test_buf);
if (pack_len > 0) {
memcpy((u8 *)&timestamp, test_buf, 8);
memcpy((u8 *)accel_g, test_buf + 8, 12);
memcpy((u8 *)gyro_dps, test_buf + 20, 12);
memcpy((u8 *)&temp_degc, test_buf + 32, 4);
log_info("pack_len:%d first pack:%u: accel_g*10:%d, %d, %d, temp_degc*10:%d, gyro_dps*10:%d, %d, %d", pack_len,
(uint32_t)timestamp,
(s32)(accel_g[0] * 10), (s32)(accel_g[1] * 10), (s32)(accel_g[2] * 10),
(s32)(temp_degc * 10),
(s32)(gyro_dps[0] * 10), (s32)(gyro_dps[1] * 10), (s32)(gyro_dps[2] * 10));
}
/* imu_sensor_io_ctl(name_test, IMU_SENSOR_READ_DATA, &raw_sensor_datas); */
/* 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); */
/* log_info("qmi8658 temp:%d.%d\n", (u16)raw_sensor_datas.temp_data, (u16)(((u16)(raw_sensor_datas.temp_data * 100)) % 100)); */
/* mdelay(10); */
/* imu_sensor_io_ctl(name_test, IMU_GET_ACCEL_DATA, &raw_acc_xyz); */
/* log_info("qmi8658 acc: %d %d %d\n", raw_acc_xyz.x, raw_acc_xyz.y, raw_acc_xyz.z); */
/* mdelay(10); */
/* imu_sensor_io_ctl(name_test, IMU_GET_GYRO_DATA, &raw_gyro_xyz); */
/* log_info("qmi8658 gyro: %d %d %d\n", raw_gyro_xyz.x, raw_gyro_xyz.y, raw_gyro_xyz.z); */
mdelay(50);
wdt_clear();
}
}
#endif
#endif

View File

@ -0,0 +1,82 @@
#ifndef _IMUSENSOR_MANAGE_H
#define _IMUSENSOR_MANAGE_H
#include "app_config.h"
#include "system/includes.h"
#if TCFG_IMUSENSOR_ENABLE
enum OPERATION_SENSOR {
IMU_SENSOR_SEARCH = 0,//检查传感器id
IMU_GET_SENSOR_NAME,//
IMU_SENSOR_ENABLE,
IMU_SENSOR_DISABLE,
IMU_SENSOR_RESET,
IMU_SENSOR_SLEEP,
IMU_SENSOR_WAKEUP,
IMU_SENSOR_INT_DET,//传感器中断状态检查
IMU_SENSOR_DATA_READY,//传感器数据准备就绪待读
IMU_SENSOR_READ_DATA,//默认读传感器所有数据
IMU_GET_ACCEL_DATA,//加速度数据
IMU_GET_GYRO_DATA,//陀螺仪数据
IMU_GET_MAG_DATA,//磁力计数据
IMU_SENSOR_CHECK_DATA,//检查传感器缓存buf是否存满
IMU_GET_SENSOR_STATUS,//获取传感器状态
IMU_SET_SENSOR_FIFO_CONFIG,//配置传感器FIFO
IMU_GET_SENSOR_READ_FIFO,//读取传感器FIFO数据
IMU_SET_SENSOR_TEMP_DISABLE,//是否关闭温度传感器
};
typedef struct {
char logo[20];
s8(*imu_sensor_init)(void *arg);
char (*imu_sensor_check)(void);
int (*imu_sensor_ctl)(u8 cmd, void *arg);
} IMU_SENSOR_INTERFACE;
typedef struct {
u8 iic_hdl;
u8 iic_delay; //这个延时并非影响iic的时钟频率而是2Byte数据之间的延时
int init_flag;
} IMU_SENSOR_INFO;
struct imusensor_platform_data {
u8 peripheral_hdl; //iic_hdl or spi_hdl
u8 peripheral_param0; //iic_delay(iic byte间间隔) or spi_cs_pin
u8 peripheral_param1; //spi_mode
char imu_sensor_name[20];
int imu_sensor_int_io;
};
typedef struct {
short x;
short y;
short z;
} imu_axis_data_t;
typedef struct {
imu_axis_data_t acc;
imu_axis_data_t gyro;
float temp_data;
} imu_sensor_data_t;
// u8 imusensor_write_nbyte(u8 w_chip_id, u8 register_address, u8 *buf, u8 data_len);
// u8 imusensor_read_nbyte(u8 r_chip_id, u8 register_address, u8 *buf, u8 data_len);
int imu_sensor_io_ctl(u8 *sensor_name, enum OPERATION_SENSOR cmd, void *arg);
int imu_sensor_init(void *_data, u16 _data_size);
extern IMU_SENSOR_INTERFACE imusensor_dev_begin[];
extern IMU_SENSOR_INTERFACE imusensor_dev_end[];
#define REGISTER_IMU_SENSOR(imuSensor) \
static IMU_SENSOR_INTERFACE imuSensor SEC_USED(.imusensor_dev)
#define list_for_each_imusensor(c) \
for (c=imusensor_dev_begin; c<imusensor_dev_end; c++)
#define IMU_SENSOR_PLATFORM_DATA_BEGIN(imu_sensor_data) \
static const struct imusensor_platform_data imu_sensor_data[] = {
#define IMU_SENSOR_PLATFORM_DATA_END() \
};
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,233 @@
#ifndef __MPU6887P_H_
#define __MPU6887P_H_
#include <string.h>
/******************************************************************
a 6-axis MotionTracking device:
a 3-axis gyroscope(±250, ±500, ±1000, and ±2000 degrees/sec.)(16-bit ADCs),
a 3-axis accelerometer(±2g, ±4g, ±8g, and ±16g)(16-bit ADCs)
VDD/VDDIO: 1.71~3.45V
FIFO:512-byte. burst read sensor data and then go into a low-power mode.
fifo_data:out_data_reg 59~72
Host (slave) interface supports I2C(400kHz), and 4-wire SPI(8MHz);
no iic master,9 axes are not supported
@The device will come up in sleep mode upon power-up
******************************************************************/
#if TCFG_MPU6887P_ENABLE
/******************************************************************
* user config MPU6887P Macro Definition
******************************************************************/
#define MPU6887P_USE_I2C 0 /*IIC.(<=400kHz) */
#define MPU6887P_USE_SPI 1 /*SPI.(<=8MHz) */
#define MPU6887P_USER_INTERFACE TCFG_MPU6887P_INTERFACE_TYPE//MPU6887P_USE_I2C
// #define MPU6887P_USER_INTERFACE MPU6887P_USE_SPI
#define MPU6887P_SA0_IIC_ADDR 0 //1:iic模式SA0接VCC, 0:iic模式SA0接GND
#define MPU6887P_6_Axis_LOW_POWER_MODE 0 //1:6_Axis_LOW_POWER_MODE(1.33ma); 0:6_Axis Low-Noise Mode(2.79ma)
//int io config
// #define MPU6887P_INT_IO1 IO_PORTB_03//TCFG_IOKEY_POWER_ONE_PORT //
// #define MPU6887P_INT_IO1 IO_PORTA_06 //
// #define MPU6887P_INT_READ_IO1() gpio_read(MPU6887P_INT_IO1)
#define MPU6887P_USE_FIFO_EN 1 //0:disable fifo 1:enable fifo(fifo size:512 bytes)
#define MPU6887P_USE_INT_EN 0 //0:disable //中断方式不成功,疑硬件问题
#define MPU6887P_USE_WOM_EN 0 //0:disable
#define MPU6887P_USE_FSYNC_EN 0 //0:disable
/******************************************************************
* MPU6887P I2C address Macro Definition
* (7bit): (0x37)011 0111@SDO=1; (0x36)011 0110@SDO=0;
******************************************************************/
#if MPU6887P_SA0_IIC_ADDR
#define MPU6887P_SLAVE_ADDRESS (0x69<<1)//0XD0
#else
#define MPU6887P_SLAVE_ADDRESS (0x68<<1)//0XD2
#endif
typedef u16(*IMU_read)(unsigned char devAddr,
unsigned char regAddr,
unsigned char *readBuf,
u16 readLen);
typedef u16(*IMU_write)(unsigned char devAddr,
unsigned char regAddr,
unsigned char *writeBuf,
u16 writeLen);
typedef struct {
// u8 comms; //0:IIC; 1:SPI //改为宏控制
#if (MPU6887P_USER_INTERFACE==MPU6887P_USE_I2C)
u8 iic_hdl;
u8 iic_delay; //这个延时并非影响iic的时钟频率而是2Byte数据之间的延时
// u8 iic_clk; //iic_clk: <=400kHz
#elif (MPU6887P_USER_INTERFACE==MPU6887P_USE_SPI)
u8 spi_hdl; //SPIx (role:master)
u8 spi_cs_pin; //
//u8 spi_work_mode;//mpu6887p only suspport 4wire(SPI_MODE_BIDIR_1BIT) (与spi结构体一样)
// u8 port; //SPIx group:A,B,C,D (spi结构体)
// U8 spi_clk; //spi_clk: <=8MHz (spi结构体)
#endif
} mpu6887p_param;
/******************************************************************
* Mpu6887p Registers Macro Definitions
******************************************************************/
enum Mpu6887pRegister {
Mpu6887pRegister_XG_OFFS_TC_H = 4, //4
Mpu6887pRegister_XG_OFFS_TC_L, //5
Mpu6887pRegister_YG_OFFS_TC_H = 7, //7
Mpu6887pRegister_YG_OFFS_TC_L, //8
Mpu6887pRegister_ZG_OFFS_TC_H = 10, //10
Mpu6887pRegister_ZG_OFFS_TC_L, //11
Mpu6887pRegister_SELF_TEST_X_ACCEL = 13, //13
Mpu6887pRegister_SELF_TEST_Y_ACCEL, //14
Mpu6887pRegister_SELF_TEST_Z_ACCEL, //15
Mpu6887pRegister_XG_OFFS_USRH = 19, //19
Mpu6887pRegister_XG_OFFS_USRL, //20
Mpu6887pRegister_YG_OFFS_USRH, //21
Mpu6887pRegister_YG_OFFS_USRL, //22
Mpu6887pRegister_ZG_OFFS_USRH, //23
Mpu6887pRegister_ZG_OFFS_USRL, //24
Mpu6887pRegister_SMPLRT_DIV, //25
Mpu6887pRegister_CONFIG, //26 ////
Mpu6887pRegister_GYRO_CONFIG, //27
Mpu6887pRegister_ACCEL_CONFIG, //28
Mpu6887pRegister_ACCEL_CONFIG_2, //29
Mpu6887pRegister_LP_MODE_CFG, //30
Mpu6887pRegister_ACCEL_WOM_X_THR = 32, //32
Mpu6887pRegister_ACCEL_WOM_Y_THR, //33
Mpu6887pRegister_ACCEL_WOM_Z_THR, //34
Mpu6887pRegister_FIFO_EN, //35
Mpu6887pRegister_FSYNC_INT = 54, //54
Mpu6887pRegister_INT_PIN_CFG, //55
Mpu6887pRegister_INT_ENABLE, //56
Mpu6887pRegister_FIFO_WM_INT_STATUS,//57
Mpu6887pRegister_INT_STATUS, //58
Mpu6887pRegister_ACCEL_XOUT_H, //59
Mpu6887pRegister_ACCEL_XOUT_L, //60
Mpu6887pRegister_ACCEL_YOUT_H, //61
Mpu6887pRegister_ACCEL_YOUT_L, //62
Mpu6887pRegister_ACCEL_ZOUT_H, //63
Mpu6887pRegister_ACCEL_ZOUT_L, //64
Mpu6887pRegister_TEMP_OUT_H, //65
Mpu6887pRegister_TEMP_OUT_L, //66
Mpu6887pRegister_GYRO_XOUT_H, //67
Mpu6887pRegister_GYRO_XOUT_L, //68
Mpu6887pRegister_GYRO_YOUT_H, //69
Mpu6887pRegister_GYRO_YOUT_L, //70
Mpu6887pRegister_GYRO_ZOUT_H, //71
Mpu6887pRegister_GYRO_ZOUT_L, //72
Mpu6887pRegister_SELF_TEST_X_GYRO = 80, //80
Mpu6887pRegister_SELF_TEST_Y_GYRO, //81
Mpu6887pRegister_SELF_TEST_Z_GYRO, //82
Mpu6887pRegister_E_ID0, //83
Mpu6887pRegister_E_ID1, //84
Mpu6887pRegister_E_ID2, //85
Mpu6887pRegister_E_ID3, //86
Mpu6887pRegister_E_ID4, //87
Mpu6887pRegister_E_ID5, //88
Mpu6887pRegister_E_ID6, //89
Mpu6887pRegister_FIFO_WM_TH1 = 96, //96
Mpu6887pRegister_FIFO_WM_TH2, //97
Mpu6887pRegister_SIGNAL_PATH_RESET = 104, //104
Mpu6887pRegister_ACCEL_INTEL_CTRL, //105
Mpu6887pRegister_USER_CTRL, //106
Mpu6887pRegister_PWR_MGMT_1, //107 ////
Mpu6887pRegister_PWR_MGMT_2, //108
Mpu6887pRegister_I2C_IF = 112, //112
Mpu6887pRegister_FIFO_COUNTH = 114, //114
Mpu6887pRegister_FIFO_COUNTL, //115
Mpu6887pRegister_FIFO_R_W, //116
Mpu6887pRegister_WHO_AM_I, //117 ////
Mpu6887pRegister_XA_OFFSET_H = 119, //119
Mpu6887pRegister_XA_OFFSET_L, //120
Mpu6887pRegister_YA_OFFSET_H = 122, //122
Mpu6887pRegister_YA_OFFSET_L, //123
Mpu6887pRegister_ZA_OFFSET_H = 125, //125
Mpu6887pRegister_ZA_OFFSET_L, //126
};
// #ifndef M_PI
// #define M_PI (3.14159265358979323846f)
// #endif
// #ifndef ONE_G
// #define ONE_G (9.807f)
// #endif
typedef enum Mpu6887p_fifo_format {
MPU6887P_FORMAT_EMPTY,
MPU6887P_FORMAT_ACCEL_8_BYTES,
MPU6887P_FORMAT_GYRO_8_BYTES,
MPU6887P_FORMAT_ACCEL_GYRO_14_BYTES,
MPU6887P_FORMAT_UNKNOWN = 0xff,
} Mpu6887p_fifo_format;
/***************************************************************************
Exported Functions
****************************************************************************/
void mpu6887p_delay(int ms);
void mpu6887p_interface_mode_set(u8 spi_en);//1:spi(4wire) ,0:iic
void mpu6887p_accel_temp_rst(u8 accel_rst_en, u8 temp_rst_en);//1:rst ,0:dis
void mpu6887p_all_reg_rst(u8 all_reg_rst_en);//1:rst ,0:dis
void mpu6887p_device_reset();
bool mpu6887p_set_sleep_enabled(u8 enable);// 0:唤醒MPU, 1:disable
void mpu6887p_power_up_set();
// void mpu6887p_clock_select(enum mpu_clock_select clock);
void mpu6887p_disable_temp_Sensor(unsigned char temp_disable);//1:temperature disable, 0:temperature enable
void mpu6887p_disable_acc_Sensors(u8 acc_x_disable, u8 acc_y_disable, u8 acc_z_disable);//1:disable , 0:enable
void mpu6887p_disable_gyro_Sensors(u8 gyro_x_disable, u8 gyro_y_disable, u8 gyro_z_disable);//1:disable , 0:enable
u8 mpu6887p_config_acc_range(u8 fsr);//fsr:0,±2g;1,±4g;2,±8g;3,±16g
u8 mpu6887p_set_accel_dlpf(u16 lpf);//Low-Noise Mode
// u8 mpu6887p_set_accel_low_power(u8 averag);//Low Power Mode
u8 mpu6887p_config_gyro_range(u8 fsr);//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
u8 mpu_set_dlpf(u16 lpf);//Low-Noise Mode
// u8 mpu6887p_set_gyro_low_power(u8 gyro_cycle_en,u8 averag);//Low Power Mode
u8 mpu_set_rate(u16 rate);// 设置采样速率.
unsigned char mpu6887p_read_status(void);
unsigned char mpu6887p_read_fsync_status(void);
float mpu6887p_readTemp(void);
// void mpu6887p_read_raw_acc_xyz(short raw_acc_xyz[3]);
// void mpu6887p_read_raw_gyro_xyz(short raw_gyro_xyz[3]);
// void mpu6887p_read_raw_acc_gyro_xyz(short raw_acc_xyz[3], short raw_gyro_xyz[3]);
void mpu6887p_read_raw_acc_xyz(void *acc_data);
void mpu6887p_read_raw_gyro_xyz(void *gyro_data);
void mpu6887p_read_raw_acc_gyro_xyz(void *raw_data);
#if (MPU6887P_USE_FIFO_EN)
// void mpu6887p_fifo_rst(u8 fifo_rst_en);//1:rst ,0:dis
// void mpu6887p_fifo_operation_enable(u8 fifo_en);//1:enable fifo ,0:dis
// u8 mpu6887p_set_fifo_data_type(u8 acc_fifo_en, u8 gyro_fifo_en);//1:write data to fifo;0:disable.
// u8 mpu6887p_set_fifo_mode(u8 fifo_mode_en);//1:fifo mode ; 0:stream mode.
// unsigned char mpu6887p_set_fifo_wm_threshold(u16 watermark_level);//watermark_level:0~1023
void mpu6887p_config_fifo(u16 watermark_level, u8 fifo_mode, u8 acc_fifo_en, u8 gyro_fifo_en);
u16 mpu6887p_read_fifo_data(u8 *buf);
unsigned char mpu6887p_read_fifo_wm_int_status(void);//读FIFO_R_W register清除.如果FIFO没读完,又达到fifo_wm,还会产生中断.
#endif
#if (MPU6887P_USE_INT_EN)
u8 mpu6887p_interrupt_type_config(u8 fifo_oflow_int_en, u8 Gdrive_int_en, u8 data_RDY_int_en); //int_type_en:1-enable; 0-disable
u8 mpu6887p_interrupt_pin_config(u8 int_pin_level, u8 int_pin_open, u8 int_pin_latch_en, u8 int_pin_clear_mode);
u8 mpu6887p_interrupt_fsync_pin_config(u8 fsync_int_level, u8 fsync_int_mode_en);
#endif
#if (MPU6887P_USE_WOM_EN)
// u8 mpu6887p_interrupt_WOM_type_config(u8 WOM_x_int_en, u8 WOM_y_int_en,u8 WOM_z_int_en);//int_type_en:1-enable; 0-disable
// u8 mpu6887p_set_WOM_int_threshold(u8 acc_wom_x_thr, u8 acc_wom_y_thr, u8 acc_wom_z_thr);//
u8 mpu6887p_WOM_mode_config(u8 acc_wom_x_thr, u8 acc_wom_y_thr, u8 acc_wom_z_thr, u16 sample_rate);//
#endif
u8 mpu6887p_sensor_init(void *priv);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,182 @@
#ifndef _MPU9250_H_
#define _MPU9250_H_
#if TCFG_TP_MPU9250_ENABLE
#define SENSORS_MPU6500_BUFF_LEN 14
#define SENSORS_MAG_BUFF_LEN 8
#define MPU9250_ADDR 0X68 //器件IIC地址(AD0:GND, AD0:VCC(0X69))
#define MPU9250_ADDRESS_W 0xD0 //陀螺地址(AD0:GND, AD0:VCC(0XD2))
#define MPU_DEVICE_ID_REG 0X75 //器件ID寄存器
#define MAG_AK8963_ENABLE 1 //AK8963磁场 enable
#define MAG_IIC_ADDRESS 0x0c //AK8963磁场从机地址(旁路直连)
#define MAG_IIC_ADDRESS_W (MAG_IIC_ADDRESS<<1) //AK8963磁场从机地址(旁路直连)
#define MAG_WHO_AM_I 0x00//IIC地址寄存器(默认数值0x48只读)
// 定义MPU9250内部地址
//****************************************
#define MPU_SELF_TESTX_REG 0X0D //自检寄存器X
#define MPU_SELF_TESTY_REG 0X0E //自检寄存器Y
#define MPU_SELF_TESTZ_REG 0X0F //自检寄存器Z
#define MPU_SELF_TESTA_REG 0X10 //自检寄存器A
#define MPU_SAMPLE_RATE_REG 0X19 //陀螺仪采样频率分频器典型值0x07(125Hz)
#define MPU_CFG_REG 0X1A //低通滤波频率典型值0x06(5Hz)
#define MPU_GYRO_CFG_REG 0X1B //陀螺仪自检及测量范围典型值0x18(不自检2000deg/s)
#define MPU_ACCEL_CFG_REG 0X1C //加速计自检、测量范围及高通滤波频率典型值0x01(不自检2G5Hz)
#define MPU_ACCEL_CFG_REG_2 0X1D //accel DLPF config
#define MPU_MOTION_DET_REG 0X1F //运动检测阀值设置寄存器
#define MPU_FIFO_EN_REG 0X23 //FIFO使能寄存器
#define MPU_I2CMST_CTRL_REG 0X24 //IIC主机控制寄存器
#define MPU_I2CSLV0_ADDR_REG 0X25 //IIC从机0器件地址寄存器
#define MPU_I2CSLV0_REG 0X26 //IIC从机0数据地址寄存器
#define MPU_I2CSLV0_CTRL_REG 0X27 //IIC从机0控制寄存器
#define MPU_I2CSLV1_ADDR_REG 0X28 //IIC从机1器件地址寄存器
#define MPU_I2CSLV1_REG 0X29 //IIC从机1数据地址寄存器
#define MPU_I2CSLV1_CTRL_REG 0X2A //IIC从机1控制寄存器
#define MPU_I2CSLV2_ADDR_REG 0X2B //IIC从机2器件地址寄存器
#define MPU_I2CSLV2_REG 0X2C //IIC从机2数据地址寄存器
#define MPU_I2CSLV2_CTRL_REG 0X2D //IIC从机2控制寄存器
#define MPU_I2CSLV3_ADDR_REG 0X2E //IIC从机3器件地址寄存器
#define MPU_I2CSLV3_REG 0X2F //IIC从机3数据地址寄存器
#define MPU_I2CSLV3_CTRL_REG 0X30 //IIC从机3控制寄存器
#define MPU_I2CSLV4_ADDR_REG 0X31 //IIC从机4器件地址寄存器
#define MPU_I2CSLV4_REG 0X32 //IIC从机4数据地址寄存器
#define MPU_I2CSLV4_DO_REG 0X33 //IIC从机4写数据寄存器
#define MPU_I2CSLV4_CTRL_REG 0X34 //IIC从机4控制寄存器
#define MPU_I2CSLV4_DI_REG 0X35 //IIC从机4读数据寄存器
#define MPU_I2CMST_STA_REG 0X36 //IIC主机状态寄存器
#define MPU_INTBP_CFG_REG 0X37 //中断/旁路设置寄存器
#define MPU_INT_EN_REG 0X38 //中断使能寄存器
#define MPU_INT_STA_REG 0X3A //中断状态寄存器
#define MPU_ACCEL_XOUTH_REG 0X3B //加速度值,X轴高8位寄存器
#define MPU_ACCEL_XOUTL_REG 0X3C //加速度值,X轴低8位寄存器
#define MPU_ACCEL_YOUTH_REG 0X3D //加速度值,Y轴高8位寄存器
#define MPU_ACCEL_YOUTL_REG 0X3E //加速度值,Y轴低8位寄存器
#define MPU_ACCEL_ZOUTH_REG 0X3F //加速度值,Z轴高8位寄存器
#define MPU_ACCEL_ZOUTL_REG 0X40 //加速度值,Z轴低8位寄存器
#define MPU_TEMP_OUTH_REG 0X41 //温度值高八位寄存器
#define MPU_TEMP_OUTL_REG 0X42 //温度值低8位寄存器
#define MPU_GYRO_XOUTH_REG 0X43 //陀螺仪值,X轴高8位寄存器
#define MPU_GYRO_XOUTL_REG 0X44 //陀螺仪值,X轴低8位寄存器
#define MPU_GYRO_YOUTH_REG 0X45 //陀螺仪值,Y轴高8位寄存器
#define MPU_GYRO_YOUTL_REG 0X46 //陀螺仪值,Y轴低8位寄存器
#define MPU_GYRO_ZOUTH_REG 0X47 //陀螺仪值,Z轴高8位寄存器
#define MPU_GYRO_ZOUTL_REG 0X48 //陀螺仪值,Z轴低8位寄存器
#define MPU_I2CSLV0_DO_REG 0X63 //IIC从机0数据寄存器
#define MPU_I2CSLV1_DO_REG 0X64 //IIC从机1数据寄存器
#define MPU_I2CSLV2_DO_REG 0X65 //IIC从机2数据寄存器
#define MPU_I2CSLV3_DO_REG 0X66 //IIC从机3数据寄存器
#define MPU_I2CMST_DELAY_REG 0X67 //IIC主机延时管理寄存器
#define MPU_SIGPATH_RST_REG 0X68 //信号通道复位寄存器
#define MPU_MDETECT_CTRL_REG 0X69 //运动检测控制寄存器
#define MPU_USER_CTRL_REG 0X6A //用户控制寄存器
#define MPU_PWR_MGMT1_REG 0X6B //电源管理寄存器1典型值0x00(正常启用)
#define MPU_PWR_MGMT2_REG 0X6C //电源管理寄存器2
#define MPU_FIFO_CNTH_REG 0X72 //FIFO计数寄存器高八位
#define MPU_FIFO_CNTL_REG 0X73 //FIFO计数寄存器低八位
#define MPU_FIFO_RW_REG 0X74 //FIFO读写寄存器
#define MPU6500_CLOCK_INTERNAL 0x00
#define MPU6500_CLOCK_PLL_XGYRO 0x01
#define MPU6500_CLOCK_PLL_YGYRO 0x02
#define MPU6500_CLOCK_PLL_ZGYRO 0x03
#define MPU6500_CLOCK_PLL_EXT32K 0x04
#define MPU6500_CLOCK_PLL_EXT19M 0x05
#define MPU6500_CLOCK_KEEP_RESET 0x07
#define MPU6500_GYRO_FS_250 0x00
#define MPU6500_GYRO_FS_500 0x01
#define MPU6500_GYRO_FS_1000 0x02
#define MPU6500_GYRO_FS_2000 0x03
#define MPU6500_ACCEL_FS_2 0x00
#define MPU6500_ACCEL_FS_4 0x01
#define MPU6500_ACCEL_FS_8 0x02
#define MPU6500_ACCEL_FS_16 0x03
#define MPU6500_ACCEL_DLPF_BW_460 0x00
#define MPU6500_ACCEL_DLPF_BW_184 0x01
#define MPU6500_ACCEL_DLPF_BW_92 0x02
#define MPU6500_ACCEL_DLPF_BW_41 0x03
#define MPU6500_ACCEL_DLPF_BW_20 0x04
#define MPU6500_ACCEL_DLPF_BW_10 0x05
#define MPU6500_ACCEL_DLPF_BW_5 0x06
#define MPU6500_DLPF_BW_256 0x00
#define MPU6500_DLPF_BW_188 0x01
#define MPU6500_DLPF_BW_98 0x02
#define MPU6500_DLPF_BW_42 0x03
#define MPU6500_DLPF_BW_20 0x04
#define MPU6500_DLPF_BW_10 0x05
#define MPU6500_DLPF_BW_5 0x06
#define MPU6500_DATA_SAMPLE_RATE 100 //HZ
/******************mag ak8963 reg*********************/
// #define MAG_IIC_ADDRESS 0x0c //AK8963磁场从机地址(旁路直连)
// #define MAG_WHO_AM_I 0x00//IIC地址寄存器(默认数值0x48只读)
#define MAG_CNTL_1 0x0A
#define MAG_CNTL_2 0x0B
#define MAG_STATE_1 0x02
#define MAG_XOUT_L 0x03
#define MAG_XOUT_H 0x04
#define MAG_YOUT_L 0x05
#define MAG_YOUT_H 0x06
#define MAG_ZOUT_L 0x07
#define MAG_ZOUT_H 0x08
#define MAG_STATE_2 0x09
#define AK8963_MODE_POWERDOWN 0x00
#define AK8963_MODE_SINGLE 0x01
#define AK8963_MODE_CONT1 0x02
#define AK8963_MODE_CONT2 0x06
#define AK8963_MODE_EXTTRIG 0x04
#define AK8963_MODE_SELFTEST 0x08
#define AK8963_MODE_FUSEROM 0x0F
#define AK8963_MODE_14BIT 0x00
#define AK8963_MODE_16BIT 0x10
// enum power_mode {
// POWER_ACTIVE_MODE=0,
// POWER_MONITOR_MODE=1,
// POWER_HIBERNATE_MODE=3,//100ua.quit:need ft6336 reset
// };
typedef struct {
u8 comms; //0:IIC; 1:SPI
u8 iic_hdl;
u8 iic_delay; //这个延时并非影响iic的时钟频率而是2Byte数据之间的延时
} mpu9250_param;
typedef struct {
s16 x_data;
s16 y_data;
s16 z_data;
} axis_data;
typedef struct {
axis_data mag_data;
axis_data accel_data;
axis_data gyro_data;
float temp_data;
} mpu9250_data;
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,561 @@
#ifndef __QMI8658C_H_
#define __QMI8658C_H_
#include <string.h>
/******************************************************************
a complete 6D MEMS.
The QMI8658C provides an I2C master interface (I2CM)to connect with an external magnetometer.
Currently the QMI8658C can support the following magnetometers:
AK09915C, AK09918CZ, and QMC6308.
Host (slave) interface supports MIPI™ I3C, I2C, and
3-wire or 4-wire SPI; auxiliary master I2C interface
supports an external magnetometer
******************************************************************/
#if TCFG_QMI8658_ENABLE
/******************************************************************
* user config QMI8658 Macro Definition
******************************************************************/
// spi模式切换到iic模式, 传感器可能需要重新上电
#define QMI8658_USE_I2C 0 /*IIC.(<=400kHz) */
#define QMI8658_USE_SPI 1 /*SPI.(<=15MHz) */
#define QMI8658_USE_I3C 2 /*I3C. */
#define QMI8658_USER_INTERFACE TCFG_QMI8658_INTERFACE_TYPE//QMI8658_USE_I2C
// #define QMI8658_USER_INTERFACE QMI8658_USE_SPI
#define QMI8658_SD0_IIC_ADDR 1 //1:iic模式SD0接VCC, 0:iic模式SD0接GND
//int io config
// #define QMI8658_INT_IO1 IO_PORTA_06 //高有效 1.CTRL9_protocol 2.WoM
// #define QMI8658_INT_READ_IO1() gpio_read(QMI8658_INT_IO1)
// #define QMI8658_INT_IO2 IO_PORTA_07 //高有效 1.data ready 2.fifo 3.test 4.AE_mode 5.WoM
// #define QMI8658_INT_READ_IO2() gpio_read(QMI8658_INT_IO2)
// 注意: fifo模式切换到寄存器模式, 传感器需要重新上电,反之不需要
#define QMI8658_USE_FIFO_EN 1 //0:disable fifo 1:enable fifo(fifo size:1536 bytes)
#define QMI8658_USE_INT_EN 0 //0:disable
#define QMI8658_USE_ANYMOTION_EN 0
#define QMI8658_USE_TAP_EN 0
#define QMI8658_USE_STEP_EN 0
#define QMI8658_UINT_MG_DPS 0
#define QMI8658_SYNC_SAMPLE_MODE 0//寄存器中断模式0:disable sync sample, 1:enable
#define QMI8658_HANDSHAKE_NEW
#define QMI8658_HANDSHAKE_TO_STATUS
#define QMI8658_NEW_HANDSHAKE 1//另一种qmi8658
#if (QMI8658_NEW_HANDSHAKE == 1)
#define QMI8658_FIFO_INT_OMAP_INT1 1//1:fifo中断映射到int1; 0:fifo中断映射到int2
#endif
/******************************************************************
* QMI8658 I2C address Macro Definition
* (7bit): (0x37)011 0111@SDO=1; (0x36)011 0110@SDO=0;
******************************************************************/
#if QMI8658_SD0_IIC_ADDR
#define QMI8658_SLAVE_ADDRESS (0x6a<<1)//0xd4
#else
#define QMI8658_SLAVE_ADDRESS (0x6b<<1)//0xd6
#endif
typedef u16(*IMU_read)(unsigned char devAddr,
unsigned char regAddr,
unsigned char *readBuf,
u16 readLen);
typedef unsigned char (*IMU_write)(unsigned char devAddr,
unsigned char regAddr,
unsigned char writebyte);
// typedef unsigned char (*IMU_write)( unsigned char devAddr,
// unsigned char regAddr,
// unsigned char *writeBuf,
// unsigned char writeLen);
typedef struct {
// u8 comms; //0:IIC; 1:SPI //宏控制
#if (QMI8658_USER_INTERFACE==QMI8658_USE_I2C)
u8 iic_hdl;
u8 iic_delay; //这个延时并非影响iic的时钟频率而是2Byte数据之间的延时
// u8 iic_clk; //iic_clk: <=400kHz
#elif (QMI8658_USER_INTERFACE==QMI8658_USE_SPI)
u8 spi_hdl; //SPIx (role:master)
u8 spi_cs_pin; //
u8 spi_work_mode;//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_param;
/******************************************************************
* QMI8658 Registers Macro Definitions
******************************************************************/
#ifndef M_PI
#define M_PI (3.14159265358979323846f)
#endif
#ifndef ONE_G
#define ONE_G (9.807f)
#endif
#define QMI8658_CTRL7_DISABLE_ALL (0x0)
#define QMI8658_CTRL7_ACC_ENABLE (0x1)
#define QMI8658_CTRL7_GYR_ENABLE (0x2)
#define QMI8658_CTRL7_MAG_ENABLE (0x4)
#define QMI8658_CTRL7_AE_ENABLE (0x8)
#define QMI8658_CTRL7_GYR_SNOOZE_ENABLE (0x10)
#define QMI8658_CTRL7_ENABLE_MASK (0xF)
#define QMI8658_CONFIG_ACC_ENABLE QMI8658_CTRL7_ACC_ENABLE
#define QMI8658_CONFIG_GYR_ENABLE QMI8658_CTRL7_GYR_ENABLE
#define QMI8658_CONFIG_MAG_ENABLE QMI8658_CTRL7_MAG_ENABLE
#define QMI8658_CONFIG_AE_ENABLE QMI8658_CTRL7_AE_ENABLE
#define QMI8658_CONFIG_ACCGYR_ENABLE (QMI8658_CONFIG_ACC_ENABLE | QMI8658_CONFIG_GYR_ENABLE)
#define QMI8658_CONFIG_ACCGYRMAG_ENABLE (QMI8658_CONFIG_ACC_ENABLE | QMI8658_CONFIG_GYR_ENABLE | QMI8658_CONFIG_MAG_ENABLE)
#define QMI8658_CONFIG_AEMAG_ENABLE (QMI8658_CONFIG_AE_ENABLE | QMI8658_CONFIG_MAG_ENABLE)
#define QMI8658_STATUS1_CMD_DONE (0x01)
#define QMI8658_STATUS1_WAKEUP_EVENT (0x04)
#if (QMI8658_NEW_HANDSHAKE)
#define QMI8658_CTRL8_INT_SEL 0x40 // bit6: 1 int1, 0 int2
#define QMI8658_CTRL8_PEDOMETER_EN 0x10
#define QMI8658_CTRL8_SIGMOTION_EN 0x08
#define QMI8658_CTRL8_NOMOTION_EN 0x04
#define QMI8658_CTRL8_ANYMOTION_EN 0x02
#define QMI8658_CTRL8_TAP_EN 0x01
#define QMI8658_INT1_ENABLE 0x08
#define QMI8658_INT2_ENABLE 0x10
#define QMI8658_DRDY_DISABLE 0x20 // ctrl7
#define QMI8658_FIFO_MAP_INT1 0x04 // ctrl1
#define QMI8658_FIFO_MAP_INT2 ~0x04
#endif
enum Qmi8658Register {
Qmi8658Register_WhoAmI = 0, // 0
Qmi8658Register_Revision, // 1
Qmi8658Register_Ctrl1, // 2
Qmi8658Register_Ctrl2, // 3
Qmi8658Register_Ctrl3, // 4
Qmi8658Register_Ctrl4, // 5
Qmi8658Register_Ctrl5, // 6
Qmi8658Register_Ctrl6, // 7
Qmi8658Register_Ctrl7, // 8
Qmi8658Register_Ctrl8, // 9
Qmi8658Register_Ctrl9, // 10
Qmi8658Register_Cal1_L = 11,
Qmi8658Register_Cal1_H,
Qmi8658Register_Cal2_L,
Qmi8658Register_Cal2_H,
Qmi8658Register_Cal3_L,
Qmi8658Register_Cal3_H,
Qmi8658Register_Cal4_L,
Qmi8658Register_Cal4_H,
Qmi8658Register_FifoWmkTh = 19,
Qmi8658Register_FifoCtrl = 20,
Qmi8658Register_FifoCount = 21,
Qmi8658Register_FifoStatus = 22,
Qmi8658Register_FifoData = 23,
Qmi8658Register_StatusI2CM = 44,
Qmi8658Register_StatusInt = 45,
Qmi8658Register_Status0,
Qmi8658Register_Status1,
Qmi8658Register_Timestamp_L = 48,
Qmi8658Register_Timestamp_M,
Qmi8658Register_Timestamp_H,
Qmi8658Register_Tempearture_L = 51,
Qmi8658Register_Tempearture_H,
Qmi8658Register_Ax_L = 53,
Qmi8658Register_Ax_H,
Qmi8658Register_Ay_L,
Qmi8658Register_Ay_H,
Qmi8658Register_Az_L,
Qmi8658Register_Az_H,
Qmi8658Register_Gx_L = 59,
Qmi8658Register_Gx_H,
Qmi8658Register_Gy_L,
Qmi8658Register_Gy_H,
Qmi8658Register_Gz_L,
Qmi8658Register_Gz_H,
Qmi8658Register_Mx_L = 65,
Qmi8658Register_Mx_H,
Qmi8658Register_My_L,
Qmi8658Register_My_H,
Qmi8658Register_Mz_L,
Qmi8658Register_Mz_H,
Qmi8658Register_Q1_L = 73,
Qmi8658Register_Q1_H,
Qmi8658Register_Q2_L,
Qmi8658Register_Q2_H,
Qmi8658Register_Q3_L,
Qmi8658Register_Q3_H,
Qmi8658Register_Q4_L,
Qmi8658Register_Q4_H,
Qmi8658Register_Dvx_L = 81,
Qmi8658Register_Dvx_H,
Qmi8658Register_Dvy_L,
Qmi8658Register_Dvy_H,
Qmi8658Register_Dvz_L,
Qmi8658Register_Dvz_H,
Qmi8658Register_AeReg1 = 87,
Qmi8658Register_AeOverflow,
Qmi8658Register_AccEl_X = 90,
Qmi8658Register_AccEl_Y,
Qmi8658Register_AccEl_Z,
Qmi8658Register_Reset = 96, //err?????
Qmi8658Register_I2CM_STATUS = 110, //err???
};
enum Qmi8658_Ois_Register {
/*-----------------------------*/
/* Setup and Control Registers */
/*-----------------------------*/
/*! \brief SPI Endian Selection, and SPI 3/4 Wire */
Qmi8658_OIS_Reg_Ctrl1 = 0x02, // 2 [0x02] -- Dflt: 0x20
/*! \brief Accelerometer control: ODR, Full Scale, Self Test */
Qmi8658_OIS_Reg_Ctrl2, // 3 [0x03]
/*! \brief Gyroscope control: ODR, Full Scale, Self Test */
Qmi8658_OIS_Reg_Ctrl3, // 4 [0x04]
/*! \brief Sensor Data Processing Settings */
Qmi8658_OIS_Reg_Ctrl5 = 0x06, // 6 [0x06]
/*! \brief Sensor enabled status: Enable Sensors */
Qmi8658_OIS_Reg_Ctrl7 = 0x08, // 8 [0x08]
/*-------------------*/
/* Status Registers */
/*-------------------*/
/*! \brief Sensor Data Availability and Lock Register */
Qmi8658_OIS_Reg_StatusInt = 0x2D, // 45 [0x2D]
/*! \brief Output data overrun and availability */
Qmi8658_OIS_Reg_Status0 = 0x2E, // 46 [0x2E]
/*-----------------------------------------------------*/
/* OIS Sensor Data Output Registers. 16-bit 2's complement */
/*-----------------------------------------------------*/
/*! \brief Accelerometer X axis least significant byte */
Qmi8658_OIS_Reg_Ax_L = 0x33, // 53 [0x35]
/*! \brief Accelerometer X axis most significant byte */
Qmi8658_OIS_Reg_Ax_H, // 54 [0x36]
/*! \brief Accelerometer Y axis least significant byte */
Qmi8658_OIS_Reg_Ay_L, // 55 [0x37]
/*! \brief Accelerometer Y axis most significant byte */
Qmi8658_OIS_Reg_Ay_H, // 56 [0x38]
/*! \brief Accelerometer Z axis least significant byte */
Qmi8658_OIS_Reg_Az_L, // 57 [0x39]
/*! \brief Accelerometer Z axis most significant byte */
Qmi8658_OIS_Reg_Az_H, // 58 [0x3A]
/*! \brief Gyroscope X axis least significant byte */
Qmi8658_OIS_Reg_Gx_L = 0x3B, // 59 [0x3B]
/*! \brief Gyroscope X axis most significant byte */
Qmi8658_OIS_Reg_Gx_H, // 60 [0x3C]
/*! \brief Gyroscope Y axis least significant byte */
Qmi8658_OIS_Reg_Gy_L, // 61 [0x3D]
/*! \brief Gyroscope Y axis most significant byte */
Qmi8658_OIS_Reg_Gy_H, // 62 [0x3E]
/*! \brief Gyroscope Z axis least significant byte */
Qmi8658_OIS_Reg_Gz_L, // 63 [0x3F]
/*! \brief Gyroscope Z axis most significant byte */
Qmi8658_OIS_Reg_Gz_H, // 64 [0x40]
};
enum Qmi8658_Ctrl9Command {
Qmi8658_Ctrl9_Cmd_NOP = 0X00,
Qmi8658_Ctrl9_Cmd_GyroBias = 0X01,
Qmi8658_Ctrl9_Cmd_Rqst_Sdi_Mod = 0X03,
Qmi8658_Ctrl9_Cmd_Rst_Fifo = 0X04,
Qmi8658_Ctrl9_Cmd_Req_Fifo = 0X05,
Qmi8658_Ctrl9_Cmd_I2CM_Write = 0X06,
Qmi8658_Ctrl9_Cmd_WoM_Setting = 0x08,
Qmi8658_Ctrl9_Cmd_AccelHostDeltaOffset = 0x09,
Qmi8658_Ctrl9_Cmd_GyroHostDeltaOffset = 0x0A,
Qmi8658_Ctrl9_Cmd_EnableExtReset = 0x0B,
Qmi8658_Ctrl9_Cmd_EnableTap = 0x0C,
Qmi8658_Ctrl9_Cmd_EnablePedometer = 0x0D,
Qmi8658_Ctrl9_Cmd_Reset_Pedometer = 0x0F,
Qmi8658_Ctrl9_Cmd_Motion = 0x0E,
Qmi8658_Ctrl9_Cmd_CopyUsid = 0x10,
Qmi8658_Ctrl9_Cmd_SetRpu = 0x11,
Qmi8658_Ctrl9_Cmd_AHB_Clock_Gating = 0x12,
Qmi8658_Ctrl9_Cmd_On_Demand_Cali = 0xA2,
Qmi8658_Ctrl9_Cmd_Dbg_WoM_Data_Enable = 0xF8,
};
enum Qmi8658_LpfConfig {
Qmi8658Lpf_Disable, /*!< \brief Disable low pass filter. */
Qmi8658Lpf_Enable /*!< \brief Enable low pass filter. */
};
enum Qmi8658_HpfConfig {
Qmi8658Hpf_Disable, /*!< \brief Disable high pass filter. */
Qmi8658Hpf_Enable /*!< \brief Enable high pass filter. */
};
enum Qmi8658_StConfig {
Qmi8658St_Disable, /*!< \brief Disable high pass filter. */
Qmi8658St_Enable /*!< \brief Enable high pass filter. */
};
enum Qmi8658_LpfMode {
A_LSP_MODE_0 = 0x00 << 1,
A_LSP_MODE_1 = 0x01 << 1,
A_LSP_MODE_2 = 0x02 << 1,
A_LSP_MODE_3 = 0x03 << 1,
G_LSP_MODE_0 = 0x00 << 5,
G_LSP_MODE_1 = 0x01 << 5,
G_LSP_MODE_2 = 0x02 << 5,
G_LSP_MODE_3 = 0x03 << 5
};
enum Qmi8658_AccRange {
Qmi8658AccRange_2g = 0x00 << 4, /*!< \brief +/- 2g range */
Qmi8658AccRange_4g = 0x01 << 4, /*!< \brief +/- 4g range */
Qmi8658AccRange_8g = 0x02 << 4, /*!< \brief +/- 8g range */
Qmi8658AccRange_16g = 0x03 << 4 /*!< \brief +/- 16g range */
};
enum Qmi8658_AccOdr {
Qmi8658AccOdr_8000Hz = 0x00, /*!< \brief High resolution 8000Hz output rate. */
Qmi8658AccOdr_4000Hz = 0x01, /*!< \brief High resolution 4000Hz output rate. */
Qmi8658AccOdr_2000Hz = 0x02, /*!< \brief High resolution 2000Hz output rate. */
Qmi8658AccOdr_1000Hz = 0x03, /*!< \brief High resolution 1000Hz output rate. */
Qmi8658AccOdr_500Hz = 0x04, /*!< \brief High resolution 500Hz output rate. */
Qmi8658AccOdr_250Hz = 0x05, /*!< \brief High resolution 250Hz output rate. */
Qmi8658AccOdr_125Hz = 0x06, /*!< \brief High resolution 125Hz output rate. */
Qmi8658AccOdr_62_5Hz = 0x07, /*!< \brief High resolution 62.5Hz output rate. */
Qmi8658AccOdr_31_25Hz = 0x08, /*!< \brief High resolution 31.25Hz output rate. */
Qmi8658AccOdr_LowPower_128Hz = 0x0c, /*!< \brief Low power 128Hz output rate. */
Qmi8658AccOdr_LowPower_21Hz = 0x0d, /*!< \brief Low power 21Hz output rate. */
Qmi8658AccOdr_LowPower_11Hz = 0x0e, /*!< \brief Low power 11Hz output rate. */
Qmi8658AccOdr_LowPower_3Hz = 0x0f /*!< \brief Low power 3Hz output rate. */
};
enum Qmi8658_GyrRange {
Qmi8658GyrRange_16dps = 0 << 4, /*!< \brief +-32 degrees per second. */
Qmi8658GyrRange_32dps = 1 << 4, /*!< \brief +-32 degrees per second. */
Qmi8658GyrRange_64dps = 2 << 4, /*!< \brief +-64 degrees per second. */
Qmi8658GyrRange_128dps = 3 << 4, /*!< \brief +-128 degrees per second. */
Qmi8658GyrRange_256dps = 4 << 4, /*!< \brief +-256 degrees per second. */
Qmi8658GyrRange_512dps = 5 << 4, /*!< \brief +-512 degrees per second. */
Qmi8658GyrRange_1024dps = 6 << 4, /*!< \brief +-1024 degrees per second. */
Qmi8658GyrRange_2048dps = 7 << 4, /*!< \brief +-2048 degrees per second. */
};
/*!
* \brief Gyroscope output rate configuration.
*/
enum Qmi8658_GyrOdr {
Qmi8658GyrOdr_8000Hz = 0x00, /*!< \brief High resolution 8000Hz output rate. */
Qmi8658GyrOdr_4000Hz = 0x01, /*!< \brief High resolution 4000Hz output rate. */
Qmi8658GyrOdr_2000Hz = 0x02, /*!< \brief High resolution 2000Hz output rate. */
Qmi8658GyrOdr_1000Hz = 0x03, /*!< \brief High resolution 1000Hz output rate. */
Qmi8658GyrOdr_500Hz = 0x04, /*!< \brief High resolution 500Hz output rate. */
Qmi8658GyrOdr_250Hz = 0x05, /*!< \brief High resolution 250Hz output rate. */
Qmi8658GyrOdr_125Hz = 0x06, /*!< \brief High resolution 125Hz output rate. */
Qmi8658GyrOdr_62_5Hz = 0x07, /*!< \brief High resolution 62.5Hz output rate. */
Qmi8658GyrOdr_31_25Hz = 0x08 /*!< \brief High resolution 31.25Hz output rate. */
};
enum Qmi8658_AeOdr {
Qmi8658AeOdr_1Hz = 0x00, /*!< \brief 1Hz output rate. */
Qmi8658AeOdr_2Hz = 0x01, /*!< \brief 2Hz output rate. */
Qmi8658AeOdr_4Hz = 0x02, /*!< \brief 4Hz output rate. */
Qmi8658AeOdr_8Hz = 0x03, /*!< \brief 8Hz output rate. */
Qmi8658AeOdr_16Hz = 0x04, /*!< \brief 16Hz output rate. */
Qmi8658AeOdr_32Hz = 0x05, /*!< \brief 32Hz output rate. */
Qmi8658AeOdr_64Hz = 0x06, /*!< \brief 64Hz output rate. */
Qmi8658AeOdr_128Hz = 0x07, /*!< \brief 128Hz output rate. */
/*!
* \brief Motion on demand mode.
*
* In motion on demand mode the application can trigger AttitudeEngine
* output samples as necessary. This allows the AttitudeEngine to be
* synchronized with external data sources.
*
* When in Motion on Demand mode the application should request new data
* by calling the Qmi8658_requestAttitudeEngineData() function. The
* AttitudeEngine will respond with a data ready event (INT2) when the
* data is available to be read.
*/
Qmi8658AeOdr_motionOnDemand = 128
};
enum Qmi8658_MagOdr {
Qmi8658MagOdr_1000Hz = 0x00, /*!< \brief 1000Hz output rate. */
Qmi8658MagOdr_500Hz = 0x01, /*!< \brief 500Hz output rate. */
Qmi8658MagOdr_250Hz = 0x02, /*!< \brief 250Hz output rate. */
Qmi8658MagOdr_125Hz = 0x03, /*!< \brief 125Hz output rate. */
Qmi8658MagOdr_62_5Hz = 0x04, /*!< \brief 62.5Hz output rate. */
Qmi8658MagOdr_31_25Hz = 0x05 /*!< \brief 31.25Hz output rate. */
};
enum Qmi8658_MagDev {
MagDev_AKM09918 = (0 << 3), /*!< \brief AKM09918. */
};
enum Qmi8658_AccUnit {
Qmi8658AccUnit_g, /*!< \brief Accelerometer output in terms of g (9.81m/s^2). */
Qmi8658AccUnit_ms2 /*!< \brief Accelerometer output in terms of m/s^2. */
};
enum Qmi8658_GyrUnit {
Qmi8658GyrUnit_dps, /*!< \brief Gyroscope output in degrees/s. */
Qmi8658GyrUnit_rads /*!< \brief Gyroscope output in rad/s. */
};
enum Qmi8658_fifo_format {
QMI8658_FORMAT_EMPTY,
QMI8658_FORMAT_ACCEL_6_BYTES,
QMI8658_FORMAT_GYRO_6_BYTES,
QMI8658_FORMAT_MAG_6_BYTES,
QMI8658_FORMAT_12_BYTES, //默认:acc + gyro
QMI8658_FORMAT_18_BYTES, //acc + gyro + mag
QMI8658_FORMAT_UNKNOWN = 0xff,
};
enum Qmi8658_FifoMode {
Qmi8658_Fifo_Bypass = 0,
Qmi8658_Fifo_Fifo = 1,
Qmi8658_Fifo_Stream = 2,
Qmi8658_Fifo_StreamToFifo = 3
};
//fifo size:1536 bytes
enum Qmi8658_FifoSize {
Qmi8658_Fifo_16 = (0 << 2), //support 3 sensor
Qmi8658_Fifo_32 = (1 << 2), //support 3 sensor
Qmi8658_Fifo_64 = (2 << 2), //support 3 sensor
Qmi8658_Fifo_128 = (3 << 2) //support 2 sensor
};
// enum Qmi8658_FifoWmkLevel
// {
// Qmi8658_Fifo_WmkEmpty = (0 << 4),
// Qmi8658_Fifo_WmkOneQuarter = (1 << 4),
// Qmi8658_Fifo_WmkHalf = (2 << 4),
// Qmi8658_Fifo_WmkThreeQuarters = (3 << 4)
// };
enum Qmi8658_anymotion_G_TH {
Qmi8658_1G = 1 << 5,
Qmi8658_2G = 2 << 5,
Qmi8658_3G = 3 << 5,
Qmi8658_4G = 4 << 5,
Qmi8658_5G = 5 << 5,
Qmi8658_6G = 6 << 5,
Qmi8658_7G = 7 << 5,
Qmi8658_8G = 8 << 5,
};
struct Qmi8658_offsetCalibration {
enum Qmi8658_AccUnit accUnit;
float accOffset[3];
enum Qmi8658_GyrUnit gyrUnit;
float gyrOffset[3];
};
struct Qmi8658_sensitivityCalibration {
float accSensitivity[3];
float gyrSensitivity[3];
};
enum Qmi8658_Interrupt {
Qmi8658_Int1_low = (0 << 6),
Qmi8658_Int2_low = (1 << 6),
Qmi8658_Int1_high = (2 << 6),
Qmi8658_Int2_high = (3 << 6)
};
enum Qmi8658_InterruptState {
Qmi8658State_high = (1 << 7), /*!< Interrupt high. */
Qmi8658State_low = (0 << 7) /*!< Interrupt low. */
};
enum Qmi8658_WakeOnMotionThreshold {
Qmi8658WomThreshold_off = 0,
Qmi8658WomThreshold_low = 32,
Qmi8658WomThreshold_mid = 128,
Qmi8658WomThreshold_high = 255
};
struct Qmi8658Config {
unsigned char inputSelection;
enum Qmi8658_AccRange accRange;
enum Qmi8658_AccOdr accOdr;
enum Qmi8658_GyrRange gyrRange;
enum Qmi8658_GyrOdr gyrOdr;
enum Qmi8658_AeOdr aeOdr;
enum Qmi8658_MagOdr magOdr;
enum Qmi8658_MagDev magDev;
#if (QMI8658_USE_FIFO_EN)
unsigned char fifo_ctrl;
unsigned char fifo_fss;
enum Qmi8658_fifo_format fifo_format;
//unsigned char fifo_status;
#endif
};
/***************************************************************************
Exported Functions
****************************************************************************/
extern unsigned char qmi8658_init(u8 demand_cali_en);
extern void Qmi8658_Config_apply(struct Qmi8658Config const *config);
extern void Qmi8658_enableSensors(unsigned char enableFlags);
extern void Qmi8658_read_acc_xyz(float acc_xyz[3]);
extern void Qmi8658_read_gyro_xyz(float gyro_xyz[3]);
extern void Qmi8658_read_xyz(float acc[3], float gyro[3], unsigned int *tim_count);
extern void Qmi8658_read_xyz_raw(short raw_acc_xyz[3], short raw_gyro_xyz[3], unsigned int *tim_count);
extern void Qmi8658_read_ae(float quat[4], float velocity[3]);
extern float Qmi8658_readTemp(void);
// extern unsigned char Qmi8658_readStatusInt(void);//无
extern unsigned char Qmi8658_readStatus0(void);
extern unsigned char Qmi8658_readStatus1(void);
extern void Qmi8658_enableWakeOnMotion(enum Qmi8658_Interrupt int_set, enum Qmi8658_WakeOnMotionThreshold threshold, unsigned char blankingTime);
extern void Qmi8658_disableWakeOnMotion(void);
#if (QMI8658_USE_FIFO_EN)
extern void Qmi8658_config_fifo(unsigned char watermark, enum Qmi8658_FifoSize size, enum Qmi8658_FifoMode mode, enum Qmi8658_fifo_format format);
// extern void Qmi8658_enable_fifo(void);//无
unsigned short Qmi8658_read_fifo(unsigned char *data);
void Qmi8658_get_fifo_format(enum Qmi8658_fifo_format *format);
#endif
#if (QMI8658_USE_STEP_EN)
unsigned char stepConfig(unsigned short odr);
uint32_t Qmi8658_step_read_stepcounter(uint32_t *step);
void step_disable(void);
#endif
#if (QMI8658_USE_ANYMOTION_EN)
// unsigned char anymotion_Config(enum Qmi8658_anymotion_G_TH motion_g_th, unsigned char motion_mg_th );
void anymotion_lowpwr_config(void);
void anymotion_high_odr_enable(void);
void anymotion_disable(void);
#endif
#if (QMI8658_USE_TAP_EN)
// unsigned char tap_Config(void);
void tap_enable(void);
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,558 @@
#ifndef __SH3001_H
#define __SH3001_H
#include <string.h>
#if TCFG_SH3001_ENABLE
/******************************************************************
* user config SH3001 Macro Definition
******************************************************************/
#define SH3001_USER_INTERFACE TCFG_SH3001_INTERFACE_TYPE //0:I2C(<=400kHz), 1:SPI(<=1MHz)
#define SH3001_SD0_IIC_ADDR 1 //1:iic模式SD0接VCC, 0:iic模式SD0接GND
//int io config
// #define SH3001_INT_IO1 IO_PORTB_03//TCFG_IOKEY_POWER_ONE_PORT //IO_PORTB_01
// #define SH3001_INT_READ_IO1() gpio_read(SH3001_INT_IO1)
#define SH3001_INT_IO2 IO_PORTA_06
#define SH3001_INT_READ_IO2() gpio_read(SH3001_INT_IO2)
#define TCFG_SH3001_USER_INT_EN 1 //1:中断模式读, 0:定时模式读
/******************************************************************
* SH3001 I2C address Macro Definition
* (7bit): (0x37)011 0111@SDO=1; (0x36)011 0110@SDO=0;
******************************************************************/
#if SH3001_SD0_IIC_ADDR
#define SH3001_ADDRESS (0x37<<1)
#else
#define SH3001_ADDRESS (0x36<<1)
#endif
/******************************************************************
* SH3001 Registers Macro Definitions
******************************************************************/
#define SH3001_ACC_XL (0x00)
#define SH3001_ACC_XH (0x01)
#define SH3001_ACC_YL (0x02)
#define SH3001_ACC_YH (0x03)
#define SH3001_ACC_ZL (0x04)
#define SH3001_ACC_ZH (0x05)
#define SH3001_GYRO_XL (0x06)
#define SH3001_GYRO_XH (0x07)
#define SH3001_GYRO_YL (0x08)
#define SH3001_GYRO_YH (0x09)
#define SH3001_GYRO_ZL (0x0A)
#define SH3001_GYRO_ZH (0x0B)
#define SH3001_TEMP_ZL (0x0C)
#define SH3001_TEMP_ZH (0x0D)
#define SH3001_CHIP_ID (0x0F)
#define SH3001_INT_STA0 (0x10)
#define SH3001_INT_STA1 (0x11)
#define SH3001_INT_STA2 (0x12)
#define SH3001_INT_STA3 (0x14)
#define SH3001_INT_STA4 (0x15)
#define SH3001_FIFO_STA0 (0x16)
#define SH3001_FIFO_STA1 (0x17)
#define SH3001_FIFO_DATA (0x18)
#define SH3001_TEMP_CONF0 (0x20)
#define SH3001_TEMP_CONF1 (0x21)
#define SH3001_ACC_CONF0 (0x22) // accelerometer config 0x22-0x26
#define SH3001_ACC_CONF1 (0x23)
#define SH3001_ACC_CONF2 (0x25)
#define SH3001_ACC_CONF3 (0x26)
#define SH3001_GYRO_CONF0 (0x28) // gyroscope config 0x28-0x2B
#define SH3001_GYRO_CONF1 (0x29)
#define SH3001_GYRO_CONF2 (0x2B)
#define SH3001_SPI_CONF (0x32)
#define SH3001_FIFO_CONF0 (0x35)
#define SH3001_FIFO_CONF1 (0x36)
#define SH3001_FIFO_CONF2 (0x37)
#define SH3001_FIFO_CONF3 (0x38)
#define SH3001_FIFO_CONF4 (0x39)
#define SH3001_MI2C_CONF0 (0x3A)
#define SH3001_MI2C_CONF1 (0x3B)
#define SH3001_MI2C_CMD0 (0x3C)
#define SH3001_MI2C_CMD1 (0x3D)
#define SH3001_MI2C_WR (0x3E)
#define SH3001_MI2C_RD (0x3F)
#define SH3001_INT_ENABLE0 (0x40)
#define SH3001_INT_ENABLE1 (0x41)
#define SH3001_INT_CONF (0x44)
#define SH3001_INT_LIMIT (0x45)
#define SH3001_ORIEN_INTCONF0 (0x46)
#define SH3001_ORIEN_INTCONF1 (0x47)
#define SH3001_ORIEN_INT_LOW (0x48)
#define SH3001_ORIEN_INT_HIGH (0x49)
#define SH3001_ORIEN_INT_SLOPE_LOW (0x4A)
#define SH3001_ORIEN_INT_SLOPE_HIGH (0x4B)
#define SH3001_ORIEN_INT_HYST_LOW (0x4C)
#define SH3001_ORIEN_INT_HYST_HIGH (0x4D)
#define SH3001_FLAT_INT_CONF (0x4E)
#define SH3001_ACT_INACT_INT_CONF (0x4F)
#define SH3001_ACT_INACT_INT_LINK (0x50)
#define SH3001_TAP_INT_THRESHOLD (0x51)
#define SH3001_TAP_INT_DURATION (0x52)
#define SH3001_TAP_INT_LATENCY (0x53)
#define SH3001_DTAP_INT_WINDOW (0x54)
#define SH3001_ACT_INT_THRESHOLD (0x55)
#define SH3001_ACT_INT_TIME (0x56)
#define SH3001_INACT_INT_THRESHOLDL (0x57)
#define SH3001_INACT_INT_TIME (0x58)
#define SH3001_HIGHLOW_G_INT_CONF (0x59)
#define SH3001_HIGHG_INT_THRESHOLD (0x5A)
#define SH3001_HIGHG_INT_TIME (0x5B)
#define SH3001_LOWG_INT_THRESHOLD (0x5C)
#define SH3001_LOWG_INT_TIME (0x5D)
#define SH3001_FREEFALL_INT_THRES (0x5E)
#define SH3001_FREEFALL_INT_TIME (0x5F)
#define SH3001_INT_PIN_MAP0 (0x79)
#define SH3001_INT_PIN_MAP1 (0x7A)
#define SH3001_INACT_INT_THRESHOLDM (0x7B)
#define SH3001_INACT_INT_THRESHOLDH (0x7C)
#define SH3001_INACT_INT_1G_REFL (0x7D)
#define SH3001_INACT_INT_1G_REFH (0x7E)
#define SH3001_SPI_REG_ACCESS (0x7F)
#define SH3001_GYRO_CONF3 (0x8F)
#define SH3001_GYRO_CONF4 (0x9F)
#define SH3001_GYRO_CONF5 (0xAF)
#define SH3001_CHIP_ID1 (0xDF)
#define SH3001_AUX_I2C_CONF (0xFD)
/******************************************************************
* ACC Config Macro Definitions
******************************************************************/
#define SH3001_ODR_1000HZ (0x00)
#define SH3001_ODR_500HZ (0x01)
#define SH3001_ODR_250HZ (0x02)
#define SH3001_ODR_125HZ (0x03)
#define SH3001_ODR_63HZ (0x04)
#define SH3001_ODR_31HZ (0x05)
#define SH3001_ODR_16HZ (0x06)
#define SH3001_ODR_2000HZ (0x08)
#define SH3001_ODR_4000HZ (0x09)
#define SH3001_ODR_8000HZ (0x0A)
#define SH3001_ODR_16000HZ (0x0B)
#define SH3001_ODR_32000HZ (0x0C)
#define SH3001_ACC_RANGE_16G (0x02)
#define SH3001_ACC_RANGE_8G (0x03)
#define SH3001_ACC_RANGE_4G (0x04)
#define SH3001_ACC_RANGE_2G (0x05)
#define SH3001_ACC_ODRX040 (0x00)
#define SH3001_ACC_ODRX025 (0x20)
#define SH3001_ACC_ODRX011 (0x40)
#define SH3001_ACC_ODRX004 (0x60)
#define SH3001_ACC_ODRX002 (0x80)
#define SH3001_ACC_FILTER_EN (0x00)
#define SH3001_ACC_FILTER_DIS (0x08)
/******************************************************************
* GYRO Config Macro Definitions
******************************************************************/
#define SH3001_GYRO_RANGE_125 (0x02)
#define SH3001_GYRO_RANGE_250 (0x03)
#define SH3001_GYRO_RANGE_500 (0x04)
#define SH3001_GYRO_RANGE_1000 (0x05)
#define SH3001_GYRO_RANGE_2000 (0x06)
#define SH3001_GYRO_ODRX00 (0x00)
#define SH3001_GYRO_ODRX01 (0x04)
#define SH3001_GYRO_ODRX02 (0x08)
#define SH3001_GYRO_ODRX03 (0x0C)
#define SH3001_GYRO_FILTER_EN (0x00)
#define SH3001_GYRO_FILTER_DIS (0x10)
/******************************************************************
* Temperature Config Macro Definitions
******************************************************************/
#define SH3001_TEMP_ODR_500 (0x00)
#define SH3001_TEMP_ODR_250 (0x10)
#define SH3001_TEMP_ODR_125 (0x20)
#define SH3001_TEMP_ODR_63 (0x30)
#define SH3001_TEMP_EN (0x80)
#define SH3001_TEMP_DIS (0x00)
/******************************************************************
* INT Config Macro Definitions
******************************************************************/
#define SH3001_INT_LOWG (0x8000)
#define SH3001_INT_HIGHG (0x4000)
#define SH3001_INT_INACT (0x2000)
#define SH3001_INT_ACT (0x1000)
#define SH3001_INT_DOUBLE_TAP (0x0800)
#define SH3001_INT_SINGLE_TAP (0x0400)
#define SH3001_INT_FLAT (0x0200)
#define SH3001_INT_ORIENTATION (0x0100)
#define SH3001_INT_FIFO_GYRO (0x0010)
#define SH3001_INT_GYRO_READY (0x0008)
#define SH3001_INT_ACC_FIFO (0x0004)
#define SH3001_INT_ACC_READY (0x0002)
#define SH3001_INT_FREE_FALL (0x0001)
#define SH3001_INT_UP_DOWN_Z (0x0040)
#define SH3001_INT_ENABLE (0x01)
#define SH3001_INT_DISABLE (0x00)
#define SH3001_INT_MAP_INT1 (0x01)
#define SH3001_INT_MAP_INT (0x00)
#define SH3001_INT0_LEVEL_LOW (0x80)
#define SH3001_INT0_LEVEL_HIGH (0x7F)
#define SH3001_INT_NO_LATCH (0x40)
#define SH3001_INT_LATCH (0xBF)
#define SH3001_INT1_LEVEL_LOW (0x20)
#define SH3001_INT1_LEVEL_HIGH (0xDF)
#define SH3001_INT_CLEAR_ANY (0x10)
#define SH3001_INT_CLEAR_STATUS (0xEF)
#define SH3001_INT1_NORMAL (0x04)
#define SH3001_INT1_OD (0xFB)
#define SH3001_INT0_NORMAL (0x01)
#define SH3001_INT0_OD (0xFE)
/******************************************************************
* Orientation Blocking Config Macro Definitions
******************************************************************/
#define SH3001_ORIENT_BLOCK_MODE0 (0x00)
#define SH3001_ORIENT_BLOCK_MODE1 (0x04)
#define SH3001_ORIENT_BLOCK_MODE2 (0x08)
#define SH3001_ORIENT_BLOCK_MODE3 (0x0C)
#define SH3001_ORIENT_SYMM (0x00)
#define SH3001_ORIENT_HIGH_ASYMM (0x01)
#define SH3001_ORIENT_LOW_ASYMM (0x02)
/******************************************************************
* Flat Time Config Macro Definitions
******************************************************************/
#define SH3001_FLAT_TIME_500MS (0x40)
#define SH3001_FLAT_TIME_1000MS (0x80)
#define SH3001_FLAT_TIME_2000MS (0xC0)
/******************************************************************
* ACT and INACT Int Config Macro Definitions
******************************************************************/
#define SH3001_ACT_AC_MODE (0x80)
#define SH3001_ACT_DC_MODE (0x00)
#define SH3001_ACT_X_INT_EN (0x40)
#define SH3001_ACT_X_INT_DIS (0x00)
#define SH3001_ACT_Y_INT_EN (0x20)
#define SH3001_ACT_Y_INT_DIS (0x00)
#define SH3001_ACT_Z_INT_EN (0x10)
#define SH3001_ACT_Z_INT_DIS (0x00)
#define SH3001_INACT_AC_MODE (0x08)
#define SH3001_INACT_DC_MODE (0x00)
#define SH3001_INACT_X_INT_EN (0x04)
#define SH3001_INACT_X_INT_DIS (0x00)
#define SH3001_INACT_Y_INT_EN (0x02)
#define SH3001_INACT_Y_INT_DIS (0x00)
#define SH3001_INACT_Z_INT_EN (0x01)
#define SH3001_INACT_Z_INT_DIS (0x00)
#define SH3001_LINK_PRE_STA (0x01)
#define SH3001_LINK_PRE_STA_NO (0x00)
/******************************************************************
* TAP Int Config Macro Definitions
******************************************************************/
#define SH3001_TAP_X_INT_EN (0x08)
#define SH3001_TAP_X_INT_DIS (0x00)
#define SH3001_TAP_Y_INT_EN (0x04)
#define SH3001_TAP_Y_INT_DIS (0x00)
#define SH3001_TAP_Z_INT_EN (0x02)
#define SH3001_TAP_Z_INT_DIS (0x00)
/******************************************************************
* HIGHG Int Config Macro Definitions
******************************************************************/
#define SH3001_HIGHG_ALL_INT_EN (0x80)
#define SH3001_HIGHG_ALL_INT_DIS (0x00)
#define SH3001_HIGHG_X_INT_EN (0x40)
#define SH3001_HIGHG_X_INT_DIS (0x00)
#define SH3001_HIGHG_Y_INT_EN (0x20)
#define SH3001_HIGHG_Y_INT_DIS (0x00)
#define SH3001_HIGHG_Z_INT_EN (0x10)
#define SH3001_HIGHG_Z_INT_DIS (0x00)
/******************************************************************
* LOWG Int Config Macro Definitions
******************************************************************/
#define SH3001_LOWG_ALL_INT_EN (0x01)
#define SH3001_LOWG_ALL_INT_DIS (0x00)
/******************************************************************
* SPI Interface Config Macro Definitions
******************************************************************/
#define SH3001_SPI_3_WIRE (0x01)
#define SH3001_SPI_4_WIRE (0x00)
/******************************************************************
* FIFO Config Macro Definitions
******************************************************************/
#define SH3001_FIFO_MODE_DIS (0x00)
#define SH3001_FIFO_MODE_FIFO (0x01)
#define SH3001_FIFO_MODE_STREAM (0x02)
#define SH3001_FIFO_MODE_TRIGGER (0x03)
#define SH3001_FIFO_ACC_DOWNS_EN (0x80)
#define SH3001_FIFO_ACC_DOWNS_DIS (0x00)
#define SH3001_FIFO_GYRO_DOWNS_EN (0x08)
#define SH3001_FIFO_GYRO_DOWNS_DIS (0x00)
#define SH3001_FIFO_FREQ_X1_2 (0x00)
#define SH3001_FIFO_FREQ_X1_4 (0x01)
#define SH3001_FIFO_FREQ_X1_8 (0x02)
#define SH3001_FIFO_FREQ_X1_16 (0x03)
#define SH3001_FIFO_FREQ_X1_32 (0x04)
#define SH3001_FIFO_FREQ_X1_64 (0x05)
#define SH3001_FIFO_FREQ_X1_128 (0x06)
#define SH3001_FIFO_FREQ_X1_256 (0x07)
#define SH3001_FIFO_EXT_Z_EN (0x2000)
#define SH3001_FIFO_EXT_Y_EN (0x1000)
#define SH3001_FIFO_EXT_X_EN (0x0080)
#define SH3001_FIFO_TEMPERATURE_EN (0x0040)
#define SH3001_FIFO_GYRO_Z_EN (0x0020)
#define SH3001_FIFO_GYRO_Y_EN (0x0010)
#define SH3001_FIFO_GYRO_X_EN (0x0008)
#define SH3001_FIFO_ACC_Z_EN (0x0004)
#define SH3001_FIFO_ACC_Y_EN (0x0002)
#define SH3001_FIFO_ACC_X_EN (0x0001)
#define SH3001_FIFO_ALL_DIS (0x0000)
/******************************************************************
* AUX I2C Config Macro Definitions
******************************************************************/
#define SH3001_MI2C_NORMAL_MODE (0x00)
#define SH3001_MI2C_BYPASS_MODE (0x01)
#define SH3001_MI2C_READ_ODR_200HZ (0x00)
#define SH3001_MI2C_READ_ODR_100HZ (0x10)
#define SH3001_MI2C_READ_ODR_50HZ (0x20)
#define SH3001_MI2C_READ_ODR_25HZ (0x30)
#define SH3001_MI2C_FAIL (0x20)
#define SH3001_MI2C_SUCCESS (0x10)
#define SH3001_MI2C_READ_MODE_AUTO (0x40)
#define SH3001_MI2C_READ_MODE_MANUAL (0x00)
/******************************************************************
* Other Macro Definitions
******************************************************************/
#define SH3001_TRUE (1)
#define SH3001_FALSE (0)
#define SH3001_NORMAL_MODE (0x00)
#define SH3001_SLEEP_MODE (0x01)
#define SH3001_POWERDOWN_MODE (0x02)
#define SH3001_ACC_NORMAL_MODE (0x03)
/***************************************************************************
* Type Definitions
****************************************************************************/
typedef unsigned char (*IMU_read)(unsigned char devAddr,
unsigned char regAddr,
unsigned char readLen,
unsigned char *readBuf);
typedef unsigned char (*IMU_write)(unsigned char devAddr,
unsigned char regAddr,
unsigned char writeLen,
unsigned char *writeBuf);
typedef struct {
signed char cXY;
signed char cXZ;
signed char cYX;
signed char cYZ;
signed char cZX;
signed char cZY;
signed char jX;
signed char jY;
signed char jZ;
unsigned char xMulti;
unsigned char yMulti;
unsigned char zMulti;
unsigned char paramP0;
} compCoefType;
typedef struct {
// u8 comms; //0:IIC; 1:SPI //宏控制
#if (SH3001_USER_INTERFACE==0)
u8 iic_hdl;
u8 iic_delay; //这个延时并非影响iic的时钟频率而是2Byte数据之间的延时
// u8 iic_clk; //iic_clk: <=400kHz
#else
u8 spi_hdl; //SPIx (role:master)
u8 spi_cs_pin; //
u8 spi_work_mode;//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_param;
/***************************************************************************
Exported Functions
****************************************************************************/
extern unsigned char SH3001_init(void);
extern void SH3001_GetImuData(short accData[3], short gyroData[3]);
extern void SH3001_GetImuCompData(short accData[3], short gyroData[3]);
extern float SH3001_GetTempData(void);
extern unsigned char SH3001_SwitchPowerMode(unsigned char powerMode);
// interrupt related fucntions
extern void SH3001_INT_Enable(unsigned short int intType,
unsigned char intEnable,
unsigned char intPinSel);
extern 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);
extern void SH3001_INT_LowG_Config(unsigned char lowGEnDisIntAll,
unsigned char lowGThres,
unsigned char lowGTimsMs);
extern void SH3001_INT_HighG_Config(unsigned char highGEnDisIntX,
unsigned char highGEnDisIntY,
unsigned char highGEnDisIntZ,
unsigned char highGEnDisIntAll,
unsigned char highGThres,
unsigned char highGTimsMs);
extern 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);
extern 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);
extern 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);
extern void SH3001_INT_Flat_Config(unsigned char flatTimeTH,
unsigned char flatTanHeta2);
extern void SH3001_INT_Orient_Config(unsigned char orientBlockMode,
unsigned char orientMode,
unsigned char orientTheta,
unsigned short orientG1point5,
unsigned short orientSlope,
unsigned short orientHyst);
extern void SH3001_INT_FreeFall_Config(unsigned char freeFallThres,
unsigned char freeFallTimsMs);
extern unsigned short SH3001_INT_Read_Status0(void);
extern unsigned char SH3001_INT_Read_Status2(void);
extern unsigned char SH3001_INT_Read_Status3(void);
extern unsigned char SH3001_INT_Read_Status4(void);
extern void SH3001_pre_INT_config(void);
// Fifo related fucntions
extern void SH3001_FIFO_Reset(unsigned char fifoMode);
extern void SH3001_FIFO_Freq_Config(unsigned char fifoAccDownSampleEnDis,
unsigned char fifoAccFreq,
unsigned char fifoGyroDownSampleEnDis,
unsigned char fifoGyroFreq);
extern void SH3001_FIFO_Data_Config(unsigned short fifoMode,
unsigned short fifoWaterMarkLevel);
extern unsigned char SH3001_FIFO_Read_Status(unsigned short int *fifoEntriesCount);
extern void SH3001_FIFO_Read_Data(unsigned char *fifoReadData,
unsigned short int fifoDataLength);
// Master I2C related fucntions
extern void SH3001_MI2C_Reset(void);
extern void SH3001_MI2C_Bus_Config(unsigned char mi2cReadMode,
unsigned char mi2cODR,
unsigned char mi2cFreq);
extern void SH3001_MI2C_Cmd_Config(unsigned char mi2cSlaveAddr,
unsigned char mi2cSlaveCmd,
unsigned char mi2cReadMode);
extern unsigned char SH3001_MI2C_Write(unsigned char mi2cWriteData);
extern unsigned char SH3001_MI2C_Read(unsigned char *mi2cReadData);
// SPI interface related fucntions
extern void SH3001_SPI_Config(unsigned char spiInterfaceMode);
#endif
#endif