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

📄 mac_rx.c

📁 TI的基于ZIGBEE2006的协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
      pRxBuf->mac.srcAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]);
    }
  }

  /*-------------------------------------------------------------------------------
   *  Prepare for payload interrupts.
   */
  pFuncRxState = &rxPayloadIsr;
  rxPrepPayload();
}


/*=================================================================================================
 * @fn          rxPrepPayload
 *
 * @brief       Common code to prepare for the payload ISR.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxPrepPayload(void)
{
  if (rxPayloadLen == 0)
  {
    MAC_RADIO_SET_RX_THRESHOLD(MAC_FCS_FIELD_LEN);
    pFuncRxState = &rxFcsIsr;
  }
  else
  {
    rxNextLen = MIN(rxPayloadLen, MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT);
    MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
  }
}


/*=================================================================================================
 * @fn          rxPayloadIsr
 *
 * @brief       Receive ISR state for reading out and storing the packet payload.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxPayloadIsr(void)
{
  MAC_RADIO_READ_RX_FIFO(pRxBuf->msdu.p, rxNextLen);
  pRxBuf->msdu.p += rxNextLen;
  rxPayloadLen -= rxNextLen;

  rxPrepPayload();
}


/*=================================================================================================
 * @fn          rxFcsIsr
 *
 * @brief       Receive ISR state for handling the FCS.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxFcsIsr(void)
{
  uint8 crcOK;

  /* read FCS, rxBuf is now available storage */
  MAC_RADIO_READ_RX_FIFO(rxBuf, MAC_FCS_FIELD_LEN);

  /*
   *  The FCS has actually been replaced within the radio by a proprietary version of the FCS.
   *  This proprietary FCS is two bytes (same length as the real FCS) and contains:
   *    1) the RSSI value
   *    2) the average correlation value (used for LQI)
   *    3) a CRC passed bit
   */

  /* save the "CRC-is-OK" status */
  crcOK = PROPRIETARY_FCS_CRC_OK(rxBuf);

  /*
   *  See if the frame should be passed up to high-level MAC.  If the CRC is OK, the
   *  the frame is always passed up.  Frames with a bad CRC are also passed up *if*
   *  a special variant of promiscuous mode is active.
   */
  if (crcOK || (rxPromiscuousMode == MAC_PROMISCUOUS_MODE_WITH_BAD_CRC))
  {
    int8 rssiDbm;
    uint8 corr;

    /*
     *  As power saving optimization, set state variable to indicate physical receive
     *  has completed and then request turning of the receiver.  This means the receiver
     *  can be off (if other conditions permit) during execution of the callback function.
     *
     *  The receiver will be requested to turn off once again at the end of the receive
     *  logic.  There is no harm in doing this.
     */
    macRxActive = MAC_RX_ACTIVE_DONE;
    macRxOffRequest();
    
    /* decode RSSI and correlation values */
    rssiDbm = PROPRIETARY_FCS_RSSI(rxBuf) + MAC_RADIO_RSSI_OFFSET;
    corr = PROPRIETARY_FCS_CORRELATION_VALUE(rxBuf);
    
    /* record parameters that get passed up to high-level */
    pRxBuf->internal.flags |= crcOK;
    pRxBuf->mac.mpduLinkQuality = macRadioComputeLQI(rssiDbm, corr);
    pRxBuf->mac.rssi = rssiDbm;
    pRxBuf->mac.correlation = corr;

    /* set the MSDU pointer to point at start of data */
    pRxBuf->msdu.p = (uint8 *) (pRxBuf + 1);
    
    /* finally... execute callback function */
    macRxCompleteCallback(pRxBuf);
    pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */
  }
  else
  {
    /*
     *  The CRC is bad so no ACK was sent.  Cancel any callback and clear the flag.
     *  (It's OK to cancel the outgoing ACK even if an ACK was not requested.  It's
     *  slightly more efficient to do so.)
     */
    MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK();
    macRxOutgoingAckFlag = 0;

    /* the CRC failed so the packet must be discarded */
    MEM_FREE((uint8 *) pRxBuf);
    pRxBuf = NULL;  /* needed to indicate buffer is no longer allocated */
  }

  /* reset threshold level, reset receive state, and complete receive logic */
  MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);
  pFuncRxState = &rxStartIsr;
  rxDone();
}


/*=================================================================================================
 * @fn          rxDone
 *
 * @brief       Common exit point for receive.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxDone(void)
{
  /* if the receive FIFO has overflowed, flush it here */
  if (MAC_RADIO_RX_FIFO_HAS_OVERFLOWED())
  {
    MAC_RADIO_FLUSH_RX_FIFO();
  }

  /* mark receive as inactive */
  macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;

  /* if there is no outgoing ACK, run the post receive updates */
  if (!macRxOutgoingAckFlag)
  {
    rxPostRxUpdates();
  }
}


/**************************************************************************************************
 * @fn          macRxAckTxDoneCallback
 *
 * @brief       Function called when the outoing ACK has completed transmitting.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macRxAckTxDoneCallback(void)
{
  macRxOutgoingAckFlag = 0;

  /*
   *  With certain interrupt priorities and timing conditions, it is possible this callback
   *  could be executed before the primary receive logic completes.  To prevent this, the
   *  post updates are only executed if receive logic is no longer active.  In the case the
   *  post updates are not executed here, they will execute when the main receive logic
   *  completes.
   */  
  if (!macRxActive)
  {
    rxPostRxUpdates();
  }
}


