📄 hibernate.c
字号:
//*****************************************************************************
//
// hibernate.c - Driver for the hibernation module
//
// Copyright (c) 2007 Luminary Micro, Inc. All rights reserved.
//
// Software License Agreement
//
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
//
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws. All rights are reserved. Any use in violation
// of the foregoing restrictions may subject the user to criminal sanctions
// under applicable laws, as well as to civil liability for the breach of the
// terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 1392 of the Stellaris Peripheral Driver Library.
//
//*****************************************************************************
//*****************************************************************************
//
//! \addtogroup hibernate_api
//! @{
//
//*****************************************************************************
#include "../hw_memmap.h"
#include "../hw_types.h"
#include "../hw_ints.h"
#include "../hw_hibernate.h"
#include "sysctl.h"
#include "interrupt.h"
#include "hibernate.h"
#include "debug.h"
//*****************************************************************************
//
// The delay in microseconds for writing to the Hibernation module registers.
//
//*****************************************************************************
#define DELAY_USECS 95
//*****************************************************************************
//
// The number of processor cycles to execute one pass of the delay loop.
//
//*****************************************************************************
#define LOOP_CYCLES 3
//*****************************************************************************
//
// The calculated number of delay loops to achieve the write delay.
//
//*****************************************************************************
static unsigned long ulWriteDelay;
//*****************************************************************************
//
//! \internal
//!
//! Provides a small delay.
//!
//! \param ulCount is the number of delay loop iterations to perform.
//!
//! Since the hibernation module needs a delay between words written to it,
//! this function provides a means of generating that delay. It
//! is written in assembly to keep the delay consistent across tool chains,
//! avoiding the need to tune the delay based on the tool chain in use.
//!
//! The loop below in theory takes 4 cycles/loop.
//!
//! \return None.
//
//*****************************************************************************
#if defined(ewarm)
static void
HibernateWriteDelay(unsigned long ulCount)
{
__asm(" subs r0, #1\n"
" bne HibernateWriteDelay\n"
" bx lr");
}
#endif
#if defined(gcc) || defined(sourcerygxx)
static void __attribute__((naked))
HibernateWriteDelay(unsigned long ulCount)
{
__asm(" subs r0, #1\n"
" bne HibernateWriteDelay\n"
" bx lr");
}
#endif
#if defined(rvmdk) || defined(__ARMCC_VERSION)
__asm void
HibernateWriteDelay(unsigned long ulCount)
{
subs r0, #1;
bne HibernateWriteDelay;
bx lr;
}
#endif
//*****************************************************************************
//
//! Enables the hibernation module for operation.
//!
//! Enables the hibernation module for operation. This function should be
//! be called before any of the hibernation module features are used.
//! The system clock must be set up by calling SysCtlClockSet() before calling
//! this function.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateEnable(void)
{
unsigned long ulSysClock;
//
// Turn on the clock enable bit.
//
HWREG(HIB_CTL) |= HIB_CTL_CLK32EN;
//
// Get the system clock value, needed for timing calculation.
//
ulSysClock = SysCtlClockGet();
//
// Compute the number of delay loops that must be used to achieve the
// desired delay for writes to the hibernation registers. This value
// will be used in calls to HibernateWriteDelay().
//
ulWriteDelay = ((ulSysClock / 1000) * DELAY_USECS) / (1000L * LOOP_CYCLES);
ulWriteDelay++;
}
//*****************************************************************************
//
//! Disables the hibernation module for operation.
//!
//! Disables the hibernation module for operation. After this function is
//! called, none of the hibernation module features are available.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateDisable(void)
{
//
// Turn off the clock enable bit.
//
HWREG(HIB_CTL) &= ~HIB_CTL_CLK32EN;
}
//*****************************************************************************
//
//! Selects the clock input for the hibernation module.
//!
//! \param ulClockInput specifies the clock input.
//!
//! Configures the clock input for the hibernation module. The configuration
//! option chosen depends entirely on hardware design. The clock input for
//! the module will either be a 32.768 kHz oscillator or a 4.194304 MHz
//! crystal. The parameter \e ulClockFlags must be one of the following:
//!
//! - HIBERNATE_CLOCK_SEL_RAW - use the raw signal from a 32.768 kHz
//! oscillator.
//! - HIBERNATE_CLOCK_SEL_DIV128 - use the crystal input, divided by 128.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateClockSelect(unsigned long ulClockInput)
{
//
// Check the arguments.
//
ASSERT((ulClockInput == HIBERNATE_CLOCK_SEL_RAW) ||
(ulClockInput == HIBERNATE_CLOCK_SEL_DIV128));
//
// Set the clock selection bit according to the parameter.
//
HWREG(HIB_CTL) = ulClockInput | (HWREG(HIB_CTL) & ~HIB_CTL_CLKSEL);
}
//*****************************************************************************
//
//! Enables the RTC feature of the hibernation module.
//!
//! Enables the RTC in the hibernation module. The RTC can be used to
//! wake the processor from hibernation at a certain time, or to generate
//! interrupts at certain times. This function must be called before using
//! any of the RTC features of the hibernation module.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateRTCEnable(void)
{
//
// Turn on the RTC enable bit.
//
HWREG(HIB_CTL) |= HIB_CTL_RTCEN;
}
//*****************************************************************************
//
//! Disables the RTC feature of the hibernation module.
//!
//! Disables the RTC in the hibernation module. After calling this function
//! the RTC features of the hibernation module will not be available.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateRTCDisable(void)
{
//
// Turn off the RTC enable bit.
//
HWREG(HIB_CTL) &= ~HIB_CTL_RTCEN;
}
//*****************************************************************************
//
//! Configures the wake conditions for the hibernation module.
//!
//! \param ulWakeFlags specifies which conditions should be used for waking.
//!
//! Enables the conditions under which the hibernation module will wake.
//! The parameter \e ulWakeFlags is the logical or of any combination of the
//! following:
//!
//! - HIBERNATE_WAKE_PIN - wake when the external wake pin is asserted.
//! - HIBERNATE_WAKE_RTC - wake when one of the RTC matches occurs.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateWakeSet(unsigned long ulWakeFlags)
{
//
// Check the arguments.
//
ASSERT(!(ulWakeFlags & ~(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC)));
//
// Set the specified wake flags in the control register.
//
HWREG(HIB_CTL) = ulWakeFlags |
(HWREG(HIB_CTL) & ~(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC));
}
//*****************************************************************************
//
//! Gets the currently configured wake conditions for the hibernation module.
//!
//! Returns the flags representing the wake configuration for the hibernation
//! module. The return value will be a combination of the following
//! flags:
//!
//! - HIBERNATE_WAKE_PIN - wake when the external wake pin is asserted.
//! - HIBERNATE_WAKE_RTC - wake when one of the RTC matches occurs.
//!
//! \return flags indicating the configured wake conditions.
//
//*****************************************************************************
unsigned long
HibernateWakeGet(void)
{
//
// Read the wake bits from the control register and return
// those bits to the caller.
//
return(HWREG(HIB_CTL) & (HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC));
}
//*****************************************************************************
//
//! Configures the low battery detection.
//!
//! \param ulLowBatFlags specifies behavior of low battery detection.
//!
//! Enables the low battery detection and whether hibernation is allowed if
//! a low battery is detected. If low battery detection is enabled, then
//! a low battery condition will be indicated in the raw interrupt status
//! register, and can also trigger an interrupt. Optionally, hibernation
//! can be aborted if a low battery is detected.
//!
//! The parameter \e ulLowBatFlags is one of the following values:
//!
//! - HIBERNATE_LOW_BAT_DETECT - detect a low battery condition.
//! - HIBERNATE_LOW_BAT_ABORT - detect a low battery condition, and abort
//! hibernation if low battery is detected.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateLowBatSet(unsigned long ulLowBatFlags)
{
//
// Check the arguments.
//
ASSERT((ulLowBatFlags == HIBERNATE_LOW_BAT_DETECT) ||
(ulLowBatFlags == HIBERNATE_LOW_BAT_ABORT));
//
// Set the low battery detect and abort bits in the control register,
// according to the parameter.
//
HWREG(HIB_CTL) = ulLowBatFlags |
(HWREG(HIB_CTL) & ~HIBERNATE_LOW_BAT_ABORT);
}
//*****************************************************************************
//
//! Gets the currently configured low battery detection behavior.
//!
//! Returns a value representing the currently configured low battery
//! detection behavior. The return value will be one of the following:
//!
//! - HIBERNATE_LOW_BAT_DETECT - detect a low battery condition.
//! - HIBERNATE_LOW_BAT_ABORT - detect a low battery condition, and abort
//! hibernation if low battery is detected.
//!
//! \return a value indicating the configured low battery detection.
//
//*****************************************************************************
unsigned long
HibernateLowBatGet(void)
{
//
// Read the low bat bits from the control register and return
// those bits to the caller.
//
return(HWREG(HIB_CTL) & HIBERNATE_LOW_BAT_ABORT);
}
//*****************************************************************************
//
//! Sets the value of the real time clock (RTC) counter.
//!
//! \param ulRTCValue is the new value for the RTC.
//!
//! Sets the value of the RTC. The RTC will count seconds if the hardware
//! is configured correctly. The RTC must be enabled by calling
//! HibernateRTCEnable() before calling this function.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateRTCSet(unsigned long ulRTCValue)
{
//
// Write the new RTC value to the RTC load register.
//
HWREG(HIB_RTCLD) = ulRTCValue;
//
// Add a delay here to enforce the required delay between write
// accesses to certain hibernation module registers.
//
HibernateWriteDelay(ulWriteDelay);
}
//*****************************************************************************
//
//! Gets the value of the real time clock (RTC) counter.
//!
//! Gets the value of the RTC and returns it to the caller.
//!
//! \return the value of the RTC.
//
//*****************************************************************************
unsigned long
HibernateRTCGet(void)
{
//
// Return the value of the RTC counter register to the caller.
//
return(HWREG(HIB_RTCC));
}
//*****************************************************************************
//
//! Sets the value of the RTC match 0 register.
//!
//! \param ulMatch is the value for the match register.
//!
//! Sets the match 0 register for the RTC. The hibernation module can be
//! configured to wake from hibernation, and/or generate an interrupt when
//! the value of the RTC counter is the same as the match register.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateRTCMatch0Set(unsigned long ulMatch)
{
//
// Write the new match value to the match register.
//
HWREG(HIB_RTCM0) = ulMatch;
//
// Add a delay here to enforce the required delay between write
// accesses to certain hibernation module registers.
//
HibernateWriteDelay(ulWriteDelay);
}
//*****************************************************************************
//
//! Gets the value of the RTC match 0 register.
//!
//! Gets the value of the match 0 register for the RTC.
//!
//! \return the value of the match register.
//
//*****************************************************************************
unsigned long
HibernateRTCMatch0Get(void)
{
//
// Return the value of the match register to the caller.
//
return(HWREG(HIB_RTCM0));
}
//*****************************************************************************
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -