Beispiel #1
0
/**************************************************************************************************
 * @fn          MRFI_Init
 *
 * @brief       Initialize MRFI.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_Init(void)
{
  /* ------------------------------------------------------------------
   *    Run-time integrity checks
   *   ---------------------------
   */
  memset(&mrfiIncomingPacket, 0x0, sizeof(mrfiIncomingPacket));

  /* verify the correct radio is installed */
  MRFI_ASSERT( CHIPID == MRFI_RADIO_PARTNUM );      /* wrong radio */
  MRFI_ASSERT( CHVER  >= MRFI_RADIO_MIN_VERSION );  /* obsolete radio version */

  /* ------------------------------------------------------------------
   *    Configure IO ports
   *   ---------------------------
   */

#if defined(MRFI_PA_LNA_ENABLED) && defined(BSP_BOARD_SRF04EB)
  MRFI_BOARD_PA_LNA_CONFIG_PORTS();
  MRFI_BOARD_PA_LNA_HGM();
#endif


  /* ------------------------------------------------------------------
   *    Configure clock to use XOSC
   *   -----------------------------
   */
  SLEEPCMD &= ~OSC_PD;                       /* turn on 16MHz RC and 32MHz XOSC */
  while (!(SLEEPSTA & XOSC_STB));            /* wait for 32MHz XOSC stable */
  asm("NOP");                             /* chip bug workaround */
  {
    uint16_t i;

    /* Require 63us delay for all revs */
    for (i=0; i<504; i++)
    {
      asm("NOP");
    }
  }
  CLKCONCMD = (0x00 | OSC_32KHZ);            /* 32MHz XOSC */
  while (CLKCONSTA != (0x00 | OSC_32KHZ));
  SLEEPCMD |= OSC_PD;                        /* turn off 16MHz RC */


  /* Configure radio registers that should be different from reset values. */
  Mrfi_RadioRegConfig();

  /* ------------------------------------------------------------------
   *    Variable Initialization
   *   -------------------------
   */

#ifdef MRFI_ASSERTS_ARE_ON
  PAN_ID0 = 0xFF;
  PAN_ID1 = 0xFF;
