|
|
|
@ -16,56 +16,196 @@
@@ -16,56 +16,196 @@
|
|
|
|
|
|
|
|
|
|
/* Includes */ |
|
|
|
|
#include <stdint.h> |
|
|
|
|
#include <math.h> |
|
|
|
|
#include <stddef.h> |
|
|
|
|
#include "em7180_common.h" |
|
|
|
|
#include "lsm6dsm.h" |
|
|
|
|
|
|
|
|
|
/* Definitions */ |
|
|
|
|
/*
|
|
|
|
|
* LSM6DSM registers |
|
|
|
|
* http://www.st.com/content/ccc/resource/technical/document/datasheet/76/27/cf/88/c5/03/42/6b/DM00218116.pdf/files/DM00218116.pdf/jcr:content/translations/en.DM00218116.pdf
|
|
|
|
|
*/ |
|
|
|
|
#define LSM6DSM_FUNC_CFG_ACCESS 0x01 |
|
|
|
|
#define LSM6DSM_SENSOR_SYNC_TIME_FRAME 0x04 |
|
|
|
|
#define LSM6DSM_SENSOR_SYNC_RES_RATIO 0x05 |
|
|
|
|
#define LSM6DSM_FIFO_CTRL1 0x06 |
|
|
|
|
#define LSM6DSM_FIFO_CTRL2 0x07 |
|
|
|
|
#define LSM6DSM_FIFO_CTRL3 0x08 |
|
|
|
|
#define LSM6DSM_FIFO_CTRL4 0x09 |
|
|
|
|
#define LSM6DSM_FIFO_CTRL5 0x0A |
|
|
|
|
#define LSM6DSM_DRDY_PULSE_CFG 0x0B |
|
|
|
|
#define LSM6DSM_INT1_CTRL 0x0D |
|
|
|
|
#define LSM6DSM_INT2_CTRL 0x0E |
|
|
|
|
#define LSM6DSM_WHO_AM_I 0x0F // should be 0x6A
|
|
|
|
|
#define LSM6DSM_CTRL1_XL 0x10 |
|
|
|
|
#define LSM6DSM_CTRL2_G 0x11 |
|
|
|
|
#define LSM6DSM_CTRL3_C 0x12 |
|
|
|
|
#define LSM6DSM_CTRL4_C 0x13 |
|
|
|
|
#define LSM6DSM_CTRL5_C 0x14 |
|
|
|
|
#define LSM6DSM_CTRL6_C 0x15 |
|
|
|
|
#define LSM6DSM_CTRL7_G 0x16 |
|
|
|
|
#define LSM6DSM_CTRL8_XL 0x17 |
|
|
|
|
#define LSM6DSM_CTRL9_XL 0x18 |
|
|
|
|
#define LSM6DSM_CTRL10_C 0x19 |
|
|
|
|
#define LSM6DSM_MASTER_CONFIG 0x1A |
|
|
|
|
#define LSM6DSM_WAKE_UP_SRC 0x1B |
|
|
|
|
#define LSM6DSM_TAP_SRC 0x1C |
|
|
|
|
#define LSM6DSM_D6D_SRC 0x1D |
|
|
|
|
#define LSM6DSM_STATUS_REG 0x1E |
|
|
|
|
#define LSM6DSM_OUT_TEMP_L 0x20 |
|
|
|
|
#define LSM6DSM_OUT_TEMP_H 0x21 |
|
|
|
|
#define LSM6DSM_OUTX_L_G 0x22 |
|
|
|
|
#define LSM6DSM_OUTX_H_G 0x23 |
|
|
|
|
#define LSM6DSM_OUTY_L_G 0x24 |
|
|
|
|
#define LSM6DSM_OUTY_H_G 0x25 |
|
|
|
|
#define LSM6DSM_OUTZ_L_G 0x26 |
|
|
|
|
#define LSM6DSM_OUTZ_H_G 0x27 |
|
|
|
|
#define LSM6DSM_OUTX_L_XL 0x28 |
|
|
|
|
#define LSM6DSM_OUTX_H_XL 0x29 |
|
|
|
|
#define LSM6DSM_OUTY_L_XL 0x2A |
|
|
|
|
#define LSM6DSM_OUTY_H_XL 0x2B |
|
|
|
|
#define LSM6DSM_OUTZ_L_XL 0x2C |
|
|
|
|
#define LSM6DSM_OUTZ_H_XL 0x2D |
|
|
|
|
#define LSM6DSM_SENSORHUB1_REG 0x2E |
|
|
|
|
#define LSM6DSM_SENSORHUB2_REG 0x2F |
|
|
|
|
#define LSM6DSM_SENSORHUB3_REG 0x30 |
|
|
|
|
#define LSM6DSM_SENSORHUB4_REG 0x31 |
|
|
|
|
#define LSM6DSM_SENSORHUB5_REG 0x32 |
|
|
|
|
#define LSM6DSM_SENSORHUB6_REG 0x33 |
|
|
|
|
#define LSM6DSM_SENSORHUB7_REG 0x34 |
|
|
|
|
#define LSM6DSM_SENSORHUB8_REG 0x35 |
|
|
|
|
#define LSM6DSM_SENSORHUB9_REG 0x36 |
|
|
|
|
#define LSM6DSM_SENSORHUB10_REG 0x37 |
|
|
|
|
#define LSM6DSM_SENSORHUB11_REG 0x38 |
|
|
|
|
#define LSM6DSM_SENSORHUB12_REG 0x39 |
|
|
|
|
#define LSM6DSM_FIFO_STATUS1 0x3A |
|
|
|
|
#define LSM6DSM_FIFO_STATUS2 0x3B |
|
|
|
|
#define LSM6DSM_FIFO_STATUS3 0x3C |
|
|
|
|
#define LSM6DSM_FIFO_STATUS4 0x3D |
|
|
|
|
#define LSM6DSM_FIFO_DATA_OUT_L 0x3E |
|
|
|
|
#define LSM6DSM_FIFO_DATA_OUT_H 0x3F |
|
|
|
|
#define LSM6DSM_TIMESTAMP0_REG 0x40 |
|
|
|
|
#define LSM6DSM_TIMESTAMP1_REG 0x41 |
|
|
|
|
#define LSM6DSM_TIMESTAMP2_REG 0x42 |
|
|
|
|
#define LSM6DSM_STEP_TIMESTAMP_L 0x49 |
|
|
|
|
#define LSM6DSM_STEP_TIMESTAMP_H 0x4A |
|
|
|
|
#define LSM6DSM_STEP_COUNTER_L 0x4B |
|
|
|
|
#define LSM6DSM_STEP_COUNTER_H 0x4C |
|
|
|
|
#define LSM6DSM_SENSORHUB13_REG 0x4D |
|
|
|
|
#define LSM6DSM_SENSORHUB14_REG 0x4E |
|
|
|
|
#define LSM6DSM_SENSORHUB15_REG 0x4F |
|
|
|
|
#define LSM6DSM_SENSORHUB16_REG 0x50 |
|
|
|
|
#define LSM6DSM_SENSORHUB17_REG 0x51 |
|
|
|
|
#define LSM6DSM_SENSORHUB18_REG 0x52 |
|
|
|
|
#define LSM6DSM_FUNC_SRC1 0x53 |
|
|
|
|
#define LSM6DSM_FUNC_SRC2 0x54 |
|
|
|
|
#define LSM6DSM_WRIST_TILT_IA 0x55 |
|
|
|
|
#define LSM6DSM_TAP_CFG 0x58 |
|
|
|
|
#define LSM6DSM_TAP_THS_6D 0x59 |
|
|
|
|
#define LSM6DSM_INT_DUR2 0x5A |
|
|
|
|
#define LSM6DSM_WAKE_UP_THS 0x5B |
|
|
|
|
#define LSM6DSM_WAKE_UP_DUR 0x5C |
|
|
|
|
#define LSM6DSM_FREE_FALL 0x5D |
|
|
|
|
#define LSM6DSM_MD1_CFG 0x5E |
|
|
|
|
#define LSM6DSM_MD2_CFG 0x5F |
|
|
|
|
#define LSM6DSM_MASTER_MODE_CODE 0x60 |
|
|
|
|
#define LSM6DSM_SENS_SYNC_SPI_ERROR_CODE 0x61 |
|
|
|
|
#define LSM6DSM_OUT_MAG_RAW_X_L 0x66 |
|
|
|
|
#define LSM6DSM_OUT_MAG_RAW_X_H 0x67 |
|
|
|
|
#define LSM6DSM_OUT_MAG_RAW_Y_L 0x68 |
|
|
|
|
#define LSM6DSM_OUT_MAG_RAW_Y_H 0x69 |
|
|
|
|
#define LSM6DSM_OUT_MAG_RAW_Z_L 0x6A |
|
|
|
|
#define LSM6DSM_OUT_MAG_RAW_Z_H 0x6B |
|
|
|
|
#define LSM6DSM_INT_OIS 0x6F |
|
|
|
|
#define LSM6DSM_CTRL1_OIS 0x70 |
|
|
|
|
#define LSM6DSM_CTRL2_OIS 0x71 |
|
|
|
|
#define LSM6DSM_CTRL3_OIS 0x72 |
|
|
|
|
#define LSM6DSM_X_OFS_USR 0x73 |
|
|
|
|
#define LSM6DSM_Y_OFS_USR 0x74 |
|
|
|
|
#define LSM6DSM_Z_OFS_USR 0x75 |
|
|
|
|
|
|
|
|
|
/* Macros */ |
|
|
|
|
#define lsm6dsm_read_byte(addr, byte) i2c_read_byte((lsm6dsm->i2c_read_func), (lsm6dsm->i2c_addr), (addr), (byte)) |
|
|
|
|
#define lsm6dsm_write_byte(addr, byte) i2c_write_byte((lsm6dsm->i2c_write_func), (lsm6dsm->i2c_addr), (addr), (byte)) |
|
|
|
|
#define lsm6dsm_read(addr, data, len) i2c_read((lsm6dsm->i2c_read_func), (lsm6dsm->i2c_addr), (addr), (data), (len)) |
|
|
|
|
#define lsm6dsm_write(addr, data, len) i2c_write((lsm6dsm->i2c_write_func), (lsm6dsm->i2c_addr), (addr), (data), (len)) |
|
|
|
|
|
|
|
|
|
/* Private Global Variables */ |
|
|
|
|
|
|
|
|
|
/* Function Prototypes */ |
|
|
|
|
static void lsm6dsm_read_data(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c, |
|
|
|
|
int16_t *destination); |
|
|
|
|
|
|
|
|
|
/* Function Definitions */ |
|
|
|
|
void lsm6dsm_init(lsm6dsm_t *lsm6dsm, uint8_t ascale, uint8_t gscale, |
|
|
|
|
uint8_t a_odr, uint8_t g_odr) |
|
|
|
|
lsm6dsm_status_t lsm6dsm_init(lsm6dsm_t *lsm6dsm, lsm6dsm_init_t *init) |
|
|
|
|
{ |
|
|
|
|
int8_t *ptr = (int8_t*) lsm6dsm; |
|
|
|
|
size_t i; |
|
|
|
|
|
|
|
|
|
return_val_if_fail(lsm6dsm, LSM6DSM_BAD_ARG); |
|
|
|
|
return_val_if_fail(init, LSM6DSM_BAD_ARG); |
|
|
|
|
|
|
|
|
|
/* zero lsm6dsm_t struct */ |
|
|
|
|
for(i = 0; i < sizeof(lsm6dsm_t); i++) |
|
|
|
|
{ |
|
|
|
|
*ptr++ = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
lsm6dsm->init = init; |
|
|
|
|
|
|
|
|
|
return LSM6DSM_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void lsm6dsm_set_delay_cb(lsm6dsm_t *lsm6dsm, delay_func_t delay_func) |
|
|
|
|
{ |
|
|
|
|
return_if_fail(lsm6dsm); |
|
|
|
|
|
|
|
|
|
lsm6dsm->ascale = ascale; |
|
|
|
|
lsm6dsm->gscale = gscale; |
|
|
|
|
lsm6dsm->a_odr = a_odr; |
|
|
|
|
lsm6dsm->g_odr = g_odr; |
|
|
|
|
lsm6dsm->delay_func = delay_func; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void lsm6dsm_config(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c) |
|
|
|
|
void lsm6dsm_set_i2c_cbs(lsm6dsm_t *lsm6dsm, i2c_read_func_t i2c_read_func, |
|
|
|
|
i2c_write_func_t i2c_write_func, uint8_t dev_addr) |
|
|
|
|
{ |
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL1_XL, |
|
|
|
|
lsm6dsm->a_odr << 4 | lsm6dsm->ascale << 2); |
|
|
|
|
return_if_fail(lsm6dsm); |
|
|
|
|
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL2_G, |
|
|
|
|
lsm6dsm->g_odr << 4 | lsm6dsm->gscale << 2); |
|
|
|
|
lsm6dsm->i2c_read_func = i2c_read_func; |
|
|
|
|
lsm6dsm->i2c_write_func = i2c_write_func; |
|
|
|
|
lsm6dsm->i2c_addr = dev_addr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t temp = broken_i2c_read_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL3_C); |
|
|
|
|
lsm6dsm_status_t lsm6dsm_config(lsm6dsm_t *lsm6dsm) |
|
|
|
|
{ |
|
|
|
|
int32_t ret = 0; |
|
|
|
|
uint8_t temp; |
|
|
|
|
|
|
|
|
|
ret |= lsm6dsm_write_byte( |
|
|
|
|
LSM6DSM_CTRL1_XL, |
|
|
|
|
lsm6dsm->init->a_odr << 4 | lsm6dsm->init->ascale << 2); |
|
|
|
|
ret |= lsm6dsm_write_byte( |
|
|
|
|
LSM6DSM_CTRL2_G, |
|
|
|
|
lsm6dsm->init->g_odr << 4 | lsm6dsm->init->gscale << 2); |
|
|
|
|
ret |= lsm6dsm_read_byte(LSM6DSM_CTRL3_C, &temp); |
|
|
|
|
// enable block update (bit 6 = 1), auto-increment registers (bit 2 = 1)
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL3_C, |
|
|
|
|
temp | 0x40 | 0x04); |
|
|
|
|
ret |= lsm6dsm_write_byte(LSM6DSM_CTRL3_C, temp | 0x40 | 0x04); |
|
|
|
|
// by default, interrupts active HIGH, push pull, little endian data
|
|
|
|
|
// (can be changed by writing to bits 5, 4, and 1, resp to above register)
|
|
|
|
|
|
|
|
|
|
// enable accel LP2 (bit 7 = 1), set LP2 tp ODR/9 (bit 6 = 1), enable input_composite (bit 3) for low noise
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL8_XL, |
|
|
|
|
0x80 | 0x40 | 0x08); |
|
|
|
|
ret |= lsm6dsm_write_byte(LSM6DSM_CTRL8_XL, 0x80 | 0x40 | 0x08); |
|
|
|
|
|
|
|
|
|
// interrupt handling
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_DRDY_PULSE_CFG, 0x80); // latch interrupt until data read
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_INT1_CTRL, 0x40); // enable significant motion interrupts on INT1
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_INT2_CTRL, 0x03); // enable accel/gyro data ready interrupts on INT2
|
|
|
|
|
ret |= lsm6dsm_write_byte(LSM6DSM_DRDY_PULSE_CFG, 0x80); // latch interrupt until data read
|
|
|
|
|
ret |= lsm6dsm_write_byte(LSM6DSM_INT1_CTRL, 0x40); // enable significant motion interrupts on INT1
|
|
|
|
|
ret |= lsm6dsm_write_byte(LSM6DSM_INT2_CTRL, 0x03); // enable accel/gyro data ready interrupts on INT2
|
|
|
|
|
|
|
|
|
|
return ret ? LSM6DSM_BAD_COMM : LSM6DSM_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint8_t lsm6dsm_chip_id_get(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c) |
|
|
|
|
/* FIXME: haven't explored the usage/usefulness of these yet: */ |
|
|
|
|
#if(0) |
|
|
|
|
uint8_t lsm6dsm_chip_id_get(lsm6dsm_t *lsm6dsm) |
|
|
|
|
{ |
|
|
|
|
uint8_t c = broken_i2c_read_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_WHO_AM_I); |
|
|
|
|
uint8_t c; |
|
|
|
|
|
|
|
|
|
lsm6dsm_read_byte(LSM6DSM_WHO_AM_I, &c); |
|
|
|
|
|
|
|
|
|
return c; |
|
|
|
|
} |
|
|
|
@ -74,7 +214,7 @@ float lsm6dsm_ares_get(lsm6dsm_t *lsm6dsm)
@@ -74,7 +214,7 @@ float lsm6dsm_ares_get(lsm6dsm_t *lsm6dsm)
|
|
|
|
|
{ |
|
|
|
|
float a_res; |
|
|
|
|
|
|
|
|
|
switch(lsm6dsm->ascale) |
|
|
|
|
switch(lsm6dsm->init->ascale) |
|
|
|
|
{ |
|
|
|
|
// Possible accelerometer scales (and their register bit settings) are:
|
|
|
|
|
// 2 Gs (00), 4 Gs (01), 8 Gs (10), and 16 Gs (11).
|
|
|
|
@ -103,7 +243,7 @@ float lsm6dsm_gres_get(lsm6dsm_t *lsm6dsm)
@@ -103,7 +243,7 @@ float lsm6dsm_gres_get(lsm6dsm_t *lsm6dsm)
|
|
|
|
|
{ |
|
|
|
|
float g_res; |
|
|
|
|
|
|
|
|
|
switch(lsm6dsm->gscale) |
|
|
|
|
switch(lsm6dsm->init->gscale) |
|
|
|
|
{ |
|
|
|
|
// Possible gyro scales (and their register bit settings) are:
|
|
|
|
|
// 250 DPS (00), 500 DPS (01), 1000 DPS (10), and 2000 DPS (11).
|
|
|
|
@ -127,16 +267,17 @@ float lsm6dsm_gres_get(lsm6dsm_t *lsm6dsm)
@@ -127,16 +267,17 @@ float lsm6dsm_gres_get(lsm6dsm_t *lsm6dsm)
|
|
|
|
|
return g_res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void lsm6dsm_reset(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c) |
|
|
|
|
void lsm6dsm_reset(lsm6dsm_t *lsm6dsm) |
|
|
|
|
{ |
|
|
|
|
// reset device
|
|
|
|
|
uint8_t temp = broken_i2c_read_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL3_C); |
|
|
|
|
uint8_t temp; |
|
|
|
|
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL3_C, temp | 0x01); // Set bit 0 to 1 to reset LSM6DSM
|
|
|
|
|
HAL_Delay(100); // Wait for all registers to reset
|
|
|
|
|
lsm6dsm_read_byte(LSM6DSM_CTRL3_C, &temp); |
|
|
|
|
lsm6dsm_write_byte(LSM6DSM_CTRL3_C, temp | 0x01); // Set bit 0 to 1 to reset LSM6DSM
|
|
|
|
|
lsm6dsm->delay_func(100); // Wait for all registers to reset
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void lsm6dsm_self_test(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c) |
|
|
|
|
void lsm6dsm_self_test(lsm6dsm_t *lsm6dsm) |
|
|
|
|
{ |
|
|
|
|
int16_t temp[7] = { 0, 0, 0, 0, 0, 0, 0 }; |
|
|
|
|
int16_t accelPTest[3] = { 0, 0, 0 }; |
|
|
|
@ -146,7 +287,7 @@ void lsm6dsm_self_test(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c)
@@ -146,7 +287,7 @@ void lsm6dsm_self_test(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c)
|
|
|
|
|
int16_t accelNom[3] = { 0, 0, 0 }; |
|
|
|
|
int16_t gyroNom[3] = { 0, 0, 0 }; |
|
|
|
|
|
|
|
|
|
lsm6dsm_read_data(lsm6dsm, hi2c, temp); |
|
|
|
|
lsm6dsm_read_data(lsm6dsm, temp); |
|
|
|
|
accelNom[0] = temp[4]; |
|
|
|
|
accelNom[1] = temp[5]; |
|
|
|
|
accelNom[2] = temp[6]; |
|
|
|
@ -154,36 +295,36 @@ void lsm6dsm_self_test(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c)
@@ -154,36 +295,36 @@ void lsm6dsm_self_test(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c)
|
|
|
|
|
gyroNom[1] = temp[2]; |
|
|
|
|
gyroNom[2] = temp[3]; |
|
|
|
|
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL5_C, 0x01); // positive accel self test
|
|
|
|
|
HAL_Delay(100); // let accel respond
|
|
|
|
|
lsm6dsm_read_data(lsm6dsm, hi2c, temp); |
|
|
|
|
lsm6dsm_write_byte(LSM6DSM_CTRL5_C, 0x01); // positive accel self test
|
|
|
|
|
lsm6dsm->delay_func(100); // let accel respond
|
|
|
|
|
lsm6dsm_read_data(lsm6dsm, temp); |
|
|
|
|
accelPTest[0] = temp[4]; |
|
|
|
|
accelPTest[1] = temp[5]; |
|
|
|
|
accelPTest[2] = temp[6]; |
|
|
|
|
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL5_C, 0x03); // negative accel self test
|
|
|
|
|
HAL_Delay(100); // let accel respond
|
|
|
|
|
lsm6dsm_read_data(lsm6dsm, hi2c, temp); |
|
|
|
|
lsm6dsm_write_byte(LSM6DSM_CTRL5_C, 0x03); // negative accel self test
|
|
|
|
|
lsm6dsm->delay_func(100); // let accel respond
|
|
|
|
|
lsm6dsm_read_data(lsm6dsm, temp); |
|
|
|
|
accelNTest[0] = temp[4]; |
|
|
|
|
accelNTest[1] = temp[5]; |
|
|
|
|
accelNTest[2] = temp[6]; |
|
|
|
|
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL5_C, 0x04); // positive gyro self test
|
|
|
|
|
HAL_Delay(100); // let gyro respond
|
|
|
|
|
lsm6dsm_read_data(lsm6dsm, hi2c, temp); |
|
|
|
|
lsm6dsm_write_byte(LSM6DSM_CTRL5_C, 0x04); // positive gyro self test
|
|
|
|
|
lsm6dsm->delay_func(100); // let gyro respond
|
|
|
|
|
lsm6dsm_read_data(lsm6dsm, temp); |
|
|
|
|
gyroPTest[0] = temp[1]; |
|
|
|
|
gyroPTest[1] = temp[2]; |
|
|
|
|
gyroPTest[2] = temp[3]; |
|
|
|
|
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL5_C, 0x0C); // negative gyro self test
|
|
|
|
|
HAL_Delay(100); // let gyro respond
|
|
|
|
|
lsm6dsm_read_data(lsm6dsm, hi2c, temp); |
|
|
|
|
lsm6dsm_write_byte(LSM6DSM_CTRL5_C, 0x0C); // negative gyro self test
|
|
|
|
|
lsm6dsm->delay_func(100); // let gyro respond
|
|
|
|
|
lsm6dsm_read_data(lsm6dsm, temp); |
|
|
|
|
gyroNTest[0] = temp[1]; |
|
|
|
|
gyroNTest[1] = temp[2]; |
|
|
|
|
gyroNTest[2] = temp[3]; |
|
|
|
|
|
|
|
|
|
broken_i2c_write_byte(hi2c, LSM6DSM_ADDRESS, LSM6DSM_CTRL5_C, 0x00); // normal mode
|
|
|
|
|
HAL_Delay(100); // let accel and gyro respond
|
|
|
|
|
lsm6dsm_write_byte(LSM6DSM_CTRL5_C, 0x00); // normal mode
|
|
|
|
|
lsm6dsm->delay_func(100); // let accel and gyro respond
|
|
|
|
|
|
|
|
|
|
/* Serial.println("Accel Self Test:"); */ |
|
|
|
|
/* Serial.print("+Ax results:"); */ |
|
|
|
@ -216,12 +357,10 @@ void lsm6dsm_self_test(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c)
@@ -216,12 +357,10 @@ void lsm6dsm_self_test(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c)
|
|
|
|
|
/* Serial.print("-Gz results:"); */ |
|
|
|
|
/* Serial.println((gyroNTest[2] - gyroNom[2]) * g_res); */ |
|
|
|
|
/* Serial.println("Should be between 20 and 80 dps"); */ |
|
|
|
|
HAL_Delay(2000); |
|
|
|
|
|
|
|
|
|
lsm6dsm->delay_func(2000); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void lsm6dsm_offset_bias(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c, |
|
|
|
|
float *dest1, float *dest2) |
|
|
|
|
void lsm6dsm_offset_bias(lsm6dsm_t *lsm6dsm, float *dest1, float *dest2) |
|
|
|
|
{ |
|
|
|
|
int16_t temp[7] = { 0, 0, 0, 0, 0, 0, 0 }; |
|
|
|
|
int32_t sum[7] = { 0, 0, 0, 0, 0, 0, 0 }; |
|
|
|
@ -229,18 +368,18 @@ void lsm6dsm_offset_bias(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c,
@@ -229,18 +368,18 @@ void lsm6dsm_offset_bias(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c,
|
|
|
|
|
float g_res = lsm6dsm_gres_get(lsm6dsm); |
|
|
|
|
|
|
|
|
|
/* Serial.println("Calculate accel and gyro offset biases: keep sensor flat and motionless!"); */ |
|
|
|
|
HAL_Delay(4000); |
|
|
|
|
lsm6dsm->delay_func(4000); |
|
|
|
|
|
|
|
|
|
for(int ii = 0; ii < 128; ii++) |
|
|
|
|
{ |
|
|
|
|
lsm6dsm_read_data(lsm6dsm, hi2c, temp); |
|
|
|
|
lsm6dsm_read_data(lsm6dsm, temp); |
|
|
|
|
sum[1] += temp[1]; |
|
|
|
|
sum[2] += temp[2]; |
|
|
|
|
sum[3] += temp[3]; |
|
|
|
|
sum[4] += temp[4]; |
|
|
|
|
sum[5] += temp[5]; |
|
|
|
|
sum[6] += temp[6]; |
|
|
|
|
HAL_Delay(50); |
|
|
|
|
lsm6dsm->delay_func(50); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
dest1[0] = sum[1] * g_res / 128.0f; |
|
|
|
@ -277,12 +416,11 @@ void lsm6dsm_offset_bias(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c,
@@ -277,12 +416,11 @@ void lsm6dsm_offset_bias(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c,
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void lsm6dsm_read_data(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c, |
|
|
|
|
int16_t *destination) |
|
|
|
|
static void lsm6dsm_read_data(lsm6dsm_t *lsm6dsm, int16_t *destination) |
|
|
|
|
{ |
|
|
|
|
uint8_t data[14]; // x/y/z accel register data stored here
|
|
|
|
|
|
|
|
|
|
broken_i2c_read(hi2c, LSM6DSM_ADDRESS, LSM6DSM_OUT_TEMP_L, data, 14); // Read the 14 raw data registers into data array
|
|
|
|
|
lsm6dsm_read(LSM6DSM_OUT_TEMP_L, data, 14); // Read the 14 raw data registers into data array
|
|
|
|
|
destination[0] = ((int16_t) data[1] << 8) | data[0]; // Turn the MSB and LSB into a signed 16-bit value
|
|
|
|
|
destination[1] = ((int16_t) data[3] << 8) | data[2]; |
|
|
|
|
destination[2] = ((int16_t) data[5] << 8) | data[4]; |
|
|
|
@ -291,3 +429,4 @@ static void lsm6dsm_read_data(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c,
@@ -291,3 +429,4 @@ static void lsm6dsm_read_data(lsm6dsm_t *lsm6dsm, I2C_HandleTypeDef *hi2c,
|
|
|
|
|
destination[5] = ((int16_t) data[11] << 8) | data[10]; |
|
|
|
|
destination[6] = ((int16_t) data[13] << 8) | data[12]; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|