📄 mac_timer.c
字号:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC2430 INTEGRATED 802.15.4 MAC AND PHY *
* *** + + *** Low-Level Timing Functions *
* *** +++ *** *
* *** *** *
* ************ *
* ********** *
* *
*******************************************************************************************************
* CONFIDENTIAL *
* The use of this file is restricted by the signed MAC software license agreement. *
* *
* Copyright Chipcon AS, 2005 *
*******************************************************************************************************
* This module contains the MAC callback timer, which is used to handle timer events, and start the *
* execution of tasks. handles. The timer generates a T1.COMPA interrupt at every *
* 320 usecs = 20 symbols = 1 backoff slot. *
* *
* Command strobes that need to be aligned with backoff slot boundary must use the WAIT_FOR_BOUNADRY() *
* macro. *
* *
* NOTE: These functions are meant to be used with an 32MHz crystal oscillator! *
*******************************************************************************************************/
#include "mac_headers.h"
//-------------------------------------------------------------------------------------------------------
// Callback table and other timer-related variables
__no_init MAC_CALLBACK_INFO __xdata pMtimCallbacks[MAC_CALLBACK_COUNT] @ 0xE000;
__no_init MAC_TIMER_INFO mtimInfo @ "PM0_XDATA";
UINT8 __data firstCallback;
UINT8 __data intAlreadyOff;
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// void mtimInit(void)
//
// DESCRIPTION:
// Initializes Timer 2 for interrupts at every backoff slot
//-------------------------------------------------------------------------------------------------------
ROOT void mtimInit(BOOL synchronousStart) {
UINT8 n;
// Initialize the callback table
for (n = 0; n < MAC_CALLBACK_COUNT; n++) {
pMtimCallbacks[n].occupied = FALSE;
}
// Set head of queue
firstCallback = NO_CALLBACK;
// Configure the timer registers
T2_STOP();
T2_SET_COUNTER(0);
T2_SET_COUNTER_RELOAD_VALUE(32 * 320); // 320 us at 32 MHz
T2_SET_COUNTER_COMPARE_VALUE(HIBYTE(32 * (320 - 32)), FALSE); // 90 %
T2_SET_OVERFLOW_COUNTER(0);
T2_SET_OVERFLOW_COUNTER_COMPARE_VALUE(0);
if (synchronousStart == FALSE)
T2_START_NOSYNC();
else
mtimStartSync ();
// Enable the timer 2 counter overflow flag
T2_CLEAR_COUNTER_OVERFLOW_FLAG();
T2_ENABLE_COUNTER_OVERFLOW_FLAG();
CLEAR_TIMER2_INT();
} // mtimInit
//-------------------------------------------------------------------------------------------------------
// BOOL mtimSetCallback(VFPTR pFunc, INT32 timeout)
//
// DESCRIPTION:
// Activates a timed callback. The callback will happen at [timeout] backoff slots from now.
// Note: There can only be MAC_CALLBACK_COUNT active callbacks.
//
// PARAMETERS:
// VFPTR pFunc
// A pointer to the callback function
// INT32 timeout
// The number of backoff slots to count before calling pFunc(). If this value is negative, the
// function will not be executed.
//
// RETURN VALUE:
// BOOL
// TRUE: OK
// FALSE: Too many active callbacks (>MAC_CALLBACK_COUNT) or invalid timeout value
//-------------------------------------------------------------------------------------------------------
ROOT BOOL mtimSetCallback(VFPTR pFunc, INT32 timeout) {
UINT8 newCallback, prevCallback, n;
MAC_CALLBACK_INFO __xdata *pNewCallback;
// Special timeout values
if (timeout < 0) {
return FALSE;
} else if (timeout == 0) {
pFunc();
return TRUE;
}
DISABLE_GLOBAL_INT();
// Locate an available entry in the callback table
for (newCallback = 0; newCallback < MAC_CALLBACK_COUNT; newCallback++) {
if (!pMtimCallbacks[newCallback].occupied) goto foundIndex;
}
// None available :(
ENABLE_GLOBAL_INT();
return FALSE;
foundIndex:
pNewCallback = &pMtimCallbacks[newCallback];
// No other active callbacks...
if (firstCallback == NO_CALLBACK) {
firstCallback = newCallback;
pNewCallback->nextCallback = NO_CALLBACK;
// Locate insertion point...
} else {
// First timeout?
if (timeout <= pMtimCallbacks[firstCallback].timeout) {
// Insert before!
pNewCallback->nextCallback = firstCallback;
pMtimCallbacks[firstCallback].timeout -= timeout;
firstCallback = newCallback;
// Search through the linked list...
} else {
prevCallback = firstCallback;
n = pMtimCallbacks[prevCallback].nextCallback;
timeout -= pMtimCallbacks[prevCallback].timeout;
while ((timeout > pMtimCallbacks[n].timeout) && (n != NO_CALLBACK)) {
timeout -= pMtimCallbacks[n].timeout;
prevCallback = n;
n = pMtimCallbacks[prevCallback].nextCallback;
}
if (n != NO_CALLBACK) {
pMtimCallbacks[n].timeout -= timeout;
}
pNewCallback->nextCallback = n;
pMtimCallbacks[prevCallback].nextCallback = newCallback;
}
}
// Always set...
pNewCallback->pFunc = pFunc;
pNewCallback->timeout = timeout;
pNewCallback->occupied = TRUE;
ENABLE_GLOBAL_INT();
return TRUE;
} // mtimSetCallback
//-------------------------------------------------------------------------------------------------------
// void mtimeCancelCallback(void *pFunc)
//
// DESCRIPTION:
// Cancels a callback. One entry of pFunc will be removed.
//
// PARAMETERS:
// void *pFunc
// A pointer to the callback function to be removed
//
// RETURN VALUE:
// BOOL
// A match was found and removed
//-------------------------------------------------------------------------------------------------------
ROOT BOOL mtimCancelCallback(void (*pFunc)()) {
UINT8 prevCallback;
UINT8 currCallback;
UINT8 nextCallback;
DISABLE_GLOBAL_INT();
prevCallback = NO_CALLBACK;
currCallback = firstCallback;
while (currCallback != NO_CALLBACK) {
nextCallback = pMtimCallbacks[currCallback].nextCallback;
if ((pFunc == pMtimCallbacks[currCallback].pFunc) && pMtimCallbacks[currCallback].occupied) {
// Deactivate the entry
pMtimCallbacks[currCallback].occupied = FALSE;
// Update the link on the callback before this entry
if (prevCallback != NO_CALLBACK) {
pMtimCallbacks[prevCallback].nextCallback = nextCallback;
}
// Update the link on the next callback entry
if (nextCallback != NO_CALLBACK) {
pMtimCallbacks[nextCallback].timeout += pMtimCallbacks[currCallback].timeout;
}
// Update the firstCallback flag if we cancelled it
if (currCallback == firstCallback) {
firstCallback = nextCallback;
}
// Done :)
ENABLE_GLOBAL_INT();
return TRUE;
}
// Move on to the next entry
prevCallback = currCallback;
currCallback = nextCallback;
}
ENABLE_GLOBAL_INT();
return FALSE;
} // mtimCancelCallback
//-------------------------------------------------------------------------------------------------------
// void mtimAlignWithBeacon(TIMESTAMP *pTimestamp)
//
// DESCRIPTION:
// Adjusts the timer to the last received packet (which should be a beacon!)
//-------------------------------------------------------------------------------------------------------
ROOT void mtimAlignWithBeacon(TIMESTAMP *pTimestamp) {
// Adjust the timestamp for extra 1/4 symbol RX/TX chain delay
pTimestamp->counter -= TRANSMITTER_DELAY;
if (pTimestamp->counter < 0) {
pTimestamp->counter += TIMER2_BACKOFF_SLOT_COUNTER_VALUE;
pTimestamp->overflowCounter--;
}
// Update the MAC timer
T2_SET_OVERFLOW_COUNTER(T2_GET_OVERFLOW_COUNTER() - pTimestamp->overflowCounter);
T2_SET_COUNTER_DELTA_DELAY(pTimestamp->counter);
// Update the "CAP is active" indicator (used by the TX engine)
T2_SET_OVERFLOW_COUNTER_COMPARE_VALUE(msupCalcCapDuration());
T2_SET_CAP_ACTIVE();
} // mtimAlignWithBeacon
//-------------------------------------------------------------------------------------------------------
// void mtimStartSync (void)
//
// DESCRIPTION:
// Start Timer2 in synchronous mode. The routine waits until Timer2 has started
//-------------------------------------------------------------------------------------------------------
ROOT void mtimStartSync (void)
{
BYTE timer2Started;
T2_START_SYNC();
do
{
timer2Started = T2CNF & TIMER2_RUN_BM;
}while (timer2Started == 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -