LSM6DS3 (#2268)
* add initial lsm6ds3 setup
* accel works
* ignore lsm6ds3 in locationd
* add gyro
* add temp
Co-authored-by: Comma Device <device@comma.ai>
old-commit-hash: e51da619c1
commatwo_master
parent
67b02775da
commit
03b2a6a137
10 changed files with 281 additions and 11 deletions
@ -0,0 +1,62 @@ |
|||||||
|
#include <cassert> |
||||||
|
#include "common/swaglog.h" |
||||||
|
#include "common/timing.h" |
||||||
|
|
||||||
|
#include "lsm6ds3_accel.hpp" |
||||||
|
|
||||||
|
|
||||||
|
LSM6DS3_Accel::LSM6DS3_Accel(I2CBus *bus) : I2CSensor(bus) {} |
||||||
|
|
||||||
|
int LSM6DS3_Accel::init(){ |
||||||
|
int ret = 0; |
||||||
|
uint8_t buffer[1]; |
||||||
|
|
||||||
|
ret = read_register(LSM6DS3_ACCEL_I2C_REG_ID, buffer, 1); |
||||||
|
if(ret < 0){ |
||||||
|
LOGE("Reading chip ID failed: %d", ret); |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
if(buffer[0] != LSM6DS3_ACCEL_CHIP_ID){ |
||||||
|
LOGE("Chip ID wrong. Got: %d, Expected %d", buffer[0], LSM6DS3_ACCEL_CHIP_ID); |
||||||
|
ret = -1; |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
// TODO: set scale and bandwith. Default is +- 2G, 50 Hz
|
||||||
|
ret = set_register(LSM6DS3_ACCEL_I2C_REG_CTRL1_XL, LSM6DS3_ACCEL_ODR_104HZ); |
||||||
|
if (ret < 0){ |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
fail: |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void LSM6DS3_Accel::get_event(cereal::SensorEventData::Builder &event){ |
||||||
|
|
||||||
|
uint64_t start_time = nanos_since_boot(); |
||||||
|
uint8_t buffer[6]; |
||||||
|
int len = read_register(LSM6DS3_ACCEL_I2C_REG_OUTX_L_XL, buffer, sizeof(buffer)); |
||||||
|
assert(len == sizeof(buffer)); |
||||||
|
|
||||||
|
float scale = 9.81 * 2.0f / (1 << 15); |
||||||
|
float x = read_16_bit(buffer[0], buffer[1]) * scale; |
||||||
|
float y = read_16_bit(buffer[2], buffer[3]) * scale; |
||||||
|
float z = read_16_bit(buffer[4], buffer[5]) * scale; |
||||||
|
|
||||||
|
event.setSource(cereal::SensorEventData::SensorSource::LSM6DS3); |
||||||
|
event.setVersion(1); |
||||||
|
event.setSensor(SENSOR_ACCELEROMETER); |
||||||
|
event.setType(SENSOR_TYPE_ACCELEROMETER); |
||||||
|
event.setTimestamp(start_time); |
||||||
|
|
||||||
|
float xyz[] = {y, -x, z}; |
||||||
|
kj::ArrayPtr<const float> vs(&xyz[0], 3); |
||||||
|
|
||||||
|
auto svec = event.initAcceleration(); |
||||||
|
svec.setV(vs); |
||||||
|
svec.setStatus(true); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "sensors/i2c_sensor.hpp" |
||||||
|
|
||||||
|
// Address of the chip on the bus
|
||||||
|
#define LSM6DS3_ACCEL_I2C_ADDR 0x6A |
||||||
|
|
||||||
|
// Registers of the chip
|
||||||
|
#define LSM6DS3_ACCEL_I2C_REG_ID 0x0F |
||||||
|
#define LSM6DS3_ACCEL_I2C_REG_CTRL1_XL 0x10 |
||||||
|
#define LSM6DS3_ACCEL_I2C_REG_OUTX_L_XL 0x28 |
||||||
|
|
||||||
|
// Constants
|
||||||
|
#define LSM6DS3_ACCEL_CHIP_ID 0x69 |
||||||
|
#define LSM6DS3_ACCEL_ODR_104HZ (0b0100 << 4) |
||||||
|
|
||||||
|
|
||||||
|
class LSM6DS3_Accel : public I2CSensor { |
||||||
|
uint8_t get_device_address() {return LSM6DS3_ACCEL_I2C_ADDR;} |
||||||
|
public: |
||||||
|
LSM6DS3_Accel(I2CBus *bus); |
||||||
|
int init(); |
||||||
|
void get_event(cereal::SensorEventData::Builder &event); |
||||||
|
}; |
@ -0,0 +1,65 @@ |
|||||||
|
#include <cassert> |
||||||
|
#include <cmath> |
||||||
|
#include "common/swaglog.h" |
||||||
|
#include "common/timing.h" |
||||||
|
|
||||||
|
#include "lsm6ds3_gyro.hpp" |
||||||
|
|
||||||
|
#define DEG2RAD(x) ((x) * M_PI / 180.0) |
||||||
|
|
||||||
|
|
||||||
|
LSM6DS3_Gyro::LSM6DS3_Gyro(I2CBus *bus) : I2CSensor(bus) {} |
||||||
|
|
||||||
|
int LSM6DS3_Gyro::init(){ |
||||||
|
int ret = 0; |
||||||
|
uint8_t buffer[1]; |
||||||
|
|
||||||
|
ret = read_register(LSM6DS3_GYRO_I2C_REG_ID, buffer, 1); |
||||||
|
if(ret < 0){ |
||||||
|
LOGE("Reading chip ID failed: %d", ret); |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
if(buffer[0] != LSM6DS3_GYRO_CHIP_ID){ |
||||||
|
LOGE("Chip ID wrong. Got: %d, Expected %d", buffer[0], LSM6DS3_GYRO_CHIP_ID); |
||||||
|
ret = -1; |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
// TODO: set scale. Default is +- 250 deg/s
|
||||||
|
ret = set_register(LSM6DS3_GYRO_I2C_REG_CTRL2_G, LSM6DS3_GYRO_ODR_104HZ); |
||||||
|
if (ret < 0){ |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
fail: |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void LSM6DS3_Gyro::get_event(cereal::SensorEventData::Builder &event){ |
||||||
|
|
||||||
|
uint64_t start_time = nanos_since_boot(); |
||||||
|
uint8_t buffer[6]; |
||||||
|
int len = read_register(LSM6DS3_GYRO_I2C_REG_OUTX_L_G, buffer, sizeof(buffer)); |
||||||
|
assert(len == sizeof(buffer)); |
||||||
|
|
||||||
|
float scale = 250.0f / (1 << 15); |
||||||
|
float x = DEG2RAD(read_16_bit(buffer[0], buffer[1]) * scale); |
||||||
|
float y = DEG2RAD(read_16_bit(buffer[2], buffer[3]) * scale); |
||||||
|
float z = DEG2RAD(read_16_bit(buffer[4], buffer[5]) * scale); |
||||||
|
|
||||||
|
event.setSource(cereal::SensorEventData::SensorSource::LSM6DS3); |
||||||
|
event.setVersion(1); |
||||||
|
event.setSensor(SENSOR_GYRO_UNCALIBRATED); |
||||||
|
event.setType(SENSOR_TYPE_GYROSCOPE_UNCALIBRATED); |
||||||
|
event.setTimestamp(start_time); |
||||||
|
|
||||||
|
float xyz[] = {y, -x, z}; |
||||||
|
kj::ArrayPtr<const float> vs(&xyz[0], 3); |
||||||
|
|
||||||
|
auto svec = event.initAcceleration(); |
||||||
|
svec.setV(vs); |
||||||
|
svec.setStatus(true); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "sensors/i2c_sensor.hpp" |
||||||
|
|
||||||
|
// Address of the chip on the bus
|
||||||
|
#define LSM6DS3_GYRO_I2C_ADDR 0x6A |
||||||
|
|
||||||
|
// Registers of the chip
|
||||||
|
#define LSM6DS3_GYRO_I2C_REG_ID 0x0F |
||||||
|
#define LSM6DS3_GYRO_I2C_REG_CTRL2_G 0x11 |
||||||
|
#define LSM6DS3_GYRO_I2C_REG_OUTX_L_G 0x22 |
||||||
|
|
||||||
|
// Constants
|
||||||
|
#define LSM6DS3_GYRO_CHIP_ID 0x69 |
||||||
|
#define LSM6DS3_GYRO_ODR_104HZ (0b0100 << 4) |
||||||
|
|
||||||
|
|
||||||
|
class LSM6DS3_Gyro : public I2CSensor { |
||||||
|
uint8_t get_device_address() {return LSM6DS3_GYRO_I2C_ADDR;} |
||||||
|
public: |
||||||
|
LSM6DS3_Gyro(I2CBus *bus); |
||||||
|
int init(); |
||||||
|
void get_event(cereal::SensorEventData::Builder &event); |
||||||
|
}; |
@ -0,0 +1,45 @@ |
|||||||
|
#include <cassert> |
||||||
|
#include "common/swaglog.h" |
||||||
|
#include "common/timing.h" |
||||||
|
|
||||||
|
#include "lsm6ds3_temp.hpp" |
||||||
|
|
||||||
|
|
||||||
|
LSM6DS3_Temp::LSM6DS3_Temp(I2CBus *bus) : I2CSensor(bus) {} |
||||||
|
|
||||||
|
int LSM6DS3_Temp::init(){ |
||||||
|
int ret = 0; |
||||||
|
uint8_t buffer[1]; |
||||||
|
|
||||||
|
ret = read_register(LSM6DS3_TEMP_I2C_REG_ID, buffer, 1); |
||||||
|
if(ret < 0){ |
||||||
|
LOGE("Reading chip ID failed: %d", ret); |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
if(buffer[0] != LSM6DS3_TEMP_CHIP_ID){ |
||||||
|
LOGE("Chip ID wrong. Got: %d, Expected %d", buffer[0], LSM6DS3_TEMP_CHIP_ID); |
||||||
|
ret = -1; |
||||||
|
goto fail; |
||||||
|
} |
||||||
|
|
||||||
|
fail: |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void LSM6DS3_Temp::get_event(cereal::SensorEventData::Builder &event){ |
||||||
|
|
||||||
|
uint64_t start_time = nanos_since_boot(); |
||||||
|
uint8_t buffer[2]; |
||||||
|
int len = read_register(LSM6DS3_TEMP_I2C_REG_OUT_TEMP_L, buffer, sizeof(buffer)); |
||||||
|
assert(len == sizeof(buffer)); |
||||||
|
|
||||||
|
float temp = 25.0f + read_16_bit(buffer[0], buffer[1]) / 16.0f; |
||||||
|
|
||||||
|
event.setSource(cereal::SensorEventData::SensorSource::LSM6DS3); |
||||||
|
event.setVersion(1); |
||||||
|
event.setType(SENSOR_TYPE_AMBIENT_TEMPERATURE); |
||||||
|
event.setTimestamp(start_time); |
||||||
|
event.setTemperature(temp); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "sensors/i2c_sensor.hpp" |
||||||
|
|
||||||
|
// Address of the chip on the bus
|
||||||
|
#define LSM6DS3_TEMP_I2C_ADDR 0x6A |
||||||
|
|
||||||
|
// Registers of the chip
|
||||||
|
#define LSM6DS3_TEMP_I2C_REG_ID 0x0F |
||||||
|
#define LSM6DS3_TEMP_I2C_REG_OUT_TEMP_L 0x20 |
||||||
|
|
||||||
|
// Constants
|
||||||
|
#define LSM6DS3_TEMP_CHIP_ID 0x69 |
||||||
|
|
||||||
|
|
||||||
|
class LSM6DS3_Temp : public I2CSensor { |
||||||
|
uint8_t get_device_address() {return LSM6DS3_TEMP_I2C_ADDR;} |
||||||
|
public: |
||||||
|
LSM6DS3_Temp(I2CBus *bus); |
||||||
|
int init(); |
||||||
|
void get_event(cereal::SensorEventData::Builder &event); |
||||||
|
}; |
Loading…
Reference in new issue