/*=================================================================================================
 * @fn          rxPostRxUpdates
 *
 * @brief       Updates that need to be performed once receive is complete.
 *
 *              It is not fatal to execute this function if somehow receive is active.  Under
 *              certain timing/interrupt conditions a new receive may have started before this
 *              function executes.  This should happen very rarely (if it happens at all) and
 *              would cause no problems.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxPostRxUpdates(void)
{
  /* turn off receiver if permitted */
  macRxOffRequest();
  
  /* update the transmit power, update may have been blocked by transmit of outgoing ACK */
  macRadioUpdateTxPower();
  
  /* initiate and transmit that was queued during receive */
  macTxStartQueuedFrame();
}


/*=================================================================================================
 * @fn          rxDiscardFrame
 *
 * @brief       Initializes for discarding a packet.  Must be called before ACK is strobed.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxDiscardFrame(void)
{
  MAC_ASSERT(pFuncRxState == &rxStartIsr); /* illegal state for calling discard frame function */

  if (rxUnreadLen == 0)
  {
    rxDone();
  }
  else
  {
    rxNextLen = MIN(rxUnreadLen, MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT);
    MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
    pFuncRxState = &rxDiscardIsr;
  }
}


/*=================================================================================================
 * @fn          rxDiscardIsr
 *
 * @brief       Receive ISR state for discarding a packet.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxDiscardIsr(void)
{
  uint8 buf[MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT];

  MAC_RADIO_READ_RX_FIFO(buf, rxNextLen);
  rxUnreadLen -= rxNextLen;

  /* read out and discard bytes until all bytes of packet are disposed of */
  if (rxUnreadLen != 0)
  {
    if (rxUnreadLen < MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT)
    {
      rxNextLen = rxUnreadLen;
      MAC_RADIO_SET_RX_THRESHOLD(rxNextLen);
    }
  }
  else
  {
    /* reset threshold level, reset receive state, and complete receive logic */
    MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN);
    pFuncRxState = &rxStartIsr;
    rxDone();
  }
}


/**************************************************************************************************
 * @fn          macRxPromiscuousMode
 *
 * @brief       Sets promiscuous mode - enabling or disabling it.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macRxPromiscuousMode(uint8 mode)
{
  rxPromiscuousMode = mode;

  if (rxPromiscuousMode == MAC_PROMISCUOUS_MODE_OFF)
  {
      MAC_RADIO_TURN_ON_RX_FRAME_FILTERING();
  }
  else
  {
    MAC_ASSERT((mode == MAC_PROMISCUOUS_MODE_WITH_BAD_CRC)   ||
               (mode == MAC_PROMISCUOUS_MODE_COMPLIANT));  /* invalid mode */

    MAC_RADIO_TURN_OFF_RX_FRAME_FILTERING();
  }
}



/**************************************************************************************************
 *                                  Compile Time Integrity Checks
 **************************************************************************************************
 */

/* check for changes to the spec that would affect the source code */
#if ((MAC_A_MAX_PHY_PACKET_SIZE   !=  0x7F )   ||  \
     (MAC_FCF_FIELD_LEN           !=  2    )   ||  \
     (MAC_FCF_FRAME_TYPE_POS      !=  0    )   ||  \
     (MAC_FCF_FRAME_PENDING_POS   !=  4    )   ||  \
     (MAC_FCF_ACK_REQUEST_POS     !=  5    )   ||  \
     (MAC_FCF_INTRA_PAN_POS       !=  6    )   ||  \
     (MAC_FCF_DST_ADDR_MODE_POS   !=  10   )   ||  \
     (MAC_FCF_FRAME_VERSION_POS   !=  12   )   ||  \
     (MAC_FCF_SRC_ADDR_MODE_POS   !=  14   ))
#error "ERROR!  Change to the spec that requires modification of source code."
#endif

/* check for changes to the internal flags format */
#if ((MAC_RX_FLAG_VERSION      !=  0x03)  ||  \
     (MAC_RX_FLAG_ACK_PENDING  !=  0x04)  ||  \
     (MAC_RX_FLAG_SECURITY     !=  0x08)  ||  \
     (MAC_RX_FLAG_PENDING      !=  0x10)  ||  \
     (MAC_RX_FLAG_ACK_REQUEST  !=  0x20)  ||  \
     (MAC_RX_FLAG_INTRA_PAN    !=  0x40))
#error "ERROR!  Change to the internal RX flags format.  Requires modification of source code."
#endif

/* validate CRC OK bit optimization */
#if (MAC_RX_FLAG_CRC_OK != PROPRIETARY_FCS_CRC_OK_BIT)
#error "ERROR!  Optimization relies on these bits having the same position."
#endif

#if (MAC_RX_ACTIVE_NO_ACTIVITY != 0x00)
#error "ERROR! Zero is reserved value of macRxActive. Allows boolean operations, e.g !macRxActive."
#endif

#if (MAC_PROMISCUOUS_MODE_OFF != 0x00)
#error "ERROR! Zero is reserved value of rxPromiscuousMode. Allows boolean operations, e.g !rxPromiscuousMode."
#endif


/**************************************************************************************************
*/

⌨️ 快捷键说明

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