556 lines
20 KiB
C
556 lines
20 KiB
C
|
/**************************************************************************************************
|
|||
|
Filename: hal_sleep.c
|
|||
|
Revised: $Date: 2012-03-07 11:55:12 -0800 (Wed, 07 Mar 2012) $
|
|||
|
Revision: $Revision: 29664 $
|
|||
|
|
|||
|
Description: This module contains the HAL power management procedures for the CC2530.
|
|||
|
|
|||
|
|
|||
|
Copyright 2006-2012 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 <EFBFBD>AS IS<EFBFBD> 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 "mac_api.h"
|
|||
|
#include "OSAL.h"
|
|||
|
#include "OSAL_Timers.h"
|
|||
|
#include "OSAL_Tasks.h"
|
|||
|
#include "OSAL_PwrMgr.h"
|
|||
|
#include "OnBoard.h"
|
|||
|
#include "hal_drivers.h"
|
|||
|
#include "hal_assert.h"
|
|||
|
#include "mac_mcu.h"
|
|||
|
|
|||
|
#ifndef ZG_BUILD_ENDDEVICE_TYPE
|
|||
|
# define ZG_BUILD_ENDDEVICE_TYPE FALSE
|
|||
|
#endif
|
|||
|
|
|||
|
#if ZG_BUILD_ENDDEVICE_TYPE && defined (NWK_AUTO_POLL)
|
|||
|
#include "nwk_globals.h"
|
|||
|
#include "ZGlobals.h"
|
|||
|
#endif
|
|||
|
|
|||
|
/* ------------------------------------------------------------------------------------------------
|
|||
|
* Macros
|
|||
|
* ------------------------------------------------------------------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
/* POWER CONSERVATION DEFINITIONS
|
|||
|
* Sleep mode H/W definitions (enabled with POWER_SAVING compile option)
|
|||
|
*/
|
|||
|
#define CC2530_PM0 0 /* PM0, Clock oscillators on, voltage regulator on */
|
|||
|
#define CC2530_PM1 1 /* PM1, 32.768 kHz oscillators on, voltage regulator on */
|
|||
|
#define CC2530_PM2 2 /* PM2, 32.768 kHz oscillators on, voltage regulator off */
|
|||
|
#define CC2530_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:
|
|||
|
* 1. turn off the system clock, and
|
|||
|
* 2. 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 CC2530_PM0
|
|||
|
#define HAL_SLEEP_TIMER CC2530_PM2
|
|||
|
#define HAL_SLEEP_DEEP CC2530_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 510000 /* maximum time to sleep allowed by ST */
|
|||
|
#define TICKS_SUBTRACTED 2
|
|||
|
|
|||
|
/* minimum time to sleep, this macro is to:
|
|||
|
* 1. avoid thrashing in-and-out of sleep with short OSAL timer (~2ms)
|
|||
|
* 2. define minimum safe sleep period
|
|||
|
*/
|
|||
|
#if !defined (PM_MIN_SLEEP_TIME)
|
|||
|
#define PM_MIN_SLEEP_TIME 14 /* default to minimum safe sleep time minimum CAP */
|
|||
|
#endif
|
|||
|
|
|||
|
/* 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);
|
|||
|
|
|||
|
/* 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 it from
|
|||
|
* the beginning of the function to entering sleep mode or more precisely, when
|
|||
|
* MAC_PwrNextTimeout() is called. The second value is determined by measuring the number
|
|||
|
* of sleep timer ticks from exit of sleep mode to the call to MAC_PwrOnReq() where the
|
|||
|
* MAC timer is restarted.
|
|||
|
*/
|
|||
|
#define HAL_SLEEP_ADJ_TICKS (11 + 12)
|
|||
|
|
|||
|
#ifndef HAL_SLEEP_DEBUG_POWER_MODE
|
|||
|
/* set CC2530 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
|
|||
|
/* 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
|
|||
|
|
|||
|
/* 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)
|
|||
|
|
|||
|
/* 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(STIF = 0;) /* clear sleep interrupt flag */
|
|||
|
|
|||
|
/* backup interrupt enable registers before sleep */
|
|||
|
#define HAL_SLEEP_IE_BACKUP_AND_DISABLE(ien0, ien1, ien2) st(ien0 = IEN0; /* backup IEN0 register */ \
|
|||
|
ien1 = IEN1; /* backup IEN1 register */ \
|
|||
|
ien2 = IEN2; /* backup IEN2 register */ \
|
|||
|
IEN0 &= STIE_BV; /* disable IEN0 except STIE */ \
|
|||
|
IEN1 &= P0IE_BV; /* disable IEN1 except P0IE */ \
|
|||
|
IEN2 &= (P1IE_BV|P2IE_BV);) /* disable IEN2 except P1IE, P2IE */
|
|||
|
|
|||
|
/* restore interrupt enable registers before sleep */
|
|||
|
#define HAL_SLEEP_IE_RESTORE(ien0, ien1, ien2) st(IEN0 = ien0; /* restore IEN0 register */ \
|
|||
|
IEN1 = ien1; /* restore IEN1 register */ \
|
|||
|
IEN2 = ien2;) /* restore IEN2 register */
|
|||
|
|
|||
|
/* convert msec to 320 usec units with round */
|
|||
|
#define HAL_SLEEP_MS_TO_320US(ms) (((((uint32) (ms)) * 100) + 31) / 32)
|
|||
|
|
|||
|
/* for optimized indexing of uint32's */
|
|||
|
#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
|
|||
|
|
|||
|
static uint32 maxSleepLoopTime = HAL_SLEEP_MS_TO_320US(MAX_SLEEP_TIME);
|
|||
|
|
|||
|
/* ------------------------------------------------------------------------------------------------
|
|||
|
* Global Variables
|
|||
|
* ------------------------------------------------------------------------------------------------
|
|||
|
*/
|
|||
|
/* PCON register value to program when setting power mode */
|
|||
|
volatile __data uint8 halSleepPconValue = PCON_IDLE;
|
|||
|
|
|||
|
/* ------------------------------------------------------------------------------------------------
|
|||
|
* Local Variables
|
|||
|
* ------------------------------------------------------------------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
/* HAL power management mode is set according to the power management state.
|
|||
|
*/
|
|||
|
static uint8 halPwrMgtMode = HAL_SLEEP_OFF;
|
|||
|
|
|||
|
#ifdef HAL_SLEEP_DEBUG_POWER_MODE
|
|||
|
static bool halSleepInt = FALSE;
|
|||
|
#endif
|
|||
|
|
|||
|
/* ------------------------------------------------------------------------------------------------
|
|||
|
* Function Prototypes
|
|||
|
* ------------------------------------------------------------------------------------------------
|
|||
|
*/
|
|||
|
|
|||
|
void halSleepSetTimer(uint32 timeout);
|
|||
|
|
|||
|
/**************************************************************************************************
|
|||
|
* @fn halSleep
|
|||
|
*
|
|||
|
* @brief This function put the CC2530 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
|
|||
|
*
|
|||
|
* None.
|
|||
|
*
|
|||
|
* @return None.
|
|||
|
**************************************************************************************************
|
|||
|
*/
|
|||
|
void halSetSleepMode(void)
|
|||
|
{
|
|||
|
PCON = halSleepPconValue;
|
|||
|
HAL_DISABLE_INTERRUPTS();
|
|||
|
}
|
|||
|
|
|||
|
/**************************************************************************************************
|
|||
|
* @fn halSetMaxSleepLoopTime
|
|||
|
*
|
|||
|
* @brief This function is to used to setup the maximum sleep loop time. This sleep loop time
|
|||
|
* should be lesser than T2 rollover so that a maximum of only one rollover occurs
|
|||
|
* when cc2530 is in sleep. This function should be called whenever rolloverTime is
|
|||
|
* changed using the function macBackoffTimerSetRollover(macTimerRollover);
|
|||
|
*
|
|||
|
* input parameters
|
|||
|
*
|
|||
|
* @param rolloverTime.
|
|||
|
*
|
|||
|
* output parameters
|
|||
|
*
|
|||
|
* None.
|
|||
|
*
|
|||
|
* @return None.
|
|||
|
**************************************************************************************************
|
|||
|
*/
|
|||
|
void halSetMaxSleepLoopTime(uint32 rolloverTime)
|
|||
|
{
|
|||
|
if( rolloverTime > HAL_SLEEP_MS_TO_320US(MAX_SLEEP_TIME) )
|
|||
|
{
|
|||
|
maxSleepLoopTime = HAL_SLEEP_MS_TO_320US(MAX_SLEEP_TIME);
|
|||
|
}
|
|||
|
maxSleepLoopTime = (rolloverTime - TICKS_SUBTRACTED);
|
|||
|
}
|
|||
|
|
|||
|
/**************************************************************************************************
|
|||
|
* @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 MAC and the CC2530.
|
|||
|
*
|
|||
|
* input parameters
|
|||
|
*
|
|||
|
* @param osal_timeout - Next OSAL timer timeout.
|
|||
|
*
|
|||
|
* output parameters
|
|||
|
*
|
|||
|
* None.
|
|||
|
*
|
|||
|
* @return None.
|
|||
|
**************************************************************************************************
|
|||
|
*/
|
|||
|
void halSleep( uint16 osal_timeout )
|
|||
|
{
|
|||
|
uint32 timeout;
|
|||
|
uint32 macTimeout = 0;
|
|||
|
|
|||
|
/* get next OSAL timer expiration converted to 320 usec units */
|
|||
|
timeout = HAL_SLEEP_MS_TO_320US(osal_timeout);
|
|||
|
if (timeout == 0)
|
|||
|
{
|
|||
|
timeout = MAC_PwrNextTimeout();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* get next MAC timer expiration */
|
|||
|
macTimeout = MAC_PwrNextTimeout();
|
|||
|
|
|||
|
/* get lesser of two timeouts */
|
|||
|
if ((macTimeout != 0) && (macTimeout < timeout))
|
|||
|
{
|
|||
|
timeout = macTimeout;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* HAL_SLEEP_PM2 is entered only if the timeout is zero and
|
|||
|
* the device is a stimulated device.
|
|||
|
*/
|
|||
|
halPwrMgtMode = (timeout == 0) ? HAL_SLEEP_DEEP : HAL_SLEEP_TIMER;
|
|||
|
|
|||
|
/* DEEP sleep can only be entered when zgPollRate == 0.
|
|||
|
* This is to eliminate any possibility of entering PM3 between
|
|||
|
* two network timers.
|
|||
|
*/
|
|||
|
#if ZG_BUILD_ENDDEVICE_TYPE && defined (NWK_AUTO_POLL)
|
|||
|
if ((timeout > HAL_SLEEP_MS_TO_320US(PM_MIN_SLEEP_TIME)) ||
|
|||
|
(timeout == 0 && zgPollRate == 0))
|
|||
|
#else
|
|||
|
if ((timeout > HAL_SLEEP_MS_TO_320US(PM_MIN_SLEEP_TIME)) ||
|
|||
|
(timeout == 0))
|
|||
|
#endif
|
|||
|
{
|
|||
|
halIntState_t ien0, ien1, ien2;
|
|||
|
|
|||
|
HAL_ASSERT(HAL_INTERRUPTS_ARE_ENABLED());
|
|||
|
HAL_DISABLE_INTERRUPTS();
|
|||
|
|
|||
|
/* always use "deep sleep" to turn off radio VREG on CC2530 */
|
|||
|
if (halSleepPconValue != 0 && MAC_PwrOffReq(MAC_PWR_SLEEP_DEEP) == MAC_SUCCESS)
|
|||
|
{
|
|||
|
/* The PCON value is not zero. There is no interrupt overriding the
|
|||
|
* sleep decision. Also, the radio granted the sleep request.
|
|||
|
*/
|
|||
|
|
|||
|
#if ((defined HAL_KEY) && (HAL_KEY == TRUE))
|
|||
|
/* get peripherals ready for sleep */
|
|||
|
HalKeyEnterSleep();
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef HAL_SLEEP_DEBUG_LED
|
|||
|
HAL_TURN_OFF_LED3();
|
|||
|
#else
|
|||
|
/* use this to turn LEDs off during sleep */
|
|||
|
HalLedEnterSleep();
|
|||
|
#endif
|
|||
|
|
|||
|
if(timeout > maxSleepLoopTime)
|
|||
|
{
|
|||
|
timeout = maxSleepLoopTime;
|
|||
|
}
|
|||
|
|
|||
|
/* enable sleep timer interrupt */
|
|||
|
if (timeout != 0)
|
|||
|
{
|
|||
|
if (timeout > HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ))
|
|||
|
{
|
|||
|
timeout -= HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME );
|
|||
|
halSleepSetTimer(HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* set sleep timer */
|
|||
|
halSleepSetTimer(timeout);
|
|||
|
}
|
|||
|
|
|||
|
/* set up sleep timer interrupt */
|
|||
|
HAL_SLEEP_TIMER_CLEAR_INT();
|
|||
|
HAL_SLEEP_TIMER_ENABLE_INT();
|
|||
|
}
|
|||
|
|
|||
|
#ifdef HAL_SLEEP_DEBUG_LED
|
|||
|
if (halPwrMgtMode == CC2530_PM1)
|
|||
|
{
|
|||
|
HAL_TURN_ON_LED1();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
HAL_TURN_OFF_LED1();
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
/* Prep CC2530 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();
|
|||
|
|
|||
|
/* set CC2530 power mode, interrupt is disabled after this function
|
|||
|
* Note that an ISR (that could wake up from power mode) which runs
|
|||
|
* between the previous instruction enabling interrupts and before
|
|||
|
* power mode is set would switch the halSleepPconValue so that
|
|||
|
* power mode shall not be entered in such a case.
|
|||
|
*/
|
|||
|
HAL_SLEEP_SET_POWER_MODE();
|
|||
|
|
|||
|
/* the interrupt is disabled - see halSetSleepMode() */
|
|||
|
|
|||
|
/* restore interrupt enable registers */
|
|||
|
HAL_SLEEP_IE_RESTORE(ien0, ien1, ien2);
|
|||
|
|
|||
|
/* disable sleep timer interrupt */
|
|||
|
HAL_SLEEP_TIMER_DISABLE_INT();
|
|||
|
|
|||
|
#ifdef HAL_SLEEP_DEBUG_LED
|
|||
|
HAL_TURN_ON_LED3();
|
|||
|
#else
|
|||
|
/* use this to turn LEDs back on after sleep */
|
|||
|
HalLedExitSleep();
|
|||
|
#endif
|
|||
|
|
|||
|
#if ((defined HAL_KEY) && (HAL_KEY == TRUE))
|
|||
|
/* handle peripherals */
|
|||
|
(void)HalKeyExitSleep();
|
|||
|
#endif
|
|||
|
|
|||
|
/* power on the MAC; blocks until completion */
|
|||
|
MAC_PwrOnReq();
|
|||
|
|
|||
|
HAL_ENABLE_INTERRUPTS();
|
|||
|
|
|||
|
/* For CC2530, T2 interrupt won<6F>t be generated when the current count is greater than
|
|||
|
* the comparator. The interrupt is only generated when the current count is equal to
|
|||
|
* the comparator. When the CC2530 is waking up from sleep, there is a small window
|
|||
|
* that the count may be grater than the comparator, therefore, missing the interrupt.
|
|||
|
* This workaround will call the T2 ISR when the current T2 count is greater than the
|
|||
|
* comparator. The problem only occurs when POWER_SAVING is turned on, i.e. the 32KHz
|
|||
|
* drives the chip in sleep and SYNC start is used.
|
|||
|
*/
|
|||
|
macMcuTimer2OverflowWorkaround();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* An interrupt may have changed the sleep decision. Do not sleep at all. Turn on
|
|||
|
* the interrupt, exit normally, and the next sleep will be allowed.
|
|||
|
*/
|
|||
|
HAL_ENABLE_INTERRUPTS();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**************************************************************************************************
|
|||
|
* @fn halSleepSetTimer
|
|||
|
*
|
|||
|
* @brief This function sets the CC2530 sleep timer compare value. First it reads and
|
|||
|
* stores the value of the sleep timer; this value is used later to update OSAL
|
|||
|
* timers. Then the timeout value is converted from 320 usec units to 32 kHz
|
|||
|
* period units and the compare value is set to the timeout.
|
|||
|
*
|
|||
|
* input parameters
|
|||
|
*
|
|||
|
* @param timeout - Timeout value in 320 usec units. The sleep timer compare is set to
|
|||
|
* this value.
|
|||
|
*
|
|||
|
* output parameters
|
|||
|
*
|
|||
|
* None.
|
|||
|
*
|
|||
|
* @return None.
|
|||
|
**************************************************************************************************
|
|||
|
*/
|
|||
|
void halSleepSetTimer(uint32 timeout)
|
|||
|
{
|
|||
|
uint32 ticks;
|
|||
|
|
|||
|
/* read the sleep timer; ST0 must be read first */
|
|||
|
((uint8 *) &ticks)[UINT32_NDX0] = ST0;
|
|||
|
((uint8 *) &ticks)[UINT32_NDX1] = ST1;
|
|||
|
((uint8 *) &ticks)[UINT32_NDX2] = ST2;
|
|||
|
((uint8 *) &ticks)[UINT32_NDX3] = 0;
|
|||
|
|
|||
|
/* Compute sleep timer compare value. The ratio of 32 kHz ticks to 320 usec ticks
|
|||
|
* is 32768/3125 = 10.48576. This is nearly 671/64 = 10.484375.
|
|||
|
*/
|
|||
|
ticks += (timeout * 671) / 64;
|
|||
|
|
|||
|
/* subtract the processing time spent in function halSleep() */
|
|||
|
ticks -= HAL_SLEEP_ADJ_TICKS;
|
|||
|
|
|||
|
/* set sleep timer compare; ST0 must be written last */
|
|||
|
ST2 = ((uint8 *) &ticks)[UINT32_NDX2];
|
|||
|
ST1 = ((uint8 *) &ticks)[UINT32_NDX1];
|
|||
|
ST0 = ((uint8 *) &ticks)[UINT32_NDX0];
|
|||
|
}
|
|||
|
|
|||
|
/**************************************************************************************************
|
|||
|
* @fn TimerElapsed
|
|||
|
*
|
|||
|
* @brief Determine the number of OSAL timer ticks elapsed during sleep.
|
|||
|
* Deprecated for CC2530 and CC2430 SoC.
|
|||
|
*
|
|||
|
* input parameters
|
|||
|
*
|
|||
|
* @param None.
|
|||
|
*
|
|||
|
* output parameters
|
|||
|
*
|
|||
|
* None.
|
|||
|
*
|
|||
|
* @return Number of timer ticks elapsed during sleep.
|
|||
|
**************************************************************************************************
|
|||
|
*/
|
|||
|
uint32 TimerElapsed( void )
|
|||
|
{
|
|||
|
/* Stubs */
|
|||
|
return (0);
|
|||
|
}
|
|||
|
|
|||
|
/**************************************************************************************************
|
|||
|
* @fn halRestoreSleepLevel
|
|||
|
*
|
|||
|
* @brief Restore the deepest timer sleep level.
|
|||
|
*
|
|||
|
* input parameters
|
|||
|
*
|
|||
|
* @param None
|
|||
|
*
|
|||
|
* output parameters
|
|||
|
*
|
|||
|
* None.
|
|||
|
*
|
|||
|
* @return None.
|
|||
|
**************************************************************************************************
|
|||
|
*/
|
|||
|
void halRestoreSleepLevel( void )
|
|||
|
{
|
|||
|
/* Stubs */
|
|||
|
}
|
|||
|
|
|||
|
/**************************************************************************************************
|
|||
|
* @fn halSleepTimerIsr
|
|||
|
*
|
|||
|
* @brief Sleep timer ISR.
|
|||
|
*
|
|||
|
* input parameters
|
|||
|
*
|
|||
|
* None.
|
|||
|
*
|
|||
|
* output parameters
|
|||
|
*
|
|||
|
* 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
|
|||
|
|
|||
|
CLEAR_SLEEP_MODE();
|
|||
|
HAL_EXIT_ISR();
|
|||
|
}
|
|||
|
|