示例#1
0
/**************************************************************************************************
 * @fn          MRFI_Sleep
 *
 * @brief       Request radio go to sleep.
 *
 * @param       none
 *
 * @return      zero : if successfully went to sleep
 *              non-zero : if sleep was not entered
 **************************************************************************************************
 */
uint8_t MRFI_Sleep(void)
{
  /* if radio is already asleep just indicate radio went to sleep successfully */
  if (mrfiRadioIsSleeping)
  {
    /* return value of zero indicates sleep state was entered */
    return( 0 );
  }

  /* determine if sleep is possible and return the corresponding code */
  {
    bspIState_t s;

    /* critical section necessary for watertight testing and setting of state variables */
    BSP_ENTER_CRITICAL_SECTION(s);
    if (!mrfiTxActive && !mrfiRxActive)
    {
      mrfiRadioIsSleeping = 1;
      MRFI_DISABLE_SYNC_PIN_INT();
      mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SIDLE);
      mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SPWD);
      BSP_EXIT_CRITICAL_SECTION(s);
      /* return value of zero indicates sleep state was entered */
      return( 0 );
    }
    else
    {
      BSP_EXIT_CRITICAL_SECTION(s);
      /* return value of non-zero indicates sleep state was *not* entered */
      return( 1 );
    }
  }
}
示例#2
0
/**************************************************************************************************
 * @fn          MRFI_WakeUp
 *
 * @brief       Wake up radio from sleep state.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void MRFI_WakeUp(void)
{
  /* if radio is already awake, just ignore wakeup request */
  if (!mrfiRadioIsSleeping)
  {
    return;
  }

  /* drive CSn low to initiate wakeup */
  MRFI_SPI_DRIVE_CSN_LOW();
  
  /* wait for MISO to go high indicating the oscillator is stable */
  while (MRFI_SPI_SO_IS_HIGH());
  
  /* wakeup is complete, drive CSn high and continue */
  MRFI_SPI_DRIVE_CSN_HIGH();

/*
 *  The test registers must be restored after sleep for the CC1100 and CC2500 radios.
 *  This is not required for the CC1101 radio.
 */
#ifndef MRFI_CC1101
  mrfiSpiWriteReg( MRFI_CC2500_SPI_REG_TEST2, SMARTRF_SETTING_TEST2 );
  mrfiSpiWriteReg( MRFI_CC2500_SPI_REG_TEST1, SMARTRF_SETTING_TEST1 );
  mrfiSpiWriteReg( MRFI_CC2500_SPI_REG_TEST0, SMARTRF_SETTING_TEST0 );
#endif

  /* clear any residual SYNC pin interrupt and then re-enable SYNC pin interrupts */
  MRFI_CLEAR_SYNC_PIN_INT_FLAG();
  MRFI_ENABLE_SYNC_PIN_INT();

  /* clear sleep flag and enter receive mode */
  mrfiRadioIsSleeping = 0;
  mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SRX);
}
示例#3
0
/**************************************************************************************************
 * @fn          Mrfi_RxModeOn
 *
 * @brief       Enable frame receiving.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
static void Mrfi_RxModeOn(void)
{
  /* NOTE: Bug #1 described in the errata swrz024.pdf for CC2520:
   * This function is never called if the radio is already in receive state.
   * If this is changed, must implement the bug workaround as described in the
   * errata (flush the Rx FIFO).
   */

  /* clear any residual receive interrupt */
  MRFI_CLEAR_RX_INTERRUPT_FLAG();

  /* send strobe to enter receive mode */
  mrfiSpiCmdStrobe(SRXON);

  /* enable receive interrupts */
  MRFI_ENABLE_RX_INTERRUPT();
}
示例#4
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();
}
示例#5
0
/**************************************************************************************************
 * @fn          MRFI_Transmit
 *
 * @brief       Transmit a packet.
 *
 * @param       pPacket - pointer to packet to transmit
 *              txType  - FORCED or CCA
 *
 * @return      Return code indicates success or failure of transmit:
 *                  MRFI_TX_RESULT_SUCCESS - transmit succeeded
 *                  MRFI_TX_RESULT_FAILED  - transmit failed because CCA failed
 **************************************************************************************************
 */
