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
+56 -6
View File
@@ -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;
}
+9 -3
View File
@@ -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