void halSleep( uint32 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;
} do
{
/* 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);
timeout = 0;
}
/* 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 */
if(HalKeyExitSleep())
{
break; }
#endif
} while(timeout != 0);
/* power on the MAC; blocks until completion */
MAC_PwrOnReq();
HAL_ENABLE_INTERRUPTS();
/* For CC2530, T2 interrupt won抰 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();
}
}
}
上面这个函数是在具体哪一行代码进行区分休眠到底是进入PM2还是PM3模式的。红色标记部分我感觉是什么情况下都能满足的呀
YiKai Chen:
halSleep只会進入PM2
user5281211:
回复 YiKai Chen:
那进入PM3是在哪里体现出来的呀
YiKai Chen:
回复 user5281211:
Z-Stack例程不會進入PM3
user5281211:
回复 YiKai Chen:
不是呀,那论坛里头那么多通过简单的配置就能进入PM3模式是怎么实现的?
YiKai Chen:
回复 user5281211:
如果你需要進入PM3得自行在應用程序中自己加上去
user5281211:
回复 YiKai Chen:
是不是通过控制SLEEPCMD和PCON来控制PM3和终端唤醒?
YiKai Chen:
回复 user5281211:
是的