From dd054efe8d6dc40a22dc7c7be26ba6eebbdca02b Mon Sep 17 00:00:00 2001 From: David Volovskiy Date: Sun, 16 Nov 2025 16:05:22 -0500 Subject: [PATCH] Added LIR latching on LIS2DW --- movement.c | 3 ++- watch-library/shared/driver/lis2dw.c | 31 ++++++++++++++++++++++++++-- watch-library/shared/driver/lis2dw.h | 14 +++++++++++-- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/movement.c b/movement.c index 345dcb34..a3a61233 100644 --- a/movement.c +++ b/movement.c @@ -816,6 +816,7 @@ bool movement_enable_tap_detection_if_available(void) { lis2dw_set_data_rate(LIS2DW_DATA_RATE_HP_400_HZ); lis2dw_set_mode(LIS2DW_MODE_LOW_POWER); lis2dw_enable_double_tap(); + lis2dw12_int_notification_set(LIS2DW12_INT_LATCHED); // Settling time (1 sample duration, i.e. 1/400Hz) delay_ms(3); @@ -836,6 +837,7 @@ bool movement_disable_tap_detection_if_available(void) { lis2dw_set_data_rate(movement_state.accelerometer_background_rate); lis2dw_set_mode(LIS2DW_MODE_LOW_POWER); lis2dw_disable_double_tap(); + lis2dw12_int_notification_set(LIS2DW12_INT_PULSED); // ...disable Z axis (not sure if this is needed, does this save power?)... lis2dw_configure_tap_threshold(0, 0, 0, 0); @@ -1118,7 +1120,6 @@ void app_setup(void) { watch_register_interrupt_callback(HAL_GPIO_A3_pin(), cb_accelerometer_event, INTERRUPT_TRIGGER_RISING); // Enable the interrupts... - lis2dw_latched_interrupts(); lis2dw_enable_interrupts(); // At first boot, this next line sets the accelerometer's sampling rate to 0, which is LIS2DW_DATA_RATE_POWERDOWN. diff --git a/watch-library/shared/driver/lis2dw.c b/watch-library/shared/driver/lis2dw.c index 6e3cb59a..339af08d 100644 --- a/watch-library/shared/driver/lis2dw.c +++ b/watch-library/shared/driver/lis2dw.c @@ -411,6 +411,33 @@ void lis2dw_configure_int2(uint8_t sources) { #endif } +void lis2dw12_int_notification_set(lis2dw12_lir_t val) { +#ifdef I2C_SERCOM + uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL3); + if (val == LIS2DW12_INT_LATCHED) { + configuration |= LIS2DW_CTRL3_VAL_LIR; + } else { + configuration &= ~LIS2DW_CTRL7_VAL_DRDY_PULSED; + } + watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL3, configuration); +#else + (void)val; +#endif +} + +lis2dw12_lir_t lis2dw12_int_notification_get(void) { +#ifdef I2C_SERCOM + uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL3); + if (configuration & LIS2DW12_INT_LATCHED) { + return LIS2DW12_INT_LATCHED; + } else { + return LIS2DW12_INT_PULSED; + } +#else + return LIS2DW12_INT_PULSED; +#endif +} + void lis2dw_enable_interrupts(void) { #ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7); @@ -425,14 +452,14 @@ void lis2dw_disable_interrupts(void) { #endif } -void lis2dw_pulsed_interrupts(void) { +void lis2dw_pulsed_drdy_interrupts(void) { #ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7, configuration | LIS2DW_CTRL7_VAL_DRDY_PULSED); #endif } -void lis2dw_latched_interrupts(void) { +void lis2dw_latched_drdy_interrupts(void) { #ifdef I2C_SERCOM uint8_t configuration = watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7); watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7, configuration & ~LIS2DW_CTRL7_VAL_DRDY_PULSED); diff --git a/watch-library/shared/driver/lis2dw.h b/watch-library/shared/driver/lis2dw.h index 2db57da1..f7b0a801 100644 --- a/watch-library/shared/driver/lis2dw.h +++ b/watch-library/shared/driver/lis2dw.h @@ -92,6 +92,12 @@ typedef enum { LIS2DW_FILTER_HIGH_PASS = 1, } lis2dw_filter_t; +typedef enum +{ + LIS2DW12_INT_PULSED = 0, + LIS2DW12_INT_LATCHED = 1, +} lis2dw12_lir_t; + typedef enum { LIS2DW_RANGE_16_G = 0b11, // +/- 16g LIS2DW_RANGE_8_G = 0b10, // +/- 8g @@ -367,6 +373,10 @@ void lis2dw_configure_tap_threshold(uint8_t threshold_x, uint8_t threshold_y, ui void lis2dw_configure_tap_duration(uint8_t latency, uint8_t quiet, uint8_t shock); +void lis2dw12_int_notification_set(lis2dw12_lir_t val); + +lis2dw12_lir_t lis2dw12_int_notification_get(void); + void lis2dw_configure_int1(uint8_t sources); void lis2dw_configure_int2(uint8_t sources); @@ -375,9 +385,9 @@ void lis2dw_enable_interrupts(void); void lis2dw_disable_interrupts(void); -void lis2dw_pulsed_interrupts(void); +void lis2dw_pulsed_drdy_interrupts(void); -void lis2dw_latched_interrupts(void); +void lis2dw_latched_drdy_interrupts(void); lis2dw_interrupt_source_t lis2dw_get_interrupt_source(void);