예제 #1
0
/**************************************************************************************************
 * @fn          macSleep
 *
 * @brief       Puts radio into the selected sleep mode.
 *
 * @param       sleepState - selected sleep level, see #defines in .h file
 *
 * @return      TRUE if radio was successfully put into selected sleep mode.
 *              FALSE if it was not safe for radio to go to sleep.
 **************************************************************************************************
 */
uint8 macSleep(uint8 sleepState)
{
  MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_AWAKE); /* radio must be awake to put it to sleep */
  MAC_ASSERT(macRxFilter == RX_FILTER_OFF); /* do not sleep when scanning or in promiscuous mode */
  MAC_ASSERT(!HAL_INTERRUPTS_ARE_ENABLED()); /* interrupts should be disabled to call this function */

 /* check to see if anything would prevent sleep */
 if (macRxActive || macTxActive || macRxEnableFlags)
 {
   /* sleep is not allowed */
   return(FALSE);
  }

  /* put MAC timer to sleep */
  MAC_RADIO_TIMER_SLEEP();

  /* update sleep state variable */
  macSleepState = sleepState;

  /* put radio in selected sleep mode */
  if (sleepState == MAC_SLEEP_STATE_OSC_OFF)
  {
    MAC_RADIO_TURN_OFF_OSC();
  }
  else
  {
    MAC_ASSERT(sleepState == MAC_SLEEP_STATE_CHIP_OFF);
    MAC_RADIO_TURN_OFF_VREG();
  }

  /* radio successfully put to sleep */
  return(TRUE);
}
예제 #2
0
/**************************************************************************************************
 * @fn          macRadioStartScan
 *
 * @brief       Puts radio into selected scan mode.
 *
 * @param       scanMode - scan mode, see #defines in .h file
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macRadioStartScan(uint8 scanMode)
{
  MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_AWAKE); /* radio must be awake */
  MAC_ASSERT(macRxFilter == RX_FILTER_OFF); /* all filtering must be off to start scan */

  /* set the receive filter based on the selected scan mode */
  if (scanMode == MAC_SCAN_ED)
  {
    macRxFilter = RX_FILTER_ALL;
  }
  else if (scanMode == MAC_SCAN_ORPHAN)
  {
    macRxFilter = RX_FILTER_NON_COMMAND_FRAMES;
  }
  else
  {
#ifdef FEATURE_ENHANCED_BEACON
    MAC_ASSERT((scanMode == MAC_SCAN_ACTIVE_ENHANCED) || (scanMode == MAC_SCAN_ACTIVE) ||
               (scanMode == MAC_SCAN_PASSIVE)); /* invalid scan type */
#else
    MAC_ASSERT((scanMode == MAC_SCAN_ACTIVE) ||
               (scanMode == MAC_SCAN_PASSIVE)); /* invalid scan type */
#endif
    macRxFilter = RX_FILTER_NON_BEACON_FRAMES;

    /* for active and passive scans, per spec the pan ID must be 0xFFFF */
    MAC_RADIO_SET_PAN_ID(0xFFFF);
  }
}
예제 #3
0
/**************************************************************************************************
 * @fn          macBackoffTimerSetCount
 *
 * @brief       Sets the count of the backoff timer.
 *
 * @param       backoff - new count
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macBackoffTimerSetCount(uint32 backoff)
{
  halIntState_t  s;

  MAC_ASSERT(backoff < backoffTimerRollover);  /* count must be less than rollover value */
  MAC_ASSERT(!(backoff & 0x80000000));  /* count must not represent negative value for int32 */

  HAL_ENTER_CRITICAL_SECTION(s);
  MAC_RADIO_BACKOFF_SET_COUNT(backoff);
  HAL_EXIT_CRITICAL_SECTION(s);
}
예제 #4
0
/**************************************************************************************************
 * @fn          macBackoffTimerSetCount
 *
 * @brief       Sets the count of the backoff timer.
 *
 * @param       backoff - new count
 *
 * @return      none
 **************************************************************************************************
 */
