From a9d1825e2ed813cb2d735af58b40401ae72d37b0 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 7 Nov 2019 20:21:02 +0100 Subject: [PATCH] cpu/lpc2387: implement periph/pm Enable IDLE and Deep Powerdown mode. IDLE is pretty straightforward - insteady of busy waiting, the CPU will enter an idle state from which it will resume on any event. Deep Power Down shuts off the entite system except for the battery backup power domain. That means the CPU will reset on resume and can be woken by e.g. RTC. SLEEP and POWERDOWN disable the PLL and the PLL and Flash respectively. This requires some proper wake-up handling. Since this turned out to be a major time sink and those modes are never currently never used in RIOT outside of tests, I left this as an exercise for a future reader. --- cpu/arm7_common/include/arm7_common.h | 7 ++-- cpu/lpc2387/Makefile.include | 1 + cpu/lpc2387/include/periph_cpu.h | 7 ++++ cpu/lpc2387/periph/pm.c | 56 +++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 cpu/lpc2387/periph/pm.c diff --git a/cpu/arm7_common/include/arm7_common.h b/cpu/arm7_common/include/arm7_common.h index 983b5277da..fd91052c7d 100644 --- a/cpu/arm7_common/include/arm7_common.h +++ b/cpu/arm7_common/include/arm7_common.h @@ -72,9 +72,10 @@ extern "C" { #define BORD (BIT4) #define PM2 (BIT7) -#define PM_IDLE (PM0) -#define PM_SLEEP (PM2|PM0) -#define PM_POWERDOWN (PM1) +#define PM_IDLE (PM0) +#define PM_SLEEP (PM2|PM0) +#define PM_POWERDOWN (PM1) +#define PM_DEEP_POWERDOWN (PM2|PM1) /** @} */ /** diff --git a/cpu/lpc2387/Makefile.include b/cpu/lpc2387/Makefile.include index fe5a518fa2..19cfdb7946 100644 --- a/cpu/lpc2387/Makefile.include +++ b/cpu/lpc2387/Makefile.include @@ -1,3 +1,4 @@ include $(RIOTCPU)/arm7_common/Makefile.include USEMODULE += arm7_common periph bitfield newlib +USEMODULE += pm_layered diff --git a/cpu/lpc2387/include/periph_cpu.h b/cpu/lpc2387/include/periph_cpu.h index b944bbc392..468e56ddb5 100644 --- a/cpu/lpc2387/include/periph_cpu.h +++ b/cpu/lpc2387/include/periph_cpu.h @@ -32,6 +32,13 @@ extern "C" { */ #define __IO volatile +/** + * @name Power mode configuration + * @{ + */ +#define PM_NUM_MODES (4) +/** @} */ + /** * @brief Fast GPIO register definition struct */ diff --git a/cpu/lpc2387/periph/pm.c b/cpu/lpc2387/periph/pm.c new file mode 100644 index 0000000000..2afbb92509 --- /dev/null +++ b/cpu/lpc2387/periph/pm.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2019 Beuth Hochschule für Technik Berlin + * + * 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_lpc2387 + * @ingroup drivers_periph_pm + * @{ + * + * @file + * @brief Implementation of the kernels power management interface + * + * @note Handling of wake-up from POWERDOWN & SLEEP is not implemented + * yet, so those states are disabled. + * + * @author Benjamin Valentin + * + * @} + */ + +#include "periph/pm.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +void pm_set(unsigned mode) +{ + switch (mode) { + case 0: + /* Everything except battery backup is powered down */ + DEBUG_PUTS("pm_set(): setting Deep Power Down mode."); + PCON |= PM_DEEP_POWERDOWN; + break; + case 1: + /* PLL & Flash are powered down */ + DEBUG_PUTS("pm_set(): setting Power Down mode."); + /* PCON |= PM_POWERDOWN; */ + PCON |= PM_IDLE; /* fixme */ + break; + case 2: + /* PLL is powered down */ + DEBUG_PUTS("pm_set(): setting Sleep mode."); + /* PCON |= PM_SLEEP; */ + PCON |= PM_IDLE; /* fixme */ + break; + default: /* Falls through */ + case 3: + DEBUG_PUTS("pm_set(): setting Idle mode."); + PCON |= PM_IDLE; + break; + } +}