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