void macBackoffTimerSetCount(uint32 backoff)
{
  halIntState_t  s;

  MAC_ASSERT(compareState == COMPARE_STATE_ROLLOVER);   /* trigger cannot be active if changing count */
  MAC_ASSERT(backoff < backoffTimerRollover);  /* count must be less than rollover value */
  MAC_ASSERT(!(backoff & 0x80000000));  /* count must not represent negative value for int32 */

  HAL_ENTER_CRITICAL_SECTION(s);
  MAC_RADIO_BACKOFF_SET_COUNT(backoff);
  HAL_EXIT_CRITICAL_SECTION(s);
}
/**************************************************************************************************
 * @fn          macBackoffTimerSetCount
 *
 * @brief       Sets the count of the backoff timer.
 *
 * @param       backoff - new count
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macBackoffTimerSetCount(uint32 backoff)
{
#if defined( FEATURE_BEACON_MODE )
  halIntState_t  s;

  MAC_ASSERT(backoff < macBackoffTimerRollover);  /* count must be less than rollover value */
  MAC_ASSERT(!(backoff & 0x80000000));  /* count must not represent negative value for int32 */
  DBG_PRINT2(DBGSYS, "MAC_RADIO_BACKOFF_SET_COUNT(%u), RAT BACKOFF = %u", backoff, MAC_RADIO_BACKOFF_COUNT());

  HAL_ENTER_CRITICAL_SECTION(s);
  MAC_RADIO_BACKOFF_SET_COUNT(backoff);
  MAC_BACKOFF_TIMER_UPDATE_WAKEUP();
  HAL_EXIT_CRITICAL_SECTION(s);
#endif /* FEATURE_BEACON_MODE */  
}
예제 #6
0
파일: mac_tx.c 프로젝트: LILCMU/WRATIOT
/**************************************************************************************************
 * @fn          macTxTimestampCallback
 *
 * @brief       This callback function records the timestamp into the receive data structure.
 *              It should be called as soon as possible after there is a valid timestamp.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macTxTimestampCallback(void)
{
  MAC_ASSERT(pMacDataTx != NULL); /* transmit structure must be there */

  pMacDataTx->internal.timestamp  = macBackoffTimerCapture();
  pMacDataTx->internal.timestamp2 = MAC_RADIO_TIMER_CAPTURE();
}
예제 #7
0
/**************************************************************************************************
 * @fn          macTxTimestampCallback
 *
 * @brief       -
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macTxTimestampCallback(void)
{
  MAC_ASSERT(pMacDataTx != NULL); /* must have data to transmit */

  pMacDataTx->internal.timestamp = MAC_RADIO_BACKOFF_CAPTURE();
  pMacDataTx->internal.timestamp2 = MAC_RADIO_TIMER_CAPTURE();
}
예제 #8
0
/**************************************************************************************************
 * @fn          macBackoffTimerSetTrigger
 *
 * @brief       Sets the trigger count for the backoff counter.  A callback is exectuted when
 *              the backoff count reaches the trigger
 *
 * @param       triggerBackoff - backoff count for new trigger
 *
 * @return      none
 **************************************************************************************************
 */
