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

📄 mac_rx.c

📁 TI的基于ZIGBEE2006的协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************************************
    Filename:
    Revised:        $Date: 2007-03-28 18:21:19 -0700 (Wed, 28 Mar 2007) $
    Revision:       $Revision: 13888 $

    Description:

    Describe the purpose and contents of the file.

    Copyright (c) 2006 by Texas Instruments, Inc.
    All Rights Reserved.  Permission to use, reproduce, copy, prepare
    derivative works, modify, distribute, perform, display or sell this
    software and/or its documentation for any purpose is prohibited
    without the express written consent of Texas Instruments, Inc.
**************************************************************************************************/



/* ------------------------------------------------------------------------------------------------
 *                                          Includes
 * ------------------------------------------------------------------------------------------------
 */

/* hal */
#include "hal_defs.h"
#include "hal_types.h"

/* high-level */
#include "mac_high_level.h"
#include "mac_spec.h"

/* exported low-level */
#include "mac_low_level.h"

/* low-level specific */
#include "mac_rx.h"
#include "mac_tx.h"
#include "mac_rx_onoff.h"
#include "mac_radio.h"

/* target specific */
#include "mac_radio_defs.h"

/* debug */
#include "mac_assert.h"


/* ------------------------------------------------------------------------------------------------
 *                                            Defines
 * ------------------------------------------------------------------------------------------------
 */
#define MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT   16   /* adjustable to tune performance */

/* receive FIFO bytes needed to start a valid receive (see function rxStartIsr for details) */
#define RX_THRESHOLD_START_LEN    (MAC_PHY_PHR_LEN        +  \
                                   MAC_FCF_FIELD_LEN      +  \
                                   MAC_SEQ_NUM_FIELD_LEN  +  \
                                   MAC_FCS_FIELD_LEN)

/* maximum size of addressing fields (note: command frame identifier processed as part of address) */
#define MAX_ADDR_FIELDS_LEN  ((MAC_EXT_ADDR_FIELD_LEN + MAC_PAN_ID_FIELD_LEN) * 2)

/* addressing mode reserved value */
#define ADDR_MODE_RESERVERED  1

/* length of command frame identifier */
#define CMD_FRAME_ID_LEN      1

/* packet size mask is equal to the maximum value */
#define PHY_PACKET_SIZE_MASK  0x7F

/* value for promiscuous off, must not conflict with other mode variants from separate include files */
#define PROMISCUOUS_MODE_OFF  0x00

/* bit of proprietary FCS format that indicates if the CRC is OK */
#define PROPRIETARY_FCS_CRC_OK_BIT  0x80

/* dummy length value for unused entry in lookup table */
#define DUMMY_LEN   0xBE

/* value for rxThresholdIntState */
#define RX_THRESHOLD_INT_STATE_INACTIVE   0
#define RX_THRESHOLD_INT_STATE_ACTIVE     1
#define RX_THRESHOLD_INT_STATE_RESET      2


/* ------------------------------------------------------------------------------------------------
 *                                             Macros
 * ------------------------------------------------------------------------------------------------
 */
#define MEM_ALLOC(x)   macDataRxMemAlloc(x)
#define MEM_FREE(x)    macDataRxMemFree((uint8 *)x)

/*
 *  Macro for encoding frame control information into internal flags format.
 *  Parameter is pointer to the frame.  NOTE!  If either the internal frame
 *  format *or* the specification changes, this macro will need to be modified.
 */
#define INTERNAL_FCF_FLAGS(p)  ((((p)[1] >> 4) & 0x03) | ((p)[0] & 0x78))

/*
 *  The radio replaces the actual FCS with different information.  This proprietary FCS is
 *  the same length as the original and includes:
 *    1) the RSSI value
 *    2) the average correlation value (used for LQI)
 *    3) a CRC passed bit
 *
 *  These macros decode the proprietary FCS.  The macro parameter is a pointer to the two byte FCS.
 */
#define PROPRIETARY_FCS_RSSI(p)                 ((int8)((p)[0]))
#define PROPRIETARY_FCS_CRC_OK(p)               ((p)[1] & PROPRIETARY_FCS_CRC_OK_BIT)
#define PROPRIETARY_FCS_CORRELATION_VALUE(p)    ((p)[1] & ~PROPRIETARY_FCS_CRC_OK_BIT)


/* ------------------------------------------------------------------------------------------------
 *                                       Global Variables
 * ------------------------------------------------------------------------------------------------
 */
uint8 macRxActive;
uint8 macRxFilter;
uint8 macRxOutgoingAckFlag;


/* ------------------------------------------------------------------------------------------------
 *                                       Local Constants
 * ------------------------------------------------------------------------------------------------
 */
static const uint8 CODE macRxAddrLen[] =
{
  0,                                                /* no address */
  DUMMY_LEN,                                        /* reserved */
  MAC_PAN_ID_FIELD_LEN + MAC_SHORT_ADDR_FIELD_LEN,  /* short address + pan id */
  MAC_PAN_ID_FIELD_LEN + MAC_EXT_ADDR_FIELD_LEN     /* extended address + pan id */
};


/* ------------------------------------------------------------------------------------------------
 *                                       Local Prototypes
 * ------------------------------------------------------------------------------------------------
 */
static void rxHaltCleanupFinalStep(void);

static void rxStartIsr(void);
static void rxAddrIsr(void);
static void rxPayloadIsr(void);
static void rxDiscardIsr(void);
static void rxFcsIsr(void);

