Sensor Watch Simulator (#35)

* Put something on screen

* Use the 32bit watch_date_time repr to pass from JS

* Implement periodic callbacks

* Clear display on enabling

* Hook up watch_set_led_color() to SVG (green-only)

* Make debug output full-width

* Remove default Emscripten canvas

* Implement sleep and button clicks

* Fix time zone conversion bug in beats-time app

* Clean up warnings

* Fix pin levels

* Set time zone to browser value (if available)

* Add basic backup data saving

* Silence format specifier warnings in both targets

* Remove unnecessary, copied files

* Use RTC pointer to clear callbacks (if available)

* Use preprocessor define to avoid hardcoding MOVEMENT_NUM_FACES

* Change each face to const preprocessor definition

* Remove Intl.DateTimeFormat usage

* Update shell.html title, header

* Add touch start/end event handlers on SVG buttons

* Update shell.html

* Update folder structure (shared, simulator, hardware under watch-library)

* Tease out shared components from watch_slcd

* Clean up simulator watch_slcd.c inline JS calls

* Fix missing newlines at end of file

* Add simulator warnings (except format, unused-paremter)

* Implement remaining watch_rtc functions

* Fix button bug on mouse down then drag out

* Implement remaining watch_slcd functions

* Link keyboard events to buttons (for keys A, L, M)

* Rewrite event handling (mouse, touch, keyboard) in C

* Set explicit text UTF-8 charset in shell.html

* Address PR comments

* Remove unused directories from include paths
This commit is contained in:
Alexsander Akers 2022-01-25 15:03:22 -05:00 committed by GitHub
parent 9e24f6c336
commit b8de35658f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
327 changed files with 2303 additions and 570 deletions

View file

@ -3,7 +3,7 @@
#include <math.h>
#include "watch.h"
const uint8_t UTC_OFFSET = 4; // set to your current UTC offset to see correct beats time
const int8_t UTC_OFFSET = 4; // set to your current UTC offset to see correct beats time
const uint8_t BEAT_REFRESH_FREQUENCY = 8;
typedef enum ApplicationMode {
@ -160,7 +160,7 @@ float clock2beats(uint16_t hours, uint16_t minutes, uint16_t seconds, int16_t ut
float beats = seconds + ((float)application_state.subsecond / (float)BEAT_REFRESH_FREQUENCY);
beats += 60 * minutes;
beats += (float)hours * 60 * 60;
beats += (utc_offset + 1) * 60 * 60; // offset from utc + 1 since beats in in UTC+1
beats += (1 - utc_offset) * 60 * 60; // offset from utc + 1 since beats in in UTC+1
beats /= 86.4; // convert to beats
while(beats > 1000) beats -= 1000; // beats %= 1000 but for a float

193
make.mk
View file

@ -9,17 +9,18 @@ endif
##############################################################################
.PHONY: all directory clean size
CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size
UF2 = python $(TOP)/utils/uf2conv.py
ifeq ($(OS), Windows_NT)
MKDIR = gmkdir
else
MKDIR = mkdir
endif
ifndef EMSCRIPTEN
CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size
UF2 = python $(TOP)/utils/uf2conv.py
CFLAGS += -W -Wall -Wextra -Wmissing-prototypes -Wmissing-declarations
CFLAGS += --std=gnu99 -Os
CFLAGS += -fno-diagnostics-show-caret
@ -30,40 +31,41 @@ CFLAGS += -MD -MP -MT $(BUILD)/$(*F).o -MF $(BUILD)/$(@F).d
LDFLAGS += -mcpu=cortex-m0plus -mthumb
LDFLAGS += -Wl,--gc-sections
LDFLAGS += -Wl,--script=$(TOP)//watch-library/linker/saml22j18.ld
LDFLAGS += -Wl,--script=$(TOP)/watch-library/hardware/linker/saml22j18.ld
LIBS += -lm
INCLUDES += \
-I$(TOP)/tinyusb/src \
-I$(TOP)/boards/$(BOARD) \
-I$(TOP)/watch-library/include \
-I$(TOP)/watch-library/hal/ \
-I$(TOP)/watch-library/hal/documentation/ \
-I$(TOP)/watch-library/hal/include/ \
-I$(TOP)/watch-library/hal/src/ \
-I$(TOP)/watch-library/hal/utils/ \
-I$(TOP)/watch-library/hal/utils/include/ \
-I$(TOP)/watch-library/hal/utils/src/ \
-I$(TOP)/watch-library/hpl/ \
-I$(TOP)/watch-library/hpl/core/ \
-I$(TOP)/watch-library/hpl/dmac/ \
-I$(TOP)/watch-library/hpl/eic/ \
-I$(TOP)/watch-library/hpl/gclk/ \
-I$(TOP)/watch-library/hpl/mclk/ \
-I$(TOP)/watch-library/hpl/osc32kctrl/ \
-I$(TOP)/watch-library/hpl/oscctrl/ \
-I$(TOP)/watch-library/hpl/pm/ \
-I$(TOP)/watch-library/hpl/port/ \
-I$(TOP)/watch-library/hpl/sercom/ \
-I$(TOP)/watch-library/hpl/slcd/ \
-I$(TOP)/watch-library/hpl/systick/ \
-I$(TOP)/watch-library/hri/ \
-I$(TOP)/watch-library/config/ \
-I$(TOP)/watch-library/hw/ \
-I$(TOP)/watch-library/watch/ \
-I$(TOP)/watch-library/driver/ \
-I$(TOP)/watch-library
-I$(TOP)/watch-library/shared/config/ \
-I$(TOP)/watch-library/shared/driver/ \
-I$(TOP)/watch-library/shared/watch/ \
-I$(TOP)/watch-library/hardware/include \
-I$(TOP)/watch-library/hardware/hal/ \
-I$(TOP)/watch-library/hardware/hal/documentation/ \
-I$(TOP)/watch-library/hardware/hal/include/ \
-I$(TOP)/watch-library/hardware/hal/src/ \
-I$(TOP)/watch-library/hardware/hal/utils/ \
-I$(TOP)/watch-library/hardware/hal/utils/include/ \
-I$(TOP)/watch-library/hardware/hal/utils/src/ \
-I$(TOP)/watch-library/hardware/hpl/ \
-I$(TOP)/watch-library/hardware/hpl/core/ \
-I$(TOP)/watch-library/hardware/hpl/dmac/ \
-I$(TOP)/watch-library/hardware/hpl/eic/ \
-I$(TOP)/watch-library/hardware/hpl/gclk/ \
-I$(TOP)/watch-library/hardware/hpl/mclk/ \
-I$(TOP)/watch-library/hardware/hpl/osc32kctrl/ \
-I$(TOP)/watch-library/hardware/hpl/oscctrl/ \
-I$(TOP)/watch-library/hardware/hpl/pm/ \
-I$(TOP)/watch-library/hardware/hpl/port/ \
-I$(TOP)/watch-library/hardware/hpl/sercom/ \
-I$(TOP)/watch-library/hardware/hpl/slcd/ \
-I$(TOP)/watch-library/hardware/hpl/systick/ \
-I$(TOP)/watch-library/hardware/hri/ \
-I$(TOP)/watch-library/hardware/hw/ \
-I$(TOP)/watch-library/hardware/watch/ \
-I$(TOP)/watch-library/hardware \
SRCS += \
$(TOP)/tinyusb/src/tusb.c \
@ -72,55 +74,92 @@ SRCS += \
$(TOP)/tinyusb/src/device/usbd.c \
$(TOP)/tinyusb/src/device/usbd_control.c \
$(TOP)/tinyusb/src/portable/microchip/samd/dcd_samd.c \
$(TOP)/watch-library/main.c \
$(TOP)/watch-library/startup_saml22.c \
$(TOP)/watch-library/hw/driver_init.c \
$(TOP)/watch-library/watch/watch_rtc.c \
$(TOP)/watch-library/watch/watch_slcd.c \
$(TOP)/watch-library/watch/watch_extint.c \
$(TOP)/watch-library/watch/watch_led.c \
$(TOP)/watch-library/watch/watch_buzzer.c \
$(TOP)/watch-library/watch/watch_adc.c \
$(TOP)/watch-library/watch/watch_gpio.c \
$(TOP)/watch-library/watch/watch_i2c.c \
$(TOP)/watch-library/watch/watch_uart.c \
$(TOP)/watch-library/watch/watch_deepsleep.c \
$(TOP)/watch-library/watch/watch_utility.c \
$(TOP)/watch-library/watch/watch_private.c \
$(TOP)/watch-library/watch/watch.c \
$(TOP)/watch-library/hal/src/hal_atomic.c \
$(TOP)/watch-library/hal/src/hal_delay.c \
$(TOP)/watch-library/hal/src/hal_ext_irq.c \
$(TOP)/watch-library/hal/src/hal_gpio.c \
$(TOP)/watch-library/hal/src/hal_i2c_m_sync.c \
$(TOP)/watch-library/hal/src/hal_spi_m_sync.c \
$(TOP)/watch-library/hal/src/hal_init.c \
$(TOP)/watch-library/hal/src/hal_io.c \
$(TOP)/watch-library/hal/src/hal_slcd_sync.c \
$(TOP)/watch-library/hal/src/hal_sleep.c \
$(TOP)/watch-library/hal/utils/src/utils_assert.c \
$(TOP)/watch-library/hal/utils/src/utils_event.c \
$(TOP)/watch-library/hal/utils/src/utils_list.c \
$(TOP)/watch-library/hal/utils/src/utils_syscalls.c \
$(TOP)/watch-library/hpl/core/hpl_core_m0plus_base.c \
$(TOP)/watch-library/hpl/core/hpl_init.c \
$(TOP)/watch-library/hpl/dmac/hpl_dmac.c \
$(TOP)/watch-library/hpl/eic/hpl_eic.c \
$(TOP)/watch-library/hpl/gclk/hpl_gclk.c \
$(TOP)/watch-library/hpl/mclk/hpl_mclk.c \
$(TOP)/watch-library/hpl/osc32kctrl/hpl_osc32kctrl.c \
$(TOP)/watch-library/hpl/oscctrl/hpl_oscctrl.c \
$(TOP)/watch-library/hpl/pm/hpl_pm.c \
$(TOP)/watch-library/hpl/sercom/hpl_sercom.c \
$(TOP)/watch-library/hpl/slcd/hpl_slcd.c \
$(TOP)/watch-library/hpl/systick/hpl_systick.c \
$(TOP)/watch-library/driver/lis2dh.c \
$(TOP)/watch-library/driver/lis2dw.c \
$(TOP)/watch-library/hardware/main.c \
$(TOP)/watch-library/hardware/startup_saml22.c \
$(TOP)/watch-library/hardware/hw/driver_init.c \
$(TOP)/watch-library/hardware/watch/watch_rtc.c \
$(TOP)/watch-library/hardware/watch/watch_slcd.c \
$(TOP)/watch-library/hardware/watch/watch_extint.c \
$(TOP)/watch-library/hardware/watch/watch_led.c \
$(TOP)/watch-library/hardware/watch/watch_buzzer.c \
$(TOP)/watch-library/hardware/watch/watch_adc.c \
$(TOP)/watch-library/hardware/watch/watch_gpio.c \
$(TOP)/watch-library/hardware/watch/watch_i2c.c \
$(TOP)/watch-library/hardware/watch/watch_uart.c \
$(TOP)/watch-library/hardware/watch/watch_deepsleep.c \
$(TOP)/watch-library/hardware/watch/watch_private.c \
$(TOP)/watch-library/hardware/watch/watch.c \
$(TOP)/watch-library/hardware/hal/src/hal_atomic.c \
$(TOP)/watch-library/hardware/hal/src/hal_delay.c \
$(TOP)/watch-library/hardware/hal/src/hal_ext_irq.c \
$(TOP)/watch-library/hardware/hal/src/hal_gpio.c \
$(TOP)/watch-library/hardware/hal/src/hal_i2c_m_sync.c \
$(TOP)/watch-library/hardware/hal/src/hal_spi_m_sync.c \
$(TOP)/watch-library/hardware/hal/src/hal_init.c \
$(TOP)/watch-library/hardware/hal/src/hal_io.c \
$(TOP)/watch-library/hardware/hal/src/hal_slcd_sync.c \
$(TOP)/watch-library/hardware/hal/src/hal_sleep.c \
$(TOP)/watch-library/hardware/hal/utils/src/utils_assert.c \
$(TOP)/watch-library/hardware/hal/utils/src/utils_event.c \
$(TOP)/watch-library/hardware/hal/utils/src/utils_list.c \
$(TOP)/watch-library/hardware/hal/utils/src/utils_syscalls.c \
$(TOP)/watch-library/hardware/hpl/core/hpl_core_m0plus_base.c \
$(TOP)/watch-library/hardware/hpl/core/hpl_init.c \
$(TOP)/watch-library/hardware/hpl/dmac/hpl_dmac.c \
$(TOP)/watch-library/hardware/hpl/eic/hpl_eic.c \
$(TOP)/watch-library/hardware/hpl/gclk/hpl_gclk.c \
$(TOP)/watch-library/hardware/hpl/mclk/hpl_mclk.c \
$(TOP)/watch-library/hardware/hpl/osc32kctrl/hpl_osc32kctrl.c \
$(TOP)/watch-library/hardware/hpl/oscctrl/hpl_oscctrl.c \
$(TOP)/watch-library/hardware/hpl/pm/hpl_pm.c \
$(TOP)/watch-library/hardware/hpl/sercom/hpl_sercom.c \
$(TOP)/watch-library/hardware/hpl/slcd/hpl_slcd.c \
$(TOP)/watch-library/hardware/hpl/systick/hpl_systick.c \
$(TOP)/watch-library/shared/driver/lis2dh.c \
$(TOP)/watch-library/shared/driver/lis2dw.c \
$(TOP)/watch-library/shared/watch/watch_private_display.c \
$(TOP)/watch-library/shared/watch/watch_utility.c \
DEFINES += \
-D__SAML22J18A__ \
-DDONT_USE_CMSIS_INIT
else
CFLAGS += -W -Wall -Wextra -Wmissing-prototypes -Wmissing-declarations
CFLAGS += -Wno-format -Wno-unused-parameter
INCLUDES += \
-I$(TOP)/boards/$(BOARD) \
-I$(TOP)/watch-library/shared/driver/ \
-I$(TOP)/watch-library/shared/config/ \
-I$(TOP)/watch-library/shared/watch/ \
-I$(TOP)/watch-library/simulator/hpl/port/ \
-I$(TOP)/watch-library/hardware/include/component \
-I$(TOP)/watch-library/hardware/hal/include/ \
-I$(TOP)/watch-library/hardware/hal/utils/include/ \
-I$(TOP)/watch-library/hardware/hpl/slcd/ \
-I$(TOP)/watch-library/hardware/hw/ \
SRCS += \
$(TOP)/watch-library/simulator/main.c \
$(TOP)/watch-library/simulator/watch/watch_rtc.c \
$(TOP)/watch-library/simulator/watch/watch_slcd.c \
$(TOP)/watch-library/simulator/watch/watch_extint.c \
$(TOP)/watch-library/simulator/watch/watch_led.c \
$(TOP)/watch-library/simulator/watch/watch_buzzer.c \
$(TOP)/watch-library/simulator/watch/watch_adc.c \
$(TOP)/watch-library/simulator/watch/watch_gpio.c \
$(TOP)/watch-library/simulator/watch/watch_i2c.c \
$(TOP)/watch-library/simulator/watch/watch_uart.c \
$(TOP)/watch-library/simulator/watch/watch_deepsleep.c \
$(TOP)/watch-library/simulator/watch/watch_private.c \
$(TOP)/watch-library/simulator/watch/watch.c \
$(TOP)/watch-library/shared/watch/watch_private_display.c \
$(TOP)/watch-library/shared/watch/watch_utility.c \
endif
ifeq ($(LED), BLUE)
CFLAGS += -DWATCH_SWAP_LED_PINS
endif

View file

@ -22,13 +22,13 @@ A fifth optional function, `watch_face_wants_background_task`, will be added to
To create a new watch face, you should create a new C header and source file in the watch-faces folder (i.e. for a watch face that displays moon phases: `moon_phase_face.h`, `moon_phase_face.c`), and implement these functions with your own unique prefix (i.e. `moon_phase_face_setup`). Then declare your watch face in your header file as follows:
```c
static const watch_face_t moon_phase_face = {
moon_phase_face_setup,
moon_phase_face_activate,
moon_phase_face_loop,
moon_phase_face_resign,
NULL // or moon_phase_face_wants_background_task, if you implemented this function
};
#define moon_phase_face ((const watch_face_t){ \
moon_phase_face_setup, \
moon_phase_face_activate, \
moon_phase_face_loop, \
moon_phase_face_resign, \
NULL, /* or moon_phase_face_wants_background_task, if you implemented this function */ \
})
```
This section will go over how each function works. The section headings use the watch_face prefix, but know that you should implement each function with your own prefix as described above.
@ -96,13 +96,13 @@ void pulsometer_face_activate(movement_settings_t *settings, void *context);
bool pulsometer_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void pulsometer_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t pulsometer_face = {
pulsometer_face_setup,
pulsometer_face_activate,
pulsometer_face_loop,
pulsometer_face_resign,
NULL
};
#define pulsometer_face ((const watch_face_t){ \
pulsometer_face_setup, \
pulsometer_face_activate, \
pulsometer_face_loop, \
pulsometer_face_resign, \
NULL, \
})
```
### pulsometer_face.c

View file

@ -17,7 +17,7 @@ void setTimezone(uint8_t timezone){
_timeZoneOffset = timezone;
}
uint32_t TimeStruct2Timestamp(struct tm time){
static uint32_t TimeStruct2Timestamp(struct tm time){
//time.tm_mon -= 1;
//time.tm_year -= 1900;
return mktime(&(time)) - (_timeZoneOffset * 3600) - 2208988800;

View file

@ -34,11 +34,11 @@ void init(void) {
bufferOffset = 0;
}
uint32_t rol32(uint32_t number, uint8_t bits) {
static uint32_t rol32(uint32_t number, uint8_t bits) {
return ((number << bits) | (uint32_t)(number >> (32-bits)));
}
void hashBlock(void) {
static void hashBlock(void) {
uint8_t i;
uint32_t a,b,c,d,e,t;
@ -75,7 +75,7 @@ void hashBlock(void) {
state.w[4] += e;
}
void addUncounted(uint8_t data) {
static void addUncounted(uint8_t data) {
buffer.b[bufferOffset ^ 3] = data;
bufferOffset++;
if (bufferOffset == BLOCK_LENGTH) {
@ -97,7 +97,7 @@ void writeArray(uint8_t *buffer, uint8_t size){
}
}
void pad(void) {
static void pad(void) {
// Implement SHA-1 padding (fips180-2 <20><>5.1.1)
// Pad with 0x80 followed by 0x00 until the end of the block

View file

@ -29,6 +29,10 @@
#include "movement.h"
#include "movement_config.h"
#if __EMSCRIPTEN__
#include <emscripten.h>
#endif
movement_state_t movement_state;
void * watch_face_contexts[MOVEMENT_NUM_FACES];
watch_date_time scheduled_tasks[MOVEMENT_NUM_FACES];
@ -149,7 +153,16 @@ static void _movement_handle_scheduled_tasks(void) {
void movement_request_tick_frequency(uint8_t freq) {
if (freq == 128) return; // Movement uses the 128 Hz tick internally
RTC->MODE2.INTENCLR.reg = 0xFE; // disable all callbacks except the 128 Hz one
// disable all callbacks except the 128 Hz one
#if __EMSCRIPTEN__
for (int i = 1; i < 128; i = i << 1) {
watch_rtc_disable_periodic_callback(i);
}
#else
RTC->MODE2.INTENCLR.reg = 0xFE;
#endif
movement_state.subsecond = 0;
movement_state.tick_frequency = freq;
if (freq) watch_rtc_register_periodic_callback(cb_tick, freq);
@ -215,6 +228,18 @@ void app_init(void) {
movement_state.light_ticks = -1;
movement_state.alarm_ticks = -1;
_movement_reset_inactivity_countdown();
#if __EMSCRIPTEN__
int32_t time_zone_offset = EM_ASM_INT({
return -new Date().getTimezoneOffset();
});
for (int i = 0, count = sizeof(movement_timezone_offsets) / sizeof(movement_timezone_offsets[0]); i < count; i++) {
if (movement_timezone_offsets[i] == time_zone_offset) {
movement_state.settings.bit.time_zone = i;
break;
}
}
#endif
}
void app_wake_from_backup(void) {

View file

@ -39,12 +39,12 @@ bool simple_clock_face_loop(movement_event_t event, movement_settings_t *setting
void simple_clock_face_resign(movement_settings_t *settings, void *context);
bool simple_clock_face_wants_background_task(movement_settings_t *settings, void *context);
static const watch_face_t simple_clock_face = {
simple_clock_face_setup,
simple_clock_face_activate,
simple_clock_face_loop,
simple_clock_face_resign,
simple_clock_face_wants_background_task
};
#define simple_clock_face ((const watch_face_t){ \
simple_clock_face_setup, \
simple_clock_face_activate, \
simple_clock_face_loop, \
simple_clock_face_resign, \
simple_clock_face_wants_background_task, \
})
#endif // SIMPLE_CLOCK_FACE_H_

View file

@ -46,12 +46,12 @@ void world_clock_face_resign(movement_settings_t *settings, void *context);
uint8_t world_clock_face_get_weekday(uint16_t day, uint16_t month, uint16_t year);
static const watch_face_t world_clock_face = {
world_clock_face_setup,
world_clock_face_activate,
world_clock_face_loop,
world_clock_face_resign,
NULL
};
#define world_clock_face ((const watch_face_t){ \
world_clock_face_setup, \
world_clock_face_activate, \
world_clock_face_loop, \
world_clock_face_resign, \
NULL, \
})
#endif // WORLD_CLOCK_FACE_H_

View file

@ -45,7 +45,7 @@ bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void
state->next_subsecond_update = (event.subsecond + 1 + (BEAT_REFRESH_FREQUENCY * 2 / 3)) % BEAT_REFRESH_FREQUENCY;
state->last_centibeat_displayed = centibeats;
}
sprintf(buf, "bt %6ld", centibeats);
sprintf(buf, "bt %6lu", centibeats);
watch_display_string(buf, 0);
break;
@ -53,7 +53,7 @@ bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void
if (!watch_tick_animation_is_running()) watch_start_tick_animation(432);
date_time = watch_rtc_get_date_time();
centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_timezone_offsets[settings->bit.time_zone]);
sprintf(buf, "bt %4ld ", centibeats / 100);
sprintf(buf, "bt %4lu ", centibeats / 100);
watch_display_string(buf, 0);
break;

View file

@ -14,12 +14,12 @@ void beats_face_activate(movement_settings_t *settings, void *context);
bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void beats_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t beats_face = {
beats_face_setup,
beats_face_activate,
beats_face_loop,
beats_face_resign,
NULL
};
#define beats_face ((const watch_face_t){ \
beats_face_setup, \
beats_face_activate, \
beats_face_loop, \
beats_face_resign, \
NULL, \
})
#endif // BEATS_FACE_H_

View file

@ -38,12 +38,12 @@ void blinky_face_activate(movement_settings_t *settings, void *context);
bool blinky_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void blinky_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t blinky_face = {
blinky_face_setup,
blinky_face_activate,
blinky_face_loop,
blinky_face_resign,
NULL
};
#define blinky_face ((const watch_face_t){ \
blinky_face_setup, \
blinky_face_activate, \
blinky_face_loop, \
blinky_face_resign, \
NULL, \
})
#endif // BLINKY_FACE_H_
#endif // BLINKY_FACE_H_

View file

@ -58,12 +58,12 @@ void countdown_face_activate(movement_settings_t *settings, void *context);
bool countdown_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void countdown_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t countdown_face = {
countdown_face_setup,
countdown_face_activate,
countdown_face_loop,
countdown_face_resign,
NULL
};
#define countdown_face ((const watch_face_t){ \
countdown_face_setup, \
countdown_face_activate, \
countdown_face_loop, \
countdown_face_resign, \
NULL, \
})
#endif // COUNTDOWN_FACE_H_

View file

@ -37,7 +37,7 @@ static void _day_one_face_update(day_one_state_t state) {
watch_date_time date_time = watch_rtc_get_date_time();
uint32_t julian_date = _day_one_face_juliandaynum(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day);
uint32_t julian_birthdate = _day_one_face_juliandaynum(state.birth_year, state.birth_month, state.birth_day);
sprintf(buf, "DA %6ld", julian_date - julian_birthdate);
sprintf(buf, "DA %6lu", julian_date - julian_birthdate);
watch_display_string(buf, 0);
}

View file

@ -44,12 +44,12 @@ void day_one_face_activate(movement_settings_t *settings, void *context);
bool day_one_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void day_one_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t day_one_face = {
day_one_face_setup,
day_one_face_activate,
day_one_face_loop,
day_one_face_resign,
NULL
};
#define day_one_face ((const watch_face_t){ \
day_one_face_setup, \
day_one_face_activate, \
day_one_face_loop, \
day_one_face_resign, \
NULL, \
})
#endif // DAY_ONE_FACE_H_

View file

@ -38,12 +38,12 @@ void pulsometer_face_activate(movement_settings_t *settings, void *context);
bool pulsometer_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void pulsometer_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t pulsometer_face = {
pulsometer_face_setup,
pulsometer_face_activate,
pulsometer_face_loop,
pulsometer_face_resign,
NULL
};
#define pulsometer_face ((const watch_face_t){ \
pulsometer_face_setup, \
pulsometer_face_activate, \
pulsometer_face_loop, \
pulsometer_face_resign, \
NULL, \
})
#endif // PULSOMETER_FACE_H_
#endif // PULSOMETER_FACE_H_

View file

@ -15,12 +15,12 @@ void stopwatch_face_activate(movement_settings_t *settings, void *context);
bool stopwatch_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void stopwatch_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t stopwatch_face = {
stopwatch_face_setup,
stopwatch_face_activate,
stopwatch_face_loop,
stopwatch_face_resign,
NULL
};
#define stopwatch_face ((const watch_face_t){ \
stopwatch_face_setup, \
stopwatch_face_activate, \
stopwatch_face_loop, \
stopwatch_face_resign, \
NULL, \
})
#endif // STOPWATCH_FACE_H_
#endif // STOPWATCH_FACE_H_

View file

@ -52,12 +52,12 @@ void sunrise_sunset_face_activate(movement_settings_t *settings, void *context);
bool sunrise_sunset_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void sunrise_sunset_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t sunrise_sunset_face = {
sunrise_sunset_face_setup,
sunrise_sunset_face_activate,
sunrise_sunset_face_loop,
sunrise_sunset_face_resign,
NULL
};
#define sunrise_sunset_face ((const watch_face_t){ \
sunrise_sunset_face_setup, \
sunrise_sunset_face_activate, \
sunrise_sunset_face_loop, \
sunrise_sunset_face_resign, \
NULL, \
})
#endif // SUNRISE_SUNSET_FACE_H_

View file

@ -15,12 +15,12 @@ void totp_face_activate(movement_settings_t *settings, void *context);
bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void totp_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t totp_face = {
totp_face_setup,
totp_face_activate,
totp_face_loop,
totp_face_resign,
NULL
};
#define totp_face ((const watch_face_t){ \
totp_face_setup, \
totp_face_activate, \
totp_face_loop, \
totp_face_resign, \
NULL, \
})
#endif // TOTP_FACE_H_

View file

@ -32,12 +32,12 @@ void character_set_face_activate(movement_settings_t *settings, void *context);
bool character_set_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void character_set_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t character_set_face = {
character_set_face_setup,
character_set_face_activate,
character_set_face_loop,
character_set_face_resign,
NULL
};
#define character_set_face ((const watch_face_t){ \
character_set_face_setup, \
character_set_face_activate, \
character_set_face_loop, \
character_set_face_resign, \
NULL, \
})
#endif // CHARACTER_SET_FACE_H_
#endif // CHARACTER_SET_FACE_H_

View file

@ -32,12 +32,12 @@ void demo_face_activate(movement_settings_t *settings, void *context);
bool demo_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void demo_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t demo_face = {
demo_face_setup,
demo_face_activate,
demo_face_loop,
demo_face_resign,
NULL
};
#define demo_face ((const watch_face_t){ \
demo_face_setup, \
demo_face_activate, \
demo_face_loop, \
demo_face_resign, \
NULL, \
})
#endif // DEMO_FACE_H_
#endif // DEMO_FACE_H_

View file

@ -37,12 +37,12 @@ void hello_there_face_activate(movement_settings_t *settings, void *context);
bool hello_there_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void hello_there_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t hello_there_face = {
hello_there_face_setup,
hello_there_face_activate,
hello_there_face_loop,
hello_there_face_resign,
NULL
};
#define hello_there_face ((const watch_face_t){ \
hello_there_face_setup, \
hello_there_face_activate, \
hello_there_face_loop, \
hello_there_face_resign, \
NULL, \
})
#endif // HELLO_THERE_FACE_H_

View file

@ -36,10 +36,11 @@
// Pressing the alarm button enters the log mode, where the main display shows the number of interrupts detected in each of the last
// 24 hours (the hour is shown in the top right digit and AM/PM indicator, if the clock is set to 12 hour mode)
static void _lis2dh_logging_face_update_display(movement_settings_t *settings, lis2dh_logger_state_t *logger_state, lis2dh_interrupt_state interrupt_state, watch_date_time date_time) {
static void _lis2dh_logging_face_update_display(movement_settings_t *settings, lis2dh_logger_state_t *logger_state, lis2dh_interrupt_state interrupt_state) {
char buf[14];
char time_indication_character;
int8_t pos;
watch_date_time date_time;
if (logger_state->log_ticks) {
pos = (logger_state->data_points - 1 - logger_state->display_index) % LIS2DH_LOGGING_NUM_DATA_POINTS;
@ -58,16 +59,16 @@ static void _lis2dh_logging_face_update_display(movement_settings_t *settings, l
}
switch (logger_state->axis_index) {
case 0:
sprintf(buf, "3A%2d%02d%4ld", date_time.unit.hour, date_time.unit.minute, logger_state->data[pos].x_interrupts + logger_state->data[pos].y_interrupts + logger_state->data[pos].z_interrupts);
sprintf(buf, "3A%2d%02d%4lu", date_time.unit.hour, date_time.unit.minute, logger_state->data[pos].x_interrupts + logger_state->data[pos].y_interrupts + logger_state->data[pos].z_interrupts);
break;
case 1:
sprintf(buf, "XA%2d%02d%4ld", date_time.unit.hour, date_time.unit.minute, logger_state->data[pos].x_interrupts);
sprintf(buf, "XA%2d%02d%4lu", date_time.unit.hour, date_time.unit.minute, logger_state->data[pos].x_interrupts);
break;
case 2:
sprintf(buf, "YA%2d%02d%4ld", date_time.unit.hour, date_time.unit.minute, logger_state->data[pos].y_interrupts);
sprintf(buf, "YA%2d%02d%4lu", date_time.unit.hour, date_time.unit.minute, logger_state->data[pos].y_interrupts);
break;
case 3:
sprintf(buf, "ZA%2d%02d%4ld", date_time.unit.hour, date_time.unit.minute, logger_state->data[pos].z_interrupts);
sprintf(buf, "ZA%2d%02d%4lu", date_time.unit.hour, date_time.unit.minute, logger_state->data[pos].z_interrupts);
break;
}
}
@ -145,7 +146,6 @@ void lis2dh_logging_face_activate(movement_settings_t *settings, void *context)
bool lis2dh_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context) {
lis2dh_logger_state_t *logger_state = (lis2dh_logger_state_t *)context;
lis2dh_interrupt_state interrupt_state = 0;
watch_date_time date_time;
switch (event.event_type) {
case EVENT_MODE_BUTTON_UP:
@ -157,13 +157,13 @@ bool lis2dh_logging_face_loop(movement_event_t event, movement_settings_t *setti
case EVENT_LIGHT_BUTTON_DOWN:
logger_state->axis_index = (logger_state->axis_index + 1) % 4;
logger_state->log_ticks = 255;
_lis2dh_logging_face_update_display(settings, logger_state, interrupt_state, date_time);
_lis2dh_logging_face_update_display(settings, logger_state, interrupt_state);
break;
case EVENT_ALARM_BUTTON_UP:
if (logger_state->log_ticks) logger_state->display_index = (logger_state->display_index + 1) % LIS2DH_LOGGING_NUM_DATA_POINTS;
logger_state->log_ticks = 255;
logger_state->axis_index = 0;
_lis2dh_logging_face_update_display(settings, logger_state, interrupt_state, date_time);
_lis2dh_logging_face_update_display(settings, logger_state, interrupt_state);
break;
case EVENT_ACTIVATE:
case EVENT_TICK:
@ -182,7 +182,7 @@ bool lis2dh_logging_face_loop(movement_event_t event, movement_settings_t *setti
} else {
watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
}
_lis2dh_logging_face_update_display(settings, logger_state, interrupt_state, date_time);
_lis2dh_logging_face_update_display(settings, logger_state, interrupt_state);
break;
case EVENT_BACKGROUND_TASK:
_lis2dh_logging_face_log_data(logger_state);

View file

@ -55,12 +55,12 @@ bool lis2dh_logging_face_loop(movement_event_t event, movement_settings_t *setti
void lis2dh_logging_face_resign(movement_settings_t *settings, void *context);
bool lis2dh_logging_face_wants_background_task(movement_settings_t *settings, void *context);
static const watch_face_t lis2dh_logging_face = {
lis2dh_logging_face_setup,
lis2dh_logging_face_activate,
lis2dh_logging_face_loop,
lis2dh_logging_face_resign,
lis2dh_logging_face_wants_background_task
};
#define lis2dh_logging_face ((const watch_face_t){ \
lis2dh_logging_face_setup, \
lis2dh_logging_face_activate, \
lis2dh_logging_face_loop, \
lis2dh_logging_face_resign, \
lis2dh_logging_face_wants_background_task, \
})
#endif // LIS2DH_LOGGING_FACE_H_

View file

@ -86,6 +86,6 @@ void voltage_face_resign(movement_settings_t *settings, void *context) {
(void) settings;
(void) context;
// make sure to restore the default in the end.
watch_set_analog_reference_voltage(ADC_REFCTRL_REFSEL_INTVCC2_Val);
watch_set_analog_reference_voltage(ADC_REFERENCE_VCC);
watch_disable_adc();
}

View file

@ -32,12 +32,12 @@ void voltage_face_activate(movement_settings_t *settings, void *context);
bool voltage_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void voltage_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t voltage_face = {
voltage_face_setup,
voltage_face_activate,
voltage_face_loop,
voltage_face_resign,
NULL
};
#define voltage_face ((const watch_face_t){ \
voltage_face_setup, \
voltage_face_activate, \
voltage_face_loop, \
voltage_face_resign, \
NULL, \
})
#endif // VOLTAGE_FACE_H_
#endif // VOLTAGE_FACE_H_

View file

@ -32,12 +32,12 @@ void preferences_face_activate(movement_settings_t *settings, void *context);
bool preferences_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void preferences_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t preferences_face = {
preferences_face_setup,
preferences_face_activate,
preferences_face_loop,
preferences_face_resign,
NULL
};
#define preferences_face ((const watch_face_t){ \
preferences_face_setup, \
preferences_face_activate, \
preferences_face_loop, \
preferences_face_resign, \
NULL, \
})
#endif // PREFERENCES_FACE_H_
#endif // PREFERENCES_FACE_H_

View file

@ -32,12 +32,12 @@ void set_time_face_activate(movement_settings_t *settings, void *context);
bool set_time_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void set_time_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t set_time_face = {
set_time_face_setup,
set_time_face_activate,
set_time_face_loop,
set_time_face_resign,
NULL
};
#define set_time_face ((const watch_face_t){ \
set_time_face_setup, \
set_time_face_activate, \
set_time_face_loop, \
set_time_face_resign, \
NULL, \
})
#endif // SET_TIME_FACE_H_

View file

@ -48,12 +48,12 @@ bool thermistor_logging_face_loop(movement_event_t event, movement_settings_t *s
void thermistor_logging_face_resign(movement_settings_t *settings, void *context);
bool thermistor_logging_face_wants_background_task(movement_settings_t *settings, void *context);
static const watch_face_t thermistor_logging_face = {
thermistor_logging_face_setup,
thermistor_logging_face_activate,
thermistor_logging_face_loop,
thermistor_logging_face_resign,
thermistor_logging_face_wants_background_task
};
#define thermistor_logging_face ((const watch_face_t){ \
thermistor_logging_face_setup, \
thermistor_logging_face_activate, \
thermistor_logging_face_loop, \
thermistor_logging_face_resign, \
thermistor_logging_face_wants_background_task, \
})
#endif // THERMISTOR_LOGGING_FACE_H_

View file

@ -32,12 +32,12 @@ void thermistor_readout_face_activate(movement_settings_t *settings, void *conte
bool thermistor_readout_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
void thermistor_readout_face_resign(movement_settings_t *settings, void *context);
static const watch_face_t thermistor_readout_face = {
thermistor_readout_face_setup,
thermistor_readout_face_activate,
thermistor_readout_face_loop,
thermistor_readout_face_resign,
NULL
};
#define thermistor_readout_face ((const watch_face_t){ \
thermistor_readout_face_setup, \
thermistor_readout_face_activate, \
thermistor_readout_face_loop, \
thermistor_readout_face_resign, \
NULL, \
})
#endif // THERMISTOR_READOUT_FACE_H_

View file

@ -4,7 +4,17 @@ OBJS = $(addprefix $(BUILD)/, $(notdir %/$(subst .c,.o, $(SRCS))))
SUBMODULES = tinyusb
ifndef EMSCRIPTEN
all: directory $(SUBMODULES) $(BUILD)/$(BIN).elf $(BUILD)/$(BIN).hex $(BUILD)/$(BIN).bin $(BUILD)/$(BIN).uf2 size
else
all: directory $(SUBMODULES) $(BUILD)/$(BIN).html
endif
$(BUILD)/$(BIN).html: $(OBJS)
@echo HTML $@
@$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ \
-s EXPORTED_FUNCTIONS=_main \
--shell-file=$(TOP)/watch-library/simulator/shell.html
$(BUILD)/$(BIN).elf: $(OBJS)
@echo LD $@

View file

@ -52,9 +52,11 @@ extern "C" {
#include <stdint.h>
#include <stdbool.h>
#ifndef __EMSCRIPTEN__
#ifndef _UNIT_TEST_
#include "parts.h"
#endif
#endif
#include "err_codes.h"
#ifdef __cplusplus

Some files were not shown because too many files have changed in this diff Show more