LSM6DS3 (#2268)
* add initial lsm6ds3 setup * accel works * ignore lsm6ds3 in locationd * add gyro * add temp Co-authored-by: Comma Device <device@comma.ai>pull/2276/head
parent
a09fd7c860
commit
e51da619c1
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