]> git.earman.xyz Git - sensor-watch.git/commitdiff
auto-detect accelerometer sensor (and don't fail build for lack of a temperature...
authorJoey Castillo <joeycastillo@utexas.edu>
Fri, 16 May 2025 04:07:15 +0000 (00:07 -0400)
committerJoey Castillo <joeycastillo@utexas.edu>
Fri, 16 May 2025 04:07:15 +0000 (00:07 -0400)
12 files changed:
Makefile
movement.c
movement.h
movement_activity.c
movement_activity.h
watch-faces/complication/countdown_face.c
watch-faces/demo/accel_interrupt_count_face.c
watch-faces/demo/accel_interrupt_count_face.h
watch-faces/sensor/activity_logging_face.c
watch-faces/sensor/activity_logging_face.h
watch-library/shared/driver/thermistor_driver.c
watch-library/shared/driver/thermistor_driver.h

index 38f89736a784605cc544d81723c358eda564f8b5..7e8d2751879cf263d21e85a5572115c50eddade3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -32,10 +32,6 @@ ifndef BOARD
 $(error Build failed: BOARD not defined. Use one of the four options below, depending on your hardware:$n$n    make BOARD=sensorwatch_red$n    make BOARD=sensorwatch_green$n    make BOARD=sensorwatch_blue$n    make BOARD=sensorwatch_pro$n$n)
 endif
 
-ifeq ($(SENSOR), MOTION)
-  DEFINES += -DHAS_ACCELEROMETER
-endif
-
 ifeq ($(SENSOR), TEMPERATURE)
   DEFINES += -DTEMPERATURE_BOARD_INSTALLED
 endif
@@ -99,9 +95,7 @@ SRCS += \
   ./watch-library/shared/watch/watch_utility.c \
 
 
-ifeq ($(SENSOR), MOTION)
 SRCS += ./watch-library/shared/driver/lis2dw.c
-endif
 
 ifdef EMSCRIPTEN
 
index c35798364237d3d77dc2a759deb55ed699f5d3c5..2d2edae16165ce497971c79101d8843805dffcb1 100644 (file)
@@ -74,11 +74,9 @@ void cb_alarm_fired(void);
 void cb_fast_tick(void);
 void cb_tick(void);
 
-#ifdef HAS_ACCELEROMETER
 void cb_accelerometer_event(void);
 void cb_accelerometer_wake(void);
 uint8_t active_minutes = 0;
-#endif
 
 #if __EMSCRIPTEN__
 void yield(void) {
@@ -156,17 +154,17 @@ static inline void _movement_disable_fast_tick_if_possible(void) {
 static void _movement_handle_top_of_minute(void) {
     watch_date_time_t date_time = watch_rtc_get_date_time();
 
-#ifdef HAS_ACCELEROMETER
-    bool accelerometer_is_alseep = HAL_GPIO_A4_read();
-    if (!accelerometer_is_alseep) active_minutes++;
-    printf("Active minutes: %d\n", active_minutes);
+    if (movement_state.has_lis2dw) {
+        bool accelerometer_is_alseep = HAL_GPIO_A4_read();
+        if (!accelerometer_is_alseep) active_minutes++;
+        printf("Active minutes: %d\n", active_minutes);
 
-    // log data every five minutes, and reset the active_minutes count.
-    if ((date_time.unit.minute % 5) == 0) {
-        _movement_log_data();
-        active_minutes = 0;
+        // log data every five minutes, and reset the active_minutes count.
+        if ((date_time.unit.minute % 5) == 0) {
+            _movement_log_data();
+            active_minutes = 0;
+        }
     }
-#endif
 
     // update the DST offset cache every 30 minutes, since someplace in the world could change.
     if (date_time.unit.minute % 30 == 0) {
@@ -519,38 +517,46 @@ void movement_set_alarm_enabled(bool value) {
     movement_state.alarm_enabled = value;
 }
 
-void movement_enable_tap_detection_if_available(void) {
-#ifdef HAS_ACCELEROMETER
-    // configure tap duration threshold and enable Z axis
-    lis2dw_configure_tap_threshold(0, 0, 12, LIS2DW_REG_TAP_THS_Z_Z_AXIS_ENABLE);
-    lis2dw_configure_tap_duration(10, 2, 2);
+bool movement_enable_tap_detection_if_available(void) {
+    if (movement_state.has_lis2dw) {
+        // configure tap duration threshold and enable Z axis
+        lis2dw_configure_tap_threshold(0, 0, 12, LIS2DW_REG_TAP_THS_Z_Z_AXIS_ENABLE);
+        lis2dw_configure_tap_duration(10, 2, 2);
 
-    // ramp data rate up to 400 Hz and high performance mode
-    lis2dw_set_low_noise_mode(true);
-    lis2dw_set_data_rate(LIS2DW_DATA_RATE_HP_400_HZ);
-    lis2dw_set_mode(LIS2DW_MODE_HIGH_PERFORMANCE);
+        // ramp data rate up to 400 Hz and high performance mode
+        lis2dw_set_low_noise_mode(true);
+        lis2dw_set_data_rate(LIS2DW_DATA_RATE_HP_400_HZ);
+        lis2dw_set_mode(LIS2DW_MODE_HIGH_PERFORMANCE);
 
-    // Settling time (1 sample duration, i.e. 1/400Hz)
-    delay_ms(3);
+        // Settling time (1 sample duration, i.e. 1/400Hz)
+        delay_ms(3);
 
-    // enable tap detection on INT1/A3.
-    lis2dw_configure_int1(LIS2DW_CTRL4_INT1_SINGLE_TAP | LIS2DW_CTRL4_INT1_6D);
-    // and enable the cb_accelerometer_event interrupt callback, so we can catch tap events.
-    watch_register_interrupt_callback(HAL_GPIO_A3_pin(), cb_accelerometer_event, INTERRUPT_TRIGGER_RISING);
-#endif
+        // enable tap detection on INT1/A3.
+        lis2dw_configure_int1(LIS2DW_CTRL4_INT1_SINGLE_TAP | LIS2DW_CTRL4_INT1_6D);
+        // and enable the cb_accelerometer_event interrupt callback, so we can catch tap events.
+        watch_register_interrupt_callback(HAL_GPIO_A3_pin(), cb_accelerometer_event, INTERRUPT_TRIGGER_RISING);
+
+        return true;
+    }
+
+    return false;
 }
 
-void movement_disable_tap_detection_if_available(void) {
-#ifdef HAS_ACCELEROMETER
-    // Ramp data rate back down to the usual lowest rate to save power.
-    lis2dw_set_low_noise_mode(false);
-    lis2dw_set_data_rate(LIS2DW_DATA_RATE_LOWEST);
-    lis2dw_set_mode(LIS2DW_MODE_LOW_POWER);
-    // disable the interrupt on INT1/A3...
-    eic_disable_interrupt(HAL_GPIO_A3_pin());
-    // ...disable Z axis (not sure if this is needed, does this save power?)...
-    lis2dw_configure_tap_threshold(0, 0, 0, 0);
-#endif
+bool movement_disable_tap_detection_if_available(void) {
+    if (movement_state.has_lis2dw) {
+        // Ramp data rate back down to the usual lowest rate to save power.
+        lis2dw_set_low_noise_mode(false);
+        lis2dw_set_data_rate(LIS2DW_DATA_RATE_LOWEST);
+        lis2dw_set_mode(LIS2DW_MODE_LOW_POWER);
+        // disable the interrupt on INT1/A3...
+        eic_disable_interrupt(HAL_GPIO_A3_pin());
+        // ...disable Z axis (not sure if this is needed, does this save power?)...
+        lis2dw_configure_tap_threshold(0, 0, 0, 0);
+
+        return true;
+    }
+
+    return false;
 }
 
 void app_init(void) {
@@ -679,16 +685,11 @@ void app_setup(void) {
         watch_register_interrupt_callback(HAL_GPIO_BTN_LIGHT_pin(), cb_light_btn_interrupt, INTERRUPT_TRIGGER_BOTH);
         watch_register_interrupt_callback(HAL_GPIO_BTN_ALARM_pin(), cb_alarm_btn_interrupt, INTERRUPT_TRIGGER_BOTH);
 
-#ifdef HAS_ACCELEROMETER
-// gossamer doesn't include all the chip-specific constants, so we have to fake them here.
-#ifndef EVSYS_ID_GEN_EIC_EXTINT_3
-#define EVSYS_ID_GEN_EIC_EXTINT_3 18
-#endif
-#ifndef EVSYS_ID_USER_TC2_EVU
-#define EVSYS_ID_USER_TC2_EVU 17
-#endif
+#ifdef I2C_SERCOM
         watch_enable_i2c();
         if (lis2dw_begin()) {
+            movement_state.has_lis2dw = true;
+
             lis2dw_set_mode(LIS2DW_MODE_LOW_POWER);         // select low power (not high performance) mode
             lis2dw_set_low_power_mode(LIS2DW_LP_MODE_1);    // lowest power mode, 12-bit
             lis2dw_set_low_noise_mode(false);               // low noise mode raises power consumption slightly; we don't need it
@@ -717,6 +718,8 @@ void app_setup(void) {
             // watch_register_extwake_callback(HAL_GPIO_A4_pin(), cb_accelerometer_wake, false);
 
             lis2dw_enable_interrupts();
+        } else {
+            watch_disable_i2c();
         }
 #endif
 
@@ -984,7 +987,6 @@ void cb_tick(void) {
     }
 }
 
-#ifdef HAS_ACCELEROMETER
 void cb_accelerometer_event(void) {
     uint8_t int_src = lis2dw_get_interrupt_source();
 
@@ -1003,5 +1005,3 @@ void cb_accelerometer_wake(void) {
     // also: wake up!
     _movement_reset_inactivity_countdown();
 }
-
-#endif
index a0a12c2ce48e9a187c90072bda975770c4dd2af2..b7d52eb570d27bec114dd731de1dc128aa9eafce 100644 (file)
@@ -286,6 +286,9 @@ typedef struct {
 
     // temporary alarm enabled boolean, until we implement this in advisories
     bool alarm_enabled;
+
+    // boolean set if accelerometer is detected
+    bool has_lis2dw;
 } movement_state_t;
 
 void movement_move_to_face(uint8_t watch_face_index);
@@ -362,5 +365,5 @@ bool movement_alarm_enabled(void);
 void movement_set_alarm_enabled(bool value);
 
 // if the board has an accelerometer, these functions will enable or disable tap detection.
-void movement_enable_tap_detection_if_available(void);
-void movement_disable_tap_detection_if_available(void);
+bool movement_enable_tap_detection_if_available(void);
+bool movement_disable_tap_detection_if_available(void);
index f5c20ec770f179315022dc8aae6ae0761d2b3824..fe91e29a7b242da40d3d48a3245b27d8a4d58657 100644 (file)
@@ -27,8 +27,6 @@
 #include "tc.h"
 #include "thermistor_driver.h"
 
-#ifdef HAS_ACCELEROMETER
-
 // RAM to stash the data points.
 movement_activity_data_point movement_activity_log[MOVEMENT_NUM_DATA_POINTS] = {0};
 // the absolute number of data points logged
@@ -74,5 +72,3 @@ movement_activity_data_point *movement_get_data_log(uint32_t *count) {
     *count = data_points;
     return movement_activity_log;
 }
-
-#endif
index 358e66265ca4f3a31245c2cf9ad19c44c54a9399..f1b256fff7adec4efc2401021687020985e028e3 100644 (file)
@@ -24,8 +24,6 @@
 
 #pragma once
 
-#ifdef HAS_ACCELEROMETER
-
 #include <stdint.h>
 
 // Log 36 hours of data points. Each data point captures 5 minutes.
@@ -48,5 +46,3 @@ void _movement_log_data(void);
 /// @param count is a pointer to a uint32_t. The absolute number of data points logged is returned by reference.
 /// You can assume that log[count % MOVEMENT_NUM_DATA_POINTS] is the latest data point, and work backwards from there.
 movement_activity_data_point *movement_get_data_log(uint32_t *count);
-
-#endif
\ No newline at end of file
index 95a7b40d6dfa2b756224ef070f2c5608e48e223b..5314acead40042f43701a289e51b25caa0f0ec7d 100644 (file)
@@ -218,13 +218,10 @@ void countdown_face_activate(void *context) {
 
     movement_request_tick_frequency(1);
     quick_ticks_running = false;
-#if HAS_ACCELEROMETER
-    if (state->mode != cd_running) {
+    if (state->mode != cd_running && movement_enable_tap_detection_if_available()) {
         state->tap_detection_ticks = TAP_DETECTION_SECONDS;
         state->has_tapped_once = false;
-        movement_enable_tap_detection_if_available();
     }
-#endif
 }
 
 bool countdown_face_loop(movement_event_t event, void *context) {
index 32b99255595430d138c03eaebc25dba3e88b7a27..dc9b5df10af600beecbf2dc63289e8e93f4edd3d 100644 (file)
@@ -29,8 +29,6 @@
 #include "tc.h"
 #include "watch.h"
 
-#ifdef HAS_ACCELEROMETER
-
 // hacky: we're just tapping into Movement's global state.
 // we should make better API for this.
 extern uint8_t active_minutes;
@@ -133,5 +131,3 @@ movement_watch_face_advisory_t accel_interrupt_count_face_advise(void *context)
 
     return retval;
 }
-
-#endif // HAS_ACCELEROMETER
index 70b03ddabc80a5b9b96f583d3fce373a45a7ec7d..3361976c06c80231c4c2c712268a49b88440a443 100644 (file)
@@ -35,8 +35,6 @@
 #include "movement.h"
 #include "watch.h"
 
-#ifdef HAS_ACCELEROMETER
-
 typedef struct {
     uint8_t new_threshold;
     uint8_t threshold;
@@ -56,5 +54,3 @@ movement_watch_face_advisory_t accel_interrupt_count_face_advise(void *context);
     accel_interrupt_count_face_resign, \
     accel_interrupt_count_face_advise, \
 })
-
-#endif // HAS_ACCELEROMETER
index 984d9a098e207df241962d51501b43c824b4609b..e6b586ae3c943f50c2930d3eb87097b49a5d78c6 100644 (file)
@@ -30,8 +30,6 @@
 #include "movement_activity.h"
 #include "watch_utility.h"
 
-#ifdef HAS_ACCELEROMETER
-
 static void _activity_logging_face_update_display(activity_logging_state_t *state, bool clock_mode_24h) {
     char buf[8];
     uint32_t count = 0;
@@ -164,5 +162,3 @@ bool activity_logging_face_loop(movement_event_t event, void *context) {
 void activity_logging_face_resign(void *context) {
     (void) context;
 }
-
-#endif
index 0a0e3726b6bbd135d4814054afb6766c784e7412..c2f3fcc686ff40ba9047790bb3cc015b594ae62c 100644 (file)
@@ -26,8 +26,6 @@
 
 #include "pins.h"
 
-#ifdef HAS_ACCELEROMETER
-
 /*
  * ACTIVITY LOGGING
  *
@@ -77,5 +75,3 @@ movement_watch_face_advisory_t activity_logging_face_advise(void *context);
     activity_logging_face_resign, \
     NULL, \
 })
-
-#endif // HAS_TEMPERATURE_SENSOR
index 8a9b20d50511ae3c4a82aae7a6ea7fbe245677b5..f8891bdd164941c3e2ab507e45efe6445ceedc8b 100644 (file)
@@ -27,9 +27,9 @@
 #include "watch.h"
 #include "watch_utility.h"
 
-#ifdef HAS_TEMPERATURE_SENSOR
 
 void thermistor_driver_enable(void) {
+#ifdef HAS_TEMPERATURE_SENSOR
     // Enable the ADC peripheral, which we'll use to read the thermistor value.
     watch_enable_adc();
     // Enable analog circuitry on the sense pin, which is tied to the thermistor resistor divider.
@@ -39,9 +39,11 @@ void thermistor_driver_enable(void) {
     HAL_GPIO_TS_ENABLE_out();
     // and make sure it's off.
     HAL_GPIO_TS_ENABLE_write(!THERMISTOR_ENABLE_VALUE);
+#endif
 }
 
 void thermistor_driver_disable(void) {
+#ifdef HAS_TEMPERATURE_SENSOR
     // Disable the ADC peripheral.
     watch_disable_adc();
     // Disable analog circuitry on the sense pin to save power.
@@ -49,9 +51,11 @@ void thermistor_driver_disable(void) {
     HAL_GPIO_TEMPSENSE_off();
     // Disable the enable pin's output circuitry.
     HAL_GPIO_TS_ENABLE_off();
+#endif
 }
 
 float thermistor_driver_get_temperature(void) {
+#ifdef HAS_TEMPERATURE_SENSOR
     // set the enable pin to the level that powers the thermistor circuit.
     HAL_GPIO_TS_ENABLE_write(THERMISTOR_ENABLE_VALUE);
     // get the sense pin level
@@ -60,6 +64,7 @@ float thermistor_driver_get_temperature(void) {
     HAL_GPIO_TS_ENABLE_write(!THERMISTOR_ENABLE_VALUE);
 
     return watch_utility_thermistor_temperature(value, THERMISTOR_HIGH_SIDE, THERMISTOR_B_COEFFICIENT, THERMISTOR_NOMINAL_TEMPERATURE, THERMISTOR_NOMINAL_RESISTANCE, THERMISTOR_SERIES_RESISTANCE);
+#else
+    return (float) 0xFFFFFFFF;
+#endif
 }
-
-#endif // HAS_TEMPERATURE_SENSOR
\ No newline at end of file
index e929e8051de28e2ad5d0c690a61e3f4509bdeea1..4abce94985286f408b8f35a5ac9be3b54a91f81d 100644 (file)
@@ -26,8 +26,6 @@
 
 #include "pins.h"
 
-#ifdef HAS_TEMPERATURE_SENSOR
-
 // TODO: Do these belong in movement_config.h? In settings we can set on the watch? In an EEPROM configuration area?
 // Think on this. [joey 11/22]
 #define THERMISTOR_ENABLE_VALUE (false)
@@ -40,5 +38,3 @@
 void thermistor_driver_enable(void);
 void thermistor_driver_disable(void);
 float thermistor_driver_get_temperature(void);
-
-#endif // HAS_TEMPERATURE_SENSOR