PM update

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4982 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-07-27 00:14:38 +00:00
parent 4c73d8338b
commit 0030f6a75f
3 changed files with 90 additions and 14 deletions

View File

@ -468,6 +468,7 @@ CONFIG_SCHED_ATEXIT=n
CONFIG_PM=y CONFIG_PM=y
CONFIG_PM_CUSTOMINIT=y CONFIG_PM_CUSTOMINIT=y
CONFIG_IDLE_CUSTOM=y CONFIG_IDLE_CUSTOM=y
CONFIG_PM_SLEEP_WAKEUP=n
# #
# Board/Application-Specific Power Management Configuration. # Board/Application-Specific Power Management Configuration.

View File

@ -74,16 +74,50 @@
# define END_IDLE() # define END_IDLE()
#endif #endif
/* Values for the RTC Alarm to wake up from the PM_STANDBY mode */ /* Values for the RTC Alarm to wake up from the PM_STANDBY mode
* (which corresponds to STM32 stop mode). If this alarm expires,
* the logic in this file will wakeup from PM_STANDBY mode and
* transition to PM_SLEEP mode (STM32 standby mode).
*/
#ifndef CONFIG_PM_ALARM_SEC #ifndef CONFIG_PM_ALARM_SEC
# define CONFIG_PM_ALARM_SEC 3 # define CONFIG_PM_ALARM_SEC 15
#endif #endif
#ifndef CONFIG_PM_ALARM_NSEC #ifndef CONFIG_PM_ALARM_NSEC
# define CONFIG_PM_ALARM_NSEC 0 # define CONFIG_PM_ALARM_NSEC 0
#endif #endif
/* Values for the RTC Alarm to reset from the PM_SLEEP mode (STM32
* standby mode). If CONFIG_PM_SLEEP_WAKEUP is defined in the
* configuration, then the logic in this file will program the RTC
* alarm to wakeup the processor after an a delay.
*
* This feature might be useful, for example, in a system that needs to
* use minimal power but awake up to perform some task at periodic
* intervals.
*/
#ifdef CONFIG_PM_SLEEP_WAKEUP
# ifndef CONFIG_RTC_ALARM
# error "CONFIG_RTC_ALARM should be enabled to use CONFIG_PM_SLEEP_WAKEUP"
# endif
/* If CONFIG_PM_SLEEP_WAKEUP is defined, then ifndefCONFIG_PM_SLEEP_WAKEUP_SEC
* and ifndefCONFIG_PM_SLEEP_WAKEUP_NSEC define the delay until the STM32
* awakens from PM_SLEEP mode.
*/
# ifndefCONFIG_PM_SLEEP_WAKEUP_SEC
# defineCONFIG_PM_SLEEP_WAKEUP_SEC 10
# endif
# ifndefCONFIG_PM_SLEEP_WAKEUP_NSEC
# defineCONFIG_PM_SLEEP_WAKEUP_NSEC 0
# endif
#endif
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
@ -112,7 +146,6 @@ static void up_idlepm(void)
#endif #endif
static enum pm_state_e oldstate = PM_NORMAL; static enum pm_state_e oldstate = PM_NORMAL;
enum pm_state_e newstate; enum pm_state_e newstate;
irqstate_t flags;
int ret; int ret;
/* Decide, which power saving level can be obtained */ /* Decide, which power saving level can be obtained */
@ -125,7 +158,7 @@ static void up_idlepm(void)
{ {
lldbg("newstate= %d oldstate=%d\n", newstate, oldstate); lldbg("newstate= %d oldstate=%d\n", newstate, oldstate);
flags = irqsave(); sched_lock();
/* Force the global state change */ /* Force the global state change */
@ -138,7 +171,7 @@ static void up_idlepm(void)
/* No state change... */ /* No state change... */
goto errout; return;
} }
/* Then perform board-specific, state-dependent logic here */ /* Then perform board-specific, state-dependent logic here */
@ -147,6 +180,14 @@ static void up_idlepm(void)
{ {
case PM_NORMAL: case PM_NORMAL:
{ {
/* If we just awakened from PM_STANDBY mode, then reconfigure
* clocking.
*/
if (oldstate == PM_STANDBY)
{
stm32_clockconfig();
}
} }
break; break;
@ -189,9 +230,9 @@ static void up_idlepm(void)
lldbg("Warning: The alarm is already set\n"); lldbg("Warning: The alarm is already set\n");
} }
#endif #endif
/* Call the STM32 stop mode */ /* Enter the STM32 stop mode */
stm32_pmstop(true); (void)stm32_pmstop(false);
/* We have been re-awakened by some even: A button press? /* We have been re-awakened by some even: A button press?
* An alarm? Cancel any pending alarm and resume the normal * An alarm? Cancel any pending alarm and resume the normal
@ -208,7 +249,6 @@ static void up_idlepm(void)
/* Resume normal operation */ /* Resume normal operation */
pm_changestate(PM_NORMAL); pm_changestate(PM_NORMAL);
newstate = PM_NORMAL;
} }
break; break;
@ -218,6 +258,37 @@ static void up_idlepm(void)
* of standby is via the reset path. * of standby is via the reset path.
*/ */
#ifdef CONFIG_PM_SLEEP_WAKEUP
/* Configure the RTC alarm to Auto Reset the system */
(void)up_rtc_gettime(&alarmtime);
alarmtime.tv_sec +=CONFIG_PM_SLEEP_WAKEUP_SEC;
alarmtime.tv_nsec +=CONFIG_PM_SLEEP_WAKEUP_NSEC;
/* The tv_nsec value must not exceed 1,000,000,000. That
* would be an invalid time.
*/
if (alarmtime.tv_nsec >= NSEC_PER_SEC)
{
/* Carry to the seconds */
alarmtime.tv_sec++;
alarmtime.tv_nsec -= NSEC_PER_SEC;
}
/* Set the alarm */
ret = up_rtc_setalarm(&alarmtime, &up_alarmcb);
if (ret < 0)
{
lldbg("Warning: The alarm is already set\n");
}
#endif
/* Enter the STM32 standby mode */
up_mdelay(10);
(void)stm32_pmstandby(); (void)stm32_pmstandby();
} }
break; break;
@ -230,8 +301,7 @@ static void up_idlepm(void)
oldstate = newstate; oldstate = newstate;
errout: sched_unlock();
irqrestore(flags);
} }
} }
#else #else

