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:
parent
b740e28538
commit
56e3553818
@ -607,6 +607,7 @@ int up_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback)
|
|||||||
{
|
{
|
||||||
struct rtc_regvals_s regvals;
|
struct rtc_regvals_s regvals;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
uint16_t cr;
|
||||||
int ret = -EBUSY;
|
int ret = -EBUSY;
|
||||||
|
|
||||||
/* Is there already something waiting on the ALARM? */
|
/* Is there already something waiting on the ALARM? */
|
||||||
@ -621,6 +622,12 @@ int up_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback)
|
|||||||
|
|
||||||
up_rtc_breakout(tp, ®vals);
|
up_rtc_breakout(tp, ®vals);
|
||||||
|
|
||||||
|
/* Enable RTC alarm */
|
||||||
|
|
||||||
|
cr = getreg16(STM32_RTC_CRH);
|
||||||
|
cr |= RTC_CRH_ALRIE;
|
||||||
|
putreg16(cr, STM32_RTC_CRH);
|
||||||
|
|
||||||
/* The set the alarm */
|
/* The set the alarm */
|
||||||
|
|
||||||
flags = irqsave();
|
flags = irqsave();
|
||||||
@ -635,3 +642,44 @@ int up_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: up_rtc_cancelalarm
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Cancel a pending alarm alarm
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* none
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on success; a negated errno on failure
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_RTC_ALARM
|
||||||
|
int up_rtc_cancelalarm(void)
|
||||||
|
{
|
||||||
|
irqstate_t flags;
|
||||||
|
int ret = -ENODATA;
|
||||||
|
|
||||||
|
if (g_alarmcb != NULL)
|
||||||
|
{
|
||||||
|
/* Cancel the global callback function */
|
||||||
|
|
||||||
|
g_alarmcb = NULL;
|
||||||
|
|
||||||
|
/* Unset the alarm */
|
||||||
|
|
||||||
|
flags = irqsave();
|
||||||
|
stm32_rtc_beginwr();
|
||||||
|
putreg16(0xffff, STM32_RTC_ALRH);
|
||||||
|
putreg16(0xffff, STM32_RTC_ALRL);
|
||||||
|
stm32_rtc_endwr();
|
||||||
|
irqrestore(flags);
|
||||||
|
|
||||||
|
ret = OK;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -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,16 +142,27 @@ 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:
|
||||||
{
|
{
|
||||||
/* Check if the buttons have already been registered */
|
/* Check if the buttons have already been registered */
|
||||||
|
|
||||||
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
|
||||||
|
@ -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);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* With extensions, modifications by:
|
* With extensions, modifications by:
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregroy Nutt <gnutt@nuttx.org>
|
* Author: Gregroy Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -256,6 +256,24 @@ EXTERN int up_rtc_settime(FAR const struct timespec *tp);
|
|||||||
EXTERN int up_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback);
|
EXTERN int up_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: up_rtc_cancelalarm
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Cancel a pending alarm alarm
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* none
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on success; a negated errno on failure
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_RTC_ALARM
|
||||||
|
EXTERN int up_rtc_cancelalarm(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user