void macBackoffTimerSetTrigger(uint32 triggerBackoff)
{
  halIntState_t  s;

  MAC_ASSERT(triggerBackoff < backoffTimerRollover); /* trigger backoff must be less than rollover backoff */

  HAL_ENTER_CRITICAL_SECTION(s);
  backoffTimerTrigger = triggerBackoff;
  if (triggerBackoff > MAC_RADIO_BACKOFF_COUNT())
  {
    compareState = COMPARE_STATE_TRIGGER;
    MAC_RADIO_BACKOFF_SET_COMPARE(triggerBackoff);
  }
  else
  {
    if (triggerBackoff == 0)
    {
      compareState = COMPARE_STATE_ROLLOVER_AND_TRIGGER;
    }
    else
    {
      compareState = COMPARE_STATE_ROLLOVER_AND_ARM_TRIGGER;
    }
    MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerRollover);
  }
  HAL_EXIT_CRITICAL_SECTION(s);
}
예제 #9
0
/**************************************************************************************************
 * @fn          macSleepWakeUp
 *
 * @brief       Wake up the radio from sleep mode.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macSleepWakeUp(void)
{
  /* don't wake up radio if it's already awake */
  if (macSleepState == MAC_SLEEP_STATE_AWAKE)
  {
    return;
  }

  /* wake up MAC timer */
  MAC_RADIO_TIMER_WAKE_UP();

  /* if radio was completely off, restore from that state first */
  if (macSleepState == MAC_SLEEP_STATE_RADIO_OFF)
  {
    /* turn on radio power (turns on oscillator too) */
    MAC_RADIO_TURN_ON_POWER();

    /* power-up initialization of receive logic */
    macRxRadioPowerUpInit();
  }
  else
  {
    MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_OSC_OFF);

    /* turn on the oscillator */
    MAC_RADIO_TURN_ON_OSC();
  }

  /* update sleep state here before requesting to turn on receiver */
  macSleepState = MAC_SLEEP_STATE_AWAKE;

  /* turn on the receiver if enabled */
  macRxOnRequest();
}
예제 #10
0
/**************************************************************************************************
 * @fn          macRadioUpdateChannel
 *
 * @brief       Update the radio channel if a new channel has been requested.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macRadioUpdateChannel(void)
{
  halIntState_t  s;

  MAC_ASSERT(!macTxActive); /* cannot change channel during a transmit */

  /* if the channel has changed, set the radio to the new channel */
  HAL_ENTER_CRITICAL_SECTION(s);
  if (reqChannel != macPhyChannel)
  {
    macPhyChannel = reqChannel;
    HAL_EXIT_CRITICAL_SECTION(s);

    /* changing the channel stops any receive in progress */
    macRxOff();
    MAC_RADIO_SET_CHANNEL(macPhyChannel);

    /* If the channel is updated in the middle of receiving a frame, we must
     * clean up the Rx logic.
     */
    macRxHaltCleanup();

    macRxOnRequest();
  }
  else
  {
    HAL_EXIT_CRITICAL_SECTION(s);
  }
}
예제 #11
0
/**************************************************************************************************
 * @fn          macBackoffTimerPeriodIsr
 *
 * @brief       Interrupt service routine that fires when the backoff count rolls over on
 *              overflow period.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macBackoffTimerPeriodIsr(void)
{
  halIntState_t s;
  uint32 macRatCount           =  MAC_RAT_COUNT;
  uint32 backoffRolloverRat    =  macBackoffTimerRollover * MAC_BACKOFF_TO_RAT_RATIO;
  uint32 ratCompensation       = (macRatCount - macPrevPeriodRatCount) % MAC_BACKOFF_TO_RAT_RATIO;
      
  MAC_ASSERT( macBackoffTimerRollover <= MAC_BACKOFF_MAXIMUM_ROLLOVER );

  if (macRatCount < backoffRolloverRat)
  {
    /* RAT wraparound has occurred. This would occur once in a blue moon (1073.74 seconds).
     */
    DBG_PRINTL1(DBGSYS, "!!! RAT wraparound !!! RAT = %u", macRatCount);
  }

  DBG_PRINTL2(DBGSYS, "macRatChanA Period ISR, Rollover Period = %u, RAT Compensation = %u", macBackoffTimerRollover, ratCompensation);
  
  /* Convert count to RAT count and set MAC Channel A Compare. The modulus calculation will 
   * compensate the math or interrupt latency error and prevent it from being accumulated.
   * Note that MAC_BACKOFF_TO_RAT_RATIO is used as part of compensation. This means the 
   * maximum error that can be compensated is 320us. If the interrupt latency is greater 
   * than 320us, more elaborated compensation scheme must be used for Beacon mode. 
   * Non-beacon mode does not require absolute timing. Longer interrupt latency can be 
   * tolerated.
   */
  macPrevPeriodRatCount = macRatCount - ratCompensation;
  macSetupRATChanCompare( macRatChanA, backoffRolloverRat + macPrevPeriodRatCount );
  macBackoffTimerRolloverCallback();
  HAL_ENTER_CRITICAL_SECTION(s);
  MAC_BACKOFF_TIMER_UPDATE_WAKEUP();
  HAL_EXIT_CRITICAL_SECTION(s);
}
예제 #12
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);
  }
}
예제 #13
0
/*=================================================================================================
 * @fn          rxAddrIsr
 *
 * @brief       Receive ISR state for decoding address.  Reads and stores the address information
 *              from the incoming packet.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxAddrIsr(void)
{
  uint8 buf[MAX_ADDR_FIELDS_LEN];
  uint8 dstAddrMode;
  uint8 srcAddrMode;
  uint8  * p;

  MAC_ASSERT(rxNextLen != 0); /* logic assumes at least one address byte in buffer */

  /*  read out address fields into local buffer in one shot */
  MAC_RADIO_READ_RX_FIFO(buf, rxNextLen);

  /* set pointer to buffer with addressing fields */
  p = buf;

  /* destination address */
  dstAddrMode = MAC_DEST_ADDR_MODE(&rxBuf[1]);
  if (dstAddrMode != SADDR_MODE_NONE)
  {
    pRxBuf->mac.srcPanId = pRxBuf->mac.dstPanId = BUILD_UINT16(p[0], p[1]);
    p += MAC_PAN_ID_FIELD_LEN;
    if (dstAddrMode == SADDR_MODE_EXT)
    {
      sAddrExtCpy(pRxBuf->mac.dstAddr.addr.extAddr, p);
      p += MAC_EXT_ADDR_FIELD_LEN;
    }
    else
    {
      pRxBuf->mac.dstAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]);
      p += MAC_SHORT_ADDR_FIELD_LEN;
    }
  }

  /* sources address */
  srcAddrMode = MAC_SRC_ADDR_MODE(&rxBuf[1]);
  if (srcAddrMode != SADDR_MODE_NONE)
  {
    if (!(pRxBuf->internal.flags & MAC_RX_FLAG_INTRA_PAN))
    {
      pRxBuf->mac.srcPanId = BUILD_UINT16(p[0], p[1]);
      p += MAC_PAN_ID_FIELD_LEN;
    }
    if (srcAddrMode == SADDR_MODE_EXT)
    {
      sAddrExtCpy(pRxBuf->mac.srcAddr.addr.extAddr, p);
    }
    else
    {
      pRxBuf->mac.srcAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]);
    }
  }

  /*-------------------------------------------------------------------------------
   *  Prepare for payload interrupts.
   */
  pFuncRxState = &rxPayloadIsr;
  rxPrepPayload();
}
예제 #14
0
/**************************************************************************************************
 * @fn          macSleep
 *
 * @brief       Puts radio into the selected sleep mode.
 *
 * @param       sleepState - selected sleep level, see #defines in .h file
 *
 * @return      TRUE if radio was successfully put into selected sleep mode.
 *              FALSE if it was not safe for radio to go to sleep.
 **************************************************************************************************
 */