static void rxPrepPayload(void);
static void rxDiscardFrame(void);
static void rxDone(void);
static void rxPostRxUpdates(void);


/* ------------------------------------------------------------------------------------------------
 *                                         Local Variables
 * ------------------------------------------------------------------------------------------------
 */
static void    (* pFuncRxState)(void);
static macRx_t  * pRxBuf;

static uint8  rxBuf[MAC_PHY_PHR_LEN + MAC_FCF_FIELD_LEN + MAC_SEQ_NUM_FIELD_LEN];
static uint8  rxUnreadLen;
static uint8  rxNextLen;
static uint8  rxPayloadLen;
static uint8  rxFilter;
static uint8  rxPromiscuousMode;
static uint8  rxIsrActiveFlag;
static uint8  rxResetFlag;


/**************************************************************************************************
 * @fn          macRxInit
 *
 * @brief       Initialize receive variable states.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macRxInit(void)
{
  macRxFilter          = RX_FILTER_OFF;
  rxPromiscuousMode    = PROMISCUOUS_MODE_OFF;
  pRxBuf               = NULL; /* required for macRxReset() to function correctly */
  macRxActive          = MAC_RX_ACTIVE_NO_ACTIVITY;
  pFuncRxState         = &rxStartIsr;
  macRxOutgoingAckFlag = 0;
  rxIsrActiveFlag      = 0;
  rxResetFlag          = 0;
}


/**************************************************************************************************
 * @fn          macRxRadioPowerUpInit
 *
 * @brief       Initialization for after radio first powers up.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macRxRadioPowerUpInit(void)
{
  /* set threshold at initial value */
  MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);

  /* clear any accidental threshold interrupt that happened as part of power up sequence */
  MAC_RADIO_CLEAR_RX_THRESHOLD_INTERRUPT_FLAG();

  /* enable threshold interrupts */
  MAC_RADIO_ENABLE_RX_THRESHOLD_INTERRUPT();
}


/**************************************************************************************************
 * @fn          macRxTxReset
 *
 * @brief       Reset the receive state.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macRxTxReset(void)
{
  /* forces receiver off, cleans up by calling macRxHaltCleanup() and macTxHaltCleanup() */
  macRxHardDisable();

  /*
   *   Note : transmit does not require any reset logic
   *          beyond what macRxHardDisable() provides.
   */

  /* restore deault filter mode to off */
  macRxFilter = RX_FILTER_OFF;

  /* return promiscuous mode to default off state */
  macRxPromiscuousMode(MAC_PROMISCUOUS_MODE_OFF);
}


/**************************************************************************************************
 * @fn          macRxHaltCleanup
 *
 * @brief       Cleanup up the receive logic after receiver is forced off.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macRxHaltCleanup(void)
{
  rxResetFlag = 1;
  if (!rxIsrActiveFlag)
  {
    rxHaltCleanupFinalStep();
    rxResetFlag = 0;
  }
}


/*=================================================================================================
 * @fn          rxHaltCleanupFinalStep
 *
 * @brief       Required cleanup if receiver is halted in the middle of a receive.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxHaltCleanupFinalStep(void)
{
  /* cancel any upcoming ACK transmit complete callback */
  MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK();

  /* set start of frame threshold */
  MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);

  /* flush the receive FIFO */
  MAC_RADIO_FLUSH_RX_FIFO();

  /* clear any receive interrupt that happened to squeak through */
  MAC_RADIO_CLEAR_RX_THRESHOLD_INTERRUPT_FLAG();

  /* if data buffer has been allocated, free it */
  if (pRxBuf != NULL)
  {
    MEM_FREE((uint8 *) pRxBuf);
  }
  pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */

  pFuncRxState = &rxStartIsr;

  /* if receive was active, perform the post receive updates */
  if (macRxActive || macRxOutgoingAckFlag)
  {
    macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
    macRxOutgoingAckFlag = 0;
    
    rxPostRxUpdates();
  }
}


/**************************************************************************************************
 * @fn          macRxThresholdIsr
 *
 * @brief       Interrupt service routine called when bytes in FIFO reach threshold value.
 *              It implements a state machine for receiving a packet.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macRxThresholdIsr(void)
{
  /* if currently reseting, do not execute receive ISR logic */
  if (rxResetFlag)
  {
    return;
  }
  
  /*
   *  Call the function that handles the current receive state.
   *  A flag is set for the duration of the call to indicate
   *  the ISR is executing.  This is necessary for the reset
   *  logic so it does not perform a reset in the middle of
   *  executing the ISR.
   */
  rxIsrActiveFlag = 1;
  (*pFuncRxState)();
  rxIsrActiveFlag = 0;
  
  /* if a reset occurred during the ISR, peform cleanup here */
  if (rxResetFlag)
  {
    rxHaltCleanupFinalStep();
    rxResetFlag = 0;
  }
}


/*=================================================================================================
 * @fn          rxStartIsr
 *
 * @brief       First ISR state for receiving a packet - compute packet length, allocate
 *              buffer, initialize buffer.  Acknowledgements are handled immediately without
 *              allocating a buffer.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxStartIsr(void)
{
  uint8  addrLen;
  uint8  ackWithPending;
  uint8  dstAddrMode;
  uint8  srcAddrMode;

  MAC_ASSERT(!macRxActive); /* receive on top of receive */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -