harden sensor acquisition after audit
This commit is contained in:
@@ -3,10 +3,16 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#define ADXL345_REG_DEVID 0x00
|
||||
#define ADXL345_REG_OFSX 0x1E
|
||||
#define ADXL345_REG_OFSY 0x1F
|
||||
#define ADXL345_REG_OFSZ 0x20
|
||||
#define ADXL345_REG_BW_RATE 0x2C
|
||||
#define ADXL345_REG_POWER_CTL 0x2D
|
||||
#define ADXL345_REG_INT_ENABLE 0x2E
|
||||
#define ADXL345_REG_INT_SOURCE 0x30
|
||||
#define ADXL345_REG_DATA_FORMAT 0x31
|
||||
#define ADXL345_REG_DATAX0 0x32
|
||||
#define ADXL345_REG_FIFO_CTL 0x38
|
||||
|
||||
#define ADXL345_DEVID_VALUE 0xE5
|
||||
#define ADXL345_BW_RATE_100_HZ 0x0A
|
||||
@@ -46,7 +52,8 @@ esp_err_t adxl345_init(adxl345_t *sensor, i2c_master_bus_handle_t bus, uint32_t
|
||||
*sensor = (adxl345_t){0};
|
||||
static const uint8_t candidate_addresses[] = {0x53, 0x1D};
|
||||
|
||||
for (size_t i = 0; i < sizeof(candidate_addresses); ++i) {
|
||||
for (size_t i = 0;
|
||||
i < sizeof(candidate_addresses) / sizeof(candidate_addresses[0]); ++i) {
|
||||
const i2c_device_config_t config = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = candidate_addresses[i],
|
||||
@@ -74,8 +81,24 @@ esp_err_t adxl345_init(adxl345_t *sensor, i2c_master_bus_handle_t bus, uint32_t
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
// Configure while in standby, then enter measurement mode.
|
||||
// The ADXL345 is not reset by an ESP32 warm reboot. Establish every state
|
||||
// that could otherwise survive from an earlier firmware run.
|
||||
esp_err_t err = write_register(sensor->device, ADXL345_REG_POWER_CTL, 0x00);
|
||||
if (err == ESP_OK) {
|
||||
err = write_register(sensor->device, ADXL345_REG_INT_ENABLE, 0x00);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
err = write_register(sensor->device, ADXL345_REG_FIFO_CTL, 0x00);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
err = write_register(sensor->device, ADXL345_REG_OFSX, 0x00);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
err = write_register(sensor->device, ADXL345_REG_OFSY, 0x00);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
err = write_register(sensor->device, ADXL345_REG_OFSZ, 0x00);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
err = write_register(sensor->device, ADXL345_REG_DATA_FORMAT, ADXL345_FORMAT_FULL_8G);
|
||||
}
|
||||
@@ -95,17 +118,45 @@ esp_err_t adxl345_init(adxl345_t *sensor, i2c_master_bus_handle_t bus, uint32_t
|
||||
err = verify_register(sensor->device, ADXL345_REG_POWER_CTL, ADXL345_POWER_MEASURE);
|
||||
}
|
||||
|
||||
if (err != ESP_OK) {
|
||||
adxl345_deinit(sensor);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t adxl345_read_raw(const adxl345_t *sensor, adxl345_sample_t *sample)
|
||||
esp_err_t adxl345_deinit(adxl345_t *sensor)
|
||||
{
|
||||
if (sensor == NULL || sensor->device == NULL || sample == NULL) {
|
||||
if (sensor == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (sensor->device == NULL) {
|
||||
sensor->address = 0;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t err = i2c_master_bus_rm_device(sensor->device);
|
||||
if (err == ESP_OK) {
|
||||
*sensor = (adxl345_t){0};
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t adxl345_read_raw(const adxl345_t *sensor, adxl345_sample_t *sample,
|
||||
uint8_t *interrupt_source)
|
||||
{
|
||||
if (sensor == NULL || sensor->device == NULL || sample == NULL ||
|
||||
interrupt_source == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t err = read_registers(sensor->device, ADXL345_REG_INT_SOURCE,
|
||||
interrupt_source, 1);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
uint8_t data[6] = {0};
|
||||
esp_err_t err = read_registers(sensor->device, ADXL345_REG_DATAX0, data, sizeof(data));
|
||||
err = read_registers(sensor->device, ADXL345_REG_DATAX0, data, sizeof(data));
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
@@ -120,4 +171,3 @@ uint8_t adxl345_address(const adxl345_t *sensor)
|
||||
{
|
||||
return sensor != NULL ? sensor->address : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,15 +20,21 @@ typedef struct {
|
||||
int16_t z;
|
||||
} adxl345_sample_t;
|
||||
|
||||
#define ADXL345_INT_SOURCE_DATA_READY 0x80
|
||||
#define ADXL345_INT_SOURCE_OVERRUN 0x01
|
||||
|
||||
/** Detect, identify, and configure an ADXL345 for 100 Hz, full-resolution +/-8 g. */
|
||||
esp_err_t adxl345_init(adxl345_t *sensor, i2c_master_bus_handle_t bus, uint32_t bus_speed_hz);
|
||||
|
||||
/** Read one sensor-native, uncalibrated XYZ sample. */
|
||||
esp_err_t adxl345_read_raw(const adxl345_t *sensor, adxl345_sample_t *sample);
|
||||
/** Remove the sensor from its I2C bus. Safe to call on an uninitialized handle. */
|
||||
esp_err_t adxl345_deinit(adxl345_t *sensor);
|
||||
|
||||
/** Read INT_SOURCE followed by one sensor-native, uncalibrated XYZ sample. */
|
||||
esp_err_t adxl345_read_raw(const adxl345_t *sensor, adxl345_sample_t *sample,
|
||||
uint8_t *interrupt_source);
|
||||
|
||||
uint8_t adxl345_address(const adxl345_t *sensor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -20,15 +20,21 @@ typedef struct {
|
||||
int16_t z;
|
||||
} l3g4200d_sample_t;
|
||||
|
||||
#define L3G4200D_STATUS_ZYXDA 0x08
|
||||
#define L3G4200D_STATUS_ZYXOR 0x80
|
||||
|
||||
/** Detect, identify, and configure an L3G4200D for 100 Hz, 25 Hz BW, +/-500 dps. */
|
||||
esp_err_t l3g4200d_init(l3g4200d_t *sensor, i2c_master_bus_handle_t bus, uint32_t bus_speed_hz);
|
||||
|
||||
/** Read one sensor-native, uncalibrated XYZ sample. */
|
||||
esp_err_t l3g4200d_read_raw(const l3g4200d_t *sensor, l3g4200d_sample_t *sample);
|
||||
/** Remove the sensor from its I2C bus. Safe to call on an uninitialized handle. */
|
||||
esp_err_t l3g4200d_deinit(l3g4200d_t *sensor);
|
||||
|
||||
/** Read STATUS_REG followed by one sensor-native, uncalibrated XYZ sample. */
|
||||
esp_err_t l3g4200d_read_raw(const l3g4200d_t *sensor, l3g4200d_sample_t *sample,
|
||||
uint8_t *status);
|
||||
|
||||
uint8_t l3g4200d_address(const l3g4200d_t *sensor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
#define L3G4200D_REG_CTRL3 0x22
|
||||
#define L3G4200D_REG_CTRL4 0x23
|
||||
#define L3G4200D_REG_CTRL5 0x24
|
||||
#define L3G4200D_REG_STATUS 0x27
|
||||
#define L3G4200D_REG_OUT_X_L 0x28
|
||||
|
||||
#define L3G4200D_WHO_AM_I_VALUE 0xD3
|
||||
#define L3G4200D_CTRL1_100_HZ 0x1F
|
||||
#define L3G4200D_CTRL4_500_DPS 0x90
|
||||
#define L3G4200D_CTRL5_LPF2_OUT 0x02
|
||||
#define L3G4200D_AUTO_INCREMENT 0x80
|
||||
#define L3G4200D_TIMEOUT_MS 100
|
||||
|
||||
@@ -48,7 +50,8 @@ esp_err_t l3g4200d_init(l3g4200d_t *sensor, i2c_master_bus_handle_t bus, uint32_
|
||||
*sensor = (l3g4200d_t){0};
|
||||
static const uint8_t candidate_addresses[] = {0x69, 0x68};
|
||||
|
||||
for (size_t i = 0; i < sizeof(candidate_addresses); ++i) {
|
||||
for (size_t i = 0;
|
||||
i < sizeof(candidate_addresses) / sizeof(candidate_addresses[0]); ++i) {
|
||||
const i2c_device_config_t config = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = candidate_addresses[i],
|
||||
@@ -89,7 +92,9 @@ esp_err_t l3g4200d_init(l3g4200d_t *sensor, i2c_master_bus_handle_t bus, uint32_
|
||||
err = write_register(sensor->device, L3G4200D_REG_CTRL4, L3G4200D_CTRL4_500_DPS);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
err = write_register(sensor->device, L3G4200D_REG_CTRL5, 0x00);
|
||||
// Route LPF2 to the output. CTRL1 BW=01 selects its 25 Hz cutoff.
|
||||
err = write_register(sensor->device, L3G4200D_REG_CTRL5,
|
||||
L3G4200D_CTRL5_LPF2_OUT);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
// 100 Hz ODR, 25 Hz bandwidth, normal mode, all axes enabled.
|
||||
@@ -101,19 +106,49 @@ esp_err_t l3g4200d_init(l3g4200d_t *sensor, i2c_master_bus_handle_t bus, uint32_
|
||||
if (err == ESP_OK) {
|
||||
err = verify_register(sensor->device, L3G4200D_REG_CTRL4, L3G4200D_CTRL4_500_DPS);
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
err = verify_register(sensor->device, L3G4200D_REG_CTRL5,
|
||||
L3G4200D_CTRL5_LPF2_OUT);
|
||||
}
|
||||
|
||||
if (err != ESP_OK) {
|
||||
l3g4200d_deinit(sensor);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t l3g4200d_read_raw(const l3g4200d_t *sensor, l3g4200d_sample_t *sample)
|
||||
esp_err_t l3g4200d_deinit(l3g4200d_t *sensor)
|
||||
{
|
||||
if (sensor == NULL || sensor->device == NULL || sample == NULL) {
|
||||
if (sensor == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (sensor->device == NULL) {
|
||||
sensor->address = 0;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t err = i2c_master_bus_rm_device(sensor->device);
|
||||
if (err == ESP_OK) {
|
||||
*sensor = (l3g4200d_t){0};
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t l3g4200d_read_raw(const l3g4200d_t *sensor, l3g4200d_sample_t *sample,
|
||||
uint8_t *status)
|
||||
{
|
||||
if (sensor == NULL || sensor->device == NULL || sample == NULL || status == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t err = read_registers(sensor->device, L3G4200D_REG_STATUS, status, 1);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
uint8_t data[6] = {0};
|
||||
uint8_t start_register = L3G4200D_REG_OUT_X_L | L3G4200D_AUTO_INCREMENT;
|
||||
esp_err_t err = read_registers(sensor->device, start_register, data, sizeof(data));
|
||||
err = read_registers(sensor->device, start_register, data, sizeof(data));
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
@@ -128,4 +163,3 @@ uint8_t l3g4200d_address(const l3g4200d_t *sensor)
|
||||
{
|
||||
return sensor != NULL ? sensor->address : 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user