Exemplo n.º 1
0
/**************************************************************************************************
 * @fn          MRFI_Rssi
 *
 * @brief       Returns "live" RSSI value
 *
 * @param       none
 *
 * @return      RSSI value in units of dBm.
 **************************************************************************************************
 */
int8_t MRFI_Rssi(void)
{
  /* Radio must be in RX state to measure rssi. */
  MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX );

  /* Wait for the RSSI to be valid:
   * Just having the Radio ON is not enough to read
   * the correct RSSI value. The Radio must in RX mode for
   * a certain duration.
   */
  MRFI_RSSI_VALID_WAIT();

  /* Read and convert RSSI to decimal and do offset compensation. */
  return( Mrfi_CalculateRssi(mrfiSpiReadReg(RSSI)) );
}
Exemplo n.º 2
0
/**************************************************************************************************
 * @fn          MRFI_Init
 *
 * @brief       Initialize MRFI.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_Init(void)
{
  /* Configure Output lines */
  MRFI_CONFIG_RESETN_PIN_AS_OUTPUT();
  MRFI_CONFIG_VREG_EN_PIN_AS_OUTPUT();

  /* Configure Input lines */
  MRFI_CONFIG_TX_FRAME_DONE_AS_INPUT();
  MRFI_CONFIG_FIFO_AS_INPUT();
  MRFI_CONFIG_FIFOP_AS_INPUT();

  /* Initialize SPI */
  mrfiSpiInit();

  /* Power up the radio chip */
  Mrfi_TurnOnRadioPower();

  /* Confirm that we are talking to the right hardware */
  MRFI_ASSERT(mrfiSpiReadReg(CHIPID) == MRFI_RADIO_PARTNUM);


  /* Random Number Generator:
   * The seed value for the randon number generator logic
   * is derived from the radio.
   */

  /* Set radio in rx mode, but with symbol search disabled. Used for RSSI
   * measurments or when we don't care about the received frames.
   */
  mrfiSpiWriteReg(FRMCTRL0, FRMCTRL0_RESET_VALUE | RX_MODE_RSSI_ONLY);

  /* Turn on the receiver */
  mrfiSpiCmdStrobe(SRXON);

  /*
   *  Wait for RSSI to be valid. RANDOM command strobe can be used
   *  to generate random number only after this.
   */
  MRFI_RSSI_VALID_WAIT();


  /* Get random byte from the radio */
  mrfiRndSeed = mrfiSpiRandomByte();

 /*
  *  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). If it is zero, initialize it to something.
  */
  if(mrfiRndSeed == 0)
  {
      mrfiRndSeed = 0x80;
  }

  /* Random number initialization is done. Turn the radio off */
  Mrfi_TurnOffRadioPower();

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

  /**********************************************************************************
   *                            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();

  BSP_ENABLE_INTERRUPTS();
}
Exemplo n.º 3
0
/**************************************************************************************************
 * @fn          MRFI_SyncPinRxIsr
 *
 * @brief       This interrupt is called when the SYNC signal transition from high to low. 
 *              The sync signal is routed to the sync pin which is a GPIO pin.  This high-to-low
 *              transition signifies a receive has completed.  The SYNC signal also goes from
 *              high to low when a transmit completes.   This is protected against within the
 *              transmit function by disabling sync pin interrupts until transmit completes.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
static void MRFI_SyncPinRxIsr(void)
{
  uint8_t frameLen;
  uint8_t rxBytes;

  /* ------------------------------------------------------------------
   *    Abort if asleep
   *   -----------------
   */
 
  /*
   *  If radio is asleep, abort immediately.  Nothing further is required.
   *  If radio is awake, set "receive active" flag and continue processing the receive.
   */
  {
    bspIState_t s;
    
    /* critical section necessary for watertight testing and setting of state variables */
    BSP_ENTER_CRITICAL_SECTION(s);

    /* if radio is asleep, just abort from here */
    if (mrfiRadioIsSleeping)
    {
      BSP_EXIT_CRITICAL_SECTION(s);
      return;
    }
    
    /* radio is not asleep, set flag that indicates receive is active */
    mrfiRxActive = 1;
    BSP_EXIT_CRITICAL_SECTION(s);
  }

  
  /* ------------------------------------------------------------------
   *    Get RXBYTES
   *   -------------
   */

  /*
   *  Read the RXBYTES register from the radio.
   *  Bit description of RXBYTES register:
   *    bit 7     - RXFIFO_OVERFLOW, set if receive overflow occurred
   *    bits 6:0  - NUM_BYTES, number of bytes in receive FIFO
   *
   *  Due a chip bug, the RXBYTES register must read the same value twice
   *  in a row to guarantee an accurate value.
   */
  {
    uint8_t rxBytesVerify;
    
    rxBytesVerify = mrfiSpiReadReg(MRFI_CC2500_SPI_REG_RXBYTES);

    do 
    {
      rxBytes = rxBytesVerify;
      rxBytesVerify = mrfiSpiReadReg(MRFI_CC2500_SPI_REG_RXBYTES);
    }
    while (rxBytes != rxBytesVerify);
  }

  
  /* ------------------------------------------------------------------
   *    FIFO empty?
   *   -------------
   */

  /*
   *  See if the receive FIFIO is empty before attempting to read from it.
   *  It is possible nothing the FIFO is empty even though the interrupt fired.
   *  This can happen if address check is enabled and a non-matching packet is
   *  received.  In that case, the radio automatically removes the packet from
   *  the FIFO.
   */
  if (rxBytes == 0)
  {
    /* receive FIFO is empty - do nothing, skip to end */
  }
  else
  {
    /* receive FIFO is not empty, continue processing */

    /* ------------------------------------------------------------------
     *    Process frame length
     *   ----------------------
     */
    
    /* read the first byte from FIFO - the packet length */
    mrfiSpiReadRxFifo(&frameLen, MRFI_LENGTH_FIELD_SIZE);

    /*
     *  Make sure that the frame length just read corresponds to number of bytes in the buffer.
     *  If these do not match up something is wrong.
     *
     *  This can happen for several reasons:
     *   1) Incoming packet has an incorrect format or is corrupted.
     *   2) The receive FIFO overflowed.  Overflow is indicated by the high
     *      bit of rxBytes.  This guarantees the value of rxBytes value will not
     *      match the number of bytes in the FIFO for overflow condition.
     *   3) Interrupts were blocked for an abnormally long time which
     *      allowed a following packet to at least start filling the
     *      receive FIFO.  In this case, all received and partially received
     *      packets will be lost - the packet in the FIFO and the packet coming in.
     *      This is the price the user pays if they implement a giant
     *      critical section.
     *   4) A failed transmit forced radio to IDLE state to flush the transmit FIFO.
     *      This could cause an active receive to be cut short.
     */
    if (rxBytes != (frameLen + MRFI_LENGTH_FIELD_SIZE + MRFI_RX_METRICS_SIZE))
    {
      bspIState_t s;

      /* mismatch between bytes-in-FIFO and frame length */

      /*
       *  Flush receive FIFO to reset receive.  Must go to IDLE state to do this.
       *  The critical section guarantees a transmit does not occur while cleaning up.
       */
      BSP_ENTER_CRITICAL_SECTION(s);
      mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SIDLE);
      mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SFRX);
      mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SRX);
      BSP_EXIT_CRITICAL_SECTION(s);
      
      /* flush complete, skip to end */
    }
    else
    {
      /* bytes-in-FIFO and frame length match up - continue processing */
      
      /* ------------------------------------------------------------------
       *    Get packet
       *   ------------
       */

      /* set length field */
      mrfiIncomingPacket.frame[MRFI_LENGTH_FIELD_OFS] = frameLen;
  
      /* get packet from FIFO */
      mrfiSpiReadRxFifo(&(mrfiIncomingPacket.frame[MRFI_FRAME_BODY_OFS]), frameLen);
  
      /* get receive metrics from FIFO */
      mrfiSpiReadRxFifo(&(mrfiIncomingPacket.rxMetrics[0]), MRFI_RX_METRICS_SIZE);


      /* ------------------------------------------------------------------
       *    CRC check
       *   ------------
       */

      /*
       *  Note!  Automatic CRC check is not, and must not, be enabled.  This feature
       *  flushes the *entire* receive FIFO when CRC fails.  If this feature is
       *  enabled it is possible to be reading from the FIFO and have a second
       *  receive occur that fails CRC and automatically flushes the receive FIFO.
       *  This could cause reads from an empty receive FIFO which puts the radio
       *  into an undefined state.
       */
      
      /* determine if CRC failed */
      if (!(mrfiIncomingPacket.rxMetrics[MRFI_RX_METRICS_CRC_LQI_OFS] & MRFI_RX_METRICS_CRC_OK_MASK))
      {
        /* CRC failed - do nothing, skip to end */
      }
      else
      {
        /* CRC passed - continue processing */

      /* ------------------------------------------------------------------
       *    Filtering 
       *   -----------
       */

        /* see if filtering is enabled and, if so, determine if address is a match */
        if (mrfiRxFilterEnabled && memcmp(MRFI_P_DST_ADDR(&mrfiIncomingPacket), &mrfiRxFilterAddr[0], MRFI_ADDR_SIZE))
        {
          /* packet filtered out - do nothing, skip to end */
        }
        else
        {
          /* packet not filtered out - receive successful */
          
          /* ------------------------------------------------------------------
           *    Receive succeeded
           *   -------------------
           */

          /* call external, higher level "receive complete" processing routine */
          MRFI_RxCompleteISR();
        }
      }
    }
  }

  /* ------------------------------------------------------------------
   *    End of function
   *   -------------------
   */
  
  /* clear "receive active" flag and exit */
  mrfiRxActive = 0;
}
Exemplo n.º 4
0
// *************************************************************************************************
// @fn          wbsl_config
// @brief       Configures the Radio Settings for WBSL
// @param       none
// @return      none
// *************************************************************************************************
void wbsl_config(void)
{

    if (!sInitWbslDone)
	{
	   /* ------------------------------------------------------------------
		*    Initialization
		*   -----------------
		*/

		/* initialize GPIO pins */
	    WBSL_CONFIG_GDO0_PIN_AS_INPUT();

		/* initialize SPI */
		wbsl_SpiInit();

		/* ------------------------------------------------------------------
		 *    Radio power-up reset
		 * ----------------------
		 */
	    WBSL_SPI_ASSERT(WBSL_SPI_CSN_IS_HIGH());

		/* pulse CSn low then high */
		WBSL_SPI_DRIVE_CSN_LOW();
		wbsl_DelayUsec(10);
		WBSL_SPI_DRIVE_CSN_HIGH();

		/* hold CSn high for at least 40 microseconds */
		wbsl_DelayUsec(40);

	    /* pull CSn low and wait for SO to go low */
		WBSL_SPI_DRIVE_CSN_LOW();
		while (WBSL_SPI_SO_IS_HIGH());

		/* return CSn pin to its default high level */
		WBSL_SPI_DRIVE_CSN_HIGH();

	    /* ------------------------------------------------------------------
		 *    Run-time integrity checks
		 * ---------------------------
		 */

	    /* verify that SPI is working, PKTLEN is an arbitrary read/write register used for testing */
		#ifdef WBSL_ASSERTS_ARE_ON
		#define TEST_VALUE 0xA5
		    wbsl_SpiWriteReg( PKTLEN, TEST_VALUE );
		    WBSL_SPI_ASSERT( mrfiSpiReadReg( PKTLEN ) == TEST_VALUE ); /* SPI is not responding */
		#endif

		  /* verify the correct radio is installed */
	    WBSL_SPI_ASSERT( wbsl_SpiReadReg( PARTNUM ) == WBSL_RADIO_PARTNUM );      /* incorrect radio specified */
		WBSL_SPI_ASSERT( wbsl_SpiReadReg( VERSION ) >= WBSL_RADIO_MIN_VERSION );  /* obsolete radio specified  */

		  /* ------------------------------------------------------------------
		   *    Configure radio
		   *   -----------------
		   */

		  /* initialize radio registers */
		{
		    u8 i;

		  	for (i=0; i<(sizeof(wbslRadioCfg)/sizeof(wbslRadioCfg[0])); i++)
		  	{
		       wbsl_SpiWriteReg(wbslRadioCfg[i][0], wbslRadioCfg[i][1]);
		  	}
		}


		  /* ------------------------------------------------------------------
		   *    Configure interrupts
		   *   ----------------------
		   */

		  /*
		   *  Configure and enable the SYNC signal interrupt.
		   *
		   *  This interrupt is used to indicate receive.  The SYNC signal goes
		   *  high when a receive OR a transmit begins.  It goes high once the
		   *  sync word is received or transmitted and then goes low again once
		   *  the packet completes.
		   */

		 WBSL_CONFIG_GDO0_AS_SYNC_SIGNAL();
		 WBSL_CONFIG_SYNC_PIN_FALLING_EDGE_INT();
		 WBSL_CLEAR_SYNC_PIN_INT_FLAG();

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

    sInitWbslDone=1;

}
Exemplo n.º 5
0
/**************************************************************************************************
 * @fn          MRFI_Init
 *
 * @brief       Initialize MRFI.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_Init(void)
{
  /* ------------------------------------------------------------------
   *    Initialization
   *   -----------------
   */

  /* initialize radio state variables */
  mrfiRxFilterEnabled = 0;
  mrfiRadioIsSleeping = 0;
  mrfiTxActive = 0;
  mrfiRxActive = 0;
  
  /* initialize GPIO pins */
  MRFI_CONFIG_GDO0_PIN_AS_INPUT();
  MRFI_CONFIG_GDO2_PIN_AS_INPUT();
  
  /* initialize SPI */
  mrfiSpiInit();
  
  /* ------------------------------------------------------------------
   *    Radio power-up reset
   *   ----------------------
   */
  MRFI_ASSERT(MRFI_SPI_CSN_IS_HIGH());
  
  /* pulse CSn low then high */
  MRFI_SPI_DRIVE_CSN_LOW();
  MRFI_DELAY(10);
  MRFI_SPI_DRIVE_CSN_HIGH();

  /* hold CSn high for at least 40 microseconds */
  MRFI_DELAY(100);
  
  /* pull CSn low and wait for SO to go low */
  MRFI_SPI_DRIVE_CSN_LOW();
  while (MRFI_SPI_SO_IS_HIGH());

  /* directly send strobe command - cannot use function as it affects CSn pin */
  MRFI_SPI_WRITE_BYTE(MRFI_CC2500_SPI_STROBE_SRES);
  MRFI_SPI_WAIT_DONE();

  /* wait for SO to go low again, reset is complete at that point */
  while (MRFI_SPI_SO_IS_HIGH());

  /* return CSn pin to its default high level */
  MRFI_SPI_DRIVE_CSN_HIGH();

  /* ------------------------------------------------------------------
   *    Run-time integrity checks
   *   ---------------------------
   */
  
  /* verify that SPI is working */
#ifdef MRFI_ASSERTS_ARE_ON
#define TEST_VALUE 0xA5
  mrfiSpiWriteReg( MRFI_CC2500_SPI_REG_PKTLEN, TEST_VALUE );
  MRFI_ASSERT( mrfiSpiReadReg( MRFI_CC2500_SPI_REG_PKTLEN ) == TEST_VALUE ); /* SPI is not responding */
#endif

  /* verify the correct radio is installed */
  MRFI_ASSERT( mrfiSpiReadReg( MRFI_CC2500_SPI_REG_PARTNUM ) == MRFI_RADIO_PARTNUM);      /* incorrect radio specified */
  MRFI_ASSERT( mrfiSpiReadReg( MRFI_CC2500_SPI_REG_VERSION ) >= MRFI_RADIO_MIN_VERSION);  /* obsolete radio specified  */
  
  /* ------------------------------------------------------------------
   *    Configure radio
   *   -----------------
   */

  /* initialize radio registers */
  {
    uint8_t i;
    
    for (i=0; i<(sizeof(mrfiRadioCfg)/sizeof(mrfiRadioCfg[0])); i++)
    {
      mrfiSpiWriteReg(mrfiRadioCfg[i][0], mrfiRadioCfg[i][1]);
    }
  }

  /* send strobe to turn on receiver */
  mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SRX);
  
  /* ------------------------------------------------------------------
   *    Configure interrupts
   *   ----------------------
   */

  /*
   *  Configure and enable the SYNC signal interrupt.
   *
   *  This interrupt is used to indicate receive.  The SYNC signal goes
   *  high when a receive OR a transmit begins.  It goes high once the
   *  sync word is received or transmitted and then goes low again once
   *  the packet completes.
   */
  MRFI_CONFIG_SYNC_PIN_FALLING_EDGE_INT();
  MRFI_CLEAR_SYNC_PIN_INT_FLAG();
  MRFI_ENABLE_SYNC_PIN_INT();
  
  /* configure PA_PD signal interrupt */
  MRFI_CONFIG_PAPD_FALLING_EDGE_INT();
  
  /* enable global interrupts */
  BSP_ENABLE_INTERRUPTS();
}