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

  /* 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;

#ifdef FEATURE_SYSTEM_STATS
    /* Increment diagnostic CRC success counter */
    macLowLevelDiags( MAC_DIAGS_RX_CRC_PASS );
#endif /* FEATURE_SYSTEM_STATS */

    /*
     *  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;
    MAC_RADIO_RSSI_LNA_OFFSET(rssiDbm);
    corr = PROPRIETARY_FCS_CORRELATION_VALUE(rxBuf);

    /* record parameters that get passed up to high-level */
    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->mhr.p   = (uint8 *) (pRxBuf + 1);
    pRxBuf->msdu.p += (pRxBuf->mhr.len - pRxBuf->msdu.len);

    if ((pRxBuf->internal.flags & MAC_RX_FLAG_ACK_PENDING) && (*pRxBuf->msdu.p != MAC_DATA_REQ_FRAME))
    {
      /* For non-data request commands, cancel the pending bit in the ACK. */
      MAC_RADIO_TX_ACK();
    }

    /* Read the source matching result back */
    if( macSrcMatchIsEnabled && MAC_RADIO_SRC_MATCH_RESULT() )
    {
      /* This result will not overwrite the previously determined pRxBuf->internal.flags */
      ackWithPending = MAC_RX_FLAG_ACK_PENDING;
    }
    pRxBuf->internal.flags |= ( crcOK | ackWithPending );

    /* finally... execute callback function */
    macRxCompleteCallback(pRxBuf);
    pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */
  }
  else
  {
#ifdef FEATURE_SYSTEM_STATS
    /* Increment diagnostic CRC failure counter */
    macLowLevelDiags( MAC_DIAGS_RX_CRC_FAIL );
#endif /* FEATURE_SYSTEM_STATS */

    /*
     *  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();
}
Exemplo n.º 2
0
/*=================================================================================================
 * @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();
}