harden sensor acquisition after audit

This commit is contained in:
Jay
2026-08-17 09:48:05 -04:00
parent f1ac20fb4f
commit b8fe233ba6
11 changed files with 376 additions and 50 deletions
+9 -3
View File
@@ -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
+40 -6
View File
@@ -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;
}