View File

@ -2,9 +2,13 @@
* configs/stm3210e-eval/src/up_lcd.c * configs/stm3210e-eval/src/up_lcd.c
* arch/arm/src/board/up_lcd.c * arch/arm/src/board/up_lcd.c
* *
* Copyright (C) 2011 Gregory Nutt. All rights reserved. * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* With power management enhancements by:
*
* Author: Diego Sanchez <dsanchez@nx-engineering.com>
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
@ -1187,7 +1191,7 @@ static void stm3210e_pm_notify(struct pm_callback_s *cb , enum pm_state_e pmstat
duty--; duty--;
} }
/* Reduce the LCD light to 50% of the MAXPOWER */ /* Reduce the LCD backlight to 50% of the MAXPOWER */
duty >>= 1; duty >>= 1;
putreg16((uint16_t)duty, STM32_TIM1_CCR1); putreg16((uint16_t)duty, STM32_TIM1_CCR1);
@ -1197,7 +1201,7 @@ static void stm3210e_pm_notify(struct pm_callback_s *cb , enum pm_state_e pmstat
case(PM_STANDBY): case(PM_STANDBY):
{ {
/* Entering STANDBY mode - Turn display off */ /* Entering STANDBY mode - Turn display backlight off */
#ifdef CONFIG_LCD_PWM #ifdef CONFIG_LCD_PWM
putreg16(0, STM32_TIM1_CCR1); putreg16(0, STM32_TIM1_CCR1);
@ -1207,8 +1211,9 @@ static void stm3210e_pm_notify(struct pm_callback_s *cb , enum pm_state_e pmstat
case(PM_SLEEP): case(PM_SLEEP):
{ {
/* Entering SLEEP mode - Logic for PM_SLEEP goes here */ /* Entering SLEEP mode - Turn off LCD */
(void)stm3210e_poweroff();
} }
break; break;