uint8 macSleep(uint8 sleepState)
{
  halIntState_t  s;

  /* disable interrupts until macSleepState can be set */
  HAL_ENTER_CRITICAL_SECTION(s);

  /* assert checks */
  MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_AWAKE); /* radio must be awake to put it to sleep */
  MAC_ASSERT(macRxFilter == RX_FILTER_OFF); /* do not sleep when scanning or in promiscuous mode */

  /* if either RX or TX is active or any RX enable flags are set, it's not OK to sleep */
  if (macRxActive || macRxOutgoingAckFlag || macTxActive || macRxEnableFlags)
  {
    HAL_EXIT_CRITICAL_SECTION(s);
    return(FALSE);
  }

  /* turn off the receiver */
  macRxOff();

  /* update sleep state variable */
  macSleepState = sleepState;

  /* macSleepState is now set, re-enable interrupts */
  HAL_EXIT_CRITICAL_SECTION(s);

  /* put MAC timer to sleep */
  MAC_RADIO_TIMER_SLEEP();

  /* put radio in selected sleep mode */
  if (sleepState == MAC_SLEEP_STATE_OSC_OFF)
  {
    MAC_RADIO_TURN_OFF_OSC();
  }
  else
  {
    MAC_ASSERT(sleepState == MAC_SLEEP_STATE_RADIO_OFF); /* unknown sleep state */
    MAC_RADIO_TURN_OFF_POWER();
  }

  /* radio successfully entered sleep mode */
  return(TRUE);
}
예제 #15
0
/**************************************************************************************************
 * @fn          macBackoffTimerSetRollover
 *
 * @brief       Set rollover count of backoff timer.
 *
 * @param       rolloverBackoff - backoff count where count is reset to zero
 *
 * @return      none
 **************************************************************************************************
 */
void macBackoffTimerSetRollover(uint32 rolloverBackoff)
{
  halIntState_t  s;

  MAC_ASSERT(rolloverBackoff > MAC_RADIO_BACKOFF_COUNT());  /* rollover value must be greater than count */

  HAL_ENTER_CRITICAL_SECTION(s);
  backoffTimerRollover = rolloverBackoff;
  MAC_RADIO_BACKOFF_SET_COMPARE(rolloverBackoff);
  HAL_EXIT_CRITICAL_SECTION(s);
}
예제 #16
0
/**************************************************************************************************
 * @fn          macRxSoftEnable
 *
 * @brief       Set enable flags but don't turn on the receiver.  Useful to leave the receiver
 *              on after a transmit, but without turning it on immediately.
 *
 * @param       flags - byte containing rx enable flags to set
 *
 * @return      none
 **************************************************************************************************
 */
