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

📄 mrfi_radio.c

📁 SimpliciTI&#8482 -1.0.4.exe for CC2430 SimpliciTI is a simple low-power RF network protocol aimed
💻 C
📖 第 1 页 / 共 3 页
字号:
      mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS]    = RFD;
      mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = RFD;

      /* Eliminate frames that are the correct size but we can tell are bogus
       * by their frame control fields.
       */
      if ((p1[MRFI_FCF_OFFSET] == MRFI_FCF_0_7) &&
          (p1[MRFI_FCF_OFFSET+1] == MRFI_FCF_8_15))
      {
        /* call external, higher level "receive complete" (CRC checking is done by hardware) */
        MRFI_RxCompleteISR();
      }
    }
  } while (RXFIFOCNT);


  /* ------------------------------------------------------------------
   *     Clean up on exit
   *   --------------------
   */

  /* Clear FIFOP interrupt:
   * This is an edge triggered interrupt. The interrupt must be first cleared
   * at the MCU before re-enabling the interrupt at the source.
   */
  S1CON = 0x00; /* Clear the interrupt at MCU. */

  RFIF &= ~IRQ_FIFOP; /* Clear the interrupt source flag. */
}


/**************************************************************************************************
 * @fn          MRFI_SetLogicalChannel
 *
 * @brief       Set logical channel.
 *
 * @param       chan - logical channel number
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_SetLogicalChannel(uint8_t chan)
{
  uint8_t phyChannel;

  MRFI_ASSERT( chan < MRFI_NUM_LOGICAL_CHANS ); /* logical channel is not valid */

  /* make sure radio is off before changing channels */
  Mrfi_RxModeOff();

  /* convert logical channel number into physical channel number */
  phyChannel = mrfiLogicalChanTable[chan];

  /* write frequency value of new channel */
  FSCTRLL = FREQ_2405MHZ + (5 * (phyChannel - 11));

  /* turn radio back on if it was on before channel change */
  if (mrfiRxOn)
  {
    Mrfi_RxModeOn();
  }
}


/**************************************************************************************************
 * @fn          MRFI_WakeUp
 *
 * @brief       Wake up radio from sleep state.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_WakeUp(void)
{
  /* if radio is asleep, wake it up */
  if (!mrfiRadioIsAwake)
  {
    /* set flag to indicate radio is awake */
    mrfiRadioIsAwake = 1;

    /* turn on radio power, pend for the power-up delay */
    RFPWR &= ~RREG_RADIO_PD;
    while((RFPWR & ADI_RADIO_PD));
  }
}


/**************************************************************************************************
 * @fn          MRFI_Sleep
 *
 * @brief       Request radio go to sleep.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_Sleep(void)
{
  /* if radio is awake, put it to sleep */
  if (mrfiRadioIsAwake)
  {
    /* go to idle so radio is in a know state before sleeping */
    MRFI_RxIdle();

    /* turn off power to the radio */
    RFPWR |= RREG_RADIO_PD;

    /* set flag to indicate radio is asleep */
    mrfiRadioIsAwake = 0;
  }
}


/**************************************************************************************************
 * @fn          MRFI_SetRxAddrFilter
 *
 * @brief       Set the address used for filtering received packets.
 *
 * @param       pAddr - pointer to address to use for filtering
 *
 * @return      none
 **************************************************************************************************
 */
uint8_t MRFI_SetRxAddrFilter(uint8_t * pAddr)
{
  /*
   *  Determine if filter address is valid.  Cannot be a reserved value.
   *   -Reserved PAN ID's of 0xFFFF and 0xFFFE.
   *   -Reserved short address of 0xFFFF.
   */
  if ((((pAddr[0] == 0xFF) || (pAddr[0] == 0xFE)) && (pAddr[1] == 0xFF))  ||
        (pAddr[2] == 0xFF) && ((pAddr[3] == 0xFF)))
  {
    /* unable to set filter address */
    return( 1 );
  }

  /* set the hardware address registers */
  PANIDL     = pAddr[0];
  PANIDH     = pAddr[1];
  SHORTADDRL = pAddr[2];
  SHORTADDRH = pAddr[3];

  /* successfully set filter address */
  return( 0 );
}


/**************************************************************************************************
 * @fn          MRFI_EnableRxAddrFilter
 *
 * @brief       Enable received packet filtering.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_EnableRxAddrFilter(void)
{
  MRFI_ASSERT( (PANIDL != 0xFF) && (PANIDH != 0xFF) ); /* filter address not set */

  /* enable hardware filtering on the radio */
  MDMCTRL0H |= ADDR_DECODE;
}


/**************************************************************************************************
 * @fn          MRFI_DisableRxAddrFilter
 *
 * @brief       Disable received packet filtering.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_DisableRxAddrFilter(void)
{
  /* disable hardware filtering on the radio */
  MDMCTRL0H &= ~ADDR_DECODE;
}


/**************************************************************************************************
 * @fn          MRFI_Rssi
 *
 * @brief       Returns "live" RSSI value
 *
 * @param       none
 *
 * @return      RSSI value in units of dBm.
 **************************************************************************************************
 */