uint8_t MRFI_Transmit(mrfiPacket_t * pPacket, uint8_t txType)
{
  uint8_t txResult = MRFI_TX_RESULT_SUCCESS;
  static uint8_t dsn = 0;

  /* radio must be awake to transmit */
  MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF );

  /* TX_DONE line status must be low. If high, some state logic problem. */
  MRFI_ASSERT(!MRFI_TX_DONE_STATUS());


  /* Turn off reciever. We ignore/drop incoming packets during transmit. */
  Mrfi_RxModeOff();


  /* --------------------------------------
   *    Populate the IEEE fields in frame
   *   ------------------------------------
   */

  /* set the sequence number, also known as DSN (Data Sequence Number) */
  pPacket->frame[MRFI_DSN_OFFSET]   = dsn++;
  pPacket->frame[MRFI_FCF_OFFSET]   = MRFI_FCF_0_7;
  pPacket->frame[MRFI_FCF_OFFSET+1] = MRFI_FCF_8_15;


  /* ------------------------------------------------------------------
   *    Write packet to transmit FIFO
   *   --------------------------------
   */
  {
    uint8_t txBufLen;
    uint8_t frameLen;
    uint8_t *p;

    /* flush FIFO of any previous transmit that did not go out */
    MRFI_RADIO_FLUSH_TX_BUFFER();

    /* set point at beginning of outgoing frame */
    p = &pPacket->frame[MRFI_LENGTH_FIELD_OFFSET];

    /* get number of bytes in the packet (does not include the length byte) */
    txBufLen = *p;

    /*
     *  Write the length byte to the FIFO.  This length does *not* include the length field
     *  itself but does include the size of the FCS (generically known as RX metrics) which
     *  is generated automatically by the radio.
     */
    frameLen = txBufLen + MRFI_RX_METRICS_SIZE;

    mrfiSpiWriteTxFifo(&frameLen, 1);

    /* skip the length field which we already sent to FIFO. */
    p++;
    /* write packet bytes to FIFO */
    mrfiSpiWriteTxFifo(p, txBufLen);
  }

  /* Forced transmit */
  if(txType == MRFI_TX_TYPE_FORCED)
  {
    /* NOTE: Bug (#1) described in the errata swrz024.pdf for CC2520:
     * We never strobe TXON when the radio is in receive state.
     * If this is changed, must implement the bug workaround as described in the
     * errata (flush the Rx FIFO).
     */

    /* strobe transmit */
    mrfiSpiCmdStrobe(STXON);

    /* wait for transmit to complete */
    while (!MRFI_TX_DONE_STATUS());

    /* Clear the TX_FRM_DONE exception flag register in the radio. */
    mrfiSpiBitClear(EXCFLAG0, 1);
  }
  else /* CCA Transmit */
  {
    /* set number of CCA retries */
    uint8_t ccaRetries = MRFI_CCA_RETRIES;

    MRFI_ASSERT( txType == MRFI_TX_TYPE_CCA );

    /* ======================================================================
    *    CCA Algorithm Loop
    * ======================================================================
    */
    while(1)
    {
      /* Turn ON the receiver to perform CCA. Can not call Mrfi_RxModeOn(),
      * since that will enable the rx interrupt, which we do not want.
      */
      mrfiSpiCmdStrobe(SRXON);

      /* Wait for RSSI to be valid. */
      MRFI_RSSI_VALID_WAIT();

      /* Request transmit on cca */
      mrfiSpiCmdStrobe(STXONCCA);

      /* If sampled CCA is set, transmit has begun. */
      if(MRFI_SAMPLED_CCA())
      {
        /* wait for transmit to complete */
        while( !MRFI_TX_DONE_STATUS() );

        /* Clear the TX_FRM_DONE exception flag register in the radio. */
        mrfiSpiBitClear(EXCFLAG0, 1);

        /* transmit is done. break out of CCA algorithm loop */
        break;
      }
      else
      {
        /* ------------------------------------------------------------------
         *    Clear Channel Assessment failed.
         * ------------------------------------------------------------------
         */

        /* Retry ? */
        if(ccaRetries != 0)
        {
          /* turn off reciever to conserve power during backoff */
          Mrfi_RxModeOff();

          /* delay for a random number of backoffs */
          Mrfi_RandomBackoffDelay();

          /* decrement CCA retries before loop continues */
          ccaRetries--;
        }
        else  /* No CCA retries left, abort */
        {
          /* set return value for failed transmit and break */
          txResult = MRFI_TX_RESULT_FAILED;
          break;
        }
      }
    } /* End CCA Algorithm Loop */
  }

  /* turn radio back off to put it in a known state */
  Mrfi_RxModeOff();

  /* If the radio was in RX state when transmit was attempted,
   * put it back in RX state.
   */
  if(mrfiRadioState == MRFI_RADIO_STATE_RX)
  {
    Mrfi_RxModeOn();
  }

  /* return the result of the transmit */
  return( txResult );
}
示例#6
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();
}
示例#7
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;
}
示例#8
0
/**************************************************************************************************
 * @fn          MRFI_Transmit
 *
 * @brief       Transmit a packet using CCA algorithm.
 *
 * @param       pPacket - pointer to packet to transmit
 *
 * @return      Return code indicates success or failure of transmit:
 *                  MRFI_TRANSMIT_SUCCESS - transmit succeeded
 *                  MRFI_TRANSMIT_CCA_FAILED - transmit failed because of CCA check(s)
 *                  MRFI_TRANSMIT_RADIO_ASLEEP - transmit failed because radio was asleep
 **************************************************************************************************
 */
