summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjoeycastillo <joeycastillo@utexas.edu>2021-09-29 11:46:53 -0400
committerGitHub <noreply@github.com>2021-09-29 11:46:53 -0400
commit7eb23e4f88a6633dd749ac2dc189249dac53e927 (patch)
tree1eb4b48fdccea954eca2883874f4c848f52912ec
parent751ed9c7a48b78063a0ef2e1d7e79ed03f70560b (diff)
parent116304162486afcdb2e9a63fb748800ed8639591 (diff)
downloadSensor-Watch-7eb23e4f88a6633dd749ac2dc189249dac53e927.tar.gz
Sensor-Watch-7eb23e4f88a6633dd749ac2dc189249dac53e927.tar.bz2
Sensor-Watch-7eb23e4f88a6633dd749ac2dc189249dac53e927.zip
Merge pull request #16 from joeycastillo/rtc-refactor
Refactor Real-Time Clock Functionality
-rw-r--r--apps/Sensor Watch BME280 Project/app.c62
-rw-r--r--apps/beats-time/app.c60
-rw-r--r--make.mk18
-rw-r--r--watch-library/hal/documentation/calendar.rst72
-rw-r--r--watch-library/hal/include/hal_calendar.h159
-rw-r--r--watch-library/hal/include/hpl_calendar.h251
-rw-r--r--watch-library/hal/src/hal_calendar.c645
-rw-r--r--watch-library/hpl/rtc/hpl_rtc.c430
-rw-r--r--watch-library/hpl/rtc/hpl_rtc_base.h52
-rw-r--r--watch-library/hw/driver_init.c11
-rw-r--r--watch-library/hw/driver_init.h21
-rw-r--r--watch-library/watch/watch.c12
-rw-r--r--watch-library/watch/watch_adc.c2
-rw-r--r--watch-library/watch/watch_adc.h5
-rw-r--r--watch-library/watch/watch_app.h3
-rw-r--r--watch-library/watch/watch_buzzer.c2
-rw-r--r--watch-library/watch/watch_buzzer.h5
-rw-r--r--watch-library/watch/watch_deepsleep.c38
-rw-r--r--watch-library/watch/watch_deepsleep.h10
-rw-r--r--watch-library/watch/watch_extint.c2
-rw-r--r--watch-library/watch/watch_extint.h4
-rw-r--r--watch-library/watch/watch_gpio.c2
-rw-r--r--watch-library/watch/watch_gpio.h5
-rw-r--r--watch-library/watch/watch_i2c.c4
-rw-r--r--watch-library/watch/watch_i2c.h5
-rw-r--r--watch-library/watch/watch_led.c2
-rw-r--r--watch-library/watch/watch_led.h5
-rw-r--r--watch-library/watch/watch_private.c4
-rw-r--r--watch-library/watch/watch_private.h8
-rw-r--r--watch-library/watch/watch_rtc.c167
-rw-r--r--watch-library/watch/watch_rtc.h114
-rw-r--r--watch-library/watch/watch_slcd.c2
-rw-r--r--watch-library/watch/watch_slcd.h5
-rw-r--r--watch-library/watch/watch_uart.c1
-rw-r--r--watch-library/watch/watch_uart.h5
35 files changed, 422 insertions, 1771 deletions
diff --git a/apps/Sensor Watch BME280 Project/app.c b/apps/Sensor Watch BME280 Project/app.c
index e07b35f8..366ccde9 100644
--- a/apps/Sensor Watch BME280 Project/app.c
+++ b/apps/Sensor Watch BME280 Project/app.c
@@ -21,13 +21,6 @@ void app_wake_from_deep_sleep() {
}
void app_setup() {
- struct calendar_date_time date_time;
- watch_get_date_time(&date_time);
- if (date_time.date.year < 2020) {
- date_time.date.year = 2020;
- watch_set_date_time(date_time);
- }
-
watch_enable_external_interrupts();
watch_register_interrupt_callback(BTN_MODE, cb_mode_pressed, INTERRUPT_TRIGGER_RISING);
watch_register_interrupt_callback(BTN_LIGHT, cb_light_pressed, INTERRUPT_TRIGGER_RISING);
@@ -64,7 +57,7 @@ void app_setup() {
watch_enable_display();
- watch_register_tick_callback(cb_tick);
+ watch_rtc_register_tick_callback(cb_tick);
}
/**
@@ -191,9 +184,8 @@ float read_humidity(int32_t t_fine) {
}
void log_data() {
- struct calendar_date_time date_time;
- watch_get_date_time(&date_time);
- uint8_t hour = date_time.time.hour;
+ watch_date_time date_time = watch_rtc_get_date_time();
+ uint8_t hour = date_time.unit.hour;
int8_t temperature = read_temperature(NULL);
for(int i = 0; i < MAX_DATA_POINTS - 1; i++) {
@@ -205,12 +197,11 @@ void log_data() {
}
void do_clock_mode() {
- struct calendar_date_time date_time;
+ watch_date_time date_time = watch_rtc_get_date_time();
const char months[12][3] = {"JA", "FE", "MR", "AR", "MA", "JN", "JL", "AU", "SE", "OC", "NO", "dE"};
- watch_get_date_time(&date_time);
- watch_display_string((char *)months[date_time.date.month - 1], 0);
- sprintf(buf, "%2d%2d%02d%02d", date_time.date.day, date_time.time.hour, date_time.time.min, date_time.time.sec);
+ watch_display_string((char *)months[date_time.unit.month - 1], 0);
+ sprintf(buf, "%2d%2d%02d%02d", date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);
watch_display_string(buf, 2);
watch_set_colon();
}
@@ -271,28 +262,27 @@ void prefs_mode_handle_secondary_button() {
}
void do_set_time_mode() {
- struct calendar_date_time date_time;
+ watch_date_time date_time = watch_rtc_get_date_time();
- watch_get_date_time(&date_time);
watch_display_string(" ", 0);
switch (application_state.page) {
case 0: // hour
- sprintf(buf, "ST t%2d", date_time.time.hour);
+ sprintf(buf, "ST t%2d", date_time.unit.hour);
break;
case 1: // minute
- sprintf(buf, "ST t %02d", date_time.time.min);
+ sprintf(buf, "ST t %02d", date_time.unit.minute);
break;
case 2: // second
- sprintf(buf, "ST t %02d", date_time.time.sec);
+ sprintf(buf, "ST t %02d", date_time.unit.second);
break;
case 3: // year
- sprintf(buf, "ST d%2d", date_time.date.year - 2000);
+ sprintf(buf, "ST d%2d", date_time.unit.year + 20);
break;
case 4: // month
- sprintf(buf, "ST d %02d", date_time.date.month);
+ sprintf(buf, "ST d %02d", date_time.unit.month);
break;
case 5: // day
- sprintf(buf, "ST d %02d", date_time.date.day);
+ sprintf(buf, "ST d %02d", date_time.unit.day);
break;
}
watch_display_string(buf, 0);
@@ -305,37 +295,36 @@ void set_time_mode_handle_primary_button() {
}
void set_time_mode_handle_secondary_button() {
- struct calendar_date_time date_time;
- watch_get_date_time(&date_time);
+ watch_date_time date_time = watch_rtc_get_date_time();
const uint8_t days_in_month[12] = {31, 28, 31, 30, 31, 30, 30, 31, 30, 31, 30, 31};
switch (application_state.page) {
case 0: // hour
- date_time.time.hour = (date_time.time.hour + 1) % 24;
+ date_time.unit.hour = (date_time.unit.hour + 1) % 24;
break;
case 1: // minute
- date_time.time.min = (date_time.time.min + 1) % 60;
+ date_time.unit.minute = (date_time.unit.minute + 1) % 60;
break;
case 2: // second
- date_time.time.sec = 0;
+ date_time.unit.second = 0;
break;
case 3: // year
// only allow 2021-2030. fix this sometime next decade
- date_time.date.year = ((date_time.date.year % 10) + 1) + 2020;
+ date_time.unit.year = ((date_time.unit.year % 10) + 1);
break;
case 4: // month
- date_time.date.month = ((date_time.date.month + 1) % 12);
+ date_time.unit.month = ((date_time.unit.month + 1) % 12);
break;
case 5: // day
- date_time.date.day = date_time.date.day + 1;
+ date_time.unit.day = date_time.unit.day + 1;
// can't set to the 29th on a leap year. if it's february 29, set to 11:59 on the 28th.
// and it should roll over.
- if (date_time.date.day > days_in_month[date_time.date.month - 1]) {
- date_time.date.day = 1;
+ if (date_time.unit.day > days_in_month[date_time.unit.month - 1]) {
+ date_time.unit.day = 1;
}
break;
}
- watch_set_date_time(date_time);
+ watch_rtc_set_date_time(date_time);
}
void cb_mode_pressed() {
@@ -377,9 +366,8 @@ void cb_alarm_pressed() {
void cb_tick() {
// TODO: use alarm interrupt to trigger data acquisition.
- struct calendar_date_time date_time;
- watch_get_date_time(&date_time);
- if (date_time.time.min == 0 && date_time.time.sec == 0) {
+ watch_date_time date_time = watch_rtc_get_date_time();
+ if (date_time.unit.minute == 0 && date_time.unit.second == 0) {
log_data();
}
diff --git a/apps/beats-time/app.c b/apps/beats-time/app.c
index c694bc5e..47d0add2 100644
--- a/apps/beats-time/app.c
+++ b/apps/beats-time/app.c
@@ -51,13 +51,6 @@ void app_wake_from_deep_sleep() {
}
void app_setup() {
- struct calendar_date_time date_time;
- watch_get_date_time(&date_time);
- if (date_time.date.year < 2020) {
- date_time.date.year = 2020;
- watch_set_date_time(date_time);
- }
-
watch_enable_external_interrupts();
watch_register_interrupt_callback(BTN_MODE, cb_mode_pressed, INTERRUPT_TRIGGER_RISING);
watch_register_interrupt_callback(BTN_LIGHT, cb_light_pressed, INTERRUPT_TRIGGER_RISING);
@@ -67,7 +60,7 @@ void app_setup() {
watch_enable_leds();
watch_enable_display();
- watch_register_tick_callback(cb_tick);
+ watch_rtc_register_tick_callback(cb_tick);
}
void app_prepare_for_sleep() {
@@ -128,24 +121,21 @@ bool app_loop() {
}
void do_clock_mode() {
- struct calendar_date_time date_time;
+ watch_date_time date_time = watch_rtc_get_date_time();
const char months[12][3] = {"JA", "FE", "MR", "AR", "MA", "JN", "JL", "AU", "SE", "OC", "NO", "dE"};
- watch_get_date_time(&date_time);
- watch_display_string((char *)months[date_time.date.month - 1], 0);
- sprintf(buf, "%2d%2d%02d%02d", date_time.date.day, date_time.time.hour, date_time.time.min, date_time.time.sec);
+ watch_display_string((char *)months[date_time.unit.month - 1], 0);
+ sprintf(buf, "%2d%2d%02d%02d", date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);
watch_display_string(buf, 2);
watch_set_colon();
+
}
void do_beats_mode() {
watch_clear_colon();
- struct calendar_date_time date_time;
-
- watch_get_date_time(&date_time);
-
- uint16_t beats = clock2beats(date_time.time.hour, date_time.time.min, date_time.time.sec, UTC_OFFSET);
+ watch_date_time date_time = watch_rtc_get_date_time();
+ uint16_t beats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, UTC_OFFSET);
sprintf(buf, "bt %04d ", beats);
watch_display_string(buf, 0);
@@ -164,28 +154,27 @@ uint16_t clock2beats(uint16_t hours, uint16_t minutes, uint16_t seconds, int16_t
}
void do_set_time_mode() {
- struct calendar_date_time date_time;
+ watch_date_time date_time = watch_rtc_get_date_time();
- watch_get_date_time(&date_time);
watch_display_string(" ", 0);
switch (application_state.page) {
case 0: // hour
- sprintf(buf, "ST t%2d", date_time.time.hour);
+ sprintf(buf, "ST t%2d", date_time.unit.hour);
break;
case 1: // minute
- sprintf(buf, "ST t %02d", date_time.time.min);
+ sprintf(buf, "ST t %02d", date_time.unit.minute);
break;
case 2: // second
- sprintf(buf, "ST t %02d", date_time.time.sec);
+ sprintf(buf, "ST t %02d", date_time.unit.second);
break;
case 3: // year
- sprintf(buf, "ST d%2d", date_time.date.year - 2000);
+ sprintf(buf, "ST d%2d", date_time.unit.year + 20);
break;
case 4: // month
- sprintf(buf, "ST d %02d", date_time.date.month);
+ sprintf(buf, "ST d %02d", date_time.unit.month);
break;
case 5: // day
- sprintf(buf, "ST d %02d", date_time.date.day);
+ sprintf(buf, "ST d %02d", date_time.unit.day);
break;
}
watch_display_string(buf, 0);
@@ -198,37 +187,36 @@ void set_time_mode_handle_primary_button() {
}
void set_time_mode_handle_secondary_button() {
- struct calendar_date_time date_time;
- watch_get_date_time(&date_time);
+ watch_date_time date_time = watch_rtc_get_date_time();
const uint8_t days_in_month[12] = {31, 28, 31, 30, 31, 30, 30, 31, 30, 31, 30, 31};
switch (application_state.page) {
case 0: // hour
- date_time.time.hour = (date_time.time.hour + 1) % 24;
+ date_time.unit.hour = (date_time.unit.hour + 1) % 24;
break;
case 1: // minute
- date_time.time.min = (date_time.time.min + 1) % 60;
+ date_time.unit.minute = (date_time.unit.minute + 1) % 60;
break;
case 2: // second
- date_time.time.sec = 0;
+ date_time.unit.second = 0;
break;
case 3: // year
// only allow 2021-2030. fix this sometime next decade
- date_time.date.year = ((date_time.date.year % 10) + 1) + 2020;
+ date_time.unit.year = ((date_time.unit.year % 10) + 1);
break;
case 4: // month
- date_time.date.month = ((date_time.date.month + 1) % 12);
+ date_time.unit.month = ((date_time.unit.month + 1) % 12);
break;
case 5: // day
- date_time.date.day = date_time.date.day + 1;
+ date_time.unit.day = date_time.unit.day + 1;
// can't set to the 29th on a leap year. if it's february 29, set to 11:59 on the 28th.
// and it should roll over.
- if (date_time.date.day > days_in_month[date_time.date.month - 1]) {
- date_time.date.day = 1;
+ if (date_time.unit.day > days_in_month[date_time.unit.month - 1]) {
+ date_time.unit.day = 1;
}
break;
}
- watch_set_date_time(date_time);
+ watch_rtc_set_date_time(date_time);
}
void cb_mode_pressed() {
diff --git a/make.mk b/make.mk
index 461bef79..299d9d31 100644
--- a/make.mk
+++ b/make.mk
@@ -31,8 +31,6 @@ LDFLAGS += -mcpu=cortex-m0plus -mthumb
LDFLAGS += -Wl,--gc-sections
LDFLAGS += -Wl,--script=$(TOP)//watch-library/linker/saml22j18.ld
-# If you add any additional directories with headers, add them to this list, e.g.
-# ../drivers/
INCLUDES += \
-I$(TOP)/tinyusb/src \
-I$(TOP)/boards/$(BOARD) \
@@ -54,7 +52,6 @@ INCLUDES += \
-I$(TOP)/watch-library/hpl/oscctrl/ \
-I$(TOP)/watch-library/hpl/pm/ \
-I$(TOP)/watch-library/hpl/port/ \
- -I$(TOP)/watch-library/hpl/rtc/ \
-I$(TOP)/watch-library/hpl/sercom/ \
-I$(TOP)/watch-library/hpl/slcd/ \
-I$(TOP)/watch-library/hpl/systick/ \
@@ -64,8 +61,6 @@ INCLUDES += \
-I$(TOP)/watch-library/watch/ \
-I$(TOP)/watch-library
-# If you add any additional C files to your project, add them each to this list, e.g.
-# ../drivers/st25dv.c
SRCS += \
$(TOP)/tinyusb/src/tusb.c \
$(TOP)/tinyusb/src/common/tusb_fifo.c \
@@ -76,9 +71,19 @@ SRCS += \
$(TOP)/watch-library/main.c \
$(TOP)/watch-library/startup_saml22.c \
$(TOP)/watch-library/hw/driver_init.c \
+ $(TOP)/watch-library/watch/watch_rtc.c \
+ $(TOP)/watch-library/watch/watch_slcd.c \
+ $(TOP)/watch-library/watch/watch_extint.c \
+ $(TOP)/watch-library/watch/watch_led.c \
+ $(TOP)/watch-library/watch/watch_buzzer.c \
+ $(TOP)/watch-library/watch/watch_adc.c \
+ $(TOP)/watch-library/watch/watch_gpio.c \
+ $(TOP)/watch-library/watch/watch_i2c.c \
+ $(TOP)/watch-library/watch/watch_uart.c \
+ $(TOP)/watch-library/watch/watch_deepsleep.c \
+ $(TOP)/watch-library/watch/watch_private.c \
$(TOP)/watch-library/watch/watch.c \
$(TOP)/watch-library/hal/src/hal_atomic.c \
- $(TOP)/watch-library/hal/src/hal_calendar.c \
$(TOP)/watch-library/hal/src/hal_delay.c \
$(TOP)/watch-library/hal/src/hal_ext_irq.c \
$(TOP)/watch-library/hal/src/hal_gpio.c \
@@ -100,7 +105,6 @@ SRCS += \
$(TOP)/watch-library/hpl/osc32kctrl/hpl_osc32kctrl.c \
$(TOP)/watch-library/hpl/oscctrl/hpl_oscctrl.c \
$(TOP)/watch-library/hpl/pm/hpl_pm.c \
- $(TOP)/watch-library/hpl/rtc/hpl_rtc.c \
$(TOP)/watch-library/hpl/sercom/hpl_sercom.c \
$(TOP)/watch-library/hpl/slcd/hpl_slcd.c \
$(TOP)/watch-library/hpl/systick/hpl_systick.c \
diff --git a/watch-library/hal/documentation/calendar.rst b/watch-library/hal/documentation/calendar.rst
deleted file mode 100644
index 8a3de6e8..00000000
--- a/watch-library/hal/documentation/calendar.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-===============================
-The Calendar driver (bare-bone)
-===============================
-
-The Calendar driver provides means to set and get current date and time.
-After enabling, an instance of the driver starts counting time from the base date with
-the resolution of one second. The default base date is 00:00:00 1st of January 1970.
-Only the base year of the base date can be changed via the driver API.
-
-The current date and time is kept internally in a relative form as the difference between
-current date and time and the base date and time. This means that changing the base year changes
-current date.
-
-The base date and time defines time "zero" or the earliest possible point in time that the calender driver can describe,
-this means that current time and alarms can not be set to anything earlier than this time.
-
-The Calendar driver provides alarm functionality.
-An alarm is a software trigger which fires on particular date and time with particular periodicity.
-Upon firing the given callback function is called.
-
-An alarm can be in single-shot mode, firing only once at matching time; or in repeating mode, meaning that it will
-reschedule a new alarm automatically based on repeating mode configuration.
-In single-shot mode an alarm is removed from the alarm queue before its callback is called. It allows an application to
-reuse the memory of expired alarm in the callback.
-
-An alarm can be triggered on the following events: match on second, minute, hour, day, month or year.
-Matching on second means that the alarm is triggered when the value of seconds of the current time is equal to
-the alarm's value of seconds. This means repeating alarm with match on seconds is triggered with the period of a minute.
-Matching on minute means that the calendars minute and seconds values has to match the alarms, the rest of the date-time
-value is ignored. In repeating mode this means a new alarm every hour.
-The same logic is applied to match on hour, day, month and year.
-
-Each instance of the Calendar driver supports infinite amount of software alarms, only limited by the amount of RAM available.
-
-Features
---------
-* Initialization and de-initialization
-* Enabling and disabling
-* Date and time operations
-* Software alarms
-
-Applications
-------------
-* A source of current date and time for an embedded system.
-* Periodical functionality in low-power applications since the driver is designed to use 1Hz clock.
-* Periodical function calls in case if it is more convenient to operate with absolute time.
-
-Dependencies
-------------
-* This driver expects a counter to be increased by one every second to count date and time correctly.
-* Each instance of the driver requires separate hardware timer.
-
-Concurrency
------------
-The Calendar driver is an interrupt driven driver.This means that the interrupt that triggers an alarm may occur during
-the process of adding or removing an alarm via the driver's API. In such case the interrupt processing is postponed
-until the alarm adding or removing is complete.
-
-The alarm queue is not protected from the access by interrupts not used by the driver. Due to this
-it is not recommended to add or remove an alarm from such interrupts: in case if a higher priority interrupt supersedes
-the driver's interrupt, adding or removing an alarm may cause unpredictable behavior of the driver.
-
-Limitations
------------
-* Only years divisible by 4 are deemed a leap year, this gives a correct result between the years 1901 to 2099.
-* The driver is designed to work outside of an operating system environment, the software alarm queue is therefore processed in interrupt context which may delay execution of other interrupts.
-* If there are a lot of frequently called interrupts with the priority higher than the driver's one, it may cause delay in alarm's triggering.
-* Changing the base year or setting current date or time does not shift alarms' date and time accordingly or expires alarms.
-
-Knows issues and workarounds
-----------------------------
-Not applicable
diff --git a/watch-library/hal/include/hal_calendar.h b/watch-library/hal/include/hal_calendar.h
index 26949a57..e69de29b 100644
--- a/watch-library/hal/include/hal_calendar.h
+++ b/watch-library/hal/include/hal_calendar.h
@@ -1,159 +0,0 @@
-/**
- * \file
- *
- * \brief Generic CALENDAR functionality declaration.
- *
- * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Subject to your compliance with these terms, you may use Microchip
- * software and any derivatives exclusively with Microchip products.
- * It is your responsibility to comply with third party license terms applicable
- * to your use of third party software (including open source software) that
- * may accompany Microchip software.
- *
- * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
- * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
- * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
- * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
- * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
- * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
- * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
- * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
- * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
- * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
- *
- * \asf_license_stop
- *
- */
-
-#ifndef _HAL_CALENDER_H_INCLUDED
-#define _HAL_CALENDER_H_INCLUDED
-
-#include "hpl_calendar.h"
-#include <utils_list.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \addtogroup doc_driver_hal_calendar_async
- *
- *@{
- */
-
-/** \brief Prototype of callback on alarm match
- * \param calendar Pointer to the HAL Calendar instance.
- */
-typedef void (*calendar_cb_alarm_t)(struct calendar_descriptor *const calendar);
-
-/** \brief Struct for alarm time
- */
-struct calendar_alarm {
- struct list_element elem;
- struct _calendar_alarm cal_alarm;
- calendar_cb_alarm_t callback;
-};
-
-/** \brief Initialize the Calendar HAL instance and hardware
- *
- * \param calendar Pointer to the HAL Calendar instance.
- * \param hw Pointer to the hardware instance.
- * \return Operation status of init
- * \retval 0 Completed successfully.
- */
-int32_t calendar_init(struct calendar_descriptor *const calendar, const void *hw);
-
-/** \brief Reset the Calendar HAL instance and hardware
- *
- * Reset Calendar instance to hardware defaults.
- *
- * \param calendar Pointer to the HAL Calendar instance.
- * \return Operation status of reset.
- * \retval 0 Completed successfully.
- */
-int32_t calendar_deinit(struct calendar_descriptor *const calendar);
-
-/** \brief Enable the Calendar HAL instance and hardware
- *
- * \param calendar Pointer to the HAL Calendar instance.
- * \return Operation status of init
- * \retval 0 Completed successfully.
- */
-int32_t calendar_enable(struct calendar_descriptor *const calendar);
-
-/** \brief Disable the Calendar HAL instance and hardware
- *
- * Disable Calendar instance to hardware defaults.
- *
- * \param calendar Pointer to the HAL Calendar instance.
- * \return Operation status of reset.
- * \retval 0 Completed successfully.
- */
-int32_t calendar_disable(struct calendar_descriptor *const calendar);
-
-/** \brief Configure the base year for calendar HAL instance and hardware
- *
- * \param calendar Pointer to the HAL Calendar instance.
- * \param p_base_year The desired base year.
- * \retval 0 Completed successfully.
- */
-int32_t calendar_set_baseyear(struct calendar_descriptor *const calendar, const uint32_t p_base_year);
-
-/** \brief Configure the time for calendar HAL instance and hardware
- *
- * \param calendar Pointer to the HAL Calendar instance.
- * \param p_calendar_time Pointer to the time configuration.
- * \retval 0 Completed successfully.
- */
-int32_t calendar_set_time(struct calendar_descriptor *const calendar, struct calendar_time *const p_calendar_time);
-
-/** \brief Configure the date for calendar HAL instance and hardware
- *
- * \param calendar Pointer to the HAL Calendar instance.
- * \param p_calendar_date Pointer to the date configuration.
- * \return Operation status of time set.
- * \retval 0 Completed successfully.
- */
-int32_t calendar_set_date(struct calendar_descriptor *const calendar, struct calendar_date *const p_calendar_date);
-
-/** \brief Get the time for calendar HAL instance and hardware
- *
- * \param calendar Pointer to the HAL Calendar instance.
- * \param date_time Pointer to the value that will be filled with the current time.
- * \return Operation status of time retrieve.
- * \retval 0 Completed successfully.
- */
-int32_t calendar_get_date_time(struct calendar_descriptor *const calendar, struct calendar_date_time *const date_time);
-
-/** \brief Config the alarm time for calendar HAL instance and hardware
- *
- * Set the alarm time to calendar instance. If the callback is NULL, remove
- * the alarm if the alarm is already added, otherwise, ignore the alarm.
- *
- * \param calendar Pointer to the HAL Calendar instance.
- * \param alarm Pointer to the configuration.
- * \param callback Pointer to the callback function.
- * \return Operation status of alarm time set.
- * \retval 0 Completed successfully.
- */
-int32_t calendar_set_alarm(struct calendar_descriptor *const calendar, struct calendar_alarm *const alarm,
- calendar_cb_alarm_t callback);
-
-/** \brief Retrieve the current driver version
- * \return Current driver version.
- */
-uint32_t calendar_get_version(void);
-
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _HAL_CALENDER_H_INCLUDED */
diff --git a/watch-library/hal/include/hpl_calendar.h b/watch-library/hal/include/hpl_calendar.h
index f94249b9..0dce40fd 100644
--- a/watch-library/hal/include/hpl_calendar.h
+++ b/watch-library/hal/include/hpl_calendar.h
@@ -33,69 +33,11 @@
#ifndef _HPL_CALENDER_H_INCLUDED
#define _HPL_CALENDER_H_INCLUDED
-#include <compiler.h>
-#include <utils_list.h>
-#include "hpl_irq.h"
-
#ifdef __cplusplus
extern "C" {
#endif
/**
- * \brief Calendar structure
- *
- * The Calendar structure forward declaration.
- */
-struct calendar_dev;
-
-/**
- * \brief Available mask options for alarms.
- *
- * Available mask options for alarms.
- */
-enum calendar_alarm_option {
- /** Alarm disabled. */
- CALENDAR_ALARM_MATCH_DISABLED = 0,
- /** Alarm match on second. */
- CALENDAR_ALARM_MATCH_SEC,
- /** Alarm match on second and minute. */
- CALENDAR_ALARM_MATCH_MIN,
- /** Alarm match on second, minute, and hour. */
- CALENDAR_ALARM_MATCH_HOUR,
- /** Alarm match on second, minute, hour, and day. */
- CALENDAR_ALARM_MATCH_DAY,
- /** Alarm match on second, minute, hour, day, and month. */
- CALENDAR_ALARM_MATCH_MONTH,
- /** Alarm match on second, minute, hour, day, month and year. */
- CALENDAR_ALARM_MATCH_YEAR
-};
-
-/**
- * \brief Available mode for alarms.
- */
-enum calendar_alarm_mode { ONESHOT = 1, REPEAT };
-/**
- * \brief Prototype of callback on alarm match
- */
-typedef void (*calendar_drv_cb_t)();
-typedef void (*calendar_drv_extwake_cb_t)(uint8_t reason);
-
-/**
- * \brief Structure of Calendar instance
- */
-struct calendar_dev {
- /** Pointer to the hardware base */
- void *hw;
- /** Alarm match callback */
- calendar_drv_cb_t callback_alarm;
- /** Tamper callback */
- calendar_drv_extwake_cb_t callback_tamper;
- /** Tick callback */
- calendar_drv_cb_t callback_tick;
- /** IRQ struct */
- struct _irq_descriptor irq;
-};
-/**
* \brief Time struct for calendar
*/
struct calendar_time {
@@ -119,17 +61,6 @@ struct calendar_date {
uint16_t year;
};
-/** \brief Calendar driver struct
- *
- */
-struct calendar_descriptor {
- struct calendar_dev device;
- struct list_descriptor alarms;
- /*base date/time = base_year/1/1/0/0/0(year/month/day/hour/min/sec)*/
- uint32_t base_year;
- uint8_t flags;
-};
-
/** \brief Date&Time struct for calendar
*/
struct calendar_date_time {
@@ -137,188 +68,6 @@ struct calendar_date_time {
struct calendar_date date;
};
-/** \brief struct for alarm time
- */
-struct _calendar_alarm {
- struct calendar_date_time datetime;
- uint32_t timestamp;
- enum calendar_alarm_option option;
- enum calendar_alarm_mode mode;
-};
-
-/** \enum for tamper detection mode
- */
-enum tamper_detection_mode { TAMPER_MODE_OFF = 0U, TAMPER_MODE_WAKE, TAMPER_MODE_CAPTURE, TAMPER_MODE_ACTL };
-
-/** \enum for tamper detection mode
- */
-enum tamper_id { TAMPID0 = 0U, TAMPID1, TAMPID2, TAMPID3, TAMPID4 };
-/**
- * \brief Initialize Calendar instance
- *
- * \param[in] dev The pointer to calendar device struct
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _calendar_init(struct calendar_dev *const dev);
-
-/**
- * \brief Deinitialize Calendar instance
- *
- * \param[in] dev The pointer to calendar device struct
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _calendar_deinit(struct calendar_dev *const dev);
-
-/**
- * \brief Enable Calendar instance
- *
- * \param[in] dev The pointer to calendar device struct
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _calendar_enable(struct calendar_dev *const dev);
-
-/**
- * \brief Disable Calendar instance
- *
- * \param[in] dev The pointer to calendar device struct
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _calendar_disable(struct calendar_dev *const dev);
-/**
- * \brief Set counter for calendar
- *
- * \param[in] dev The pointer to calendar device struct
- * \param[in] counter The counter for set
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _calendar_set_counter(struct calendar_dev *const dev, const uint32_t counter);
-
-/**
- * \brief Get counter for calendar
- *
- * \param[in] dev The pointer to calendar device struct
- *
- * \return return current counter value
- */
-uint32_t _calendar_get_counter(struct calendar_dev *const dev);
-
-/**
- * \brief Set compare value for calendar
- *
- * \param[in] dev The pointer to calendar device struct
- * \param[in] comp The compare value for set
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _calendar_set_comp(struct calendar_dev *const dev, const uint32_t comp);
-
-/**
- * \brief Get compare value for calendar
- *
- * \param[in] dev The pointer to calendar device struct
- *
- * \return return current compare value
- */
-uint32_t _calendar_get_comp(struct calendar_dev *const dev);
-
-/**
- * \brief Register callback for calendar alarm
- *
- * \param[in] dev The pointer to calendar device struct
- * \param[in] callback The pointer to callback function
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _calendar_register_callback(struct calendar_dev *const dev, calendar_drv_cb_t callback);
-
-/**
- * \brief Set calendar IRQ
- *
- * \param[in] dev The pointer to calendar device struct
- */
-void _calendar_set_irq(struct calendar_dev *const dev);
-
-/**
- * \brief Register callback for 1Hz tick from prescaler
- *
- * \param[in] dev The pointer to calendar device struct
- * \param[in] callback The pointer to callback function
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _prescaler_register_callback(struct calendar_dev *const dev, calendar_drv_cb_t callback);
-
-/**
- * \brief Register callback for tamper detection
- *
- * \param[in] dev The pointer to calendar device struct
- * \param[in] callback The pointer to callback function
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _extwake_register_callback(struct calendar_dev *const dev, calendar_drv_extwake_cb_t callback);
-
-/**
- * \brief Find tamper is detected on specified pin
- *
- * \param[in] dev The pointer to calendar device struct
- * \param[in] enum Tamper ID number
- *
- * \return true on detection success and false on failure.
- */
-bool _is_tamper_detected(struct calendar_dev *const dev, enum tamper_id tamper_id_pin);
-
-/**
- * \brief brief Clear the Tamper ID flag
- *
- * \param[in] dev The pointer to calendar device struct
- * \param[in] enum Tamper ID number
- *
- * \return ERR_NONE
- */
-int32_t _tamper_clear_tampid_flag(struct calendar_dev *const dev, enum tamper_id tamper_id_pin);
-
-/**
- * \brief Enable Debounce Asynchronous Feature
- *
- * \param[in] dev The pointer to calendar device struct
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _tamper_enable_debounce_asynchronous(struct calendar_dev *const dev);
-
-/**
- * \brief Disable Tamper Debounce Asynchronous Feature
- *
- * \param[in] dev The pointer to calendar device struct
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _tamper_disable_debounce_asynchronous(struct calendar_dev *const dev);
-
-/**
- * \brief Enable Tamper Debounce Majority Feature
- *
- * \param[in] dev The pointer to calendar device struct
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _tamper_enable_debounce_majority(struct calendar_dev *const dev);
-
-/**
- * \brief Enable Tamper Debounce Majority Feature
- *
- * \param[in] dev The pointer to calendar device struct
- *
- * \return ERR_NONE on success, or an error code on failure.
- */
-int32_t _tamper_disable_debounce_majority(struct calendar_dev *const dev);
-
#ifdef __cplusplus
}
#endif
diff --git a/watch-library/hal/src/hal_calendar.c b/watch-library/hal/src/hal_calendar.c
index 68cb7286..e69de29b 100644
--- a/watch-library/hal/src/hal_calendar.c
+++ b/watch-library/hal/src/hal_calendar.c
@@ -1,645 +0,0 @@
-/**
- * \file
- *
- * \brief Generic CALENDAR functionality implementation.
- *
- * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Subject to your compliance with these terms, you may use Microchip
- * software and any derivatives exclusively with Microchip products.
- * It is your responsibility to comply with third party license terms applicable
- * to your use of third party software (including open source software) that
- * may accompany Microchip software.
- *
- * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
- * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
- * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
- * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
- * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
- * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
- * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
- * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
- * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
- * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
- *
- * \asf_license_stop
- *
- */
-
-#include "hal_calendar.h"
-#include <utils.h>
-#include <utils_assert.h>
-#include <hal_atomic.h>
-
-#define CALENDAR_VERSION 0x00000001u
-#define SECS_IN_LEAP_YEAR 31622400
-#define SECS_IN_NON_LEAP_YEAR 31536000
-#define SECS_IN_31DAYS 2678400
-#define SECS_IN_30DAYS 2592000
-#define SECS_IN_29DAYS 2505600
-#define SECS_IN_28DAYS 2419200
-#define SECS_IN_DAY 86400
-#define SECS_IN_HOUR 3600
-#define SECS_IN_MINUTE 60
-#define DEFAULT_BASE_YEAR 1970
-
-#define SET_ALARM_BUSY 1
-#define PROCESS_ALARM_BUSY 2
-
-/** \brief leap year check
- * \retval false not leap year.
- * \retval true leap year.
- */
-static bool leap_year(uint16_t year)
-{
- if (year & 3) {
- return false;
- } else {
- return true;
- }
-}
-
-/** \brief calculate the seconds in specified year/month
- * \retval 0 month error.
- */
-static uint32_t get_secs_in_month(uint32_t year, uint8_t month)
-{
- uint32_t sec_in_month = 0;
-
- if (leap_year(year)) {
- switch (month) {
- case 1:
- case 3:
- case 5:
- case 7:
- case 8:
- case 10:
- case 12:
- sec_in_month = SECS_IN_31DAYS;
- break;
- case 2:
- sec_in_month = SECS_IN_29DAYS;
- break;
- case 4:
- case 6:
- case 9:
- case 11:
- sec_in_month = SECS_IN_30DAYS;
- break;
- default:
- break;
- }
- } else {
- switch (month) {
- case 1:
- case 3:
- case 5:
- case 7:
- case 8:
- case 10:
- case 12:
- sec_in_month = SECS_IN_31DAYS;
- break;
- case 2:
- sec_in_month = SECS_IN_28DAYS;
- break;
- case 4:
- case 6:
- case 9:
- case 11:
- sec_in_month = SECS_IN_30DAYS;
- break;
- default:
- break;
- }
- }
-
- return sec_in_month;
-}
-
-/** \brief convert timestamp to date/time
- */
-static int32_t convert_timestamp_to_datetime(struct calendar_descriptor *const calendar, uint32_t ts,
- struct calendar_date_time *dt)
-{
- uint32_t tmp, sec_in_year, sec_in_month;
- uint32_t tmp_year = calendar->base_year;
- uint8_t tmp_month = 1;
- uint8_t tmp_day = 1;
- uint8_t tmp_hour = 0;
- uint8_t tmp_minutes = 0;
-
- tmp = ts;
-
- /* Find year */
- while (true) {
- sec_in_year = leap_year(tmp_year) ? SECS_IN_LEAP_YEAR : SECS_IN_NON_LEAP_YEAR;
-
- if (tmp >= sec_in_year) {
- tmp -= sec_in_year;
- tmp_year++;
- } else {
- break;
- }
- }
- /* Find month of year */
- while (true) {
- sec_in_month = get_secs_in_month(tmp_year, tmp_month);
-
- if (tmp >= sec_in_month) {
- tmp -= sec_in_month;
- tmp_month++;
- } else {
- break;
- }
- }
- /* Find day of month */
- while (true) {
- if (tmp >= SECS_IN_DAY) {
- tmp -= SECS_IN_DAY;
- tmp_day++;
- } else {
- break;
- }
- }
- /* Find hour of day */
- while (true) {
- if (tmp >= SECS_IN_HOUR) {
- tmp -= SECS_IN_HOUR;
- tmp_hour++;
- } else {
- break;
- }
- }
- /* Find minute in hour */
- while (true) {
- if (tmp >= SECS_IN_MINUTE) {
- tmp -= SECS_IN_MINUTE;
- tmp_minutes++;
- } else {
- break;
- }
- }
-
- dt->date.year = tmp_year;
- dt->date.month = tmp_month;
- dt->date.day = tmp_day;
- dt->time.hour = tmp_hour;
- dt->time.min = tmp_minutes;
- dt->time.sec = tmp;
-
- return ERR_NONE;
-}
-
-/** \brief convert date/time to timestamp
- * \return timestamp
- */
-static uint32_t convert_datetime_to_timestamp(struct calendar_descriptor *const calendar, struct calendar_date_time *dt)
-{
- uint32_t tmp = 0;
- uint32_t i = 0;
- uint8_t year, month, day, hour, minutes, seconds;
-
- year = dt->date.year - calendar->base_year;
- month = dt->date.month;
- day = dt->date.day;
- hour = dt->time.hour;
- minutes = dt->time.min;
- seconds = dt->time.sec;
-
- /* tot up year field */
- for (i = 0; i < year; ++i) {
- if (leap_year(calendar->base_year + i)) {
- tmp += SECS_IN_LEAP_YEAR;
- } else {
- tmp += SECS_IN_NON_LEAP_YEAR;
- }
- }
-
- /* tot up month field */
- for (i = 1; i < month; ++i) {
- tmp += get_secs_in_month(dt->date.year, i);
- }
-
- /* tot up day/hour/minute/second fields */
- tmp += (day - 1) * SECS_IN_DAY;
- tmp += hour * SECS_IN_HOUR;
- tmp += minutes * SECS_IN_MINUTE;
- tmp += seconds;
-
- return tmp;
-}
-
-/** \brief calibrate timestamp to make desired timestamp ahead of current timestamp
- */
-static void calibrate_timestamp(struct calendar_descriptor *const calendar, struct calendar_alarm *alarm,
- struct calendar_alarm *current_dt)
-{
- uint32_t alarm_ts;
- uint32_t current_ts = current_dt->cal_alarm.timestamp;
-
- (void)calendar;
-
- alarm_ts = alarm->cal_alarm.timestamp;
-
- /* calibrate timestamp */
- switch (alarm->cal_alarm.option) {
- case CALENDAR_ALARM_MATCH_SEC:
-
- if (alarm_ts <= current_ts) {
- alarm_ts += SECS_IN_MINUTE;
- }
-
- break;
- case CALENDAR_ALARM_MATCH_MIN:
-
- if (alarm_ts <= current_ts) {
- alarm_ts += SECS_IN_HOUR;
- }
-
- break;
- case CALENDAR_ALARM_MATCH_HOUR:
-
- if (alarm_ts <= current_ts) {
- alarm_ts += SECS_IN_DAY;
- }
-
- break;
- case CALENDAR_ALARM_MATCH_DAY:
-
- if (alarm_ts <= current_ts) {
- alarm_ts += get_secs_in_month(current_dt->cal_alarm.datetime.date.year,
- current_dt->cal_alarm.datetime.date.month);
- }
-
- break;
- case CALENDAR_ALARM_MATCH_MONTH:
-
- if (alarm_ts <= current_ts) {
- if (leap_year(current_dt->cal_alarm.datetime.date.year)) {
- alarm_ts += SECS_IN_LEAP_YEAR;
- } else {
- alarm_ts += SECS_IN_NON_LEAP_YEAR;
- }
- }
-
- break;
- /* do nothing for year match */
- case CALENDAR_ALARM_MATCH_YEAR:
- default:
- break;
- }
-
- /* desired timestamp after calibration */
- alarm->cal_alarm.timestamp = alarm_ts;
-}
-
-/** \brief complete alarm to absolute date/time, then fill up the timestamp
- */
-static void fill_alarm(struct calendar_descriptor *const calendar, struct calendar_alarm *alarm)
-{
- struct calendar_alarm current_dt;
- uint32_t tmp, current_ts;
-
- /* get current date/time */
- current_ts = _calendar_get_counter(&calendar->device);
- convert_timestamp_to_datetime(calendar, current_ts, &current_dt.cal_alarm.datetime);
-
- current_dt.cal_alarm.timestamp = current_ts;
-
- /* complete alarm */
- switch (alarm->cal_alarm.option) {
- case CALENDAR_ALARM_MATCH_SEC:
- alarm->cal_alarm.datetime.date.year = current_dt.cal_alarm.datetime.date.year;
- alarm->cal_alarm.datetime.date.month = current_dt.cal_alarm.datetime.date.month;
- alarm->cal_alarm.datetime.date.day = current_dt.cal_alarm.datetime.date.day;
- alarm->cal_alarm.datetime.time.hour = current_dt.cal_alarm.datetime.time.hour;
- alarm->cal_alarm.datetime.time.min = current_dt.cal_alarm.datetime.time.min;
- break;
- case CALENDAR_ALARM_MATCH_MIN:
- alarm->cal_alarm.datetime.date.year = current_dt.cal_alarm.datetime.date.year;
- alarm->cal_alarm.datetime.date.month = current_dt.cal_alarm.datetime.date.month;
- alarm->cal_alarm.datetime.date.day = current_dt.cal_alarm.datetime.date.day;
- alarm->cal_alarm.datetime.time.hour = current_dt.cal_alarm.datetime.time.hour;
- break;
- case CALENDAR_ALARM_MATCH_HOUR:
- alarm->cal_alarm.datetime.date.year = current_dt.cal_alarm.datetime.date.year;
- alarm->cal_alarm.datetime.date.month = current_dt.cal_alarm.datetime.date.month;
- alarm->cal_alarm.datetime.date.day = current_dt.cal_alarm.datetime.date.day;
- break;
- case CALENDAR_ALARM_MATCH_DAY:
- alarm->cal_alarm.datetime.date.year = current_dt.cal_alarm.datetime.date.year;
- alarm->cal_alarm.datetime.date.month = current_dt.cal_alarm.datetime.date.month;
- break;
- case CALENDAR_ALARM_MATCH_MONTH:
- alarm->cal_alarm.datetime.date.year = current_dt.cal_alarm.datetime.date.year;
- break;
- case CALENDAR_ALARM_MATCH_YEAR:
- break;
- default:
- break;
- }
-
- /* fill up the timestamp */
- tmp = convert_datetime_to_timestamp(calendar, &alarm->cal_alarm.datetime);
- alarm->cal_alarm.timestamp = tmp;
-
- /* calibrate the timestamp */
- calibrate_timestamp(calendar, alarm, &current_dt);
- convert_timestamp_to_datetime(calendar, alarm->cal_alarm.timestamp, &alarm->cal_alarm.datetime);
-}
-
-/** \brief add new alarm into the list in ascending order
- */
-static int32_t calendar_add_new_alarm(struct list_descriptor *list, struct calendar_alarm *alarm)
-{
- struct calendar_descriptor *calendar = CONTAINER_OF(list, struct calendar_descriptor, alarms);
- struct calendar_alarm * head, *it, *prev = NULL;
-
- /*get the head of alarms list*/
- head = (struct calendar_alarm *)list_get_head(list);
-
- /*if head is null, insert new alarm as head*/
- if (!head) {
- list_insert_as_head(list, alarm);
- _calendar_set_comp(&calendar->device, alarm->cal_alarm.timestamp);
- return ERR_NONE;
- }
-
- /*insert the new alarm in accending order, the head will be invoked firstly */
- for (it = head; it; it = (struct calendar_alarm *)list_get_next_element(it)) {
- if (alarm->cal_alarm.timestamp <= it->cal_alarm.timestamp) {
- break;
- }
-
- prev = it;
- }
-
- /*insert new alarm into the list */
- if (it == head) {
- list_insert_as_head(list, alarm);
- /*get the head and set it into register*/
- _calendar_set_comp(&calendar->device, alarm->cal_alarm.timestamp);
-
- } else {
- list_insert_after(prev, alarm);
- }
-
- return ERR_NONE;
-}
-
-/** \brief callback for alarm
- */
-static void calendar_alarm(struct calendar_dev *const dev)
-{
- struct calendar_descriptor *calendar = CONTAINER_OF(dev, struct calendar_descriptor, device);
-
- struct calendar_alarm *head, *it, current_dt;
-
- if ((calendar->flags & SET_ALARM_BUSY) || (calendar->flags & PROCESS_ALARM_BUSY)) {
- calendar->flags |= PROCESS_ALARM_BUSY;
- return;
- }
-
- /* get current timestamp */
- current_dt.cal_alarm.timestamp = _calendar_get_counter(dev);
-
- /* get the head */
- head = (struct calendar_alarm *)list_get_head(&calendar->alarms);
- ASSERT(head);
-
- /* remove all alarms and invoke them*/
- for (it = head; it; it = (struct calendar_alarm *)list_get_head(&calendar->alarms)) {
- /* check the timestamp with current timestamp*/
- if (it->cal_alarm.timestamp <= current_dt.cal_alarm.timestamp) {
- list_remove_head(&calendar->alarms);
- it->callback(calendar);
-
- if (it->cal_alarm.mode == REPEAT) {
- calibrate_timestamp(calendar, it, &current_dt);
- convert_timestamp_to_datetime(calendar, it->cal_alarm.timestamp, &it->cal_alarm.datetime);
- calendar_add_new_alarm(&calendar->alarms, it);
- }
- } else {
- break;
- }
- }
-
- /*if no alarm in the list, register null */
- if (!it) {
- _calendar_register_callback(&calendar->device, NULL);
- return;
- }
-
- /*put the new head into register */
- _calendar_set_comp(&calendar->device, it->cal_alarm.timestamp);
-}
-
-/** \brief Initialize Calendar
- */
-int32_t calendar_init(struct calendar_descriptor *const calendar, const void *hw)
-{
- int32_t ret = 0;
-
- /* Sanity check arguments */
- ASSERT(calendar);
-
- if (calendar->device.hw == hw) {
- /* Already initialized with current configuration */
- return ERR_NONE;
- } else if (calendar->device.hw != NULL) {
- /* Initialized with another configuration */
- return ERR_ALREADY_INITIALIZED;
- }
- calendar->device.hw = (void *)hw;
- ret = _calendar_init(&calendar->device);
- calendar->base_year = DEFAULT_BASE_YEAR;
-
- return ret;
-}
-
-/** \brief Reset the Calendar
- */
-int32_t calendar_deinit(struct calendar_descriptor *const calendar)
-{
- /* Sanity check arguments */
- ASSERT(calendar);
-
- if (calendar->device.hw == NULL) {
- return ERR_NOT_INITIALIZED;
- }
- _calendar_deinit(&calendar->device);
- calendar->device.hw = NULL;
-
- return ERR_NONE;
-}
-
-/** \brief Enable the Calendar
- */
-int32_t calendar_enable(struct calendar_descriptor *const calendar)
-{
- /* Sanity check arguments */
- ASSERT(calendar);
-
- _calendar_enable(&calendar->device);
-
- return ERR_NONE;
-}
-
-/** \brief Disable the Calendar
- */
-int32_t calendar_disable(struct calendar_descriptor *const calendar)
-{
- /* Sanity check arguments */
- ASSERT(calendar);
-
- _calendar_disable(&calendar->device);
-
- return ERR_NONE;
-}
-
-/** \brief Set base year for calendar
- */
-int32_t calendar_set_baseyear(struct calendar_descriptor *const calendar, const uint32_t p_base_year)
-{
- /* Sanity check arguments */
- ASSERT(calendar);
-
- calendar->base_year = p_base_year;
-
- return ERR_NONE;
-}
-
-/** \brief Set time for calendar
- */
-int32_t calendar_set_time(struct calendar_descriptor *const calendar, struct calendar_time *const p_calendar_time)
-{
- struct calendar_date_time dt;
- uint32_t current_ts, new_ts;
-
- /* Sanity check arguments */
- ASSERT(calendar);
-
- /* convert time to timestamp */
- current_ts = _calendar_get_counter(&calendar->device);
- convert_timestamp_to_datetime(calendar, current_ts, &dt);
- dt.time.sec = p_calendar_time->sec;
- dt.time.min = p_calendar_time->min;
- dt.time.hour = p_calendar_time->hour;
-
- new_ts = convert_datetime_to_timestamp(calendar, &dt);
-
- _calendar_set_counter(&calendar->device, new_ts);
-
- return ERR_NONE;
-}
-
-/** \brief Set date for calendar
- */
-int32_t calendar_set_date(struct calendar_descriptor *const calendar, struct calendar_date *const p_calendar_date)
-{
- struct calendar_date_time dt;
- uint32_t current_ts, new_ts;
-
- /* Sanity check arguments */
- ASSERT(calendar);
-
- /* convert date to timestamp */
- current_ts = _calendar_get_counter(&calendar->device);
- convert_timestamp_to_datetime(calendar, current_ts, &dt);
- dt.date.day = p_calendar_date->day;
- dt.date.month = p_calendar_date->month;
- dt.date.year = p_calendar_date->year;
-
- new_ts = convert_datetime_to_timestamp(calendar, &dt);
-
- _calendar_set_counter(&calendar->device, new_ts);
-
- return ERR_NONE;
-}
-
-/** \brief Get date/time for calendar
- */
-int32_t calendar_get_date_time(struct calendar_descriptor *const calendar, struct calendar_date_time *const date_time)
-{
- uint32_t current_ts;
-
- /* Sanity check arguments */
- ASSERT(calendar);
-
- /* convert current timestamp to date/time */
- current_ts = _calendar_get_counter(&calendar->device);
- convert_timestamp_to_datetime(calendar, current_ts, date_time);
-
- return ERR_NONE;
-}
-
-/** \brief Set alarm for calendar
- */
-int32_t calendar_set_alarm(struct calendar_descriptor *const calendar, struct calendar_alarm *const alarm,
- calendar_cb_alarm_t callback)
-{
- struct calendar_alarm *head;
-
- /* Sanity check arguments */
- ASSERT(calendar);
- ASSERT(alarm);
-
- alarm->callback = callback;
-
- fill_alarm(calendar, alarm);
-
- calendar->flags |= SET_ALARM_BUSY;
-
- head = (struct calendar_alarm *)list_get_head(&calendar->alarms);
-
- if (head != NULL) {
- /* already added */
- if (is_list_element(&calendar->alarms, alarm)) {
- if (callback == NULL) {
- /* remove alarm */
- list_delete_element(&calendar->alarms, alarm);
-
- if (!list_get_head(&calendar->alarms)) {
- _calendar_register_callback(&calendar->device, NULL);
- }
- } else {
- /* re-add */
- list_delete_element(&calendar->alarms, alarm);
- calendar_add_new_alarm(&calendar->alarms, alarm);
- }
- } else if (callback != NULL) {
- calendar_add_new_alarm(&calendar->alarms, alarm);
- }
-
- calendar->flags &= ~SET_ALARM_BUSY;
-
- if (calendar->flags & PROCESS_ALARM_BUSY) {
- CRITICAL_SECTION_ENTER()
- calendar->flags &= ~PROCESS_ALARM_BUSY;
- _calendar_set_irq(&calendar->device);
- CRITICAL_SECTION_LEAVE()
- }
- } else if (callback != NULL) {
- /* if head is NULL, Register callback*/
- _calendar_register_callback(&calendar->device, calendar_alarm);
- calendar_add_new_alarm(&calendar->alarms, alarm);
- }
-
- calendar->flags &= ~SET_ALARM_BUSY;
-
- return ERR_NONE;
-}
-
-/** \brief Retrieve driver version
- * \return Current driver version
- */
-uint32_t calendar_get_version(void)
-{
- return CALENDAR_VERSION;
-}
diff --git a/watch-library/hpl/rtc/hpl_rtc.c b/watch-library/hpl/rtc/hpl_rtc.c
deleted file mode 100644
index e580fa78..00000000
--- a/watch-library/hpl/rtc/hpl_rtc.c
+++ /dev/null
@@ -1,430 +0,0 @@
-
-/**
- * \file
- *
- * \brief RTC Driver
- *
- * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Subject to your compliance with these terms, you may use Microchip
- * software and any derivatives exclusively with Microchip products.
- * It is your responsibility to comply with third party license terms applicable
- * to your use of third party software (including open source software) that
- * may accompany Microchip software.
- *
- * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
- * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
- * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
- * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
- * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
- * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
- * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
- * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
- * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
- * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
- *
- * \asf_license_stop
- *
- */
-
-#include <hpl_calendar.h>
-#include <utils_assert.h>
-#include <hpl_rtc_config.h>
-
-/*!< Pointer to hpl device */
-static struct calendar_dev *_rtc_dev = NULL;
-
-/**
- * \brief Initializes the RTC module with given configurations.
- */
-int32_t _calendar_init(struct calendar_dev *const dev)
-{
- ASSERT(dev && dev->hw);
-
- _rtc_dev = dev;
-
- if (hri_rtcmode0_get_CTRLA_ENABLE_bit(dev->hw)) {
-#if !CONF_RTC_INIT_RESET
- return ERR_DENIED;
-#else
- hri_rtcmode0_clear_CTRLA_ENABLE_bit(dev->hw);
- hri_rtcmode0_wait_for_sync(dev->hw, RTC_MODE0_SYNCBUSY_ENABLE);
-#endif
- }
- hri_rtcmode0_set_CTRLA_SWRST_bit(dev->hw);
- hri_rtcmode0_wait_for_sync(dev->hw, RTC_MODE0_SYNCBUSY_SWRST);
-
-#if CONF_RTC_EVENT_CONTROL_ENABLE == 1
- hri_rtcmode0_write_EVCTRL_reg(
- dev->hw,
- (CONF_RTC_PEREO0 << RTC_MODE0_EVCTRL_PEREO0_Pos) | (CONF_RTC_PEREO1 << RTC_MODE0_EVCTRL_PEREO1_Pos)
- | (CONF_RTC_PEREO2 << RTC_MODE0_EVCTRL_PEREO2_Pos) | (CONF_RTC_PEREO3 << RTC_MODE0_EVCTRL_PEREO3_Pos)
- | (CONF_RTC_PEREO4 << RTC_MODE0_EVCTRL_PEREO4_Pos) | (CONF_RTC_PEREO5 << RTC_MODE0_EVCTRL_PEREO5_Pos)
- | (CONF_RTC_PEREO6 << RTC_MODE0_EVCTRL_PEREO6_Pos) | (CONF_RTC_PEREO7 << RTC_MODE0_EVCTRL_PEREO7_Pos)
- | (CONF_RTC_COMPE0 << RTC_MODE0_EVCTRL_CMPEO_Pos) | (CONF_RTC_OVFEO << RTC_MODE0_EVCTRL_OVFEO_Pos));
-#endif
-
- hri_rtcmode0_write_CTRLA_reg(dev->hw, RTC_MODE0_CTRLA_PRESCALER(CONF_RTC_PRESCALER) | RTC_MODE0_CTRLA_COUNTSYNC);
-
- hri_rtc_write_TAMPCTRL_reg(
- dev->hw,
- (CONF_RTC_TAMPER_INACT_0 << RTC_TAMPCTRL_IN0ACT_Pos) | (CONF_RTC_TAMPER_INACT_1 << RTC_TAMPCTRL_IN1ACT_Pos)
- | (CONF_RTC_TAMPER_INACT_2 << RTC_TAMPCTRL_IN2ACT_Pos)
- | (CONF_RTC_TAMPER_INACT_3 << RTC_TAMPCTRL_IN3ACT_Pos)
- | (CONF_RTC_TAMPER_INACT_4 << RTC_TAMPCTRL_IN4ACT_Pos) | (CONF_RTC_TAMP_LVL_0 << RTC_TAMPCTRL_TAMLVL0_Pos)
- | (CONF_RTC_TAMP_LVL_1 << RTC_TAMPCTRL_TAMLVL1_Pos) | (CONF_RTC_TAMP_LVL_2 << RTC_TAMPCTRL_TAMLVL2_Pos)
- | (CONF_RTC_TAMP_LVL_3 << RTC_TAMPCTRL_TAMLVL3_Pos) | (CONF_RTC_TAMP_LVL_4 << RTC_TAMPCTRL_TAMLVL4_Pos)
- | (CONF_RTC_TAMP_DEBNC_0 << RTC_TAMPCTRL_DEBNC0_Pos) | (CONF_RTC_TAMP_DEBNC_1 << RTC_TAMPCTRL_DEBNC1_Pos)
- | (CONF_RTC_TAMP_DEBNC_2 << RTC_TAMPCTRL_DEBNC2_Pos) | (CONF_RTC_TAMP_DEBNC_3 << RTC_TAMPCTRL_DEBNC3_Pos)
- | (CONF_RTC_TAMP_DEBNC_4 << RTC_TAMPCTRL_DEBNC4_Pos));
-
- if ((CONF_RTC_TAMPER_INACT_0 == TAMPER_MODE_ACTL) | (CONF_RTC_TAMPER_INACT_1 == TAMPER_MODE_ACTL)
- | (CONF_RTC_TAMPER_INACT_2 == TAMPER_MODE_ACTL) | (CONF_RTC_TAMPER_INACT_3 == TAMPER_MODE_ACTL)
- | (CONF_RTC_TAMPER_INACT_4 == TAMPER_MODE_ACTL)) {
- hri_rtcmode0_set_CTRLB_RTCOUT_bit(dev->hw);
- }
- return ERR_NONE;
-}
-
-/**
- * \brief Deinit the RTC module
- */
-int32_t _calendar_deinit(struct calendar_dev *const dev)
-{
- ASSERT(dev && dev->hw);
-
- NVIC_DisableIRQ(RTC_IRQn);
- dev->callback_alarm = NULL;
- dev->callback_tick = NULL;
- dev->callback_tamper = NULL;
-
- hri_rtcmode0_clear_CTRLA_ENABLE_bit(dev->hw);
- hri_rtcmode0_set_CTRLA_SWRST_bit(dev->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Enable the RTC module
- */
-int32_t _calendar_enable(struct calendar_dev *const dev)
-{
- ASSERT(dev && dev->hw);
-
- hri_rtcmode0_set_CTRLA_ENABLE_bit(dev->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Disable the RTC module
- */
-int32_t _calendar_disable(struct calendar_dev *const dev)
-{
- ASSERT(dev && dev->hw);
-
- hri_rtcmode0_clear_CTRLA_ENABLE_bit(dev->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Set the current calendar time to desired time.
- */
-int32_t _calendar_set_counter(struct calendar_dev *const dev, const uint32_t counter)
-{
- ASSERT(dev && dev->hw);
-
- hri_rtcmode0_write_COUNT_reg(dev->hw, counter);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Get current counter
- */
-uint32_t _calendar_get_counter(struct calendar_dev *const dev)
-{
- ASSERT(dev && dev->hw);
-
- return hri_rtcmode0_read_COUNT_reg(dev->hw);
-}
-
-/**
- * \brief Set the compare for the specified value.
- */
-int32_t _calendar_set_comp(struct calendar_dev *const dev, const uint32_t comp)
-{
- ASSERT(dev && dev->hw);
-
- hri_rtcmode0_write_COMP_reg(dev->hw, 0, comp);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Get the compare value
- */
-uint32_t _calendar_get_comp(struct calendar_dev *const dev)
-{
- ASSERT(dev && dev->hw);
-
- return hri_rtcmode0_read_COMP_reg(dev->hw, 0);
-}
-
-/**
- * \brief Find tamper is detected on specified pin
- */
-bool _is_tamper_detected(struct calendar_dev *const dev, enum tamper_id tamper_id_pin)
-{
- bool value;
-
- ASSERT(dev && dev->hw);
-
- value = ((hri_rtc_read_TAMPID_reg(dev->hw) >> tamper_id_pin) & 0x01);
- return value;
-}
-
-/**
- * \brief Clear the Tamper ID flag
- */
-int32_t _tamper_clear_tampid_flag(struct calendar_dev *const dev, enum tamper_id tamper_id_pin)
-{
- ASSERT(dev && dev->hw);
-
- hri_rtc_write_TAMPID_reg(dev->hw, (true << tamper_id_pin));
-
- return ERR_NONE;
-}
-
-/**
- * \brief Enable Tamper Debounce Asynchronous Feature
- */
-int32_t _tamper_enable_debounce_asynchronous(struct calendar_dev *const dev)
-{
- int32_t return_value;
-
- hri_rtcmode0_write_CTRLA_ENABLE_bit(dev->hw, false);
-
- while (hri_rtcmode0_read_SYNCBUSY_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- }
-
- if (hri_rtcmode0_read_CTRLA_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- return_value = ERR_FAILURE;
- } else {
- hri_rtcmode0_write_CTRLB_DEBASYNC_bit(dev->hw, true);
- return_value = ERR_NONE;
- while (hri_rtcmode0_read_SYNCBUSY_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- }
- hri_rtcmode0_write_CTRLA_ENABLE_bit(dev->hw, true);
- }
-
- return return_value;
-}
-
-/**
- * \brief Disable Tamper Debounce Asynchronous Feature
- */
-int32_t _tamper_disable_debounce_asynchronous(struct calendar_dev *const dev)
-{
- int32_t return_value;
-
- hri_rtcmode0_write_CTRLA_ENABLE_bit(dev->hw, false);
-
- while (hri_rtcmode0_read_SYNCBUSY_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- }
-
- if (hri_rtcmode0_read_CTRLA_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- return_value = ERR_FAILURE;
- } else {
- hri_rtcmode0_write_CTRLB_DEBASYNC_bit(dev->hw, false);
- return_value = ERR_NONE;
- while (hri_rtcmode0_read_SYNCBUSY_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- }
- hri_rtcmode0_write_CTRLA_ENABLE_bit(dev->hw, true);
- }
-
- return return_value;
-}
-
-/**
- * \brief Enable Tamper Debounce Majority Feature
- */
-int32_t _tamper_enable_debounce_majority(struct calendar_dev *const dev)
-{
- int32_t return_value;
-
- hri_rtcmode0_write_CTRLA_ENABLE_bit(dev->hw, false);
-
- while (hri_rtcmode0_read_SYNCBUSY_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- }
-
- if (hri_rtcmode0_read_CTRLA_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- return_value = ERR_FAILURE;
- } else {
- hri_rtcmode0_write_CTRLB_DEBMAJ_bit(dev->hw, true);
- return_value = ERR_NONE;
-
- while (hri_rtcmode0_read_SYNCBUSY_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- }
- hri_rtcmode0_write_CTRLA_ENABLE_bit(dev->hw, true);
- }
-
- return return_value;
-}
-
-/**
- * \brief Disable Tamper Debounce Majority Feature
- */
-int32_t _tamper_disable_debounce_majority(struct calendar_dev *const dev)
-{
- int32_t return_value;
-
- hri_rtcmode0_write_CTRLA_ENABLE_bit(dev->hw, false);
-
- while (hri_rtcmode0_read_SYNCBUSY_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- }
-
- if (hri_rtcmode0_read_CTRLA_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- return_value = ERR_FAILURE;
- } else {
- hri_rtcmode0_write_CTRLB_DEBMAJ_bit(dev->hw, false);
- return_value = ERR_NONE;
-
- while (hri_rtcmode0_read_SYNCBUSY_reg(dev->hw) & RTC_MODE2_CTRLA_ENABLE) {
- }
- hri_rtcmode0_write_CTRLA_ENABLE_bit(dev->hw, true);
- }
-
- return return_value;
-}
-
-int32_t _prescaler_register_callback(struct calendar_dev *const dev, calendar_drv_cb_t callback)
-{
- ASSERT(dev && dev->hw);
-
- /* Check callback */
- if (callback != NULL) {
- /* register the callback */
- dev->callback_tick = callback;
-
- /* enable RTC_IRQn */
- NVIC_ClearPendingIRQ(RTC_IRQn);
- NVIC_EnableIRQ(RTC_IRQn);
-
- /* enable periodic interrupt */
- hri_rtcmode0_set_INTEN_PER7_bit(dev->hw);
- } else {
- /* disable periodic interrupt */
- hri_rtcmode0_clear_INTEN_PER7_bit(dev->hw);
- }
-
- return ERR_NONE;
-}
-
-int32_t _extwake_register_callback(struct calendar_dev *const dev, calendar_drv_extwake_cb_t callback)
-{
- ASSERT(dev && dev->hw);
-
- /* Check callback */
- if (callback != NULL) {
- /* register the callback */
- dev->callback_tamper = callback;
-
- /* enable RTC_IRQn */
- NVIC_ClearPendingIRQ(RTC_IRQn);
- NVIC_EnableIRQ(RTC_IRQn);
-
- hri_rtcmode0_clear_interrupt_TAMPER_bit(dev->hw);
- /* enable tamper interrupt */
- hri_rtcmode0_set_INTEN_TAMPER_bit(dev->hw);
- } else {
- /* disable tamper interrupt */
- hri_rtcmode0_clear_INTEN_TAMPER_bit(dev->hw);
- }
-
- return ERR_NONE;
-}
-/**
- * \brief Registers callback for the specified callback type
- */
-int32_t _calendar_register_callback(struct calendar_dev *const dev, calendar_drv_cb_t callback)
-{
- ASSERT(dev && dev->hw);
-
- /* Check callback */
- if (callback != NULL) {
- /* register the callback */
- dev->callback_alarm = callback;
-
- /* enable RTC_IRQn */
- NVIC_ClearPendingIRQ(RTC_IRQn);
- NVIC_EnableIRQ(RTC_IRQn);
-
- /* enable cmp */
- hri_rtcmode0_set_INTEN_CMP0_bit(dev->hw);
- } else {
- /* disable cmp */
- hri_rtcmode0_clear_INTEN_CMP0_bit(dev->hw);
- }
-
- return ERR_NONE;
-}
-
-/**
- * \brief RTC interrupt handler
- *
- * \param[in] dev The pointer to calendar device struct
- */
-static void _rtc_interrupt_handler(struct calendar_dev *dev)
-{
- /* Read and mask interrupt flag register */
- uint16_t interrupt_status = hri_rtcmode0_read_INTFLAG_reg(dev->hw);
- uint16_t interrupt_enabled = hri_rtcmode0_read_INTEN_reg(dev->hw);
-
- if ((interrupt_status & interrupt_enabled) & RTC_MODE2_INTFLAG_ALARM0) {
- if (dev->callback_alarm != NULL) {
- dev->callback_alarm();
- }
-
- /* Clear interrupt flag */
- hri_rtcmode0_clear_interrupt_CMP0_bit(dev->hw);
- } else if ((interrupt_status & interrupt_enabled) & RTC_MODE2_INTFLAG_PER7) {
- if (dev->callback_tick != NULL) {
- dev->callback_tick();
- }
-
- /* Clear interrupt flag */
- hri_rtcmode0_clear_interrupt_PER7_bit(dev->hw);
- } else if ((interrupt_status & interrupt_enabled) & RTC_MODE2_INTFLAG_TAMPER) {
- uint8_t reason = hri_rtc_get_TAMPID_reg(dev->hw, 0x1F);
- if (dev->callback_tamper != NULL) {
- dev->callback_tamper(reason);
- }
- hri_rtc_write_TAMPID_reg(dev->hw, reason);
-
- /* Clear interrupt flag */
- hri_rtcmode0_clear_interrupt_TAMPER_bit(dev->hw);
- }
-}
-/**
- * \brief Set calendar IRQ
- */
-void _calendar_set_irq(struct calendar_dev *const dev)
-{
- (void)dev;
- NVIC_SetPendingIRQ(RTC_IRQn);
-}
-
-/**
- * \brief Rtc interrupt handler
- */
-void RTC_Handler(void)
-{
- _rtc_interrupt_handler(_rtc_dev);
-}
diff --git a/watch-library/hpl/rtc/hpl_rtc_base.h b/watch-library/hpl/rtc/hpl_rtc_base.h
deleted file mode 100644
index 06e3bd79..00000000
--- a/watch-library/hpl/rtc/hpl_rtc_base.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * \file
- *
- * \brief RTC
- *
- * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Subject to your compliance with these terms, you may use Microchip
- * software and any derivatives exclusively with Microchip products.
- * It is your responsibility to comply with third party license terms applicable
- * to your use of third party software (including open source software) that
- * may accompany Microchip software.
- *
- * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
- * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
- * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
- * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
- * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
- * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
- * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
- * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
- * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
- * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
- *
- * \asf_license_stop
- */
-
-#ifndef _HPL_RTC2_V200_H_INCLUDED
-#define _HPL_RTC2_V200_H_INCLUDED
-
-#include <hpl_timer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Retrieve timer helper functions
- *
- * \return A pointer to set of timer helper functions
- */
-struct _timer_hpl_interface *_rtc_get_timer(void);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _HPL_RTC2_V200_H_INCLUDED */
diff --git a/watch-library/hw/driver_init.c b/watch-library/hw/driver_init.c
index 2cfdced7..09723bec 100644
--- a/watch-library/hw/driver_init.c
+++ b/watch-library/hw/driver_init.c
@@ -13,19 +13,8 @@
struct slcd_sync_descriptor SEGMENT_LCD_0;
-struct calendar_descriptor CALENDAR_0;
-
struct i2c_m_sync_desc I2C_0;
-void CALENDAR_0_CLOCK_init(void) {
- hri_mclk_set_APBAMASK_RTC_bit(MCLK);
-}
-
-void CALENDAR_0_init(void) {
- CALENDAR_0_CLOCK_init();
- calendar_init(&CALENDAR_0, RTC);
-}
-
void I2C_0_PORT_init(void) {
gpio_set_pin_pull_mode(SDA,
diff --git a/watch-library/hw/driver_init.h b/watch-library/hw/driver_init.h
index 019a0b56..002f07aa 100644
--- a/watch-library/hw/driver_init.h
+++ b/watch-library/hw/driver_init.h
@@ -31,43 +31,22 @@ extern "C" {
#include <hal_io.h>
#include <hal_sleep.h>
#include <hal_ext_irq.h>
-#include <hal_calendar.h>
#include <hal_i2c_m_sync.h>
#include <hal_delay.h>
#include <hal_slcd_sync.h>
extern struct adc_sync_descriptor ADC_0;
-extern struct calendar_descriptor CALENDAR_0;
-
extern struct i2c_m_sync_desc I2C_0;
-extern struct pwm_descriptor PWM_0;
-
-extern struct pwm_descriptor PWM_1;
extern struct slcd_sync_descriptor SEGMENT_LCD_0;
-void ADC_0_PORT_init(void);
-void ADC_0_CLOCK_init(void);
-void ADC_0_init(void);
-
-void CALENDAR_0_CLOCK_init(void);
-void CALENDAR_0_init(void);
-
void I2C_0_CLOCK_init(void);
void I2C_0_init(void);
void I2C_0_PORT_init(void);
void delay_driver_init(void);
-void PWM_0_PORT_init(void);
-void PWM_0_CLOCK_init(void);
-void PWM_0_init(void);
-
-void PWM_1_PORT_init(void);
-void PWM_1_CLOCK_init(void);
-void PWM_1_init(void);
-
void EXTERNAL_IRQ_0_init(void);
void SEGMENT_LCD_0_init(void);
diff --git a/watch-library/watch/watch.c b/watch-library/watch/watch.c
index 6196b1f3..de7160c5 100644
--- a/watch-library/watch/watch.c
+++ b/watch-library/watch/watch.c
@@ -24,18 +24,6 @@
#include "watch.h"
-#include "watch_rtc.c"
-#include "watch_slcd.c"
-#include "watch_extint.c"
-#include "watch_led.c"
-#include "watch_buzzer.c"
-#include "watch_adc.c"
-#include "watch_gpio.c"
-#include "watch_i2c.c"
-#include "watch_uart.c"
-#include "watch_deepsleep.c"
-#include "watch_private.c"
-
bool battery_is_low = false;
// receives interrupts from MCLK, OSC32KCTRL, OSCCTRL, PAC, PM, SUPC and TAL, whatever that is.
diff --git a/watch-library/watch/watch_adc.c b/watch-library/watch/watch_adc.c
index 490a49b1..90980a88 100644
--- a/watch-library/watch/watch_adc.c
+++ b/watch-library/watch/watch_adc.c
@@ -22,6 +22,8 @@
* SOFTWARE.
*/
+#include "watch_adc.h"
+
void _watch_sync_adc() {
while (ADC->SYNCBUSY.reg);
}
diff --git a/watch-library/watch/watch_adc.h b/watch-library/watch/watch_adc.h
index b49f1301..c9b6ad2a 100644
--- a/watch-library/watch/watch_adc.h
+++ b/watch-library/watch/watch_adc.h
@@ -21,8 +21,12 @@
* 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
@@ -103,3 +107,4 @@ void watch_disable_analog_input(const uint8_t pin);
void watch_disable_adc();
/// @}
+#endif
diff --git a/watch-library/watch/watch_app.h b/watch-library/watch/watch_app.h
index fd7ea706..00a6a610 100644
--- a/watch-library/watch/watch_app.h
+++ b/watch-library/watch/watch_app.h
@@ -21,6 +21,8 @@
* 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
@@ -103,3 +105,4 @@ void app_prepare_for_sleep();
void app_wake_from_sleep();
/// @}
+#endif
diff --git a/watch-library/watch/watch_buzzer.c b/watch-library/watch/watch_buzzer.c
index 9cb37393..007a44ca 100644
--- a/watch-library/watch/watch_buzzer.c
+++ b/watch-library/watch/watch_buzzer.c
@@ -22,6 +22,8 @@
* SOFTWARE.
*/
+#include "watch_buzzer.h"
+
inline void watch_enable_buzzer() {
if (!hri_tcc_get_CTRLA_reg(TCC0, TCC_CTRLA_ENABLE)) {
_watch_enable_tcc();
diff --git a/watch-library/watch/watch_buzzer.h b/watch-library/watch/watch_buzzer.h
index 995e059a..e15657be 100644
--- a/watch-library/watch/watch_buzzer.h
+++ b/watch-library/watch/watch_buzzer.h
@@ -21,8 +21,12 @@
* 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.
*/
@@ -157,3 +161,4 @@ void watch_buzzer_play_note(BuzzerNote note, uint16_t duration_ms);
extern const uint16_t NotePeriods[108];
/// @}
+#endif
diff --git a/watch-library/watch/watch_deepsleep.c b/watch-library/watch/watch_deepsleep.c
index a69ba66c..b7da82ee 100644
--- a/watch-library/watch/watch_deepsleep.c
+++ b/watch-library/watch/watch_deepsleep.c
@@ -22,6 +22,8 @@
* 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.
@@ -29,24 +31,9 @@
#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
-static void extwake_callback(uint8_t reason);
-ext_irq_cb_t btn_alarm_callback;
-ext_irq_cb_t a2_callback;
-ext_irq_cb_t a4_callback;
-
- static void extwake_callback(uint8_t reason) {
- 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();
- }
-}
-
void watch_register_extwake_callback(uint8_t pin, ext_irq_cb_t callback, bool level) {
uint32_t pinmux;
- hri_rtc_tampctrl_reg_t config = hri_rtc_get_TAMPCTRL_reg(RTC, 0xFFFFFFFF);
+ hri_rtc_tampctrl_reg_t config = RTC->MODE2.TAMPCTRL.reg;
switch (pin) {
case A4:
@@ -84,16 +71,17 @@ void watch_register_extwake_callback(uint8_t pin, ext_irq_cb_t callback, bool le
gpio_set_pin_function(pin, pinmux);
// disable the RTC
- 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);
- }
+ RTC->MODE2.CTRLA.bit.ENABLE = 0;
+ while (RTC->MODE2.SYNCBUSY.bit.ENABLE);
+
// update the configuration
- hri_rtc_write_TAMPCTRL_reg(RTC, config);
+ RTC->MODE2.TAMPCTRL.reg = config;
// re-enable the RTC
- hri_rtcmode0_set_CTRLA_ENABLE_bit(RTC);
+ RTC->MODE2.CTRLA.bit.ENABLE = 1;
- _extwake_register_callback(&CALENDAR_0.device, extwake_callback);
+ NVIC_ClearPendingIRQ(RTC_IRQn);
+ NVIC_EnableIRQ(RTC_IRQn);
+ RTC->MODE2.INTENSET.reg = RTC_MODE2_INTENSET_TAMPER;
}
void watch_disable_extwake_interrupt(uint8_t pin) {
@@ -176,7 +164,7 @@ void watch_enter_shallow_sleep(char *message) {
_watch_disable_all_peripherals_except_slcd();
// disable tick interrupt
- watch_register_tick_callback(NULL);
+ watch_rtc_disable_all_periodic_callbacks();
// disable brownout detector interrupt, which could inadvertently wake us up.
SUPC->INTENCLR.bit.BOD33DET = 1;
@@ -202,7 +190,7 @@ void watch_enter_deep_sleep() {
// so let's do it!
watch_register_extwake_callback(BTN_ALARM, NULL, true);
- watch_register_tick_callback(NULL);
+ 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);
diff --git a/watch-library/watch/watch_deepsleep.h b/watch-library/watch/watch_deepsleep.h
index 1e118929..3dc428d0 100644
--- a/watch-library/watch/watch_deepsleep.h
+++ b/watch-library/watch/watch_deepsleep.h
@@ -21,8 +21,17 @@
* 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 Deep Sleep Control
* @brief This section covers functions related to preparing for and entering BACKUP mode, the
* deepest sleep mode available on the SAM L22
@@ -110,3 +119,4 @@ void watch_enter_shallow_sleep(char *message);
*/
void watch_enter_deep_sleep();
/// @}
+#endif
diff --git a/watch-library/watch/watch_extint.c b/watch-library/watch/watch_extint.c
index f2bad949..dcaa0d80 100644
--- a/watch-library/watch/watch_extint.c
+++ b/watch-library/watch/watch_extint.c
@@ -22,6 +22,8 @@
* SOFTWARE.
*/
+#include "watch_extint.h"
+
void watch_enable_external_interrupts() {
// 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));
diff --git a/watch-library/watch/watch_extint.h b/watch-library/watch/watch_extint.h
index 9c810534..758fe8bc 100644
--- a/watch-library/watch/watch_extint.h
+++ b/watch-library/watch/watch_extint.h
@@ -21,8 +21,11 @@
* 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
@@ -78,3 +81,4 @@ 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();
/// @}
+#endif
diff --git a/watch-library/watch/watch_gpio.c b/watch-library/watch/watch_gpio.c
index a9bc139d..b37d009f 100644
--- a/watch-library/watch/watch_gpio.c
+++ b/watch-library/watch/watch_gpio.c
@@ -22,6 +22,8 @@
* 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);
diff --git a/watch-library/watch/watch_gpio.h b/watch-library/watch/watch_gpio.h
index 640686e0..fc43642c 100644
--- a/watch-library/watch/watch_gpio.h
+++ b/watch-library/watch/watch_gpio.h
@@ -21,8 +21,12 @@
* 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.
*/
@@ -69,3 +73,4 @@ void watch_disable_digital_output(const uint8_t pin);
*/
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
index 385d9d08..d2cf474b 100644
--- a/watch-library/watch/watch_i2c.c
+++ b/watch-library/watch/watch_i2c.c
@@ -22,7 +22,9 @@
* SOFTWARE.
*/
- struct io_descriptor *I2C_0_io;
+#include "watch_i2c.h"
+
+struct io_descriptor *I2C_0_io;
void watch_enable_i2c() {
I2C_0_init();
diff --git a/watch-library/watch/watch_i2c.h b/watch-library/watch/watch_i2c.h
index 7ac05c13..65df49b4 100644
--- a/watch-library/watch/watch_i2c.h
+++ b/watch-library/watch/watch_i2c.h
@@ -21,8 +21,12 @@
* 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
@@ -99,3 +103,4 @@ uint32_t watch_i2c_read24(int16_t addr, uint8_t reg);
*/
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
index 7b189452..1348c977 100644
--- a/watch-library/watch/watch_led.c
+++ b/watch-library/watch/watch_led.c
@@ -22,6 +22,8 @@
* SOFTWARE.
*/
+#include "watch_led.h"
+
void watch_enable_leds() {
if (!hri_tcc_get_CTRLA_reg(TCC0, TCC_CTRLA_ENABLE)) {
_watch_enable_tcc();
diff --git a/watch-library/watch/watch_led.h b/watch-library/watch/watch_led.h
index 0927e716..2b9dead0 100644
--- a/watch-library/watch/watch_led.h
+++ b/watch-library/watch/watch_led.h
@@ -21,8 +21,12 @@
* 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-
@@ -86,3 +90,4 @@ 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
index bdf6b78a..270208dc 100644
--- a/watch-library/watch/watch_private.c
+++ b/watch-library/watch/watch_private.c
@@ -22,6 +22,7 @@
* SOFTWARE.
*/
+#include "watch_private.h"
#include "tusb.h"
void _watch_init() {
@@ -56,8 +57,7 @@ void _watch_init() {
SUPC->BOD33.bit.ENABLE = 1;
// External wake depends on RTC; calendar is a required module.
- CALENDAR_0_init();
- calendar_enable(&CALENDAR_0);
+ _watch_rtc_init();
// set up state
btn_alarm_callback = NULL;
diff --git a/watch-library/watch/watch_private.h b/watch-library/watch/watch_private.h
index abee085a..8045e438 100644
--- a/watch-library/watch/watch_private.h
+++ b/watch-library/watch/watch_private.h
@@ -21,10 +21,17 @@
* 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();
+/// Initializes the real-time clock peripheral.
+void _watch_rtc_init();
+
/// Called by buzzer and LED setup functions. You should not call this from your app.
void _watch_enable_tcc();
@@ -33,3 +40,4 @@ void _watch_disable_tcc();
/// Called by main.c if plugged in to USB. You should not call this from your app.
void _watch_enable_usb();
+#endif
diff --git a/watch-library/watch/watch_rtc.c b/watch-library/watch/watch_rtc.c
index 2d6d598f..a50da7c4 100644
--- a/watch-library/watch/watch_rtc.c
+++ b/watch-library/watch/watch_rtc.c
@@ -22,19 +22,174 @@
* SOFTWARE.
*/
- bool _watch_rtc_is_enabled() {
- return RTC->MODE0.CTRLA.bit.ENABLE;
+#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() {
+ return RTC->MODE2.CTRLA.bit.ENABLE;
+}
+
+void _sync_rtc() {
+ while (RTC->MODE2.SYNCBUSY.reg);
}
+void _watch_rtc_init() {
+ 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() {
+ 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() {
+ 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() {
+ 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() {
+ 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) {
- calendar_set_date(&CALENDAR_0, &date_time.date);
- calendar_set_time(&CALENDAR_0, &date_time.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) {
- calendar_get_date_time(&CALENDAR_0, 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) {
- _prescaler_register_callback(&CALENDAR_0.device, 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
index c685ac26..1776a712 100644
--- a/watch-library/watch/watch_rtc.h
+++ b/watch-library/watch/watch_rtc.h
@@ -21,8 +21,11 @@
* 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
@@ -35,24 +38,127 @@
* 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 sbould always return true.
+ * You may call this function, but outside of app_init, it should always return true.
*/
bool _watch_rtc_is_enabled();
+/** @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();
+
+/** @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 both shallow and deep 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();
+
+/** @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();
+
+/** @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();
+
/** @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 be populated with the correct date and time on return.
+ * @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.
+ * @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
index 7210713a..ba9d12b2 100644
--- a/watch-library/watch/watch_slcd.c
+++ b/watch-library/watch/watch_slcd.c
@@ -22,6 +22,8 @@
* SOFTWARE.
*/
+#include "watch_slcd.h"
+
//////////////////////////////////////////////////////////////////////////////////////////
// Segmented Display
diff --git a/watch-library/watch/watch_slcd.h b/watch-library/watch/watch_slcd.h
index efef99ac..4f5a617c 100644
--- a/watch-library/watch/watch_slcd.h
+++ b/watch-library/watch/watch_slcd.h
@@ -21,8 +21,12 @@
* 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.
@@ -100,3 +104,4 @@ void watch_clear_indicator(WatchIndicatorSegment indicator);
void watch_clear_all_indicators();
/// @}
+#endif
diff --git a/watch-library/watch/watch_uart.c b/watch-library/watch/watch_uart.c
index 3d97803d..d35533d0 100644
--- a/watch-library/watch/watch_uart.c
+++ b/watch-library/watch/watch_uart.c
@@ -50,6 +50,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "watch_uart.h"
#include "peripheral_clk_config.h"
void watch_enable_debug_uart(uint32_t baud) {
diff --git a/watch-library/watch/watch_uart.h b/watch-library/watch/watch_uart.h
index 3c4f7aef..3e98bd35 100644
--- a/watch-library/watch/watch_uart.h
+++ b/watch-library/watch/watch_uart.h
@@ -21,8 +21,12 @@
* 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.
@@ -51,3 +55,4 @@ void watch_debug_putc(char c);
__attribute__((deprecated("Use printf to log debug messages over USB.")))
void watch_debug_puts(char *s);
/// @}
+#endif