powerpods/main/bosch456.h
simon 35b39fce46 Add configurable BMA456 tap detection profile in bosch456.h.
Centralize multitap tuning so sensitivity and timing can be adjusted without changing driver init logic.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 14:03:46 +02:00

90 lines
3.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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