mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 05:12:57 +01:00
Merge pull request #6160 from kaspar030/introduce_new_power_management
Introduce new power management
This commit is contained in:
commit
6270283033
8
Makefile.features
Normal file
8
Makefile.features
Normal file
@ -0,0 +1,8 @@
|
||||
# import list of provided features
|
||||
-include $(RIOTBOARD)/$(BOARD)/Makefile.features
|
||||
-include $(RIOTCPU)/$(CPU)/Makefile.features
|
||||
|
||||
DEFAULT_FEATURES += periph_pm
|
||||
|
||||
# add available default features to required list
|
||||
FEATURES_REQUIRED += $(filter-out $(DISABLE_FEATURES), $(filter $(FEATURES_PROVIDED), $(DEFAULT_FEATURES)))
|
@ -398,8 +398,8 @@ $(CURDIR)/eclipsesym.xml:
|
||||
# Extra make goals for testing and comparing changes.
|
||||
include $(RIOTBASE)/Makefile.buildtests
|
||||
|
||||
# import list of provided features
|
||||
-include $(RIOTBOARD)/$(BOARD)/Makefile.features
|
||||
# process provided features
|
||||
include $(RIOTBASE)/Makefile.features
|
||||
|
||||
# Export variables used throughout the whole make system:
|
||||
include $(RIOTBASE)/Makefile.vars
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include "lpc23xx.h" /* LPC23XX/24xx Peripheral Registers */
|
||||
#include "cpu.h"
|
||||
#include "lpm.h"
|
||||
#include "VIC.h"
|
||||
#include "ssp0-board.h"
|
||||
#include "smb380-board.h"
|
||||
@ -142,8 +141,6 @@ uint8_t SMB380_HystereseFunctionSample(int16_t *value)
|
||||
|
||||
static void SMB380_simple_interrupthandler(void)
|
||||
{
|
||||
lpm_awake();
|
||||
|
||||
SMB380_getAcceleration(SMB380_X_AXIS, NULL, &simple_buffer[0]);
|
||||
SMB380_getAcceleration(SMB380_Y_AXIS, NULL, &simple_buffer[1]);
|
||||
SMB380_getAcceleration(SMB380_Z_AXIS, NULL, &simple_buffer[2]);
|
||||
@ -249,8 +246,6 @@ static void SMB380_extIntHandler(void)
|
||||
{
|
||||
int16_t accInt[4];
|
||||
|
||||
lpm_awake(); //initializes clock
|
||||
|
||||
SMB380_getAcceleration(SMB380_X_AXIS, NULL, &accInt[0]);
|
||||
SMB380_getAcceleration(SMB380_Y_AXIS, NULL, &accInt[1]);
|
||||
SMB380_getAcceleration(SMB380_Z_AXIS, NULL, &accInt[2]);
|
||||
@ -1021,7 +1016,6 @@ void SMB380_enableNewDataInt(void)
|
||||
* prevent deep sleep, reason: 400 µs wake-up time is to long for 3kHz
|
||||
* interrupts
|
||||
*/
|
||||
SETBIT(lpm_prevent_sleep, LPM_PREVENT_SLEEP_ACCSENSOR);
|
||||
SMB380_Prepare();
|
||||
SMB380_ssp_write(SMB380_CONTROL4, 0, SMB380_READ_REGISTER);
|
||||
uReg = SMB380_ssp_read();
|
||||
@ -1050,7 +1044,6 @@ void SMB380_disableNewDataInt(void)
|
||||
* enable deep sleep, reason: 400 µs wake-up time was to long for 3kHz
|
||||
* interrupts
|
||||
*/
|
||||
CLRBIT(lpm_prevent_sleep, LPM_PREVENT_SLEEP_ACCSENSOR);
|
||||
irq_restore(cpsr);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
//#include "mma7455l-board.h"
|
||||
#include "gpioint.h"
|
||||
#include <stdio.h>
|
||||
#include "lpm.h"
|
||||
|
||||
//uint16_t sampleRateMMA7455L;
|
||||
//uint16_t interruptTicksMMA7455L;
|
||||
|
@ -10,3 +10,4 @@ export FFLAGS = rf2500 "prog $(HEXFILE)"
|
||||
INCLUDES += -I$(RIOTBOARD)/$(BOARD)/drivers/include
|
||||
|
||||
USEMODULE += chronos-drivers
|
||||
USEMODULE += periph_common
|
||||
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* 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 boards_qemu-i386
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-power mode emulation for qemu-i386.
|
||||
*
|
||||
* @author René Kijewski <rene.kijewski@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "lpm.h"
|
||||
#include "x86_reboot.h"
|
||||
|
||||
void lpm_init(void)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_set(enum lpm_mode target)
|
||||
{
|
||||
if (target != LPM_ON) {
|
||||
if (target == LPM_POWERDOWN) {
|
||||
x86_shutdown();
|
||||
}
|
||||
__asm__ volatile ("hlt");
|
||||
}
|
||||
return LPM_UNKNOWN;
|
||||
}
|
||||
|
||||
void lpm_awake(void)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
void lpm_begin_awake(void)
|
||||
{
|
||||
/* void */
|
||||
}
|
||||
|
||||
void lpm_end_awake(void)
|
||||
{
|
||||
/* void */
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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 core_arch
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Architecture dependent interface for power mode management
|
||||
*
|
||||
* This file acts as a wrapper between the kernels power management interface and the architecture
|
||||
* dependent implementation of power management.
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef LPM_ARCH_H
|
||||
#define LPM_ARCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Define the mapping between the architecture independent interfaces
|
||||
and the kernel internal interfaces
|
||||
*
|
||||
* This mapping is done for compatibility of existing platforms,
|
||||
* new platforms should always use the *_arch_* interfaces.
|
||||
* @{
|
||||
*/
|
||||
#ifdef COREIF_NG
|
||||
#define lpm_init lpm_arch_init
|
||||
#define lpm_set lpm_arch_set
|
||||
#define lpm_get lpm_arch_get
|
||||
#define lpm_awake lpm_arch_awake
|
||||
#define lpm_begin_awake lpm_arch_begin_awake
|
||||
#define lpm_end_awake lpm_arch_end_awake
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Available power modes
|
||||
*/
|
||||
enum lpm_mode {
|
||||
LPM_ON, /**< MCU is active */
|
||||
LPM_IDLE, /**< MCU is idle */
|
||||
LPM_SLEEP, /**< MCU in sleep mode */
|
||||
LPM_POWERDOWN, /**< MCU is powered down */
|
||||
LPM_OFF, /**< MCU is off */
|
||||
LPM_UNKNOWN = -1 /**< status unknown/unavailable */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialize the controller power management
|
||||
*/
|
||||
void lpm_arch_init(void);
|
||||
|
||||
/**
|
||||
* @brief Try to set the controller to a given power mode
|
||||
*
|
||||
* @param[in] target the desired power mode
|
||||
*
|
||||
* @return the power mode that was actually set
|
||||
*/
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target);
|
||||
|
||||
/**
|
||||
* @brief Get the controller's current power mode
|
||||
*
|
||||
* @return the power mode the controller is currently in
|
||||
*/
|
||||
enum lpm_mode lpm_arch_get(void);
|
||||
|
||||
/**
|
||||
* @brief Wakeup the controller from a low-power sleep mode
|
||||
*/
|
||||
void lpm_arch_awake(void);
|
||||
|
||||
/**
|
||||
* @brief This hook is called on the beginning of a wake-up phase
|
||||
*/
|
||||
void lpm_arch_begin_awake(void);
|
||||
|
||||
/**
|
||||
* @brief This hook is called on the end of a wake-up phase
|
||||
*/
|
||||
void lpm_arch_end_awake(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LPM_ARCH_H */
|
||||
/** @} */
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Freie Universität 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup core_lpm Power Management
|
||||
* @ingroup core
|
||||
* @brief The kernels power management interface
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Power management interface
|
||||
*
|
||||
* This interface needs to be implemented for each platform.
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics
|
||||
*/
|
||||
|
||||
#ifndef LPM_H_
|
||||
#define LPM_H_
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialization of power management (including clock setup)
|
||||
*
|
||||
* This function is invoked once during boot.
|
||||
*/
|
||||
void lpm_init(void);
|
||||
|
||||
/**
|
||||
* @brief Switches the MCU to a new power mode
|
||||
* @param[in] target Target power mode
|
||||
* @return The previous power mode
|
||||
*/
|
||||
enum lpm_mode lpm_set(enum lpm_mode target);
|
||||
|
||||
/**
|
||||
* @brief Switches the MCU to active power mode LPM_ON
|
||||
*/
|
||||
void lpm_awake(void);
|
||||
|
||||
/**
|
||||
* @brief Begin to switch MCU to active power mode.
|
||||
*/
|
||||
void lpm_begin_awake(void);
|
||||
|
||||
/**
|
||||
* @brief Finish to switch MCU to active power mode.
|
||||
*/
|
||||
void lpm_end_awake(void);
|
||||
|
||||
/**
|
||||
* @brief Returns the current power mode
|
||||
* @return Current power mode
|
||||
*/
|
||||
enum lpm_mode lpm_get(void);
|
||||
|
||||
/**
|
||||
* @brief LPM-internal variable
|
||||
*/
|
||||
extern volatile int lpm_prevent_sleep;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LPM_H_ */
|
||||
/** @} */
|
@ -19,6 +19,8 @@
|
||||
#ifndef REBOOT_H_
|
||||
#define REBOOT_H_
|
||||
|
||||
#include "periph/pm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -28,7 +30,10 @@
|
||||
*
|
||||
* This function is used by core_panic() when the DEVELHELP macro is not defined.
|
||||
*/
|
||||
void reboot(void);
|
||||
static inline void reboot(void)
|
||||
{
|
||||
pm_reboot();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Freie Universität Berlin
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* 2013 Freie Universität 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
|
||||
@ -24,10 +25,11 @@
|
||||
#include "kernel_init.h"
|
||||
#include "sched.h"
|
||||
#include "thread.h"
|
||||
#include "lpm.h"
|
||||
#include "irq.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "periph/pm.h"
|
||||
|
||||
#ifdef MODULE_SCHEDSTATISTICS
|
||||
#include "sched.h"
|
||||
#endif
|
||||
@ -39,8 +41,6 @@
|
||||
#include <auto_init.h>
|
||||
#endif
|
||||
|
||||
volatile int lpm_prevent_sleep = 0;
|
||||
|
||||
extern int main(void);
|
||||
static void *main_trampoline(void *arg)
|
||||
{
|
||||
@ -66,14 +66,7 @@ static void *idle_thread(void *arg)
|
||||
(void) arg;
|
||||
|
||||
while (1) {
|
||||
if (lpm_prevent_sleep) {
|
||||
lpm_set(LPM_IDLE);
|
||||
}
|
||||
else {
|
||||
lpm_set(LPM_IDLE);
|
||||
/* lpm_set(LPM_SLEEP); */
|
||||
/* lpm_set(LPM_POWERDOWN); */
|
||||
}
|
||||
pm_set_lowest();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
10
core/panic.c
10
core/panic.c
@ -28,10 +28,9 @@
|
||||
#include "kernel_defines.h"
|
||||
#include "cpu.h"
|
||||
#include "irq.h"
|
||||
#include "lpm.h"
|
||||
#include "panic.h"
|
||||
#include "arch/panic_arch.h"
|
||||
#include "reboot.h"
|
||||
#include "periph/pm.h"
|
||||
#include "log.h"
|
||||
|
||||
#if defined(DEVELHELP) && defined(MODULE_PS)
|
||||
@ -43,6 +42,8 @@ const char assert_crash_message[] = "FAILED ASSERTION.";
|
||||
/* flag preventing "recursive crash printing loop" */
|
||||
static int crashed = 0;
|
||||
|
||||
void __attribute__((weak)) panic_arch(void) {}
|
||||
|
||||
/* WARNING: this function NEVER returns! */
|
||||
NORETURN void core_panic(core_panic_t crash_code, const char *message)
|
||||
{
|
||||
@ -75,7 +76,10 @@ NORETURN void core_panic(core_panic_t crash_code, const char *message)
|
||||
panic_arch();
|
||||
#ifndef DEVELHELP
|
||||
/* DEVELHELP not set => reboot system */
|
||||
reboot();
|
||||
pm_reboot();
|
||||
#else
|
||||
/* DEVELHELP set => power off system */
|
||||
pm_off();
|
||||
#endif
|
||||
|
||||
/* tell the compiler that we won't return from this function
|
||||
|
@ -29,6 +29,8 @@ export CFLAGS += -DCOREIF_NG=1
|
||||
export USEMODULE += cortexm_common
|
||||
# Export the peripheral drivers to be linked into the final binary:
|
||||
export USEMODULE += periph
|
||||
# include common periph code
|
||||
export USEMODULE += periph_common
|
||||
# all cortex MCU's use newlib as libc
|
||||
export USEMODULE += newlib
|
||||
|
||||
|
@ -107,7 +107,7 @@ void thread_print_stack(void)
|
||||
printf("STACK (%d)= %X \n", i, *s);
|
||||
}
|
||||
|
||||
void reboot(void)
|
||||
void pm_reboot(void)
|
||||
{
|
||||
while (1) {
|
||||
arm_reset();
|
||||
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 INRIA
|
||||
*
|
||||
* 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_arm7_common
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Crash handling functions implementation for ARM-based MCUs
|
||||
*
|
||||
* @author Kévin Roussel <Kevin.Roussel@inria.fr>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*/
|
||||
|
||||
#include "lpm.h"
|
||||
|
||||
void panic_arch(void)
|
||||
{
|
||||
#ifdef DEVELHELP
|
||||
/* enter infinite loop, into deepest possible sleep mode */
|
||||
while (1) {
|
||||
lpm_set(LPM_OFF);
|
||||
}
|
||||
#endif
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||
*
|
||||
* 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_atmega1281
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
(void) target;
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||
*
|
||||
* 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_atmega2560
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
(void) target;
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
|
||||
*
|
||||
* 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_atmega328p
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
(void) target;
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
@ -12,6 +12,7 @@ export LINKFLAGS += -Wl,--gc-sections -static -lgcc
|
||||
|
||||
# export the peripheral drivers to be linked into the final binary
|
||||
export USEMODULE += periph
|
||||
export USEMODULE += periph_common
|
||||
|
||||
# the atmel port uses uart_stdio
|
||||
export USEMODULE += uart_stdio
|
||||
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 INRIA
|
||||
*
|
||||
* 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_atmega_common
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Crash handling functions implementation for ATmega MCUs
|
||||
*
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*/
|
||||
|
||||
#include <avr/wdt.h>
|
||||
#include "lpm.h"
|
||||
|
||||
void panic_arch(void)
|
||||
{
|
||||
wdt_disable();
|
||||
#ifdef DEVELHELP
|
||||
/* enter infinite loop, into deepest possible sleep mode */
|
||||
while (1) {
|
||||
lpm_set(LPM_OFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
@ -12,7 +12,7 @@
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels reboot interface
|
||||
* @brief Implementation of common AVR periph/pm functions
|
||||
*
|
||||
* @author Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
@ -22,9 +22,10 @@
|
||||
|
||||
#include <avr/wdt.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "irq.h"
|
||||
#include "periph/pm.h"
|
||||
|
||||
void reboot(void)
|
||||
void pm_reboot(void)
|
||||
{
|
||||
/*
|
||||
* Since the AVR doesn't support a real software reset, we set the Watchdog
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Loci Controls Inc.
|
||||
*
|
||||
* 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_cc2538
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Ian Martin <ian@locicontrols.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
(void) target;
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Leon George
|
||||
*
|
||||
* 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_cc26x0
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief implementation of the kernels power management interface
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
}
|
@ -21,9 +21,12 @@
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "lpm.h"
|
||||
#include "log.h"
|
||||
|
||||
#ifdef FEATURE_PERIPH_PM
|
||||
#include "periph/pm.h"
|
||||
#endif
|
||||
|
||||
#ifdef DEVELHELP
|
||||
static void print_ipsr(void)
|
||||
{
|
||||
@ -42,9 +45,5 @@ void panic_arch(void)
|
||||
print_ipsr();
|
||||
/* The bkpt instruction will signal to the debugger to break here. */
|
||||
__asm__("bkpt #0");
|
||||
/* enter infinite loop, into deepest possible sleep mode */
|
||||
while (1) {
|
||||
lpm_set(LPM_OFF);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
39
cpu/cortexm_common/pm.c
Normal file
39
cpu/cortexm_common/pm.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* 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_cortexm_common
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief common periph/pm functions
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph/pm.h"
|
||||
|
||||
#ifndef FEATURES_PERIPH_PM
|
||||
void pm_set_lowest(void)
|
||||
{
|
||||
/* Executes a device DSB (Data Synchronization Barrier) */
|
||||
__DSB();
|
||||
/* Enter standby mode */
|
||||
__WFI();
|
||||
}
|
||||
#endif
|
||||
|
||||
void pm_reboot(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität 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_ezr32wg
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.peterse@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
1
cpu/k60/Makefile.features
Normal file
1
cpu/k60/Makefile.features
Normal file
@ -0,0 +1 @@
|
||||
FEATURES_PROVIDED += periph_pm
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Eistec AB
|
||||
*
|
||||
* 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_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernel's power management interface
|
||||
*
|
||||
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
static inline void wait(void)
|
||||
{
|
||||
/* Clear the SLEEPDEEP bit to make sure we go into WAIT (sleep) mode instead
|
||||
* of deep sleep.
|
||||
*/
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
/* WFI instruction will start entry into WAIT mode */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* Stub waiting for https://github.com/RIOT-OS/RIOT/pull/2605 */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
switch (target) {
|
||||
case LPM_ON:
|
||||
/* MCU is active, do not go to low power */
|
||||
break;
|
||||
|
||||
case LPM_IDLE:
|
||||
case LPM_SLEEP:
|
||||
case LPM_POWERDOWN:
|
||||
case LPM_OFF:
|
||||
wait();
|
||||
break;
|
||||
|
||||
case LPM_UNKNOWN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return LPM_ON;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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_k64f
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
@ -10,6 +10,9 @@ export UNDEF += $(BINDIR)/kinetis_common/fcfield.o
|
||||
# include kinetis common periph drivers
|
||||
export USEMODULE += kinetis_common_periph
|
||||
|
||||
#include layered power mode module
|
||||
USEMODULE += pm_layered
|
||||
|
||||
# Define a recipe to build the watchdog disable binary, used when flashing
|
||||
$(RIOTCPU)/kinetis_common/dist/wdog-disable.bin: $(RIOTCPU)/kinetis_common/dist/wdog-disable.s
|
||||
$(AD)$(MAKE) -C $(RIOTCPU)/kinetis_common/dist/ $(notdir $@)
|
||||
|
@ -239,6 +239,11 @@ enum {
|
||||
*/
|
||||
void gpio_init_port(gpio_t pin, uint32_t pcr);
|
||||
|
||||
/**
|
||||
* @brief define number of usable power modes
|
||||
*/
|
||||
#define PM_NUM_MODES (1U)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
40
cpu/kinetis_common/periph/pm.c
Normal file
40
cpu/kinetis_common/periph/pm.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* 2014 Eistec AB
|
||||
*
|
||||
* 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_kinetis_common
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "periph/pm.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
void pm_set(unsigned mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case 0:
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Executes a device DSB (Data Synchronization Barrier) */
|
||||
__DSB();
|
||||
/* Enter standby mode */
|
||||
__WFI();
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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_kw2x
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Rakendra Thapa <rakendrathapa@gmail.com
|
||||
*
|
||||
* 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_lm4f120
|
||||
* @{
|
||||
*
|
||||
* @file lpm_arch.c
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Rakendra Thapa <rakendrathapa@gmail.com>
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO*/
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
/** @} */
|
@ -1,5 +1,3 @@
|
||||
export CPU_ARCH = cortex-m0
|
||||
|
||||
USEMODULE += periph_common
|
||||
|
||||
include $(RIOTCPU)/Makefile.include.cortexm_common
|
||||
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität 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_lpc11u34
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Paul RATHGEB <paul.rathgeb@skynet.be>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO*/
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* 2015 Freie Universität 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_lpc11u34
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels reboot interface
|
||||
*
|
||||
* @author Paul RATHGEB <paul.rathgeb@skynet.be>
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "reboot.h"
|
||||
#include "cpu.h"
|
||||
#include "log.h"
|
||||
|
||||
void reboot(void)
|
||||
{
|
||||
LOG_INFO("RIOT rebooting...\n");
|
||||
NVIC_SystemReset();
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
export CPU_ARCH = cortex-m3
|
||||
|
||||
USEMODULE += periph_common
|
||||
|
||||
include $(RIOTCPU)/Makefile.include.cortexm_common
|
||||
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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_lpc1768
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO*/
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* 2014 Freie Universität 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_lpc1768
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels reboot interface
|
||||
*
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
void reboot(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
*
|
||||
* 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 lpc2387
|
||||
* @ingroup lpm
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief LPC2387 Low-Power management
|
||||
* @ingroup lpc2387
|
||||
*
|
||||
* @author Heiko Will
|
||||
* @version $Revision$
|
||||
*
|
||||
* @note $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "lpc23xx.h"
|
||||
#include "lpc2387.h"
|
||||
#include "lpm.h"
|
||||
|
||||
/* lpm is accessed before memory init and initialized separately through code */
|
||||
__attribute__((section(".noinit")))
|
||||
static enum lpm_mode lpm;
|
||||
|
||||
extern void init_clks1(void);
|
||||
extern void init_clks2(void);
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
void lpm_init(void)
|
||||
{
|
||||
lpm = LPM_ON;
|
||||
}
|
||||
|
||||
#define LPM_DEBUG (1)
|
||||
|
||||
void lpm_begin_awake(void)
|
||||
{
|
||||
if (lpm >= LPM_SLEEP) { // wake up from deep sleep
|
||||
init_clks1();
|
||||
}
|
||||
}
|
||||
|
||||
void lpm_end_awake(void)
|
||||
{
|
||||
if (lpm >= LPM_SLEEP) { // wake up from deep sleep
|
||||
init_clks2();
|
||||
}
|
||||
|
||||
lpm = LPM_ON;
|
||||
}
|
||||
|
||||
void lpm_awake(void)
|
||||
{
|
||||
#if LPM_DEBUG
|
||||
unsigned long usec = RTC_CTC;
|
||||
#endif
|
||||
|
||||
if (lpm >= LPM_SLEEP) { // wake up from deep sleep
|
||||
/* benchmark */
|
||||
init_clks1();
|
||||
init_clks2();
|
||||
/* Debug tests */
|
||||
#if LPM_DEBUG
|
||||
usec = RTC_CTC - usec;
|
||||
DEBUG("Wakeup in %lu usecs\n", usec * 31);
|
||||
#endif
|
||||
}
|
||||
|
||||
lpm = LPM_ON;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_set(enum lpm_mode target)
|
||||
{
|
||||
unsigned target_flags;
|
||||
enum lpm_mode last_lpm = lpm;
|
||||
|
||||
/* calculate target mcu power mode */
|
||||
if (target == LPM_IDLE) {
|
||||
target_flags = PM_IDLE;
|
||||
}
|
||||
else if (target == LPM_SLEEP) {
|
||||
target_flags = PM_SLEEP;
|
||||
}
|
||||
else if (target == LPM_POWERDOWN) {
|
||||
target_flags = PM_POWERDOWN;
|
||||
}
|
||||
else {
|
||||
target_flags = 0;
|
||||
}
|
||||
|
||||
lpm = target;
|
||||
|
||||
DEBUG("# LPM power down %u -> %u\n", lpm, target);
|
||||
|
||||
PCON |= target_flags; // set target power mode
|
||||
return last_lpm;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
enum lpm_mode
|
||||
lpm_get(void)
|
||||
{
|
||||
return lpm;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
@ -17,7 +17,6 @@
|
||||
#include "periph/rtc.h"
|
||||
#include "VIC.h"
|
||||
#include "lpc2387.h"
|
||||
#include "lpm.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
@ -164,8 +163,6 @@ void rtc_poweroff(void)
|
||||
|
||||
void RTC_IRQHandler(void)
|
||||
{
|
||||
lpm_begin_awake();
|
||||
|
||||
if (RTC_ILR & ILR_RTSSF) {
|
||||
/* sub second interrupt (does not need flag-clearing) */
|
||||
}
|
||||
@ -179,7 +176,6 @@ void RTC_IRQHandler(void)
|
||||
_cb(_cb_arg);
|
||||
}
|
||||
DEBUG("Ring\n");
|
||||
lpm_end_awake();
|
||||
}
|
||||
|
||||
VICVectAddr = 0; /* Acknowledge Interrupt */
|
||||
|
@ -111,7 +111,7 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, void *stack_sta
|
||||
/******************************************************************************/
|
||||
|
||||
/* System reboot */
|
||||
void reboot(void)
|
||||
void pm_reboot(void)
|
||||
{
|
||||
/* force an hardware reboot ("Power-Up Clear"), by writing
|
||||
an illegal value to the watchdog control register */
|
||||
|
@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief low-power mode implementation for MSP430 MCUs
|
||||
*
|
||||
* @author Kévin Roussel <Kevin.Roussel@inria.fr>
|
||||
* @author Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ > 5)
|
||||
#include <intrinsics.h> // MSP430-gcc compiler instrinsics
|
||||
#endif
|
||||
|
||||
#include "board.h"
|
||||
#include <msp430.h>
|
||||
|
||||
#include "lpm.h"
|
||||
|
||||
/* Initialise the MSP430 power-saving mechanisms. */
|
||||
void lpm_init(void)
|
||||
{
|
||||
/* nothing to initialize on MSP430s: everything is done by fiddling
|
||||
with 4 bits of the status register (SR). */
|
||||
|
||||
/* just ensure MCU is fully up and running at start */
|
||||
lpm_awake();
|
||||
}
|
||||
|
||||
/* Change the current power-saving mode. */
|
||||
enum lpm_mode lpm_set(enum lpm_mode target)
|
||||
{
|
||||
enum lpm_mode last_mode = lpm_get();
|
||||
|
||||
/* ensure that interrupts are enabled before going to sleep,
|
||||
or we're bound to hang our MCU! */
|
||||
assert((target == LPM_ON) || (__read_status_register() & GIE));
|
||||
|
||||
switch (target) {
|
||||
case LPM_ON:
|
||||
/* fully running MCU */
|
||||
__bic_status_register(CPUOFF | OSCOFF | SCG0 | SCG1);
|
||||
break;
|
||||
case LPM_IDLE:
|
||||
/* lightest mode => LPM0 mode of MSP430 */
|
||||
__bic_status_register(OSCOFF | SCG0 | SCG1);
|
||||
/* only stops CPU block */
|
||||
__bis_status_register(CPUOFF);
|
||||
break;
|
||||
case LPM_SLEEP:
|
||||
/* mid-level mode => LPM1 mode of MSP430 */
|
||||
__bic_status_register(OSCOFF | SCG1);
|
||||
/* stops CPU and master clock blocks */
|
||||
__bis_status_register(CPUOFF | SCG0);
|
||||
break;
|
||||
case LPM_POWERDOWN:
|
||||
/* deep-level mode => LPM3 mode of MSP430 */
|
||||
__bic_status_register(OSCOFF);
|
||||
/* stops all blocks except auxiliary clock (timers) */
|
||||
__bis_status_register(CPUOFF | SCG0 | SCG1);
|
||||
break;
|
||||
case LPM_OFF:
|
||||
/* MCU totally down (LPM4), only RESET or NMI can resume execution */
|
||||
__bis_status_register(CPUOFF | OSCOFF | SCG0 | SCG1);
|
||||
/* all blocks off */
|
||||
break;
|
||||
default:
|
||||
assert(0); /* abort if NDEBUG is not defined */
|
||||
break;
|
||||
}
|
||||
|
||||
return last_mode;
|
||||
}
|
||||
|
||||
#define LPM_MASK_SR (CPUOFF | OSCOFF | SCG0 | SCG1)
|
||||
|
||||
/* Return the current LPM mode of the MSP430 MCU. */
|
||||
enum lpm_mode lpm_get(void)
|
||||
{
|
||||
enum lpm_mode current_mode = LPM_UNKNOWN;
|
||||
|
||||
unsigned int current_sr = __read_status_register();
|
||||
switch (current_sr & LPM_MASK_SR) {
|
||||
case CPUOFF + OSCOFF + SCG0 + SCG1: /* MSP430's LPM4 */
|
||||
current_mode = LPM_OFF;
|
||||
break;
|
||||
case CPUOFF + SCG0 + SCG1: /* MSP430's LPM3 */
|
||||
case CPUOFF + SCG1: /* MSP430's LPM2 */
|
||||
current_mode = LPM_POWERDOWN;
|
||||
break;
|
||||
case CPUOFF + SCG0: /* MSP430's LPM1 */
|
||||
current_mode = LPM_SLEEP;
|
||||
break;
|
||||
case CPUOFF: /* MSP430's LPM1 */
|
||||
current_mode = LPM_IDLE;
|
||||
break;
|
||||
case 0: /* MSP430 active */
|
||||
current_mode = LPM_ON;
|
||||
break;
|
||||
}
|
||||
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
/* resume the MSP430 MCU */
|
||||
inline void lpm_awake(void)
|
||||
{
|
||||
/* disable all power savings mechanisms */
|
||||
__bic_status_register(CPUOFF | OSCOFF | SCG0 | SCG1);
|
||||
}
|
||||
|
||||
/* the following two functions have no actual role to play MSP430s */
|
||||
inline void lpm_begin_awake(void) { }
|
||||
inline void lpm_end_awake(void) { }
|
@ -112,7 +112,6 @@ void msp430_cpu_init(void)
|
||||
{
|
||||
irq_disable();
|
||||
init_ports();
|
||||
// lpm_init();
|
||||
irq_enable();
|
||||
|
||||
if ((uintptr_t)cur_break & 1) { /* Workaround for msp430-ld bug!*/
|
||||
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014, 2015 INRIA
|
||||
*
|
||||
* 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_msp430_common
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Crash handling functions implementation for MSP430 MCUs
|
||||
*
|
||||
* @author Kévin Roussel <Kevin.Roussel@inria.fr>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "lpm.h"
|
||||
|
||||
void panic_arch(void)
|
||||
{
|
||||
/* disable watchdog and all possible sources of interrupts */
|
||||
WDTCTL = WDTPW | WDTHOLD;
|
||||
#ifdef DEVELHELP
|
||||
/* enter infinite loop, into deepest possible sleep mode */
|
||||
while (1) {
|
||||
lpm_set(LPM_OFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
1
cpu/native/Makefile.features
Normal file
1
cpu/native/Makefile.features
Normal file
@ -0,0 +1 @@
|
||||
FEATURES_PROVIDED += periph_pm
|
@ -37,8 +37,7 @@
|
||||
|
||||
#include "irq.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "lpm.h"
|
||||
#include "periph/pm.h"
|
||||
|
||||
#include "native_internal.h"
|
||||
|
||||
@ -448,7 +447,7 @@ static void native_shutdown(int sig, siginfo_t *info, void *context)
|
||||
(void)info;
|
||||
(void)context;
|
||||
|
||||
lpm_set(LPM_OFF);
|
||||
pm_off();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,123 +0,0 @@
|
||||
/**
|
||||
* Native CPU lpm.h implementation
|
||||
*
|
||||
* Uses system calls to emulate CPU power modes.
|
||||
*
|
||||
* Copyright (C) 2013 Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
|
||||
*
|
||||
* 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 lpm
|
||||
* @ingroup native_cpu
|
||||
* @{
|
||||
* @file
|
||||
* @author Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
|
||||
#include "lpm.h"
|
||||
#include "debug.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "native_internal.h"
|
||||
|
||||
static enum lpm_mode native_lpm;
|
||||
|
||||
void lpm_init(void)
|
||||
{
|
||||
DEBUG("lpm_init()\n");
|
||||
native_lpm = LPM_ON;
|
||||
return;
|
||||
}
|
||||
|
||||
void _native_lpm_sleep(void)
|
||||
{
|
||||
_native_in_syscall++; // no switching here
|
||||
real_pause();
|
||||
_native_in_syscall--;
|
||||
|
||||
if (_native_sigpend > 0) {
|
||||
DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n");
|
||||
_native_in_syscall++;
|
||||
_native_syscall_leave();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LPM_IDLE uses sleep() to wait for interrupts
|
||||
* LPM_OFF exits process
|
||||
* other modes not supported at the moment
|
||||
*/
|
||||
enum lpm_mode lpm_set(enum lpm_mode target)
|
||||
{
|
||||
enum lpm_mode last_lpm;
|
||||
|
||||
//DEBUG("lpm_set(%i)\n", target);
|
||||
|
||||
last_lpm = native_lpm;
|
||||
native_lpm = target;
|
||||
|
||||
switch(native_lpm) { /* @contiki :-p */
|
||||
case LPM_ON:
|
||||
break;
|
||||
|
||||
case LPM_IDLE:
|
||||
//DEBUG("lpm_set(): pause()\n");
|
||||
|
||||
//pause();
|
||||
_native_lpm_sleep();
|
||||
break;
|
||||
|
||||
/* XXX: unfinished modes: */
|
||||
case LPM_SLEEP:
|
||||
/*TODO: implement*/
|
||||
printf("XXX: lpm_set(): LPM_SLEEP not implemented\n");
|
||||
//sigsuspend();
|
||||
|
||||
case LPM_POWERDOWN:
|
||||
/*TODO: implement*/
|
||||
printf("XXX: lpm_set(): LPM_POWERDOWN not implemented\n");
|
||||
//sigsuspend();
|
||||
|
||||
case LPM_OFF:
|
||||
printf("lpm_set(): exit()\n");
|
||||
real_exit(EXIT_SUCCESS);
|
||||
|
||||
default:
|
||||
DEBUG("XXX: unsupported power mode: %i\n", native_lpm);
|
||||
real_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return last_lpm;
|
||||
}
|
||||
|
||||
void lpm_awake(void)
|
||||
{
|
||||
DEBUG("XXX: lpm_awake()\n");
|
||||
native_lpm = LPM_ON;
|
||||
return;
|
||||
}
|
||||
|
||||
void lpm_begin_awake(void)
|
||||
{
|
||||
DEBUG("XXX: lpm_begin_awake()\n");
|
||||
return;
|
||||
}
|
||||
|
||||
void lpm_end_awake(void)
|
||||
{
|
||||
DEBUG("XXX: lpm_end_awake()\n");
|
||||
native_lpm = LPM_ON;
|
||||
return;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_get(void)
|
||||
{
|
||||
return native_lpm;
|
||||
}
|
@ -1,28 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* 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.
|
||||
* 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 native_cpu
|
||||
* @ingroup native_cpu
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief native reboot() implementation
|
||||
* @brief native Power Management implementation
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "periph/pm.h"
|
||||
#include "native_internal.h"
|
||||
#include "netdev2_tap.h"
|
||||
#include "tty_uart.h"
|
||||
|
||||
void reboot(void)
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
void pm_set_lowest(void)
|
||||
{
|
||||
_native_in_syscall++; // no switching here
|
||||
real_pause();
|
||||
_native_in_syscall--;
|
||||
|
||||
if (_native_sigpend > 0) {
|
||||
_native_in_syscall++;
|
||||
_native_syscall_leave();
|
||||
}
|
||||
}
|
||||
|
||||
void pm_off(void)
|
||||
{
|
||||
puts("\nnative: exiting");
|
||||
real_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void pm_reboot(void)
|
||||
{
|
||||
printf("\n\n\t\t!! REBOOT !!\n\n");
|
||||
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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_nrf51822
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Frank Holtz <frank-riot2015@holtznet.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO: needs to be implemented */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
switch (target) {
|
||||
/* wait for next interrupt */
|
||||
case LPM_IDLE:
|
||||
case LPM_SLEEP:
|
||||
case LPM_POWERDOWN:
|
||||
__DSB();
|
||||
__WFI();
|
||||
break;
|
||||
case LPM_OFF:
|
||||
/* Switch of RAM and power off */
|
||||
NRF_POWER->RAMON = 0;
|
||||
NRF_POWER->SYSTEMOFF = 1;
|
||||
break;
|
||||
|
||||
/* do nothing here */
|
||||
case LPM_UNKNOWN:
|
||||
case LPM_ON:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO: needs to be implemented */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO: needs to be implemented */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO: needs to be implemented */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO: needs to be implemented */
|
||||
}
|
30
cpu/nrf51/periph/pm.c
Normal file
30
cpu/nrf51/periph/pm.c
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* 2014 Freie Universität 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_nrf51
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "periph/pm.h"
|
||||
#include "cpu.h"
|
||||
|
||||
void pm_off(void)
|
||||
{
|
||||
NRF_POWER->RAMON = 0;
|
||||
NRF_POWER->SYSTEMOFF = 1;
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Freie Universität 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_nrf52
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO: needs to be implemented */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
switch (target) {
|
||||
/* wait for next interrupt */
|
||||
case LPM_IDLE:
|
||||
case LPM_SLEEP:
|
||||
case LPM_POWERDOWN:
|
||||
__DSB();
|
||||
__WFI();
|
||||
break;
|
||||
|
||||
case LPM_OFF:
|
||||
NRF_POWER->SYSTEMOFF = 1;
|
||||
break;
|
||||
|
||||
/* do nothing here */
|
||||
case LPM_UNKNOWN:
|
||||
case LPM_ON:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO: needs to be implemented */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO: needs to be implemented */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO: needs to be implemented */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO: needs to be implemented */
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Freie Universität Berlin
|
||||
* 2015 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* 2016 Freie Universität 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
|
||||
@ -8,23 +8,22 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_cortexm_common
|
||||
* @ingroup cpu_nrf52
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels reboot interface
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "periph/pm.h"
|
||||
#include "cpu.h"
|
||||
|
||||
void reboot(void)
|
||||
void pm_off(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
NRF_POWER->SYSTEMOFF = 1;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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_sam3
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
(void) target;
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
// TODO
|
||||
}
|
1
cpu/samd21/Makefile.features
Normal file
1
cpu/samd21/Makefile.features
Normal file
@ -0,0 +1 @@
|
||||
FEATURES_PROVIDED += periph_pm
|
@ -1,5 +1,7 @@
|
||||
export CPU_ARCH = cortex-m0plus
|
||||
export CPU_FAM = samd21
|
||||
|
||||
USEMODULE += pm_layered
|
||||
|
||||
include $(RIOTCPU)/sam0_common/Makefile.include
|
||||
include $(RIOTCPU)/Makefile.include.cortexm_common
|
||||
|
@ -39,7 +39,7 @@ static void clk_init(void)
|
||||
|
||||
/* configure internal 8MHz oscillator to run without prescaler */
|
||||
SYSCTRL->OSC8M.bit.PRESC = 0;
|
||||
SYSCTRL->OSC8M.bit.ONDEMAND = 0;
|
||||
SYSCTRL->OSC8M.bit.ONDEMAND = 1;
|
||||
SYSCTRL->OSC8M.bit.RUNSTDBY = 0;
|
||||
SYSCTRL->OSC8M.bit.ENABLE = 1;
|
||||
while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC8MRDY)) {}
|
||||
@ -84,6 +84,14 @@ static void clk_init(void)
|
||||
/* make sure we synchronize clock generator 0 before we go on */
|
||||
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
|
||||
|
||||
/* Setup Clock generator 2 with divider 1 (32.768kHz) */
|
||||
GCLK->GENDIV.reg = (GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(0));
|
||||
GCLK->GENCTRL.reg = (GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_GENEN |
|
||||
GCLK_GENCTRL_RUNSTDBY |
|
||||
GCLK_GENCTRL_SRC_OSCULP32K);
|
||||
|
||||
while (GCLK->STATUS.bit.SYNCBUSY) {}
|
||||
|
||||
/* redirect all peripherals to a disabled clock generator (7) by default */
|
||||
for (int i = 0x3; i <= 0x22; i++) {
|
||||
GCLK->CLKCTRL.reg = ( GCLK_CLKCTRL_ID(i) | GCLK_CLKCTRL_GEN_GCLK7 );
|
||||
|
@ -102,6 +102,8 @@ static inline int _sercom_id(SercomUsart *sercom)
|
||||
return ((((uint32_t)sercom) >> 10) & 0x7) - 2;
|
||||
}
|
||||
|
||||
#define PM_NUM_MODES (3)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -138,7 +138,7 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
|
||||
PM->APBAMASK.reg |= PM_APBAMASK_EIC;
|
||||
GCLK->CLKCTRL.reg = (EIC_GCLK_ID |
|
||||
GCLK_CLKCTRL_CLKEN |
|
||||
GCLK_CLKCTRL_GEN_GCLK0);
|
||||
GCLK_CLKCTRL_GEN_GCLK2);
|
||||
while (GCLK->STATUS.bit.SYNCBUSY) {}
|
||||
/* configure the active flank */
|
||||
EIC->CONFIG[exti >> 3].reg &= ~(0xf << ((exti & 0x7) * 4));
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
* Copyright (C) 2015 Saurabh Singh
|
||||
*
|
||||
@ -16,11 +17,15 @@
|
||||
*
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
* @author Saurabh Singh <saurabh@cezy.co>
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
#include "cpu.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
#include "periph/pm.h"
|
||||
|
||||
#define ENABLE_DEBUG (1)
|
||||
#include "debug.h"
|
||||
|
||||
enum system_sleepmode {
|
||||
/**
|
||||
@ -45,82 +50,40 @@ enum system_sleepmode {
|
||||
SYSTEM_SLEEPMODE_STANDBY,
|
||||
};
|
||||
|
||||
static enum lpm_mode current_mode;
|
||||
|
||||
static void start_lpm(void);
|
||||
|
||||
|
||||
void lpm_arch_init(void)
|
||||
void pm_set(unsigned mode)
|
||||
{
|
||||
current_mode = LPM_ON;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
enum lpm_mode last_mode = current_mode;
|
||||
|
||||
switch (target) {
|
||||
case LPM_ON: /* Run mode */
|
||||
current_mode = LPM_ON;
|
||||
switch (mode) {
|
||||
case 0:
|
||||
/* Standby Mode
|
||||
* Potential Wake Up sources: asynchronous
|
||||
*/
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
break;
|
||||
case LPM_IDLE: /* Sleep mode Idle 0 */
|
||||
current_mode = LPM_IDLE;
|
||||
/* Idle Mode 0 */
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
PM->SLEEP.reg = SYSTEM_SLEEPMODE_IDLE_0;
|
||||
start_lpm();
|
||||
break;
|
||||
case LPM_SLEEP: /* Sleep mode Idle 1 */
|
||||
current_mode = LPM_SLEEP;
|
||||
/* Idle Mode 1 */
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
PM->SLEEP.reg = SYSTEM_SLEEPMODE_IDLE_1;
|
||||
start_lpm();
|
||||
break;
|
||||
case LPM_POWERDOWN: /* Sleep mode Idle 2 */
|
||||
/* Idle Mode 2 */
|
||||
current_mode = LPM_POWERDOWN;
|
||||
case 1:
|
||||
/* Sleep mode Idle 2
|
||||
* Potential Wake Up sources: asynchronous
|
||||
*/
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
PM->SLEEP.reg = SYSTEM_SLEEPMODE_IDLE_2;
|
||||
start_lpm();
|
||||
break;
|
||||
case LPM_OFF: /* Standby Mode - Potential Wake Up sources: Asynchronous */
|
||||
current_mode = LPM_OFF;
|
||||
/* Standby Mode */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
start_lpm();
|
||||
case 2:
|
||||
/* Sleep mode Idle 1
|
||||
* Potential Wake Up sources: Synchronous (APB), asynchronous
|
||||
*/
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
PM->SLEEP.reg = SYSTEM_SLEEPMODE_IDLE_1;
|
||||
break;
|
||||
default:
|
||||
case 3:
|
||||
/* Sleep mode Idle 0
|
||||
* Potential Wake Up sources: Synchronous (APB, AHB), asynchronous
|
||||
*/
|
||||
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
||||
PM->SLEEP.reg = SYSTEM_SLEEPMODE_IDLE_0;
|
||||
break;
|
||||
}
|
||||
|
||||
return last_mode;
|
||||
}
|
||||
|
||||
static void start_lpm(void)
|
||||
{
|
||||
/* Executes a device DSB (Data Synchronization Barrier) */
|
||||
__DSB();
|
||||
/* Enter standby mode */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
if (current_mode == LPM_SLEEP) {
|
||||
/* Re-init */
|
||||
cpu_init();
|
||||
}
|
||||
current_mode = LPM_ON;
|
||||
}
|
||||
|
||||
/** Not needed */
|
||||
void lpm_arch_begin_awake(void){ }
|
||||
|
||||
/** Not needed */
|
||||
void lpm_arch_end_awake(void){ }
|
1
cpu/saml21/Makefile.features
Normal file
1
cpu/saml21/Makefile.features
Normal file
@ -0,0 +1 @@
|
||||
FEATURES_PROVIDED += periph_pm
|
@ -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
|
||||
|
@ -18,8 +18,6 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
static void _gclk_setup(int gclk, uint32_t reg)
|
||||
@ -68,6 +66,4 @@ void cpu_init(void)
|
||||
/* Setup GCLK generators */
|
||||
_gclk_setup(0, GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC16M);
|
||||
_gclk_setup(1, GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K);
|
||||
|
||||
lpm_arch_init();
|
||||
}
|
||||
|
@ -60,6 +60,8 @@ typedef enum {
|
||||
/** @} */
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
#define PM_NUM_MODES (3)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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_saml21
|
||||
* @{
|
||||
*
|
||||
* @file lpm_arch.c
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lpm.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
MCLK->APBAMASK.reg |= MCLK_APBAMASK_PM;
|
||||
PM->CTRLA.reg = PM_CTRLA_MASK & (~PM_CTRLA_IORET);
|
||||
|
||||
SUPC->BOD33.bit.ENABLE=0;
|
||||
|
||||
lpm_prevent_sleep = 1;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
uint32_t mode;
|
||||
switch(target) {
|
||||
case LPM_IDLE:
|
||||
DEBUG("lpm_arch_set(): setting IDLE mode.\n");
|
||||
mode = PM_SLEEPCFG_SLEEPMODE_IDLE2;
|
||||
break;
|
||||
case LPM_SLEEP:
|
||||
DEBUG("lpm_arch_set(): setting STANDBY mode.\n");
|
||||
mode = PM_SLEEPCFG_SLEEPMODE_STANDBY;
|
||||
break;
|
||||
case LPM_POWERDOWN:
|
||||
DEBUG("lpm_arch_set(): setting BACKUP mode.\n");
|
||||
mode = PM_SLEEPCFG_SLEEPMODE_BACKUP;
|
||||
break;
|
||||
default:
|
||||
DEBUG("lpm_arch_set(): unhandled low-power mode.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* write sleep configuration */
|
||||
PM->SLEEPCFG.bit.SLEEPMODE = mode;
|
||||
|
||||
/* make sure value has been set */
|
||||
while (PM->SLEEPCFG.bit.SLEEPMODE != mode) {}
|
||||
|
||||
/* ensure all memory accesses have completed */
|
||||
__DSB();
|
||||
|
||||
/* go to sleep mode (issue wait-for-interrupt instruction) */
|
||||
__WFI();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
// TODO
|
||||
}
|
56
cpu/saml21/periph/pm.c
Normal file
56
cpu/saml21/periph/pm.c
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* 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 <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#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();
|
||||
}
|
@ -44,6 +44,13 @@ extern "C" {
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REGS
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Number of usable low power modes
|
||||
*/
|
||||
#if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || defined(DOXYGEN)
|
||||
#define PM_NUM_MODES (2U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Available peripheral buses
|
||||
*/
|
||||
@ -62,6 +69,7 @@ typedef enum {
|
||||
#endif
|
||||
} bus_t;
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/**
|
||||
* @brief Overwrite the default gpio_t type definition
|
||||
* @{
|
||||
@ -69,6 +77,7 @@ typedef enum {
|
||||
#define HAVE_GPIO_T
|
||||
typedef uint32_t gpio_t;
|
||||
/** @} */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Definition of a fitting UNDEF value
|
||||
|
71
cpu/stm32_common/periph/pm.c
Normal file
71
cpu/stm32_common/periph/pm.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* 2015 Freie Universität Berlin
|
||||
* 2015 Engineering-Spirit
|
||||
*
|
||||
* 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_stm32
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Nick v. IJzendoorn <nijzndoorn@engineering-spirit.nl>
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @author Fabian Nack <nack@inf.fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "irq.h"
|
||||
#include "periph/pm.h"
|
||||
|
||||
#define ENABLE_DEBUG (1)
|
||||
#include "debug.h"
|
||||
|
||||
void pm_set(unsigned mode)
|
||||
{
|
||||
/* I just copied it from stm32f1/2/4, but I suppose it would work for the
|
||||
* others... /KS */
|
||||
#if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4)
|
||||
switch (mode) {
|
||||
case 0:
|
||||
/* Set PDDS to enter standby mode on deepsleep and clear flags */
|
||||
PWR->CR |= (PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF);
|
||||
/* Enable WKUP pin to use for wakeup from standby mode */
|
||||
PWR->CSR |= PWR_CSR_EWUP;
|
||||
/* Set SLEEPDEEP bit of system control block */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
break;
|
||||
case 1: /* STM Stop mode */
|
||||
/* Clear PDDS and LPDS bits to enter stop mode on */
|
||||
/* deepsleep with voltage regulator on */
|
||||
PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS);
|
||||
/* Set SLEEPDEEP bit of system control block */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
break;
|
||||
case 2: /* STM Sleep mode */
|
||||
/* Reset SLEEPDEEP bit of system control block */
|
||||
SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Executes a device DSB (Data Synchronization Barrier) */
|
||||
__DSB();
|
||||
/* Enter standby mode */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
#if defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4)
|
||||
void pm_off(void)
|
||||
{
|
||||
irq_disable();
|
||||
pm_set(0);
|
||||
}
|
||||
#endif
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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_stm32f0
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO*/
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
1
cpu/stm32f1/Makefile.features
Normal file
1
cpu/stm32f1/Makefile.features
Normal file
@ -0,0 +1 @@
|
||||
FEATURES_PROVIDED += periph_pm
|
@ -1,5 +1,7 @@
|
||||
export CPU_ARCH = cortex-m3
|
||||
export CPU_FAM = stm32f1
|
||||
|
||||
USEMODULE += pm_layered
|
||||
|
||||
include $(RIOTCPU)/stm32_common/Makefile.include
|
||||
include $(RIOTCPU)/Makefile.include.cortexm_common
|
||||
|
@ -123,6 +123,8 @@ typedef struct {
|
||||
uint8_t chan; /**< DAC device used for this line */
|
||||
} dac_conf_t;
|
||||
|
||||
#define PM_NUM_MODES (2U)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Engineering-Spirit
|
||||
*
|
||||
* 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_stm32f1
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Nick v. IJzendoorn <nijzndoorn@engineering-spirit.nl>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
static enum lpm_mode current_mode = LPM_UNKNOWN;
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
current_mode = LPM_ON;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
enum lpm_mode last_mode = current_mode;
|
||||
|
||||
switch (target) {
|
||||
case LPM_ON: /* STM Run mode */
|
||||
current_mode = LPM_ON;
|
||||
break;
|
||||
case LPM_IDLE: /* STM Sleep mode */
|
||||
current_mode = LPM_IDLE;
|
||||
/* Reset SLEEPDEEP bit of system control block */
|
||||
SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
|
||||
/* Enter sleep mode */
|
||||
__WFI();
|
||||
break;
|
||||
case LPM_SLEEP: /* STM Stop mode */
|
||||
current_mode = LPM_SLEEP;
|
||||
/* Clear PDDS and LPDS bits to enter stop mode on */
|
||||
/* deepsleep with voltage regulator on */
|
||||
PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS);
|
||||
/* Set SLEEPDEEP bit of system control block */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
/* Enter stop mode */
|
||||
__WFI();
|
||||
break;
|
||||
case LPM_POWERDOWN: /* STM Standby mode */
|
||||
/* Fall-through */
|
||||
case LPM_OFF: /* STM Standby mode */
|
||||
current_mode = LPM_POWERDOWN;
|
||||
/* Set PDDS to enter standby mode on deepsleep and clear flags */
|
||||
PWR->CR |= (PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF);
|
||||
/* Enable WKUP pin to use for wakeup from standby mode */
|
||||
PWR->CSR |= PWR_CSR_EWUP;
|
||||
/* Set SLEEPDEEP bit of system control block */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
#if defined ( __CC_ARM )
|
||||
/* Ensure that store operations are completed */
|
||||
__force_stores();
|
||||
#endif
|
||||
/* Enter standby mode */
|
||||
__WFI();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return last_mode;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
if (current_mode == LPM_SLEEP) {
|
||||
/* After stop mode, the clock system needs to be reconfigured */
|
||||
cpu_init();
|
||||
}
|
||||
current_mode = LPM_ON;
|
||||
}
|
||||
|
||||
/** Not provided */
|
||||
inline void lpm_arch_begin_awake(void) { }
|
||||
|
||||
/** Not provided */
|
||||
inline void lpm_arch_end_awake(void) { }
|
1
cpu/stm32f2/Makefile.features
Normal file
1
cpu/stm32f2/Makefile.features
Normal file
@ -0,0 +1 @@
|
||||
FEATURES_PROVIDED += periph_pm
|
@ -1,5 +1,7 @@
|
||||
export CPU_ARCH = cortex-m3
|
||||
export CPU_FAM = stm32f2
|
||||
|
||||
USEMODULE += pm_layered
|
||||
|
||||
include $(RIOTCPU)/stm32_common/Makefile.include
|
||||
include $(RIOTCPU)/Makefile.include.cortexm_common
|
||||
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Engineering-Spirit
|
||||
*
|
||||
* 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_stm32f2
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Nick v. IJzendoorn <nijzndoorn@engineering-spirit.nl>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
static enum lpm_mode current_mode = LPM_UNKNOWN;
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
current_mode = LPM_ON;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
enum lpm_mode last_mode = current_mode;
|
||||
|
||||
switch (target) {
|
||||
case LPM_ON: /* STM Run mode */
|
||||
current_mode = LPM_ON;
|
||||
break;
|
||||
case LPM_IDLE: /* STM Sleep mode */
|
||||
current_mode = LPM_IDLE;
|
||||
/* Reset SLEEPDEEP bit of system control block */
|
||||
SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
|
||||
/* Enter sleep mode */
|
||||
__WFI();
|
||||
break;
|
||||
case LPM_SLEEP: /* STM Stop mode */
|
||||
current_mode = LPM_SLEEP;
|
||||
/* Clear PDDS and LPDS bits to enter stop mode on */
|
||||
/* deepsleep with voltage regulator on */
|
||||
PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS);
|
||||
/* Set SLEEPDEEP bit of system control block */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
/* Enter stop mode */
|
||||
__WFI();
|
||||
break;
|
||||
case LPM_POWERDOWN: /* STM Standby mode */
|
||||
/* Fall-through */
|
||||
case LPM_OFF: /* STM Standby mode */
|
||||
current_mode = LPM_POWERDOWN;
|
||||
/* Set PDDS to enter standby mode on deepsleep and clear flags */
|
||||
PWR->CR |= (PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF);
|
||||
/* Enable WKUP pin to use for wakeup from standby mode */
|
||||
PWR->CSR |= PWR_CSR_EWUP;
|
||||
/* Set SLEEPDEEP bit of system control block */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
#if defined ( __CC_ARM )
|
||||
/* Ensure that store operations are completed */
|
||||
__force_stores();
|
||||
#endif
|
||||
/* Enter standby mode */
|
||||
__WFI();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return last_mode;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
if (current_mode == LPM_SLEEP) {
|
||||
/* After stop mode, the clock system needs to be reconfigured */
|
||||
cpu_init();
|
||||
}
|
||||
current_mode = LPM_ON;
|
||||
}
|
||||
|
||||
/** Not provided */
|
||||
inline void lpm_arch_begin_awake(void) { }
|
||||
|
||||
/** Not provided */
|
||||
inline void lpm_arch_end_awake(void) { }
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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_stm32f3
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
1
cpu/stm32f4/Makefile.features
Normal file
1
cpu/stm32f4/Makefile.features
Normal file
@ -0,0 +1 @@
|
||||
FEATURES_PROVIDED += periph_pm
|
@ -1,5 +1,7 @@
|
||||
export CPU_ARCH = cortex-m4f
|
||||
export CPU_FAM = stm32f4
|
||||
|
||||
USEMODULE += pm_layered
|
||||
|
||||
include $(RIOTCPU)/stm32_common/Makefile.include
|
||||
include $(RIOTCPU)/Makefile.include.cortexm_common
|
||||
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität 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_stm32f4
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernels power management interface
|
||||
*
|
||||
* @author Fabian Nack <nack@inf.fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
static enum lpm_mode current_mode = LPM_UNKNOWN;
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
current_mode = LPM_ON;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
enum lpm_mode last_mode = current_mode;
|
||||
|
||||
switch (target) {
|
||||
case LPM_ON: /* STM Run mode */
|
||||
current_mode = LPM_ON;
|
||||
break;
|
||||
case LPM_IDLE: /* STM Sleep mode */
|
||||
current_mode = LPM_IDLE;
|
||||
/* Reset SLEEPDEEP bit of system control block */
|
||||
SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
|
||||
/* Enter sleep mode */
|
||||
__WFI();
|
||||
break;
|
||||
case LPM_SLEEP: /* STM Stop mode */
|
||||
current_mode = LPM_SLEEP;
|
||||
/* Clear PDDS and LPDS bits to enter stop mode on */
|
||||
/* deepsleep with voltage regulator on */
|
||||
PWR->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS);
|
||||
/* Set SLEEPDEEP bit of system control block */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
/* Enter stop mode */
|
||||
__WFI();
|
||||
break;
|
||||
case LPM_POWERDOWN: /* STM Standby mode */
|
||||
/* Fall-through */
|
||||
case LPM_OFF: /* STM Standby mode */
|
||||
current_mode = LPM_POWERDOWN;
|
||||
/* Set PDDS to enter standby mode on deepsleep and clear flags */
|
||||
PWR->CR |= (PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF);
|
||||
/* Enable WKUP pin to use for wakeup from standby mode */
|
||||
PWR->CSR |= PWR_CSR_EWUP;
|
||||
/* Set SLEEPDEEP bit of system control block */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
#if defined ( __CC_ARM )
|
||||
/* Ensure that store operations are completed */
|
||||
__force_stores();
|
||||
#endif
|
||||
/* Enter standby mode */
|
||||
__WFI();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return last_mode;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
if (current_mode == LPM_SLEEP) {
|
||||
/* After stop mode, the clock system needs to be reconfigured */
|
||||
cpu_init();
|
||||
}
|
||||
current_mode = LPM_ON;
|
||||
}
|
||||
|
||||
/** Not provided */
|
||||
inline void lpm_arch_begin_awake(void) { }
|
||||
|
||||
/** Not provided */
|
||||
inline void lpm_arch_end_awake(void) { }
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität 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_stm32l1
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the kernel's lpm interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "arch/lpm_arch.h"
|
||||
|
||||
void lpm_arch_init(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_set(enum lpm_mode target)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum lpm_mode lpm_arch_get(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpm_arch_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_begin_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void lpm_arch_end_awake(void)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
export USEMODULE += quad_math
|
||||
export USEMODULE += periph_common
|
||||
export USEPKG += tlsf
|
||||
|
41
cpu/x86/include/periph_cpu.h
Normal file
41
cpu/x86/include/periph_cpu.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* stub for x86 periph configuration
|
||||
*
|
||||
* @ingroup x86
|
||||
* @{
|
||||
* @file
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#ifndef PERIPH_CONF_
|
||||
#define PERIPH_CONF_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PERIPH_CONF_ */
|
||||
|
||||
/** @} */
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 INRIA
|
||||
*
|
||||
* 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 x86_cpu
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Crash handling functions implementation for x86 port
|
||||
*
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*/
|
||||
|
||||
#include "x86_reboot.h"
|
||||
#include "lpm.h"
|
||||
|
||||
void panic_arch(void)
|
||||
{
|
||||
#if DEVELHELP
|
||||
/* enter infinite loop, into deepest possible sleep mode */
|
||||
while (1) {
|
||||
lpm_set(LPM_OFF);
|
||||
}
|
||||
#else
|
||||
x86_shutdown();
|
||||
#endif
|
||||
}
|
@ -33,6 +33,7 @@
|
||||
#include "x86_interrupts.h"
|
||||
#include "x86_ports.h"
|
||||
#include "x86_reboot.h"
|
||||
#include "periph/pm.h"
|
||||
|
||||
#define KBC_DATA (0x60)
|
||||
#define KBC_STATUS (0x64)
|
||||
@ -86,7 +87,7 @@ void NORETURN x86_kbc_reboot(void)
|
||||
static x86_reboot_t reboot_fun;
|
||||
static bool reboot_twice;
|
||||
|
||||
void reboot(void)
|
||||
void pm_reboot(void)
|
||||
{
|
||||
__asm__ volatile ("cli");
|
||||
if (!reboot_twice) {
|
||||
@ -98,6 +99,11 @@ void reboot(void)
|
||||
x86_kbc_reboot();
|
||||
}
|
||||
|
||||
void pm_off(void)
|
||||
{
|
||||
x86_shutdown();
|
||||
}
|
||||
|
||||
void x86_set_reboot_fun(x86_reboot_t fun)
|
||||
{
|
||||
reboot_fun = fun;
|
||||
|
58
drivers/include/periph/pm.h
Normal file
58
drivers/include/periph/pm.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_periph_pm Power Management
|
||||
* @ingroup drivers_periph
|
||||
* @brief The kernels power management interface
|
||||
* @{
|
||||
*
|
||||
* The following functions *must* be available for every platform:
|
||||
*
|
||||
* pm_reboot()
|
||||
* pm_off()
|
||||
*
|
||||
* @file
|
||||
* @brief Power management interface
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#ifndef PM_H_
|
||||
#define PM_H_
|
||||
|
||||
#include "assert.h"
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Reboot MCU
|
||||
*/
|
||||
void pm_reboot(void);
|
||||
|
||||
/**
|
||||
* @brief Turn off MCU completely
|
||||
*/
|
||||
void pm_off(void);
|
||||
|
||||
/**
|
||||
* @brief Switches the MCU to the lowest possible power mode
|
||||
*
|
||||
* This function will be called by the idle thread.
|
||||
*/
|
||||
void pm_set_lowest(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PM_H_ */
|
||||
/** @} */
|
33
drivers/periph_common/pm.c
Normal file
33
drivers/periph_common/pm.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* 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 drivers_periph_pm
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Platform-independent power management fallback code
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "irq.h"
|
||||
#include "periph/pm.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
void __attribute__((weak)) pm_set_lowest(void) {}
|
||||
|
||||
void __attribute__((weak)) pm_off(void)
|
||||
{
|
||||
irq_disable();
|
||||
while(1) {};
|
||||
}
|
75
sys/include/pm_layered.h
Normal file
75
sys/include/pm_layered.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* 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 drivers_periph_pm
|
||||
* @{
|
||||
*
|
||||
* This module provides a base infrastructure that MCU's may use to implement
|
||||
* periph/pm.
|
||||
*
|
||||
* This simple power management interface is based on the following assumptions:
|
||||
*
|
||||
* - CPUs define up to 4 power modes (from zero, the lowest power mode, to
|
||||
* PM_NUM_MODES-1, the highest)
|
||||
* - there is an implicit extra idle mode (which has the number PM_NUM_MODES)
|
||||
* - individual power modes can be blocked/unblocked, e.g., by peripherals
|
||||
* - if a mode is blocked, so are implicitly all lower modes
|
||||
* - the idle thread automatically selects and sets the lowest unblocked mode
|
||||
*
|
||||
* In order to use this module, you'll need to implement pm_set().
|
||||
*
|
||||
* @file
|
||||
* @brief Layered low power mode infrastructure
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#ifndef PM_LAYERED_H_
|
||||
#define PM_LAYERED_H_
|
||||
|
||||
#include "assert.h"
|
||||
#include "periph/pm.h"
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Block a power mode
|
||||
*
|
||||
* @param[in] mode power mode to block
|
||||
*/
|
||||
void pm_block(unsigned mode);
|
||||
|
||||
/**
|
||||
* @brief Unblock a power mode
|
||||
*
|
||||
* @param[in] mode power mode to unblock
|
||||
*/
|
||||
void pm_unblock(unsigned mode);
|
||||
|
||||
/**
|
||||
* @brief Switches the MCU to a new power mode
|
||||
*
|
||||
* This function will be called by @ref pm_set_lowest() after determining the
|
||||
* lowest non-blocked mode.
|
||||
*
|
||||
* It needs to be implemented for each MCU using this module.
|
||||
*
|
||||
* @param[in] mode Target power mode
|
||||
*/
|
||||
void pm_set(unsigned mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PM_LAYERED_H_ */
|
||||
/** @} */
|
1
sys/pm_layered/Makefile
Normal file
1
sys/pm_layered/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
95
sys/pm_layered/pm.c
Normal file
95
sys/pm_layered/pm.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* 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 drivers_periph_pm
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Platform-independent power management code
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "irq.h"
|
||||
#include "periph/pm.h"
|
||||
#include "pm_layered.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#ifndef PM_NUM_MODES
|
||||
#error PM_NUM_MODES must be defined in periph_cpu.h!
|
||||
#endif
|
||||
|
||||
#ifndef PM_BLOCKER_INITIAL
|
||||
#define PM_BLOCKER_INITIAL { .val_u32=0x01010101 }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Power Management mode typedef
|
||||
*/
|
||||
typedef union {
|
||||
uint32_t val_u32;
|
||||
uint8_t val_u8[PM_NUM_MODES];
|
||||
} pm_blocker_t;
|
||||
|
||||
/**
|
||||
* @brief Global variable for keeping track of blocked modes
|
||||
*/
|
||||
volatile pm_blocker_t pm_blocker = PM_BLOCKER_INITIAL;
|
||||
|
||||
void pm_set_lowest(void)
|
||||
{
|
||||
pm_blocker_t blocker = (pm_blocker_t) pm_blocker;
|
||||
unsigned mode = PM_NUM_MODES;
|
||||
while (mode) {
|
||||
if (blocker.val_u8[mode-1]) {
|
||||
break;
|
||||
}
|
||||
mode--;
|
||||
}
|
||||
|
||||
/* set lowest mode if blocker is still the same */
|
||||
unsigned state = irq_disable();
|
||||
if (blocker.val_u32 == pm_blocker.val_u32) {
|
||||
DEBUG("pm: setting mode %u\n", mode);
|
||||
pm_set(mode);
|
||||
}
|
||||
else {
|
||||
DEBUG("pm: mode block changed\n");
|
||||
}
|
||||
irq_restore(state);
|
||||
}
|
||||
|
||||
void pm_block(unsigned mode)
|
||||
{
|
||||
assert(pm_blocker.val_u8[mode] != 255);
|
||||
|
||||
unsigned state = irq_disable();
|
||||
pm_blocker.val_u8[mode]++;
|
||||
irq_restore(state);
|
||||
}
|
||||
|
||||
void pm_unblock(unsigned mode)
|
||||
{
|
||||
assert(pm_blocker.val_u8[mode] > 0);
|
||||
|
||||
unsigned state = irq_disable();
|
||||
pm_blocker.val_u8[mode]--;
|
||||
irq_restore(state);
|
||||
}
|
||||
|
||||
void __attribute__((weak)) pm_off(void)
|
||||
{
|
||||
pm_blocker.val_u32 = 0;
|
||||
pm_set_lowest();
|
||||
while(1);
|
||||
}
|
@ -23,7 +23,6 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include "thread.h"
|
||||
#include "lpm.h"
|
||||
|
||||
/* One stack for all threads. DON'T TRY THIS AT HOME!! */
|
||||
static char dummy_stack[THREAD_STACKSIZE_DEFAULT];
|
||||
@ -49,6 +48,6 @@ int main(void)
|
||||
if (-EOVERFLOW == thr_id) {
|
||||
puts("Thread creation successful aborted\n");
|
||||
}
|
||||
lpm_set(LPM_OFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "map.h"
|
||||
|
||||
#include "embUnit.h"
|
||||
#include "lpm.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#define UNCURRY(FUN, ARGS) FUN(ARGS)
|
||||
|
Loading…
Reference in New Issue
Block a user