power down accelerometer unless a watch face requests it
This commit is contained in:
parent
6ac2c13098
commit
69b8048790
29
movement.c
29
movement.c
@ -40,7 +40,6 @@
|
||||
#include "shell.h"
|
||||
#include "utz.h"
|
||||
#include "zones.h"
|
||||
#include "lis2dw.h"
|
||||
#include "tc.h"
|
||||
#include "evsys.h"
|
||||
#include "delay.h"
|
||||
@ -539,7 +538,7 @@ 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_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);
|
||||
@ -550,6 +549,24 @@ bool movement_disable_tap_detection_if_available(void) {
|
||||
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;
|
||||
|
||||
@ -702,7 +719,6 @@ void app_setup(void) {
|
||||
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
|
||||
@ -730,7 +746,14 @@ void app_setup(void) {
|
||||
// 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();
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#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 {
|
||||
@ -291,6 +292,8 @@ 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);
|
||||
@ -373,6 +376,10 @@ void movement_set_alarm_enabled(bool value);
|
||||
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.
|
||||
|
||||
@ -54,6 +54,13 @@ void accelerometer_status_face_setup(uint8_t watch_face_index, void ** context_p
|
||||
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;
|
||||
|
||||
@ -126,5 +133,9 @@ bool accelerometer_status_face_loop(movement_event_t event, void *context) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
typedef struct {
|
||||
uint8_t new_threshold;
|
||||
uint8_t threshold;
|
||||
lis2dw_data_rate_t old_rate;
|
||||
bool is_setting;
|
||||
} accel_interrupt_count_state_t;
|
||||
|
||||
|
||||
@ -73,6 +73,8 @@ void activity_logging_face_setup(uint8_t watch_face_index, void ** context_ptr)
|
||||
if (*context_ptr == NULL) {
|
||||
*context_ptr = malloc(sizeof(activity_logging_state_t));
|
||||
memset(*context_ptr, 0, sizeof(activity_logging_state_t));
|
||||
// At first run, tell Movement to run the accelerometer in the background. It will now run at this rate forever.
|
||||
movement_set_accelerometer_background_rate(LIS2DW_DATA_RATE_LOWEST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user