#include "shell.h"
#include "utz.h"
#include "zones.h"
-#include "lis2dw.h"
#include "tc.h"
#include "evsys.h"
#include "delay.h"
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_data_rate(movement_state.accelerometer_background_rate);
lis2dw_set_mode(LIS2DW_MODE_LOW_POWER);
// ...disable Z axis (not sure if this is needed, does this save power?)...
lis2dw_configure_tap_threshold(0, 0, 0, 0);
return false;
}
+lis2dw_data_rate_t movement_get_accelerometer_background_rate(void) {
+ if (movement_state.has_lis2dw) return movement_state.accelerometer_background_rate;
+ else return LIS2DW_DATA_RATE_POWERDOWN;
+}
+
+bool movement_set_accelerometer_background_rate(lis2dw_data_rate_t new_rate) {
+ if (movement_state.has_lis2dw) {
+ if (movement_state.accelerometer_background_rate != new_rate) {
+ lis2dw_set_data_rate(new_rate);
+ movement_state.accelerometer_background_rate = new_rate;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
float movement_get_temperature(void) {
float temperature_c = (float)0xFFFFFFFF;
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
- lis2dw_set_data_rate(LIS2DW_DATA_RATE_LOWEST); // sample at 1.6 Hz, lowest rate available
lis2dw_enable_stationary_motion_detection(); // stationary/motion detection mode keeps the data rate at 1.6 Hz even in sleep
lis2dw_set_range(LIS2DW_RANGE_2_G); // Application note AN5038 recommends 2g range
lis2dw_enable_sleep(); // allow acceleromter to sleep and wake on activity
// but it will only fire once tap recognition is enabled.
watch_register_interrupt_callback(HAL_GPIO_A3_pin(), cb_accelerometer_event, INTERRUPT_TRIGGER_RISING);
+ // Enable the interrupts...
lis2dw_enable_interrupts();
+
+ // ...and power down the accelerometer to save energy. This means the interrupts we just configured won't fire.
+ // Tap detection will ramp up sesing and make use of the A3 interrupt.
+ // If a watch face wants to check in on the A4 pin, it can call movement_set_accelerometer_background_rate
+ lis2dw_set_data_rate(LIS2DW_DATA_RATE_POWERDOWN);
+ movement_state.accelerometer_background_rate = LIS2DW_DATA_RATE_POWERDOWN;
} else {
watch_disable_i2c();
}
#include <stdbool.h>
#include "watch.h"
#include "utz.h"
+#include "lis2dw.h"
/// @brief A struct that allows a watch face to report its state back to Movement.
typedef struct {
// boolean set if accelerometer is detected
bool has_lis2dw;
+ // data rate for background accelerometer sensing
+ lis2dw_data_rate_t accelerometer_background_rate;
} movement_state_t;
void movement_move_to_face(uint8_t watch_face_index);
bool movement_enable_tap_detection_if_available(void);
bool movement_disable_tap_detection_if_available(void);
+// gets and sets the accelerometer data rate in the background
+lis2dw_data_rate_t movement_get_accelerometer_background_rate(void);
+bool movement_set_accelerometer_background_rate(lis2dw_data_rate_t new_rate);
+
// If the board has a temperature sensor, this function will give you the temperature in degrees celsius.
// If the board has multiple temperature sensors, it will use the most accurate one available.
// If the board has no temperature sensors, it will return 0xFFFFFFFF.
void accelerometer_status_face_activate(void *context) {
accel_interrupt_count_state_t *state = (accel_interrupt_count_state_t *)context;
+ // get the current data rate from Movement
+ state->old_rate = movement_get_accelerometer_background_rate();
+ if (state->old_rate == LIS2DW_DATA_RATE_POWERDOWN) {
+ // if accelerometer was powered down, power it up at the lowest possible rate
+ movement_set_accelerometer_background_rate(LIS2DW_DATA_RATE_LOWEST);
+ }
+
// never in settings mode at the start
state->is_setting = false;
}
void accelerometer_status_face_resign(void *context) {
- (void) context;
+ accel_interrupt_count_state_t *state = (accel_interrupt_count_state_t *)context;
+
+ // restore old data rate. This only does something if old_rate was POWERDOWN.
+ // If the old rate was anything other than POWERDOWN, we didn't change anything and this will be a no-op.
+ movement_set_accelerometer_background_rate(state->old_rate);
}