642 lines
21 KiB
C
642 lines
21 KiB
C
/*******************************************************************************
|
|
Filename: hal_sleep.c
|
|
Revised: $Date: 2012-07-13 06:58:11 -0700 (Fri, 13 Jul 2012) $
|
|
Revision: $Revision: 30922 $
|
|
|
|
Description: This module contains the HAL power management procedures for
|
|
the CC2540.
|
|
|
|
Copyright 2006-2013 Texas Instruments Incorporated. All rights reserved.
|
|
|
|
IMPORTANT: Your use of this Software is limited to those specific rights
|
|
granted under the terms of a software license agreement between the user
|
|
who downloaded the software, his/her employer (which must be your employer)
|
|
and Texas Instruments Incorporated (the "License"). You may not use this
|
|
Software unless you agree to abide by the terms of the License. The License
|
|
limits your use, and you acknowledge, that the Software may not be modified,
|
|
copied or distributed unless embedded on a Texas Instruments microcontroller
|
|
or used solely and exclusively in conjunction with a Texas Instruments radio
|
|
frequency transceiver, which is integrated into your product. Other than for
|
|
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
|
|
works of, modify, distribute, perform, display or sell this Software and/or
|
|
its documentation for any purpose.
|
|
|
|
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
|
|
PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
|
|
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
|
|
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
|
|
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
|
|
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
|
|
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
|
|
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
|
|
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
|
|
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
|
|
|
|
Should you have any questions regarding your right to use this Software,
|
|
contact Texas Instruments Incorporated at www.TI.com.
|
|
*******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* INCLUDES
|
|
*/
|
|
#include "hal_types.h"
|
|
#include "hal_mcu.h"
|
|
#include "hal_board.h"
|
|
#include "hal_sleep.h"
|
|
#include "hal_led.h"
|
|
#include "hal_key.h"
|
|
#include "OSAL.h"
|
|
#include "OSAL_Timers.h"
|
|
#include "OSAL_Tasks.h"
|
|
#include "OSAL_PwrMgr.h"
|
|
#include "hal_drivers.h"
|
|
#include "hal_assert.h"
|
|
#include "ll_sleep.h"
|
|
#include "ll_timer2.h"
|
|
#include "ll_math.h"
|
|
|
|
/*******************************************************************************
|
|
* MACROS
|
|
*/
|
|
|
|
#ifndef HAL_SLEEP_DEBUG_POWER_MODE
|
|
// Set CC2540 power mode; always use PM2.
|
|
#define HAL_SLEEP_PREP_POWER_MODE(mode) \
|
|
st( SLEEPCMD &= ~PMODE; /* clear mode bits */ \
|
|
SLEEPCMD |= mode; /* set mode bits */ \
|
|
while (!(STLOAD & LDRDY)); \
|
|
halSleepPconValue = PCON_IDLE; \
|
|
)
|
|
#define HAL_SLEEP_SET_POWER_MODE() \
|
|
halSetSleepMode()
|
|
|
|
#else // HAL_SLEEP_DEBUG_POWER_MODE
|
|
|
|
// Debug: Don't set power mode, just block until sleep timer interrupt.
|
|
#define HAL_SLEEP_PREP_POWER_MODE(mode) /* nothing */
|
|
#define HAL_SLEEP_SET_POWER_MODE() \
|
|
st( while(halSleepInt == FALSE); \
|
|
halSleepInt = FALSE; \
|
|
HAL_DISABLE_INTERRUPTS(); \
|
|
)
|
|
#endif // !HAL_SLEEP_DEBUG_POWER_MODE
|
|
|
|
// sleep timer interrupt control
|
|
#define HAL_SLEEP_TIMER_ENABLE_INT() st(IEN0 |= STIE_BV;) // enable sleep timer interrupt
|
|
#define HAL_SLEEP_TIMER_DISABLE_INT() st(IEN0 &= ~STIE_BV;) // disable sleep timer interrupt
|
|
#define HAL_SLEEP_TIMER_CLEAR_INT() st(IRCON &= ~0x80;) // clear sleep interrupt flag
|
|
|
|
// backup interrupt enable registers before sleep
|
|
#define HAL_SLEEP_IE_BACKUP_AND_DISABLE( ien0, ien1, ien2 ) \
|
|
st( (ien0) = IEN0; \
|
|
(ien1) = IEN1; \
|
|
(ien2) = IEN2; \
|
|
IEN0 &= STIE_BV; \
|
|
IEN1 &= P0IE_BV; \
|
|
IEN2 &= (P1IE_BV|P2IE_BV); \
|
|
)
|
|
|
|
// restore interrupt enable registers before sleep
|
|
#define HAL_SLEEP_IE_RESTORE( ien0, ien1, ien2 ) \
|
|
st( IEN0 = (ien0); \
|
|
IEN1 = (ien1); \
|
|
IEN2 = (ien2); \
|
|
)
|
|
|
|
// convert msec to 625 usec units with round
|
|
#define HAL_SLEEP_MS_TO_625US( ms ) (((((uint32) (ms)) * 8) + 4) / 5)
|
|
|
|
// convert msec to 32kHz units without round : the ratio of 32 kHz ticks to
|
|
// msec ticks is 32768/1000 = 32.768 or 4096/125
|
|
#define HAL_SLEEP_MS_TO_32KHZ( ms ) ((((uint32) (ms)) * 4096) / 125)
|
|
|
|
//Max 16 bit value
|
|
#define MAX_16BIT_TIMEOUT 0xFFFF
|
|
|
|
#if !defined NOP
|
|
#define NOP() asm("NOP")
|
|
#endif
|
|
|
|
/*******************************************************************************
|
|
* CONSTANTS
|
|
*/
|
|
|
|
// POWER CONSERVATION DEFINITIONS
|
|
// Sleep mode H/W definitions (enabled with POWER_SAVING compile option).
|
|
#define CC2540_PM0 0 // PM0, Clock oscillators on, voltage regulator on
|
|
#define CC2540_PM1 1 // PM1, 32.768 kHz oscillators on, voltage regulator on
|
|
#define CC2540_PM2 2 // PM2, 32.768 kHz oscillators on, voltage regulator off
|
|
#define CC2540_PM3 3 // PM3, All clock oscillators off, voltage regulator off
|
|
|
|
// HAL power management mode is set according to the power management state.
|
|
// The default setting is HAL_SLEEP_OFF. The actual value is tailored to
|
|
// different HW platform. Both HAL_SLEEP_TIMER and HAL_SLEEP_DEEP selections
|
|
// will turn off the system clock, and halt the MCU. HAL_SLEEP_TIMER can be
|
|
// woken up by sleep timer interrupt, I/O interrupt and reset. HAL_SLEEP_DEEP
|
|
// can be woken up by I/O interrupt and reset.
|
|
#define HAL_SLEEP_OFF CC2540_PM0
|
|
#define HAL_SLEEP_TIMER CC2540_PM2
|
|
#define HAL_SLEEP_DEEP CC2540_PM3
|
|
|
|
// MAX_SLEEP_TIME calculation:
|
|
// Sleep timer maximum duration = 0xFFFF7F / 32768 Hz = 511.996 seconds
|
|
// Round it to 510 seconds or 510000 ms
|
|
#define MAX_SLEEP_TIME 16711680 // max time to sleep allowed by ST, in 32kHz ticks
|
|
|
|
// Minimum time to sleep:
|
|
// 1. avoid thrashing in-and-out of sleep with short OSAL timer
|
|
// 2. define minimum safe sleep period
|
|
#if !defined (PM_MIN_SLEEP_TIME)
|
|
#define PM_MIN_SLEEP_TIME 66 // default to min safe sleep time, in 32kHz ticks
|
|
#endif // !PM_MIN_SLEEP_TIME
|
|
|
|
// This value is used to adjust the sleep timer compare value such that the
|
|
// sleep timer compare takes into account the amount of processing time spent in
|
|
// function halSleep(). The first value is determined by measuring the number of
|
|
// sleep timer ticks from the beginning of the function to entering sleep mode.
|
|
// The second value is determined by measuring the number of sleep timer ticks
|
|
// from exit of sleep mode to the call to osal_adjust_timers().
|
|
#if defined( CC2541) || defined( CC2541S )
|
|
#define HAL_SLEEP_ADJ_TICKS 25 // default sleep adjustment, in 32kHz ticks
|
|
#else // CC2540
|
|
#define HAL_SLEEP_ADJ_TICKS 35 // default sleep adjustment, in 32kHz ticks
|
|
#endif // CC2541 || CC2541S
|
|
|
|
// sleep and external interrupt port masks
|
|
#define STIE_BV BV(5)
|
|
#define P0IE_BV BV(5)
|
|
#define P1IE_BV BV(4)
|
|
#define P2IE_BV BV(1)
|
|
|
|
// for optimized indexing of uint32
|
|
#if HAL_MCU_LITTLE_ENDIAN()
|
|
#define UINT32_NDX0 0
|
|
#define UINT32_NDX1 1
|
|
#define UINT32_NDX2 2
|
|
#define UINT32_NDX3 3
|
|
#else
|
|
#define UINT32_NDX0 3
|
|
#define UINT32_NDX1 2
|
|
#define UINT32_NDX2 1
|
|
#define UINT32_NDX3 0
|
|
#endif // HAL_MCU_LITTLE_ENDIAN()
|
|
|
|
/*******************************************************************************
|
|
* TYPEDEFS
|
|
*/
|
|
|
|
/*******************************************************************************
|
|
* LOCAL VARIABLES
|
|
*/
|
|
|
|
// HAL power management mode is set according to the power management state.
|
|
static uint8 halPwrMgtMode = HAL_SLEEP_OFF;
|
|
|
|
// Flag to indicate if wake is due to impending radio event.
|
|
static uint8 wakeForRF;
|
|
|
|
#ifdef HAL_SLEEP_DEBUG_POWER_MODE
|
|
static bool halSleepInt = FALSE;
|
|
#endif // HAL_SLEEP_DEBUG_POWER_MODE
|
|
|
|
/*******************************************************************************
|
|
* GLOBAL VARIABLES
|
|
*/
|
|
|
|
// PCON register value to program when setting power mode
|
|
volatile __data uint8 halSleepPconValue = PCON_IDLE;
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
*/
|
|
|
|
// The PCON instruction must be 4-byte aligned. The following code may cause
|
|
// excessive power consumption if not aligned. See linker file ".xcl" for
|
|
// actual placement.
|
|
#pragma location = "SLEEP_CODE"
|
|
void halSetSleepMode(void);
|
|
|
|
void halSleepSetTimer( uint32 sleepTime, uint32 timeout );
|
|
uint32 halSleepReadTimer( void );
|
|
uint32 TimerElapsed( void );
|
|
|
|
/*******************************************************************************
|
|
* @fn halSleep
|
|
*
|
|
* @brief This function put the CC2540 to sleep. The PCON instruction must
|
|
* be 4-byte aligned. The following code may cause excessive power
|
|
* consumption if not aligned. See linker file ".xcl" for actual
|
|
* placement.
|
|
*
|
|
* input parameters
|
|
*
|
|
* @param None.
|
|
*
|
|
* output parameters
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return None.
|
|
*/
|
|
#pragma optimize=none
|
|
void halSetSleepMode(void)
|
|
{
|
|
// WARNING: DO NOT ADD ANY ADDITIONAL CODE; THIS IS A FIXED SIZED SEGMENT!
|
|
PCON = halSleepPconValue;
|
|
// Disallow waking ISR from running in order to give the highest priority to LL_PowerOnReq().
|
|
HAL_DISABLE_INTERRUPTS();
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* @fn halSleep
|
|
*
|
|
* @brief This function is called from the OSAL task loop using and
|
|
* existing OSAL interface. It sets the low power mode of the LL
|
|
* and the CC2540.
|
|
*
|
|
* input parameters
|
|
*
|
|
* @param osal_timeout - Next OSAL timer timeout, in msec.
|
|
*
|
|
* output parameters
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return None.
|
|
*/
|
|
void halSleep( uint32 osal_timeout )
|
|
{
|
|
uint32 timeout;
|
|
uint32 llTimeout;
|
|
uint32 sleepTimer;
|
|
|
|
halDriverBegPM();
|
|
|
|
#ifdef DEBUG_GPIO
|
|
// TEMP
|
|
P1_0 = 1;
|
|
#endif // DEBUG_GPIO
|
|
|
|
if (osal_timeout > MAX_16BIT_TIMEOUT)
|
|
{
|
|
osal_timeout = MAX_16BIT_TIMEOUT;
|
|
}
|
|
|
|
// get LL timeout value already converted to 32kHz ticks
|
|
LL_TimeToNextRfEvent( &sleepTimer, &llTimeout );
|
|
|
|
// check if no OSAL timeout
|
|
// Note: If the next wake event is due to an OSAL timeout, then wakeForRF
|
|
// will already be FALSE, and the call to LL_TimeToNExtRfEvent will
|
|
// already have taken a snapshot of the Sleep Timer.
|
|
if (osal_timeout == 0)
|
|
{
|
|
// use common variable
|
|
timeout = llTimeout;
|
|
|
|
// check if there's time before the next radio event
|
|
// Note: Since the OSAL timeout is zero, then if the radio timeout is
|
|
// not zero, the next wake (if one) will be due to the radio event.
|
|
wakeForRF = (timeout != 0) ? TRUE : FALSE;
|
|
}
|
|
else // OSAL timeout is non-zero
|
|
{
|
|
// convet OSAL timeout to sleep time
|
|
// Note: Could be early by one 32kHz timer tick due to rounding.
|
|
timeout = HAL_SLEEP_MS_TO_32KHZ( osal_timeout );
|
|
|
|
// so check time to radio event is non-zero, and if so, use shorter value
|
|
if ((llTimeout != 0) && (llTimeout < timeout))
|
|
{
|
|
// use common variable
|
|
timeout = llTimeout;
|
|
|
|
// the next ST wake time is due to radio
|
|
wakeForRF = TRUE;
|
|
}
|
|
else // OSAL timeout will be used to wake
|
|
{
|
|
// so take a snapshot of the sleep timer for sleep based on OSAL timeout
|
|
sleepTimer = halSleepReadTimer();
|
|
|
|
// the next ST wake time is not due to radio
|
|
wakeForRF = FALSE;
|
|
}
|
|
}
|
|
|
|
// HAL_SLEEP_PM3 is entered only if the timeout is zero
|
|
halPwrMgtMode = (timeout == 0) ? HAL_SLEEP_DEEP : HAL_SLEEP_TIMER;
|
|
|
|
#ifdef DEBUG_GPIO
|
|
// TEMP
|
|
P1_0 = 0;
|
|
#endif // DEBUG_GPIO
|
|
|
|
// check if sleep should be entered
|
|
if ( (timeout > PM_MIN_SLEEP_TIME) || (timeout == 0) )
|
|
{
|
|
halIntState_t ien0, ien1, ien2;
|
|
|
|
#ifdef DEBUG_GPIO
|
|
// TEMP
|
|
P1_0 = 1;
|
|
#endif // DEBUG_GPIO
|
|
|
|
HAL_ASSERT( HAL_INTERRUPTS_ARE_ENABLED() );
|
|
HAL_DISABLE_INTERRUPTS();
|
|
|
|
// check if radio allows sleep, and if so, preps system for shutdown
|
|
if ( LL_PowerOffReq(halPwrMgtMode) == LL_SLEEP_REQUEST_ALLOWED )
|
|
{
|
|
#if ((defined HAL_KEY) && (HAL_KEY == TRUE))
|
|
// get peripherals ready for sleep
|
|
HalKeyEnterSleep();
|
|
#endif // ((defined HAL_KEY) && (HAL_KEY == TRUE))
|
|
|
|
#ifdef HAL_SLEEP_DEBUG_LED
|
|
HAL_TURN_OFF_LED3();
|
|
#else
|
|
// use this to turn LEDs off during sleep
|
|
HalLedEnterSleep();
|
|
#endif // HAL_SLEEP_DEBUG_LED
|
|
|
|
// enable sleep timer interrupt
|
|
if (timeout != 0)
|
|
{
|
|
// check if the time to next wake event is greater than max sleep time
|
|
if (timeout > MAX_SLEEP_TIME )
|
|
{
|
|
// it is, so limit to max allowed sleep time (~510s)
|
|
halSleepSetTimer( sleepTimer, MAX_SLEEP_TIME );
|
|
}
|
|
else // not more than allowed sleep time
|
|
{
|
|
// so set sleep time to actual amount
|
|
halSleepSetTimer( sleepTimer, timeout );
|
|
}
|
|
}
|
|
|
|
// prep CC254x power mode
|
|
HAL_SLEEP_PREP_POWER_MODE(halPwrMgtMode);
|
|
|
|
// save interrupt enable registers and disable all interrupts
|
|
HAL_SLEEP_IE_BACKUP_AND_DISABLE(ien0, ien1, ien2);
|
|
HAL_ENABLE_INTERRUPTS();
|
|
|
|
#ifdef DEBUG_GPIO
|
|
// TEMP
|
|
P1_0 = 0;
|
|
#endif // DEBUG_GPIO
|
|
|
|
// set CC254x power mode; interrupts are disabled after this function
|
|
// Note: Any ISR that could wake the device from sleep needs to use
|
|
// CLEAR_SLEEP_MODE(), which will clear the halSleepPconValue flag
|
|
// used to enter sleep mode, thereby preventing the device from
|
|
// missing this interrupt.
|
|
HAL_SLEEP_SET_POWER_MODE();
|
|
|
|
#ifdef DEBUG_GPIO
|
|
// TEMP
|
|
P1_0 = 1;
|
|
#endif // DEBUG_GPIO
|
|
|
|
// check if ST interrupt pending, and if not, clear wakeForRF flag
|
|
// Note: This is needed in case we are not woken by the sleep timer but
|
|
// by for example a key press. In this case, the flag has to be
|
|
// cleared as we are not just before a radio event.
|
|
// Note: There is the possiblity that we may wake from an interrupt just
|
|
// before the sleep timer would have woken us just before a radio
|
|
// event, in which case power will be wasted as we will probably
|
|
// enter this routine one or more times before the radio event.
|
|
// However, this is presumably unusual, and isn't expected to have
|
|
// much impact on average power consumption.
|
|
if ( (wakeForRF == TRUE) && !(IRCON & 0x80) )
|
|
{
|
|
wakeForRF = FALSE;
|
|
}
|
|
|
|
// restore interrupt enable registers
|
|
HAL_SLEEP_IE_RESTORE(ien0, ien1, ien2);
|
|
|
|
// power on the LL; blocks until completion
|
|
// Note: This is done here to ensure the 32MHz XOSC has stablized, in
|
|
// case it is needed (e.g. the ADC is used by the joystick).
|
|
LL_PowerOnReq( (halPwrMgtMode == CC2540_PM3), wakeForRF );
|
|
|
|
#ifdef HAL_SLEEP_DEBUG_LED
|
|
HAL_TURN_ON_LED3();
|
|
#else //!HAL_SLEEP_DEBUG_LED
|
|
// use this to turn LEDs back on after sleep
|
|
HalLedExitSleep();
|
|
#endif // HAL_SLEEP_DEBUG_LED
|
|
|
|
#if ((defined HAL_KEY) && (HAL_KEY == TRUE))
|
|
// handle peripherals
|
|
(void)HalKeyExitSleep();
|
|
#endif // ((defined HAL_KEY) && (HAL_KEY == TRUE))
|
|
}
|
|
|
|
HAL_ENABLE_INTERRUPTS();
|
|
}
|
|
|
|
halDriverEndPM();
|
|
|
|
#ifdef DEBUG_GPIO
|
|
// TEMP
|
|
P1_0 = 0;
|
|
#endif // DEBUG_GPIO
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
* @fn halSleepSetTimer
|
|
*
|
|
* @brief This function sets the CC2540 sleep timer compare value based
|
|
* on a given snapshot of the sleep timer, and a timeout that is
|
|
* relative to that snapshot. The snapshot is provided as it may
|
|
* need to be taken as close to the snapshot of Timer 2 (the radio
|
|
* timer) as possible so that the time to the next radio event,
|
|
* when converted to 32kHz ticks, is as accurate as possible in
|
|
* terms of sleep time. In addition, the offset is adjusted based
|
|
* on a configurable adjustment to take the sleep handler's
|
|
* execution time into account. The sleep timer interrupt is then
|
|
* setup for wake.
|
|
*
|
|
* input parameters
|
|
*
|
|
* @param sleepTimer - Sleep timer value timeout is relative to.
|
|
* @param timeout - Timeout value in 32kHz units.
|
|
*
|
|
* output parameters
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return None.
|
|
*/
|
|
void halSleepSetTimer( uint32 sleepTimer, uint32 timeout )
|
|
{
|
|
HAL_SLEEP_TIMER_DISABLE_INT();
|
|
|
|
// compute sleep timer compare value
|
|
sleepTimer += timeout;
|
|
|
|
// subtract the processing time spent in function halSleep()
|
|
sleepTimer -= HAL_SLEEP_ADJ_TICKS;
|
|
|
|
// set sleep timer compare; ST0 must be written last
|
|
ST2 = ((uint8 *)&sleepTimer)[UINT32_NDX2];
|
|
ST1 = ((uint8 *)&sleepTimer)[UINT32_NDX1];
|
|
ST0 = ((uint8 *)&sleepTimer)[UINT32_NDX0];
|
|
|
|
HAL_SLEEP_TIMER_CLEAR_INT();
|
|
HAL_SLEEP_TIMER_ENABLE_INT();
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
* @fn halSleepReadTimer
|
|
*
|
|
* @brief This function reads the CC2540 sleep timer.
|
|
*
|
|
* input parameters
|
|
*
|
|
* @param None.
|
|
*
|
|
* output parameters
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return A snapshot of the 24 bit sleep timer.
|
|
*/
|
|
uint32 halSleepReadTimer( void )
|
|
{
|
|
uint32 sleepTimer;
|
|
|
|
// read the sleep timer
|
|
// Note: Read of ST0 latches ST1 and ST2.
|
|
((uint8 *)&sleepTimer)[UINT32_NDX0] = ST0;
|
|
((uint8 *)&sleepTimer)[UINT32_NDX1] = ST1;
|
|
((uint8 *)&sleepTimer)[UINT32_NDX2] = ST2;
|
|
((uint8 *)&sleepTimer)[UINT32_NDX3] = 0;
|
|
|
|
return( sleepTimer );
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
* @fn TimerElapsed
|
|
*
|
|
* @brief Determine the number of OSAL timer ticks elapsed during sleep.
|
|
*
|
|
* input parameters
|
|
*
|
|
* @param None.
|
|
*
|
|
* output parameters
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return Number of timer ticks elapsed during sleep.
|
|
*/
|
|
uint32 TimerElapsed( void )
|
|
{
|
|
return( 0 );
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
* @fn halRestoreSleepLevel
|
|
*
|
|
* @brief Restore the deepest timer sleep level.
|
|
*
|
|
* input parameters
|
|
*
|
|
* @param None
|
|
*
|
|
* output parameters
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return None.
|
|
*/
|
|
void halRestoreSleepLevel( void )
|
|
{
|
|
// Stub
|
|
#ifdef PM_TEST
|
|
osal_start_timerEx (Hal_TaskID, HAL_SLEEP_TIMER_EVENT, 1000);
|
|
#endif // PM_TEST
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
* @fn halSleepTimerIsr
|
|
*
|
|
* @brief Sleep timer ISR.
|
|
*
|
|
* input parameters
|
|
*
|
|
* None.
|
|
*
|
|
* output parameters
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return None.
|
|
*/
|
|
HAL_ISR_FUNCTION(halSleepTimerIsr, ST_VECTOR)
|
|
{
|
|
HAL_ENTER_ISR();
|
|
|
|
HAL_SLEEP_TIMER_CLEAR_INT();
|
|
|
|
#ifdef HAL_SLEEP_DEBUG_POWER_MODE
|
|
halSleepInt = TRUE;
|
|
#endif // HAL_SLEEP_DEBUG_POWER_MODE
|
|
|
|
CLEAR_SLEEP_MODE();
|
|
|
|
HAL_EXIT_ISR();
|
|
|
|
return;
|
|
}
|
|
|
|
/**************************************************************************************************
|
|
* @fn halSleepWait
|
|
*
|
|
* @brief Perform a blocking wait for the specified number of microseconds.
|
|
* Use assumptions about number of clock cycles needed for the various instructions.
|
|
* This function assumes a 32 MHz clock.
|
|
* NB! This function is highly dependent on architecture and compiler!
|
|
*
|
|
* input parameters
|
|
*
|
|
* @param duration - Duration of wait in microseconds.
|
|
*
|
|
* output parameters
|
|
*
|
|
* None.
|
|
*
|
|
* @return None.
|
|
**************************************************************************************************
|
|
*/
|
|
#pragma optimize=none
|
|
void halSleepWait(uint16 duration)
|
|
{
|
|
duration >>= 1;
|
|
|
|
while (duration-- > 0)
|
|
{
|
|
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
|
NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*/
|
|
|