#endif



  /* ------------------------------------------------------------------
   *    Initialize Random Seed Value
   *   -------------------------------
   */


  /*
   *  Set radio for infinite reception.  Once radio reaches this state,
   *  it will stay in receive mode regardless RF activity.
   */
  FRMCTRL0 = (FRMCTRL0 & ~RX_MODE_MASK) | RX_MODE_INFINITE_RX;

  /* turn on the receiver */
  RFST = ISRXON;

  /* Wait for RSSI to be valid. Once valid, radio is stable and random bits
   * can be read.
   */
  MRFI_RSSI_VALID_WAIT();

  /* put 16 random bits into the seed value */
  {
    uint16_t rndSeed;
    uint8_t  i;

    rndSeed = 0;

    for(i=0; i<16; i++)
    {
      /* read random bit to populate the random seed */
      rndSeed = (rndSeed << 1) | (RFRND & 0x01);
    }

    /*
     *  The seed value must not be zero.  If it is, the pseudo random sequence will be always be zero.
     *  There is an extremely small chance this seed could randomly be zero (more likely some type of
     *  hardware problem would cause this).  To solve this, a single bit is forced to be one.  This
     *  slightly reduces the randomness but guarantees a good seed value.
     */
    rndSeed |= 0x0080;

    /*
     *  Two writes to RNDL will set the random seed.  A write to RNDL copies current contents
     *  of RNDL to RNDH before writing new the value to RNDL.
     */
    RNDL = rndSeed & 0xFF;
    RNDL = rndSeed >> 8;
  }

  /* turn off the receiver, flush RX FIFO just in case something got in there */
  RFST = ISRFOFF;

  /* flush the rx buffer */
  MRFI_RADIO_FLUSH_RX_BUFFER();

  /* take receiver out of infinite reception mode; set back to normal operation */
  FRMCTRL0 = (FRMCTRL0 & ~RX_MODE_MASK) | RX_MODE_NORMAL;


  /* Initial radio state is OFF state */
  mrfiRadioState = MRFI_RADIO_STATE_OFF;

  /* ------------------------------------------------------------------
   *    Configure Radio Registers
   *   ---------------------------
   */

  /* disable address filtering */
  FRMFILT0 &= ~FRAME_FILTER_EN;

  /* reject beacon/ack/cmd frames and accept only data frames,
   * when filtering is enabled.
   */
  FRMFILT1 &= ~(ACCEPT_BEACON | ACCEPT_ACK | ACCEPT_CMD);

  /* don't enable rx after tx is done. */
  FRMCTRL1 &= ~RX_ENABLE_ON_TX;

  /* set FIFOP threshold to maximum */
  FIFOPCTRL = 127;

  /* set default channel */
  MRFI_SetLogicalChannel( 0 );

  /* set default output power level */
  MRFI_SetRFPwr(MRFI_NUM_POWER_SETTINGS - 1);

  /* enable general RF interrupts */
  IEN2 |= RFIE;


  /* ------------------------------------------------------------------
   *    Final Initialization
   *   -----------------------
   */


  /**********************************************************************************
   *                            Compute reply delay scalar
   *
   * The IEEE radio has a fixed data rate of 250 Kbps. Data rate inference
   * from radio regsiters is not necessary for this radio.
   *
   * The maximum delay needed depends on the MAX_APP_PAYLOAD parameter. Figure
   * out how many bits that will be when overhead is included. Bits/bits-per-second
   * is seconds to transmit (or receive) the maximum frame. We multiply this number
   * by 1000 to find the time in milliseconds. We then additionally multiply by
   * 10 so we can add 5 and divide by 10 later, thus rounding up to the number of
   * milliseconds. This last won't matter for slow transmissions but for faster ones
   * we want to err on the side of being conservative and making sure the radio is on
   * to receive the reply. The semaphore monitor will shut it down. The delay adds in
   * a platform fudge factor that includes processing time on peer plus lags in Rx and
   * processing time on receiver's side. Also includes round trip delays from CCA
   * retries. This portion is included in PLATFORM_FACTOR_CONSTANT defined in mrfi.h.
   *
   * **********************************************************************************
   */

#define   PHY_PREAMBLE_SYNC_BYTES    8

  {
    uint32_t bits, dataRate = 250000;

    bits = ((uint32_t)((PHY_PREAMBLE_SYNC_BYTES + MRFI_MAX_FRAME_SIZE)*8))*10000;

    /* processing on the peer + the Tx/Rx time plus more */
    sReplyDelayScalar = PLATFORM_FACTOR_CONSTANT + (((bits/dataRate)+5)/10);
  }

  /*
   *  Random delay - This prevents devices on the same power source from repeated
   *  transmit collisions on power up.
   */
  Mrfi_RandomBackoffDelay();

  /* enable global interrupts */
  BSP_ENABLE_INTERRUPTS();
}
Beispiel #2
0
/**************************************************************************************************
 * @fn          MRFI_WakeUp
 *
 * @brief       Wake up radio from off/sleep state.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_WakeUp(void)
{
  /* if radio is asleep, wake it up */
  if(mrfiRadioState == MRFI_RADIO_STATE_OFF)
  {
    /* enter idle mode */
    mrfiRadioState = MRFI_RADIO_STATE_IDLE;

    /* turn on radio power */
    Mrfi_TurnOnRadioPower();

    /* Configure the radio registers. All radio settings that are lost
     * on MRFI_Sleep() call must be restored here. Since we are putting the
     * radio in LPM2 power mode, all register and memory values that are
     * different from reset must be restored.
     */

    MRFI_BOARD_CONFIG_RADIO_GPIO();

#ifdef MRFI_PA_LNA_ENABLED

    /* Init ports */
    MRFI_BOARD_PA_LNA_CONFIG_PORTS();

    if(mrfiLnaHighGainMode)
    {
      /* Set LNA to High Gain Mode */
      MRFI_BOARD_PA_LNA_HGM();
    }
    else
    {
     /* Set LNA to Low Gain Mode */
      MRFI_BOARD_PA_LNA_LGM();
    }

#endif

    /* Set FIFO_P threshold to max (127). Thus a FIFO_P signal is set whenever
     * a full frame is received.
     */
    mrfiSpiWriteReg(FIFOPCTRL, 0x7F);

    /* Accept only DATA frames. Reject CMD/BECAON/ACK frames. */
    mrfiSpiWriteReg(FRMFILT1, 0x10);

    /* Restore the address filter settings */
    if(mrfiAddrFilterStatus & MRFI_FILTER_ADDRESS_SET)
    {
      MRFI_SetRxAddrFilter(mrfiFilterAddr);
    }

    if(mrfiAddrFilterStatus & MRFI_FILTER_ADDRESS_ENABLED)
    {
      MRFI_EnableRxAddrFilter();
    }
    else
    {
      MRFI_DisableRxAddrFilter();
    }

    /* Following values need to be changed from their reset value.
     * See Table-21 CC2520 datasheet.
     */
#ifdef MRFI_PA_LNA_ENABLED
    /* This value is not in datasheet yet. */
    mrfiSpiWriteReg(TXPOWER,  0xE1);
#else
    mrfiSpiWriteReg(TXPOWER,  0x32);
#endif
    mrfiSpiWriteReg(CCACTRL0, 0xF8);
    mrfiSpiWriteReg(MDMCTRL0, 0x85);
    mrfiSpiWriteReg(MDMCTRL1, 0x14);
    mrfiSpiWriteReg(RXCTRL,   0x3F);
    mrfiSpiWriteReg(FSCTRL,   0x5A);
    mrfiSpiWriteReg(FSCAL1,   0x2B);
    mrfiSpiWriteReg(AGCCTRL1, 0x11);
    mrfiSpiWriteReg(ADCTEST0, 0x10);
    mrfiSpiWriteReg(ADCTEST1, 0x0E);
    mrfiSpiWriteReg(ADCTEST2, 0x03);

    /* set default channel */
    MRFI_SetLogicalChannel(mrfiCurrentLogicalChannel);
  }
}
Beispiel #3
0
/**************************************************************************************************
 * @fn          MRFI_Init
 *
 * @brief       Initialize MRFI.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_Init(void)
{
  /* ------------------------------------------------------------------
   *    Run-time integrity checks
   *   ---------------------------
   */

  /* verify the correct radio is installed */
  MRFI_ASSERT( CHIPID == MRFI_RADIO_PARTNUM );      /* wrong radio */
  MRFI_ASSERT( CHVER  >= MRFI_RADIO_MIN_VERSION );  /* obsolete radio version */

  /* ------------------------------------------------------------------
   *    Configure IO ports
   *   ---------------------------
   */

#if defined(MRFI_PA_LNA_ENABLED) && defined(BSP_BOARD_SRF04EB)
  MRFI_BOARD_PA_LNA_CONFIG_PORTS();
  MRFI_BOARD_PA_LNA_HGM();
#endif


  /* ------------------------------------------------------------------
   *    Configure clock to use XOSC
   *   -----------------------------
   */
  SLEEP &= ~OSC_PD;                       /* turn on 16MHz RC and 32MHz XOSC */
  while (!(SLEEP & XOSC_STB));            /* wait for 32MHz XOSC stable */
  asm("NOP");                             /* chip bug workaround */
  {
    uint16_t i;

    /* Require 63us delay for all revs */
    for (i=0; i<504; i++)
    {
      asm("NOP");
    }
  }
  CLKCON = (0x00 | OSC_32KHZ);            /* 32MHz XOSC */
  while (CLKCON != (0x00 | OSC_32KHZ));
  SLEEP |= OSC_PD;                        /* turn off 16MHz RC */


  /* ------------------------------------------------------------------
   *    Variable Initialization
   *   -------------------------
   */

#ifdef MRFI_ASSERTS_ARE_ON
  PANIDL = 0xFF;
  PANIDH = 0xFF;
