Ejemplo n.º 1
0
/*=================================================================================================
 * @fn          txComplete
 *
 * @brief       Transmit has completed.  Perform needed maintenance and return status of
 *              the transmit via callback function.
 *
 * @param       status - status of the transmit that just went out
 *
 * @return      none
 *=================================================================================================
 */
static void txComplete(uint8 status)
{
  /* reset the retransmit flag */
  txRetransmitFlag = 0;

  /* update tx state; turn off receiver if nothing is keeping it on */
  macTxActive = MAC_TX_ACTIVE_NO_ACTIVITY;
  
  /* If no ACK is pending go to sleep sooner than wait for high level mac
   * to clear MAC_RX_POLL bit and then go to sleep 
   */
  if (status != MAC_ACK_PENDING)
  {
    macRxEnableFlags &= ~MAC_RX_POLL;
  }

  /* turn off receive if allowed */
  macRxOffRequest();

  /* update transmit power in case there was a change */
  macRadioUpdateTxPower();

  /*
   *  Channel cannot change during transmit so update it here.  (Channel *can* change during
   *  a receive.  The update function resets receive logic and any partially received
   *  frame is purged.)
   */
  macRadioUpdateChannel();

  /* return status of transmit via callback function */
  macTxCompleteCallback(status);
}
Ejemplo n.º 2
0
/*=================================================================================================
 * @fn          txComplete
 *
 * @brief       Transmit has completed.  Perform needed maintenance and return status of
 *              the transmit via callback function.
 *
 * @param       status - status of the transmit that just went out
 *
 * @return      none
 *=================================================================================================
 */
static void txComplete(uint8 status)
{
  /*
   *  Unless receive is active, update power here.  Power is *always* updated at end of receive.
   */
  if (!macRxActive)
  {
    macRadioUpdateTxPower();
  }

  /*
   *  Channel cannot change during transmit so update it here.  (Channel *can* change during
   *  a receive.  The update function resets receive logic and any partially received
   *  frame is purged.)
   */
  macRadioUpdateChannel();

  /* reset the retransmit flag */
  txRetransmitFlag = FALSE;

  /* update tx state; turn off receiver if nothing is keeping it on */
  macTxActive = FALSE;

  /* turn off receive if allowed */
  macRxOffRequest();

  /* return status of transmit via callback function */
  macTxCompleteCallback(status);
}
Ejemplo n.º 3
0
/*=================================================================================================
 * @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();
}
Ejemplo n.º 4
0
/**************************************************************************************************
 * @fn          macRxDisable
 *
 * @brief       Clear indicated rx enable flags.  If all flags are clear, turn off receiver
 *              unless there is an active receive or transmit.
 *
 * @param       flags - byte containg rx enable flags to clear
 *
 * @return      none
 **************************************************************************************************
 */
void macRxDisable(uint8 flags)
{
  halIntState_t  s;

  MAC_ASSERT(flags != 0); /* rx flags not affected */

  /* clear the indicated flags */
  HAL_ENTER_CRITICAL_SECTION(s);
  macRxEnableFlags &= (0xff ^ flags);
  HAL_EXIT_CRITICAL_SECTION(s);

  /* turn off the radio if it is allowed */
  macRxOffRequest();
}
Ejemplo n.º 5
0
/**************************************************************************************************
 * @fn          macRxDisable
 *
 * @brief       Clear indicated rx enable flags.  If all flags are clear, turn off receiver
 *              unless there is an active receive or transmit.
 *
 * @param       flags - byte containg rx enable flags to clear
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macRxDisable(uint8 flags)
{
  halIntState_t  s;

  MAC_ASSERT(flags != 0); /* rx flags not affected */
  DBG_PRINT1(DBGSYS, "macRxDisable(0x%X)", flags);
  
  /* clear the indicated flags */
  HAL_ENTER_CRITICAL_SECTION(s);
  macRxEnableFlags &= (flags ^ 0xFF);
  HAL_EXIT_CRITICAL_SECTION(s);

  /* turn off the radio if it is allowed */
  macRxOffRequest();

  /* Power management state may change. Hence, vote. */
  macPwrVote();
}
Ejemplo n.º 6
0
/**************************************************************************************************
 * @fn          macTxChannelBusyCallback
 *
 * @brief       This callback is executed if a CSMA transmit was attempted but the channel
 *              was busy.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macTxChannelBusyCallback(void)
{
  MAC_ASSERT((macTxType == MAC_TX_TYPE_SLOTTED_CSMA) || (macTxType == MAC_TX_TYPE_UNSLOTTED_CSMA));

  /* turn off receiver if allowed */
  macTxActive = MAC_TX_ACTIVE_CHANNEL_BUSY;
  macRxOffRequest();

  /*  clear channel assement failed, follow through with CSMA algorithm */
  nb++;
  if (nb > pMacPib->maxCsmaBackoffs)
  {
    txComplete(MAC_CHANNEL_ACCESS_FAILURE);
  }
  else
  {
    macTxBe = MIN(macTxBe+1, pMacPib->maxBe);
    txCsmaPrep();
    macTxActive = MAC_TX_ACTIVE_GO;
    txCsmaGo();
  }
}
Ejemplo n.º 7
0
/*=================================================================================================
 * @fn          txComplete
 *
 * @brief       Transmit has completed.  Perform needed maintenance and return status of
 *              the transmit via callback function.
 *
 * @param       status - status of the transmit that just went out
 *
 * @return      none
 *=================================================================================================
 */
static void txComplete(uint8 status)
{
  /* reset the retransmit flag */
  txRetransmitFlag = 0;

  /* update tx state; turn off receiver if nothing is keeping it on */
  macTxActive = MAC_TX_ACTIVE_NO_ACTIVITY;

  if(pMacPib->rf4cepowerSavings)
  {
    /* mark receive as inactive */
    macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY;
  }
  
  /* In general, the MAC_RX_POLL is controlled by high level MAC. The flag is 
   * cleared here when no ACK is pending to allow the RX to be turned off sooner
   * in order to save power.
   */
  if (status != MAC_ACK_PENDING)
  {
    macRxEnableFlags &= ~MAC_RX_POLL;
  }

  /* turn off receive if allowed */
  macRxOffRequest();

  /* update transmit power in case there was a change */
  macRadioUpdateTxPower();

  /*
   *  Channel cannot change during transmit so update it here.  (Channel *can* change during
   *  a receive.  The update function resets receive logic and any partially received
   *  frame is purged.)
   */
  macRadioUpdateChannel();

  /* return status of transmit via callback function */
  macTxCompleteCallback(status);
}
Ejemplo n.º 8
0
/*=================================================================================================
 * @fn          txComplete
 *
 * @brief       Transmit has completed.  Perform needed maintenance and return status of
 *              the transmit via callback function.
 *
 * @param       status - status of the transmit that just went out
 *
 * @return      none
 *=================================================================================================
 */
static void txComplete(uint8 status)
{
  /* reset the retransmit flag */
  txRetransmitFlag = 0;

  /* update tx state; turn off receiver if nothing is keeping it on */
  macTxActive = MAC_TX_ACTIVE_NO_ACTIVITY;

  /* turn off receive if allowed */
  macRxOffRequest();

  /* update transmit power in case there was a change */
  macRadioUpdateTxPower();

  /*
   *  Channel cannot change during transmit so update it here.  (Channel *can* change during
   *  a receive.  The update function resets receive logic and any partially received
   *  frame is purged.)
   */
  macRadioUpdateChannel();

  /* return status of transmit via callback function */
  macTxCompleteCallback(status);
}
Ejemplo n.º 9
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();
}
Ejemplo n.º 10
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();
}