void macRxSoftEnable(uint8 flags)
{
  halIntState_t  s;

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

  /* set the enable flags but do not turn on the receiver */
  HAL_ENTER_CRITICAL_SECTION(s);
  macRxEnableFlags |= flags;
  HAL_EXIT_CRITICAL_SECTION(s);
}
예제 #17
0
/**************************************************************************************************
 * @fn          macRxEnable
 *
 * @brief       Set enable flags and then turn on receiver.
 *
 * @param       flags - byte containing rx enable flags to set
 *
 * @return      none
 **************************************************************************************************
 */
void macRxEnable(uint8 flags)
{
  halIntState_t  s;

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

  /* set enable flags and then turn on receiver */
  HAL_ENTER_CRITICAL_SECTION(s);
  macRxEnableFlags |= flags;
  macRxOn();
  HAL_EXIT_CRITICAL_SECTION(s);
}
예제 #18
0
/**************************************************************************************************
 * @fn          macMemReadRxFifo
 *
 * @brief       Read multiple bytes from receive FIFO.
 *
 * @param       pData - pointer to location to store read data
 * @param       len   - number of bytes to read from RX FIFO
 *
 * @return      none
 **************************************************************************************************
 */
void macMemReadRxFifo(uint8 * pData, uint8 len)
{
  MAC_ASSERT(len != 0); /* pointless to read zero bytes */

  do
  {
    *pData = RFD;
    pData++;
    len--;
  }
  while (len);
}
예제 #19
0
/**************************************************************************************************
 * @fn          macMemWriteTxFifo
 *
 * @brief       Write multiple bytes to the transmit FIFO.
 *
 * @param       pData - pointer to bytes to be written to TX FIFO
 * @param       len   - number of bytes to write
 *
 * @return      none
 **************************************************************************************************
 */
void macMemWriteTxFifo(uint8 * pData, uint8 len)
{
  MAC_ASSERT(len != 0); /* pointless to write zero bytes */

  do
  {
    RFD = *pData;
    pData++;
    len--;
  }
  while (len);
}
예제 #20
0
/**************************************************************************************************
 * @fn          macBackoffTimerSetTrigger
 *
 * @brief       Sets the trigger count for the backoff counter.  A callback is exectuted when
 *              the backoff count reaches the trigger
 *
 * @param       triggerBackoff - backoff count for new trigger
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macBackoffTimerSetTrigger(uint32 triggerBackoff)
{
  halIntState_t  s;

  MAC_ASSERT(triggerBackoff < macBackoffTimerRollover); /* trigger backoff must be less than rollover backoff */
  DBG_PRINT1(DBGSYS, "MAC_RADIO_BACKOFF_SET_COMPARE(%u)", triggerBackoff);
  
  HAL_ENTER_CRITICAL_SECTION(s);
  backoffTimerTrigger = triggerBackoff;
  MAC_RADIO_BACKOFF_SET_COMPARE(triggerBackoff);
  MAC_BACKOFF_TIMER_UPDATE_WAKEUP();
  HAL_EXIT_CRITICAL_SECTION(s);
}
예제 #21
0
/**************************************************************************************************
 * @fn          macBackoffTimerSetRollover
 *
 * @brief       Set rollover count of backoff timer. 
 *
 * @param       rolloverBackoff - backoff count where count is reset to zero
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macBackoffTimerSetRollover(uint32 rolloverBackoff)
{
  halIntState_t  s;

  /* Normally called on initialization but timer realign also calls this. */
  MAC_ASSERT(rolloverBackoff > MAC_RADIO_BACKOFF_COUNT());  /* rollover value must be greater than count */
  DBG_PRINTL1(DBGSYS, "MAC_RADIO_BACKOFF_SET_PERIOD(%u)", rolloverBackoff);
  
  HAL_ENTER_CRITICAL_SECTION(s);
  macBackoffTimerRollover = rolloverBackoff;
  MAC_RADIO_BACKOFF_SET_PERIOD(rolloverBackoff);
  MAC_BACKOFF_TIMER_UPDATE_WAKEUP();
  HAL_EXIT_CRITICAL_SECTION(s);
}
예제 #22
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();
}
예제 #23
0
/*=================================================================================================
 * @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;
  }
}
예제 #24
0
/**************************************************************************************************
 * @fn          macRxSoftEnable
 *
 * @brief       Set enable flags but don't turn on the receiver.  Useful to leave the receiver
 *              on after a transmit, but without turning it on immediately.
 *
 * @param       flags - byte containing rx enable flags to set
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macRxSoftEnable(uint8 flags)
{
  halIntState_t  s;

  MAC_ASSERT(flags != 0); /* rx flags not affected */
  DBG_PRINT1(DBGSYS, "macRxSoftEnable(0x%X)", flags);

  /* set the enable flags but do not turn on the receiver */
  HAL_ENTER_CRITICAL_SECTION(s);
  macRxEnableFlags |= flags;
  HAL_EXIT_CRITICAL_SECTION(s);

  /* Power management state may change. Hence, vote. */
  macPwrVote();
}
예제 #25
0
/**************************************************************************************************
 * @fn          macRxPromiscuousMode
 *
 * @brief       Sets promiscuous mode - enabling or disabling it.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API 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();
  }
}
예제 #26
0
파일: mac_low_level.c 프로젝트: gxp/node
/**************************************************************************************************
 * @fn          macLowLevelReset
 *
 * @brief       Reset low-level MAC.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macLowLevelReset(void)
{
  MAC_ASSERT(!HAL_INTERRUPTS_ARE_ENABLED());   /* interrupts must be disabled */

  /* reset radio modules;  if not awake, skip this */
  if (macSleepState == MAC_SLEEP_STATE_AWAKE)
  {
    macRxTxReset();
    macRadioReset();
  }

  /* reset timer */
  macBackoffTimerReset();

  /* power up the radio */
  macSleepWakeUp();
}
예제 #27
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();
}
예제 #28
0
/**************************************************************************************************
 * @fn          macBackoffSetupPwrMgmt
 *
 * @brief       Intializes backoff timer power management logic.
 *              Note that this function must be called only once.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macBackoffSetupPwrMgmt(void)
{
#ifdef USE_ICALL
  /* Register power transition notification */
  if (ICall_pwrRegisterNotify(macBackoffTimerICallPwrNotify,
                              &macBackoffTimerICallPwrNotifyData) !=
      ICALL_ERRNO_SUCCESS)
  {
    MAC_ASSERT(0);
  }
#endif /* USE_ICALL */
#ifdef OSAL_PORT2TIRTOS
  /* Register power transition notification */
  Power_registerNotify(&macBackoffPwrNotifyObj,
                       (Power_ENTERING_STANDBY |
                        Power_ENTERING_SHUTDOWN |
                        Power_AWAKE_STANDBY),
                       (xdc_Fxn) macBackoffTimerPwrNotify,
                       (UArg) NULL, 0);
#endif /* OSAL_PORT2TIRTOS */
}
예제 #29
0
/**************************************************************************************************
 * @fn          macBackoffTimerSetTrigger
 *
 * @brief       Sets the trigger count for the backoff counter.  A callback is exectuted when
 *              the backoff count reaches the trigger
 *
 * @param       triggerBackoff - backoff count for new trigger
 *
 * @return      none
 **************************************************************************************************
 */
MAC_INTERNAL_API void macBackoffTimerSetTrigger(uint32 triggerBackoff)
{
  halIntState_t  s;

  MAC_ASSERT(triggerBackoff < backoffTimerRollover); /* trigger backoff must be less than rollover backoff */

  HAL_ENTER_CRITICAL_SECTION(s);
  backoffTimerTrigger = triggerBackoff;
  MAC_RADIO_BACKOFF_SET_COMPARE(triggerBackoff);
  if (triggerBackoff == MAC_RADIO_BACKOFF_COUNT())
  {
    /* Clear the interrupt and fire it manually */
    MAC_RADIO_BACKOFF_COMPARE_CLEAR_INTERRUPT();
    HAL_EXIT_CRITICAL_SECTION(s);
    macBackoffTimerTriggerCallback();
  }
  else
  {
    HAL_EXIT_CRITICAL_SECTION(s);
  }
}
예제 #30
0
파일: mac_tx.c 프로젝트: LILCMU/WRATIOT
/**************************************************************************************************
 * @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();
  }
}