more accurate names for deep sleep and shallow sleep modes
This commit is contained in:
		
							parent
							
								
									1020dd7898
								
							
						
					
					
						commit
						38a2dff234
					
				@ -16,8 +16,8 @@ void app_init() {
 | 
			
		||||
    memset(&application_state, 0, sizeof(application_state));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_wake_from_deep_sleep() {
 | 
			
		||||
    // This app does not support deep sleep mode.
 | 
			
		||||
void app_wake_from_backup() {
 | 
			
		||||
    // This app does not support BACKUP mode.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_setup() {
 | 
			
		||||
@ -63,13 +63,13 @@ void app_setup() {
 | 
			
		||||
/**
 | 
			
		||||
 * Nothing to do here.
 | 
			
		||||
 */
 | 
			
		||||
void app_prepare_for_sleep() {
 | 
			
		||||
void app_prepare_for_standby() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @todo restore the BME280's calibration values from backup memory
 | 
			
		||||
 */
 | 
			
		||||
void app_wake_from_sleep() {
 | 
			
		||||
void app_wake_from_standby() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ void app_init() {
 | 
			
		||||
    memset(&application_state, 0, sizeof(application_state));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_wake_from_deep_sleep() {
 | 
			
		||||
void app_wake_from_backup() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_setup() {
 | 
			
		||||
@ -28,11 +28,11 @@ void app_setup() {
 | 
			
		||||
    watch_enable_buzzer();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_prepare_for_sleep() {
 | 
			
		||||
void app_prepare_for_standby() {
 | 
			
		||||
    watch_display_string("  rains ", 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_wake_from_sleep() {
 | 
			
		||||
void app_wake_from_standby() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool app_loop() {
 | 
			
		||||
 | 
			
		||||
@ -51,14 +51,14 @@ void app_init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief the app_wake_from_deep_sleep function is only called if your app is waking from
 | 
			
		||||
 * @brief the app_wake_from_backup function is only called if your app is waking from
 | 
			
		||||
 * the ultra-low power BACKUP sleep mode. You may have chosen to store some state in the
 | 
			
		||||
 * RTC's backup registers prior to entering this mode. You may restore that state here.
 | 
			
		||||
 *
 | 
			
		||||
 * @see watch_enter_deep_sleep()
 | 
			
		||||
 */
 | 
			
		||||
void app_wake_from_deep_sleep() {
 | 
			
		||||
    // this app only supports shallow sleep mode.
 | 
			
		||||
void app_wake_from_backup() {
 | 
			
		||||
    // This app does not support BACKUP mode.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -69,9 +69,12 @@ void app_wake_from_deep_sleep() {
 | 
			
		||||
 * accelerometer that will run at all times should be configured here, whereas you may
 | 
			
		||||
 * want to enable a more power-hungry environmental sensor only when you need it.
 | 
			
		||||
 *
 | 
			
		||||
 * @note If your app enters the ultra-low power BACKUP sleep mode, this function will
 | 
			
		||||
 * be called again when it wakes from that deep sleep state. In this state, the RTC will
 | 
			
		||||
 * still be configured with the correct date and time.
 | 
			
		||||
 * @note If your app enters the Sleep or Deep Sleep modes, this function will be called
 | 
			
		||||
 * again on wake, since those modes will have disabled all pins and peripherals; you'll
 | 
			
		||||
 * likely need to set them up again. This function will also be called again if your app
 | 
			
		||||
 * entered the ultra-low power BACKUP mode, since BACKUP mode will have done all that and
 | 
			
		||||
 * also wiped out the system RAM. Note that when this is called after waking from sleep,
 | 
			
		||||
 * the RTC will still be configured with the correct date and time.
 | 
			
		||||
 */
 | 
			
		||||
void app_setup() {
 | 
			
		||||
    watch_enable_leds();
 | 
			
		||||
@ -94,25 +97,24 @@ void app_setup() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief the app_prepare_for_sleep function is called before the watch goes into the
 | 
			
		||||
 * STANDBY sleep mode. In STANDBY mode, most peripherals are shut down, and no code
 | 
			
		||||
 * will run until the watch receives an interrupt (generally either the 1Hz tick or
 | 
			
		||||
 * a press on one of the buttons).
 | 
			
		||||
 * @brief the app_prepare_for_standby function is called before the watch goes into STANDBY mode.
 | 
			
		||||
 * In STANDBY mode, most peripherals are shut down, and no code will run until the watch receives
 | 
			
		||||
 * an interrupt (generally either the 1Hz tick or a press on one of the buttons).
 | 
			
		||||
 */
 | 
			
		||||
void app_prepare_for_sleep() {
 | 
			
		||||
void app_prepare_for_standby() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief the app_wake_from_sleep function is called after the watch wakes from the
 | 
			
		||||
 * STANDBY sleep mode.
 | 
			
		||||
 * @brief the app_wake_from_standby function is called after the watch wakes from STANDBY mode,
 | 
			
		||||
 * but before your main app_loop.
 | 
			
		||||
 */
 | 
			
		||||
void app_wake_from_sleep() {
 | 
			
		||||
void app_wake_from_standby() {
 | 
			
		||||
    application_state.wake_count++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief the app_loop function is called once on app startup and then again each time
 | 
			
		||||
 * the watch STANDBY sleep mode.
 | 
			
		||||
 * @brief the app_loop function is called once on app startup and then again each time the
 | 
			
		||||
 * watch exits STANDBY mode.
 | 
			
		||||
 */
 | 
			
		||||
bool app_loop() {
 | 
			
		||||
    if (application_state.beep) {
 | 
			
		||||
@ -157,7 +159,7 @@ bool app_loop() {
 | 
			
		||||
        delay_ms(250);
 | 
			
		||||
 | 
			
		||||
        // nap time :)
 | 
			
		||||
        watch_enter_shallow_sleep(false);
 | 
			
		||||
        watch_enter_deep_sleep_mode();
 | 
			
		||||
 | 
			
		||||
        // we just woke up; wait a moment again for the user's finger to be off the button...
 | 
			
		||||
        delay_ms(250);
 | 
			
		||||
 | 
			
		||||
@ -50,8 +50,8 @@ void app_init() {
 | 
			
		||||
    memset(&application_state, 0, sizeof(application_state));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_wake_from_deep_sleep() {
 | 
			
		||||
    // This app does not support deep sleep mode.
 | 
			
		||||
void app_wake_from_backup() {
 | 
			
		||||
    // This app does not support BACKUP mode.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_setup() {
 | 
			
		||||
@ -67,10 +67,10 @@ void app_setup() {
 | 
			
		||||
    watch_rtc_register_tick_callback(cb_tick);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_prepare_for_sleep() {
 | 
			
		||||
void app_prepare_for_standby() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_wake_from_sleep() {
 | 
			
		||||
void app_wake_from_standby() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void update_tick_frequency() {
 | 
			
		||||
 | 
			
		||||
@ -56,8 +56,8 @@ void app_init() {
 | 
			
		||||
    _movement_reset_inactivity_countdown();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_wake_from_deep_sleep() {
 | 
			
		||||
    // This app does not support deep sleep mode.
 | 
			
		||||
void app_wake_from_backup() {
 | 
			
		||||
    // This app does not support BACKUP mode.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_setup() {
 | 
			
		||||
@ -94,10 +94,10 @@ void app_setup() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_prepare_for_sleep() {
 | 
			
		||||
void app_prepare_for_standby() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void app_wake_from_sleep() {
 | 
			
		||||
void app_wake_from_standby() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool app_loop() {
 | 
			
		||||
@ -147,11 +147,11 @@ bool app_loop() {
 | 
			
		||||
        while (movement_state.le_mode_ticks == -1) {
 | 
			
		||||
            event.event_type = EVENT_LOW_ENERGY_UPDATE;
 | 
			
		||||
            watch_faces[movement_state.current_watch_face].loop(event, &movement_state.settings, watch_face_contexts[movement_state.current_watch_face]);
 | 
			
		||||
            watch_enter_shallow_sleep(true);
 | 
			
		||||
            watch_enter_sleep_mode();
 | 
			
		||||
        }
 | 
			
		||||
        // as soon as le_mode_ticks is reset by the extwake handler, we bail out of the loop and reactivate ourselves.
 | 
			
		||||
        event.event_type = EVENT_ACTIVATE;
 | 
			
		||||
        // this is a hack tho: waking from shallow sleep, app_setup does get called, but it happens before we have reset our ticks.
 | 
			
		||||
        // this is a hack tho: waking from sleep mode, app_setup does get called, but it happens before we have reset our ticks.
 | 
			
		||||
        // need to figure out if there's a better heuristic for determining how we woke up.
 | 
			
		||||
        app_setup();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -57,7 +57,7 @@ int main(void) {
 | 
			
		||||
    // 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();
 | 
			
		||||
        app_wake_from_backup();
 | 
			
		||||
 | 
			
		||||
        // disable the tamper interrupt and clear the tamper bit
 | 
			
		||||
        hri_rtcmode0_clear_INTEN_TAMPER_bit(RTC);
 | 
			
		||||
@ -75,9 +75,9 @@ int main(void) {
 | 
			
		||||
        bool can_sleep = app_loop();
 | 
			
		||||
 | 
			
		||||
        if (can_sleep && !usb_enabled) {
 | 
			
		||||
            app_prepare_for_sleep();
 | 
			
		||||
            app_prepare_for_standby();
 | 
			
		||||
            sleep(4);
 | 
			
		||||
            app_wake_from_sleep();
 | 
			
		||||
            app_wake_from_standby();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,7 @@
 | 
			
		||||
  *
 | 
			
		||||
  *            1. Your app_init() function is called.
 | 
			
		||||
  *               - This method should only be used to set your initial application state.
 | 
			
		||||
  *            2. If your app is waking from BACKUP, app_wake_from_deep_sleep()  is called.
 | 
			
		||||
  *            2. If your app is waking from BACKUP, app_wake_from_backup() is called.
 | 
			
		||||
  *               - If you saved state in the RTC's backup registers, you can restore it here.
 | 
			
		||||
  *            3. Your app_setup() method is called.
 | 
			
		||||
  *               - You may wish to enable some functionality and peripherals here.
 | 
			
		||||
@ -43,11 +43,11 @@
 | 
			
		||||
  *               - Return true if your app is prepared to enter STANDBY mode.
 | 
			
		||||
  *            5. This step differs depending on the value returned by app_loop:
 | 
			
		||||
  *               - If you returned false, execution resumes at (4).
 | 
			
		||||
  *               - If you returned true, app_prepare_for_sleep() is called; execution moves on to (6).
 | 
			
		||||
  *            6. The microcontroller enters the STANDBY sleep mode.
 | 
			
		||||
  *               - If you returned true, app_prepare_for_standby() is called; execution moves on to (6).
 | 
			
		||||
  *            6. The microcontroller enters STANDBY mode.
 | 
			
		||||
  *               - No user code will run, and the watch will enter a low power mode.
 | 
			
		||||
  *               - The watch will remain in this state until an interrupt wakes it.
 | 
			
		||||
  *            7. Once woken from STANDBY, your app_wake_from_sleep() function is called.
 | 
			
		||||
  *            7. Once woken from STANDBY, your app_wake_from_standby() function is called.
 | 
			
		||||
  *               - After this, execution resumes at (4).
 | 
			
		||||
  */
 | 
			
		||||
/// @{
 | 
			
		||||
@ -57,11 +57,11 @@
 | 
			
		||||
  */
 | 
			
		||||
void app_init();
 | 
			
		||||
 | 
			
		||||
/** @brief A function you will implement to wake from deep sleep mode. The app_wake_from_deep_sleep function is only
 | 
			
		||||
  *        called if your app is waking from the ultra-low power BACKUP sleep mode. You may have chosen to store some
 | 
			
		||||
  *        state in the RTC's backup registers prior to entering this mode. You may restore that state here.
 | 
			
		||||
/** @brief A function you will implement to wake from BACKUP mode, which wipes the system's RAM, and with it, your
 | 
			
		||||
  *        application's state. You may have chosen to store some important application state in the RTC's backup
 | 
			
		||||
  *        registers prior to entering this mode. You may restore that state here.
 | 
			
		||||
  */
 | 
			
		||||
void app_wake_from_deep_sleep();
 | 
			
		||||
void app_wake_from_backup();
 | 
			
		||||
 | 
			
		||||
/** @brief A function you will implement to set up your application. The app_setup function is like setup() in Arduino.
 | 
			
		||||
  *        It is called once when the program begins. You should set pin modes and enable any peripherals you want to
 | 
			
		||||
@ -74,12 +74,12 @@ void app_wake_from_deep_sleep();
 | 
			
		||||
void app_setup();
 | 
			
		||||
 | 
			
		||||
/** @brief A function you will implement to serve as the app's main run loop. This method will be called repeatedly,
 | 
			
		||||
           or if you enter STANDBY sleep mode, as soon as the device wakes from sleep.
 | 
			
		||||
  * @return You should return true if your app is prepared to enter STANDBY sleep mode. If you return false, your
 | 
			
		||||
  *         app's app_loop method will be called again immediately. Note that in STANDBY mode, the watch will consume
 | 
			
		||||
  *         only about 95 microamperes of power, whereas if you return false and keep the app awake, it will consume
 | 
			
		||||
  *         about 355 microamperes. This is the difference between months of battery life and days. As much as
 | 
			
		||||
  *         possible, you should limit the amount of time your app spends awake.
 | 
			
		||||
           or if you enter STANDBY mode, as soon as the device wakes from sleep.
 | 
			
		||||
  * @return You should return true if your app is prepared to enter STANDBY mode. If you return false, your app's
 | 
			
		||||
  *         app_loop method will be called again immediately. Note that in STANDBY mode, the watch will consume only
 | 
			
		||||
  *         about 95 microamperes of power, whereas if you return false and keep the app awake, it will consume about
 | 
			
		||||
  *         355 microamperes. This is the difference between months of battery life and days. As much as possible,
 | 
			
		||||
  *         you should limit the amount of time your app spends awake.
 | 
			
		||||
  * @note Only the RTC, the segment LCD controller and the external interrupt controller run in STANDBY mode. If you
 | 
			
		||||
  *       are using, e.g. the PWM function to set a custom LED color, you should return false here until you are
 | 
			
		||||
  *       finished with that operation. Note however that the peripherals will continue running after waking up,
 | 
			
		||||
@ -88,21 +88,21 @@ void app_setup();
 | 
			
		||||
  */
 | 
			
		||||
bool app_loop();
 | 
			
		||||
 | 
			
		||||
/** @brief A function you will implement to prepare to enter STANDBY sleep mode. The app_prepare_for_sleep function is
 | 
			
		||||
 *         called before the watch goes into the STANDBY sleep mode. In STANDBY mode, most peripherals are shut down,
 | 
			
		||||
 *         and no code will run until the watch receives an interrupt (generally either the 1Hz tick or a press on one
 | 
			
		||||
 *         of the buttons).
 | 
			
		||||
/** @brief A function you will implement to prepare to enter STANDBY mode. The app_prepare_for_standby function is
 | 
			
		||||
 *         called after your app_loop function returns true, and just before the watch enters STANDBY mode. In this
 | 
			
		||||
 *         mode most peripherals are shut down, and no code will run until the watch receives an interrupt (generally
 | 
			
		||||
 *         either the 1Hz tick or a press on one of the buttons).
 | 
			
		||||
 * @note If you are PWM'ing the LED or playing a sound on the buzzer, the TC/TCC peripherals that drive those operations
 | 
			
		||||
 *       will not run in STANDBY. BUT! the output pins will retain the state they had when entering standby. This means
 | 
			
		||||
 *       you could end up entering standby with an LED on and draining power, or with a DC potential across the piezo
 | 
			
		||||
 *       buzzer that could damage it if left in this state. If your app_loop does not prevent sleep during these
 | 
			
		||||
 *       activities, you should make sure to disable these outputs in app_prepare_for_sleep.
 | 
			
		||||
 *       activities, you should make sure to disable these outputs in app_prepare_for_standby.
 | 
			
		||||
 */
 | 
			
		||||
void app_prepare_for_sleep();
 | 
			
		||||
void app_prepare_for_standby();
 | 
			
		||||
 | 
			
		||||
/** @brief A method you will implement to configure the app after waking from STANDBY sleep mode.
 | 
			
		||||
/** @brief A method you will implement to configure the app after waking from STANDBY mode.
 | 
			
		||||
  */
 | 
			
		||||
void app_wake_from_sleep();
 | 
			
		||||
void app_wake_from_standby();
 | 
			
		||||
 | 
			
		||||
/// @}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -151,12 +151,7 @@ void _watch_disable_all_peripherals_except_slcd() {
 | 
			
		||||
    MCLK->APBCMASK.reg &= ~MCLK_APBCMASK_SERCOM3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void watch_enter_shallow_sleep(bool display_on) {
 | 
			
		||||
    if (!display_on) {
 | 
			
		||||
        slcd_sync_deinit(&SEGMENT_LCD_0);
 | 
			
		||||
        hri_mclk_clear_APBCMASK_SLCD_bit(SLCD);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
void watch_enter_sleep_mode() {
 | 
			
		||||
    // disable all other peripherals
 | 
			
		||||
    _watch_disable_all_peripherals_except_slcd();
 | 
			
		||||
 | 
			
		||||
@ -178,15 +173,19 @@ void watch_enter_shallow_sleep(bool display_on) {
 | 
			
		||||
    // call app_setup so the app can re-enable everything we disabled.
 | 
			
		||||
    app_setup();
 | 
			
		||||
 | 
			
		||||
    // and call app_wake_from_sleep (since main won't have a chance to do it)
 | 
			
		||||
    app_wake_from_sleep();
 | 
			
		||||
    // and call app_wake_from_standby (since main won't have a chance to do it)
 | 
			
		||||
    app_wake_from_standby();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void watch_enter_deep_sleep() {
 | 
			
		||||
    // this will not work on the current silicon revision, but I said in the documentation that we do it.
 | 
			
		||||
    // so let's do it!
 | 
			
		||||
    watch_register_extwake_callback(BTN_ALARM, NULL, true);
 | 
			
		||||
void watch_enter_deep_sleep_mode() {
 | 
			
		||||
    // identical to sleep mode except we disable the LCD first.
 | 
			
		||||
    slcd_sync_deinit(&SEGMENT_LCD_0);
 | 
			
		||||
    hri_mclk_clear_APBCMASK_SLCD_bit(SLCD);
 | 
			
		||||
 | 
			
		||||
    watch_enter_sleep_mode();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void watch_enter_backup_mode() {
 | 
			
		||||
    watch_rtc_disable_all_periodic_callbacks();
 | 
			
		||||
    _watch_disable_all_peripherals_except_slcd();
 | 
			
		||||
    slcd_sync_deinit(&SEGMENT_LCD_0);
 | 
			
		||||
@ -196,3 +195,15 @@ void watch_enter_deep_sleep() {
 | 
			
		||||
    // go into backup sleep mode (5). when we exit, the reset controller will take over.
 | 
			
		||||
    sleep(5);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// deprecated
 | 
			
		||||
void watch_enter_shallow_sleep(bool display_on) {
 | 
			
		||||
    if (display_on) watch_enter_sleep_mode();
 | 
			
		||||
    else watch_enter_deep_sleep_mode();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// deprecated
 | 
			
		||||
void watch_enter_deep_sleep() {
 | 
			
		||||
    watch_register_extwake_callback(BTN_ALARM, NULL, true);
 | 
			
		||||
    watch_enter_backup_mode();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -32,26 +32,54 @@ 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
 | 
			
		||||
/** @addtogroup deepsleep Sleep Control
 | 
			
		||||
  * @brief This section covers functions related to the various sleep modes available to the watch,
 | 
			
		||||
  *        including Sleep, Deep Sleep, and BACKUP mode.
 | 
			
		||||
  * @details These terms changed meaning a bit over the course of development; if you are coming
 | 
			
		||||
  *          to this documentation after having worked with an earlier version of the library,
 | 
			
		||||
  *          these definitions should clarify the terminology. Terms in all caps are modes of the
 | 
			
		||||
  *          SAM L22; terms in Title Case are specific implementations in this library.
 | 
			
		||||
  *           - ACTIVE mode is the mode the SAM L22 is in when both the main clock and the CPU are
 | 
			
		||||
  *             running. It is the most power-hungry mode. If you ever call delay_ms to wait a beat,
 | 
			
		||||
  *             the watch will remain in ACTIVE mode while taking that delay. In addition, whenever
 | 
			
		||||
  *             your `app_loop` function returns false, the device will remain in ACTIVE mode and
 | 
			
		||||
  *             call your `app_loop` function again.
 | 
			
		||||
  *           - STANDBY mode turns off the main clock and halts the CPU. Since the PWM driver is
 | 
			
		||||
  *             run from the main clock, it also stops the buzzer and any dimming of the LEDs.
 | 
			
		||||
  *             In this mode, the watch can wake from any interrupt source. Whenever your `app_loop`
 | 
			
		||||
  *             function returns true, the watch enters STANDBY mode until the next tick or other
 | 
			
		||||
  *             interrupt. This mode uses much less power than ACTIVE mode.
 | 
			
		||||
  *           - Sleep Mode is a special case of STANDBY mode. In this mode, the watch turns off
 | 
			
		||||
  *             almost all peripherals (including the external interrupt controller), and disables
 | 
			
		||||
  *             all pins except for the external wake pins. In this mode the watch can only wake
 | 
			
		||||
  *             from the RTC alarm interrupt or an external wake pin (A2, A4 or the alarm button),
 | 
			
		||||
  *             but the display remains on and your app's state is retained. You can enter this
 | 
			
		||||
  *             mode by calling `watch_enter_sleep_mode`. It consumes an order of magnitude less
 | 
			
		||||
  *             power than STANDBY mode.
 | 
			
		||||
  *           - Deep Sleep Mode is identical to sleep mode, but it also turns off the LCD to save
 | 
			
		||||
  *             a bit more power. You can enter this mode by calling `watch_enter_deep_sleep_mode`.
 | 
			
		||||
  *           - BACKUP mode is the lowest possible power mode on the SAM L22. It turns off all pins
 | 
			
		||||
  *             and peripherals except for the RTC. It also turns off the RAM, obliterating your
 | 
			
		||||
  *             application's state. The only way to wake from this mode is by setting an external
 | 
			
		||||
  *             wake interrupt on pin A2 or pin A4, and when you do wake it will be much like a
 | 
			
		||||
  *             wake from reset. You can enter this mode by calling `watch_enter_backup_mode`.
 | 
			
		||||
  */
 | 
			
		||||
/// @{
 | 
			
		||||
 | 
			
		||||
/** @brief Registers a callback on one of the RTC's external wake pins, which can wake the device
 | 
			
		||||
  *        from deep sleep (aka BACKUP) mode.
 | 
			
		||||
  *        from Sleep, Deep Sleep and BACKUP modes (but see warning re: BACKUP mode).
 | 
			
		||||
  * @param pin Either pin BTN_ALARM, A2, or A4. These are the three external wake pins. If the pin
 | 
			
		||||
  *            is BTN_ALARM, this function also enables an internal pull down on that pin.
 | 
			
		||||
  * @param callback The callback to be called if this pin triggers outside of deep sleep mode. If
 | 
			
		||||
  *                 this is NULL, no callback will be called even in normal mode, but the interrupt
 | 
			
		||||
  *                 will still be enabled so that it can wake from deep sleep or backup mode.
 | 
			
		||||
  * @param callback The callback to be called if this pin triggers outside of BACKUP mode. If this is
 | 
			
		||||
  *                 NULL, no callback will be called even in normal modes, but the interrupt will
 | 
			
		||||
  *                 still be enabled so that it can wake the device.
 | 
			
		||||
  * @param level The level you wish to scan for: true for rising, false for falling. Note that you
 | 
			
		||||
  *              cannot scan for both rising and falling edges like you can with the external interrupt
 | 
			
		||||
  *              pins; with the external wake interrupt, you can only get one or the other.
 | 
			
		||||
  * @note When in normal or STANDBY mode, this will function much like a standard external interrupt
 | 
			
		||||
  *       situation: these pins will wake from standby, and your callback will be called. However,
 | 
			
		||||
  *       if the device enters deep sleep and one of these pins wakes the device, your callback
 | 
			
		||||
  *       WILL NOT be called, as the device is basically waking from reset at that point.
 | 
			
		||||
  * @note When in ACTIVE, STANDBY and Sleep / Deep sleep modes, this will function much like a standard
 | 
			
		||||
  *       external interrupt situation: these pins will wake the device, and your callback will be
 | 
			
		||||
  *       called. However, if the device enters BACKUP mode and one of these pins wakes the device, your
 | 
			
		||||
  *       callback WILL NOT be called, as the device is basically waking from reset at that point.
 | 
			
		||||
  * @warning As of the current SAM L22 silicon revision (rev B), the BTN_ALARM pin cannot wake the
 | 
			
		||||
  *          device from BACKUP mode. You can still use this function to register a BTN_ALARM interrupt
 | 
			
		||||
  *          in normal or deep sleep mode, but to wake from BACKUP, you will need to use pin A2 or A4.
 | 
			
		||||
@ -59,59 +87,73 @@ extern ext_irq_cb_t a4_callback;
 | 
			
		||||
void watch_register_extwake_callback(uint8_t pin, ext_irq_cb_t callback, bool level);
 | 
			
		||||
 | 
			
		||||
/** @brief Unregisters the RTC interrupt on one of the EXTWAKE pins. This will prevent a value change on
 | 
			
		||||
  *        one of these pins from waking the device from shallow and deep sleep modes.
 | 
			
		||||
  *        one of these pins from waking the device.
 | 
			
		||||
  * @param pin Either pin BTN_ALARM, A2, or A4. If the pin is BTN_ALARM, this function DOES NOT disable
 | 
			
		||||
  *            the internal pull down on that pin.
 | 
			
		||||
  */
 | 
			
		||||
void watch_disable_extwake_interrupt(uint8_t pin);
 | 
			
		||||
 | 
			
		||||
/** @brief Stores data in one of the RTC's backup registers, which retain their data in deep sleep mode.
 | 
			
		||||
/** @brief Stores data in one of the RTC's backup registers, which retain their data in BACKUP mode.
 | 
			
		||||
  * @param data An unsigned 32 bit integer with the data you wish to store.
 | 
			
		||||
  * @param reg A register from 0-7.
 | 
			
		||||
  */
 | 
			
		||||
void watch_store_backup_data(uint32_t data, uint8_t reg);
 | 
			
		||||
 | 
			
		||||
/** @brief Gets 32 bits of data from the RTC's backup register.
 | 
			
		||||
/** @brief Gets 32 bits of data from the RTC's BACKUP register.
 | 
			
		||||
  * @param reg A register from 0-7.
 | 
			
		||||
  * @return An unsigned 32 bit integer with the from the backup register.
 | 
			
		||||
  */
 | 
			
		||||
uint32_t watch_get_backup_data(uint8_t reg);
 | 
			
		||||
 | 
			
		||||
/** @brief Enters a shallow sleep mode by disabling all pins and peripherals except the RTC and (optionally)
 | 
			
		||||
  *        the LCD. You can wake from this mode by pressing the ALARM button, if you have an registered an
 | 
			
		||||
  *        external wake callback on the ALARM button. When your app wakes from this shallow sleep mode, your
 | 
			
		||||
  *        app_setup method will be called, since this function will have disabled things you set up.
 | 
			
		||||
  * @param display_on if true, leaves the LCD on to display whatever content was on-screen. If false, disables
 | 
			
		||||
  *                   the segment LCD controller for additional power savings.
 | 
			
		||||
  * @details This shallow sleep mode is not the lowest power mode available (see watch_enter_deep_sleep), but
 | 
			
		||||
  *          it has the benefit of retaining your application state and being able to wake from the ALARM button.
 | 
			
		||||
  *          It also provides an option for displaying a message to the user when asleep. Note that whether you
 | 
			
		||||
  *          want to wake from the ALARM button, the A2 RTC interrupt or the A4 interrupt, you must configure
 | 
			
		||||
  *          this by calling watch_register_extwake_callback first.
 | 
			
		||||
/** @brief enters Sleep Mode by disabling all pins and peripherals except the RTC and the LCD.
 | 
			
		||||
  * @details This sleep mode is not the lowest power mode available, but it has the benefit of allowing you
 | 
			
		||||
  *          to display a message to the user while asleep. You can also set an alarm interrupt to wake at a
 | 
			
		||||
  *          configfurable interval (every minute, hour or day) to update the display. You can wake from this
 | 
			
		||||
  *          mode by pressing the ALARM button, if you registered an extwake callback on the ALARM button.
 | 
			
		||||
  *          Also note that when your app wakes from this sleep mode, your app_setup method will be called
 | 
			
		||||
  *          again, since this function will have disabled things you set up there.
 | 
			
		||||
  *
 | 
			
		||||
  *          Power consumption in shallow sleep mode varies a bit with the battery voltage and the temperature,
 | 
			
		||||
  *          but at 3 V and 25~30° C you can roughly estimate:
 | 
			
		||||
  *           * < 12µA current draw with the LCD controller on
 | 
			
		||||
  *           * < 6µA current draw with the LCD controller off
 | 
			
		||||
  *          Note that to wake from either the ALARM button, the A2 interrupt or the A4 interrupt, you
 | 
			
		||||
  *          must first configure this by calling watch_register_extwake_callback.
 | 
			
		||||
  *
 | 
			
		||||
  *          You can estimate the power consumption of this mode to be on the order of 30 microwatts
 | 
			
		||||
  *          (about 10 µA at 3 V).
 | 
			
		||||
  */
 | 
			
		||||
void watch_enter_shallow_sleep(bool display_on);
 | 
			
		||||
void watch_enter_sleep_mode();
 | 
			
		||||
 | 
			
		||||
/** @brief enters Deep Sleep Mode by disabling all pins and peripherals except the RTC.
 | 
			
		||||
  * @details Short of BACKUP mode, this is the lowest power mode you can enter while retaining your
 | 
			
		||||
  *          application state (and the ability to wake with the alarm button). Just note that the display
 | 
			
		||||
  *          will be completely off, so you should document to the user of your application that they will
 | 
			
		||||
  *          need to press the alarm button to wake the device, or use a sensor board with support for
 | 
			
		||||
  *          an external wake pin.
 | 
			
		||||
  *
 | 
			
		||||
  *          All notes from watch_enter_sleep_mode apply here, except for power consumption. You can estimate
 | 
			
		||||
  *          the power consumption of this mode to be on the order of 12 microwatts (about 4µA at 3 V).
 | 
			
		||||
  */
 | 
			
		||||
void watch_enter_deep_sleep_mode();
 | 
			
		||||
 | 
			
		||||
/** @brief Enters the SAM L22's lowest-power mode, BACKUP.
 | 
			
		||||
  * @details This function does some housekeeping before entering BACKUP mode. It first disables all
 | 
			
		||||
  *          peripherals except for the RTC, and disables the tick interrupt (since that would wake
 | 
			
		||||
  *          us up from deep sleep). It also sets an external wake source on the ALARM button, if one
 | 
			
		||||
  *          was not already set. If you wish to wake from another source, such as one of the external
 | 
			
		||||
  *          wake interrupt pins on the 9-pin connector, set that up prior to calling this function.
 | 
			
		||||
  * @details This function does some housekeeping before entering BACKUP mode. It first disables all pins
 | 
			
		||||
  *          and peripherals except for the RTC, and disables the tick interrupt (since that would wake
 | 
			
		||||
  *          us up from BACKUP mode). Once again, if you wish to wake from the A2 or the A4 interrupt,
 | 
			
		||||
  *          you must first configure this by calling watch_register_extwake_callback.
 | 
			
		||||
  * @note If you have a callback set for an external wake interrupt, it will be called if triggered while
 | 
			
		||||
  *       in ACTIVE, IDLE or STANDBY modes, but it *will not be called* when waking from BACKUP.
 | 
			
		||||
  *       Waking from backup is effectively like waking from reset, except that your @ref
 | 
			
		||||
  *       app_wake_from_deep_sleep function will be called.
 | 
			
		||||
  *       in ACTIVE, STANDBY, Sleep and Deep Sleep modes, but it *will not be called* when waking from
 | 
			
		||||
  *       BACKUP mode. Waking from backup is effectively like waking from reset, except that your
 | 
			
		||||
  *       @ref app_wake_from_backup function will be called.
 | 
			
		||||
  * @warning On current revisions of the SAM L22 silicon, the ALARM_BTN pin (PA02 RTC/IN2) cannot wake
 | 
			
		||||
  *          the device from deep sleep mode. There is an errata note (Reference: 15010) that says that
 | 
			
		||||
  *          due to a silicon bug, RTC/IN2 is not functional in BACKUP. As a result, you should not call
 | 
			
		||||
  *          this function unless you have a device on the nine-pin connector with an external interrupt
 | 
			
		||||
  *          on pin A2 or A4 (i.e. an accelerometer with an interrupt pin).
 | 
			
		||||
  */
 | 
			
		||||
void watch_enter_backup_mode();
 | 
			
		||||
 | 
			
		||||
__attribute__((deprecated("Use watch_enter_sleep_mode or watch_enter_deep_sleep_mode instead")))
 | 
			
		||||
void watch_enter_shallow_sleep(bool display_on);
 | 
			
		||||
 | 
			
		||||
__attribute__((deprecated("Use watch_enter_backup_mode instead")))
 | 
			
		||||
void watch_enter_deep_sleep();
 | 
			
		||||
/// @}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -88,8 +88,8 @@ watch_date_time watch_rtc_get_date_time();
 | 
			
		||||
  * @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.
 | 
			
		||||
  *          wake the device from all sleep modes. The key to its versatility is the mask parameter.
 | 
			
		||||
  *          Suppose we set an alarm for midnight, 00:00:00.
 | 
			
		||||
  *           * if mask is ALARM_MATCH_SS, the alarm will fire every minute when the clock ticks to seconds == 0.
 | 
			
		||||
  *           * with ALARM_MATCH_MMSS, the alarm will once an hour, at the top of each hour.
 | 
			
		||||
  *           * with ALARM_MATCH_HHMMSS, the alarm will fire at midnight every day.
 | 
			
		||||
 | 
			
		||||
@ -110,7 +110,7 @@ void watch_clear_all_indicators();
 | 
			
		||||
/** @brief Blinks a single character in position 7. Does not affect other positions.
 | 
			
		||||
  * @details Six of the seven segments in position 7 (and only position 7) are capable of autonomous
 | 
			
		||||
  *          blinking. This blinking does not require any CPU resources, and will continue even in
 | 
			
		||||
  *          standby and shallow sleep mode (if the LCD remains on).
 | 
			
		||||
  *          STANDBY and Sleep mode (but not Deep Sleep mode, since that mode turns off the LCD).
 | 
			
		||||
  * @param character The character you wish to blink.
 | 
			
		||||
  * @param duration The duration of the on/off cycle in milliseconds, from 50 to ~4250 ms.
 | 
			
		||||
  * @note Segment B of position 7 cannot blink autonomously, so not all characters will work well.
 | 
			
		||||
@ -132,8 +132,8 @@ void watch_stop_blink();
 | 
			
		||||
  *          or backward in a shift register whose positions map to fixed segments on the LCD. Given
 | 
			
		||||
  *          this constraint, an animation across all six segments does not make sense; so the watch
 | 
			
		||||
  *          library offers only a simple "tick/tock" in segments D and E. This animation does not
 | 
			
		||||
  *          require any CPU resources, and will continue even in standby and shallow sleep mode
 | 
			
		||||
  *          (if the LCD remains on).
 | 
			
		||||
  *          require any CPU resources, and will continue even in STANDBY and Sleep mode (but not Deep
 | 
			
		||||
  *          Sleep mode, since that mode turns off the LCD).
 | 
			
		||||
  * @param duration The duration of each frame in ms. 500 milliseconds produces a classic tick/tock.
 | 
			
		||||
  */
 | 
			
		||||
void watch_start_tick_animation(uint32_t duration);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user