Add UART ACCEL_READ command for on-demand BMA456 samples.

Expose MessageType 24 with protobuf response (success, x, y, z in raw LSB),
firmware handler with mutex-safe I2C read, goTool `accel` CLI, and docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-28 19:55:02 +02:00
co-authored by Cursor
parent 16c521f71c
commit ba20544762
16 changed files with 479 additions and 99 deletions
+45 -4
View File
@@ -14,6 +14,7 @@
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/idf_additions.h"
#include "freertos/semphr.h"
#include <rom/ets_sys.h>
#include <string.h>
@@ -34,6 +35,7 @@ static int16_t s_last_z;
static bool s_have_last_sample;
static volatile bool s_int_pending;
static SemaphoreHandle_t s_accel_mutex;
static esp_err_t check_bma4(const char *api_name, int8_t rslt);
@@ -121,6 +123,30 @@ void bma456_set_accel_deadzone(uint32_t deadzone_lsb) {
uint32_t bma456_get_accel_deadzone(void) { return s_accel_deadzone; }
esp_err_t bma456_read_accel(int16_t *x, int16_t *y, int16_t *z) {
if (!s_bma456_ready || x == NULL || y == NULL || z == NULL) {
return ESP_ERR_INVALID_STATE;
}
if (s_accel_mutex == NULL ||
xSemaphoreTake(s_accel_mutex, pdMS_TO_TICKS(500)) != pdTRUE) {
return ESP_ERR_TIMEOUT;
}
struct bma4_accel sens_data = {0};
int8_t ret = bma4_read_accel_xyz(&sens_data, &s_bma456);
xSemaphoreGive(s_accel_mutex);
if (ret != BMA4_OK) {
bma4_error_codes_print_result("bma4_read_accel_xyz", ret);
return ESP_FAIL;
}
*x = sens_data.x;
*y = sens_data.y;
*z = sens_data.z;
return ESP_OK;
}
void bma456_report_accel_if_changed(int16_t x, int16_t y, int16_t z) {
if (!s_bma456_ready || !sample_exceeds_deadzone(x, y, z)) {
return;
@@ -187,11 +213,19 @@ static void read_sensor_task(void *param) {
struct bma4_accel sens_data = {0};
while (1) {
int8_t ret = bma4_read_accel_xyz(&sens_data, &s_bma456);
if (ret == BMA4_OK) {
bool got_sample = false;
if (s_accel_mutex != NULL &&
xSemaphoreTake(s_accel_mutex, pdMS_TO_TICKS(500)) == pdTRUE) {
int8_t ret = bma4_read_accel_xyz(&sens_data, &s_bma456);
xSemaphoreGive(s_accel_mutex);
if (ret == BMA4_OK) {
got_sample = true;
} else {
bma4_error_codes_print_result("bma4_read_accel_xyz", ret);
}
}
if (got_sample) {
bma456_report_accel_if_changed(sens_data.x, sens_data.y, sens_data.z);
} else {
bma4_error_codes_print_result("bma4_read_accel_xyz", ret);
}
if (s_int_pending) {
@@ -343,6 +377,13 @@ esp_err_t init_bma456(i2c_master_bus_handle_t bus_handle) {
goto fail;
}
if (s_accel_mutex == NULL) {
s_accel_mutex = xSemaphoreCreateMutex();
if (s_accel_mutex == NULL) {
goto fail;
}
}
if (xTaskCreate(read_sensor_task, "bma456_poll", 4096, NULL, 1, NULL) !=
pdPASS) {
goto fail;