auto-detect accelerometer sensor (and don't fail build for lack of a temperature sensor)
This commit is contained in:
parent
55df80c3d9
commit
c5bda0faeb
6
Makefile
6
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
|
||||
|
||||
|
||||
98
movement.c
98
movement.c
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user