Ejemplo n.º 1
0
/*=================================================================================================
 * @fn          txGo
 *
 * @brief       Start a transmit going.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void txGo(void)
{
  /*
   *  If execution has reached this point, any transmitted ACK has long since completed.  It is
   *  possible though that there is still a pending callback.  If so, it is irrelevant and needs to
   *  be canceled at this point.
   */
  MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK();
  macRxOutgoingAckFlag = 0;

  /* based on type of transmit, call the correct "go" functionality */
  if (macTxType == MAC_TX_TYPE_SLOTTED)
  {
    MAC_RADIO_TX_GO_SLOTTED();
  }

#ifdef FEATURE_GREEN_POWER
  else if (macTxType == MAC_TX_TYPE_GREEN_POWER)
  {
    MAC_RADIO_TX_GO_GREEN_POWER();
  }
#endif /* #ifdef FEATURE_GREEN_POWER */

  else
  {
    txCsmaGo();
  }
}
Ejemplo n.º 2
0
/**************************************************************************************************
 * @fn          macTxDoneCallback
 *
 * @brief       -
 *
 * @param       -
 *
 * @return      none
 **************************************************************************************************
 */
void macTxDoneCallback(uint8 status)
{
  if (status == MAC_TXDONE_SUCCESS)
  {
    /* see if ACK was requested */
    if (!txAckReq)
    {
      /* ACK was not requested, transmit is complete */
      txComplete(MAC_SUCCESS);
    }
    else
    {
      /*
       *  ACK was requested - must wait to receive it.  A timer is set
       *  to expire after the timeout duration for waiting for an ACK.
       *  If an ACK is received, the function macTxAckReceived() is called.
       *  If an ACK is not received within the timeout period,
       *  the function macTxAckTimeoutCallback() is called.
       */
      macTxListenForAck = TRUE;
      MAC_RADIO_TX_REQUEST_ACK_TIMEOUT_CALLBACK();
    }
  }
  else if (status == MAC_TXDONE_CHANNEL_BUSY)
  {
    MAC_ASSERT((macTxType == MAC_TX_TYPE_SLOTTED_CSMA) || (macTxType == MAC_TX_TYPE_UNSLOTTED_CSMA));

    /*  clear channel assement failed, follow through with CSMA algorithm */
    nb++;
    if (nb > macPib.maxCsmaBackoffs)
    {
      txComplete(MAC_CHANNEL_ACCESS_FAILURE);
    }
    else
    {
      macTxBe = MIN(macTxBe+1, macPib.maxBe);
      txCsmaPrep();
      txCsmaGo();
    }
  }
  else
  {
    MAC_ASSERT(status == MAC_TXDONE_INSUFFICIENT_TIME);

    txComplete(MAC_NO_TIME);
  }
}
Ejemplo n.º 3
0
/**************************************************************************************************
 * @fn          macTxStartQueuedFrame
 *
 * @brief       -
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macTxStartQueuedFrame(void)
{
  halIntState_t  s;

  HAL_ENTER_CRITICAL_SECTION(s);
  if (macTxFrameInQueueFlag)
  {
    macTxFrameInQueueFlag = FALSE;
    HAL_EXIT_CRITICAL_SECTION(s);
    if (macTxType == MAC_TX_TYPE_SLOTTED)
    {
      MAC_RADIO_TX_GO_SLOTTED();
    }
    else
    {
      txCsmaGo();
    }
  }
  HAL_EXIT_CRITICAL_SECTION(s);
}
Ejemplo n.º 4
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.º 5
0
/**************************************************************************************************
 * @fn          macTxFrame
 *
 * @brief       Transmit the frame pointed to by pMacDataTx with unslotted CSMA.
 *              NOTE! It is not legal to call this function from interrupt context.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macTxFrame(uint8 txType)
{
  MAC_ASSERT(!macTxActive);                                 /* transmit on top of transmit */
  MAC_ASSERT(!macTxFrameInQueueFlag);                       /* already a queued transmit */
  MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_AWAKE);       /* radio must be awake */

  /* initialize */
  macTxActive = TRUE;
  macTxType   = txType;

  /*-------------------------------------------------------------------------------
   *  Prepare for transmit.
   */
  if (macTxType == MAC_TX_TYPE_SLOTTED)
  {
    MAC_RADIO_TX_PREP_SLOTTED();
  }
  else
  {
    MAC_ASSERT((macTxType == MAC_TX_TYPE_SLOTTED_CSMA) || (macTxType == MAC_TX_TYPE_UNSLOTTED_CSMA));

    nb = 0;
    macTxBe = (pMacDataTx->internal.txOptions & MAC_TXOPTION_ALT_BE) ? macPib.altBe : macPib.minBe;

    if ((macTxType == MAC_TX_TYPE_SLOTTED_CSMA) && (macPib.battLifeExt))
    {
      macTxBe = MIN(2, macTxBe);
    }

    txCsmaPrep();
  }


  /*-------------------------------------------------------------------------------
   *  Load transmit FIFO unless this is a retransmit.  No need to write
   *  the FIFO again in that case.
   */
  if (!txRetransmitFlag)
  {
    uint8 * p;
    uint8   lenMhrMsdu;

    MAC_ASSERT(pMacDataTx != NULL); /* must have data to transmit */

    /* save needed parameters */
    txAckReq = MAC_ACK_REQUEST(pMacDataTx->msdu.p);
    txSeqn   = MAC_SEQ_NUMBER(pMacDataTx->msdu.p);

    /* set length of frame (note: use of term msdu is a misnomer, here it's actually mhr + msdu) */
    lenMhrMsdu = pMacDataTx->msdu.len;

    /* calling code guarantees an unused prepended byte  */
    p = pMacDataTx->msdu.p - PREPENDED_BYTE_LEN;

    /* first byte of buffer is length of MPDU */
    *p = lenMhrMsdu + MFR_LEN;

    /*
     *  Flush the TX FIFO.  This is necessary in case the previous transmit was never
     *  actually sent (e.g. CSMA failed without strobing TXON).  If bytes are written to
     *  the FIFO but not transmitted, they remain in the FIFO to be transmitted whenever
     *  a strobe of TXON does happen.
     */
    MAC_RADIO_FLUSH_TX_FIFO();

    /* write bytes to FIFO, prepended byte is included, MFR is not (it's generated by hardware) */
    MAC_RADIO_WRITE_TX_FIFO(p, PREPENDED_BYTE_LEN + lenMhrMsdu);
  }

  /*-------------------------------------------------------------------------------
   *  If not receiving, start the transmit.  If receive is active
   *  queue up the transmit.
   */
  {
    halIntState_t  s;

    HAL_ENTER_CRITICAL_SECTION(s);
    if (!macRxActive)
    {
      HAL_EXIT_CRITICAL_SECTION(s);
      if (macTxType == MAC_TX_TYPE_SLOTTED)
      {
        MAC_RADIO_TX_GO_SLOTTED();
      }
      else
      {
        txCsmaGo();
      }
    }
    else
    {
      macTxFrameInQueueFlag = TRUE;
      HAL_EXIT_CRITICAL_SECTION(s);
    }
  }
}