#endif


  /* ------------------------------------------------------------------
   *    Initialize Random Seed Value
   *   -------------------------------
   */

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

  /*
   *  Set radio for infinite reception.  Once radio reaches this state,
   *  it will stay in receive mode regardless RF activity.
   */
  MDMCTRL1L = MDMCTRL1L_RESET_VALUE | RX_MODE_INFINITE_RECEPTION;

  /* turn on the receiver */
  RFST = ISRXON;

  /*
   *  Wait for radio to reach infinite reception state.  Once it does,
   *  The least significant bit of ADTSTH should be pretty random.
   */
  while (FSMSTATE != FSM_FFCTRL_STATE_RX_INF)

  /* put 16 random bits into the seed value */
  {
    uint16_t rndSeed;
    uint8_t  i;

    rndSeed = 0;

    for(i=0; i<16; i++)
    {
      /* use most random bit of analog to digital receive conversion to populate the random seed */
      rndSeed = (rndSeed << 1) | (ADCTSTH & 0x01);
    }

    /*
     *  The seed value must not be zero.  If it is, the pseudo random sequence will be always be zero.
     *  There is an extremely small chance this seed could randomly be zero (more likely some type of
     *  hardware problem would cause this).  To solve this, a single bit is forced to be one.  This
     *  slightly reduces the randomness but guarantees a good seed value.
     */
    rndSeed |= 0x0080;

    /*
     *  Two writes to RNDL will set the random seed.  A write to RNDL copies current contents
     *  of RNDL to RNDH before writing new the value to RNDL.
     */
    RNDL = rndSeed & 0xFF;
    RNDL = rndSeed >> 8;
  }

  /* turn off the receiver, flush RX FIFO just in case something got in there */
  RFST = ISRFOFF;

  /* flush the rx buffer */
  MRFI_RADIO_FLUSH_RX_BUFFER();

  /* take receiver out of infinite reception mode; set back to normal operation */
  MDMCTRL1L = MDMCTRL1L_RESET_VALUE | RX_MODE_NORMAL_OPERATION;

  /* turn radio back off */
  RFPWR |= RREG_RADIO_PD;

  /* Initial radio state is OFF state */
  mrfiRadioState = MRFI_RADIO_STATE_OFF;
  /* ------------------------------------------------------------------
   *    Configure Radio Registers
   *   ---------------------------
   */

  /* tuning adjustments for optimal radio performance; details available in datasheet */
  RXCTRL0H = 0x32;
  RXCTRL0L = 0xF5;

  /* disable address filtering */
  MDMCTRL0H &= ~ADDR_DECODE;

  /* set FIFOP threshold to maximum */
  IOCFG0 = 127;

  /* set default channel */
  MRFI_SetLogicalChannel( 0 );

  /* enable general RF interrupts */
  IEN2 |= RFIE;


  /* ------------------------------------------------------------------
   *    Final Initialization
   *   -----------------------
   */


  /**********************************************************************************
   *                            Compute reply delay scalar
   *
   * The IEEE radio has a fixed data rate of 250 Kbps. Data rate inference
   * from radio regsiters is not necessary for this radio.
   *
   * The maximum delay needed depends on the MAX_APP_PAYLOAD parameter. Figure
   * out how many bits that will be when overhead is included. Bits/bits-per-second
   * is seconds to transmit (or receive) the maximum frame. We multiply this number
   * by 1000 to find the time in milliseconds. We then additionally multiply by
   * 10 so we can add 5 and divide by 10 later, thus rounding up to the number of
   * milliseconds. This last won't matter for slow transmissions but for faster ones
   * we want to err on the side of being conservative and making sure the radio is on
   * to receive the reply. The semaphore monitor will shut it down. The delay adds in
   * a fudge factor that includes processing time on peer plus lags in Rx and processing
   * time on receiver's side.
   *
   * **********************************************************************************
   */
#define   PLATFORM_FACTOR_CONSTANT    2
#define   PHY_PREAMBLE_SYNC_BYTES     8

  {
    uint32_t bits, dataRate = 250000;

    bits = ((uint32_t)((PHY_PREAMBLE_SYNC_BYTES + MRFI_MAX_FRAME_SIZE)*8))*10000;

    /* processing on the peer + the Tx/Rx time plus more */
    sReplyDelayScalar = PLATFORM_FACTOR_CONSTANT + (((bits/dataRate)+5)/10);
  }

  /*
   *  Random delay - This prevents devices on the same power source from repeated
   *  transmit collisions on power up.
   */
  Mrfi_RandomBackoffDelay();

  /* enable global interrupts */
  BSP_ENABLE_INTERRUPTS();
}