From a1f510576ad37d88d0985cf0ede02135c466d3a2 Mon Sep 17 00:00:00 2001 From: patacongo Date: Fri, 27 Jul 2012 00:14:38 +0000 Subject: PM update git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4982 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/configs/stm3210e-eval/pm/defconfig | 1 + nuttx/configs/stm3210e-eval/src/up_idle.c | 90 +++++++++++++++++++++++++++---- nuttx/configs/stm3210e-eval/src/up_lcd.c | 13 +++-- 3 files changed, 90 insertions(+), 14 deletions(-) (limited to 'nuttx/configs') diff --git a/nuttx/configs/stm3210e-eval/pm/defconfig b/nuttx/configs/stm3210e-eval/pm/defconfig index d4fb6e8b9..a5c8bd185 100644 --- a/nuttx/configs/stm3210e-eval/pm/defconfig +++ b/nuttx/configs/stm3210e-eval/pm/defconfig @@ -468,6 +468,7 @@ CONFIG_SCHED_ATEXIT=n CONFIG_PM=y CONFIG_PM_CUSTOMINIT=y CONFIG_IDLE_CUSTOM=y +CONFIG_PM_SLEEP_WAKEUP=n # # Board/Application-Specific Power Management Configuration. diff --git a/nuttx/configs/stm3210e-eval/src/up_idle.c b/nuttx/configs/stm3210e-eval/src/up_idle.c index 2b92f9c5e..b73b88c08 100644 --- a/nuttx/configs/stm3210e-eval/src/up_idle.c +++ b/nuttx/configs/stm3210e-eval/src/up_idle.c @@ -74,16 +74,50 @@ # define END_IDLE() #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 -# define CONFIG_PM_ALARM_SEC 3 +# define CONFIG_PM_ALARM_SEC 15 #endif #ifndef CONFIG_PM_ALARM_NSEC # define CONFIG_PM_ALARM_NSEC 0 #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 ****************************************************************************/ @@ -112,7 +146,6 @@ static void up_idlepm(void) #endif 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 */ @@ -125,7 +158,7 @@ static void up_idlepm(void) { lldbg("newstate= %d oldstate=%d\n", newstate, oldstate); - flags = irqsave(); + sched_lock(); /* Force the global state change */ @@ -138,7 +171,7 @@ static void up_idlepm(void) /* No state change... */ - goto errout; + return; } /* Then perform board-specific, state-dependent logic here */ @@ -147,6 +180,14 @@ static void up_idlepm(void) { case PM_NORMAL: { + /* If we just awakened from PM_STANDBY mode, then reconfigure + * clocking. + */ + + if (oldstate == PM_STANDBY) + { + stm32_clockconfig(); + } } break; @@ -189,9 +230,9 @@ static void up_idlepm(void) lldbg("Warning: The alarm is already set\n"); } #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? * An alarm? Cancel any pending alarm and resume the normal @@ -208,7 +249,6 @@ static void up_idlepm(void) /* Resume normal operation */ pm_changestate(PM_NORMAL); - newstate = PM_NORMAL; } break; @@ -218,6 +258,37 @@ static void up_idlepm(void) * 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(); } break; @@ -230,8 +301,7 @@ static void up_idlepm(void) oldstate = newstate; -errout: - irqrestore(flags); + sched_unlock(); } } #else diff --git a/nuttx/configs/stm3210e-eval/src/up_lcd.c b/nuttx/configs/stm3210e-eval/src/up_lcd.c index 42da4864a..045f564c3 100644 --- a/nuttx/configs/stm3210e-eval/src/up_lcd.c +++ b/nuttx/configs/stm3210e-eval/src/up_lcd.c @@ -2,9 +2,13 @@ * configs/stm3210e-eval/src/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 * + * With power management enhancements by: + * + * Author: Diego Sanchez + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -1187,7 +1191,7 @@ static void stm3210e_pm_notify(struct pm_callback_s *cb , enum pm_state_e pmstat duty--; } - /* Reduce the LCD light to 50% of the MAXPOWER */ + /* Reduce the LCD backlight to 50% of the MAXPOWER */ duty >>= 1; 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): { - /* Entering STANDBY mode - Turn display off */ + /* Entering STANDBY mode - Turn display backlight off */ #ifdef CONFIG_LCD_PWM 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): { - /* Entering SLEEP mode - Logic for PM_SLEEP goes here */ + /* Entering SLEEP mode - Turn off LCD */ + (void)stm3210e_poweroff(); } break; -- cgit v1.2.3