summaryrefslogtreecommitdiffstats
path: root/watch-library/watch
diff options
context:
space:
mode:
Diffstat (limited to 'watch-library/watch')
-rw-r--r--watch-library/watch/tusb_config.h91
-rw-r--r--watch-library/watch/watch.c44
-rw-r--r--watch-library/watch/watch.h83
-rw-r--r--watch-library/watch/watch_adc.c179
-rw-r--r--watch-library/watch/watch_adc.h157
-rw-r--r--watch-library/watch/watch_app.h108
-rw-r--r--watch-library/watch/watch_buzzer.c64
-rw-r--r--watch-library/watch/watch_buzzer.h164
-rw-r--r--watch-library/watch/watch_deepsleep.c209
-rw-r--r--watch-library/watch/watch_deepsleep.h159
-rw-r--r--watch-library/watch/watch_extint.c111
-rw-r--r--watch-library/watch/watch_extint.h85
-rw-r--r--watch-library/watch/watch_gpio.c61
-rw-r--r--watch-library/watch/watch_gpio.h76
-rw-r--r--watch-library/watch/watch_i2c.c93
-rw-r--r--watch-library/watch/watch_i2c.h106
-rw-r--r--watch-library/watch/watch_led.c69
-rw-r--r--watch-library/watch/watch_led.h93
-rw-r--r--watch-library/watch/watch_private.c423
-rw-r--r--watch-library/watch/watch_private.h50
-rw-r--r--watch-library/watch/watch_rtc.c195
-rw-r--r--watch-library/watch/watch_rtc.h164
-rw-r--r--watch-library/watch/watch_slcd.c318
-rw-r--r--watch-library/watch/watch_slcd.h151
-rw-r--r--watch-library/watch/watch_uart.c89
-rw-r--r--watch-library/watch/watch_uart.h58
-rw-r--r--watch-library/watch/watch_utility.c172
-rw-r--r--watch-library/watch/watch_utility.h100
28 files changed, 0 insertions, 3672 deletions
diff --git a/watch-library/watch/tusb_config.h b/watch-library/watch/tusb_config.h
deleted file mode 100644
index a22b2b99..00000000
--- a/watch-library/watch/tusb_config.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach (tinyusb.org)
- *
- * 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 _TUSB_CONFIG_H_
-#define _TUSB_CONFIG_H_
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-//--------------------------------------------------------------------
-// COMMON CONFIGURATION
-//--------------------------------------------------------------------
-
-// defined by board.mk
-#define CFG_TUSB_MCU OPT_MCU_SAML22
-
-#define BOARD_DEVICE_RHPORT_NUM 0
-#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED
-#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_FULL_SPEED)
-
-#define CFG_TUSB_OS OPT_OS_NONE
-
-// disable TinyUSB debug. our printf method prints stuff to the USB console, so you just get infinite noise.
-// if you need to debug tinyUSB issues, use the alternate _write function in watch_private.c to echo to the UART.
-#define CFG_TUSB_DEBUG 0
-
-/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
- * Tinyusb use follows macros to declare transferring memory so that they can be put
- * into those specific section.
- * e.g
- * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
- * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
- */
-#ifndef CFG_TUSB_MEM_SECTION
-#define CFG_TUSB_MEM_SECTION
-#endif
-
-#ifndef CFG_TUSB_MEM_ALIGN
-#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
-#endif
-
-//--------------------------------------------------------------------
-// DEVICE CONFIGURATION
-//--------------------------------------------------------------------
-
-#ifndef CFG_TUD_ENDPOINT0_SIZE
-#define CFG_TUD_ENDPOINT0_SIZE 64
-#endif
-
-//------------- CLASS -------------//
-#define CFG_TUD_CDC 1
-#define CFG_TUD_MSC 0
-#define CFG_TUD_HID 0
-#define CFG_TUD_MIDI 0
-#define CFG_TUD_VENDOR 0
-
-// CDC FIFO size of TX and RX
-#define CFG_TUD_CDC_RX_BUFSIZE (64)
-#define CFG_TUD_CDC_TX_BUFSIZE (64)
-
-// CDC Endpoint transfer buffer size, more is faster
-#define CFG_TUD_CDC_EP_BUFSIZE (64)
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* _TUSB_CONFIG_H_ */
diff --git a/watch-library/watch/watch.c b/watch-library/watch/watch.c
deleted file mode 100644
index 791fd974..00000000
--- a/watch-library/watch/watch.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2021 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 "watch.h"
-
-bool battery_is_low = false;
-
-// receives interrupts from MCLK, OSC32KCTRL, OSCCTRL, PAC, PM, SUPC and TAL, whatever that is.
-void SYSTEM_Handler(void) {
- if (SUPC->INTFLAG.bit.BOD33DET) {
- battery_is_low = true;
- SUPC->INTENCLR.bit.BOD33DET = 1;
- SUPC->INTFLAG.reg &= ~SUPC_INTFLAG_BOD33DET;
- }
-}
-
-bool watch_is_battery_low(void) {
- return battery_is_low;
-}
-
-bool watch_is_buzzer_or_led_enabled(void){
- return hri_mclk_get_APBCMASK_TCC0_bit(MCLK);
-}
diff --git a/watch-library/watch/watch.h b/watch-library/watch/watch.h
deleted file mode 100644
index 064f90ec..00000000
--- a/watch-library/watch/watch.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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.
- */
-/// @file watch.h
-
-#ifndef WATCH_H_
-#define WATCH_H_
-#include <stdint.h>
-#include <stdbool.h>
-#include "driver_init.h"
-
-/** @mainpage Sensor Watch Documentation
- * @brief This documentation covers most of the functions you will use to interact with the Sensor Watch
- hardware. It is divided into the following sections:
- - @ref app - This section covers the functions that you will implement in your app.c file when designing a
- Sensor Watch app.
- - @ref rtc - This section covers functions related to the SAM L22's real-time clock peripheral, including
- date, time and alarm functions.
- - @ref slcd - This section covers functions related to the Segment LCD display driver, which is responsible
- for displaying strings of characters and indicators on the main watch display.
- - @ref buttons - This section covers functions related to the three buttons: Light, Mode and Alarm.
- - @ref led - This section covers functions related to the bi-color red/green LED mounted behind the LCD.
- - @ref buzzer - This section covers functions related to the piezo buzzer.
- - @ref adc - This section covers functions related to the SAM L22's analog-to-digital converter, as well as
- configuring and reading values from the five analog-capable pins on the 9-pin connector.
- - @ref gpio - This section covers functions related to general-purpose input and output signals.
- - @ref i2c - This section covers functions related to the SAM L22's built-I2C driver, including configuring
- the I2C bus, putting values directly on the bus and reading data from registers on I2C devices.
- - @ref debug - This section covers functions related to the debug UART, available on pin D1 of the 9-pin connector.
- - @ref deepsleep - This section covers functions related to preparing for and entering BACKUP mode, the
- deepest sleep mode available on the SAM L22.
- */
-
-#include "watch_app.h"
-#include "watch_rtc.h"
-#include "watch_slcd.h"
-#include "watch_extint.h"
-#include "watch_led.h"
-#include "watch_buzzer.h"
-#include "watch_adc.h"
-#include "watch_gpio.h"
-#include "watch_i2c.h"
-#include "watch_uart.h"
-#include "watch_deepsleep.h"
-
-#include "watch_private.h"
-
-/** @brief Returns true when the battery voltage dips below 2.5V.
- * @details A CR2016 battery will have a nominal voltage between 2.9 and 3 volts for most of its lifespan. Once the battery
- * discharges to about 60%, the voltage will drift slightly lower; this may manifest as a dimmer LED. By the time
- * the battery voltage has fallen to 2.5 volts, it will have probably less than 10% of its capacity remaining, and
- * you can expect the voltage to drop relatively quickly as the battery dies.
- */
-bool watch_is_battery_low(void);
-
-/** @brief Returns true if either the buzzer or the LED driver is enabled.
- * @details Both the buzzer and the LED use the TCC peripheral to drive their behavior. This function returns true if that
- * peripheral is enabled. You can use this function to determine whether you need to call the watch_disable_leds or
- * or watch_enable_buzzer functions before using these peripherals.
- */
-bool watch_is_buzzer_or_led_enabled(void);
-
-#endif /* WATCH_H_ */ \ No newline at end of file
diff --git a/watch-library/watch/watch_adc.c b/watch-library/watch/watch_adc.c
deleted file mode 100644
index 5ba7abdf..00000000
--- a/watch-library/watch/watch_adc.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 "watch_adc.h"
-
-static void _watch_sync_adc(void) {
- while (ADC->SYNCBUSY.reg);
-}
-
-static uint16_t _watch_get_analog_value(uint16_t channel) {
- if (ADC->INPUTCTRL.bit.MUXPOS != channel) {
- ADC->INPUTCTRL.bit.MUXPOS = channel;
- _watch_sync_adc();
- }
-
- ADC->SWTRIG.bit.START = 1;
- while (!ADC->INTFLAG.bit.RESRDY);
-
- return ADC->RESULT.reg;
-}
-
-void watch_enable_adc(void) {
- MCLK->APBCMASK.reg |= MCLK_APBCMASK_ADC;
- GCLK->PCHCTRL[ADC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN;
-
- uint16_t calib_reg = 0;
- calib_reg = ADC_CALIB_BIASREFBUF((*(uint32_t *)ADC_FUSES_BIASREFBUF_ADDR >> ADC_FUSES_BIASREFBUF_Pos)) |
- ADC_CALIB_BIASCOMP((*(uint32_t *)ADC_FUSES_BIASCOMP_ADDR >> ADC_FUSES_BIASCOMP_Pos));
-
- if (!ADC->SYNCBUSY.bit.SWRST) {
- if (ADC->CTRLA.bit.ENABLE) {
- ADC->CTRLA.bit.ENABLE = 0;
- _watch_sync_adc();
- }
- ADC->CTRLA.bit.SWRST = 1;
- }
- _watch_sync_adc();
-
- if (USB->DEVICE.CTRLA.bit.ENABLE) {
- // if USB is enabled, we are running an 8 MHz clock.
- // divide by 16 for a 500kHz ADC clock.
- ADC->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV16_Val;
- } else {
- // otherwise it's 4 Mhz. divide by 8 for a 500kHz ADC clock.
- ADC->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV8_Val;
- }
- ADC->CALIB.reg = calib_reg;
- ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC2_Val;
- ADC->INPUTCTRL.bit.MUXNEG = ADC_INPUTCTRL_MUXNEG_GND_Val;
- ADC->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_16BIT_Val;
- ADC->AVGCTRL.bit.SAMPLENUM = ADC_AVGCTRL_SAMPLENUM_16_Val;
- ADC->SAMPCTRL.bit.SAMPLEN = 0;
- ADC->INTENSET.reg = ADC_INTENSET_RESRDY;
- ADC->CTRLA.bit.ENABLE = 1;
- _watch_sync_adc();
- // throw away one measurement after reference change (the channel doesn't matter).
- _watch_get_analog_value(ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC);
-}
-
-void watch_enable_analog_input(const uint8_t pin) {
- gpio_set_pin_direction(pin, GPIO_DIRECTION_OFF);
- switch (pin) {
- case A0:
- gpio_set_pin_function(pin, PINMUX_PB04B_ADC_AIN12);
- break;
- case A1:
- gpio_set_pin_function(pin, PINMUX_PB01B_ADC_AIN9);
- break;
- case A2:
- gpio_set_pin_function(pin, PINMUX_PB02B_ADC_AIN10);
- break;
- case A3:
- gpio_set_pin_function(pin, PINMUX_PB03B_ADC_AIN11);
- break;
- case A4:
- gpio_set_pin_function(pin, PINMUX_PB00B_ADC_AIN8);
- break;
- default:
- return;
- }
-}
-
-uint16_t watch_get_analog_pin_level(const uint8_t pin) {
- switch (pin) {
- case A0:
- return _watch_get_analog_value(ADC_INPUTCTRL_MUXPOS_AIN12_Val);
- case A1:
- return _watch_get_analog_value(ADC_INPUTCTRL_MUXPOS_AIN9_Val);
- case A2:
- return _watch_get_analog_value(ADC_INPUTCTRL_MUXPOS_AIN10_Val);
- case A3:
- return _watch_get_analog_value(ADC_INPUTCTRL_MUXPOS_AIN11_Val);
- case A4:
- return _watch_get_analog_value(ADC_INPUTCTRL_MUXPOS_AIN8_Val);
- default:
- return 0;
- }
-}
-
-void watch_set_analog_num_samples(uint16_t samples) {
- // ignore any input that's not a power of 2 (i.e. only one bit set)
- if (__builtin_popcount(samples) != 1) return;
- // if only one bit is set, counting the trailing zeroes is equivalent to log2(samples)
- uint8_t sample_val = __builtin_ctz(samples);
- // make sure the desired value is within range and set it, if so.
- if (sample_val <= ADC_AVGCTRL_SAMPLENUM_1024_Val) {
- ADC->AVGCTRL.bit.SAMPLENUM = sample_val;
- _watch_sync_adc();
- }
-}
-
-void watch_set_analog_sampling_length(uint8_t cycles) {
- // for clarity the API asks the user how many cycles they want the measurement to take.
- // but the ADC always needs at least one cycle; it just wants to know how many *extra* cycles we want.
- // so we subtract one from the user-provided value, and clamp to the maximum.
- ADC->SAMPCTRL.bit.SAMPLEN = (cycles - 1) & 0x3F;
- _watch_sync_adc();
-}
-
-void watch_set_analog_reference_voltage(watch_adc_reference_voltage reference) {
- ADC->CTRLA.bit.ENABLE = 0;
-
- if (reference == ADC_REFERENCE_INTREF) SUPC->VREF.bit.VREFOE = 1;
- else SUPC->VREF.bit.VREFOE = 0;
-
- ADC->REFCTRL.bit.REFSEL = reference;
- ADC->CTRLA.bit.ENABLE = 1;
- _watch_sync_adc();
- // throw away one measurement after reference change (the channel doesn't matter).
- _watch_get_analog_value(ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC);
-}
-
-uint16_t watch_get_vcc_voltage(void) {
- // stash the previous reference so we can restore it when we're done.
- uint8_t oldref = ADC->REFCTRL.bit.REFSEL;
-
- // if we weren't already using the internal reference voltage, select it now.
- if (oldref != ADC_REFERENCE_INTREF) watch_set_analog_reference_voltage(ADC_REFERENCE_INTREF);
-
- // get the data
- uint32_t raw_val = _watch_get_analog_value(ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC_Val);
-
- // restore the old reference, if needed.
- if (oldref != ADC_REFERENCE_INTREF) watch_set_analog_reference_voltage(oldref);
-
- return (uint16_t)((raw_val * 1000) / (1024 * 1 << ADC->AVGCTRL.bit.SAMPLENUM));
-}
-
-inline void watch_disable_analog_input(const uint8_t pin) {
- gpio_set_pin_function(pin, GPIO_PIN_FUNCTION_OFF);
-}
-
-inline void watch_disable_adc(void) {
- ADC->CTRLA.bit.ENABLE = 0;
- _watch_sync_adc();
-
- MCLK->APBCMASK.reg &= ~MCLK_APBCMASK_ADC;
-}
diff --git a/watch-library/watch/watch_adc.h b/watch-library/watch/watch_adc.h
deleted file mode 100644
index aa7c801a..00000000
--- a/watch-library/watch/watch_adc.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_ADC_H_INCLUDED
-#define _WATCH_ADC_H_INCLUDED
-////< @file watch_adc.h
-
-#include "watch.h"
-
-/** @addtogroup adc Analog Input
- * @brief This section covers functions related to the SAM L22's analog-to-digital converter,
- * as well as configuring and reading values from the five analog-capable pins on the
- * 9-pin connector.
- */
-/// @{
-/** @brief Enables the ADC peripheral. You must call this before attempting to read a value
- * from an analog pin.
- */
-void watch_enable_adc(void);
-
-/** @brief Configures the selected pin for analog input.
- * @param pin One of pins A0-A4.
- */
-void watch_enable_analog_input(const uint8_t pin);
-
-/** @brief Reads an analog value from one of the pins.
- * @param pin One of pins A0-A4.
- * @return a 16-bit unsigned integer from 0-65535 representing the sampled value, unless you
- * have changed the number of samples. @see watch_set_num_analog_samples for details
- * on how that function changes the values returned from this one.
- **/
-uint16_t watch_get_analog_pin_level(const uint8_t pin);
-
-/** @brief Sets the number of samples to accumulate when measuring a pin level. Default is 16.
- * @param samples A power of 2 <= 1024. Specifically: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512
- or 1024. Any other value will be ignored.
- * @details The SAM L22's ADC has a resolution of 12 bits. By default, the watch configures
- * the ADC to take 16 samples of the analog input and accumulate them in the result
- * register; this effectively gives us a 16-bit resolution, at the cost of taking 16
- * ADC cycles to complete a measurement. If you are measuring a slowly changing signal
- * like a thermistor output or an ambient light sensor this is probably fine, even
- * desirable. If you are measuring something a bit more fast-paced, like an analog
- * accelerometer, you may wish to exchange precision for speed. In this case you may
- * call this function to configure the ADC to accumulate fewer samples. HOWEVER! Note
- * that this may change the range of values returned from watch_get_analog_pin_level:
- * - For watch_set_num_analog_samples(1), the returned value will be 12 bits (0-4095).
- * - For watch_set_num_analog_samples(2), the returned value will be 13 bits (0-8191).
- * - For watch_set_num_analog_samples(4), the returned value will be 14 bits (0-16383).
- * - For watch_set_num_analog_samples(8), the returned value will be 15 bits (0-32767).
- * For sampling values over 16, the returned value will still be 16 bits (0-65535); the
- * ADC will automatically divide the measured value by whatever factor is necessary to fit
- * the result in 16 bits.
- * @see watch_get_analog_pin_level
- **/
-void watch_set_analog_num_samples(uint16_t samples);
-
-/** @brief Sets the length of time spent sampling, which allows measurement of higher impedance inputs.
- * Default is 1.
- * @param cycles The number of ADC cycles to sample, between 1 and 64.
- * @see this article by Thea Flowers: https://blog.thea.codes/getting-the-most-out-of-the-samd21-adc/
- * which is where I learned all of this.
- * @details To measure an analog value, the SAM L22 must charge a capacitor to the analog voltage
- * presented at the input. This takes time. Importantly, the higher the input impedance,
- * the more time this takes. As a basic example: if you are using a thermistor tied to
- * VCC to measure temperature, the capacitor has to charge through the thermistor. The
- * higher the resistor value, the higher the input impedance, and the more time we need
- * to allow for the measurement. By default, the ADC is configured to run on a 500 kHz
- * clock with a sample time of one cycle. This is appropriate for an input impedance up
- * to about 28kΩ. Setting the sampling time to 4 cycles allows for an input impedance up
- * to 123kΩ. Setting the sampling time to the maximum of 64 cycles theoretically allows
- * for input impedance up to 2 MΩ. (I based these numbers on the calculator in the linked
- * blog post; it also has a ton of great info on the SAM D21 ADC, which is similar to the
- * SAM L22's).
- **/
-void watch_set_analog_sampling_length(uint8_t cycles);
-
-typedef enum {
- ADC_REFERENCE_INTREF = ADC_REFCTRL_REFSEL_INTREF_Val,
- ADC_REFERENCE_VCC_DIV1POINT6 = ADC_REFCTRL_REFSEL_INTVCC0_Val,
- ADC_REFERENCE_VCC_DIV2 = ADC_REFCTRL_REFSEL_INTVCC1_Val,
- ADC_REFERENCE_VCC = ADC_REFCTRL_REFSEL_INTVCC2_Val,
-} watch_adc_reference_voltage;
-
-
-/** @brief Selects the reference voltage to use for analog readings. Default is ADC_REFERENCE_VCC.
- * @param reference One of ADC_REFERENCE_VCC, ADC_REFERENCE_VCC_DIV1POINT6, ADC_REFERENCE_VCC_DIV2
- * or ADC_REFERENCE_INTREF.
- * @details In order to turn an analog voltage into a 16-bit integer, the ADC needs to compare the
- * measured voltage to a reference point. For example, if you were powering the watch with
- * VCC == 3.0V and you had two 10K resistors connected in series from 3V to GND, you could
- * expect to get 3 volts when you measure the top of the voltage divider, 0 volts at the
- * bottom, and 1.5 volts in the middle. If you read these values uising a reference voltage
- * of ADC_REFERENCE_VCC, the top value would be about 65535, the bottom about 0, and the
- * middle about 32768. However! If we used ADC_REFERENCE_VCC_DIV2 as our reference, we would
- * expect to get 65535 both at the top and the middle, because the largest value the ADC can
- * measure in this configutation is 1.5V (VCC / 2).
- *
- * By changing the reference voltage from ADC_REFERENCE_VCC to ADC_REFERENCE_VCC_DIV1POINT6
- * or ADC_REFERENCE_VCC_DIV2, you can get more resolution when measuring small voltages (i.e.
- * a phototransistor circuit in low light).
- *
- * There is also a special reference voltage called ADC_REFERENCE_INTREF. The SAM L22's
- * Supply Controller provides a selectable voltage reference (by default, 1.024 V) that you
- * can select as a reference voltage for ADC conversions. Unlike the three references we
- * talked about in the last paragraph, this reference voltage does not depend on VCC, which
- * makes it very useful for measuring the battery voltage (since you can't really compare
- * VCC to itself). You can change the INTREF voltage to 2.048 or 4.096 V by poking at the
- * supply controller's VREF register, but the watch library does not support this use case.
- **/
-void watch_set_analog_reference_voltage(watch_adc_reference_voltage reference);
-
-/** @brief Returns the voltage of the VCC supply in millivolts (i.e. 3000 mV == 3.0 V). If running on
- * a coin cell, this will be the battery voltage.
- * @details Unlike other ADC functions, this function does not return a raw value from the ADC, but
- * rather scales it to an actual number of millivolts. This is because the ADC doesn't let
- * us measure VCC per se; it instead lets us measure VCC / 4, and we choose to measure it
- * against the internal reference voltage of 1.024 V. In short, the ADC gives us a number
- * that's complicated to deal with, so we just turn it into a useful number for you :)
- * @note This function depends on INTREF being 1.024V. If you have changed it by poking at the supply
- * controller's VREF.SEL bits, this function will return inaccurate values.
- */
-uint16_t watch_get_vcc_voltage(void);
-
-/** @brief Disables the analog circuitry on the selected pin.
- * @param pin One of pins A0-A4.
- */
-void watch_disable_analog_input(const uint8_t pin);
-
-/** @brief Disables the ADC peripheral.
- * @note You will need to call watch_enable_adc to re-enable the ADC peripheral. When you do, it will
- * have the default settings of 16 samples and 1 measurement cycle; if you customized these
- * parameters, you will need to set them up again.
- **/
-void watch_disable_adc(void);
-
-/// @}
-#endif
diff --git a/watch-library/watch/watch_app.h b/watch-library/watch/watch_app.h
deleted file mode 100644
index 4fa29df8..00000000
--- a/watch-library/watch/watch_app.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_APP_H_INCLUDED
-#define _WATCH_APP_H_INCLUDED
-////< @file watch_app.h
-
-/** @addtogroup app Application Framework
- * @brief This section covers the functions that you will implement in your app.c file when designing a Sensor Watch app.
- * @details You should be able to write a watch app by simply implementing these functions and declaring callbacks for
- * various GPIO and peripheral interrupts. The main.c file takes care of calling these functions for you. The
- * general flow:
- *
- * 1. Your app_init() function is called.
- * - This method should only be used to set your initial application state.
- * 2. If your app is waking from BACKUP, app_wake_from_backup() is called.
- * - If you saved state in the RTC's backup registers, you can restore it here.
- * 3. Your app_setup() method is called.
- * - You may wish to enable some functionality and peripherals here.
- * - You should definitely set up some interrupts here.
- * 4. The main run loop begins: your app_loop() function is called.
- * - Run code and update your UI here.
- * - Return true if your app is prepared to enter STANDBY mode.
- * 5. This step differs depending on the value returned by app_loop:
- * - If you returned false, execution resumes at (4).
- * - If you returned true, app_prepare_for_standby() is called; execution moves on to (6).
- * 6. The microcontroller enters STANDBY mode.
- * - No user code will run, and the watch will enter a low power mode.
- * - The watch will remain in this state until an interrupt wakes it.
- * 7. Once woken from STANDBY, your app_wake_from_standby() function is called.
- * - After this, execution resumes at (4).
- */
-/// @{
-/** @brief A function you will implement to initialize your application state. The app_init function is called before
- * anything else. Use it to set up any internal data structures or application state required by your app,
- * but don't configure any peripherals just yet.
- */
-void app_init(void);
-
-/** @brief A function you will implement to wake from BACKUP mode, which wipes the system's RAM, and with it, your
- * application's state. You may have chosen to store some important application state in the RTC's backup
- * registers prior to entering this mode. You may restore that state here.
- */
-void app_wake_from_backup(void);
-
-/** @brief A function you will implement to set up your application. The app_setup function is like setup() in Arduino.
- * It is called once when the program begins. You should set pin modes and enable any peripherals you want to
- * set up (real-time clock, I2C, etc.) Depending on your application, you may or may not want to configure
- * sensors on your sensor board here. For example, a low-power accelerometer that will run at all times should
- * be configured here, whereas you may want to enable a more power-hungry sensor only when you need it.
- * @note If your app enters the ultra-low power BACKUP sleep mode, this function will be called again when it wakes
- * from that deep sleep state. In this state, the RTC will still be configured with the correct date and time.
- */
-void app_setup(void);
-
-/** @brief A function you will implement to serve as the app's main run loop. This method will be called repeatedly,
- or if you enter STANDBY mode, as soon as the device wakes from sleep.
- * @return You should return true if your app is prepared to enter STANDBY mode. If you return false, your app's
- * app_loop method will be called again immediately. Note that in STANDBY mode, the watch will consume only
- * about 95 microamperes of power, whereas if you return false and keep the app awake, it will consume about
- * 355 microamperes. This is the difference between months of battery life and days. As much as possible,
- * you should limit the amount of time your app spends awake.
- * @note Only the RTC, the segment LCD controller and the external interrupt controller run in STANDBY mode. If you
- * are using, e.g. the PWM function to set a custom LED color, you should return false here until you are
- * finished with that operation. Note however that the peripherals will continue running after waking up,
- * so e.g. the I2C controller, if configured, will sleep in STANDBY. But you can use it again as soon as your
- * app wakes up.
- */
-bool app_loop(void);
-
-/** @brief A function you will implement to prepare to enter STANDBY mode. The app_prepare_for_standby function is
- * called after your app_loop function returns true, and just before the watch enters STANDBY mode. In this
- * mode most peripherals are shut down, and no code will run until the watch receives an interrupt (generally
- * either the 1Hz tick or a press on one of the buttons).
- * @note If you are PWM'ing the LED or playing a sound on the buzzer, the TC/TCC peripherals that drive those operations
- * will not run in STANDBY. BUT! the output pins will retain the state they had when entering standby. This means
- * you could end up entering standby with an LED on and draining power, or with a DC potential across the piezo
- * buzzer that could damage it if left in this state. If your app_loop does not prevent sleep during these
- * activities, you should make sure to disable these outputs in app_prepare_for_standby.
- */
-void app_prepare_for_standby(void);
-
-/** @brief A method you will implement to configure the app after waking from STANDBY mode.
- */
-void app_wake_from_standby(void);
-
-/// @}
-#endif
diff --git a/watch-library/watch/watch_buzzer.c b/watch-library/watch/watch_buzzer.c
deleted file mode 100644
index a275b00d..00000000
--- a/watch-library/watch/watch_buzzer.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 "watch_buzzer.h"
-
- inline void watch_enable_buzzer(void) {
- if (!hri_tcc_get_CTRLA_reg(TCC0, TCC_CTRLA_ENABLE)) {
- _watch_enable_tcc();
- }
-}
-inline void watch_set_buzzer_period(uint32_t period) {
- hri_tcc_write_PERBUF_reg(TCC0, period);
-}
-
-void watch_disable_buzzer(void) {
- _watch_disable_tcc();
-}
-
-inline void watch_set_buzzer_on(void) {
- gpio_set_pin_direction(BUZZER, GPIO_DIRECTION_OUT);
- gpio_set_pin_function(BUZZER, WATCH_BUZZER_TCC_PINMUX);
-}
-
-inline void watch_set_buzzer_off(void) {
- gpio_set_pin_direction(BUZZER, GPIO_DIRECTION_OFF);
- gpio_set_pin_function(BUZZER, GPIO_PIN_FUNCTION_OFF);
-}
-
-// note: the buzzer uses a 1 MHz clock. these values were determined by dividing 1,000,000 by the target frequency.
-// i.e. for a 440 Hz tone (A4 on the piano), 1MHz/440Hz = 2273
-const uint16_t NotePeriods[108] = {18182,17161,16197,15288,14430,13620,12857,12134,11453,10811,10204,9631,9091,8581,8099,7645,7216,6811,6428,6068,5727,5405,5102,4816,4545,4290,4050,3822,3608,3405,3214,3034,2863,2703,2551,2408,2273,2145,2025,1911,1804,1703,1607,1517,1432,1351,1276,1204,1136,1073,1012,956,902,851,804,758,716,676,638,602,568,536,506,478,451,426,402,379,358,338,319,301,284,268,253,239,225,213,201,190,179,169,159,150,142,134,127};
-
-void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms) {
- if (note == BUZZER_NOTE_REST) {
- watch_set_buzzer_off();
- } else {
- hri_tcc_write_PERBUF_reg(TCC0, NotePeriods[note]);
- hri_tcc_write_CCBUF_reg(TCC0, WATCH_BUZZER_TCC_CHANNEL, NotePeriods[note] / 2);
- watch_set_buzzer_on();
- }
- delay_ms(duration_ms);
- watch_set_buzzer_off();
-}
diff --git a/watch-library/watch/watch_buzzer.h b/watch-library/watch/watch_buzzer.h
deleted file mode 100644
index 1b5d197c..00000000
--- a/watch-library/watch/watch_buzzer.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_BUZZER_H_INCLUDED
-#define _WATCH_BUZZER_H_INCLUDED
-////< @file watch_buzzer.h
-
-#include "watch.h"
-
-/** @addtogroup buzzer Buzzer
- * @brief This section covers functions related to the piezo buzzer embedded in the F-91W's back plate.
- */
-/// @{
-/** @brief Enables the TCC peripheral, which drives the buzzer.
- */
-void watch_enable_buzzer(void);
-
-/** @brief Sets the period of the buzzer.
- * @param period The period of a single cycle for the TCC peripheral. You can determine the period for
- * a desired frequency with the following formula: period = 1000000 / freq
- */
-void watch_set_buzzer_period(uint32_t period);
-
-/** @brief Disables the TCC peripheral that drives the buzzer.
- * @note If you are using PWM to set custom LED colors, this method will also disable the LED PWM driver,
- * since the buzzer and LED both make use of the same peripheral to drive their PWM behavior.
- */
-void watch_disable_buzzer(void);
-
-/** @brief Turns the buzzer output on. It will emit a continuous sound at the given frequency.
- * @note The TCC peripheral that drives the buzzer does not run in standby mode; if you wish for buzzer
- * output to continue, you should prevent your app from going to sleep.
- */
-void watch_set_buzzer_on(void);
-
-/** @brief Turns the buzzer output off.
- */
-void watch_set_buzzer_off(void);
-
-/// @brief 87 notes for use with watch_buzzer_play_note
-typedef enum BuzzerNote {
- BUZZER_NOTE_A1, ///< 55.00 Hz
- BUZZER_NOTE_A1SHARP_B1FLAT, ///< 58.27 Hz
- BUZZER_NOTE_B1, ///< 61.74 Hz
- BUZZER_NOTE_C2, ///< 65.41 Hz
- BUZZER_NOTE_C2SHARP_D2FLAT, ///< 69.30 Hz
- BUZZER_NOTE_D2, ///< 73.42 Hz
- BUZZER_NOTE_D2SHARP_E2FLAT, ///< 77.78 Hz
- BUZZER_NOTE_E2, ///< 82.41 Hz
- BUZZER_NOTE_F2, ///< 87.31 Hz
- BUZZER_NOTE_F2SHARP_G2FLAT, ///< 92.50 Hz
- BUZZER_NOTE_G2, ///< 98.00 Hz
- BUZZER_NOTE_G2SHARP_A2FLAT, ///< 103.83 Hz
- BUZZER_NOTE_A2, ///< 110.00 Hz
- BUZZER_NOTE_A2SHARP_B2FLAT, ///< 116.54 Hz
- BUZZER_NOTE_B2, ///< 123.47 Hz
- BUZZER_NOTE_C3, ///< 130.81 Hz
- BUZZER_NOTE_C3SHARP_D3FLAT, ///< 138.59 Hz
- BUZZER_NOTE_D3, ///< 146.83 Hz
- BUZZER_NOTE_D3SHARP_E3FLAT, ///< 155.56 Hz
- BUZZER_NOTE_E3, ///< 164.81 Hz
- BUZZER_NOTE_F3, ///< 174.61 Hz
- BUZZER_NOTE_F3SHARP_G3FLAT, ///< 185.00 Hz
- BUZZER_NOTE_G3, ///< 196.00 Hz
- BUZZER_NOTE_G3SHARP_A3FLAT, ///< 207.65 Hz
- BUZZER_NOTE_A3, ///< 220.00 Hz
- BUZZER_NOTE_A3SHARP_B3FLAT, ///< 233.08 Hz
- BUZZER_NOTE_B3, ///< 246.94 Hz
- BUZZER_NOTE_C4, ///< 261.63 Hz
- BUZZER_NOTE_C4SHARP_D4FLAT, ///< 277.18 Hz
- BUZZER_NOTE_D4, ///< 293.66 Hz
- BUZZER_NOTE_D4SHARP_E4FLAT, ///< 311.13 Hz
- BUZZER_NOTE_E4, ///< 329.63 Hz
- BUZZER_NOTE_F4, ///< 349.23 Hz
- BUZZER_NOTE_F4SHARP_G4FLAT, ///< 369.99 Hz
- BUZZER_NOTE_G4, ///< 392.00 Hz
- BUZZER_NOTE_G4SHARP_A4FLAT, ///< 415.30 Hz
- BUZZER_NOTE_A4, ///< 440.00 Hz
- BUZZER_NOTE_A4SHARP_B4FLAT, ///< 466.16 Hz
- BUZZER_NOTE_B4, ///< 493.88 Hz
- BUZZER_NOTE_C5, ///< 523.25 Hz
- BUZZER_NOTE_C5SHARP_D5FLAT, ///< 554.37 Hz
- BUZZER_NOTE_D5, ///< 587.33 Hz
- BUZZER_NOTE_D5SHARP_E5FLAT, ///< 622.25 Hz
- BUZZER_NOTE_E5, ///< 659.25 Hz
- BUZZER_NOTE_F5, ///< 698.46 Hz
- BUZZER_NOTE_F5SHARP_G5FLAT, ///< 739.99 Hz
- BUZZER_NOTE_G5, ///< 783.99 Hz
- BUZZER_NOTE_G5SHARP_A5FLAT, ///< 830.61 Hz
- BUZZER_NOTE_A5, ///< 880.00 Hz
- BUZZER_NOTE_A5SHARP_B5FLAT, ///< 932.33 Hz
- BUZZER_NOTE_B5, ///< 987.77 Hz
- BUZZER_NOTE_C6, ///< 1046.50 Hz
- BUZZER_NOTE_C6SHARP_D6FLAT, ///< 1108.73 Hz
- BUZZER_NOTE_D6, ///< 1174.66 Hz
- BUZZER_NOTE_D6SHARP_E6FLAT, ///< 1244.51 Hz
- BUZZER_NOTE_E6, ///< 1318.51 Hz
- BUZZER_NOTE_F6, ///< 1396.91 Hz
- BUZZER_NOTE_F6SHARP_G6FLAT, ///< 1479.98 Hz
- BUZZER_NOTE_G6, ///< 1567.98 Hz
- BUZZER_NOTE_G6SHARP_A6FLAT, ///< 1661.22 Hz
- BUZZER_NOTE_A6, ///< 1760.00 Hz
- BUZZER_NOTE_A6SHARP_B6FLAT, ///< 1864.66 Hz
- BUZZER_NOTE_B6, ///< 1975.53 Hz
- BUZZER_NOTE_C7, ///< 2093.00 Hz
- BUZZER_NOTE_C7SHARP_D7FLAT, ///< 2217.46 Hz
- BUZZER_NOTE_D7, ///< 2349.32 Hz
- BUZZER_NOTE_D7SHARP_E7FLAT, ///< 2489.02 Hz
- BUZZER_NOTE_E7, ///< 2637.02 Hz
- BUZZER_NOTE_F7, ///< 2793.83 Hz
- BUZZER_NOTE_F7SHARP_G7FLAT, ///< 2959.96 Hz
- BUZZER_NOTE_G7, ///< 3135.96 Hz
- BUZZER_NOTE_G7SHARP_A7FLAT, ///< 3322.44 Hz
- BUZZER_NOTE_A7, ///< 3520.00 Hz
- BUZZER_NOTE_A7SHARP_B7FLAT, ///< 3729.31 Hz
- BUZZER_NOTE_B7, ///< 3951.07 Hz
- BUZZER_NOTE_C8, ///< 4186.01 Hz
- BUZZER_NOTE_C8SHARP_D8FLAT, ///< 4434.92 Hz
- BUZZER_NOTE_D8, ///< 4698.63 Hz
- BUZZER_NOTE_D8SHARP_E8FLAT, ///< 4978.03 Hz
- BUZZER_NOTE_E8, ///< 5274.04 Hz
- BUZZER_NOTE_F8, ///< 5587.65 Hz
- BUZZER_NOTE_F8SHARP_G8FLAT, ///< 5919.91 Hz
- BUZZER_NOTE_G8, ///< 6271.93 Hz
- BUZZER_NOTE_G8SHARP_A8FLAT, ///< 6644.88 Hz
- BUZZER_NOTE_A8, ///< 7040.00 Hz
- BUZZER_NOTE_A8SHARP_B8FLAT, ///< 7458.62 Hz
- BUZZER_NOTE_B8, ///< 7902.13 Hz
- BUZZER_NOTE_REST ///< no sound
-} BuzzerNote;
-
-/** @brief Plays the given note for a set duration.
- * @param note The note you wish to play, or BUZZER_NOTE_REST to disable output for the given duration.
- * @param duration_ms The duration of the note.
- * @note Note that this will block your UI for the duration of the note's play time, and it will
- * after this call, the buzzer period will be set to the period of this note.
- */
-void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms);
-
-/// @brief An array of periods for all the notes on a piano, corresponding to the names in BuzzerNote.
-extern const uint16_t NotePeriods[108];
-
-/// @}
-#endif
diff --git a/watch-library/watch/watch_deepsleep.c b/watch-library/watch/watch_deepsleep.c
deleted file mode 100644
index 1813ff24..00000000
--- a/watch-library/watch/watch_deepsleep.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 "watch_extint.h"
-
-// this warning only appears when you `make BOARD=OSO-SWAT-A1-02`. it's annoying,
-// but i'd rather have it warn us at build-time than fail silently at run-time.
-// besides, no one but me really has any of these boards anyway.
-#if BTN_ALARM != GPIO(GPIO_PORTA, 2)
-#warning This board revision does not support external wake on BTN_ALARM, so watch_register_extwake_callback will not work with it. Use watch_register_interrupt_callback instead.
-#endif
-
-void watch_register_extwake_callback(uint8_t pin, ext_irq_cb_t callback, bool level) {
- uint32_t pinmux;
- hri_rtc_tampctrl_reg_t config = RTC->MODE2.TAMPCTRL.reg;
-
- switch (pin) {
- case A4:
- a4_callback = callback;
- pinmux = PINMUX_PB00G_RTC_IN0;
- config &= ~(3 << RTC_TAMPCTRL_IN0ACT_Pos);
- config &= ~(1 << RTC_TAMPCTRL_TAMLVL0_Pos);
- config |= 1 << RTC_TAMPCTRL_IN0ACT_Pos;
- config |= 1 << RTC_TAMPCTRL_DEBNC0_Pos;
- if (level) config |= 1 << RTC_TAMPCTRL_TAMLVL0_Pos;
- break;
- case A2:
- a2_callback = callback;
- pinmux = PINMUX_PB02G_RTC_IN1;
- config &= ~(3 << RTC_TAMPCTRL_IN1ACT_Pos);
- config &= ~(1 << RTC_TAMPCTRL_TAMLVL1_Pos);
- config |= 1 << RTC_TAMPCTRL_IN1ACT_Pos;
- config |= 1 << RTC_TAMPCTRL_DEBNC1_Pos;
- if (level) config |= 1 << RTC_TAMPCTRL_TAMLVL1_Pos;
- break;
- case BTN_ALARM:
- gpio_set_pin_pull_mode(pin, GPIO_PULL_DOWN);
- btn_alarm_callback = callback;
- pinmux = PINMUX_PA02G_RTC_IN2;
- config &= ~(3 << RTC_TAMPCTRL_IN2ACT_Pos);
- config &= ~(1 << RTC_TAMPCTRL_TAMLVL2_Pos);
- config |= 1 << RTC_TAMPCTRL_IN2ACT_Pos;
- config |= 1 << RTC_TAMPCTRL_DEBNC2_Pos;
- if (level) config |= 1 << RTC_TAMPCTRL_TAMLVL2_Pos;
- break;
- default:
- return;
- }
- gpio_set_pin_direction(pin, GPIO_DIRECTION_IN);
- gpio_set_pin_function(pin, pinmux);
-
- // disable the RTC
- RTC->MODE2.CTRLA.bit.ENABLE = 0;
- while (RTC->MODE2.SYNCBUSY.bit.ENABLE);
-
- // update the configuration
- RTC->MODE2.TAMPCTRL.reg = config;
- // re-enable the RTC
- RTC->MODE2.CTRLA.bit.ENABLE = 1;
-
- NVIC_ClearPendingIRQ(RTC_IRQn);
- NVIC_EnableIRQ(RTC_IRQn);
- RTC->MODE2.INTENSET.reg = RTC_MODE2_INTENSET_TAMPER;
-}
-
-void watch_disable_extwake_interrupt(uint8_t pin) {
- hri_rtc_tampctrl_reg_t config = hri_rtc_get_TAMPCTRL_reg(RTC, 0xFFFFFFFF);
-
- switch (pin) {
- case A4:
- a4_callback = NULL;
- config &= ~(3 << RTC_TAMPCTRL_IN0ACT_Pos);
- break;
- case A2:
- a2_callback = NULL;
- config &= ~(3 << RTC_TAMPCTRL_IN1ACT_Pos);
- break;
- case BTN_ALARM:
- btn_alarm_callback = NULL;
- config &= ~(3 << RTC_TAMPCTRL_IN2ACT_Pos);
- break;
- default:
- return;
- }
-
- if (hri_rtcmode0_get_CTRLA_ENABLE_bit(RTC)) {
- hri_rtcmode0_clear_CTRLA_ENABLE_bit(RTC);
- hri_rtcmode0_wait_for_sync(RTC, RTC_MODE0_SYNCBUSY_ENABLE);
- }
- hri_rtc_write_TAMPCTRL_reg(RTC, config);
- hri_rtcmode0_set_CTRLA_ENABLE_bit(RTC);
-}
-
-void watch_store_backup_data(uint32_t data, uint8_t reg) {
- if (reg < 8) {
- RTC->MODE0.BKUP[reg].reg = data;
- }
-}
-
-uint32_t watch_get_backup_data(uint8_t reg) {
- if (reg < 8) {
- return RTC->MODE0.BKUP[reg].reg;
- }
-
- return 0;
-}
-
-static void _watch_disable_all_pins_except_rtc(void) {
- uint32_t config = RTC->MODE0.TAMPCTRL.reg;
- uint32_t portb_pins_to_disable = 0xFFFFFFFF;
-
- // if there's an action set on RTC/IN[0], leave PB00 configured
- if (config & RTC_TAMPCTRL_IN0ACT_Msk) portb_pins_to_disable &= 0xFFFFFFFE;
- // same with RTC/IN[1] and PB02
- if (config & RTC_TAMPCTRL_IN1ACT_Msk) portb_pins_to_disable &= 0xFFFFFFFB;
-
- // port A: always keep PA02 configured as-is; that's our ALARM button.
- gpio_set_port_direction(0, 0xFFFFFFFB, GPIO_DIRECTION_OFF);
- // port B: disable all pins we didn't save above.
- gpio_set_port_direction(1, portb_pins_to_disable, GPIO_DIRECTION_OFF);
-}
-
-static void _watch_disable_all_peripherals_except_slcd(void) {
- _watch_disable_tcc();
- watch_disable_adc();
- watch_disable_external_interrupts();
- watch_disable_i2c();
- // TODO: replace this with a proper function when we remove the debug UART
- SERCOM3->USART.CTRLA.reg &= ~SERCOM_USART_CTRLA_ENABLE;
- MCLK->APBCMASK.reg &= ~MCLK_APBCMASK_SERCOM3;
-}
-
-void watch_enter_sleep_mode(void) {
- // disable all other peripherals
- _watch_disable_all_peripherals_except_slcd();
-
- // disable tick interrupt
- watch_rtc_disable_all_periodic_callbacks();
-
- // disable brownout detector interrupt, which could inadvertently wake us up.
- SUPC->INTENCLR.bit.BOD33DET = 1;
-
- // disable all pins
- _watch_disable_all_pins_except_rtc();
-
- // enter standby (4); we basically hang out here until an interrupt wakes us.
- sleep(4);
-
- // and we awake! re-enable the brownout detector
- SUPC->INTENSET.bit.BOD33DET = 1;
-
- // call app_setup so the app can re-enable everything we disabled.
- app_setup();
-
- // and call app_wake_from_standby (since main won't have a chance to do it)
- app_wake_from_standby();
-}
-
-void watch_enter_deep_sleep_mode(void) {
- // identical to sleep mode except we disable the LCD first.
- slcd_sync_deinit(&SEGMENT_LCD_0);
- hri_mclk_clear_APBCMASK_SLCD_bit(SLCD);
-
- watch_enter_sleep_mode();
-}
-
-void watch_enter_backup_mode(void) {
- watch_rtc_disable_all_periodic_callbacks();
- _watch_disable_all_peripherals_except_slcd();
- slcd_sync_deinit(&SEGMENT_LCD_0);
- hri_mclk_clear_APBCMASK_SLCD_bit(SLCD);
- _watch_disable_all_pins_except_rtc();
-
- // go into backup sleep mode (5). when we exit, the reset controller will take over.
- sleep(5);
-}
-
-// deprecated
-void watch_enter_shallow_sleep(bool display_on) {
- if (display_on) watch_enter_sleep_mode();
- else watch_enter_deep_sleep_mode();
-}
-
-// deprecated
-void watch_enter_deep_sleep(void) {
- watch_register_extwake_callback(BTN_ALARM, NULL, true);
- watch_enter_backup_mode();
-}
diff --git a/watch-library/watch/watch_deepsleep.h b/watch-library/watch/watch_deepsleep.h
deleted file mode 100644
index 56d75478..00000000
--- a/watch-library/watch/watch_deepsleep.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_DEEPSLEEP_H_INCLUDED
-#define _WATCH_DEEPSLEEP_H_INCLUDED
-////< @file watch_deepsleep.h
-
-#include "watch.h"
-
-// These are declared in watch_rtc.c.
-extern ext_irq_cb_t btn_alarm_callback;
-extern ext_irq_cb_t a2_callback;
-extern ext_irq_cb_t a4_callback;
-
-/** @addtogroup deepsleep Sleep Control
- * @brief This section covers functions related to the various sleep modes available to the watch,
- * including Sleep, Deep Sleep, and BACKUP mode.
- * @details These terms changed meaning a bit over the course of development; if you are coming
- * to this documentation after having worked with an earlier version of the library,
- * these definitions should clarify the terminology. Terms in all caps are modes of the
- * SAM L22; terms in Title Case are specific implementations in this library.
- * - ACTIVE mode is the mode the SAM L22 is in when both the main clock and the CPU are
- * running. It is the most power-hungry mode. If you ever call delay_ms to wait a beat,
- * the watch will remain in ACTIVE mode while taking that delay. In addition, whenever
- * your `app_loop` function returns false, the device will remain in ACTIVE mode and
- * call your `app_loop` function again.
- * - STANDBY mode turns off the main clock and halts the CPU. Since the PWM driver is
- * run from the main clock, it also stops the buzzer and any dimming of the LEDs.
- * In this mode, the watch can wake from any interrupt source. Whenever your `app_loop`
- * function returns true, the watch enters STANDBY mode until the next tick or other
- * interrupt. This mode uses much less power than ACTIVE mode.
- * - Sleep Mode is a special case of STANDBY mode. In this mode, the watch turns off
- * almost all peripherals (including the external interrupt controller), and disables
- * all pins except for the external wake pins. In this mode the watch can only wake
- * from the RTC alarm interrupt or an external wake pin (A2, A4 or the alarm button),
- * but the display remains on and your app's state is retained. You can enter this
- * mode by calling `watch_enter_sleep_mode`. It consumes an order of magnitude less
- * power than STANDBY mode.
- * - Deep Sleep Mode is identical to sleep mode, but it also turns off the LCD to save
- * a bit more power. You can enter this mode by calling `watch_enter_deep_sleep_mode`.
- * - BACKUP mode is the lowest possible power mode on the SAM L22. It turns off all pins
- * and peripherals except for the RTC. It also turns off the RAM, obliterating your
- * application's state. The only way to wake from this mode is by setting an external
- * wake interrupt on pin A2 or pin A4, and when you do wake it will be much like a
- * wake from reset. You can enter this mode by calling `watch_enter_backup_mode`.
- */
-/// @{
-
-/** @brief Registers a callback on one of the RTC's external wake pins, which can wake the device
- * from Sleep, Deep Sleep and BACKUP modes (but see warning re: BACKUP mode).
- * @param pin Either pin BTN_ALARM, A2, or A4. These are the three external wake pins. If the pin
- * is BTN_ALARM, this function also enables an internal pull down on that pin.
- * @param callback The callback to be called if this pin triggers outside of BACKUP mode. If this is
- * NULL, no callback will be called even in normal modes, but the interrupt will
- * still be enabled so that it can wake the device.
- * @param level The level you wish to scan for: true for rising, false for falling. Note that you
- * cannot scan for both rising and falling edges like you can with the external interrupt
- * pins; with the external wake interrupt, you can only get one or the other.
- * @note When in ACTIVE, STANDBY and Sleep / Deep sleep modes, this will function much like a standard
- * external interrupt situation: these pins will wake the device, and your callback will be
- * called. However, if the device enters BACKUP mode and one of these pins wakes the device, your
- * callback WILL NOT be called, as the device is basically waking from reset at that point.
- * @warning As of the current SAM L22 silicon revision (rev B), the BTN_ALARM pin cannot wake the
- * device from BACKUP mode. You can still use this function to register a BTN_ALARM interrupt
- * in normal or deep sleep mode, but to wake from BACKUP, you will need to use pin A2 or A4.
- */
-void watch_register_extwake_callback(uint8_t pin, ext_irq_cb_t callback, bool level);
-
-/** @brief Unregisters the RTC interrupt on one of the EXTWAKE pins. This will prevent a value change on
- * one of these pins from waking the device.
- * @param pin Either pin BTN_ALARM, A2, or A4. If the pin is BTN_ALARM, this function DOES NOT disable
- * the internal pull down on that pin.
- */
-void watch_disable_extwake_interrupt(uint8_t pin);
-
-/** @brief Stores data in one of the RTC's backup registers, which retain their data in BACKUP mode.
- * @param data An unsigned 32 bit integer with the data you wish to store.
- * @param reg A register from 0-7.
- */
-void watch_store_backup_data(uint32_t data, uint8_t reg);
-
-/** @brief Gets 32 bits of data from the RTC's BACKUP register.
- * @param reg A register from 0-7.
- * @return An unsigned 32 bit integer with the from the backup register.
- */
-uint32_t watch_get_backup_data(uint8_t reg);
-
-/** @brief enters Sleep Mode by disabling all pins and peripherals except the RTC and the LCD.
- * @details This sleep mode is not the lowest power mode available, but it has the benefit of allowing you
- * to display a message to the user while asleep. You can also set an alarm interrupt to wake at a
- * configfurable interval (every minute, hour or day) to update the display. You can wake from this
- * mode by pressing the ALARM button, if you registered an extwake callback on the ALARM button.
- * Also note that when your app wakes from this sleep mode, your app_setup method will be called
- * again, since this function will have disabled things you set up there.
- *
- * Note that to wake from either the ALARM button, the A2 interrupt or the A4 interrupt, you
- * must first configure this by calling watch_register_extwake_callback.
- *
- * You can estimate the power consumption of this mode to be on the order of 30 microwatts
- * (about 10 µA at 3 V).
- */
-void watch_enter_sleep_mode(void);
-
-/** @brief enters Deep Sleep Mode by disabling all pins and peripherals except the RTC.
- * @details Short of BACKUP mode, this is the lowest power mode you can enter while retaining your
- * application state (and the ability to wake with the alarm button). Just note that the display
- * will be completely off, so you should document to the user of your application that they will
- * need to press the alarm button to wake the device, or use a sensor board with support for
- * an external wake pin.
- *
- * All notes from watch_enter_sleep_mode apply here, except for power consumption. You can estimate
- * the power consumption of this mode to be on the order of 12 microwatts (about 4µA at 3 V).
- */
-void watch_enter_deep_sleep_mode(void);
-
-/** @brief Enters the SAM L22's lowest-power mode, BACKUP.
- * @details This function does some housekeeping before entering BACKUP mode. It first disables all pins
- * and peripherals except for the RTC, and disables the tick interrupt (since that would wake
- * us up from BACKUP mode). Once again, if you wish to wake from the A2 or the A4 interrupt,
- * you must first configure this by calling watch_register_extwake_callback.
- * @note If you have a callback set for an external wake interrupt, it will be called if triggered while
- * in ACTIVE, STANDBY, Sleep and Deep Sleep modes, but it *will not be called* when waking from
- * BACKUP mode. Waking from backup is effectively like waking from reset, except that your
- * @ref app_wake_from_backup function will be called.
- * @warning On current revisions of the SAM L22 silicon, the ALARM_BTN pin (PA02 RTC/IN2) cannot wake
- * the device from deep sleep mode. There is an errata note (Reference: 15010) that says that
- * due to a silicon bug, RTC/IN2 is not functional in BACKUP. As a result, you should not call
- * this function unless you have a device on the nine-pin connector with an external interrupt
- * on pin A2 or A4 (i.e. an accelerometer with an interrupt pin).
- */
-void watch_enter_backup_mode(void);
-
-__attribute__((deprecated("Use watch_enter_sleep_mode or watch_enter_deep_sleep_mode instead")))
-void watch_enter_shallow_sleep(bool display_on);
-
-__attribute__((deprecated("Use watch_enter_backup_mode instead")))
-void watch_enter_deep_sleep(void);
-/// @}
-#endif
diff --git a/watch-library/watch/watch_extint.c b/watch-library/watch/watch_extint.c
deleted file mode 100644
index 5924b646..00000000
--- a/watch-library/watch/watch_extint.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 "watch_extint.h"
-
-void watch_enable_external_interrupts(void) {
- // Configure EIC to use GCLK3 (the 32.768 kHz crystal)
- hri_gclk_write_PCHCTRL_reg(GCLK, EIC_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos));
- // Enable AHB clock for the EIC
- hri_mclk_set_APBAMASK_EIC_bit(MCLK);
- // call HAL's external interrupt init function
- ext_irq_init();
-}
-
-void watch_disable_external_interrupts(void) {
- ext_irq_deinit();
- hri_mclk_clear_APBAMASK_EIC_bit(MCLK);
-}
-
-void watch_register_interrupt_callback(const uint8_t pin, ext_irq_cb_t callback, watch_interrupt_trigger trigger) {
- uint8_t config_index;
- uint8_t sense_pos;
- switch (pin) {
- case A0:
- // for EIC channels 8-15, we need to set the SENSE value in CONFIG[1]
- config_index = (WATCH_A0_EIC_CHANNEL > 7) ? 1 : 0;
- // either way the index in CONFIG[n] must be 0-7
- sense_pos = 4 * (WATCH_A0_EIC_CHANNEL % 8);
- break;
- case A1:
- config_index = (WATCH_A1_EIC_CHANNEL > 7) ? 1 : 0;
- sense_pos = 4 * (WATCH_A1_EIC_CHANNEL % 8);
- break;
- case A2:
- config_index = (WATCH_A2_EIC_CHANNEL > 7) ? 1 : 0;
- sense_pos = 4 * (WATCH_A2_EIC_CHANNEL % 8);
- break;
- case A3:
- config_index = (WATCH_A3_EIC_CHANNEL > 7) ? 1 : 0;
- sense_pos = 4 * (WATCH_A3_EIC_CHANNEL % 8);
- break;
- case A4:
- config_index = (WATCH_A4_EIC_CHANNEL > 7) ? 1 : 0;
- sense_pos = 4 * (WATCH_A4_EIC_CHANNEL % 8);
- break;
- case BTN_ALARM:
- config_index = (WATCH_BTN_ALARM_EIC_CHANNEL > 7) ? 1 : 0;
- sense_pos = 4 * (WATCH_BTN_ALARM_EIC_CHANNEL % 8);
- break;
- case BTN_LIGHT:
- config_index = (WATCH_BTN_LIGHT_EIC_CHANNEL > 7) ? 1 : 0;
- sense_pos = 4 * (WATCH_BTN_LIGHT_EIC_CHANNEL % 8);
- break;
- case BTN_MODE:
- config_index = (WATCH_BTN_MODE_EIC_CHANNEL > 7) ? 1 : 0;
- sense_pos = 4 * (WATCH_BTN_MODE_EIC_CHANNEL % 8);
- break;
- default:
- return;
- }
-
- gpio_set_pin_direction(pin, GPIO_DIRECTION_IN);
-
- // EIC configuration register is enable-protected, so we have to disable it first...
- if (hri_eic_get_CTRLA_reg(EIC, EIC_CTRLA_ENABLE)) {
- hri_eic_clear_CTRLA_ENABLE_bit(EIC);
- // ...and wait for it to synchronize.
- hri_eic_wait_for_sync(EIC, EIC_SYNCBUSY_ENABLE);
- }
- // now update the configuration...
- hri_eic_config_reg_t config = EIC->CONFIG[config_index].reg;
- config &= ~(7 << sense_pos);
- config |= trigger << (sense_pos);
- hri_eic_write_CONFIG_reg(EIC, config_index, config);
- // ...set the pin mode...
- gpio_set_pin_function(pin, GPIO_PIN_FUNCTION_A);
- if (pin == BTN_ALARM || pin == BTN_LIGHT || pin == BTN_MODE) gpio_set_pin_pull_mode(pin, GPIO_PULL_DOWN);
- // ...and re-enable the EIC
- hri_eic_set_CTRLA_ENABLE_bit(EIC);
-
- ext_irq_register(pin, callback);
-}
-
-inline void watch_register_button_callback(const uint8_t pin, ext_irq_cb_t callback) {
- watch_register_interrupt_callback(pin, callback, INTERRUPT_TRIGGER_RISING);
-}
-
-inline void watch_enable_buttons(void) {
- watch_enable_external_interrupts();
-}
diff --git a/watch-library/watch/watch_extint.h b/watch-library/watch/watch_extint.h
deleted file mode 100644
index 452461b3..00000000
--- a/watch-library/watch/watch_extint.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_EXTINT_H_INCLUDED
-#define _WATCH_EXTINT_H_INCLUDED
-////< @file watch_extint.h
-
-#include "watch.h"
-#include "hal_ext_irq.h"
-
-/** @addtogroup buttons Buttons & External Interrupts
- * @brief This section covers functions related to the three buttons: Light, Mode and Alarm, as well as
- * external interrupts from devices on the nine-pin connector.
- * @details The buttons are the core input UI of the watch, and the way the user will interact with
- * your application. They are active high, pulled down by the microcontroller, and triggered
- * when one of the "pushers" brings a tab from the metal frame into contact with the edge
- * of the board. Note that the buttons can only wake the watch from STANDBY mode, at least as
- * of the current SAM L22 silicon revision. The external interrupt controller runs in STANDBY
- * mode, but it does not run in BACKUP mode; to wake from BACKUP, buttons will not cut it.
- */
-/// @{
-
-///@brief An enum defining the types of interrupt trigger you wish to scan for.
-typedef enum watch_interrupt_trigger {
- INTERRUPT_TRIGGER_NONE = 0,
- INTERRUPT_TRIGGER_RISING,
- INTERRUPT_TRIGGER_FALLING,
- INTERRUPT_TRIGGER_BOTH,
-} watch_interrupt_trigger;
-
-/// @brief Enables the external interrupt controller.
-void watch_enable_external_interrupts(void);
-
-/// @brief Disables the external interrupt controller.
-void watch_disable_external_interrupts(void);
-
-/** @brief Configures an external interrupt callback on one of the external interrupt pins.
- * @details You can set one interrupt callback per pin, and you can monitor for a rising condition,
- * a falling condition, or both. If you just want to detect a button press, register your
- * interrupt with INTERRUPT_TRIGGER_RISING; if you want to detect an active-low interrupt
- * signal from a device on the nine-pin connector, use INTERRUPT_TRIGGER_FALLING. If you
- * want to detect both rising and falling conditions (i.e. button down and button up), use
- * INTERRUPT_TRIGGER_BOTH and use watch_get_pin_level to check the pin level in your callback
- * to determine which condition caused the interrupt.
- * @param pin One of BTN_LIGHT, BTN_MODE, BTN_ALARM, A0, A1, A3 or A4. If the pin parameter matches one of
- * the three button pins, this function will also enable an internal pull-down resistor. If
- * the pin parameter is A0-A4, you are responsible for setting any required pull configuration
- * using watch_enable_pull_up or watch_enable_pull_down.
- * @param callback The function you wish to have called when the button is pressed.
- * @param trigger The condition on which you wish to trigger: rising, falling or both.
- * @note Pins A2 and A4 can also generate interrupts via the watch_register_extwake_callback function, which
- * will allow them to trigger even when the watch is in deep sleep mode.
- * @warning As of now, A2 is not usable via the watch_register_interrupt_callback function. To enable an
- * external interrupt on pin A2, use the watch_register_extwake_callback function. This issue will be
- * addressed in a future revision of the watch library.
- */
-void watch_register_interrupt_callback(const uint8_t pin, ext_irq_cb_t callback, watch_interrupt_trigger trigger);
-
-__attribute__((deprecated("Use watch_register_interrupt_callback or watch_register_extwake_callback instead")))
-void watch_register_button_callback(const uint8_t pin, ext_irq_cb_t callback);
-
-__attribute__((deprecated("Use watch_enable_external_interrupts instead")))
-void watch_enable_buttons(void);
-/// @}
-#endif
diff --git a/watch-library/watch/watch_gpio.c b/watch-library/watch/watch_gpio.c
deleted file mode 100644
index b37d009f..00000000
--- a/watch-library/watch/watch_gpio.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 "watch_gpio.h"
-
- void watch_enable_digital_input(const uint8_t pin) {
- gpio_set_pin_direction(pin, GPIO_DIRECTION_IN);
- gpio_set_pin_function(pin, GPIO_PIN_FUNCTION_OFF);
-}
-
-void watch_disable_digital_input(const uint8_t pin) {
- gpio_set_pin_direction(pin, GPIO_DIRECTION_OFF);
- gpio_set_pin_pull_mode(pin, GPIO_PULL_OFF);
- gpio_set_pin_function(pin, GPIO_PIN_FUNCTION_OFF);
-}
-
-void watch_enable_pull_up(const uint8_t pin) {
- gpio_set_pin_pull_mode(pin, GPIO_PULL_UP);
-}
-
-void watch_enable_pull_down(const uint8_t pin) {
- gpio_set_pin_pull_mode(pin, GPIO_PULL_DOWN);
-}
-
-bool watch_get_pin_level(const uint8_t pin) {
- return gpio_get_pin_level(pin);
-}
-
-void watch_enable_digital_output(const uint8_t pin) {
- gpio_set_pin_direction(pin, GPIO_DIRECTION_OUT);
- gpio_set_pin_function(pin, GPIO_PIN_FUNCTION_OFF);
-}
-
-void watch_disable_digital_output(const uint8_t pin) {
- gpio_set_pin_direction(pin, GPIO_DIRECTION_OFF);
-}
-
-void watch_set_pin_level(const uint8_t pin, const bool level) {
- gpio_set_pin_level(pin, level);
-}
diff --git a/watch-library/watch/watch_gpio.h b/watch-library/watch/watch_gpio.h
deleted file mode 100644
index fc43642c..00000000
--- a/watch-library/watch/watch_gpio.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_GPIO_H_INCLUDED
-#define _WATCH_GPIO_H_INCLUDED
-////< @file watch_gpio.h
-
-#include "watch.h"
-
-/** @addtogroup gpio Digital Input and Output
- * @brief This section covers functions related to general-purpose input and output signals.
- */
-/// @{
-/** @brief Configures the selected pin for digital input.
- * @param pin The pin that you wish to act as an input.
- */
-void watch_enable_digital_input(const uint8_t pin);
-
-/** @brief Disables any digital input, along with any pull-up or pull-down configuration.
- * @param pin The pin that you wish to disable.
- */
-void watch_disable_digital_input(const uint8_t pin);
-
-/** @brief Enables a pull-up resistor on the selected pin.
- * @param pin The pin that you wish to configure.
- */
-void watch_enable_pull_up(const uint8_t pin);
-
-/** @brief Enables a pull-down resistor on the selected pin.
- * @param pin The pin that you wish to configure.
- */
-void watch_enable_pull_down(const uint8_t pin);
-
-/** @brief Gets the level of the selected pin.
- * @param pin The pin whose value you wish to read.
- * @return true if the pin was logic high; otherwise, false.
- */
-bool watch_get_pin_level(const uint8_t pin);
-
-/** @brief Configures the selected pin for digital output.
- * @param pin The pin that you wish to act as an output.
- */
-void watch_enable_digital_output(const uint8_t pin);
-
-/** @brief Disables digital output on the selected pin.
- * @param pin The pin that you wish disable.
- */
-void watch_disable_digital_output(const uint8_t pin);
-
-/** @brief Sets the level of the selected pin.
- * @param pin The pin whose value you wish to set.
- * @param level The level you wish to set: true for high, false for low.
- */
-void watch_set_pin_level(const uint8_t pin, const bool level);
-/// @}
-#endif
diff --git a/watch-library/watch/watch_i2c.c b/watch-library/watch/watch_i2c.c
deleted file mode 100644
index ff20afc6..00000000
--- a/watch-library/watch/watch_i2c.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 "watch_i2c.h"
-
-struct io_descriptor *I2C_0_io;
-
-void watch_enable_i2c(void) {
- I2C_0_init();
- i2c_m_sync_get_io_descriptor(&I2C_0, &I2C_0_io);
- i2c_m_sync_enable(&I2C_0);
-}
-
-void watch_disable_i2c(void) {
- i2c_m_sync_disable(&I2C_0);
- hri_mclk_clear_APBCMASK_SERCOM1_bit(MCLK);
-}
-
-void watch_i2c_send(int16_t addr, uint8_t *buf, uint16_t length) {
- i2c_m_sync_set_periphaddr(&I2C_0, addr, I2C_M_SEVEN);
- io_write(I2C_0_io, buf, length);
-}
-
-void watch_i2c_receive(int16_t addr, uint8_t *buf, uint16_t length) {
- i2c_m_sync_set_periphaddr(&I2C_0, addr, I2C_M_SEVEN);
- io_read(I2C_0_io, buf, length);
-}
-
-void watch_i2c_write8(int16_t addr, uint8_t reg, uint8_t data) {
- uint8_t buf[2];
- buf[0] = reg;
- buf[1] = data;
-
- watch_i2c_send(addr, (uint8_t *)&buf, 2);
-}
-
-uint8_t watch_i2c_read8(int16_t addr, uint8_t reg) {
- uint8_t data;
-
- watch_i2c_send(addr, (uint8_t *)&reg, 1);
- watch_i2c_receive(addr, (uint8_t *)&data, 1);
-
- return data;
-}
-
-uint16_t watch_i2c_read16(int16_t addr, uint8_t reg) {
- uint16_t data;
-
- watch_i2c_send(addr, (uint8_t *)&reg, 1);
- watch_i2c_receive(addr, (uint8_t *)&data, 2);
-
- return data;
-}
-
-uint32_t watch_i2c_read24(int16_t addr, uint8_t reg) {
- uint32_t data;
- data = 0;
-
- watch_i2c_send(addr, (uint8_t *)&reg, 1);
- watch_i2c_receive(addr, (uint8_t *)&data, 3);
-
- return data << 8;
-}
-
-uint32_t watch_i2c_read32(int16_t addr, uint8_t reg) {
- uint32_t data;
-
- watch_i2c_send(addr, (uint8_t *)&reg, 1);
- watch_i2c_receive(addr, (uint8_t *)&data, 4);
-
- return data;
-}
diff --git a/watch-library/watch/watch_i2c.h b/watch-library/watch/watch_i2c.h
deleted file mode 100644
index fbcc1a92..00000000
--- a/watch-library/watch/watch_i2c.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_I2C_H_INCLUDED
-#define _WATCH_I2C_H_INCLUDED
-////< @file watch_i2c.h
-
-#include "watch.h"
-
-/** @addtogroup i2c I2C Controller Driver
- * @brief This section covers functions related to the SAM L22's built-I2C driver, including
- * configuring the I2C bus, putting values directly on the bus and reading data from
- * registers on I2C devices.
- */
-/// @{
-/** @brief Enables the I2C peripheral. Call this before attempting to interface with I2C devices.
- */
-void watch_enable_i2c(void);
-
-/** @brief Disables the I2C peripheral.
- */
-void watch_disable_i2c(void);
-
-/** @brief Sends a series of values to a device on the I2C bus.
- * @param addr The address of the device you wish to talk to.
- * @param buf A series of unsigned bytes; the data you wish to transmit.
- * @param length The number of bytes in buf that you wish to send.
- */
-void watch_i2c_send(int16_t addr, uint8_t *buf, uint16_t length);
-
-/** @brief Receives a series of values from a device on the I2C bus.
- * @param addr The address of the device you wish to hear from.
- * @param buf Storage for the incoming bytes; on return, it will contain the received data.
- * @param length The number of bytes that you wish to receive.
- */
-void watch_i2c_receive(int16_t addr, uint8_t *buf, uint16_t length);
-
-/** @brief Writes a byte to a register in an I2C device.
- * @param addr The address of the device you wish to address.
- * @param reg The register on the device that you wish to set.
- * @param data The value that you wish to set the register to.
- */
-void watch_i2c_write8(int16_t addr, uint8_t reg, uint8_t data);
-
-/** @brief Reads a byte from a register in an I2C device.
- * @param addr The address of the device you wish to address.
- * @param reg The register on the device that you wish to read.
- * @return An unsigned byte representing the value of the register that was read.
- */
-uint8_t watch_i2c_read8(int16_t addr, uint8_t reg);
-
-/** @brief Reads an unsigned little-endian word from a register in an I2C device.
- * @param addr The address of the device you wish to address.
- * @param reg The register on the device that you wish to read.
- * @return An unsigned word representing the value of the register that was read.
- * @note This reads two bytes into the word in bus order. If the device returns
- the LSB first and then the MSB, you can use this value as returned.
- If the device returns the data in big-endian order or uses some other
- kind of fancy bit packing, you may need to shuffle some bits around.
- */
-uint16_t watch_i2c_read16(int16_t addr, uint8_t reg);
-
-/** @brief Reads three bytes as an unsigned little-endian int from a register in an I2C device.
- * @param addr The address of the device you wish to address.
- * @param reg The register on the device that you wish to read.
- * @return An unsigned word representing the value of the register that was read.
- * @note This reads three bytes into the word in bus order. If the device returns
- these bytes LSB first, you can use this value as returned. If there is a
- sign bit, the device returns the data in big-endian order, or it uses some
- other kind of fancy bit packing, you may need to shuffle some bits around.
- */
-uint32_t watch_i2c_read24(int16_t addr, uint8_t reg);
-
-
-/** @brief Reads an unsigned little-endian int from a register in an I2C device.
- * @param addr The address of the device you wish to address.
- * @param reg The register on the device that you wish to read.
- * @return An unsigned word representing the value of the register that was read.
- * @note This reads three bytes into the word in bus order. If the device returns
- these bytes LSB first, you can use this value as returned. If the device
- returns the data in big-endian order, or it uses some other kind of fancy
- bit packing, you may need to shuffle some bits around.
- */
-uint32_t watch_i2c_read32(int16_t addr, uint8_t reg);
-/// @}
-#endif
diff --git a/watch-library/watch/watch_led.c b/watch-library/watch/watch_led.c
deleted file mode 100644
index 52174b54..00000000
--- a/watch-library/watch/watch_led.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 "watch_led.h"
-
-void watch_enable_leds(void) {
- if (!hri_tcc_get_CTRLA_reg(TCC0, TCC_CTRLA_ENABLE)) {
- _watch_enable_tcc();
- }
-}
-
-void watch_disable_leds(void) {
- _watch_disable_tcc();
-}
-
-void watch_enable_led(bool unused) {
- (void)unused;
- watch_enable_leds();
-}
-
-void watch_disable_led(bool unused) {
- (void)unused;
- watch_disable_leds();
-}
-
-void watch_set_led_color(uint8_t red, uint8_t green) {
- if (hri_tcc_get_CTRLA_reg(TCC0, TCC_CTRLA_ENABLE)) {
- uint32_t period = hri_tcc_get_PER_reg(TCC0, TCC_PER_MASK);
- hri_tcc_write_CCBUF_reg(TCC0, WATCH_RED_TCC_CHANNEL, ((period * red * 1000ull) / 255000ull));
- hri_tcc_write_CCBUF_reg(TCC0, WATCH_GREEN_TCC_CHANNEL, ((period * green * 1000ull) / 255000ull));
- }
-}
-
-void watch_set_led_red(void) {
- watch_set_led_color(255, 0);
-}
-
-void watch_set_led_green(void) {
- watch_set_led_color(0, 255);
-}
-
-void watch_set_led_yellow(void) {
- watch_set_led_color(255, 255);
-}
-
-void watch_set_led_off(void) {
- watch_set_led_color(0, 0);
-}
diff --git a/watch-library/watch/watch_led.h b/watch-library/watch/watch_led.h
deleted file mode 100644
index 9e9f5640..00000000
--- a/watch-library/watch/watch_led.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_LED_H_INCLUDED
-#define _WATCH_LED_H_INCLUDED
-////< @file watch_led.h
-
-#include "watch.h"
-
-/** @addtogroup led LED Control
- * @brief This section covers functions related to the bi-color red/green LED mounted behind the LCD.
- * @details The SAM L22 is an exceedingly power efficient chip, whereas the LED's are relatively power-
- * hungry. The green LED, at full power, consumes more power than the whole chip in active mode,
- * and the red LED consumes about twelve times as much power! The LED's should thus be used only
- * sparingly in order to preserve battery life.
- * @note Some watches use a red/blue LED instead of a red/green LED. You will be able to determine this
- * easily when you double tap the reset button: if the pulsing bootloader LED is red, you have a
- * red/green edition; if it is blue, you have a red/blue edition. For red/blue watches, build your
- * project with the command `make LED=BLUE`, and the watch library will automatically swap the pins
- * so that watch_set_led_red sets the red LED, and watch_set_led_green sets the blue one.
- */
-/// @{
-/** @brief Enables the bi-color LED.
- * @note The TCC peripheral that drives the LEDs does not run in STANDBY mode — but the outputs do! This
- * means that if you set either red, green or both LEDs to full power, they will shine even when
- * your app is asleep. If, however, you set a custom color using watch_set_led_color, the color will
- * not display correctly in STANDBY mode. You will need to keep your app running while the LED is on.
- */
-void watch_enable_leds(void);
-
-/** @brief Disables the LEDs.
- * @note This method will also disable the buzzer, since the buzzer and LED both make use of the same
- * peripheral to drive their PWM behavior.
- */
-void watch_disable_leds(void);
-
-/** @brief Sets the LED to a custom color by modulating each output's duty cycle.
- * @param red The red value from 0-255.
- * @param green The green value from 0-255. If your watch has a red/blue LED, this will be the blue value.
- * @note If you are displaying a custom color, you will need to prevent your app from going to sleep
- * while the LED is on; otherwise, the color will not display correctly. You can do this by
- * returning false in your app_loop method.
- */
-void watch_set_led_color(uint8_t red, uint8_t green);
-
-/** @brief Sets the red LED to full brightness, and turns the green LED off.
- * @details Of the two LED's in the RG bi-color LED, the red LED is the less power-efficient one (~4.5 mA).
- */
-void watch_set_led_red(void);
-
-/** @brief Sets the green LED to full brightness, and turns the red LED off.
- * @details Of the two LED's in the RG bi-color LED, the green LED is the more power-efficient one (~0.44 mA).
- * @note If your watch has a red/blue LED, this method will set the LED to blue.
- */
-void watch_set_led_green(void);
-
-/** @brief Sets both red and green LEDs to full brightness.
- * @details The total current draw between the two LED's in this mode will be ~5 mA, which is more than the
- * watch draws in any other mode. Take care not to drain the battery.
- * @note If your watch has a red/blue LED, this method will set the LED to pink.
- */
-void watch_set_led_yellow(void);
-
-/** @brief Turns both the red and the green LEDs off. */
-void watch_set_led_off(void);
-
-__attribute__((deprecated("Use watch_enable_leds instead")))
-void watch_enable_led(bool unused);
-
-__attribute__((deprecated("Use watch_disable_leds instead")))
-void watch_disable_led(bool unused);
-/// @}
-#endif
diff --git a/watch-library/watch/watch_private.c b/watch-library/watch/watch_private.c
deleted file mode 100644
index ae2589e7..00000000
--- a/watch-library/watch/watch_private.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 "watch_private.h"
-#include "watch_utility.h"
-#include "tusb.h"
-
-void _watch_init(void) {
- // disable the LED pin (it may have been enabled by the bootloader)
- watch_disable_digital_output(RED);
-
- // RAM should be back-biased in STANDBY
- PM->STDBYCFG.bit.BBIASHS = 1;
-
- // Use switching regulator for lower power consumption.
- SUPC->VREG.bit.SEL = 1;
- while(!SUPC->STATUS.bit.VREGRDY);
-
- // set up the brownout detector (low battery warning)
- NVIC_DisableIRQ(SYSTEM_IRQn);
- NVIC_ClearPendingIRQ(SYSTEM_IRQn);
- NVIC_EnableIRQ(SYSTEM_IRQn);
- SUPC->BOD33.bit.ENABLE = 0; // BOD33 must be disabled to change its configuration
- SUPC->BOD33.bit.VMON = 0; // Monitor VDD in active and standby mode
- SUPC->BOD33.bit.ACTCFG = 1; // Enable sampling mode when active
- SUPC->BOD33.bit.RUNSTDBY = 1; // Enable sampling mode in standby
- SUPC->BOD33.bit.STDBYCFG = 1; // Run in standby
- SUPC->BOD33.bit.RUNBKUP = 0; // Don't run in backup mode
- SUPC->BOD33.bit.PSEL = 0xB; // Check battery level every 4 seconds
- SUPC->BOD33.bit.LEVEL = 31; // Detect brownout at 2.5V (1.445V + level * 34mV)
- SUPC->BOD33.bit.ACTION = 0x2; // Generate an interrupt when BOD33 is triggered
- SUPC->BOD33.bit.HYST = 0; // Disable hysteresis
- while(!SUPC->STATUS.bit.B33SRDY);
-
- // Enable interrupt on BOD33 detect
- SUPC->INTENSET.bit.BOD33DET = 1;
- SUPC->BOD33.bit.ENABLE = 1;
-
- // External wake depends on RTC; calendar is a required module.
- _watch_rtc_init();
-
- // set up state
- btn_alarm_callback = NULL;
- a2_callback = NULL;
- a4_callback = NULL;
-}
-
-static inline void _watch_wait_for_entropy() {
- while (!hri_trng_get_INTFLAG_reg(TRNG, TRNG_INTFLAG_DATARDY));
-}
-
-// this function is called by arc4random to get entropy for random number generation.
-// let's use the SAM L22's true random number generator to seed the PRNG!
-int getentropy(void *buf, size_t buflen) {
- hri_mclk_set_APBCMASK_TRNG_bit(MCLK);
- hri_trng_set_CTRLA_ENABLE_bit(TRNG);
-
- size_t i = 0;
- while(i < buflen / 4) {
- _watch_wait_for_entropy();
- ((uint32_t *)buf)[i++] = hri_trng_read_DATA_reg(TRNG);
- }
-
- // but what if they asked for an awkward number of bytes?
- if (buflen % 4) {
- // all good: let's fill in one, two or three bytes at the end of the buffer.
- _watch_wait_for_entropy();
- uint32_t last_little_bit = hri_trng_read_DATA_reg(TRNG);
- for(size_t j = 0; j <= (buflen % 4); j++) {
- ((uint8_t *)buf)[i * 4 + j] = (last_little_bit >> (j * 8)) & 0xFF;
- }
- }
-
- hri_trng_clear_CTRLA_ENABLE_bit(TRNG);
- hri_mclk_clear_APBCMASK_TRNG_bit(MCLK);
-
- return 0;
-}
-
-int _gettimeofday(struct timeval *tv, void *tzvp) {
- (void)tzvp;
- watch_date_time date_time = watch_rtc_get_date_time();
-
- // FIXME: this assumes the system time is UTC! Will break for any other time zone.
- tv->tv_sec = watch_utility_date_time_to_unix_time(date_time, 0);
- tv->tv_usec = 0;
-
- return 0;
-}
-
-void _watch_enable_tcc(void) {
- // clock TCC0 with the main clock (8 MHz) and enable the peripheral clock.
- hri_gclk_write_PCHCTRL_reg(GCLK, TCC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK0_Val | GCLK_PCHCTRL_CHEN);
- hri_mclk_set_APBCMASK_TCC0_bit(MCLK);
- // disable and reset TCC0.
- hri_tcc_clear_CTRLA_ENABLE_bit(TCC0);
- hri_tcc_wait_for_sync(TCC0, TCC_SYNCBUSY_ENABLE);
- hri_tcc_write_CTRLA_reg(TCC0, TCC_CTRLA_SWRST);
- hri_tcc_wait_for_sync(TCC0, TCC_SYNCBUSY_SWRST);
- // divide the clock down to 1 MHz
- if (hri_usbdevice_get_CTRLA_ENABLE_bit(USB)) {
- // if USB is enabled, we are running an 8 MHz clock.
- hri_tcc_write_CTRLA_reg(TCC0, TCC_CTRLA_PRESCALER_DIV8);
- } else {
- // otherwise it's 4 Mhz.
- hri_tcc_write_CTRLA_reg(TCC0, TCC_CTRLA_PRESCALER_DIV4);
- }
- // We're going to use normal PWM mode, which means period is controlled by PER, and duty cycle is controlled by
- // each compare channel's value:
- // * Buzzer tones are set by setting PER to the desired period for a given frequency, and CC[1] to half of that
- // period (i.e. a square wave with a 50% duty cycle).
- // * LEDs on CC[2] and CC[3] can be set to any value from 0 (off) to PER (fully on).
- hri_tcc_write_WAVE_reg(TCC0, TCC_WAVE_WAVEGEN_NPWM);
- #ifdef WATCH_INVERT_LED_POLARITY
- // This is here for the dev board, which uses a common anode LED (instead of common cathode like the actual watch).
- hri_tcc_set_WAVE_reg(TCC0, (1 << (TCC_WAVE_POL0_Pos + WATCH_RED_TCC_CHANNEL)) |
- (1 << (TCC_WAVE_POL0_Pos + WATCH_GREEN_TCC_CHANNEL)));
- #endif
- // The buzzer will set the period depending on the tone it wants to play, but we have to set some period here to
- // get the LED working. Almost any period will do, tho it should be below 20000 (i.e. 50 Hz) to avoid flickering.
- hri_tcc_write_PER_reg(TCC0, 4096);
- // Set the duty cycle of all pins to 0: LED's off, buzzer not buzzing.
- hri_tcc_write_CC_reg(TCC0, WATCH_BUZZER_TCC_CHANNEL, 0);
- hri_tcc_write_CC_reg(TCC0, WATCH_RED_TCC_CHANNEL, 0);
- hri_tcc_write_CC_reg(TCC0, WATCH_GREEN_TCC_CHANNEL, 0);
- // Enable the TCC
- hri_tcc_set_CTRLA_ENABLE_bit(TCC0);
- hri_tcc_wait_for_sync(TCC0, TCC_SYNCBUSY_ENABLE);
-
- // enable LED PWM pins (the LED driver assumes if the TCC is on, the pins are enabled)
- gpio_set_pin_direction(RED, GPIO_DIRECTION_OUT);
- gpio_set_pin_function(RED, WATCH_RED_TCC_PINMUX);
- gpio_set_pin_direction(GREEN, GPIO_DIRECTION_OUT);
- gpio_set_pin_function(GREEN, WATCH_GREEN_TCC_PINMUX);
-}
-
-void _watch_disable_tcc(void) {
- // disable all PWM pins
- gpio_set_pin_direction(BUZZER, GPIO_DIRECTION_OFF);
- gpio_set_pin_function(BUZZER, GPIO_PIN_FUNCTION_OFF);
- gpio_set_pin_direction(RED, GPIO_DIRECTION_OFF);
- gpio_set_pin_function(RED, GPIO_PIN_FUNCTION_OFF);
- gpio_set_pin_direction(GREEN, GPIO_DIRECTION_OFF);
- gpio_set_pin_function(GREEN, GPIO_PIN_FUNCTION_OFF);
-
- // disable the TCC
- hri_tcc_clear_CTRLA_ENABLE_bit(TCC0);
- hri_mclk_clear_APBCMASK_TCC0_bit(MCLK);
-}
-
-void _watch_enable_usb(void) {
- // disable USB, just in case.
- hri_usb_clear_CTRLA_ENABLE_bit(USB);
-
- // bump clock up to 8 MHz
- hri_oscctrl_write_OSC16MCTRL_FSEL_bf(OSCCTRL, OSCCTRL_OSC16MCTRL_FSEL_8_Val);
-
- // reset flags and disable DFLL
- OSCCTRL->INTFLAG.reg = OSCCTRL_INTFLAG_DFLLRDY;
- OSCCTRL->DFLLCTRL.reg = 0;
- while (!(OSCCTRL->STATUS.reg & OSCCTRL_STATUS_DFLLRDY));
-
- // set the coarse and fine values to speed up frequency lock.
- uint32_t coarse =(*((uint32_t *)NVMCTRL_OTP5)) >> 26;
- OSCCTRL->DFLLVAL.reg = OSCCTRL_DFLLVAL_COARSE(coarse) |
- OSCCTRL_DFLLVAL_FINE(0x200);
- // set coarse and fine steps, and multiplier (48 MHz = 32768 Hz * 1465)
- OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_CSTEP( 1 ) |
- OSCCTRL_DFLLMUL_FSTEP( 1 ) |
- OSCCTRL_DFLLMUL_MUL( 1465 );
- // set closed loop mode, chill cycle disable and USB clock recovery mode, and enable the DFLL.
- OSCCTRL->DFLLCTRL.reg = OSCCTRL_DFLLCTRL_MODE | OSCCTRL_DFLLCTRL_CCDIS | OSCCTRL_DFLLCTRL_ONDEMAND | OSCCTRL_DFLLCTRL_RUNSTDBY | OSCCTRL_DFLLCTRL_USBCRM | OSCCTRL_DFLLCTRL_ENABLE;
- while (!(OSCCTRL->STATUS.reg & OSCCTRL_STATUS_DFLLRDY));
-
- // assign DFLL to GCLK1
- GCLK->GENCTRL[1].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL48M) | GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_GENEN;// | GCLK_GENCTRL_OE;
- while (GCLK->SYNCBUSY.bit.GENCTRL1);
-
- // assign GCLK1 to USB
- hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN);
- hri_mclk_set_AHBMASK_USB_bit(MCLK);
- hri_mclk_set_APBBMASK_USB_bit(MCLK);
-
- // USB Pin Init
- gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(PIN_PA24, false);
- gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF);
- gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT);
- gpio_set_pin_level(PIN_PA25, false);
- gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF);
-
- gpio_set_pin_function(PIN_PA24, PINMUX_PA24G_USB_DM);
- gpio_set_pin_function(PIN_PA25, PINMUX_PA25G_USB_DP);
-
- // before we init TinyUSB, we are going to need a periodic callback to handle TinyUSB tasks.
- // TC2 and TC3 are reserved for devices on the 9-pin connector, so let's use TC0.
- // clock TC0 with the 8 MHz clock on GCLK0.
- hri_gclk_write_PCHCTRL_reg(GCLK, TC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK0_Val | GCLK_PCHCTRL_CHEN);
- // and enable the peripheral clock.
- hri_mclk_set_APBCMASK_TC0_bit(MCLK);
- // disable and reset TC0.
- hri_tc_clear_CTRLA_ENABLE_bit(TC0);
- hri_tc_wait_for_sync(TC0, TC_SYNCBUSY_ENABLE);
- hri_tc_write_CTRLA_reg(TC0, TC_CTRLA_SWRST);
- hri_tc_wait_for_sync(TC0, TC_SYNCBUSY_SWRST);
- // configure the TC to overflow 1,000 times per second
- hri_tc_write_CTRLA_reg(TC0, TC_CTRLA_PRESCALER_DIV64 | // divide the 8 MHz clock by 64 to count at 125 KHz
- TC_CTRLA_MODE_COUNT8 | // count in 8-bit mode
- TC_CTRLA_RUNSTDBY); // run in standby, just in case we figure that out
- hri_tccount8_write_PER_reg(TC0, 125); // 125000 Hz / 125 = 1,000 Hz
- // set an interrupt on overflow; this will call TC0_Handler below.
- hri_tc_set_INTEN_OVF_bit(TC0);
- NVIC_ClearPendingIRQ(TC0_IRQn);
- NVIC_EnableIRQ (TC0_IRQn);
-
- // now we can init TinyUSB
- tusb_init();
- // and start the timer that handles USB device tasks.
- hri_tc_set_CTRLA_ENABLE_bit(TC0);
-}
-
-// this function ends up getting called by printf to log stuff to the USB console.
-int _write(int file, char *ptr, int len) {
- (void)file;
- if (hri_usbdevice_get_CTRLA_ENABLE_bit(USB)) {
- tud_cdc_n_write(0, (void const*)ptr, len);
- tud_cdc_n_write_flush(0);
- return len;
- }
-
- return 0;
-}
-
-// this method could be overridden to read stuff from the USB console? but no need rn.
-int _read(void) {
- return 0;
-}
-
-// Alternate function that outputs to the debug UART. useful for debugging USB issues.
-// int _write(int file, char *ptr, int len) {
-// (void)file;
-// int pos = 0;
-// while(pos < len) watch_debug_putc(ptr[pos++]);
-
-// return 0;
-// }
-
-void USB_Handler(void) {
- tud_int_handler(0);
-}
-
-void TC0_Handler(void) {
- tud_task();
- TC0->COUNT8.INTFLAG.reg |= TC_INTFLAG_OVF;
-}
-
-
-// USB Descriptors and tinyUSB callbacks follow.
-
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach (tinyusb.org)
- *
- * 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.
- *
- */
-
-//--------------------------------------------------------------------+
-// Device Descriptors
-//--------------------------------------------------------------------+
-tusb_desc_device_t const desc_device =
-{
- .bLength = sizeof(tusb_desc_device_t),
- .bDescriptorType = TUSB_DESC_DEVICE,
- .bcdUSB = 0x0200,
-
- // Use Interface Association Descriptor (IAD) for CDC
- // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
- .bDeviceClass = TUSB_CLASS_MISC,
- .bDeviceSubClass = MISC_SUBCLASS_COMMON,
- .bDeviceProtocol = MISC_PROTOCOL_IAD,
-
- .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
-
- .idVendor = 0x1209,
- .idProduct = 0x2151,
- .bcdDevice = 0x0100,
-
- .iManufacturer = 0x01,
- .iProduct = 0x02,
- .iSerialNumber = 0x03,
-
- .bNumConfigurations = 0x01
-};
-
-// Invoked when received GET DEVICE DESCRIPTOR
-// Application return pointer to descriptor
-uint8_t const * tud_descriptor_device_cb(void) {
- return (uint8_t const *) &desc_device;
-}
-
-//--------------------------------------------------------------------+
-// Configuration Descriptor
-//--------------------------------------------------------------------+
-
-enum {
- ITF_NUM_CDC = 0,
- ITF_NUM_CDC_DATA,
- ITF_NUM_TOTAL
-};
-
-#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
-
-#define EPNUM_CDC_NOTIF 0x81
-#define EPNUM_CDC_OUT 0x02
-#define EPNUM_CDC_IN 0x82
-
-
-uint8_t const desc_fs_configuration[] = {
- // Config number, interface count, string index, total length, attribute, power in mA
- TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
-
- // Interface number, string index, EP notification address and size, EP data address (out, in) and size.
- TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
-};
-
-// Invoked when received GET CONFIGURATION DESCRIPTOR
-// Application return pointer to descriptor
-// Descriptor contents must exist long enough for transfer to complete
-uint8_t const * tud_descriptor_configuration_cb(uint8_t index) {
- (void) index; // for multiple configurations
- return desc_fs_configuration;
-}
-
-//--------------------------------------------------------------------+
-// String Descriptors
-//--------------------------------------------------------------------+
-
-// array of pointer to string descriptors
-char const* string_desc_arr [] =
-{
- (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
- "TinyUSB", // 1: Manufacturer
- "TinyUSB Device", // 2: Product
- "123456", // 3: Serials, should use chip ID
- "TinyUSB CDC", // 4: CDC Interface
-};
-
-static uint16_t _desc_str[32];
-
-// Invoked when received GET STRING DESCRIPTOR request
-// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
-uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
-{
- (void) langid;
-
- uint8_t chr_count;
-
- if ( index == 0) {
- memcpy(&_desc_str[1], string_desc_arr[0], 2);
- chr_count = 1;
- } else {
- // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
- // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
-
- if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
-
- const char* str = string_desc_arr[index];
-
- // Cap at max char
- chr_count = strlen(str);
- if ( chr_count > 31 ) chr_count = 31;
-
- // Convert ASCII string into UTF-16
- for(uint8_t i=0; i<chr_count; i++)
- {
- _desc_str[1+i] = str[i];
- }
- }
-
- // first byte is length (including header), second byte is string type
- _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
-
- return _desc_str;
-}
diff --git a/watch-library/watch/watch_private.h b/watch-library/watch/watch_private.h
deleted file mode 100644
index 7bb91d1f..00000000
--- a/watch-library/watch/watch_private.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2021 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 _WATCH_PRIVATE_H_INCLUDED
-#define _WATCH_PRIVATE_H_INCLUDED
-
-#include "watch.h"
-
-/// Called by main.c while setting up the app. You should not call this from your app.
-void _watch_init(void);
-
-/// Initializes the real-time clock peripheral.
-void _watch_rtc_init(void);
-
-/// Called by buzzer and LED setup functions. You should not call this from your app.
-void _watch_enable_tcc(void);
-
-/// Called by buzzer and LED teardown functions. You should not call this from your app.
-void _watch_disable_tcc(void);
-
-/// Called by main.c if plugged in to USB. You should not call this from your app.
-void _watch_enable_usb(void);
-
-// this function ends up getting called by printf to log stuff to the USB console.
-int _write(int file, char *ptr, int len);
-
-// this method could be overridden to read stuff from the USB console? but no need rn.
-int _read(void);
-
-#endif
diff --git a/watch-library/watch/watch_rtc.c b/watch-library/watch/watch_rtc.c
deleted file mode 100644
index 14a968c4..00000000
--- a/watch-library/watch/watch_rtc.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 "watch_rtc.h"
-
-ext_irq_cb_t tick_callbacks[8];
-ext_irq_cb_t alarm_callback;
-ext_irq_cb_t btn_alarm_callback;
-ext_irq_cb_t a2_callback;
-ext_irq_cb_t a4_callback;
-
-bool _watch_rtc_is_enabled(void) {
- return RTC->MODE2.CTRLA.bit.ENABLE;
-}
-
-static void _sync_rtc(void) {
- while (RTC->MODE2.SYNCBUSY.reg);
-}
-
-void _watch_rtc_init(void) {
- MCLK->APBAMASK.reg |= MCLK_APBAMASK_RTC;
-
- if (_watch_rtc_is_enabled()) return; // don't reset the RTC if it's already set up.
-
- RTC->MODE2.CTRLA.bit.ENABLE = 0;
- _sync_rtc();
-
- RTC->MODE2.CTRLA.bit.SWRST = 1;
- _sync_rtc();
-
- RTC->MODE2.CTRLA.bit.MODE = RTC_MODE2_CTRLA_MODE_CLOCK_Val;
- RTC->MODE2.CTRLA.bit.PRESCALER = RTC_MODE2_CTRLA_PRESCALER_DIV1024_Val;
- RTC->MODE2.CTRLA.bit.CLOCKSYNC = 1;
- RTC->MODE2.CTRLA.bit.ENABLE = 1;
- _sync_rtc();
-}
-
-void watch_rtc_set_date_time(watch_date_time date_time) {
- RTC->MODE2.CLOCK.reg = date_time.reg;
- _sync_rtc();
-}
-
-watch_date_time watch_rtc_get_date_time(void) {
- watch_date_time retval;
-
- _sync_rtc();
- retval.reg = RTC->MODE2.CLOCK.reg;
-
- return retval;
-}
-
-void watch_rtc_register_tick_callback(ext_irq_cb_t callback) {
- watch_rtc_register_periodic_callback(callback, 1);
-}
-
-void watch_rtc_disable_tick_callback(void) {
- watch_rtc_disable_periodic_callback(1);
-}
-
-void watch_rtc_register_periodic_callback(ext_irq_cb_t callback, uint8_t frequency) {
- // we told them, it has to be a power of 2.
- if (__builtin_popcount(frequency) != 1) return;
-
- // this left-justifies the period in a 32-bit integer.
- uint32_t tmp = frequency << 24;
- // now we can count the leading zeroes to get the value we need.
- // 0x01 (1 Hz) will have 7 leading zeros for PER7. 0xF0 (128 Hz) will have no leading zeroes for PER0.
- uint8_t per_n = __builtin_clz(tmp);
-
- // this also maps nicely to an index for our list of tick callbacks.
- tick_callbacks[per_n] = callback;
-
- NVIC_ClearPendingIRQ(RTC_IRQn);
- NVIC_EnableIRQ(RTC_IRQn);
- RTC->MODE2.INTENSET.reg = 1 << per_n;
-}
-
-void watch_rtc_disable_periodic_callback(uint8_t frequency) {
- if (__builtin_popcount(frequency) != 1) return;
- uint8_t per_n = __builtin_clz(frequency << 24);
- RTC->MODE2.INTENCLR.reg = 1 << per_n;
-}
-
-void watch_rtc_disable_all_periodic_callbacks(void) {
- RTC->MODE2.INTENCLR.reg = 0xFF;
-}
-
-void watch_rtc_register_alarm_callback(ext_irq_cb_t callback, watch_date_time alarm_time, watch_rtc_alarm_match mask) {
- RTC->MODE2.Mode2Alarm[0].ALARM.reg = alarm_time.reg;
- RTC->MODE2.Mode2Alarm[0].MASK.reg = mask;
- RTC->MODE2.INTENSET.reg = RTC_MODE2_INTENSET_ALARM0;
- alarm_callback = callback;
- NVIC_ClearPendingIRQ(RTC_IRQn);
- NVIC_EnableIRQ(RTC_IRQn);
- RTC->MODE2.INTENSET.reg = RTC_MODE2_INTENSET_ALARM0;
-}
-
-void watch_rtc_disable_alarm_callback(void) {
- RTC->MODE2.INTENCLR.reg = RTC_MODE2_INTENCLR_ALARM0;
-}
-
-void RTC_Handler(void) {
- uint16_t interrupt_status = RTC->MODE2.INTFLAG.reg;
- uint16_t interrupt_enabled = RTC->MODE2.INTENSET.reg;
-
- if ((interrupt_status & interrupt_enabled) & RTC_MODE2_INTFLAG_PER_Msk) {
- // handle the tick callback first, it's what we do the most.
- // start from PER7, the 1 Hz tick.
- for(int8_t i = 7; i >= 0; i--) {
- if ((interrupt_status & interrupt_enabled) & (1 << i)) {
- if (tick_callbacks[i] != NULL) {
- tick_callbacks[i]();
- }
- RTC->MODE2.INTFLAG.reg = 1 << i;
- break;
- }
- }
- } else if ((interrupt_status & interrupt_enabled) & RTC_MODE2_INTFLAG_TAMPER) {
- // handle the extwake interrupts next.
- uint8_t reason = RTC->MODE2.TAMPID.reg;
- if (reason & RTC_TAMPID_TAMPID2) {
- if (btn_alarm_callback != NULL) btn_alarm_callback();
- } else if (reason & RTC_TAMPID_TAMPID1) {
- if (a2_callback != NULL) a2_callback();
- } else if (reason & RTC_TAMPID_TAMPID0) {
- if (a4_callback != NULL) a4_callback();
- }
- RTC->MODE2.TAMPID.reg = reason;
- RTC->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_TAMPER;
- } else if ((interrupt_status & interrupt_enabled) & RTC_MODE2_INTFLAG_ALARM0) {
- // finally handle the alarm.
- if (alarm_callback != NULL) {
- alarm_callback();
- }
- RTC->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_ALARM0;
- }
-}
-
-///////////////////////
-// Deprecated functions
-
-void watch_set_date_time(struct calendar_date_time date_time) {
- RTC_MODE2_CLOCK_Type val;
-
- val.bit.SECOND = date_time.time.sec;
- val.bit.MINUTE = date_time.time.min;
- val.bit.HOUR = date_time.time.hour;
- val.bit.DAY = date_time.date.day;
- val.bit.MONTH = date_time.date.month;
- val.bit.YEAR = (uint8_t)(date_time.date.year - WATCH_RTC_REFERENCE_YEAR);
-
- RTC->MODE2.CLOCK.reg = val.reg;
-
- _sync_rtc();
-}
-
-void watch_get_date_time(struct calendar_date_time *date_time) {
- _sync_rtc();
- RTC_MODE2_CLOCK_Type val = RTC->MODE2.CLOCK;
-
- date_time->time.sec = val.bit.SECOND;
- date_time->time.min = val.bit.MINUTE;
- date_time->time.hour = val.bit.HOUR;
- date_time->date.day = val.bit.DAY;
- date_time->date.month = val.bit.MONTH;
- date_time->date.year = val.bit.YEAR + WATCH_RTC_REFERENCE_YEAR;
-}
-
-void watch_register_tick_callback(ext_irq_cb_t callback) {
- tick_callbacks[7] = callback;
- NVIC_ClearPendingIRQ(RTC_IRQn);
- NVIC_EnableIRQ(RTC_IRQn);
- RTC->MODE2.INTENSET.reg = RTC_MODE2_INTENSET_PER7;
-}
diff --git a/watch-library/watch/watch_rtc.h b/watch-library/watch/watch_rtc.h
deleted file mode 100644
index 6dac63f5..00000000
--- a/watch-library/watch/watch_rtc.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_RTC_H_INCLUDED
-#define _WATCH_RTC_H_INCLUDED
-////< @file watch_rtc.h
-
-#include "watch.h"
-#include "hpl_calendar.h"
-
-/** @addtogroup rtc Real-Time Clock
- * @brief This section covers functions related to the SAM L22's real-time clock peripheral, including
- * date, time and alarm functions.
- * @details The real-time clock is the only peripheral that main.c enables for you. It is the cornerstone
- * of low power operation on the watch, and it is required for several key functions that we
- * assume will be available, namely the wake from BACKUP mode and the callback on the ALARM button.
- * It is also required for the operation of the 1 Hz tick interrupt, which you will most likely use
- * to wake from STANDBY mode.
- */
-/// @{
-
-#define WATCH_RTC_REFERENCE_YEAR (2020)
-
-typedef union {
- struct {
- uint32_t second : 6; // 0-59
- uint32_t minute : 6; // 0-59
- uint32_t hour : 5; // 0-23
- uint32_t day : 5; // 1-31
- uint32_t month : 4; // 1-12
- uint32_t year : 6; // 0-63 (representing 2020-2083)
- } unit;
- uint32_t reg; // the bit-packed value as expected by the RTC peripheral's CLOCK register.
-} watch_date_time;
-
-typedef enum watch_rtc_alarm_match {
- ALARM_MATCH_DISABLED = 0,
- ALARM_MATCH_SS,
- ALARM_MATCH_MMSS,
- ALARM_MATCH_HHMMSS,
-} watch_rtc_alarm_match;
-
-/** @brief Called by main.c to check if the RTC is enabled.
- * You may call this function, but outside of app_init, it should always return true.
- */
-bool _watch_rtc_is_enabled(void);
-
-/** @brief Sets the date and time.
- * @param date_time The date and time you wish to set, with a year value from 0-63 representing 2020-2083.
- * @note The SAM L22 stores the year as six bits representing a value from 0 to 63. It treats this as a year
- * offset from a reference year, which must be a leap year. Since 2020 was a leap year, and it allows
- * useful dates through 2083, it is assumed that watch apps will use 2020 as the reference year; thus
- * 1 means 2021, 2 means 2022, etc. **You will be responsible for handling this offset in your code**,
- * if the calendar year is needed for timestamp calculation logic or display purposes.
- */
-void watch_rtc_set_date_time(watch_date_time date_time);
-
-/** @brief Returns the date and time.
- * @return A watch_date_time with the current date and time, with a year value from 0-63 representing 2020-2083.
- * @see watch_rtc_set_date_time for notes about how the year is stored.
- */
-watch_date_time watch_rtc_get_date_time(void);
-
-/** @brief Registers an alarm callback that will be called when the RTC time matches the target time, as masked
- * by the provided mask.
- * @param callback The function you wish to have called when the alarm fires. If this value is NULL, the alarm
- * interrupt will still be enabled, but no callback function will be called.
- * @param alarm_time The time that you wish to match. The date is currently ignored.
- * @param mask One of the values in watch_rtc_alarm_match indicating which values to check.
- * @details The alarm interrupt is a versatile tool for scheduling events in the future, especially since it can
- * wake the device from all sleep modes. The key to its versatility is the mask parameter.
- * Suppose we set an alarm for midnight, 00:00:00.
- * * if mask is ALARM_MATCH_SS, the alarm will fire every minute when the clock ticks to seconds == 0.
- * * with ALARM_MATCH_MMSS, the alarm will once an hour, at the top of each hour.
- * * with ALARM_MATCH_HHMMSS, the alarm will fire at midnight every day.
- * In theory the SAM L22's alarm function can match on days, months and even years, but I have not had
- * success with this yet; as such, I am omitting these options for now.
- */
-void watch_rtc_register_alarm_callback(ext_irq_cb_t callback, watch_date_time alarm_time, watch_rtc_alarm_match mask);
-
-/** @brief Disables the alarm callback.
- */
-void watch_rtc_disable_alarm_callback(void);
-
-/** @brief Registers a "tick" callback that will be called once per second.
- * @param callback The function you wish to have called when the clock ticks. If you pass in NULL, the tick
- * interrupt will still be enabled, but no callback function will be called.
- * @note this is equivalent to calling watch_rtc_register_periodic_callback with a frequency of 1. It can be
- * disabled with either watch_rtc_disable_tick_callback() or watch_rtc_disable_periodic_callback(1),
- * and will also be disabled when watch_rtc_disable_all_periodic_callbacks is called.
- */
-void watch_rtc_register_tick_callback(ext_irq_cb_t callback);
-
-/** @brief Disables the tick callback for the given period.
- */
-void watch_rtc_disable_tick_callback(void);
-
-/** @brief Registers a callback that will be called at a configurable period.
- * @param callback The function you wish to have called at the specified period. If you pass in NULL, the periodic
- * interrupt will still be enabled, but no callback function will be called.
- * @param frequency The frequency of the tick in Hz. **Must be a power of 2**, from 1 to 128 inclusive.
- * @note A 1 Hz tick (@see watch_rtc_register_tick_callback) is suitable for most applications, in that it gives you a
- * chance to update the display once a second — an ideal update rate for a watch! If however you are displaying
- * a value (such as an accelerometer output) that updates more frequently than once per second, you may want to
- * tick at 16 or 32 Hz to update the screen more quickly. Just remember that the more frequent the tick, the more
- * power your app will consume. Ideally you should enable the fast tick only when the user requires it (i.e. in
- * response to an input event), and move back to the slow tick after some time.
- *
- * Also note that the RTC peripheral does not have sub-second resolution, so even if you set a 2 or 4 Hz interval,
- * the system will not have any way of telling you where you are within a given second; watch_rtc_get_date_time
- * will return the exact same timestamp until the second ticks over.
- */
-void watch_rtc_register_periodic_callback(ext_irq_cb_t callback, uint8_t frequency);
-
-/** @brief Disables the tick callback for the given period.
- * @param frequency The frequency of the tick you wish to disable, in Hz. **Must be a power of 2**, from 1 to 128.
- */
-void watch_rtc_disable_periodic_callback(uint8_t frequency);
-
-/** @brief Disables all periodic callbacks, including the once-per-second tick callback.
- */
-void watch_rtc_disable_all_periodic_callbacks(void);
-
-/** @brief Sets the system date and time.
- * @param date_time A struct representing the date and time you wish to set.
- */
-__attribute__((deprecated("Use watch_rtc_set_date_time function instead")))
-void watch_set_date_time(struct calendar_date_time date_time);
-
-/** @brief Returns the system date and time in the provided struct.
- * @param date_time A pointer to a calendar_date_time struct. It will have with the correct date and time on return.
- */
-__attribute__((deprecated("Use the watch_rtc_get_date_time function instead")))
-void watch_get_date_time(struct calendar_date_time *date_time);
-
-/** @brief Registers a "tick" callback that will be called once per second.
- * @param callback The function you wish to have called when the clock ticks. If you pass in NULL, the tick
- * interrupt will still be enabled, but no callback function will be called.
- */
-__attribute__((deprecated("Use the watch_rtc_register_tick_callback function instead")))
-void watch_register_tick_callback(ext_irq_cb_t callback);
-
-/// @}
-#endif
diff --git a/watch-library/watch/watch_slcd.c b/watch-library/watch/watch_slcd.c
deleted file mode 100644
index 1b1e53e4..00000000
--- a/watch-library/watch/watch_slcd.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 "watch_slcd.h"
-#include "hpl_slcd_config.h"
-
- //////////////////////////////////////////////////////////////////////////////////////////
-// Segmented Display
-
-static const uint8_t Character_Set[] =
-{
- 0b00000000, //
- 0b01100000, // ! (L in the top half for positions 4 and 6)
- 0b00100010, // "
- 0b01100011, // # (degree symbol, hash mark doesn't fit)
- 0b00000000, // $ (unused)
- 0b00000000, // % (unused)
- 0b01000100, // & ("lowercase 7" for positions 4 and 6)
- 0b00100000, // '
- 0b00111001, // (
- 0b00001111, // )
- 0b00000000, // * (unused)
- 0b11000000, // + (only works in position 0)
- 0b00000100, // ,
- 0b01000000, // -
- 0b01000000, // . (same as -, semantically most useful)
- 0b00010010, // /
- 0b00111111, // 0
- 0b00000110, // 1
- 0b01011011, // 2
- 0b01001111, // 3
- 0b01100110, // 4
- 0b01101101, // 5
- 0b01111101, // 6
- 0b00000111, // 7
- 0b01111111, // 8
- 0b01101111, // 9
- 0b00000000, // : (unused)
- 0b00000000, // ; (unused)
- 0b01011000, // <
- 0b01001000, // =
- 0b01001100, // >
- 0b01010011, // ?
- 0b11111111, // @ (all segments on)
- 0b01110111, // A
- 0b01111111, // B
- 0b00111001, // C
- 0b00111111, // D
- 0b01111001, // E
- 0b01110001, // F
- 0b00111101, // G
- 0b01110110, // H
- 0b10001001, // I (only works in position 0)
- 0b00001110, // J
- 0b01110101, // K
- 0b00111000, // L
- 0b10110111, // M (only works in position 0)
- 0b00110111, // N
- 0b00111111, // O
- 0b01110011, // P
- 0b01100111, // Q
- 0b11110111, // R (only works in position 1)
- 0b01101101, // S
- 0b10000001, // T (only works in position 0; set (1, 12) to make it work in position 1)
- 0b00111110, // U
- 0b00111110, // V
- 0b10111110, // W (only works in position 0)
- 0b01111110, // X
- 0b01101110, // Y
- 0b00011011, // Z
- 0b00111001, // [
- 0b00100100, // backslash
- 0b00001111, // ]
- 0b00100011, // ^
- 0b00001000, // _
- 0b00000010, // `
- 0b01011111, // a
- 0b01111100, // b
- 0b01011000, // c
- 0b01011110, // d
- 0b01111011, // e
- 0b01110001, // f
- 0b01101111, // g
- 0b01110100, // h
- 0b00010000, // i
- 0b01000010, // j (appears as superscript to work in more positions)
- 0b01110101, // k
- 0b00110000, // l
- 0b10110111, // m (only works in position 0)
- 0b01010100, // n
- 0b01011100, // o
- 0b01110011, // p
- 0b01100111, // q
- 0b01010000, // r
- 0b01101101, // s
- 0b01111000, // t
- 0b01100010, // u (appears in (u)pper half to work in more positions)
- 0b00011100, // v (looks like u but in the lower half)
- 0b10111110, // w (only works in position 0)
- 0b01111110, // x
- 0b01101110, // y
- 0b00011011, // z
- 0b00111001, // {
- 0b00110000, // |
- 0b00001111, // }
- 0b00000001, // ~
-};
-
-static const uint64_t Segment_Map[] = {
- 0x4e4f0e8e8f8d4d0d, // Position 0, mode
- 0xc8c4c4c8b4b4b0b, // Position 1, mode (Segments B and C shared, as are segments E and F)
- 0xc049c00a49890949, // Position 2, day of month (Segments A, D, G shared; missing segment F)
- 0xc048088886874707, // Position 3, day of month
- 0xc053921252139352, // Position 4, clock hours (Segments A and D shared)
- 0xc054511415559594, // Position 5, clock hours
- 0xc057965616179716, // Position 6, clock minutes (Segments A and D shared)
- 0xc041804000018a81, // Position 7, clock minutes
- 0xc043420203048382, // Position 8, clock seconds
- 0xc045440506468584, // Position 9, clock seconds
-};
-
-static const uint8_t Num_Chars = 10;
-
-static const uint32_t IndicatorSegments[6] = {
- SLCD_SEGID(0, 17), // WATCH_INDICATOR_SIGNAL
- SLCD_SEGID(0, 16), // WATCH_INDICATOR_BELL
- SLCD_SEGID(2, 17), // WATCH_INDICATOR_PM
- SLCD_SEGID(2, 16), // WATCH_INDICATOR_24H
- SLCD_SEGID(1, 10), // WATCH_INDICATOR_LAP
-};
-
-static void _sync_slcd(void) {
- while (SLCD->SYNCBUSY.reg);
-}
-
-void watch_enable_display(void) {
- SEGMENT_LCD_0_init();
- slcd_sync_enable(&SEGMENT_LCD_0);
-}
-
-inline void watch_set_pixel(uint8_t com, uint8_t seg) {
- slcd_sync_seg_on(&SEGMENT_LCD_0, SLCD_SEGID(com, seg));
-}
-
-inline void watch_clear_pixel(uint8_t com, uint8_t seg) {
- slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(com, seg));
-}
-
-void watch_clear_display(void) {
- SLCD->SDATAL0.reg = 0;
- SLCD->SDATAL1.reg = 0;
- SLCD->SDATAL2.reg = 0;
-}
-
-static void watch_display_character(uint8_t character, uint8_t position) {
- // special cases for positions 4 and 6
- if (position == 4 || position == 6) {
- if (character == '7') character = '&'; // "lowercase" 7
- else if (character == 'A') character = 'a'; // A needs to be lowercase
- else if (character == 'o') character = 'O'; // O needs to be uppercase
- else if (character == 'L') character = '!'; // L needs to be in top half
- else if (character == 'M' || character == 'm' || character == 'N') character = 'n'; // M and uppercase N need to be lowercase n
- else if (character == 'c') character = 'C'; // C needs to be uppercase
- else if (character == 'J') character = 'j'; // same
- else if (character == 'v' || character == 'V' || character == 'U' || character == 'W' || character == 'w') character = 'u'; // bottom segment duplicated, so show in top half
- } else {
- if (character == 'u') character = 'v'; // we can use the bottom segment; move to lower half
- else if (character == 'j') character = 'J'; // same but just display a normal J
- }
- if (position > 1) {
- if (character == 'T') character = 't'; // uppercase T only works in positions 0 and 1
- }
- if (position == 1) {
- if (character == 'o') character = 'O'; // O needs to be uppercase
- if (character == 'i') character = 'l'; // I needs to be uppercase (use an l, it looks the same)
- if (character == 'n') character = 'N'; // N needs to be uppercase
- if (character == 'r') character = 'R'; // R needs to be uppercase
- if (character == 'd') character = 'D'; // D needs to be uppercase
- if (character == 'v' || character == 'V' || character == 'u') character = 'U'; // side segments shared, make uppercase
- if (character == 'b') character = 'B'; // B needs to be uppercase
- if (character == 'c') character = 'C'; // C needs to be uppercase
- } else {
- if (character == 'R') character = 'r'; // R needs to be lowercase almost everywhere
- }
- if (position == 0) {
- slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(0, 15)); // clear funky ninth segment
- } else {
- if (character == 'I') character = 'l'; // uppercase I only works in position 0
- }
-
- uint64_t segmap = Segment_Map[position];
- uint64_t segdata = Character_Set[character - 0x20];
-
- for (int i = 0; i < 8; i++) {
- uint8_t com = (segmap & 0xFF) >> 6;
- if (com > 2) {
- // COM3 means no segment exists; skip it.
- segmap = segmap >> 8;
- segdata = segdata >> 1;
- continue;
- }
- uint8_t seg = segmap & 0x3F;
- slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(com, seg));
- if (segdata & 1) slcd_sync_seg_on(&SEGMENT_LCD_0, SLCD_SEGID(com, seg));
- segmap = segmap >> 8;
- segdata = segdata >> 1;
- }
- if (character == 'T' && position == 1) slcd_sync_seg_on(&SEGMENT_LCD_0, SLCD_SEGID(1, 12)); // add descender
- else if (position == 0 && (character == 'B' || character == 'D')) slcd_sync_seg_on(&SEGMENT_LCD_0, SLCD_SEGID(0, 15)); // add funky ninth segment
- else if (position == 1 && (character == 'B' || character == 'D' || character == '@')) slcd_sync_seg_on(&SEGMENT_LCD_0, SLCD_SEGID(0, 12)); // add funky ninth segment
-}
-
-void watch_display_string(char *string, uint8_t position) {
- size_t i = 0;
- while(string[i] != 0) {
- watch_display_character(string[i], position + i);
- i++;
- if (position + i >= Num_Chars) break;
- }
- // uncomment this line to see screen output on terminal, i.e.
- // FR 29
- // 11 50 23
- // note that for partial displays (positon > 0) it will only show the characters that were updated.
- // printf("________\n %c%c %c%c\n%c%c %c%c %c%c\n--------\n", (position > 0) ? ' ' : string[0], (position > 1) ? ' ' : string[1 - position], (position > 2) ? ' ' : string[2 - position], (position > 3) ? ' ' : string[3 - position], (position > 4) ? ' ' : string[4 - position], (position > 5) ? ' ' : string[5 - position], (position > 6) ? ' ' : string[6 - position], (position > 7) ? ' ' : string[7 - position], (position > 8) ? ' ' : string[8 - position], (position > 9) ? ' ' : string[9 - position]);
-}
-
-inline void watch_set_colon(void) {
- slcd_sync_seg_on(&SEGMENT_LCD_0, SLCD_SEGID(1, 16));
-}
-
-inline void watch_clear_colon(void) {
- slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(1, 16));
-}
-
-inline void watch_set_indicator(WatchIndicatorSegment indicator) {
- slcd_sync_seg_on(&SEGMENT_LCD_0, IndicatorSegments[indicator]);
-}
-
-inline void watch_clear_indicator(WatchIndicatorSegment indicator) {
- slcd_sync_seg_off(&SEGMENT_LCD_0, IndicatorSegments[indicator]);
-}
-
-void watch_clear_all_indicators(void) {
- slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(2, 17));
- slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(2, 16));
- slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(0, 17));
- slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(0, 16));
- slcd_sync_seg_off(&SEGMENT_LCD_0, SLCD_SEGID(1, 10));
-}
-
-void watch_start_character_blink(char character, uint32_t duration) {
- SLCD->CTRLD.bit.FC0EN = 0;
- _sync_slcd();
-
- if (duration <= SLCD_FC_BYPASS_MAX_MS) {
- SLCD->FC0.reg = SLCD_FC0_PB | ((duration / (1000 / SLCD_FRAME_FREQUENCY)) - 1);
- } else {
- SLCD->FC0.reg = (((duration / (1000 / SLCD_FRAME_FREQUENCY)) / 8 - 1));
- }
- SLCD->CTRLD.bit.FC0EN = 1;
-
- watch_display_character(character, 7);
- watch_clear_pixel(2, 10); // clear segment B of position 7 since it can't blink
-
- SLCD->CTRLD.bit.BLINK = 0;
- SLCD->CTRLA.bit.ENABLE = 0;
- _sync_slcd();
-
- SLCD->BCFG.bit.BSS0 = 0x07;
- SLCD->BCFG.bit.BSS1 = 0x07;
-
- SLCD->CTRLD.bit.BLINK = 1;
- _sync_slcd();
- SLCD->CTRLA.bit.ENABLE = 1;
- _sync_slcd();
-}
-
-void watch_stop_blink(void) {
- SLCD->CTRLD.bit.FC0EN = 0;
- SLCD->CTRLD.bit.BLINK = 0;
-}
-
-void watch_start_tick_animation(uint32_t duration) {
- watch_display_character(' ', 8);
- const uint32_t segs[] = { SLCD_SEGID(0, 2)};
- slcd_sync_start_animation(&SEGMENT_LCD_0, segs, 1, duration);
-}
-
-bool watch_tick_animation_is_running(void) {
- return hri_slcd_get_CTRLD_CSREN_bit(SLCD);
-}
-
-void watch_stop_tick_animation(void) {
- const uint32_t segs[] = { SLCD_SEGID(0, 2)};
- slcd_sync_stop_animation(&SEGMENT_LCD_0, segs, 1);
- watch_display_character(' ', 8);
-}
diff --git a/watch-library/watch/watch_slcd.h b/watch-library/watch/watch_slcd.h
deleted file mode 100644
index 3f550bb0..00000000
--- a/watch-library/watch/watch_slcd.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_SLCD_H_INCLUDED
-#define _WATCH_SLCD_H_INCLUDED
-////< @file watch_slcd.h
-
-#include "watch.h"
-
-/** @addtogroup slcd Segment LCD Display
- * @brief This section covers functions related to the Segment LCD display driver, which is responsible
- * for displaying strings of characters and indicators on the main watch display.
- * @details The segment LCD controller consumes about 3 microamperes of power with no segments on, and
- * about 4 microamperes with all segments on. There is also a slight power impact associated
- * with updating the screen (about 1 microampere to update at 1 Hz). For the absolute lowest
- * power operation, update the display only when its contents have changed, and disable the
- * SLCD peripheral when the screen is not in use.
- * For a map of all common and segment pins, see <a href="segmap.html">segmap.html</a>. You can
- * hover over any segment in that diagram to view the common and segment pins associated with
- * each segment of the display.
- */
-/// @{
-
-/// An enum listing the icons and indicators available on the watch.
-typedef enum WatchIndicatorSegment {
- WATCH_INDICATOR_SIGNAL = 0, ///< The hourly signal indicator; also useful for indicating that sensors are on.
- WATCH_INDICATOR_BELL, ///< The small bell indicating that an alarm is set.
- WATCH_INDICATOR_PM, ///< The PM indicator, indicating that a time is in the afternoon.
- WATCH_INDICATOR_24H, ///< The 24H indicator, indicating that the watch is in a 24-hour mode.
- WATCH_INDICATOR_LAP ///< The LAP indicator; the F-91W uses this in its stopwatch UI.
-} WatchIndicatorSegment;
-
-/** @brief Enables the Segment LCD display.
- * Call this before attempting to set pixels or display strings.
- */
-void watch_enable_display(void);
-
-/** @brief Sets a pixel. Use this to manually set a pixel with a given common and segment number.
- * See <a href="segmap.html">segmap.html</a>.
- * @param com the common pin, numbered from 0-2.
- * @param seg the segment pin, numbered from 0-23.
- */
-void watch_set_pixel(uint8_t com, uint8_t seg);
-
-/** @brief Clears a pixel. Use this to manually clear a pixel with a given common and segment number.
- * See <a href="segmap.html">segmap.html</a>.
- * @param com the common pin, numbered from 0-2.
- * @param seg the segment pin, numbered from 0-23.
- */
-void watch_clear_pixel(uint8_t com, uint8_t seg);
-
-/** @brief Clears all segments of the display, including incicators and the colon.
- */
-void watch_clear_display(void);
-
-/** @brief Displays a string at the given position, starting from the top left. There are ten digits.
- A space in any position will clear that digit.
- * @param string A null-terminated string.
- * @param position The position where you wish to start displaying the string. The day of week digits
- * are positions 0 and 1; the day of month digits are positions 2 and 3, and the main
- * clock line occupies positions 4-9.
- * @note This method does not clear the display; if for example you display a two-character string at
- position 0, positions 2-9 will retain whatever state they were previously displaying.
- */
-void watch_display_string(char *string, uint8_t position);
-
-/** @brief Turns the colon segment on.
- */
-void watch_set_colon(void);
-
-/** @brief Turns the colon segment off.
- */
-void watch_clear_colon(void);
-
-/** @brief Sets an indicator on the LCD. Use this to turn on one of the indicator segments.
- * @param indicator One of the indicator segments from the enum. @see WatchIndicatorSegment
- */
-void watch_set_indicator(WatchIndicatorSegment indicator);
-
-/** @brief Clears an indicator on the LCD. Use this to turn off one of the indicator segments.
- * @param indicator One of the indicator segments from the enum. @see WatchIndicatorSegment
- */
-void watch_clear_indicator(WatchIndicatorSegment indicator);
-
-/** @brief Clears all indicator segments.
- * @see WatchIndicatorSegment
- */
-void watch_clear_all_indicators(void);
-
-/** @brief Blinks a single character in position 7. Does not affect other positions.
- * @details Six of the seven segments in position 7 (and only position 7) are capable of autonomous
- * blinking. This blinking does not require any CPU resources, and will continue even in
- * STANDBY and Sleep mode (but not Deep Sleep mode, since that mode turns off the LCD).
- * @param character The character you wish to blink.
- * @param duration The duration of the on/off cycle in milliseconds, from 50 to ~4250 ms.
- * @note Segment B of position 7 cannot blink autonomously, so not all characters will work well.
- * Supported characters for blinking:
- * * Punctuation: underscore, apostrophe, comma, hyphen, equals sign, tilde (top segment only)
- * * Numbers: 5, 6, ampersand (lowercase 7)
- * * Letters: b, C, c, E, F, h, i, L, l, n, o, S, t
- */
-void watch_start_character_blink(char character, uint32_t duration);
-
-/** @brief Stops and clears all blinking segments.
- * @details This will stop all blinking in position 7, and clear all segments in that digit.
- */
-void watch_stop_blink(void);
-
-/** @brief Begins a two-segment "tick-tock" animation in position 8.
- * @details Six of the seven segments in position 8 (and only position 8) are capable of autonomous
- * animation. This animation is very basic, and consists of moving a bit pattern forward
- * or backward in a shift register whose positions map to fixed segments on the LCD. Given
- * this constraint, an animation across all six segments does not make sense; so the watch
- * library offers only a simple "tick/tock" in segments D and E. This animation does not
- * require any CPU resources, and will continue even in STANDBY and Sleep mode (but not Deep
- * Sleep mode, since that mode turns off the LCD).
- * @param duration The duration of each frame in ms. 500 milliseconds produces a classic tick/tock.
- */
-void watch_start_tick_animation(uint32_t duration);
-
-/** @brief Checks if the tick animation is currently running.
- * @return true if the animation is running; false otherwise.
- */
-bool watch_tick_animation_is_running(void);
-
-/** @brief Stops the tick/tock animation and clears all animating segments.
- * @details This will stop the animation and clear all segments in position 8.
- */
-void watch_stop_tick_animation(void);
-/// @}
-#endif
diff --git a/watch-library/watch/watch_uart.c b/watch-library/watch/watch_uart.c
deleted file mode 100644
index 64b63bee..00000000
--- a/watch-library/watch/watch_uart.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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.
- */
-
- /*
- * UART methods are Copyright (c) 2014-2017, Alex Taradov <alex@taradov.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "watch_uart.h"
-#include "peripheral_clk_config.h"
-
-void watch_enable_debug_uart(uint32_t baud) {
- uint64_t br = (uint64_t)65536 * ((CONF_CPU_FREQUENCY * 4) - 16 * baud) / (CONF_CPU_FREQUENCY * 4);
-
- gpio_set_pin_direction(A2, GPIO_DIRECTION_OUT);
- gpio_set_pin_function(A2, PINMUX_PB02C_SERCOM3_PAD0);
-
- MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM3;
-
- GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN;
- while (0 == (GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN));
-
- SERCOM3->USART.CTRLA.reg =
- SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE(1/*USART_INT_CLK*/) |
- SERCOM_USART_CTRLA_RXPO(1/*PAD1*/) | SERCOM_USART_CTRLA_TXPO(0/*PAD0*/);
-
- SERCOM3->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
- SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/);
-
- SERCOM3->USART.BAUD.reg = (uint16_t)br;
-
- SERCOM3->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
-}
-
-void watch_debug_putc(char c) {
- while (!(SERCOM3->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE));
- SERCOM3->USART.DATA.reg = c;
-}
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-void watch_debug_puts(char *s) {
- while (*s) watch_debug_putc(*s++);
-}
-#pragma GCC diagnostic pop
diff --git a/watch-library/watch/watch_uart.h b/watch-library/watch/watch_uart.h
deleted file mode 100644
index 3e98bd35..00000000
--- a/watch-library/watch/watch_uart.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2020 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 _WATCH_UART_H_INCLUDED
-#define _WATCH_UART_H_INCLUDED
-////< @file watch_uart.h
-
-#include "watch.h"
-
-/** @addtogroup debug Debug UART
- * @brief This section covers functions related to the debug UART, available on
- * pin D1 of the 9-pin connector.
- * @warning These functions were used early on in development, before the TinyUSB
- * CDC was implemented. You can now print debug messages to the USB console
- * using printf, rendering this bit irrelevant. These methods will likely
- * be refactored out in the future, in favor of a more full-featured UART
- * on the nine-pin connector.
- **/
-/// @{
-/** @brief Initializes the debug UART.
- * @param baud The baud rate
- */
-__attribute__((deprecated("Use printf to log debug messages over USB.")))
-void watch_enable_debug_uart(uint32_t baud);
-
-/** @brief Outputs a single character on the debug UART.
- * @param c The character you wish to output.
- */
-__attribute__((deprecated("Use printf to log debug messages over USB.")))
-void watch_debug_putc(char c);
-
-/** @brief Outputs a string on the debug UART.
- * @param s A null-terminated string.
- */
-__attribute__((deprecated("Use printf to log debug messages over USB.")))
-void watch_debug_puts(char *s);
-/// @}
-#endif
diff --git a/watch-library/watch/watch_utility.c b/watch-library/watch/watch_utility.c
deleted file mode 100644
index 835076d9..00000000
--- a/watch-library/watch/watch_utility.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2021 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 <math.h>
-#include "watch_utility.h"
-
-const char * watch_utility_get_weekday(watch_date_time date_time) {
- static const char weekdays[7][3] = {"SA", "SU", "MO", "TU", "WE", "TH", "FR"};
- date_time.unit.year += 20;
- if (date_time.unit.month <= 2) {
- date_time.unit.month += 12;
- date_time.unit.year--;
- }
- return weekdays[(date_time.unit.day + 13 * (date_time.unit.month + 1) / 5 + date_time.unit.year + date_time.unit.year / 4 + 525) % 7];
-}
-
-uint32_t watch_utility_convert_to_unix_time(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint32_t utc_offset) {
- uint16_t DAYS_SO_FAR[] = {
- 0, // Jan
- 31, // Feb
- 59, // March
- 90, // April
- 120, // May
- 151, // June
- 181, // July
- 212, // August
- 243, // September
- 273, // October
- 304, // November
- 334 // December
- };
-
- uint32_t year_adj = year + 4800;
- uint32_t febs = year_adj - (month <= 2 ? 1 : 0); /* Februaries since base. */
- uint32_t leap_days = 1 + (febs / 4) - (febs / 100) + (febs / 400);
- uint32_t days = 365 * year_adj + leap_days + DAYS_SO_FAR[month - 1] + day - 1;
- days -= 2472692; /* Adjust to Unix epoch. */
-
- uint32_t timestamp = days * 86400;
- timestamp += hour * 3600;
- timestamp += minute * 60;
- timestamp += second;
- timestamp -= utc_offset;
-
- return timestamp;
-}
-
-uint32_t watch_utility_date_time_to_unix_time(watch_date_time date_time, uint32_t utc_offset) {
- return watch_utility_convert_to_unix_time(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second, utc_offset);
-}
-
-#define LEAPOCH (946684800LL + 86400*(31+29))
-
-#define DAYS_PER_400Y (365*400 + 97)
-#define DAYS_PER_100Y (365*100 + 24)
-#define DAYS_PER_4Y (365*4 + 1)
-
-watch_date_time watch_utility_date_time_from_unix_time(uint32_t timestamp, uint32_t utc_offset) {
- watch_date_time retval;
- retval.reg = 0;
- int32_t days, secs;
- int32_t remdays, remsecs, remyears;
- int32_t qc_cycles, c_cycles, q_cycles;
- int32_t years, months;
- int32_t wday, yday, leap;
- static const int8_t days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
- timestamp += utc_offset;
-
- secs = timestamp - LEAPOCH;
- days = secs / 86400;
- remsecs = secs % 86400;
- if (remsecs < 0) {
- remsecs += 86400;
- days--;
- }
-
- wday = (3+days)%7;
- if (wday < 0) wday += 7;
-
- qc_cycles = (int)(days / DAYS_PER_400Y);
- remdays = days % DAYS_PER_400Y;
- if (remdays < 0) {
- remdays += DAYS_PER_400Y;
- qc_cycles--;
- }
-
- c_cycles = remdays / DAYS_PER_100Y;
- if (c_cycles == 4) c_cycles--;
- remdays -= c_cycles * DAYS_PER_100Y;
-
- q_cycles = remdays / DAYS_PER_4Y;
- if (q_cycles == 25) q_cycles--;
- remdays -= q_cycles * DAYS_PER_4Y;
-
- remyears = remdays / 365;
- if (remyears == 4) remyears--;
- remdays -= remyears * 365;
-
- leap = !remyears && (q_cycles || !c_cycles);
- yday = remdays + 31 + 28 + leap;
- if (yday >= 365+leap) yday -= 365+leap;
-
- years = remyears + 4*q_cycles + 100*c_cycles + 400*qc_cycles;
-
- for (months=0; days_in_month[months] <= remdays; months++)
- remdays -= days_in_month[months];
-
- years += 2000;
-
- months += 2;
- if (months >= 12) {
- months -=12;
- years++;
- }
-
- if (years < 2020 || years > 2083) return retval;
- retval.unit.year = years - WATCH_RTC_REFERENCE_YEAR;
- retval.unit.month = months + 1;
- retval.unit.day = remdays + 1;
-
- retval.unit.hour = remsecs / 3600;
- retval.unit.minute = remsecs / 60 % 60;
- retval.unit.second = remsecs % 60;
-
- return retval;
-}
-
-watch_date_time watch_utility_date_time_convert_zone(watch_date_time date_time, uint32_t origin_utc_offset, uint32_t destination_utc_offset) {
- uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, origin_utc_offset);
- return watch_utility_date_time_from_unix_time(timestamp, destination_utc_offset);
-}
-
-float watch_utility_thermistor_temperature(uint16_t value, bool highside, float b_coefficient, float nominal_temperature, float nominal_resistance, float series_resistance) {
- float reading = (float)value;
-
- if (highside) {
- reading = (1023.0 * series_resistance) / (reading / 64.0);
- reading -= series_resistance;
- } else {
- reading = series_resistance / (65535.0 / value - 1.0);
- }
-
- reading = reading / nominal_resistance;
- reading = log(reading);
- reading /= b_coefficient;
- reading += 1.0 / (nominal_temperature + 273.15);
- reading = 1.0 / reading;
- reading -= 273.15;
-
- return reading;
-}
diff --git a/watch-library/watch/watch_utility.h b/watch-library/watch/watch_utility.h
deleted file mode 100644
index 66af6ed5..00000000
--- a/watch-library/watch/watch_utility.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2021 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 _WATCH_UTILITY_H_INCLUDED
-#define _WATCH_UTILITY_H_INCLUDED
-////< @file watch_utility.h
-
-#include "watch.h"
-
-/** @addtogroup utility Utility Functions
- * @brief This section covers various useful functions that don't fit anywhere else.
- **/
-/// @{
-/** @brief Returns a two-letter weekday for the given timestamp, suitable for display
- * in positions 0-1 of the watch face
- * @param date_time The watch_date_time whose weekday you want.
- */
-const char * watch_utility_get_weekday(watch_date_time date_time);
-
-/** @brief Returns the UNIX time (seconds since 1970) for a given date/time in UTC.
- * @param date_time The watch_date_time that you wish to convert.
- * @param year The year of the date you wish to convert.
- * @param month The month of the date you wish to convert.
- * @param day The day of the date you wish to convert.
- * @param hour The hour of the date you wish to convert.
- * @param minute The minute of the date you wish to convert.
- * @param second The second of the date you wish to convert.
- * @param utc_offset The number of seconds that date_time is offset from UTC, or 0 if the time is UTC.
- * @return A UNIX timestamp for the given date/time and UTC offset.
- * @note Implemented by Wesley Ellis (tahnok) and based on BSD-licensed code by Josh Haberman:
- * https://blog.reverberate.org/2020/05/12/optimizing-date-algorithms.html
- */
-uint32_t watch_utility_convert_to_unix_time(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint32_t utc_offset);
-
-/** @brief Returns the UNIX time (seconds since 1970) for a given watch_date_time struct.
- * @param date_time The watch_date_time that you wish to convert.
- * @param utc_offset The number of seconds that date_time is offset from UTC, or 0 if the time is UTC.
- * @return A UNIX timestamp for the given watch_date_time and UTC offset.
- */
-uint32_t watch_utility_date_time_to_unix_time(watch_date_time date_time, uint32_t utc_offset);
-
-/** @brief Returns the UNIX time (seconds since 1970) for a given watch_date_time struct.
- * @param timestamp The UNIX timestamp that you wish to convert.
- * @param utc_offset The number of seconds that you wish date_time to be offset from UTC.
- * @return A watch_date_time for the given UNIX timestamp and UTC offset, or if outside the range that
- * watch_date_time can represent, a watch_date_time with all fields set to 0.
- * @note Adapted from MIT-licensed code from musl, Copyright © 2005-2014 Rich Felker, et al.:
- * https://github.com/esmil/musl/blob/1cc81f5cb0df2b66a795ff0c26d7bbc4d16e13c6/src/time/__secs_to_tm.c
- */
-watch_date_time watch_utility_date_time_from_unix_time(uint32_t timestamp, uint32_t utc_offset);
-
-/** @brief Converts a time from a given time zone to another time zone.
- * @param date_time The watch_date_time that you wish to convert
- * @param origin_utc_offset The number of seconds from UTC in the origin time zone
- * @param destination_utc_offset The number of seconds from UTC in the destination time zone
- * @return A watch_date_time for the given UNIX timestamp and UTC offset, or if outside the range that
- * watch_date_time can represent, a watch_date_time with all fields set to 0.
- * @note Adapted from MIT-licensed code from musl, Copyright © 2005-2014 Rich Felker, et al.:
- * https://github.com/esmil/musl/blob/1cc81f5cb0df2b66a795ff0c26d7bbc4d16e13c6/src/time/__secs_to_tm.c
- */
-watch_date_time watch_utility_date_time_convert_zone(watch_date_time date_time, uint32_t origin_utc_offset, uint32_t destination_utc_offset);
-
-/** @brief Returns a temperature in degrees Celsius for a given thermistor voltage divider circuit.
- * @param value The raw analog reading from the thermistor pin (0-65535)
- * @param highside True if the thermistor is connected to VCC and the series resistor is connected
- * to GND; false if the thermistor is connected to GND and the series resistor is
- * connected to VCC.
- * @param b_coefficient From your thermistor's data sheet, the B25/85 coefficient. A typical value
- * will be between 2000 and 5000.
- * @param nominal_temperature From your thermistor's data sheet, the temperature (in Celsius) at
- * which the thermistor's resistance is at its nominal value.
- * @param nominal_resistance The thermistor's resistance at the nominal temperature.
- * @param series_resistance The value of the other resistor in the voltage divider.
- * @note Ported from Adafruit's MIT-licensed CircuitPython thermistor code, (c) 2017 Scott Shawcroft:
- * https://github.com/adafruit/Adafruit_CircuitPython_Thermistor/blob/main/adafruit_thermistor.py
- */
-float watch_utility_thermistor_temperature(uint16_t value, bool highside, float b_coefficient, float nominal_temperature, float nominal_resistance, float series_resistance);
-
-#endif