-I./watch-library/hardware/watch \
-I./watch-faces/clock \
-I./watch-faces/complication \
+ -I./watch-faces/demo \
+ -I./watch-faces/sensor \
-I./watch-faces/settings \
# Add your source files here.
+++ /dev/null
-/*
- * MIT License
- *
- * Copyright (c) 2022 Joey Castillo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "voltage_face.h"
-#include "watch.h"
-
-static void _voltage_face_update_display(void) {
- char buf[14];
-
- watch_enable_adc();
- float voltage = (float)watch_get_vcc_voltage() / 1000.0;
- watch_disable_adc();
-
- sprintf(buf, "BA %4.2f V", voltage);
- // printf("%s\n", buf);
- watch_display_string(buf, 0);
-}
-
-void voltage_face_setup(uint8_t watch_face_index, void ** context_ptr) {
- (void) watch_face_index;
- (void) context_ptr;
-}
-
-void voltage_face_activate(void *context) {
- (void) context;
-}
-
-bool voltage_face_loop(movement_event_t event, void *context) {
- (void) context;
- watch_date_time date_time;
- switch (event.event_type) {
- case EVENT_ACTIVATE:
- _voltage_face_update_display();
- break;
- case EVENT_TICK:
- date_time = watch_rtc_get_date_time();
- if (date_time.unit.second % 5 == 4) {
- watch_set_indicator(WATCH_INDICATOR_SIGNAL);
- } else if (date_time.unit.second % 5 == 0) {
- _voltage_face_update_display();
- watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
- }
- break;
- case EVENT_LOW_ENERGY_UPDATE:
- // clear seconds area and start tick animation if necessary
- if (!watch_sleep_animation_is_running()) {
- watch_display_string(" ", 8);
- watch_start_sleep_animation(1000);
- }
- // update once an hour
- if (date_time.unit.minute == 0) {
- watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
- _voltage_face_update_display();
- watch_display_string(" ", 8);
- }
- break;
- default:
- movement_default_loop_handler(event);
- break;
- }
-
- return true;
-}
-
-void voltage_face_resign(void *context) {
- (void) context;
-}
+++ /dev/null
-/*
- * MIT License
- *
- * Copyright (c) 2022 Joey Castillo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef VOLTAGE_FACE_H_
-#define VOLTAGE_FACE_H_
-
-/*
- * VOLTAGE face
- *
- * This watch face is very simple and has no controls to speak of. It displays
- * the battery voltage as measured by the SAM L22’s ADC.
- *
- * Note that the Simple Clock watch face includes a low battery warning, so you
- * don’t technically need to this watch face unless you want to track the
- * battery level.
- */
-
-#include "movement.h"
-
-void voltage_face_setup(uint8_t watch_face_index, void ** context_ptr);
-void voltage_face_activate(void *context);
-bool voltage_face_loop(movement_event_t event, void *context);
-void voltage_face_resign(void *context);
-
-#define voltage_face ((const watch_face_t){ \
- voltage_face_setup, \
- voltage_face_activate, \
- voltage_face_loop, \
- voltage_face_resign, \
- NULL, \
-})
-
-#endif // VOLTAGE_FACE_H_
advanced_alarm_face,
countdown_face,
fast_stopwatch_face,
+ voltage_face,
preferences_face,
set_time_face,
};
#include "countdown_face.h"
#include "fast_stopwatch_face.h"
#include "sunrise_sunset_face.h"
+#include "float_demo_face.h"
+#include "voltage_face.h"
#include "set_time_face.h"
#include "preferences_face.h"
// New includes go above this line.
./watch-faces/complication/countdown_face.c \
./watch-faces/complication/fast_stopwatch_face.c \
./watch-faces/complication/sunrise_sunset_face.c \
+ ./watch-faces/demo/float_demo_face.c \
+ ./watch-faces/sensor/voltage_face.c \
./watch-faces/settings/set_time_face.c \
./watch-faces/settings/preferences_face.c \
--- /dev/null
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Joey Castillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "float_demo_face.h"
+#include "watch.h"
+
+void float_demo_face_setup(uint8_t watch_face_index, void ** context_ptr) {
+ (void) watch_face_index;
+ if (*context_ptr == NULL) *context_ptr = malloc(sizeof(float));
+}
+
+void float_demo_face_activate(void *context) {
+ float *c = (float *)context;
+ *c = 0;
+ watch_display_text_with_fallback(WATCH_POSITION_TOP, "FLOAT", "FL");
+ movement_request_tick_frequency(32);
+}
+
+bool float_demo_face_loop(movement_event_t event, void *context) {
+ float *c = (float *)context;
+ switch (event.event_type) {
+ case EVENT_TICK:
+ *c = (*c) + 0.11;
+ // fall through
+ case EVENT_ACTIVATE:
+ watch_display_float_with_best_effort(*c, "#F");
+ break;
+ default:
+ movement_default_loop_handler(event);
+ break;
+ }
+
+ return true;
+}
+
+void float_demo_face_resign(void *context) {
+ (void) context;
+}
--- /dev/null
+/*
+ * MIT License
+ *
+ * Copyright (c) 2024 Joey Castillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef FLOAT_DEMO_FACE_H_
+#define FLOAT_DEMO_FACE_H_
+
+/*
+ * FLOAT DEMO
+ *
+ * To be deleted, tests float display functionality.
+ */
+
+#include "movement.h"
+
+void float_demo_face_setup(uint8_t watch_face_index, void ** context_ptr);
+void float_demo_face_activate(void *context);
+bool float_demo_face_loop(movement_event_t event, void *context);
+void float_demo_face_resign(void *context);
+
+#define float_demo_face ((const watch_face_t){ \
+ float_demo_face_setup, \
+ float_demo_face_activate, \
+ float_demo_face_loop, \
+ float_demo_face_resign, \
+ NULL, \
+})
+
+#endif // FLOAT_DEMO_FACE_H_
--- /dev/null
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Joey Castillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "voltage_face.h"
+#include "watch.h"
+
+static void _voltage_face_update_display(void) {
+ watch_enable_adc();
+ float voltage = (float)watch_get_vcc_voltage() / 1000.0;
+ watch_disable_adc();
+
+ watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "BAT", "BA");
+ watch_display_float_with_best_effort(voltage, " V");
+}
+
+void voltage_face_setup(uint8_t watch_face_index, void ** context_ptr) {
+ (void) watch_face_index;
+ (void) context_ptr;
+}
+
+void voltage_face_activate(void *context) {
+ (void) context;
+}
+
+bool voltage_face_loop(movement_event_t event, void *context) {
+ (void) context;
+ watch_date_time date_time;
+ switch (event.event_type) {
+ case EVENT_ACTIVATE:
+ _voltage_face_update_display();
+ break;
+ case EVENT_TICK:
+ date_time = watch_rtc_get_date_time();
+ if (date_time.unit.second % 5 == 4) {
+ watch_set_indicator(WATCH_INDICATOR_SIGNAL);
+ } else if (date_time.unit.second % 5 == 0) {
+ _voltage_face_update_display();
+ watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
+ }
+ break;
+ case EVENT_LOW_ENERGY_UPDATE:
+ // clear seconds area (on classic LCD) and start tick animation if necessary
+ if (!watch_sleep_animation_is_running()) {
+ watch_display_text_with_fallback(WATCH_POSITION_SECONDS, " V", " ");
+ watch_start_sleep_animation(1000);
+ }
+ // update once an hour
+ if (date_time.unit.minute == 0) {
+ watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
+ _voltage_face_update_display();
+ watch_display_text_with_fallback(WATCH_POSITION_SECONDS, " V", " ");
+ }
+ break;
+ default:
+ movement_default_loop_handler(event);
+ break;
+ }
+
+ return true;
+}
+
+void voltage_face_resign(void *context) {
+ (void) context;
+}
--- /dev/null
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Joey Castillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef VOLTAGE_FACE_H_
+#define VOLTAGE_FACE_H_
+
+/*
+ * VOLTAGE face
+ *
+ * This watch face is very simple and has no controls to speak of. It displays
+ * the battery voltage as measured by the SAM L22’s ADC.
+ *
+ * Note that the Simple Clock watch face includes a low battery warning, so you
+ * don’t technically need to this watch face unless you want to track the
+ * battery level.
+ */
+
+#include "movement.h"
+
+void voltage_face_setup(uint8_t watch_face_index, void ** context_ptr);
+void voltage_face_activate(void *context);
+bool voltage_face_loop(movement_event_t event, void *context);
+void voltage_face_resign(void *context);
+
+#define voltage_face ((const watch_face_t){ \
+ voltage_face_setup, \
+ voltage_face_activate, \
+ voltage_face_loop, \
+ voltage_face_resign, \
+ NULL, \
+})
+
+#endif // VOLTAGE_FACE_H_
#include "watch_slcd.h"
#include "watch_common_display.h"
#include <string.h>
+#include <stdio.h>
#ifdef USE_CUSTOM_LCD
static const uint32_t IndicatorSegments[] = {
#endif
}
+void watch_display_float_with_best_effort(float value, const char *units) {
+ char buf[8];
+ char buf_fallback[8];
+ const char *blank_units = " ";
+
+ if (value < 0.0) {
+ watch_clear_decimal_if_available();
+ watch_display_text_with_fallback(WATCH_POSITION_BOTTOM, "Undflo", " Unflo");
+ return;
+ } else if (value > 199.99) {
+ watch_clear_decimal_if_available();
+ watch_display_text(WATCH_POSITION_BOTTOM, "Ovrflo");
+ return;
+ }
+
+ uint16_t value_times_100 = (uint16_t)(value * 100.0);
+ if (value_times_100 > 9999) {
+ snprintf(buf, sizeof(buf), "%5u%s", value_times_100, units ? units : blank_units);
+ snprintf(buf_fallback, sizeof(buf_fallback), "%4.1f%s", value, units ? units : blank_units);
+ } else if (value_times_100 > 999) {
+ snprintf(buf, sizeof(buf), "%4u%s", value_times_100, units ? units : blank_units);
+ snprintf(buf_fallback, sizeof(buf_fallback), "%4.1f%s", value, units ? units : blank_units);
+ } else {
+ snprintf(buf, sizeof(buf), " %03u%s", value_times_100 % 1000u, units ? units : blank_units);
+ snprintf(buf_fallback, sizeof(buf_fallback), "%4.2f%s", value, units ? units : blank_units);
+ }
+
+ watch_display_text_with_fallback(WATCH_POSITION_BOTTOM, buf, buf_fallback);
+ watch_set_decimal_if_available();
+}
+
void watch_set_colon(void) {
#ifdef USE_CUSTOM_LCD
watch_set_pixel(0, 0);
*/
void watch_display_text_with_fallback(watch_position_t location, const char *string, const char *fallback);
+/**
+ * @brief Displays a floating point number as best we can on whatever LCD is available.
+ * @details The custom LCD can energize a decimal point in the same position as the colon. With the leading 1,
+ * we can display numbers from 0.00 to 199.99 with two digits of precision. The original F-91W LCD has
+ * no decimal point, so we use a hyphen to indicate the decimal point. For floats from 0.00 to 9.99,
+ * we can display the number with two digits after the "decimal point" (hyphen). For floats from 10.0
+ * to 99.9, you'll only get one digit after the hyphen. For floats from 100 to 199.9, we'll still give
+ * you one digit after the hyphen, but you'll lose the second character of your units.
+ * @param value A floating point number from 0.00 to 199.99 to display on the main clock digits.
+ * @param units A 1-2 character string to display in the seconds position. Second character may be truncated.
+ */
+void watch_display_float_with_best_effort(float value, const char *units);
+
/** @brief Turns the colon segment on.
*/
void watch_set_colon(void);