Browse Source

cpu/stm32f4: Add low power mode implementation

dev/timer
Fabian Nack 8 years ago
parent
commit
36025280de
  1. 77
      cpu/stm32f4/lpm_arch.c

77
cpu/stm32f4/lpm_arch.c

@ -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) { }

Loading…
Cancel
Save