⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac_timer.c

📁 zigbee location examples
💻 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 + -