Centralize multitap tuning so sensitivity and timing can be adjusted without changing driver init logic. Co-authored-by: Cursor <cursoragent@cursor.com>
90 lines
3.2 KiB
C
90 lines
3.2 KiB
C
#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 <stdbool.h>
|
||
#include <stdint.h>
|
||
|
||
/** 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
|