uint8_t MRFI_Transmit(mrfiPacket_t * pPacket)
{
  uint8_t ccaRetries;
  uint8_t txBufLen;
  uint8_t savedSyncIntState;
  uint8_t returnValue;

  /* abort transmit if radio is asleep */
  {
    bspIState_t s;

    /* critical section necessary for watertight testing and setting of state variables */
    BSP_ENTER_CRITICAL_SECTION(s);

    /* if radio is asleep, abort transmit and return reason for failure */
    if (mrfiRadioIsSleeping)
    {
      BSP_EXIT_CRITICAL_SECTION(s);
      return( MRFI_TRANSMIT_RADIO_ASLEEP );
    }
    
    /* radio is not asleep, set flag that indicates transmit is active */
    mrfiTxActive = 1;
    BSP_EXIT_CRITICAL_SECTION(s);
  }
  
  /* set number of CCA retries */
  ccaRetries = MRFI_CCA_RETRIES;
  
  /* compute number of bytes to write to transmit FIFO */
  txBufLen = pPacket->frame[MRFI_LENGTH_FIELD_OFS] + MRFI_LENGTH_FIELD_SIZE;
  
  /* write packet to transmit FIFO */
  mrfiSpiWriteTxFifo(&(pPacket->frame[0]), txBufLen);
  
  /* ===============================================================================
   *    Main Loop 
   *  =============
   */
  for (;;)
  {
    /* CCA delay */
    MRFI_DELAY(2000);

    /* disable sync pin interrupts, necessary because both transmit and receive affect sync signal */
    MRFI_DISABLE_SYNC_PIN_INT();

    /* store the sync pin interrupt flag, important so original state can be restored */
    savedSyncIntState = MRFI_SYNC_PIN_INT_FLAG_IS_SET();
      
    /*
     *  Clear the PA_PD pin interrupt flag.  This flag, not the interrupt itself,
     *  is used to capture the transition that indicates a transmit was started.
     *  The pin level cannot be used to indicate transmit success as timing may
     *  prevent the transition from being detected.  The interrupt latch captures
     *  the event regardless of timing.
     */
    MRFI_CLEAR_PAPD_PIN_INT_FLAG();
    
    /* send strobe to initiate transmit */
    mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_STX);
    
    /*  delay long enough for the PA_PD signal to indicate a successful transmit */
    MRFI_DELAY(250);

    /* if the interrupt flag of the PA_PD pin is set, CCA passed and the transmit has started */
    if (MRFI_PAPD_INT_FLAG_IS_SET())
    {
      /* ------------------------------------------------------------------
       *    Clear Channel Assessment passed.
       *   ----------------------------------
       */

      /* wait for transmit to complete */
      while (!MRFI_PAPD_PIN_IS_HIGH());

      /*
       *  Restore the original sync interrupt state.  The successful transmit just
       *  caused a transition on the sync signal that set the flag (if not already
       *  set).  To restore the original state, the flag is simply cleared if it
       *  was clear earlier.
       */
      if (!savedSyncIntState)
      {
        MRFI_CLEAR_SYNC_PIN_INT_FLAG();
      }
      
      /* transmit complete, enable sync pin interrupts */
      MRFI_ENABLE_SYNC_PIN_INT();

      /* set return value for successful transmit and break */      
      returnValue = MRFI_TRANSMIT_SUCCESS;
      break;
    }

    /* ------------------------------------------------------------------
     *    Clear Channel Assessment failed.
     *   ----------------------------------
     */
    
    /* CCA failed, safe to enable sync pin interrupts */
    MRFI_ENABLE_SYNC_PIN_INT();

    /* if no CCA retries are left, transmit failed so abort */    
    if (ccaRetries == 0)
    {
      bspIState_t s;

      /*
       *  Flush the transmit FIFO.  It must be flushed so that
       *  the next transmit can start with a clean slate.
       *  Critical section prevents receive interrupt from
       *  occurring in the middle of clean-up.
       */
      BSP_ENTER_CRITICAL_SECTION(s);
      mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SIDLE);
      mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SFTX);
      mrfiSpiCmdStrobe(MRFI_CC2500_SPI_STROBE_SRX);
      BSP_EXIT_CRITICAL_SECTION(s);

      /* set return value for failed transmit and break */      
      returnValue = MRFI_TRANSMIT_CCA_FAILED;
      break;
    }

    /* decrement CCA retries before loop continues */
    ccaRetries--;
  }
  /*
   * =============================================================================== */

  mrfiTxActive = 0;
  return( returnValue );
}
示例#9
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();
}