#ifndef BOSCH456_H #define BOSCH456_H /** * Powerpod driver for Bosch BMA456H (hearable variant) on the shared I2C bus. * * Vendor API: components/bma456 (bma4.c + bma456h.c only). * Implementation: bosch456.c */ #include "driver/i2c_types.h" #include "esp_err.h" #include #include /** 7-bit I2C address (SDO low). */ #define BMA456_I2C_ADDR 0x18 /** Sensor interrupt line → ESP32 GPIO (active high, rising edge). */ #define BMA456_INT_GPIO 10 /** Software filter: log accel only when |axis - last| > deadzone (raw LSB). */ #define BMA456_DEFAULT_ACCEL_DEADZONE 100u /** * BMA456H multitap tuning (see BST-BMA456-AN000). * * Time fields use register units: value × 5 ms (e.g. 100 → 500 ms). * tap_sens_thres: 0 = most sensitive … 15 = least (~78 mg per LSB). * axis_sel: 0 = X, 1 = Y, 2 = Z. * wait_for_timeout: 0 = report immediately, 1 = wait max_gest_dur for classification. */ typedef struct { uint16_t tap_sens_thres; uint16_t max_gest_dur; uint16_t tap_shock_dur; uint16_t quite_time_after_gest; uint16_t wait_for_timeout; uint16_t axis_sel; bool enable_single; bool enable_double; bool enable_triple; } bma456_tap_config_t; /** Edit these values to tune tap detection, then rebuild. */ #define BMA456_TAP_CONFIG_DEFAULT \ { \ .tap_sens_thres = 5, /* sensitive; 0=max, Bosch default=9 */ \ .max_gest_dur = 100, /* 500 ms window for double/triple */ \ .tap_shock_dur = 6, /* 30 ms debounce after each impulse */ \ .quite_time_after_gest = 60, /* 300 ms min gap between gestures */ \ .wait_for_timeout = 0, /* 0 = faster single-tap response */ \ .axis_sel = 2, /* Z axis */ \ .enable_single = true, \ .enable_double = true, \ .enable_triple = true, \ } /** * Probe and configure the sensor on bus_handle (100 kHz device). * On failure the device is removed and ESP_ERR_NOT_FOUND / ESP_FAIL is returned; * firmware continues without a sensor (see bma456_is_ready()). */ esp_err_t init_bma456(i2c_master_bus_handle_t bus_handle); bool bma456_is_ready(void); void bma456_set_accel_deadzone(uint32_t deadzone_lsb); uint32_t bma456_get_accel_deadzone(void); /** Log accel when any axis moved more than deadzone since last reported sample. */ void bma456_report_accel_if_changed(int16_t x, int16_t y, int16_t z); /** Tap kinds from BMA456H multitap output. */ typedef enum { BMA456_TAP_SINGLE = 1, BMA456_TAP_DOUBLE = 2, BMA456_TAP_TRIPLE = 3, } bma456_tap_kind_t; typedef void (*bma456_tap_handler_t)(bma456_tap_kind_t kind, void *ctx); /** Optional callback invoked from sensor task on tap interrupt (may be NULL). */ void bma456_set_tap_handler(bma456_tap_handler_t handler, void *ctx); /** On-demand read of current accel XYZ (raw LSB). Returns ESP_ERR_INVALID_STATE if sensor not ready. */ esp_err_t bma456_read_accel(int16_t *x, int16_t *y, int16_t *z); #endif