PM update

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4932 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-07-11 23:21:16 +00:00
parent 83f4b246cb
commit 304ecac2c8
2 changed files with 68 additions and 15 deletions

View File

@ -44,6 +44,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/clock.h>
#include <nuttx/power/pm.h> #include <nuttx/power/pm.h>
#include <debug.h> #include <debug.h>
@ -74,7 +75,7 @@
/* 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 */
#ifndef CONFIG_PM_ALARM_SEC #ifndef CONFIG_PM_ALARM_SEC
# define CONFIG_PM_ALARM_SEC 1 # define CONFIG_PM_ALARM_SEC 3
#endif #endif
#ifndef CONFIG_PM_ALARM_NSEC #ifndef CONFIG_PM_ALARM_NSEC
@ -85,7 +86,9 @@
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_PM
static void up_alarmcb(void); static void up_alarmcb(void);
#endif
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
@ -128,12 +131,10 @@ static void up_idlepm(void)
/* The new state change failed, revert to the preceding state */ /* The new state change failed, revert to the preceding state */
(void)pm_changestate(oldstate); (void)pm_changestate(oldstate);
}
else
{
/* Save the new state */
oldstate = newstate; /* No state change... */
goto errout;
} }
/* Then perform board-specific, state-dependent logic here */ /* Then perform board-specific, state-dependent logic here */
@ -141,7 +142,18 @@ static void up_idlepm(void)
switch (newstate) switch (newstate)
{ {
case PM_NORMAL: case PM_NORMAL:
{
/* Cancel the alarm that was set in PM_STANDBY */
if (oldstate == PM_STANDBY)
{
ret = up_rtc_cancelalarm();
if (ret < 0)
{
lldbg("Warning: Cancel alarm failed\n");
}
}
}
break; break;
case PM_IDLE: case PM_IDLE:
@ -150,7 +162,7 @@ static void up_idlepm(void)
up_unregisterbuttons(); up_unregisterbuttons();
/* Initialize the buttoms to wake up the system from the idle /* Initialize the buttons to wake up the system from the idle
* mode * mode
*/ */
@ -168,26 +180,53 @@ static void up_idlepm(void)
up_pmbuttons(); up_pmbuttons();
(void)up_rtc_gettime(&alarmtime);
/* Configure the RTC alarm to Auto Wake the system */ /* Configure the RTC alarm to Auto Wake the system */
alarmtime.tv_sec = CONFIG_PM_ALARM_SEC; alarmtime.tv_sec += CONFIG_PM_ALARM_SEC;
alarmtime.tv_nsec = CONFIG_PM_ALARM_NSEC; alarmtime.tv_nsec += CONFIG_PM_ALARM_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); ret = up_rtc_setalarm(&alarmtime, &up_alarmcb);
if (ret < 0) if (ret < 0)
{ {
lldbg("The alarm is already set to %d seconds \n", lldbg("Warning: The alarm is already set.\n");
alarmtime.tv_sec);
} }
/* Call the STM32 stop mode */ /* Call the STM32 stop mode */
stm32_pmstop(true); stm32_pmstop(true);
/* We have been re-awakened by some even: A button press?
* An alarm? Cancel any pending alarm and resume the normal
* operation.
*/
up_rtc_cancelalarm();
pm_changestate(PM_NORMAL);
} }
break; break;
case PM_SLEEP: case PM_SLEEP:
{ {
/* We should not return from standby mode. The only way out
* of standby is via the reset path.
*/
(void)stm32_pmstandby(); (void)stm32_pmstandby();
} }
break; break;
@ -196,6 +235,11 @@ static void up_idlepm(void)
break; break;
} }
/* Save the new state */
oldstate = newstate;
errout:
irqrestore(flags); irqrestore(flags);
} }
} }
@ -203,7 +247,6 @@ static void up_idlepm(void)
# define up_idlepm() # define up_idlepm()
#endif #endif
/************************************************************************************ /************************************************************************************
* Name: up_alarmcb * Name: up_alarmcb
* *
@ -212,9 +255,16 @@ static void up_idlepm(void)
* *
************************************************************************************/ ************************************************************************************/
#ifdef CONFIG_PM
static void up_alarmcb(void) static void up_alarmcb(void)
{ {
/* This alarm occurs because there wasn't any EXTI interrupt during the
* PM_STANDBY period. So just go to sleep.
*/
pm_changestate(PM_SLEEP);
} }
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions

View File

@ -273,8 +273,11 @@ static const struct button_info_s g_buttoninfo[NUM_PMBUTTONS] =
#ifdef CONFIG_ARCH_IRQBUTTONS #ifdef CONFIG_ARCH_IRQBUTTONS
static void button_handler(int id, int irq) static void button_handler(int id, int irq)
{ {
/* At this point the MCU should have already awakened. Just report some /* At this point the MCU should have already awakened. The state
* activity in order to drive the rest of the system to the PM_NORMAL state * change will be handled in the IDLE loop when the system is re-awakened
* The button interrupt handler should be totally ignorant of the PM
* activities and should report button activity as if nothing
* special happened.
*/ */
pm_activity(CONFIG_PM_BUTTON_ACTIVITY); pm_activity(CONFIG_PM_BUTTON_ACTIVITY);