Skip to content

Commit

Permalink
cpu/stm32f4: Add low power mode implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
fnack committed Feb 11, 2015
1 parent a0c4c89 commit 3602528
Showing 1 changed file with 61 additions and 16 deletions.
77 changes: 61 additions & 16 deletions 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
Expand All @@ -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) { }

0 comments on commit 3602528

Please sign in to comment.