📄 mac_timer.c
字号:
#pragma section @@DATA time at 0xED00
#include "includes.h"
//#pragma section @@DATA time at 0xEB00
//-------------------------------------------------------------------------------------------------------
// Callback table and other timer-related variables
MAC_CALLBACK_INFO pMtimCallbacks[MAC_CALLBACK_COUNT];
MAC_TIMER_INFO mtimInfo;
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// void mtimInit(void)
//
// DESCRIPTION:
// Initializes Timer 1 of the ATMEGA128/64 for interrupts at every backoff slot.
//-------------------------------------------------------------------------------------------------------
void mtimInit(void) {
UINT8 n;
// Initialize the callback table / queue
for (n = 0; n < MAC_CALLBACK_COUNT; n++) {
pMtimCallbacks[n].occupied = FALSE;
}
mtimInfo.nextCallback = NO_CALLBACK;
// Reset time stamps and counters
mtimInfo.bosCounter = 0;
mtimInfo.captureBosCounter = 0;
mtimInfo.captureTcnt = 0;
mtimInfo.captureTime = 0;
mtimInfo.bosCounterAdjustTime = 0;
// Configure the timer registers
/// TIMER1_INIT(TIMER1_CAPTURE_NOISE_CANCELLER | TIMER1_CAPTURE_ON_POSEDGE);
/// TIMER1_SET_COMPA_VALUE(MAC_TIMER_OVERFLOW_VALUE);
/// TIMER1_SET_COMPB_VALUE(MAC_TIMER_BACKOFF_SLOT_OFFSET);
} // mtimInit
//-------------------------------------------------------------------------------------------------------
// ZBOOL 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:
// ZBOOL
// TRUE: OK
// FALSE: Too many active callbacks (>MAC_CALLBACK_COUNT) or invalid timeout value
//-------------------------------------------------------------------------------------------------------
ZBOOL mtimSetCallback(VFPTR pFunc, INT32 timeout) {
UINT8 newCallback, prevCallback, n;
MAC_CALLBACK_INFO *pNewCallback;
// Special timeout values
if (timeout < 0) {
return FALSE;
} else if (timeout == 0) {
pFunc();
return TRUE;
}
// Locate an available entry in the callback table
DISABLE_GLOBAL_INT();
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 (mtimInfo.nextCallback == NO_CALLBACK) {
mtimInfo.nextCallback = newCallback;
pNewCallback->prevCallback = NO_CALLBACK;
pNewCallback->nextCallback = NO_CALLBACK;
// Locate insertion point...
} else {
// First timeout?
if (timeout <= pMtimCallbacks[mtimInfo.nextCallback].timeout) {
// Insert before!
pNewCallback->prevCallback = NO_CALLBACK;
pNewCallback->nextCallback = mtimInfo.nextCallback;
pMtimCallbacks[mtimInfo.nextCallback].timeout -= timeout;
pMtimCallbacks[mtimInfo.nextCallback].prevCallback = newCallback;
mtimInfo.nextCallback = newCallback;
// Search through the linked list...
} else {
prevCallback = mtimInfo.nextCallback;
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;
pMtimCallbacks[n].prevCallback = newCallback;
}
pNewCallback->prevCallback = prevCallback;
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:
// ZBOOL
// A match was found and removed
//-------------------------------------------------------------------------------------------------------
ZBOOL mtimCancelCallback(void *pFunc) {
UINT8 n, prevIndex, nextIndex;
DISABLE_GLOBAL_INT();
// Search through the whole array
for (n = 0; n < MAC_CALLBACK_COUNT; n++) {
if ((pFunc == pMtimCallbacks[n].pFunc) && pMtimCallbacks[n].occupied) {
// Deactivate the entry
pMtimCallbacks[n].occupied = FALSE;
// Get the indexes of the previous and the next entries
prevIndex = pMtimCallbacks[n].prevCallback;
nextIndex = pMtimCallbacks[n].nextCallback;
// Update the link on the callback before this entry
if (prevIndex != NO_CALLBACK) {
pMtimCallbacks[prevIndex].nextCallback = nextIndex;
}
// Update the link on the next callback entry
if (nextIndex != NO_CALLBACK) {
pMtimCallbacks[nextIndex].prevCallback = prevIndex;
pMtimCallbacks[nextIndex].timeout += pMtimCallbacks[n].timeout;
}
// Update nextCallback if the removed callback was the first entry
if (n == mtimInfo.nextCallback) mtimInfo.nextCallback = pMtimCallbacks[n].nextCallback;
ENABLE_GLOBAL_INT();
return TRUE;
}
}
ENABLE_GLOBAL_INT();
return FALSE;
} // mtimeCancelCallback
//-------------------------------------------------------------------------------------------------------
// void mtimAlignWithBeacon(void)
//
// DESCRIPTION:
// Adjusts the timer to the last received packet (which should be a beacon!)
//-------------------------------------------------------------------------------------------------------
void mtimAlignWithBeacon(void) {
DISABLE_GLOBAL_INT();
// Delay the next timer tick
/// OCR1A = MAC_TIMER_OVERFLOW_VALUE + mtimInfo.captureTcnt - (MAC_TIMER_BACKOFF_SLOT_OFFSET + 322 - 1);
mtimInfo.bosCounter -= mtimInfo.captureBosCounter;
// Clear the compare(A) interrupt flag
/// TIFR = BM(OCF1A);
// Set the beacon "time stamp"
mtimInfo.bosCounterAdjustTime += (mtimInfo.captureBosCounter * (UINT32) MAC_SYMBOL_DURATION * (UINT32) aUnitBackoffPeriod) + (UINT32) mtimInfo.captureTcnt / CLOCK_SPEED_MHZ;
ENABLE_GLOBAL_INT();
} // mtimAlignWithBeacon
//-------------------------------------------------------------------------------------------------------
// SIGNAL(SIG_INPUT_CAPTURE1)
//
// DESCRIPTION:
// This interrupt is trigged when the CC2420 SFD pin goes high at the start of a transmitted/
// received frame. The ISR generates a time stamp to be used with beacons.
//-------------------------------------------------------------------------------------------------------
/*SIGNAL(SIG_INPUT_CAPTURE1) {
mtimInfo.captureTcnt = ICR1;
mtimInfo.captureBosCounter = mtimInfo.bosCounter;
if ((TCNT1 > ICR1) && BM(OCF1A)){
mtimInfo.captureBosCounter++;
}
mtimInfo.captureTime = mtimInfo.bosCounterAdjustTime + (mtimInfo.captureBosCounter * MAC_SYMBOL_DURATION * aUnitBackoffPeriod) + (UINT32) mtimInfo.captureTcnt / CLOCK_SPEED_MHZ;
}*/ // SIGNAL(SIG_INPUT_CAPTURE1) --li
//-------------------------------------------------------------------------------------------------------
// SIGNAL(SIG_OUTPUT_COMPARE1A)
//
// DESCRIPTION:
// Timer tick interrupt at an interval of 320 us.
// Handles callback timers, and initiates task execution at every backoff slot boundary.
// The FIFOP interrupt is turned off initially, and can (optionally) be turned back on by running
// tasks.
//-------------------------------------------------------------------------------------------------------
//SIGNAL(SIG_OUTPUT_COMPARE1A) {
// MAC_CALLBACK_INFO *pMCI;
//
// // Clear the flag which is used to trigger WAIT_FOR_BOUNDARY()
// TIFR = BM(OCF1B);
//
// // Reset the overflow flag (could be modified to skew the timing)
// OCR1A = MAC_TIMER_OVERFLOW_VALUE;
//
// // Disable the FIFOP interrupt to make sure that it won't interrupt the callbacks
// DISABLE_FIFOP_INT();
// DISABLE_T1_COMPC_INT();
//
//
// // Handle callbacks
// if (mtimInfo.nextCallback != NO_CALLBACK) {
// pMCI = &pMtimCallbacks[mtimInfo.nextCallback];
// if (!--pMCI->timeout) {
//callback: mtimInfo.nextCallback = pMCI->nextCallback;
// pMCI->occupied = FALSE;
// pMCI->pFunc();
// DISABLE_GLOBAL_INT();
// if (mtimInfo.nextCallback != NO_CALLBACK) {
// pMCI = &pMtimCallbacks[mtimInfo.nextCallback];
// pMCI->prevCallback = NO_CALLBACK;
// if (!pMCI->timeout) goto callback;
// }
// }
// }
// mtimInfo.bosCounter++;
//
// // Handle tasks
// ENABLE_GLOBAL_INT();
// mschDoTask();
//
// // Some tasks will enable the FIFOP interrupt, and others will not.
// // Anyway, make sure that we leave from this interrupt in the correct state
// DISABLE_GLOBAL_INT();
// DISABLE_T1_COMPC_INT();
// if (mrxInfo.keepFifopIntOff) {
// DISABLE_FIFOP_INT();
// } else {
// ENABLE_FIFOP_INT();
// }
//
//} // SIGNAL(SIG_OUTPUT_COMPARE1A) --li
//-------------------------------------------------------------------------------------------------------
// SIGNAL(SIG_OUTPUT_COMPARE1C)
//
// DESCRIPTION:
// Used by the FIFOP interrupt to make sure that is enabled a short while after it has returned.
// This allows for timer ticks in between, which has a lower priority than the FIFOP interrupt.
//-------------------------------------------------------------------------------------------------------
//SIGNAL(SIG_OUTPUT_COMPARE1C) {
// ENABLE_FIFOP_INT();
// DISABLE_T1_COMPC_INT();
//} // SIGNAL(SIG_OUTPUT_COMPARE1C) --li
/*******************************************************************************************************
* Revision history:
*
* $Log: mac_timer.c,v $
* Revision 1.10 2004/11/11 09:39:23 thl
* Fixed SIGNAL(SIG_INPUT_CAPTURE1) function
*
* Revision 1.9 2004/11/10 09:33:15 thl
* Fixed a number of bugs according to: MAC software check lists.xls
*
* Revision 1.8 2004/08/13 13:04:48 jol
* CC2420 MAC Release v0.7
*
*
*******************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -