void cc1101_init(void) { SPI_CSN_L(); Mrfi_DelayUsec(10); SPI_CSN_H(); Mrfi_DelayUsec(40); SPI_CSN_L(); while (SPI_MISO_READ()); spi_writebyte(SRES); while (SPI_MISO_READ()); SPI_CSN_H(); RfWriteRfSettings(); Mrfi_SpiWriteReg(TI_CCxxx0_IOCFG0, 0x06); { uint8_t tmp = 0; tmp = Mrfi_SpiReadReg(TI_CCxxx0_IOCFG0); if(tmp != 0x06) while(1); } Mrfi_SpiCmdStrobe(SIDLE); Mrfi_SpiCmdStrobe(SRX); P2IES |= GPIO0; // Ñ¡ÔñÉÏÉý/ϽµÑØ P2REN |= GPIO0; // push-up enable P2IFG &=~GPIO0; P2IE |= GPIO0; }
/************************************************************************************************** * @fn MRFI_DelayMs * * @brief Delay the specified number of milliseconds. * * @param milliseconds - delay time * * @return none ************************************************************************************************** */ void MRFI_DelayMs(uint16_t milliseconds) { while(milliseconds) { Mrfi_DelayUsec( 1000 ); milliseconds--; } }
/************************************************************************************************** * @fn MRFI_DelayMs * * @brief Delay the specified number of milliseconds. * * @param milliseconds - delay time * * @return none ************************************************************************************************** */ void MRFI_DelayMs(uint16_t milliseconds) { while (milliseconds) { Mrfi_DelayUsec( APP_USEC_VALUE ); milliseconds--; } }
/************************************************************************************************** * @fn Mrfi_RandomBackoffDelay * * @brief Waits for random amount of time before returning. * The range is: 1*250 to 16*250 us. * * @param none * * @return none ************************************************************************************************** */ static void Mrfi_RandomBackoffDelay(void) { uint8_t backoffs; uint8_t i; /* calculate random value for backoffs - 1 to 16 */ backoffs = (MRFI_RandomByte() & 0x0F) + 1; /* delay for randomly computed number of backoff periods */ for (i=0; i<backoffs; i++) { Mrfi_DelayUsec( MRFI_BACKOFF_PERIOD_USECS ); } }
/************************************************************************************************** * @fn Mrfi_TurnOnRadioPower * * @brief Power ON the radio chip. * * @param none * * @return none ************************************************************************************************** */ static void Mrfi_TurnOnRadioPower(void) { /* put radio chip into reset */ MRFI_DRIVE_RESETN_PIN_LOW(); /* enable the voltage regulator */ MRFI_DRIVE_VREG_EN_PIN_HIGH(); /* wait for the chip to power up */ Mrfi_DelayUsec(MRFI_VREG_SETTLE_TIME_USECS); /* release from reset */ MRFI_DRIVE_RESETN_PIN_HIGH(); /* wait for the radio crystal oscillator to stabilize */ MRFI_SPI_SET_CHIP_SELECT_ON(); while (!MRFI_SPI_SO_IS_HIGH()); MRFI_SPI_SET_CHIP_SELECT_OFF(); }
/************************************************************************************************** * @fn MRFI_Rssi * * @brief Returns "live" RSSI value * * @param none * * @return RSSI value in units of dBm. ************************************************************************************************** */ int8_t MRFI_Rssi(void) { int8_t rssi; /* Radio must be in RX state to measure rssi. */ MRFI_ASSERT( mrfiRadioState == MRFI_RADIO_STATE_RX ); /* * Assuming that the Radio was just turned on, we must wait for * RSSI to be valid. */ Mrfi_DelayUsec( MRFI_RSSI_VALID_DELAY_US ); /* read RSSI value from hardware */ rssi = RSSIL; /* apply offset given in datasheet */ rssi = rssi + MRFI_RSSI_OFFSET; /* return RSSI value */ return( rssi ); }
/************************************************************************************************** * @fn mrfiRadioInterfaceCmdStrobe * * @brief Send command strobe to the radio. Returns status byte read during transfer * of strobe command. * * @param addr - address of register to strobe * * @return status byte of radio ************************************************************************************************** */ uint8_t mrfiRadioInterfaceCmdStrobe(uint8_t addr) { uint8_t statusByte, gdoState; mrfiRIFIState_t s; /* Check for invalid address. * 0xBD is for SNOP with MSP set to read the bytes available in RX FIFO. */ MRFI_RIF_ASSERT( (addr == 0xBD) || (addr >= RF_SRES) && (addr <= RF_SNOP)); /* Lock out access to Radio IF */ MRFI_RIF_ENTER_CRITICAL_SECTION(s); /* Clear the Status read flag */ MRFI_RADIO_STATUS_READ_CLEAR(); /* Wait for radio to be ready for next instruction */ MRFI_RADIO_INST_WRITE_WAIT(); if ((addr > RF_SRES) && (addr < RF_SNOP)) { /* buffer IOCFG2 state */ gdoState = MRFI_RADIO_REG_READ(IOCFG2); /* c-ready to GDO2 */ MRFI_RADIO_REG_WRITE(IOCFG2, 0x29); RF1AINSTRB = addr; /* chip at sleep mode */ if ((RF1AIN & 0x04) == 0x04) { if ( (addr == RF_SXOFF) || (addr == RF_SPWD) || (addr == RF_SWOR) ) { /* Do nothing */ } else { /* c-ready */ while ((RF1AIN & 0x04) == 0x04); /* Delay should be 760us */ Mrfi_DelayUsec(760); } } /* restore IOCFG2 setting */ MRFI_RADIO_REG_WRITE(IOCFG2, gdoState); } else { /* chip active mode */ RF1AINSTRB = addr; } /* Read status byte */ statusByte = RF1ASTAT0B; /* Allow access to Radio IF */ MRFI_RIF_EXIT_CRITICAL_SECTION(s); /* return the status byte */ return statusByte; }
/************************************************************************************************** * @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_TX_RESULT_SUCCESS - transmit succeeded * MRFI_TX_RESULT_FAILED - transmit failed because CCA failed ************************************************************************************************** */ uint8_t MRFI_Transmit(mrfiPacket_t * pPacket, uint8_t txType) { static uint8_t dsn = 0; uint8_t txResult = MRFI_TX_RESULT_SUCCESS; /* radio must be awake to transmit */ MRFI_ASSERT( mrfiRadioState != MRFI_RADIO_STATE_OFF ); /* ------------------------------------------------------------------ * Initialize hardware for transmit * ----------------------------------- */ /* turn off reciever */ Mrfi_RxModeOff(); /* clear 'transmit done' interrupt flag, this bit is tested to see when transmit completes */ RFIF &= ~IRQ_TXDONE; /* ------------------------------------------------------------------ * Populate the IEEE fields in frame * ------------------------------------ */ /* set the sequence number, also known as DSN (Data Sequence Number) */ pPacket->frame[MRFI_DSN_OFFSET] = dsn; /* increment the sequence number, value is retained (static variable) for use in next transmit */ dsn++; /* * Populate the FCF (Frame Control Field) with the following settings. * * bits description setting * -------------------------------------------------------------------------------------- * 0-2 Frame Type 001 - data frame * 3 Security Enabled 0 - security disabled * 4 Frame Pending 0 - no pending data * 5 Ack Request 0 - no Ack request * 6 PAN ID Compression 0 - no PAN ID compression * 7 Reserved 0 - reserved * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * 8-9 Reserved 00 - reserved * 10-11 Destination Addressing Mode 10 - PAN ID + 16-bit short address * 12-13 Frame Version 00 - IEEE Std 802.15.4-2003 * 14-15 Source Addressing Mode 10 - PAN ID + 16-bit short address * */ 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 * p; uint8_t i; /* flush FIFO of any previous transmit that did not go out */ RFST = ISFLUSHTX; /* 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. */ RFD = txBufLen + MRFI_RX_METRICS_SIZE; /* write packet bytes to FIFO */ for (i=0; i<txBufLen; i++) { p++; RFD = *p; } } /* ------------------------------------------------------------------ * Immediate transmit * --------------------- */ if (txType == MRFI_TX_TYPE_FORCED) { /* strobe transmit */ RFST = ISTXON; /* wait for transmit to complete */ while (!(RFIF & IRQ_TXDONE)); /* transmit is done */ } else { /* ------------------------------------------------------------------ * CCA transmit * --------------- */ MRFI_ASSERT( txType == MRFI_TX_TYPE_CCA ); { bspIState_t s; uint8_t txActive; uint8_t ccaRetries; /* set number of CCA retries */ ccaRetries = MRFI_CCA_RETRIES; /* =============================================================================== * CCA Algorithm Loop * ==================== */ for (;;) { /* Turn ON the receiver to perform CCA. Can not call Mrfi_RxModeOn(), * since that will enable the rx interrupt, which we do not want. */ RFST = ISRXON; /* * Wait for CCA to be valid. */ Mrfi_DelayUsec( MRFI_RSSI_VALID_DELAY_US ); /* * Initiate transmit with CCA. Command is strobed and then status is * immediately checked. If status shows transmit is active, this means * that CCA passed and the transmit has gone out. A critical section * guarantees timing status check happens immediately after strobe. */ BSP_ENTER_CRITICAL_SECTION(s); RFST = ISTXONCCA; txActive = RFSTATUS & TX_ACTIVE; BSP_EXIT_CRITICAL_SECTION(s); /* see transmit went out */ if (txActive) { /* ----------| CCA Passed |---------- */ /* wait for transmit to complete */ while (!(RFIF & IRQ_TXDONE)); /* transmit is done. break out of CCA algorithm loop */ break; } else { /* ----------| CCA Failed |---------- */ /* if no CCA retries are left, transmit failed so abort */ if (ccaRetries == 0) { /* set return value for failed transmit */ txResult = MRFI_TX_RESULT_FAILED; /* break out of CCA algorithm loop */ break; } /* decrement CCA retries before loop continues */ ccaRetries--; /* turn off reciever to conserve power during backoff */ Mrfi_RxModeOff(); /* delay for a random number of backoffs */ Mrfi_RandomBackoffDelay(); } } /* * --- 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 ); }