This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

对halSleep函数的一点疑问

Other Parts Discussed in Thread: CC2530, Z-STACK

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模式的。红色标记部分我感觉是什么情况下都能满足的呀