int8_t MRFI_Rssi(void)
{
  int8_t rssi;

  MRFI_ASSERT( mrfiRxOn ); /* radio must be on to read RSSI value */

  /*
   *  Assuming that the Radio was just turned on, we must wait for
   *  RSSI to be valid. For that, we need to wait for 20 symbol periods:
   *  - 12 symbols to go from idle to rx state
   *  - 8 symbols to calculate the RSSI value
   */
  Mrfi_DelayUsec( 20 * IEEE_USECS_PER_SYMBOL );

  /* read RSSI value from hardware */
  rssi = RSSIL;

  /* apply offset given in datasheet */
  rssi = rssi + MRFI_BOARD_RSSI_OFFSET;

  /* return RSSI value */
  return( rssi );
}


/**************************************************************************************************
 * @fn          MRFI_RandomByte
 *
 * @brief       Returns a random byte using a special hardware feature that generates new
 *              random values based on the truly random seed set earlier.
 *
 * @param       none
 *
 * @return      a random byte
 **************************************************************************************************
 */
uint8_t MRFI_RandomByte(void)
{
  /* clock the random generator to get a new random value */
  ADCCON1 = (ADCCON1 & ~RCTRL_BITS) | RCTRL_CLOCK_LFSR;

  /* return newly randomized value from hardware */
  return(RNDH);
}


/**************************************************************************************************
 * @fn          MRFI_DelayMs
 *
 * @brief       Delay the specified number of milliseconds.
 *
 * @param       milliseconds - delay time
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_DelayMs(uint16_t milliseconds)
{
  while (milliseconds)
  {
    Mrfi_DelayUsec( 1000 );
    milliseconds--;
  }
}


/**************************************************************************************************
 * @fn          Mrfi_RxModeOn
 *
 * @brief       Put radio into receive mode.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
static void Mrfi_RxModeOn(void)
{
  /* send strobe to enter receive mode */
  RFST = ISRXON;

  /* enable receive interrupts */
  RFIM |= IM_FIFOP;
}


/**************************************************************************************************
 * @fn          Mrfi_RxModeOff
 *
 * @brief       -
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
static void Mrfi_RxModeOff(void)
{
  /*disable receive interrupts */
  RFIM &= ~IM_FIFOP;

  /* turn off radio */
  RFST = ISRFOFF;

  /* flush the receive FIFO of any residual data */
  RFST = ISFLUSHRX;

  /* clear receive interrupt */
  RFIF = ~IRQ_FIFOP;
}


/**************************************************************************************************
 * @fn          Mrfi_RandomBackoffDelay
 *
 * @brief       -
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
static void Mrfi_RandomBackoffDelay(void)
{
  uint8_t backoffs;
  uint8_t i;

  /* calculate random value for backoffs - 1 to 16 */
  backoffs = (MRFI_RandomByte() & 0x0F) + 1;

  /* delay for randomly computed number of backoff periods */
  for (i=0; i<backoffs; i++)
  {
    Mrfi_DelayUsec( MRFI_BACKOFF_PERIOD_USECS );
  }
}

/****************************************************************************************************
 * @fn          Mrfi_DelayUsec
 *
 * @brief       Execute a delay loop using the MAC timer. The macro actually used to do the delay
 *              is not reentrant. This routine makes the delay execution reentrant by breaking up
 *              the requested delay up into small chunks and executing each chunk as a critical
 *              section. The chunk size is choosen to be the smallest value used by MRFI. The delay
 *              is only approximate because of the overhead computations. It errs on the side of
 *              being too long.
 *
 * input parameters
 * @param   howLong - number of microseconds to delay
 *
 * @return      none
 ****************************************************************************************************
 */
static void Mrfi_DelayUsec(uint16_t howLong)
{
  bspIState_t intState;
  uint16_t    count = howLong/IEEE_USECS_PER_SYMBOL;

  if (howLong)
  {
    do
    {
      BSP_ENTER_CRITICAL_SECTION(intState);
      MRFI_DELAY_USECS(IEEE_USECS_PER_SYMBOL);
      BSP_EXIT_CRITICAL_SECTION(intState);
    } while (count--);
  }

  return;
}

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

/*
 *  The current implementation requires an address size of four bytes.  These four bytes are
 *  spread across the PAN ID and the short address.  A larger address size is possible by using
 *  long address instead of short address.  The change is not difficult but it does require
 *  code modification.
 */
#if (MRFI_ADDR_SIZE != 4)
#error "ERROR:  Address size must be four bytes.  A different address size requires code modification."
#endif

/* verify that specified frame size fits within radio FIFO */
#if ((MRFI_MAX_FRAME_SIZE + MRFI_RX_METRICS_SIZE) > 127)
#error "ERROR:  Maximum possible packet length exceeded.  Decrease value of maximum payload."
#endif

/*
 *  These asserts happen if there is extraneous compiler padding of arrays.
 *  Modify compiler settings for no padding, or, if that is not possible,
 *  comment out the offending asserts.
 */
BSP_STATIC_ASSERT(sizeof(mrfiLogicalChanTable) == ((sizeof(mrfiLogicalChanTable)/sizeof(mrfiLogicalChanTable[0])) * sizeof(mrfiLogicalChanTable[0])));
BSP_STATIC_ASSERT(sizeof(mrfiBroadcastAddr) == ((sizeof(mrfiBroadcastAddr)/sizeof(mrfiBroadcastAddr[0])) * sizeof(mrfiBroadcastAddr[0])));


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

⌨️ 快捷键说明

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