mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Revision:
18:da299f395b9e
diff -r 0b20abc991ca -r da299f395b9e targets/hal/TARGET_Atmel/TARGET_SAM_CortexM0P/drivers/system/power/TARGET_SAML21/power.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_Atmel/TARGET_SAM_CortexM0P/drivers/system/power/TARGET_SAML21/power.h	Mon Nov 09 13:30:11 2015 +0000
@@ -0,0 +1,889 @@
+/**
+ * \file
+ *
+ * \brief SAM L21 Power functionality
+ *
+ * Copyright (C) 2014-2015 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ *    Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+/*
+ * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
+ */
+#ifndef POWER_H_INCLUDED
+#define POWER_H_INCLUDED
+
+#include <compiler.h>
+#include <clock.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup asfdoc_sam0_system_group
+ * @{
+ */
+
+/**
+ * \brief Device sleep modes.
+ *
+ * List of available sleep modes in the device. A table of clocks available in
+ * different sleep modes can be found in \ref asfdoc_sam0_system_module_overview_sleep_mode.
+ */
+enum system_sleepmode {
+    /** IDLE sleep mode */
+    SYSTEM_SLEEPMODE_IDLE       = PM_SLEEPCFG_SLEEPMODE(0x2),
+    /** STANDBY sleep mode */
+    SYSTEM_SLEEPMODE_STANDBY    = PM_SLEEPCFG_SLEEPMODE_STANDBY,
+    /** BACKUP sleep mode */
+    SYSTEM_SLEEPMODE_BACKUP     = PM_SLEEPCFG_SLEEPMODE_BACKUP,
+    /** OFF sleep mode */
+    SYSTEM_SLEEPMODE_OFF        = PM_SLEEPCFG_SLEEPMODE_OFF,
+};
+
+/**
+ * \brief Performance level.
+ *
+ * List of performance levels. Performance level technique consists of
+ * adjusting the regulator output voltage to reduce power consumption.
+ */
+enum system_performance_level {
+    /** Performance level 0 */
+    SYSTEM_PERFORMANCE_LEVEL_0  = PM_PLCFG_PLSEL_PL0,
+    /** Performance level 2 */
+    SYSTEM_PERFORMANCE_LEVEL_2  = PM_PLCFG_PLSEL_PL2,
+};
+
+/**
+ * \brief RAM Back-biasing mode.
+ *
+ * List of RAM back bias modes. By default, in standby sleep mode,
+ * RAM is in low power mode (back biased) if its power domain is in
+ * retention state. This behavior can be changed by configuring the Back Bias
+ * bit groups in STDBYCFG(STDBYCFG.BBIASxx).
+ */
+enum system_ram_back_bias_mode {
+    /** Retention Back biasing mode */
+    SYSTEM_RAM_BACK_BIAS_RETENTION = 0,
+    /** Standby Back Biasing mode */
+    SYSTEM_RAM_BACK_BIAS_STANDBY,
+    /** Standby OFF mode */
+    SYSTEM_RAM_BACK_BIAS_STANDBY_OFF,
+    /** Always OFF mode */
+    SYSTEM_RAM_BACK_BIAS_OFF,
+};
+
+/**
+ * \brief Linked power domain.
+ *
+ * List of linked power domains. Power domains can be linked to each other.
+ * It allows a power domain (PDn) to be kept in active state if the inferior
+ * power domain (PDn-1) is in active state too.
+ */
+enum system_linked_power_domain {
+    /** Power domains PD0/PD1/PD2 are not linked */
+    SYSTEM_LINKED_POWER_DOMAIN_DEFAULT   = PM_STDBYCFG_LINKPD_DEFAULT_Val,
+    /** Power domains PD0 and PD1 are linked */
+    SYSTEM_LINKED_POWER_DOMAIN_PD01      = PM_STDBYCFG_LINKPD_PD01_Val,
+    /** Power domains PD1 and PD2 are linked */
+    SYSTEM_LINKED_POWER_DOMAIN_PD12      = PM_STDBYCFG_LINKPD_PD12_Val,
+    /** All Power domains are linked */
+    SYSTEM_LINKED_POWER_DOMAIN_PD012     = PM_STDBYCFG_LINKPD_PD012_Val,
+};
+
+/**
+ * \brief Power domain.
+ *
+ * List of power domains. Power domain gating technique consists of turning
+ * on or off power domain voltage to save power while keeping other domains
+ * powered up.
+ */
+enum system_power_domain {
+    /** All power domains switching are handled by hardware */
+    SYSTEM_POWER_DOMAIN_DEFAULT = PM_STDBYCFG_PDCFG_DEFAULT_Val,
+    /** Power domain 0 (PD0) is forced ACTIVE */
+    SYSTEM_POWER_DOMAIN_PD0     = PM_STDBYCFG_PDCFG_PD0_Val,
+    /** Power domain 0 and 1 (PD0 and PD1) are forced ACTIVE */
+    SYSTEM_POWER_DOMAIN_PD01    = PM_STDBYCFG_PDCFG_PD01_Val,
+    /** All power domains are forced ACTIVE */
+    SYSTEM_POWER_DOMAIN_PD012   = PM_STDBYCFG_PDCFG_PD012_Val,
+};
+
+/**
+ * \brief Voltage regulator.
+ *
+ * Voltage regulators selection. In active mode, the voltage regulator
+ * can be chosen on the fly between a LDO or a Buck converter.
+ */
+enum system_voltage_regulator_sel {
+    /** The voltage regulator in active mode is a LDO voltage regulator */
+    SYSTEM_VOLTAGE_REGULATOR_LDO    = SUPC_VREG_SEL_LDO_Val,
+    /** The voltage regulator in active mode is a buck converter */
+    SYSTEM_VOLTAGE_REGULATOR_BUCK   = SUPC_VREG_SEL_BUCK_Val,
+};
+
+/**
+ * \brief Low power efficiency.
+ *
+ * Low power mode efficiency.
+ */
+enum system_voltage_regulator_low_power_efficiency {
+    /** The voltage regulator in Low power mode has the default efficiency and
+    	support the whole VDD range (1.62V to 3.6V) */
+    SYSTEM_VOLTAGE_REGULATOR_LOW_POWER_EFFICIENCY_DEFAULT,
+    /** The voltage regulator in Low power mode has the highest efficiency and
+    	support the limited VDD range (2.5V to 3.6V) */
+    SYSTEM_VOLTAGE_REGULATOR_LOW_POWER_EFFICIENCY_HIGHTEST,
+};
+
+/**
+ * \brief Voltage reference value.
+ *
+ * Voltage references selection.
+ */
+enum system_voltage_references_sel {
+    /** 1.0V voltage reference typical value */
+    SYSTEM_VOLTAGE_REFERENCE_1V0    = SUPC_VREF_SEL_1V0_Val,
+    /** 1.1V voltage reference typical value */
+    SYSTEM_VOLTAGE_REFERENCE_1V1    = SUPC_VREF_SEL_1V1_Val,
+    /** 1.2V voltage reference typical value */
+    SYSTEM_VOLTAGE_REFERENCE_1V2    = SUPC_VREF_SEL_1V2_Val,
+    /** 1.25V voltage reference typical value */
+    SYSTEM_VOLTAGE_REFERENCE_1V25   = SUPC_VREF_SEL_1V25_Val,
+    /** 2.0V voltage reference typical value */
+    SYSTEM_VOLTAGE_REFERENCE_2V0    = SUPC_VREF_SEL_2V0_Val,
+    /** 2.2V voltage reference typical value */
+    SYSTEM_VOLTAGE_REFERENCE_2V2    = SUPC_VREF_SEL_2V2_Val,
+    /** 2.4V voltage reference typical value */
+    SYSTEM_VOLTAGE_REFERENCE_2V4    = SUPC_VREF_SEL_2V4_Val,
+    /** 2.5V voltage reference typical value */
+    SYSTEM_VOLTAGE_REFERENCE_2V5    = SUPC_VREF_SEL_2V5_Val,
+};
+
+/**
+ * \brief Battery power switch configuration enum.
+ *
+ * Enum for Battery power switch modes.
+ */
+enum system_battery_power_switch {
+    /** The backup domain is always supplied by main power */
+    SYSTEM_BATTERY_POWER_SWITCH_NONE      = SUPC_BBPS_CONF_NONE_Val,
+    /** The power switch is handled by the automatic power switch */
+    SYSTEM_BATTERY_POWER_SWITCH_AUTOMATIC = SUPC_BBPS_CONF_APWS_Val,
+    /** The backup domain is always supplied by battery backup power */
+    SYSTEM_BATTERY_POWER_SWITCH_FORCED    = SUPC_BBPS_CONF_FORCED_Val,
+    /** The power switch is handled by the BOD33 */
+    SYSTEM_BATTERY_POWER_SWITCH_BOD33     = SUPC_BBPS_CONF_BOD33_Val,
+};
+
+/**
+ * \brief Voltage reference.
+ *
+ * List of available voltage references (VREF) that may be used within the
+ * device.
+ */
+enum system_voltage_reference {
+    /** Temperature sensor voltage reference */
+    SYSTEM_VOLTAGE_REFERENCE_TEMPSENSE,
+    /** Voltage reference output */
+    SYSTEM_VOLTAGE_REFERENCE_OUTPUT,
+};
+
+/**
+ * \brief Backup IO enum.
+ *
+ * List of Backup input and output pins.
+ * If enabled (\ref system_backup_pin_output_enable), the pins can be driven
+ * by the SUPC.
+ */
+enum system_backup_pin {
+    /** Power Supply OK status pin */
+    SYSTEM_BACKUP_PIN_PSOK  = (0x1 << 0),
+    /** Backup output pin 0  */
+    SYSTEM_BACKUP_PIN_OUT_0 = (0x1 << 1),
+    /** Backup output pin 1  */
+    SYSTEM_BACKUP_PIN_OUT_1 = (0x1 << 2)
+};
+
+/**
+ * \brief Standby configuration.
+ *
+ * Configuration structure for standby mode.
+ */
+struct system_standby_config {
+    /** Power domain */
+    enum system_power_domain  power_domain;
+    /** Enable dynamic power gating for power domain 0 */
+    bool enable_dpgpd0;
+    /** Enable dynamic power gating for power domain 1 */
+    bool enable_dpgpd1;
+    /** Automatic VREG switching disable */
+    bool disable_avregsd;
+    /** Linked power domain */
+    enum system_linked_power_domain linked_power_domain;
+    /** Back bias for HMCRAMCHS */
+    enum system_ram_back_bias_mode hmcramchs_back_bias;
+    /** Back bias for HMCRAMCLP */
+    enum system_ram_back_bias_mode hmcramclp_back_bias;
+};
+
+/**
+ * \brief Voltage Regulator System (VREG) Control configuration.
+ *
+ * Configuration structure for VREG.
+ */
+struct system_voltage_regulator_config {
+    /** Voltage scaling period */
+    uint8_t  voltage_scale_period;
+    /** Voltage scaling voltage step */
+    uint8_t voltage_scale_step;
+    /** Run in standby in standby sleep mode */
+    bool run_in_standby;
+    /** Voltage Regulator Selection */
+    enum system_voltage_regulator_sel  regulator_sel;
+    /** Low power efficiency */
+    enum system_voltage_regulator_low_power_efficiency low_power_efficiency;
+};
+
+/**
+ * \brief Voltage References System (VREF) Control configuration.
+ *
+ * Configuration structure for VREF.
+ */
+struct system_voltage_references_config {
+    /** Voltage References Selection */
+    enum system_voltage_references_sel  sel;
+    /** On Demand Control */
+    bool on_demand;
+    /** Run in standby */
+    bool run_in_standby;
+};
+
+/**
+ * \brief Battery Backup Power Switch (BBPS) Control configuration.
+ *
+ * Configuration structure for Battery Backup Power Switch (BBPS).
+ */
+struct system_battery_backup_power_switch_config {
+    /** Enable device wake up when BBPS switches from
+    	battery backup power to main power */
+    bool wake_enabled;
+    /** Battery backup power switch configuration */
+    enum system_battery_power_switch battery_power_switch;
+};
+
+/**
+ * \name Voltage Regulator
+ * @{
+ */
+
+/**
+ * \brief Retrieve the default configuration for voltage regulator.
+ *
+ * Fills a configuration structure with the default configuration:
+ *   - Voltage scaling period is 1μs
+ *   - Voltage scaling voltage step is 2*min_step
+ *   - The voltage regulator is in low power mode in Standby sleep mode
+ *   - The voltage regulator in active mode is an LDO voltage regulator
+ *   - The voltage regulator in Low power mode has the default efficiency
+ *
+ * \param[out] config  Configuration structure to fill with default values
+ */
+static inline void system_voltage_regulator_get_config_defaults(
+    struct system_voltage_regulator_config *const config)
+{
+    Assert(config);
+    config->voltage_scale_period = 0;
+    config->voltage_scale_step   = 0;
+    config->run_in_standby       = false;
+    config->regulator_sel        = SYSTEM_VOLTAGE_REGULATOR_LDO;
+    config->low_power_efficiency = SYSTEM_VOLTAGE_REGULATOR_LOW_POWER_EFFICIENCY_DEFAULT;
+}
+
+/**
+ * \brief Configure voltage regulator.
+ *
+ * Configures voltage regulator with the given configuration.
+ *
+ * \param[in] config  Voltage regulator configuration structure containing
+ *                    the new config
+ */
+static inline void system_voltage_regulator_set_config(
+    struct system_voltage_regulator_config *const config)
+{
+    Assert(config);
+    SUPC->VREG.bit.VSPER    = config->voltage_scale_period;
+    SUPC->VREG.bit.VSVSTEP  = config->voltage_scale_step;
+    SUPC->VREG.bit.RUNSTDBY = config->run_in_standby;
+    SUPC->VREG.bit.SEL      = config->regulator_sel;
+    SUPC->VREG.bit.LPEFF    = config->low_power_efficiency;
+    while(!(SUPC->STATUS.reg & SUPC_STATUS_VREGRDY)) {
+        ;
+    }
+}
+
+/**
+* \brief Enable the selected voltage regulator.
+ *
+ * Enables the selected voltage regulator source.
+ */
+static inline void system_voltage_regulator_enable(void)
+{
+    SUPC->VREG.reg |= SUPC_VREG_ENABLE;
+}
+
+/**
+ * \brief Disable the selected voltage regulator.
+ *
+ * Disables the selected voltage regulator.
+ */
+static inline void system_voltage_regulator_disable(void)
+{
+    SUPC->VREG.reg &= ~SUPC_VREG_ENABLE;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * \name Voltage References
+ * @{
+ */
+
+/**
+ * \brief Retrieve the default configuration for voltage reference.
+ *
+ * Fill a configuration structure with the default configuration:
+ *   - 1.0V voltage reference typical value
+ *   - On demand control disabled
+ *   - The voltage reference and the temperature sensor are halted during standby sleep mode
+ *
+ * \param[out] config  Configuration structure to fill with default values
+ */
+static inline void system_voltage_reference_get_config_defaults(
+    struct system_voltage_references_config *const config)
+{
+    Assert(config);
+    config->sel            = SYSTEM_VOLTAGE_REFERENCE_1V0;
+    config->on_demand      = false;
+    config->run_in_standby = false;
+}
+
+/**
+ * \brief Configure voltage reference.
+ *
+ * Configures voltage reference with the given configuration.
+ *
+ * \param[in] config  Voltage reference configuration structure containing
+ *                    the new config
+ */
+static inline void system_voltage_reference_set_config(
+    struct system_voltage_references_config *const config)
+{
+    Assert(config);
+    SUPC->VREF.bit.SEL      = config->sel;
+    SUPC->VREF.bit.ONDEMAND = config->on_demand;
+    SUPC->VREF.bit.RUNSTDBY = config->run_in_standby;
+}
+
+/**
+ * \brief Enable the selected voltage reference.
+ *
+ * Enables the selected voltage reference source, making the voltage reference
+ * available on a pin as well as an input source to the analog peripherals.
+ *
+ * \param[in] vref  Voltage reference to enable
+ */
+static inline void system_voltage_reference_enable(
+    const enum system_voltage_reference vref)
+{
+    switch (vref) {
+        case SYSTEM_VOLTAGE_REFERENCE_TEMPSENSE:
+            SUPC->VREF.reg |= SUPC_VREF_TSEN;
+            break;
+        case SYSTEM_VOLTAGE_REFERENCE_OUTPUT:
+            SUPC->VREF.reg |= SUPC_VREF_VREFOE;
+            break;
+        default:
+            Assert(false);
+            return;
+    }
+}
+
+/**
+ * \brief Disable the selected voltage reference.
+ *
+ * Disables the selected voltage reference source.
+ *
+ * \param[in] vref  Voltage reference to disable
+ */
+static inline void system_voltage_reference_disable(
+    const enum system_voltage_reference vref)
+{
+    switch (vref) {
+        case SYSTEM_VOLTAGE_REFERENCE_TEMPSENSE:
+            SUPC->VREF.reg &= ~SUPC_VREF_TSEN;
+            break;
+        case SYSTEM_VOLTAGE_REFERENCE_OUTPUT:
+            SUPC->VREF.reg &= ~SUPC_VREF_VREFOE;
+            break;
+        default:
+            Assert(false);
+            return;
+    }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * \name Battery Backup Power Switch
+ * @{
+ */
+
+/**
+ * \brief Retrieve the default configuration for battery backup power switch control.
+ *
+ * Fills a configuration structure with the default configuration:
+ *   - The main Power Supply OK status is not available on the PSOK pin
+ *   - The device is not woken up when switched from battery backup power to main power
+ *   - The backup domain is always supplied by main power
+ *
+ * \param[out] config  Configuration structure to fill with default values
+ */
+static inline void system_battery_backup_power_switch_get_config_defaults(
+    struct system_battery_backup_power_switch_config *const config)
+{
+    Assert(config);
+    config->wake_enabled         = false;
+    config->battery_power_switch = SYSTEM_BATTERY_POWER_SWITCH_NONE;
+}
+
+/**
+ * \brief Configure battery backup power switch.
+ *
+ * Configures battery backup power switch with the given configuration.
+ *
+ * \param[in] config  Battery backup power switch configuration structure containing
+ *                    the new config
+ */
+static inline void system_battery_backup_power_switch_set_config(
+    struct system_battery_backup_power_switch_config *const config)
+{
+    Assert(config);
+    uint32_t new_config = SUPC->BBPS.reg & SUPC_BBPS_PSOKEN;
+
+    if(config->wake_enabled) {
+        new_config |= SUPC_BBPS_WAKEEN;
+    }
+
+    new_config |= SUPC_BBPS_CONF(config->battery_power_switch);
+
+    SUPC->BBPS.reg = new_config;
+
+    if (config->battery_power_switch == SYSTEM_BATTERY_POWER_SWITCH_AUTOMATIC) {
+        while (!(SUPC->STATUS.reg & SUPC_STATUS_APWSRDY)) {
+            ;
+        }
+    }
+}
+
+/**
+ * @}
+ */
+
+/**
+ * \name Output Pins in Backup Mode
+ * @{
+ */
+
+/**
+ *  \brief Enable the backup pin output.
+ *
+ *  The output is enabled and driven by the SUPC.
+ *
+ *  \param[in] pin Backup pin index
+ */
+static inline void system_backup_pin_output_enable(
+    enum system_backup_pin pin)
+{
+    if (pin == SYSTEM_BACKUP_PIN_PSOK) {
+        SUPC->BBPS.reg |= SUPC_BBPS_PSOKEN;
+    } else {
+        SUPC->BKOUT.reg |= SUPC_BKOUT_EN(pin >> 1);
+    }
+}
+
+/**
+ *  \brief Disable the backup pin output.
+ *
+ *  The output is not enabled.
+ *
+ *  \param[in] pin Backup pin index
+ */
+static inline void system_backup_pin_output_disable(
+    enum system_backup_pin pin)
+{
+    if (pin == SYSTEM_BACKUP_PIN_PSOK) {
+        SUPC->BBPS.reg &= ~SUPC_BBPS_PSOKEN;
+    } else {
+        SUPC->BKOUT.reg &= ~SUPC_BKOUT_EN(pin >> 1);
+    }
+}
+
+/**
+ * \brief Check if backup pin output is enabled.
+ *
+ *  \param[in] pin Backup pin index
+ *
+ * \return The enabled status.
+ * \retval true The output is enabled
+ * \retval false The output is not enabled
+ */
+static inline bool system_backup_pin_output_is_enabled(
+    enum system_backup_pin pin)
+{
+    bool enabled = false;
+
+    if (pin == SYSTEM_BACKUP_PIN_PSOK) {
+        if (SUPC->BBPS.reg & SUPC_BBPS_PSOKEN) {
+            enabled = true;
+        }
+    } else {
+        if (SUPC->BKOUT.reg & SUPC_BKOUT_EN(pin >> 1)) {
+            enabled = true;
+        }
+    }
+    return enabled;
+}
+
+/**
+ *  \brief Enable the backup pin toggle on RTC event.
+ *
+ *  Toggle output on RTC event is enabled.
+ *
+ *  \param[in] pin Backup pin index
+ */
+static inline void system_backup_pin_output_enable_rtc_toggle(
+    enum system_backup_pin pin)
+{
+    Assert(pin != SYSTEM_BACKUP_PIN_PSOK);
+
+    SUPC->BKOUT.reg |= SUPC_BKOUT_RTCTGL(pin >> 1);
+}
+
+/**
+ *  \brief Disable the backup pin toggle on RTC event.
+ *
+ *  Toggle output on RTC event is disabled.
+ *
+ *  \param[in] pin Backup pin index
+ */
+static inline void system_backup_pin_output_disable_rtc_toggle(
+    enum system_backup_pin pin)
+{
+    Assert(pin != SYSTEM_BACKUP_PIN_PSOK);
+
+    SUPC->BKOUT.reg &= ~SUPC_BKOUT_RTCTGL(pin >> 1);
+}
+
+/**
+ *  \brief Set the backup pin.
+ *
+ *  Set the corresponding output pin.
+ *
+ *  \param[in] pin Backup pin index
+ */
+static inline void system_backup_pin_output_set(
+    enum system_backup_pin pin)
+{
+    Assert(pin != SYSTEM_BACKUP_PIN_PSOK);
+
+    SUPC->BKOUT.reg |= SUPC_BKOUT_SET(pin >> 1);
+}
+
+/**
+ *  \brief Clear the backup pin.
+ *
+ *  Clear the corresponding output.
+ *
+ *  \param[in] pin Backup pin index
+ */
+static inline void system_backup_pin_output_clear(
+    enum system_backup_pin pin)
+{
+    Assert(pin != SYSTEM_BACKUP_PIN_PSOK);
+
+    SUPC->BKOUT.reg |= SUPC_BKOUT_CLR(pin >> 1);
+}
+
+/**
+ *  \brief Get the backup I/O input values.
+ *
+ *  Get the backup I/O data input values. If the corresponding pin is enabled,
+ *  the I/O input value is given on the pin.
+ *
+ *  \param[in] pin Backup pin index
+ *
+ * \return The backup I/O input level value.
+ */
+static inline bool system_backup_pin_output_get(enum system_backup_pin pin)
+{
+    Assert(pin != SYSTEM_BACKUP_PIN_PSOK);
+
+    return (SUPC->BKIN.reg & SUPC_BKIN_BKIN(pin >> 1));
+}
+
+/**
+ * @}
+ */
+
+/**
+ * \name Device Sleep Control
+ * @{
+ */
+
+/**
+ * \brief Set the sleep mode of the device.
+ *
+ * Sets the sleep mode of the device; the configured sleep mode will be entered
+ * upon the next call of the \ref system_sleep() function.
+ *
+ * For an overview of which systems are disabled in sleep for the different
+ * sleep modes, see \ref asfdoc_sam0_system_module_overview_sleep_mode.
+ *
+ * \param[in] sleep_mode  Sleep mode to configure for the next sleep operation
+ */
+static inline void system_set_sleepmode(
+    const enum system_sleepmode sleep_mode)
+{
+    PM->SLEEPCFG.reg = sleep_mode;
+    while(PM->SLEEPCFG.reg != sleep_mode) ;
+}
+
+/**
+ * \brief Put the system to sleep waiting for interrupt.
+ *
+ * Executes a device DSB (Data Synchronization Barrier) instruction to ensure
+ * all ongoing memory accesses have completed. Further, a WFI (Wait For Interrupt)
+ * instruction is executed to place the device into the sleep mode specified by
+ * \ref system_set_sleepmode.
+ */
+static inline void system_sleep(void)
+{
+    __DSB();
+    __WFI();
+}
+
+/**
+ * @}
+ */
+
+/**
+ * \name Performance Level Control
+ * @{
+ */
+
+/**
+ * \brief Switch performance level.
+ *
+ *  The bus frequency must be reduced prior to scaling down the performance level,
+ *  in order to not exceed the maximum frequency allowed for the performance level.
+ *
+ *  When scaling up the performance level (for example from PL0 to PL2), the bus
+ *  frequency can be increased first when the performance level transition is
+ *  completed. Check the performance level status before increasing the frequency.
+ *
+ * \param[in] performance_level  Performance level to switch
+ *
+ * \retval STATUS_ERR_INVALID_ARG  Invalid parameter
+ * \retval STATUS_OK               Successfully
+ */
+static inline enum status_code system_switch_performance_level(
+    const enum system_performance_level performance_level)
+{
+
+    if (performance_level == (enum system_performance_level)PM->PLCFG.reg) {
+        return STATUS_OK;
+    }
+
+    /* Clear performance level status */
+    PM->INTFLAG.reg = PM_INTFLAG_PLRDY;
+
+    /* Switch performance level */
+    PM->PLCFG.reg = performance_level;
+
+    /* Waiting performance level ready */
+    while (!PM->INTFLAG.reg) {
+        ;
+    }
+    return STATUS_OK;
+}
+
+/**
+ * \brief Get performance level.
+ *
+ * Get performance level.
+ *
+ * \return Current performance level.
+ */
+static inline enum system_performance_level system_get_performance_level(void)
+{
+    return (enum system_performance_level)PM->PLCFG.reg;
+}
+
+/**
+ * \brief Get performance level status.
+ *
+ * Get performance level status.
+ * \return Performance level status: Written to one when the performance level is ready.
+ */
+static inline uint8_t system_get_performance_level_status(void)
+{
+    return PM->INTFLAG.reg;
+}
+
+/**
+ * \brief Clear performance level status.
+ *
+ * Clear performance level status.
+ */
+static inline void system_clear_performance_level_status(void)
+{
+    PM->INTFLAG.reg = PM_INTFLAG_PLRDY;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * \name Standby Configuration
+ * @{
+ */
+
+/**
+ * \brief Retrieve the default configuration for standby.
+ *
+ * Fills a configuration structure with the default configuration for standby:
+ *   - Retention back biasing mode for HMCRAMCLP
+ *   - Retention back biasing mode for HMCRAMCHS
+ *   - Power domains PD0/PD1/PD2 are not linked
+ *   - Automatic VREG switching is used
+ *   - Dynamic power gating for power domain 1 is disabled
+ *   - Dynamic power gating for power domain 0 is disabled
+ *   - All power domains switching are handled by hardware
+ *
+ * \param[out] config  Configuration structure to fill with default values
+ */
+static inline void system_standby_get_config_defaults(
+    struct system_standby_config *const config)
+{
+    Assert(config);
+    config->power_domain        = SYSTEM_POWER_DOMAIN_DEFAULT;
+    config->enable_dpgpd0       = false;
+    config->enable_dpgpd1       = false;
+    config->disable_avregsd     = false;
+    config->linked_power_domain = SYSTEM_LINKED_POWER_DOMAIN_DEFAULT;
+    config->hmcramchs_back_bias = SYSTEM_RAM_BACK_BIAS_RETENTION;
+    config->hmcramclp_back_bias = SYSTEM_RAM_BACK_BIAS_RETENTION;
+}
+
+/**
+ * \brief Configure standby mode.
+ *
+ * Configures standby with the given configuration.
+ *
+ * \param[in] config  Standby configuration structure containing
+ *                    the new config
+ */
+static inline void system_standby_set_config(
+    struct system_standby_config *const config)
+{
+    Assert(config);
+    PM->STDBYCFG.reg = PM_STDBYCFG_PDCFG(config->power_domain)
+                       | (config->enable_dpgpd0 << PM_STDBYCFG_DPGPD0_Pos)
+                       | (config->enable_dpgpd1 << PM_STDBYCFG_DPGPD1_Pos)
+                       | (config->disable_avregsd << PM_STDBYCFG_AVREGSD_Pos)
+                       | PM_STDBYCFG_LINKPD(config->linked_power_domain)
+                       | PM_STDBYCFG_BBIASHS(config->hmcramchs_back_bias)
+                       | PM_STDBYCFG_BBIASLP(config->hmcramclp_back_bias);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * \name I/O Retention
+ * @{
+ */
+
+/**
+ * \brief Enable I/O retention.
+ *
+ *  Enable I/O retention. After waking up from Backup mode, I/O lines are held
+ *  until the bit is written to 0.
+ */
+static inline void system_io_retension_enable(void)
+{
+    PM->CTRLA.reg = PM_CTRLA_IORET;
+}
+
+/**
+ * \brief Disable I/O retention.
+ *
+ * Disable IO retention. After waking up from Backup mode, I/O lines are not held.
+ */
+static inline void system_io_retension_disable(void)
+{
+    PM->CTRLA.reg = PM_CTRLA_MASK & (~PM_CTRLA_IORET);
+}
+
+/**
+ * @}
+ */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* POWER_H_INCLUDED */