📄 mac_power_management.c
字号:
// is also resumed as part of this routine. RxOnWhenIdle is restored to its value prior to the call
// of this routine.
// The external interrupt or the sleep timer interrupt must be intialized prior to the call of this
// routine.
//
// ARGUMENTS:
// POWER_MODE powerMode
// Power mode according to data sheet for CC2430
// POWER_MODE_PM1 Voltage regulator to the digital part is on. High speed oscillator is off,
// low speed oscillator is on
// POWER_MODE_PM2 Voltage regulator to the digital part is off. High speed oscillator is off,
// low speed oscillator is on
// POWER_MODE_PM3 Voltage regulator to the digital part is off. All oscillators is off.
//
// RESUME_MODE resumeMode
// Depends on how much of the MAC variables that was preserved during power down. In power control
// PM1 or when all data are places in upper 4 kRAM, RESUME_MODE_ALL_PRESERVED can be used. The
// XDATA segment and the PM0_XDATA segment must be located in upper 4 kRAM.
// If the PM0_XDATA segment is located in lower 4 kRAM and XDATA in upper 4 kRAM,
// the RESUME_MODE_PARTS_PRESERVED must be used.
// RESUME_MODE_ALL_PRESERVED, restarts only timer2
// RESUME_MODE_PARTS_PRESERVED restarts timer2, the task and memory pool system
//
// BOOL synchronousStart
// FALSE Start timer2 immediate
// TRUE Start timer2 synchronous with external 32.768 kHz clock
//
//-------------------------------------------------------------------------------------------------------
ROOT void mpmSetAndResumeMacAndCpuPowerMode (POWER_MODE powerMode,
RESUME_MODE resumeMode,
BOOL synchronousStart)
{
BYTE rxOnWhenIdle;
mpmPowerDownMac (&rxOnWhenIdle);
// Power down cpu
SLEEP &= 0xFC;
switch (powerMode)
{
case POWER_MODE_PM1:
SLEEP |= CC2430_PM1;
break;
case POWER_MODE_PM2:
SLEEP |= CC2430_PM2;
break;
case POWER_MODE_PM3:
SLEEP |= CC2430_PM3;
break;
}
PCON = 1;
// CPU will HALT here. Processing is resumed when an external interrupt or a sleep timer interrupt
// occurs
// Correction of active power up bug
asm("NOP");
asm("NOP");
mpmResumeMacAfterPowerDown (resumeMode,
synchronousStart,
rxOnWhenIdle);
}
//-------------------------------------------------------------------------------------------------------
// ROOT void mpmPowerDownMac (BYTE *rxOnWhenIdle)
//
// DESCRIPTION:
// Stops MAC prosessing and turns the radio off.
//
// ARGUMENTS:
// BYTE rxOnWhenIdle
// Contains the value of rxOnWhenIdle prior to power down
//
//-------------------------------------------------------------------------------------------------------
ROOT void mpmPowerDownMac (BYTE *rxOnWhenIdle)
{
BYTE setAttributeValue;
mlmeGetRequest (MAC_RX_ON_WHEN_IDLE, rxOnWhenIdle);
setAttributeValue = FALSE;
mlmeSetRequest (MAC_RX_ON_WHEN_IDLE, &setAttributeValue);
// Power down
mpmSetRequest(MPM_CC2430_XOSC_AND_VREG_OFF);
while (mpmGetState() != MPM_CC2430_XOSC_AND_VREG_OFF);
}
//-------------------------------------------------------------------------------------------------------
// void mpmResumeMacAfterPowerDown (RESUME_MODE resumeMode,
// BOOL synchronousStart,
// BOOL rxOnWhenIdle)
//
// DESCRIPTION:
// Resumes the mac protocol after a power down
//
// ARGUMENTS:
// RESUME_MODE resumeMode
// Depends on how much of the MAC variables that was preserved during power down. In power control
// PM1 or when all data are places in upper 4 kRAM, RESUME_MODE_ALL_PRESERVED can be used. The
// XDATA segment and the PM0_XDATA segment must be located in upper 4 kRAM.
// If the PM0_XDATA segment is located in lower 4 kRAM and XDATA in upper 4 kRAM,
// the RESUME_MODE_PARTS_PRESERVED must be used.
// RESUME_MODE_ALL_PRESERVED, restarts only timer2. The fastest and less power consuming mode
// RESUME_MODE_PARTS_PRESERVED restarts timer2, the task and memory pool system
//
// BOOL synchronousStart
// FALSE Start timer2 immediate
// TRUE Start timer2 synchronous with external 32.768 kHz clock
//
// BOOL rxOnWhenIdle
// FALSE RX is off
// TRUE Turn RX on
//-------------------------------------------------------------------------------------------------------
ROOT void mpmResumeMacAfterPowerDown (RESUME_MODE resumeMode,
BOOL synchronousStart,
BOOL rxOnWhenIdle)
{
BYTE setAttributeValue;
WORD mdmctrl0;
switch (resumeMode)
{
case RESUME_MODE_ALL_PRESERVED:
DISABLE_GLOBAL_INT();
if (synchronousStart == FALSE)
T2_START_NOSYNC ();
else
mtimStartSync ();
ENABLE_TIMER2_INT();
macInfo.state = MAC_STATE_DEFAULT;
// Power up radio
mpmSetRequest(MPM_CC2430_ON);
while (mpmGetState() != MPM_CC2430_ON);
DISABLE_TIMER2_INT();
break;
case RESUME_MODE_PARTS_PRESERVED:
DISABLE_GLOBAL_INT();
InitializeCommonStorage ();
InitializeDma ();
InitializeRfInterrupts ();
mschInit();
mtimInit(synchronousStart);
ENABLE_TIMER2_INT();
macInfo.state = MAC_STATE_DEFAULT;
// Power up radio
mpmSetRequest(MPM_CC2430_ON);
while (mpmGetState() != MPM_CC2430_ON);
DISABLE_TIMER2_INT();
// Initialize variables in the various modules
mrxpInit();
mtxpInit();
#if MAC_OPT_FFD
miqInit();
#endif
mtxInfo.startTxTask = mschReserveTask();
mrxInfo.state = MRX_STATE_LEN_FCF_SEQ;
mbcnInfo.rxTaskNumber = NO_TASK;
mbcnInfo.txTaskNumber = NO_TASK;
mbcnInfo.pTxPacket = NULL;
mscInfo.scanStatus = MSC_STATUS_FINISHED;
break;
}
// Reset flags
RESET_MF();
// MAC command state
macInfo.state = MAC_STATE_DEFAULT;
// Flush the RX FIFO twice (chip bug)
ISFLUSHRX;
ISFLUSHRX;
ISFLUSHTX;
ISFLUSHTX;
// Resume coordinator
#pragma diag_suppress=PA082
mdmctrl0 = READ_RFR16(MDMCTRL0);
#pragma diag_default=PA082
if (mdmctrl0 & PAN_COORDINATOR_BM)
ResumeCoordinatorAfterPowerDown (resumeMode, synchronousStart);
else
ResumeDeviceAfterPowerDown (resumeMode, synchronousStart);
// Turn the interrupts back on
EnableRfInterrupts ();
ENABLE_TIMER2_INT();
ENABLE_GLOBAL_INT();
// Turn on receiver
if (rxOnWhenIdle == TRUE)
{
setAttributeValue = TRUE;
mlmeSetRequest(MAC_RX_ON_WHEN_IDLE, &setAttributeValue);
}
}
//-------------------------------------------------------------------------------------------------------
// static void ResumeCoordinatorAfterPowerDown (RESUME_MODE resumeMode)
// BOOL synchronousStart)
//
// DESCRIPTION:
// Resumes the coordinator after a power down
//
//-------------------------------------------------------------------------------------------------------
static void ResumeCoordinatorAfterPowerDown (RESUME_MODE resumeMode, BOOL synchronousStart)
{
if (mpib.macBeaconOrder == 15)
mtimSetCallback(mbcnExpirePacketsNonBeacon, (UINT32)(aBaseSuperframeDuration / aUnitBackoffPeriod));
}
//-------------------------------------------------------------------------------------------------------
// static void ResumeDeviceAfterPowerDown (RESUME_MODE resumeMode,
// BOOL synchronousStart)
//
// DESCRIPTION:
// Resumes a device after a power down
//
//-------------------------------------------------------------------------------------------------------
static void ResumeDeviceAfterPowerDown (RESUME_MODE resumeMode, BOOL synchronousStart)
{
BYTE setAttributeValue;
// Beacon network ?
if ((mpib.macBeaconOrder != 15) && (synchronousStart == FALSE))
{
switch (resumeMode)
{
case RESUME_MODE_ALL_PRESERVED:
setAttributeValue = mpib.macBeaconOrder;
mpib.macBeaconOrder = 0;
mlmeSetRequest(MAC_BEACON_ORDER, &setAttributeValue);
// Synchronize with the beacon in case of a beacon-enabled PAN
mlmeSyncRequest(ppib.phyCurrentChannel, TRUE);
break;
case RESUME_MODE_PARTS_PRESERVED:
setAttributeValue = mpib.macBeaconOrder;
mpib.macBeaconOrder = 0;
mlmeSetRequest(MAC_BEACON_ORDER, &setAttributeValue);
// Synchronize with the beacon in case of a beacon-enabled PAN
mlmeSyncRequest(ppib.phyCurrentChannel, TRUE);
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -