|
|
|
@ -1,5 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2014 Freie Universität Berlin |
|
|
|
|
* 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 |
|
|
|
@ -13,41 +13,86 @@
|
|
|
|
|
* @file |
|
|
|
|
* @brief Implementation of the kernels power management interface |
|
|
|
|
* |
|
|
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de> |
|
|
|
|
* @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) |
|
|
|
|
{ |
|
|
|
|
/* TODO */ |
|
|
|
|
current_mode = LPM_ON; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum lpm_mode lpm_arch_set(enum lpm_mode target) |
|
|
|
|
{ |
|
|
|
|
/* TODO */ |
|
|
|
|
return 0; |
|
|
|
|
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) |
|
|
|
|
{ |
|
|
|
|
/* TODO */ |
|
|
|
|
return 0; |
|
|
|
|
return current_mode; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void lpm_arch_awake(void) |
|
|
|
|
{ |
|
|
|
|
/* TODO */ |
|
|
|
|
if (current_mode == LPM_SLEEP) { |
|
|
|
|
/* After stop mode, the clock system needs to be reconfigured */ |
|
|
|
|
cpu_init(); |
|
|
|
|
} |
|
|
|
|
current_mode = LPM_ON; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void lpm_arch_begin_awake(void) |
|
|
|
|
{ |
|
|
|
|
/* TODO */ |
|
|
|
|
} |
|
|
|
|
/** Not provided */ |
|
|
|
|
inline void lpm_arch_begin_awake(void) { } |
|
|
|
|
|
|
|
|
|
void lpm_arch_end_awake(void) |
|
|
|
|
{ |
|
|
|
|
/* TODO */ |
|
|
|
|
} |
|
|
|
|
/** Not provided */ |
|
|
|
|
inline void lpm_arch_end_awake(void) { } |
|
|
|
|