Skip to content

Commit

Permalink
wake from backup, clarify docs
Browse files Browse the repository at this point in the history
  • Loading branch information
joeycastillo committed Jul 17, 2024
1 parent 51de7a5 commit ff220ae
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 29 deletions.
61 changes: 41 additions & 20 deletions common/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,55 @@
#include "sam.h"
#include "pins.h"

/** @brief A function you will implement to initialize your application state. The app_init function is called after
* system clocks are initialized, and before anything else.
* @details Use this function to set up any internal data structures or state required by your app, and set up any
* low-level parameters like CPU speed or microcontroller register configuration.
* @note If your application plans to use the real-time clock perhiperal, you should call the `rtc_init` function here.
/** @brief A function you will implement to initialize your application's low-
* level setup. The app_init function is called after system clocks are
* initialized, and before anything else.
* @details You may be wondering why there is an `app_init` function as well as
* an `app_setup` function. The main difference is that app_init is
* only meant to be callec once, at boot, whereas you might want to
* call app_setup multiple times, for example if you want to disable
* some peripherals before entering STANDBY mode, and re-enable them
* after waking up. In essence, you should set up anything that will
* run forever in app_init, whereas anything that could get turned off
* in the course of execution should be set up in app_setup.
* @note If your application plans to use the real-time clock perhiperal, you
* probably want to call the `rtc_init` function here.
*/
void app_init(void);

/** @brief A function you will implement to set up your application. The app_setup function is like setup() in Arduino.
* It is called once when the program begins. You should set pin modes and enable any peripherals you want to
* set up (real-time clock, I2C, etc.) Depending on your application, you may or may not want to configure
* sensors here. For example, a low-power accelerometer that will run at all times should be configured here,
* whereas you may want to enable a more power-hungry sensor only when you need it.
/** @brief OPTIONAL: A function you may implement to restore state after waking
* up from BACKUP mode on the SAM L21 or L22. This function is called
* after system_init, but before app_setup. You can stash a bit of your
* application state in the RTC's BKUP and GPn registers, and use this
* function as an opportinity to restore it before app_setup is called.
* @note You do not need to implement this function unless you are using the
* SAM L21 or L22 and you want to restore state from BACKUP mode.
*/
void app_wake_from_backup(void);

/** @brief A function you will implement to set up your app. The app_setup
* function is like setup() in Arduino. It is called once when the
* program begins, after app_init and app_wake_from_backup, if it
* exists. You should use this function to set up your application
* state and configure any peripherals you need to use.
*/
void app_setup(void);

/** @brief A function you will implement to serve as the app's main run loop. This method will be called repeatedly,
* or if you enter STANDBY mode, as soon as the device wakes from that mode.
* @note In order to wake from STANDBY mode, you must set up an interrupt or wake source. Otherwise your app will
* remain in STANDBY indefinitely.
* @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.
/** @brief A function you will implement to serve as the app's main run loop.
* This method will be called repeatedly, or if you enter STANDBY mode,
* as soon as the device wakes from that mode.
* @note In order to wake from STANDBY mode, you must set up an interrupt or
* wake source. Otherwise your app will remain in STANDBY indefinitely.
* @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.
*/
bool app_loop(void);

/** @brief OPTIONAL: A function to yield control of the CPU to other tasks. This function is called in the delay
* function to allow other tasks to run while the CPU is busy waiting. By default, this function
* does nothing, but if you are using the USB peripheral, you should implement this function and call
* `tud_task` at minumum, along with any other USB-related tasks you need to run.
/** @brief OPTIONAL: A function to yield control of the CPU to other tasks.
* This function is called in the delay function to allow other tasks
* to run while the CPU is busy waiting. By default, this function does
* nothing, but if you are using the USB peripheral, you should
* implement this function and call `tud_task` at minumum, along with
* any other USB-related tasks you need to run.
*/
void yield(void);
7 changes: 1 addition & 6 deletions common/delay.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
#include "delay.h"
#include "sam.h"
#include "system.h"

static void __empty() {
// Empty
}

void yield(void) __attribute__ ((weak, alias("__empty")));
#include "app.h"

void delay_init(void) {
SysTick->LOAD = SysTick_LOAD_RELOAD_Msk;
Expand Down
13 changes: 10 additions & 3 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
#include "system.h"
#include "delay.h"

void _enter_standby_mode(void);

int main(void) {
// set up system clocks
sys_init();
Expand All @@ -20,7 +18,8 @@ int main(void) {
// allow application to do its own initialization
app_init();

// TODO: restore from BACKUP state
// restore from BACKUP state
app_wake_from_backup();

// allow application to do its initial setup
app_setup();
Expand All @@ -35,3 +34,11 @@ int main(void) {

return 0;
}

static void __empty() {
// Empty
}

void app_wake_from_backup(void) __attribute__ ((weak, alias("__empty")));

void yield(void) __attribute__ ((weak, alias("__empty")));

0 comments on commit ff220ae

Please sign in to comment.