summaryrefslogtreecommitdiffstats
path: root/watch-library
diff options
context:
space:
mode:
authorJoey Castillo <jose.castillo@gmail.com>2021-08-03 18:00:07 -0400
committerJoey Castillo <jose.castillo@gmail.com>2021-08-03 18:09:58 -0400
commitfc31739eb6fdf230a26930e8d42de7a26558aeae (patch)
treedcd629420799cba11304d0d4184f15c5f12f3e6e /watch-library
parent8a06636833e007675c150532035588bc1bf7749a (diff)
downloadSensor-Watch-fc31739eb6fdf230a26930e8d42de7a26558aeae.tar.gz
Sensor-Watch-fc31739eb6fdf230a26930e8d42de7a26558aeae.tar.bz2
Sensor-Watch-fc31739eb6fdf230a26930e8d42de7a26558aeae.zip
WIP deep sleep mode
Diffstat (limited to 'watch-library')
-rw-r--r--watch-library/config/hpl_eic_config.h16
-rw-r--r--watch-library/config/hpl_rtc_config.h6
-rw-r--r--watch-library/hal/include/hpl_calendar.h27
-rw-r--r--watch-library/hpl/rtc/hpl_rtc.c54
-rw-r--r--watch-library/hw/atmel_start_pins.h2
-rw-r--r--watch-library/hw/driver_init.c2
-rwxr-xr-xwatch-library/main.c10
-rw-r--r--watch-library/watch/watch.c30
8 files changed, 99 insertions, 48 deletions
diff --git a/watch-library/config/hpl_eic_config.h b/watch-library/config/hpl_eic_config.h
index 3b268a10..5066be66 100644
--- a/watch-library/config/hpl_eic_config.h
+++ b/watch-library/config/hpl_eic_config.h
@@ -138,14 +138,14 @@
// <e> Interrupt 2 Settings
// <id> eic_arch_enable_irq_setting2
#ifndef CONF_EIC_ENABLE_IRQ_SETTING2
-#define CONF_EIC_ENABLE_IRQ_SETTING2 0
+#define CONF_EIC_ENABLE_IRQ_SETTING2 1
#endif
// <q> External Interrupt 2 Filter Enable
// <i> Indicates whether the external interrupt 2 filter is enabled or not
// <id> eic_arch_filten2
#ifndef CONF_EIC_FILTEN2
-#define CONF_EIC_FILTEN2 0
+#define CONF_EIC_FILTEN2 1
#endif
// <q> External Interrupt 2 Event Output Enable
@@ -165,7 +165,7 @@
// <i> This defines input sense trigger
// <id> eic_arch_sense2
#ifndef CONF_EIC_SENSE2
-#define CONF_EIC_SENSE2 EIC_NMICTRL_NMISENSE_NONE_Val
+#define CONF_EIC_SENSE2 EIC_NMICTRL_NMISENSE_RISE_Val
#endif
// <q> External Interrupt 2 Asynchronous Edge Detection Mode
@@ -264,7 +264,7 @@
// <e> Interrupt 5 Settings
// <id> eic_arch_enable_irq_setting5
#ifndef CONF_EIC_ENABLE_IRQ_SETTING5
-#define CONF_EIC_ENABLE_IRQ_SETTING5 1
+#define CONF_EIC_ENABLE_IRQ_SETTING5 0
#endif
// <q> External Interrupt 5 Filter Enable
@@ -291,7 +291,7 @@
// <i> This defines input sense trigger
// <id> eic_arch_sense5
#ifndef CONF_EIC_SENSE5
-#define CONF_EIC_SENSE5 EIC_NMICTRL_NMISENSE_RISE_Val
+#define CONF_EIC_SENSE5 EIC_NMICTRL_NMISENSE_NONE_Val
#endif
// <q> External Interrupt 5 Asynchronous Edge Detection Mode
@@ -313,7 +313,7 @@
// <i> Indicates whether the external interrupt 6 filter is enabled or not
// <id> eic_arch_filten6
#ifndef CONF_EIC_FILTEN6
-#define CONF_EIC_FILTEN6 0
+#define CONF_EIC_FILTEN6 1
#endif
// <q> External Interrupt 6 Event Output Enable
@@ -355,7 +355,7 @@
// <i> Indicates whether the external interrupt 7 filter is enabled or not
// <id> eic_arch_filten7
#ifndef CONF_EIC_FILTEN7
-#define CONF_EIC_FILTEN7 0
+#define CONF_EIC_FILTEN7 1
#endif
// <q> External Interrupt 7 Event Output Enable
@@ -723,7 +723,7 @@
// </e>
-#define CONFIG_EIC_EXTINT_MAP {5, PIN_PB05}, {6, PIN_PA22}, {7, PIN_PA23},
+#define CONFIG_EIC_EXTINT_MAP {2, PIN_PA02}, {6, PIN_PA22}, {7, PIN_PA23},
// <<< end of configuration section >>>
diff --git a/watch-library/config/hpl_rtc_config.h b/watch-library/config/hpl_rtc_config.h
index 9085ca37..582a1c23 100644
--- a/watch-library/config/hpl_rtc_config.h
+++ b/watch-library/config/hpl_rtc_config.h
@@ -114,14 +114,14 @@
// <e> RTC Tamper Input 2 settings
// <id> tamper_input_2_settings
#ifndef CONF_TAMPER_INPUT_2_SETTINGS
-#define CONF_TAMPER_INPUT_2_SETTINGS 0
+#define CONF_TAMPER_INPUT_2_SETTINGS 1
#endif
// <q> Tamper Level Settings
// <i> Indicates Tamper input 2 level
// <id> tamper_level_2
#ifndef CONF_RTC_TAMP_LVL_2
-#define CONF_RTC_TAMP_LVL_2 0
+#define CONF_RTC_TAMP_LVL_2 1
#endif
// <o> RTC Tamper Input Action
@@ -132,7 +132,7 @@
// <i> These bits define the RTC Tamper Input Action to be performed
// <id> rtc_tamper_input_action_2
#ifndef CONF_RTC_TAMPER_INACT_2
-#define CONF_RTC_TAMPER_INACT_2 0
+#define CONF_RTC_TAMPER_INACT_2 1
#endif
// <q> Debounce Enable for Tamper Input
diff --git a/watch-library/hal/include/hpl_calendar.h b/watch-library/hal/include/hpl_calendar.h
index 16601d3a..87b1a5a8 100644
--- a/watch-library/hal/include/hpl_calendar.h
+++ b/watch-library/hal/include/hpl_calendar.h
@@ -77,12 +77,7 @@ enum calendar_alarm_mode { ONESHOT = 1, REPEAT };
/**
* \brief Prototype of callback on alarm match
*/
-typedef void (*calendar_drv_cb_alarm_t)(struct calendar_dev *const dev);
-
-/**
- * \brief Prototype of callback on tamper detect
- */
-typedef void (*tamper_drv_cb_t)(struct calendar_dev *const dev);
+typedef void (*calendar_drv_cb_t)(struct calendar_dev *const dev);
/**
* \brief Structure of Calendar instance
@@ -91,9 +86,11 @@ struct calendar_dev {
/** Pointer to the hardware base */
void *hw;
/** Alarm match callback */
- calendar_drv_cb_alarm_t callback;
+ calendar_drv_cb_t callback_alarm;
/** Tamper callback */
- tamper_drv_cb_t callback_tamper;
+ calendar_drv_cb_t callback_tamper;
+ /** Tamper callback */
+ calendar_drv_cb_t callback_tick;
/** IRQ struct */
struct _irq_descriptor irq;
};
@@ -236,7 +233,7 @@ uint32_t _calendar_get_comp(struct calendar_dev *const dev);
*
* \return ERR_NONE on success, or an error code on failure.
*/
-int32_t _calendar_register_callback(struct calendar_dev *const dev, calendar_drv_cb_alarm_t callback);
+int32_t _calendar_register_callback(struct calendar_dev *const dev, calendar_drv_cb_t callback);
/**
* \brief Set calendar IRQ
@@ -246,6 +243,16 @@ int32_t _calendar_register_callback(struct calendar_dev *const dev, calendar_drv
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
@@ -253,7 +260,7 @@ void _calendar_set_irq(struct calendar_dev *const dev);
*
* \return ERR_NONE on success, or an error code on failure.
*/
-int32_t _tamper_register_callback(struct calendar_dev *const dev, tamper_drv_cb_t callback_tamper);
+int32_t _extwake_register_callback(struct calendar_dev *const dev, calendar_drv_cb_t callback);
/**
* \brief Find tamper is detected on specified pin
diff --git a/watch-library/hpl/rtc/hpl_rtc.c b/watch-library/hpl/rtc/hpl_rtc.c
index c28ddec6..0d119da1 100644
--- a/watch-library/hpl/rtc/hpl_rtc.c
+++ b/watch-library/hpl/rtc/hpl_rtc.c
@@ -99,7 +99,9 @@ int32_t _calendar_deinit(struct calendar_dev *const dev)
ASSERT(dev && dev->hw);
NVIC_DisableIRQ(RTC_IRQn);
- dev->callback = NULL;
+ 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);
@@ -302,27 +304,49 @@ int32_t _tamper_disable_debounce_majority(struct calendar_dev *const dev)
return return_value;
}
-int32_t _tamper_register_callback(struct calendar_dev *const dev, tamper_drv_cb_t callback_tamper)
+int32_t _prescaler_register_callback(struct calendar_dev *const dev, calendar_drv_cb_t callback)
{
ASSERT(dev && dev->hw);
/* Check callback */
- if (callback_tamper != NULL) {
+ if (callback != NULL) {
/* register the callback */
- dev->callback_tamper = callback_tamper;
+ dev->callback_tick = callback;
/* enable RTC_IRQn */
NVIC_ClearPendingIRQ(RTC_IRQn);
NVIC_EnableIRQ(RTC_IRQn);
- /* enable tamper interrupt */
+ /* enable periodic interrupt */
hri_rtcmode0_set_INTEN_PER7_bit(dev->hw);
} else {
- /* disable tamper interrupt */
+ /* disable periodic interrupt */
hri_rtcmode0_clear_INTEN_PER7_bit(dev->hw);
+ }
+
+ return ERR_NONE;
+}
+
+// TODO: refactor this so it doesn't take a callback (it will never get called anyway)
+int32_t _extwake_register_callback(struct calendar_dev *const dev, calendar_drv_cb_t callback)
+{
+ ASSERT(dev && dev->hw);
- /* disable RTC_IRQn */
- NVIC_DisableIRQ(RTC_IRQn);
+ /* 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;
@@ -330,14 +354,14 @@ int32_t _tamper_register_callback(struct calendar_dev *const dev, tamper_drv_cb_
/**
* \brief Registers callback for the specified callback type
*/
-int32_t _calendar_register_callback(struct calendar_dev *const dev, calendar_drv_cb_alarm_t callback)
+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 = callback;
+ dev->callback_alarm = callback;
/* enable RTC_IRQn */
NVIC_ClearPendingIRQ(RTC_IRQn);
@@ -348,9 +372,6 @@ int32_t _calendar_register_callback(struct calendar_dev *const dev, calendar_drv
} else {
/* disable cmp */
hri_rtcmode0_clear_INTEN_CMP0_bit(dev->hw);
-
- /* disable RTC_IRQn */
- NVIC_DisableIRQ(RTC_IRQn);
}
return ERR_NONE;
@@ -368,15 +389,18 @@ static void _rtc_interrupt_handler(struct calendar_dev *dev)
uint16_t interrupt_enabled = hri_rtcmode0_read_INTEN_reg(dev->hw);
if ((interrupt_status & interrupt_enabled) & RTC_MODE2_INTFLAG_ALARM0) {
- dev->callback(dev);
+ dev->callback_alarm(dev);
/* Clear interrupt flag */
hri_rtcmode0_clear_interrupt_CMP0_bit(dev->hw);
} else if ((interrupt_status & interrupt_enabled) & RTC_MODE2_INTFLAG_PER7) {
- dev->callback_tamper(dev);
+ dev->callback_tick(dev);
/* Clear interrupt flag */
hri_rtcmode0_clear_interrupt_PER7_bit(dev->hw);
+ } else if ((interrupt_status & interrupt_enabled) & RTC_MODE2_INTFLAG_TAMPER) {
+ /* Clear interrupt flag */
+ hri_rtcmode0_clear_interrupt_TAMPER_bit(dev->hw);
}
}
/**
diff --git a/watch-library/hw/atmel_start_pins.h b/watch-library/hw/atmel_start_pins.h
index 36fe6bf4..28dc9919 100644
--- a/watch-library/hw/atmel_start_pins.h
+++ b/watch-library/hw/atmel_start_pins.h
@@ -49,7 +49,7 @@
#define A2 GPIO(GPIO_PORTB, 2)
#define D0 GPIO(GPIO_PORTB, 3)
#define A0 GPIO(GPIO_PORTB, 4)
-#define BTN_ALARM GPIO(GPIO_PORTB, 5)
+#define BTN_ALARM GPIO(GPIO_PORTA, 2)
#define COM0 GPIO(GPIO_PORTB, 6)
#define COM1 GPIO(GPIO_PORTB, 7)
#define COM2 GPIO(GPIO_PORTB, 8)
diff --git a/watch-library/hw/driver_init.c b/watch-library/hw/driver_init.c
index 4f1f8eee..02907feb 100644
--- a/watch-library/hw/driver_init.c
+++ b/watch-library/hw/driver_init.c
@@ -50,7 +50,7 @@ void EXTERNAL_IRQ_0_init(void) {
// <GPIO_PULL_DOWN"> Pull-down
GPIO_PULL_DOWN);
- gpio_set_pin_function(BTN_ALARM, PINMUX_PB05A_EIC_EXTINT5);
+ gpio_set_pin_function(BTN_ALARM, PINMUX_PA02A_EIC_EXTINT2);
// Set pin direction to input
gpio_set_pin_direction(BTN_LIGHT, GPIO_DIRECTION_IN);
diff --git a/watch-library/main.c b/watch-library/main.c
index 67e47896..42d0b56a 100755
--- a/watch-library/main.c
+++ b/watch-library/main.c
@@ -43,7 +43,6 @@
//-----------------------------------------------------------------------------
HAL_GPIO_PIN(UART_TX, B, 0)
-HAL_GPIO_PIN(UART_RX, B, 2)
//-----------------------------------------------------------------------------
static void uart_init(uint32_t baud) {
@@ -51,8 +50,6 @@ static void uart_init(uint32_t baud) {
HAL_GPIO_UART_TX_out();
HAL_GPIO_UART_TX_pmuxen(HAL_GPIO_PMUX_C);
- HAL_GPIO_UART_RX_in();
- HAL_GPIO_UART_RX_pmuxen(HAL_GPIO_PMUX_C);
MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM3;
@@ -92,10 +89,15 @@ int main(void) {
// User code. Give the app a chance to initialize its data structures and state.
app_init();
- // At this point, if the RTC peripheral is enabled, we are waking from BACKUP.
+ // If the RTC is already enabled, we're either waking from BACKUP mode or a reset.
+ // Ideally we should check if the TAMPER or CMP0 (alarm) flags are set.
if (watch_rtc_is_enabled()) {
// User code. Give the application a chance to restore state from backup registers.
app_wake_from_deep_sleep();
+
+ // disable the tamper interrupt and clear the tamper bit
+ hri_rtcmode0_clear_INTEN_TAMPER_bit(RTC);
+ hri_rtcmode0_clear_interrupt_TAMPER_bit(RTC);
}
// Watch library code. Set initial parameters for the device and enable the RTC.
diff --git a/watch-library/watch/watch.c b/watch-library/watch/watch.c
index 82b7467c..922aeb0a 100644
--- a/watch-library/watch/watch.c
+++ b/watch-library/watch/watch.c
@@ -271,8 +271,7 @@ static void tick_callback(struct calendar_dev *const dev) {
void watch_enable_tick_callback(ext_irq_cb_t callback) {
tick_user_callback = callback;
- // TODO: rename this method to reflect that it now sets the PER7 interrupt.
- _tamper_register_callback(&CALENDAR_0.device, &tick_callback);
+ _prescaler_register_callback(&CALENDAR_0.device, &tick_callback);
}
static bool ADC_0_ENABLED = false;
@@ -359,8 +358,27 @@ uint32_t watch_get_backup_data(uint8_t reg) {
return 0;
}
-void watch_enter_deep_sleep(){
- // Not yet implemented.
- // TODO: enable tamper interrupt on ALARM pin.
- // sleep(5);
+static void extwake_callback(struct calendar_dev *const dev) {
+ // this will never get called since we are basically waking from reset
+}
+
+void watch_enter_deep_sleep() {
+ // enable and configure the external wake interrupt
+ _extwake_register_callback(&CALENDAR_0.device, &extwake_callback);
+ _tamper_enable_debounce_asynchronous(&CALENDAR_0.device);
+
+ // disable SLCD
+ slcd_sync_deinit(&SEGMENT_LCD_0);
+ hri_mclk_clear_APBCMASK_SLCD_bit(SLCD);
+
+ // TODO: disable other peripherals
+
+ // disable EIC interrupt on ALARM pin (if any) and enable RTC interrupt.
+ ext_irq_disable(BTN_ALARM);
+ gpio_set_pin_direction(BTN_ALARM, GPIO_DIRECTION_IN);
+ gpio_set_pin_pull_mode(BTN_ALARM, GPIO_PULL_DOWN);
+ gpio_set_pin_function(BTN_ALARM, PINMUX_PA02G_RTC_IN2);
+
+ // go into backup sleep mode
+ sleep(5);
}