diff --git a/arch/arm/src/armv7-m/up_itm.c b/arch/arm/src/armv7-m/up_itm.c index 661f571203..e25cd20532 100644 --- a/arch/arm/src/armv7-m/up_itm.c +++ b/arch/arm/src/armv7-m/up_itm.c @@ -93,7 +93,7 @@ * ch - Character to transmit. * * Returned Value: - * Character to transmit. + * Character to transmit. * *****************************************************************************/ @@ -141,11 +141,12 @@ int32_t itm_receivechar(void) * Description: * * Input Parameters: - * The function checks whether a character is pending for reading in the variable g_itm_rxbuffer. + * The function checks whether a character is pending for reading in the + * variable g_itm_rxbuffer. * * Returned Value: - * 0 No character available. - * 1 Character available. + * 0 No character available. + * 1 Character available. * *****************************************************************************/ diff --git a/arch/arm/src/efm32/efm32_idle.c b/arch/arm/src/efm32/efm32_idle.c index 7b525bbe3e..327140dfa0 100644 --- a/arch/arm/src/efm32/efm32_idle.c +++ b/arch/arm/src/efm32/efm32_idle.c @@ -40,6 +40,8 @@ #include #include +#include + #include #include @@ -47,6 +49,7 @@ #include "chip.h" #include "up_internal.h" +#include "efm32_pm.h" /**************************************************************************** * Pre-processor Definitions @@ -72,6 +75,85 @@ * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: up_idlepm + * + * Description: + * Perform IDLE state power management. + * + * REVISIT: These power management hooks were taken with no modification + * from the STM32 implementation and need review against EFM32 reduced + * power modes. + * + ****************************************************************************/ + +#ifdef CONFIG_PM +static void up_idlepm(void) +{ + static enum pm_state_e oldstate = PM_NORMAL; + enum pm_state_e newstate; + irqstate_t flags; + int ret; + + /* Decide, which power saving level can be obtained */ + + newstate = pm_checkstate(); + + /* Check for state changes */ + + if (newstate != oldstate) + { + flags = irqsave(); + + /* Perform board-specific, state-dependent logic here */ + + llvdbg("newstate= %d oldstate=%d\n", newstate, oldstate); + + /* Then force the global state change */ + + ret = pm_changestate(newstate); + if (ret < 0) + { + /* The new state change failed, revert to the preceding state */ + + (void)pm_changestate(oldstate); + } + else + { + /* Save the new state */ + + oldstate = newstate; + } + + /* MCU-specific power management logic */ + + switch (newstate) + { + case PM_NORMAL: + break; + + case PM_IDLE: + break; + + case PM_STANDBY: + efm32_pmstop(true); + break; + + case PM_SLEEP: + (void)efm32_pmstandby(); + break; + + default: + break; + } + + irqrestore(flags); + } +} +#else +# define up_idlepm() +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -92,5 +174,12 @@ void up_idle(void) { /* Perform IDLE mode power management */ + + up_idlepm(); + /* Sleep until an interrupt occurs to save power. */ + + BEGIN_IDLE(); + asm("WFI"); + END_IDLE(); } diff --git a/arch/arm/src/efm32/efm32_pm.h b/arch/arm/src/efm32/efm32_pm.h new file mode 100644 index 0000000000..ec56547a0e --- /dev/null +++ b/arch/arm/src/efm32/efm32_pm.h @@ -0,0 +1,155 @@ +/************************************************************************************ + * arch/arm/src/efm32/efm32_pm.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_EFM32_EFM32_PM_H +#define __ARCH_ARM_SRC_EFM32_EFM32_PM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" +#include "up_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + + #ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: efm32_pmstop + * + * Description: + * Enter STOP mode. + * + * REVISIT: This power management interface was taken with no modification + * from the STM32 implementation and needs to be reviewed against EFM32 + * reduced power modes. Comments here apply to the STM32! + * + * Input Parameters: + * lpds - true: To further reduce power consumption in Stop mode, put the + * internal voltage regulator in low-power mode using the LPDS bit + * of the Power control register (PWR_CR). + * + * Returned Value: + * Zero means that the STOP was successfully entered and the system has + * been re-awakened. The internal voltage regulator is back to its + * original state. Otherwise, STOP mode did not occur and a negated + * errno value is returned to indicate the cause of the failure. + * + ****************************************************************************/ + +int efm32_pmstop(bool lpds); + +/**************************************************************************** + * Name: efm32_pmstandby + * + * Description: + * Enter STANDBY mode. + * + * REVISIT: This power management interface was taken with no modification + * from the STM32 implementation and needs to be reviewed against EFM32 + * reduced power modes. Comments here apply to the STM32! + * + * Input Parameters: + * None + * + * Returned Value. + * On success, this function will not return (STANDBY mode can only be + * terminated with a reset event). Otherwise, STANDBY mode did not occur + * and a negated errno value is returned to indicate the cause of the + * failure. + * + ****************************************************************************/ + +int efm32_pmstandby(void); + +/**************************************************************************** + * Name: efm32_pmsleep + * + * Description: + * Enter SLEEP mode. + * + * REVISIT: This power management interface was taken with no modification + * from the STM32 implementation and needs to be reviewed against EFM32 + * reduced power modes. Comments here apply to the STM32! + * + * Input Parameters: + * sleeponexit - true: SLEEPONEXIT bit is set when the WFI instruction is + * executed, the MCU enters Sleep mode as soon as it + * exits the lowest priority ISR. + * - false: SLEEPONEXIT bit is cleared, the MCU enters Sleep mode + * as soon as WFI or WFE instruction is executed. + * Returned Value: + * Zero means that the STOP was successfully entered and the system has + * been re-awakened. The internal voltage regulator is back to its + * original state. Otherwise, STOP mode did not occur and a negated + * errno value is returned to indicate the cause of the failure. + * + ****************************************************************************/ + +void efm32_pmsleep(bool sleeponexit); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_EFM32_EFM32_PM_H */ diff --git a/arch/arm/src/stm32/stm32_idle.c b/arch/arm/src/stm32/stm32_idle.c index 2b5de78aaa..e9e12e648b 100644 --- a/arch/arm/src/stm32/stm32_idle.c +++ b/arch/arm/src/stm32/stm32_idle.c @@ -211,4 +211,3 @@ void up_idle(void) #endif #endif } - diff --git a/arch/arm/src/stm32/stm32_pm.h b/arch/arm/src/stm32/stm32_pm.h index d6dbe52453..88e06fa9d8 100644 --- a/arch/arm/src/stm32/stm32_pm.h +++ b/arch/arm/src/stm32/stm32_pm.h @@ -62,7 +62,8 @@ #ifndef __ASSEMBLY__ #ifdef __cplusplus #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif @@ -84,13 +85,13 @@ extern "C" { * * Returned Value: * Zero means that the STOP was successfully entered and the system has - * been re-awakened. The internal volatage regulator is back to its + * been re-awakened. The internal voltage regulator is back to its * original state. Otherwise, STOP mode did not occur and a negated * errno value is returned to indicate the cause of the failure. * ****************************************************************************/ -EXTERN int stm32_pmstop(bool lpds); +int stm32_pmstop(bool lpds); /**************************************************************************** * Name: stm32_pmstandby @@ -109,7 +110,7 @@ EXTERN int stm32_pmstop(bool lpds); * ****************************************************************************/ -EXTERN int stm32_pmstandby(void); +int stm32_pmstandby(void); /**************************************************************************** * Name: stm32_pmsleep @@ -125,13 +126,13 @@ EXTERN int stm32_pmstandby(void); * as soon as WFI or WFE instruction is executed. * Returned Value: * Zero means that the STOP was successfully entered and the system has - * been re-awakened. The internal volatage regulator is back to its + * been re-awakened. The internal voltage regulator is back to its * original state. Otherwise, STOP mode did not occur and a negated * errno value is returned to indicate the cause of the failure. * ****************************************************************************/ -EXTERN void stm32_pmsleep(bool sleeponexit); +void stm32_pmsleep(bool sleeponexit); #undef EXTERN #ifdef __cplusplus diff --git a/drivers/power/battery.c b/drivers/power/battery.c index d093ce7d69..b26fe6c6b9 100644 --- a/drivers/power/battery.c +++ b/drivers/power/battery.c @@ -249,6 +249,7 @@ int battery_register(FAR const char *devpath, FAR struct battery_dev_s *dev) { dbg("Failed to register driver: %d\n", ret); } + return ret; } #endif /* CONFIG_BATTERY */