From a8c5fcc5eb5c8edc75db8576cc1187e6e56b96a0 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Mon, 9 Jan 2017 23:15:47 +0100 Subject: [PATCH] cpu: saml21: add periph/pm support --- cpu/saml21/Makefile.features | 1 + cpu/saml21/Makefile.include | 2 ++ cpu/saml21/include/periph_cpu.h | 2 ++ cpu/saml21/periph/pm.c | 56 +++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 cpu/saml21/Makefile.features create mode 100644 cpu/saml21/periph/pm.c diff --git a/cpu/saml21/Makefile.features b/cpu/saml21/Makefile.features new file mode 100644 index 0000000000..7a418ea511 --- /dev/null +++ b/cpu/saml21/Makefile.features @@ -0,0 +1 @@ +FEATURES_PROVIDED += periph_pm diff --git a/cpu/saml21/Makefile.include b/cpu/saml21/Makefile.include index 17d168d77d..3ff606767e 100644 --- a/cpu/saml21/Makefile.include +++ b/cpu/saml21/Makefile.include @@ -1,5 +1,7 @@ export CPU_ARCH = cortex-m0plus export CPU_FAM = saml21 +USEMODULE += pm_layered + include $(RIOTCPU)/sam0_common/Makefile.include include $(RIOTCPU)/Makefile.include.cortexm_common diff --git a/cpu/saml21/include/periph_cpu.h b/cpu/saml21/include/periph_cpu.h index 33672533b1..7488b7db6c 100644 --- a/cpu/saml21/include/periph_cpu.h +++ b/cpu/saml21/include/periph_cpu.h @@ -60,6 +60,8 @@ typedef enum { /** @} */ #endif /* ndef DOXYGEN */ +#define PM_NUM_MODES (3) + #ifdef __cplusplus } #endif diff --git a/cpu/saml21/periph/pm.c b/cpu/saml21/periph/pm.c new file mode 100644 index 0000000000..341459f953 --- /dev/null +++ b/cpu/saml21/periph/pm.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017 Kaspar Schleiser + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_saml21 + * @{ + * + * @file + * @brief Implementation of the kernels power management interface + * + * @author Kaspar Schleiser + * + * @} + */ + +#include "periph/pm.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +void pm_set(unsigned mode) +{ + if (mode < PM_NUM_MODES) { + uint32_t _mode; + + switch (mode) { + case 0: + DEBUG("pm_set(): setting BACKUP mode.\n"); + _mode = PM_SLEEPCFG_SLEEPMODE_BACKUP; + break; + case 1: + DEBUG("pm_set(): setting STANDBY mode.\n"); + _mode = PM_SLEEPCFG_SLEEPMODE_STANDBY; + break; + case 2: + DEBUG("pm_set(): setting IDLE mode.\n"); + _mode = PM_SLEEPCFG_SLEEPMODE_IDLE2; + break; + } + + /* write sleep configuration */ + PM->SLEEPCFG.bit.SLEEPMODE = _mode; + /* make sure value has been set */ + while (PM->SLEEPCFG.bit.SLEEPMODE != _mode) {} + } + + /* Executes a device DSB (Data Synchronization Barrier) */ + __DSB(); + /* Enter standby mode */ + __WFI(); +}