예제 #1
0
/**************************************************************************************************
 * @fn          Mrfi_RxModeOff
 *
 * @brief       -
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
static void Mrfi_RxModeOff(void)
{
  /*disable receive interrupts */
  RFIRQM0 &= ~IM_FIFOP;

  /* turn off radio */
  RFST = ISRFOFF;

  /* flush the receive FIFO of any residual data */
  MRFI_RADIO_FLUSH_RX_BUFFER();

  /* clear receive interrupt */
  RFIRQF0 = ~IRQ_FIFOP;
}
예제 #2
0
/**************************************************************************************************
 * @fn          Mrfi_RxModeOff
 *
 * @brief       Disable frame receiving.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
static void Mrfi_RxModeOff(void)
{
  /* NOTE: Bug (#1) described in the errata swrz024.pdf for CC2520:
   * The sequence of sending the RFOFF strobe takes care of the bug.
   * If this is changed, ensure that the bug workaround is in place.
   */

  /*disable receive interrupts */
  MRFI_DISABLE_RX_INTERRUPT();

  /* turn off radio */
  mrfiSpiCmdStrobe(SRFOFF);

  /* flush the receive FIFO of any residual data */
  MRFI_RADIO_FLUSH_RX_BUFFER();

  /* clear receive interrupt */
  MRFI_CLEAR_RX_INTERRUPT_FLAG();
}
예제 #3
0
/**************************************************************************************************
 * @fn          Mrfi_FiFoPIsr
 *
 * @brief       Interrupt Service Routine for handling FIFO_P event.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void Mrfi_FiFoPIsr(void)
{
  uint8_t numBytes;
  uint8_t i;

  /* NOTE: Bug #2 described in the errata swrz024.pdf for CC2520:
   * There is a possiblity of small glitch in the fifo_p signal
   * (2 cycle of 32 MHz). Workaround is to make sure that fifo_p signal stays
   * high for longer than that. Else, it is a false alarm.
   */
  if(!MRFI_FIFOP_STATUS()) return;
  if(!MRFI_FIFOP_STATUS()) return;

  /* Ah... it is for real... Continue processing. */

  /* We should receive this interrupt only in RX state
   * Should never receive it if RX was turned ON only for
   * some internal mrfi processing like - during CCA.
   * Otherwise something is terribly wrong.
   */
  MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX );

  do
  {
    /*
     * Pend on frame rx completion. First time through this always passes.
     * Later, though, it is possible that the Rx FIFO has bytes but we
     * havn't received a complete frame yet.
     */
    while( !MRFI_FIFOP_STATUS() );

    /* Check for Rx overflow. Checking here means we may flush a valid frame */
    if( MRFI_FIFOP_STATUS() && !MRFI_FIFO_STATUS() )
    {
      /* Flush receive FIFO to recover from overflow */
      MRFI_RADIO_FLUSH_RX_BUFFER();
      break;
    }

    /* clear interrupt flag so we can detect another frame later. */
    MRFI_CLEAR_RX_INTERRUPT_FLAG();

    /*
     *  Determine number of bytes to be read from receive FIFO.  The first byte
     *  has the number of bytes in the packet.  A mask must be applied though
     *  to strip off unused bits.  The number of bytes in the packet does not
     *  include the length byte itself but does include the FCS (generically known
     *  as RX metrics).
     */
    mrfiSpiReadRxFifo(&numBytes, 1);
    numBytes &= IEEE_PHY_PACKET_SIZE_MASK;

    /* see if frame will fit in maximum available buffer or is too small */
    if (((numBytes + MRFI_LENGTH_FIELD_SIZE - MRFI_RX_METRICS_SIZE) > MRFI_MAX_FRAME_SIZE) ||
         (numBytes < MRFI_MIN_SMPL_FRAME_SIZE))
    {
      uint8_t dummy;
      /* packet is too big or too small. remove it from FIFO */
      for (i=0; i<numBytes; i++)
      {
        /* read and discard bytes from FIFO */
        mrfiSpiReadRxFifo(&dummy, 1);
      }
    }
    else
    {
      uint8_t *p, nextByte;

      /* Clear out my buffer to remove leftovers in case a bogus packet gets through */
      for(i=0; i < MRFI_MAX_FRAME_SIZE; i++)
      {
        mrfiIncomingPacket.frame[i] = 0;
      }

      /* set pointer at first byte of frame storage */
      p  = &mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFFSET];

      /*
       *  Store frame length into the incoming packet memory.  Size of rx metrics
       *  is subtracted to get the MRFI frame length which separates rx metrics from
       *  the frame length.
       */
      *p = numBytes - MRFI_RX_METRICS_SIZE;

      /* read frame bytes from rx FIFO and store into incoming packet memory */
      p++;
      mrfiSpiReadRxFifo(p, numBytes-MRFI_RX_METRICS_SIZE);

      /* The next two bytes in the rx fifo are:
       * - RSSI of the received frams
       * - CRC OK bit and the 7 bit wide correlation value.
       * Read this rx metrics and store to incoming packet.
       */

      /* Add the RSSI offset to get the proper RSSI value. */
      mrfiSpiReadRxFifo(&nextByte, 1);
      mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] = Mrfi_CalculateRssi(nextByte);

      /* The second byte has 7 bits of Correlation value and 1 bit of
       * CRC pass/fail info. Remove the CRC pass/fail bit info.
       * Also note that for CC2520 radio this is the correlation value and not
       * the LQI value. Some convertion is needed to extract the LQI value.
       * This convertion is left to the application at this time.
       */
      mrfiSpiReadRxFifo(&nextByte, 1);
      mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = nextByte & MRFI_RX_METRICS_LQI_MASK;

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

    /* If the client code takes long time to process the frame,
     * rx fifo could overflow during this time. As soon as this condition is
     * reached, the radio fsm stops all activities till the rx fifo is flushed.
     * It also puts the fifo signal low. When we come out of this while loop,
     * we really don't know if it is because of overflow condition or
     * there is no data in the fifo. So we must check for overflow condition
     * before exiting the ISR otherwise it could get stuck in this "overflow"
     * state forever.
     */

  } while( MRFI_FIFO_STATUS() ); /* Continue as long as there is some data in FIFO */

  /* Check if we exited the loop due to fifo overflow.
   * and not due to no data in fifo.
   */
  if( MRFI_FIFOP_STATUS() && !MRFI_FIFO_STATUS() )
  {
    /* Flush receive FIFO to recover from overflow */
    MRFI_RADIO_FLUSH_RX_BUFFER();
  }
}
예제 #4
0
/**************************************************************************************************
 * @fn          MRFI_RxIsr
 *
 * @brief       Receive interrupt.  Reads incoming packet from radio FIFO.  If CRC passes the
 *              external function MRFI_RxCompleteISR() is called.
 *
 *              Note : All RF interrupts use this same interrupt vector.  Normally, the interrupt
 *              enable bits and interrupt flag bits are examined to see which interrupts need to
 *              be serviced.  In this implementation, only the FIFOP interrupt is used.  This
 8              function is optimized to take advantage of that fact.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
BSP_ISR_FUNCTION( MRFI_RxIsr, RF_VECTOR )
{
  uint8_t numBytes;
  uint8_t i, crcOK;

  /* We should receive this interrupt only in RX state
   * Should never receive it if RX was turned On only for
   * some internal mrfi processing like - during CCA.
   * Otherwise something is terribly wrong.
   */
  MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX );

  /* While there is stuff in the Rx FIFO... */
  do {
    /*
     * Pend on frame completion. First timne through this always passes.
     * Later, though, it is possible that the Rx FIFO has bytes but we
     * havn't received a complete frame yet.
     */
    while (!(RFIRQF0 & IRQ_FIFOP)) ;

    /* Check for Rx overflow. Checking here means we may flush a valid frame */
    if ((FSMSTAT1 & FIFOP) && (!(FSMSTAT1 & FIFO)))
    {
      /* flush receive FIFO to recover from overflow (per datasheet, flush must be done twice) */
      MRFI_RADIO_FLUSH_RX_BUFFER();
      break;
    }

    /* clear interrupt flag so we can detect another frame later. */
    RFIRQF0 &= ~IRQ_FIFOP;

    /* ------------------------------------------------------------------
     *    Read packet from FIFO
     *   -----------------------
     */

    /*
     *  Determine number of bytes to be read from receive FIFO.  The first byte
     *  has the number of bytes in the packet.  A mask must be applied though
     *  to strip off unused bits.  The number of bytes in the packet does not
     *  include the length byte itself but does include the FCS (generically known
     *  as RX metrics).
     */
    numBytes = RFD & IEEE_PHY_PACKET_SIZE_MASK;

    /* see if frame will fit in maximum available buffer or is too small */
    if (((numBytes + MRFI_LENGTH_FIELD_SIZE - MRFI_RX_METRICS_SIZE) > MRFI_MAX_FRAME_SIZE) ||
         (numBytes < MRFI_MIN_SMPL_FRAME_SIZE))
    {
      /* packet is too big or too small. remove it from FIFO */
      for (i=0; i<numBytes; i++)
      {
        /* read and discard bytes from FIFO */
        RFD;
      }
    }
    else
    {
      uint8_t *p, *p1;

      /* set pointer at first byte of frame storage */
      p  = &mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFFSET];
      p1 = mrfiIncomingPacket.frame;

      /* Clear out my buffer to remove leftovers in case a bogus packet gets through */
      memset(p1, 0x0, sizeof(mrfiIncomingPacket.frame));

      /*
       *  Store frame length into the incoming packet memory.  Size of rx metrics
       *  is subtracted to get the MRFI frame length which separates rx metrics from
       *  the frame length.
       */
      *p = numBytes - MRFI_RX_METRICS_SIZE;

      /* read frame bytes from receive FIFO and store into incoming packet memory */
      for (i=0; i<numBytes-MRFI_RX_METRICS_SIZE; i++)
      {
        p++;
        *p = RFD;
      }

      /* read rx metrics and store to incoming packet */

      /* Add the RSSI offset to get the proper RSSI value. */
      mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] = RFD + MRFI_RSSI_OFFSET;

      /* The second byte has 7 bits of Correlation value and 1 bit of
       * CRC pass/fail info. Remove the CRC pass/fail bit info.
       * Also note that for CC2430 radio this is the correlation value and not
       * the LQI value. Some convertion is needed to extract the LQI value.
       * This convertion is left to the application at this time.
       */
      crcOK = RFD;   /* get CRC/LQI byte */
      if (!(crcOK & (~MRFI_RX_METRICS_LQI_MASK)))
      {
        /* bad CRC. Move on... */
        continue;
      }

      /* CRC OK. Save LQI info */
      mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = (crcOK & MRFI_RX_METRICS_LQI_MASK);

      /* 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" */
        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. */

  RFIRQF0 &= ~IRQ_FIFOP; /* Clear the interrupt source flag. */
}
예제 #5
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();
}
예제 #6
0
/**************************************************************************************************
 * @fn          MRFI_RxIsr
 *
 * @brief       Receive interrupt.  Reads incoming packet from radio FIFO.  If CRC passes the
 *              external function MRFI_RxCompleteISR() is called.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
BSP_ISR_FUNCTION( MRFI_RxIsr, RF_VECTOR )
{
  uint8_t numBytes;
  uint8_t i, crcOK;

  /* Clear the MCU interrupt. */
  S1CON = 0x00;

  /* Process FIFOP interrupt */
  if(RFIF & IRQ_FIFOP)
  {
    /* We should receive this interrupt only in RX state
     * Should never receive it if RX was turned On only for
     * some internal mrfi processing like - during CCA.
     * Otherwise something is terribly wrong.
     */
    MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX );

    /* While there is at least one frame in the Rx FIFO */
    while(RFIF & IRQ_FIFOP)
    {
      /* Check for Rx overflow. Checking here means we may flush a valid frame */
      if ((RFSTATUS & FIFOP) && (!(RFSTATUS & FIFO)))
      {
        /* flush receive FIFO to recover from overflow (per datasheet, flush must be done twice) */
        MRFI_RADIO_FLUSH_RX_BUFFER();
        break;
      }

      /* ------------------------------------------------------------------
       *    Read packet from FIFO
       *   -----------------------
       */

      /*
       *  Determine number of bytes to be read from receive FIFO.  The first byte
       *  has the number of bytes in the packet.  A mask must be applied though
       *  to strip off unused bits.  The number of bytes in the packet does not
       *  include the length byte itself but does include the FCS (generically known
       *  as RX metrics).
       */
      numBytes = RFD & IEEE_PHY_PACKET_SIZE_MASK;

      /* see if frame will fit in maximum available buffer or is too small */
      if (((numBytes + MRFI_LENGTH_FIELD_SIZE - MRFI_RX_METRICS_SIZE) > MRFI_MAX_FRAME_SIZE) ||
           (numBytes < MRFI_MIN_SMPL_FRAME_SIZE))
      {
        /* packet is too big or too small. remove it from FIFO */
        for (i=0; i<numBytes; i++)
        {
          /* read and discard bytes from FIFO */
          RFD;
        }
      }
      else
      {
        uint8_t *p, *p1;

        /* set pointer at first byte of frame storage */
        p  = &mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFFSET];
        p1 = mrfiIncomingPacket.frame;

        /* Clear out my buffer to remove leftovers in case a bogus packet gets through */
        memset(p1, 0x0, sizeof(mrfiIncomingPacket.frame));

        /*
         *  Store frame length into the incoming packet memory.  Size of rx metrics
         *  is subtracted to get the MRFI frame length which separates rx metrics from
         *  the frame length.
         */
        *p = numBytes - MRFI_RX_METRICS_SIZE;

        /* read frame bytes from receive FIFO and store into incoming packet memory */
        for (i=0; i<numBytes-MRFI_RX_METRICS_SIZE; i++)
        {
          p++;
          *p = RFD;
        }

        /* read rx metrics and store to incoming packet */

        /* Add the RSSI offset to get the proper RSSI value. */
        mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_RSSI_OFS] = RFD + MRFI_RSSI_OFFSET;

        /* The second byte has 7 bits of Correlation value and 1 bit of
         * CRC pass/fail info. Remove the CRC pass/fail bit info.
         * Also note that for CC2430 radio this is the correlation value and not
         * the LQI value. Some convertion is needed to extract the LQI value.
         * This convertion is left to the application at this time.
         */
        crcOK = RFD;   /* get CRC/LQI byte */

        if (crcOK & MRFI_RX_METRICS_CRC_OK_MASK)
        {
          /* CRC OK. Save LQI info */
          mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] = (crcOK & MRFI_RX_METRICS_LQI_MASK);

          /* 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" */
            MRFI_RxCompleteISR();
          }
        }
      } /* Frame fits in the buffer. */

      /* Clear the interrupt source flag. This must be done after reading
       * the frame from the buffer. Otherwise the flag remains set. If another
       * frame is sitting in the buffer, the IRQ_FIFOP will be immediately set
       * again.
       */
       RFIF &= ~IRQ_FIFOP;
    }   /* While there is at least one frame in the Rx FIFO */
  }     /* Process FIFOP interrupt */
  else
  {
    /* Don't assert here. It is possible that the MCU interrupt was set by
     * FIFOP but we processed it in the while() loop of the FIFOP handler in
     * the previous run of this ISR.
     */

    /* If any other RF interrupt is enabled, add that handler here. */
  }

  /* Bugzilla Chip Bug#297: Don't delete */
  RFIF = 0xFF;
}
예제 #7
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();
}