// Contributed by Cor void Radio_WakeUp() { TI_CC_CSn_PxOUT &= ~TI_CC_CSn_PIN; // /CS low while (TI_CC_SPI_USCIB0_PxIN & TI_CC_SPI_USCIB0_SOMI); //wait till P1.6 goes low TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; // /CS high // write some test setting back; TI_CC_SPIWriteReg(TI_CCxxx0_TEST2, 0x88); // Various test settings. TI_CC_SPIWriteReg(TI_CCxxx0_TEST1, 0x31); // Various test settings. TI_CC_SPIWriteReg(TI_CCxxx0_TEST0, 0x0B); // Various test settings. TI_CC_SPIStrobe(TI_CCxxx0_SFRX); // flush the receive FIFO of any residual data TI_CC_SPIStrobe(TI_CCxxx0_SIDLE); // set IDLE }
void RF_init() { TI_CC_SPISetup(); // Initialize SPI port TI_CC_PowerupResetCCxxxx(); // Reset CCxxxx writeRFSettings(); // Write RF settings to config reg TI_CC_SPIWriteBurstReg(TI_CCxxx0_PATABLE, paTable, paTableLen);//Write PATABLE //TI_CC_SPIStrobe(TI_CCxxx0_SIDLE); // set IDLE TI_CC_SPIWriteReg (TI_CCxxx0_PATABLE,paTable[0]); // init at max powerlevel // Configure ports -- switch inputs, LEDs, GDO0 to RX packet info from CCxxxx TI_CC_SW_PxREN |= TI_CC_SW1; // Enable Pull up resistor TI_CC_SW_PxOUT |= TI_CC_SW1; // Enable pull up resistor TI_CC_SW_PxIES |= TI_CC_SW1; // Int on falling edge TI_CC_SW_PxIFG &= ~(TI_CC_SW1); // Clr flags TI_CC_SW_PxIE |= TI_CC_SW1; // Activate interrupt enables TI_CC_GDO0_PxIES |= TI_CC_GDO0_PIN; // Int on falling edge (end of pkt) TI_CC_GDO0_PxIFG &= ~TI_CC_GDO0_PIN; // Clear flag TI_CC_GDO0_PxIE |= TI_CC_GDO0_PIN; // Enable int on end of packet TI_CC_SPIStrobe(TI_CCxxx0_SRX); // Initialize CCxxxx in RX mode. // When a pkt is received, it will // signal on GDO0 and wake CPU }
void RF_change_Power(char power) { if (power<paTableLen) {TI_CC_SPIStrobe(TI_CCxxx0_SIDLE); // set IDLE TI_CC_SPIWriteReg (TI_CCxxx0_PATABLE,paTable[power]); //Out_Payload.Status.power=TI_CC_SPIReadReg(TI_CCxxx0_PATABLE); } }
void writeRFSettings(void) { // Write register settings TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG2, 0x0B); // GDO2 output pin config. TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG0, 0x06); // GDO0 output pin config. TI_CC_SPIWriteReg(TI_CCxxx0_PKTLEN, 0xFF); // Packet length. //TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL1, 0x05); // Packet automation control. TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL0, 0x05); // Packet automation control. TI_CC_SPIWriteReg(TI_CCxxx0_ADDR, 0x01); // Device address. //TI_CC_SPIWriteReg(TI_CCxxx0_CHANNR, 0x00); // Channel number. TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL1, 0x06); // Freq synthesizer control. //TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL0, 0x00); // Freq synthesizer control. TI_CC_SPIWriteReg(TI_CCxxx0_FREQ2, 0x21); // Freq control word, high byte TI_CC_SPIWriteReg(TI_CCxxx0_FREQ1, 0x62); // Freq control word, mid byte. TI_CC_SPIWriteReg(TI_CCxxx0_FREQ0, 0x76); // Freq control word, low byte. TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4, 0xF5); // Modem configuration. TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG3, 0x83); // Modem configuration. TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2, 0x13); // Modem configuration. //TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG1, 0x62); // Modem configuration. //TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG0, 0x76); // Modem configuration. TI_CC_SPIWriteReg(TI_CCxxx0_DEVIATN, 0x15); // Modem dev (when FSK mod en) TI_CC_SPIWriteReg(TI_CCxxx0_MCSM1 , 0x3F); //MainRadio Cntrl State Machine // Ez fontos TI_CC_SPIWriteReg(TI_CCxxx0_MCSM0 , 0x18); //MainRadio Cntrl State Machine TI_CC_SPIWriteReg(TI_CCxxx0_FOCCFG, 0x16); // Freq Offset Compens. Config //TI_CC_SPIWriteReg(TI_CCxxx0_BSCFG, 0x1C); // Bit synchronization config. //TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL2, 0xC7); // AGC control. //TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL1, 0x00); // AGC control. //TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL0, 0xB2); // AGC control. //TI_CC_SPIWriteReg(TI_CCxxx0_FREND1, 0xB6); // Front end RX configuration. //TI_CC_SPIWriteReg(TI_CCxxx0_FREND0, 0x10); // Front end RX configuration. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL3, 0xE9); // Frequency synthesizer cal. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL2, 0x2A); // Frequency synthesizer cal. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL1, 0x00); // Frequency synthesizer cal. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL0, 0x1F); // Frequency synthesizer cal. //TI_CC_SPIWriteReg(TI_CCxxx0_FSTEST, 0x59); // Frequency synthesizer cal. TI_CC_SPIWriteReg(TI_CCxxx0_TEST2, 0x81); // Various test settings. TI_CC_SPIWriteReg(TI_CCxxx0_TEST1, 0x35); // Various test settings. TI_CC_SPIWriteReg(TI_CCxxx0_TEST0, 0x09); // Various test settings. }
void WriteRFSettings(void) { // Configuro els registres del Transceiver, rutina copiada de la nota d'aplicació de // texas instruments TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG2, SMARTRF_SETTING_IOCFG2); // GDO2 output pin config. SMARTRF_SETTING_IOCFG2 = 0x29 // GDO2is CHIP_RDYn TI_CC_SPIWriteReg(TI_CCxxx0_PKTLEN, SMARTRF_SETTING_PKTLEN); // Packet length. SMARTRF_SETTING_PKTLEN = 0xFF // Indicates the packet length when fixed packet length is enabled. // If variable length packets are used, this value indicates the maximum length packets allowed. TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL1, SMARTRF_SETTING_PKTCTRL1); // Packet automation control. SMARTRF_SETTING_PKTCTRL1 = 0x07 // // Bit Field Name Reset R/W Description // // 7:5 PQT[2:0] 0 (000) R/W P reamble quality estimator threshold. The preamble quality estimator increases an internal counter by one each time a bit is // received that is different from the previous bit, and decreases the counter by 8 each time a bit is received that is the same as the last bit. // // A threshold of 4-PQT for this counter is used to gate sync word detection. When PQT=0 a sync word is always accepted. // // 4 Reserved 0 R0 // // 3 CRC_AUTOFLUSH 0 R/W Enable automatic flush of RX FIFO when CRC is not OK. This requires that only one packet is in the RX FIFO and that packet length is limited to the RX FIFO size. // // PKTCTRL0.CC2400_EN must be 0 (default) for the CRC autoflush function to work correctly. // // 2 APPEND_STATUS 1 R/W When enabled, two status bytes will be appended to the payload of the packet. The status bytes contain RSSI and LQI values, as well as the CRC OK flag. // // 1:0 ADR_CHK[1:0] 0 (00) R/W Controls address check configuration of received packages. // Setting Address check configuration // 0 (00) No address check // 1 (01) Address check, no broadcast // 2 (10) Address check and 0 (0x00) broadcast // 3 (11) Address check and 0 (0x00) and 255 (0xFF) broadcast TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL0, SMARTRF_SETTING_PKTCTRL0); // Packet automation control. SMARTRF_SETTING_PKTCTRL0 = 0x05 // // Bit Field Name Reset R/W Description // // 7 Reserved R0 // // 6 WHITE_DATA 1 R/W Turn data whitening on / off // 0: Whitening off // 1: Whitening on // // Data whitening can only be used when PKTCTRL0.CC2400_EN=0 (default). // // 5:4 PKT_FORMAT[1:0] 0 (00) R/W Format of RX and TX data // Setting Packet format // 0 (00) Normal mode, use FIFOs for RX and TX // 1 (01) Synchronous serial mode, used for backwards compatibility. Data in on GDO0 // 2 (10) Random TX mode; sends random data using PN9 generator. Used for test. Works as normal mode, setting 0 (00), in RX. // 3 (11) Asynchronous serial mode. Data in on GDO0 and data out on either of the GDO0 pins // // 3 CC2400_EN 0 R/W Enable CC2400 support. Use same CRC implementation as CC2400. // // PKTCTRL1.CRC_AUTOFLUSH must be 0 if PKTCTRL0.CC2400_EN=1. // // PKTCTRL0.WHITE_DATA must be 0 if PKTCTRL0.CC2400_EN=1. // // 2 CRC_EN 1 R/W 1: CRC calculation in TX and CRC check in RX enabled // 0: CRC disabled for TX and RX // // 1:0 LENGTH_CONFIG[1:0] 1 (01) R/W Configure the packet length // Setting Packet length configuration // 0 (00) Fixed packet length mode. Length configured in PKTLEN register // 1 (01) Variable packet length mode. Packet length configured by the first byte after sync word // 2 (10) Infinite packet length mode // 3 (11) Reserved TI_CC_SPIWriteReg(TI_CCxxx0_ADDR, SMARTRF_SETTING_ADDR); // Device address. SMARTRF_SETTING_ADDR = 0x00 // // Bit Field Name Reset R/W Description // // 7:0 DEVICE_ADDR[7:0] 0 (0x00) R/W Address used for packet filtration. Optional broadcast addresses are 0 (0x00) and 255 (0xFF). // TI_CC_SPIWriteReg(TI_CCxxx0_CHANNR, SMARTRF_SETTING_CHANNR); // Channel number. TI_CC_SPIWriteReg(TI_CCxxx0_CHANNR, Canal); // El numero de canal // // Bit Field Name Reset R/W Description // // 7:0 CHAN[7:0] 0 (0x00) R/W The 8-bit unsigned channel number, which is multiplied by the channel spacing setting and added to the base frequency. TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL1, SMARTRF_SETTING_FSCTRL1); // Freq synthesizer control. SMARTRF_SETTING_FSCTRL1 = 0x0A // // Bit Field Name Reset R/W Description // // 7:5 Reserved R0 // 4:0 FREQ_IF[4:0] 15 (0x0F) R/W The desired IF frequency to employ in RX. Subtracted from FS base frequency in RX and controls the digital complex mixer in the demodulator. // f(if) = (F(xosc)/2^10)*Freq_if // The default value gives an IF frequency of 381 kHz, assuming a 26.0 MHz crystal. // TI_CC_SPIWriteReg(TI_CCxxx0_FSCTRL0, SMARTRF_SETTING_FSCTRL0); // Freq synthesizer control. SMARTRF_SETTING_FSCTRL0 = 0x00 // // Bit Field Name Reset R/W Description // // 7:0 FREQOFF[7:0] 0 (0x00) R/W Frequency offset added to the base frequency before being used by the FS. (2’s complement). // Resolution is FXTAL/214 (1.59 - 1.65 kHz); range is ±202 kHz to ±210 kHz, dependent of XTAL frequency. TI_CC_SPIWriteReg(TI_CCxxx0_FREQ2, SMARTRF_SETTING_FREQ2); // Freq control word, high byte SMARTRF_SETTING_FREQ2 = 0x5A // // Bit Field Name Reset R/W Description // // 7:6 FREQ[23:22] 1 (01) R FREQ[23:22] is always binary 01 (the FREQ2 register is in the range 85 to 95 with 26-27 MHz crystal) // // 5:0 FREQ[21:16] 30 (0x1E) R/W FREQ[23:0] is the base frequency for the frequency synthesiser in increments of Fxosc/2^16. // Fcarrier = Fxosc/2^16*Freq[23:0] TI_CC_SPIWriteReg(TI_CCxxx0_FREQ1, SMARTRF_SETTING_FREQ1); // Freq control word, mid byte. SMARTRF_SETTING_FREQ1 = 0x1C // // Bit Field Name Reset R/W Description // // 7:0 FREQ[15:8] 196 (0xC4) R/W Ref. FREQ2 register TI_CC_SPIWriteReg(TI_CCxxx0_FREQ0, SMARTRF_SETTING_FREQ0); // Freq control word, low byte. SMARTRF_SETTING_FREQ0 = 0x71 // // Bit Field Name Reset R/W Description // // 7:0 FREQ[7:0] 236 (0xEC) R/W Ref. FREQ2 register TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4, SMARTRF_SETTING_MDMCFG4); // Modem configuration. SMARTRF_SETTING_MDMCFG4 = 0x2D // // Bit Field Name Reset R/W Description // // 7:6 CHANBW_E[1:0] 2 (10) R/W // 5:4 CHANBW_M[1:0] 0 (00) R/W Sets the decimation ratio for the delta-sigma ADC input stream and thus the channel bandwidth. // BWchannel= (Fxosc)/(8(4+CHANBW_M)2^(CHANBW E)) // The default values give 203 kHz channel filter bandwidth, assuming a 26.0 MHz crystal. // 3:0 DRATE_E[3:0] 12 (1100) R/W The exponent of the user specified symbol rate TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG3, SMARTRF_SETTING_MDMCFG3); // Modem configuration. SMARTRF_SETTING_MDMCFG3 = 0x2F // // Bit Field Name Reset R/W Description // // 7:0 DRATE_M[7:0] 34 (0x22) R/W The mantissa of the user specified symbol rate. The symbol rate is configured using an unsigned, floating-point number // with 9-bit mantissa and 4-bit exponent. The 9th bit is a hidden ‘1’. The resulting data rate is: // Rdata = ((256+Drate_M)2^(Drate_E))/(2^(28))*Fxosc // The default values give a data rate of 115.051 kBaud (closest setting to 115.2 kBaud), assuming a 26.0 MHz crystal. TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2, SMARTRF_SETTING_MDMCFG2); // Modem configuration. SMARTRF_SETTING_MDMCFG2 = 0x72 // // Bit Field Name Reset R/W Description // // 7 DEM_DCFILT_OFF 0 R/W Disable digital DC blocking filter before demodulator. // 0 = Enable (better sensitivity) // 1 = Disable (current optimized). Only for data rates < 250 kBaud // The recommended IF frequency changes when the DC blocking is disabled. Please use SmartRF Studio [5] to calculate correct register setting. // // 6:4 MOD_FORMAT[2:0] 0 (000) R/W The modulation format of the radio signal // Setting Modulation format // 0 (000) 2-FSK // 1 (001) GFSK // 2 (010) - // 3 (011) OOK // 4 (100) - // 5 (101) - // 6 (110) - // 7 (111) MSK // // 3 MANCHESTER_EN 0 R/W Enables Manchester encoding/decoding. // 0 = Disable // 1 = Enable // // 2:0 SYNC_MODE[2:0] 2 (010) R/W Combined sync-word qualifier mode. // The values 0 (000) and 4 (100) disables preamble and sync word transmission in TX and preamble and sync word detection in RX. // The values 1 (001), 2 (010), 5 (101) and 6 (110) enables 16-bit sync word transmission in TX and 16- bits sync word detection in RX. // Only 15 of 16 bits need to match in RX when using setting 1 (001) or 5 (101). // // The values 3 (011) and 7 (111) enables repeated sync word transmission in TX and 32-bits sync word detection in RX (only 30 of 32 bits need to match). // Setting Sync-word qualifier mode // 0 (000) No preamble/sync // 1 (001) 15/16 sync word bits detected // 2 (010) 16/16 sync word bits detected // 3 (011) 30/32 sync word bits detected // 4 (100) No preamble/sync, carrier-sense above threshold // 5 (101) 15/16 + carrier-sense above threshold // 6 (110) 16/16 + carrier-sense above threshold // 7 (111) 30/32 + carrier-sense above threshold TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG1, SMARTRF_SETTING_MDMCFG1); // Modem configuration. SMARTRF_SETTING_MDMCFG1 = 0x22 // // Bit Field Name Reset R/W Description // // 7 FEC_EN 0 R/W Enable Forward Error Correction (FEC) with interleaving for packet payload // 0 = Disable // 1 = Enable (Only supported for fixed packet length mode, i.e. PKTCTRL0.LENGTH_CONFIG=0) // // 6:4 NUM_PREAMBLE[2:0] 2 (010) R/W Sets the minimum number of preamble bytes to be transmitted // Setting Number of preamble bytes // 0 (000) 2 // 1 (001) 3 // 2 (010) 4 // 3 (011) 6 // 4 (100) 8 // 5 (101) 12 // 6 (110) 16 // 7 (111) 24 // // 3:2 Reserved R0 // 1:0 CHANSPC_E[1:0] 2 (10) R/W 2 bit exponent of channel spacing TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG0, SMARTRF_SETTING_MDMCFG0); // Modem configuration. TI_CC_SPIWriteReg(TI_CCxxx0_DEVIATN, SMARTRF_SETTING_DEVIATN); // Modem dev (when FSK mod en) TI_CC_SPIWriteReg(TI_CCxxx0_MCSM0 , SMARTRF_SETTING_MCSM0); //MainRadio Cntrl State Machine TI_CC_SPIWriteReg(TI_CCxxx0_FOCCFG, SMARTRF_SETTING_FOCCFG); // Freq Offset Compens. Config TI_CC_SPIWriteReg(TI_CCxxx0_BSCFG, SMARTRF_SETTING_BSCFG); // Bit synchronization config. TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL2, SMARTRF_SETTING_AGCCTRL2); // AGC control. TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL1, SMARTRF_SETTING_AGCCTRL1); // AGC control. TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL0, SMARTRF_SETTING_AGCCTRL0); // AGC control. TI_CC_SPIWriteReg(TI_CCxxx0_FREND1, SMARTRF_SETTING_FREND1); // Front end RX configuration. TI_CC_SPIWriteReg(TI_CCxxx0_FREND0, SMARTRF_SETTING_FREND0); // Front end RX configuration. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL3, SMARTRF_SETTING_FSCAL3); // Frequency synthesizer cal. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL2, SMARTRF_SETTING_FSCAL2); // Frequency synthesizer cal. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL1, SMARTRF_SETTING_FSCAL1); // Frequency synthesizer cal. TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL0, SMARTRF_SETTING_FSCAL0); // Frequency synthesizer cal. TI_CC_SPIWriteReg(TI_CCxxx0_FSTEST, SMARTRF_SETTING_FSTEST); // Frequency synthesizer cal. TI_CC_SPIWriteReg(TI_CCxxx0_TEST2, SMARTRF_SETTING_TEST2); // Various test settings. TI_CC_SPIWriteReg(TI_CCxxx0_TEST1, SMARTRF_SETTING_TEST1); // Various test settings. TI_CC_SPIWriteReg(TI_CCxxx0_TEST0, SMARTRF_SETTING_TEST0); // Various test settings. // Registres que toco manualment TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG2, 0x0B); // GDO2 output pin config. TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG0, 0x06); // GDO0 output pin config. TI_CC_SPIWriteReg(TI_CCxxx0_PKTLEN, 0xFF); // Packet length. // TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL1, 0x06); // 0x05); // Packet automation control. // Addres Broadcast 0x00, 0xFF enable, APPEND_STATUS // V62 TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL1, 0xE); // Packet automation control. Activo el CRC autoflusss // End V62 TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL0, 0x05);// Packet automation control. // Variable Pk length , CRC ON TI_CC_SPIWriteReg(TI_CCxxx0_ADDR, NET_ADDRESS_Device); // Device address. TI_CC_SPIWriteReg(TI_CCxxx0_MCSM1 , 0x3e); //MainRadio Cntrl State Machine // TX_OFF--> Seguim en TX TI_CC_SPIWriteReg(TI_CCxxx0_MCSM0 , 0x18); //MainRadio Cntrl State Machine // OOOOJJJJOOOO PODEM REDUIR EL CONSUM TI_CC_SPIWriteReg(TI_CCxxx0_SYNC1 , NET_ADDRESS_Sinc);// Defineixo la adreça de xarxa TI_CC_SPIWriteReg(TI_CCxxx0_SYNC0 , NET_ADDRESS_Sinc); }
//Perform the scan, returns the amount of bytes stored in the rssiArray unsigned int scanFreqBands(void) { //Amount of bytes stored in the rssiArray unsigned int rssiLen=0; BYTE i; //RSSI value as reported by the CC device UINT8 rssi_dec; //RSSI value translated to dBm INT16 rssi_dBm; //Variable to store the current value of the TEST0 register BYTE currentTest0; //Variable to store the FREQ register value for the current frequency UINT32 freqRegs; //Temp variables for the FREQ register calculation BYTE tempFreq2,tempFreq1,tempFreq0; //Variables to store the current frequency to be scanned UINT16 currentFreqMhz, currentFreqKhz; //Controls if we should perform a calibration before starting RX //in the current frequency BOOL calNeeded; //Copy of the pointer to the RSSI array BYTE * rssiPtr=rssiTable; //Initialize the value of the frequency counters currentFreqMhz = scanParameters.startFreqMhz; currentFreqKhz = scanParameters.startFreqKhz; //Initialize freqRegs to the value for startFreq freqRegs=freqRegsBase; //Get reset value of TEST0 currentTest0=TI_CC_SPIReadReg(TI_CCxxx0_TEST0); //For the start frequency a calibration is always needed calNeeded=TRUE; while (currentFreqMhz<scanParameters.stopFreqMhz || currentFreqKhz<scanParameters.stopFreqKhz) { //Find out if we need to change the TEST0 register for(i=0; i<NUM_TEST0_RANGES; i++){ //Find the TEST0 range the current frequency belongs to if(currentFreqMhz>=test0RangeLimits[i] && currentFreqMhz<=test0RangeLimits[i+1]){ if(currentTest0!=test0Values[i]){ TI_CC_SPIWriteReg(TI_CCxxx0_TEST0, test0Values[i]); currentTest0=TI_CC_SPIReadReg(TI_CCxxx0_TEST0); //Also change the value of the FSCAL2 register to enable the VCO calibration stage TI_CC_SPIWriteReg(TI_CCxxx0_FSCAL2, 0x2A); calNeeded=TRUE; } break; } } //Write the frequency registers FREQ2, FREQ1 and FREQ0 tempFreq0=(BYTE)freqRegs; tempFreq1=(BYTE)(freqRegs>>8); tempFreq2=(BYTE)(freqRegs>>16); TI_CC_SPIWriteReg(TI_CCxxx0_FREQ2, tempFreq2); TI_CC_SPIWriteReg(TI_CCxxx0_FREQ1, tempFreq1); TI_CC_SPIWriteReg(TI_CCxxx0_FREQ0, tempFreq0); //Calibrate if needed if(calNeeded){ TI_CC_SPIStrobe(TI_CCxxx0_SCAL); calNeeded=FALSE; } //Enter RX mode by issuing an SRX strobe command TI_CC_SPIStrobe(TI_CCxxx0_SRX); static BYTE state; //Wait for radio to enter RX state by checking the status byte do { //state = TI_CC_GetTxStatus() & TI_CCxxx0_STATUS_STATE_BM; state=TI_CC_SPIReadStatus(TI_CCxxx0_MARCSTATE); state&=TI_CCxxx0_MARCSTATE_MASK; //Flush the FIFO RX buffer in case of overflow if(state==TI_CCxxx0_MARCSTATE_SM_RXFIFO_OVERFLOW) TI_CC_SPIStrobe(TI_CCxxx0_SFRX); } while (state != TI_CCxxx0_MARCSTATE_SM_RX); //Wait for RSSI to be valid usleep(scanParameters.rssiWait); //Enter IDLE state by issuing an SIDLE strobe command TI_CC_SPIStrobe(TI_CCxxx0_SIDLE); //Read RSSI value and store it in rssi_dec rssi_dec = TI_CC_SPIReadStatus(TI_CCxxx0_RSSI); //Store the value in the rssi array *rssiPtr++=rssi_dec; //Update rssiLen rssiLen+=sizeof(BYTE); //Flush the FIFO buffer, just in case TI_CC_SPIStrobe(TI_CCxxx0_SFRX); //At the end of the loop, update the frequency counters //TODO: Consider using Horner division code currentFreqKhz += scanParameters.freqResolution; if (currentFreqKhz >= 1000) { currentFreqMhz += currentFreqKhz/1000; currentFreqKhz %= 1000; //According to DN508, a frequency calibration //covers all frequencies less than 1Mhz apart //from the one we calibrated for calNeeded=TRUE; } //Update the value of the FREQ2:FREQ1:FREQ0 register value freqRegs+=freqRegsStep; } return rssiLen; }
//This function configures the SPI interface //to the CC1101, resets the device and //sets the scanning parameters //GETS: Pointer to the scan parameters //and the pointer to the structure //where the Rssi values will be stored //RETURNS: NULL if something went wrong //or pointer to the SCAN_CONFIG structure //with the parameters actually used by the function SCAN_CONFIG * configScanner(SCAN_CONFIG * pconfigParameters, BYTE * rssiArray) { BYTE reg; //Store the array pointer, if it's NULL report failure if(rssiArray==NULL) return NULL; rssiTable = rssiArray; //Configure the SPI interface TI_CC_SPISetup(); //Reset the CC1101 TI_CC_PowerupResetCCxxxx(); //If pconfigParameters is NULL, use defaults if(pconfigParameters==NULL){ pconfigParameters=&scanParameters; scanParameters.startFreqMhz=MIN_FREQ; scanParameters.startFreqKhz=0; scanParameters.stopFreqMhz=MAX_FREQ; //scanParameters.stopFreqMhz=820; scanParameters.stopFreqKhz=0; scanParameters.freqResolution=DEFAULT_RESOLUTION; scanParameters.modFormat=TI_CCxxx0_MDMCFG2_MODFORMAT_ASK; scanParameters.rssiWait=AVG_WAIT_WITH_AGC; scanParameters.activateAGC=TRUE; } /**Start parsing parameters**/ //Parsing startFreq if (pconfigParameters->startFreqMhz < MIN_FREQ || pconfigParameters->startFreqMhz > MAX_FREQ) { //Use default value: MIN_FREQ scanParameters.startFreqMhz = MIN_FREQ; scanParameters.startFreqKhz = 0; } else { scanParameters.startFreqMhz = pconfigParameters->startFreqMhz; if (pconfigParameters->startFreqKhz>= 1000 || pconfigParameters->startFreqMhz==MAX_FREQ) { //Use default value: 0 scanParameters.startFreqKhz = 0; } else{ scanParameters.startFreqKhz = pconfigParameters->startFreqKhz; } } //Parsing stopFreq if (pconfigParameters->stopFreqMhz < MIN_FREQ || pconfigParameters->stopFreqMhz > MAX_FREQ) { //Use default value: MAX_FREQ scanParameters.stopFreqMhz = MAX_FREQ; scanParameters.stopFreqKhz = 0; } else { scanParameters.stopFreqMhz = pconfigParameters->stopFreqMhz; if (pconfigParameters->stopFreqKhz>= 1000 || pconfigParameters->stopFreqMhz==MAX_FREQ) { //Use default value: 0 scanParameters.stopFreqKhz = 0; } else{ scanParameters.stopFreqKhz = pconfigParameters->stopFreqKhz; } } //Check if the range limits make sense if (scanParameters.startFreqMhz > scanParameters.stopFreqMhz) return NULL; if (scanParameters.startFreqMhz == scanParameters.stopFreqMhz && scanParameters.startFreqKhz > scanParameters.stopFreqKhz) return NULL; if (scanParameters.startFreqMhz == MAX_FREQ && scanParameters.startFreqKhz > 0) return NULL; //Parsing filterBandwidth if(pconfigParameters->freqResolution<filterBandwidthList[0][0] || pconfigParameters->freqResolution>filterBandwidthList[3][3]) scanParameters.freqResolution=DEFAULT_RESOLUTION; //Find the valid filter value closest to the one requested UINT16 diff, tempDiff; BYTE i, j, row, column; for (i = 0; i < sizeof(filterBandwidthList); i++) { for (j = 0; j < sizeof(*filterBandwidthList); j++) { if(filterBandwidthList[i][j] > pconfigParameters->freqResolution) tempDiff=filterBandwidthList[i][j] - pconfigParameters->freqResolution; else tempDiff=pconfigParameters->freqResolution - filterBandwidthList[i][j]; if (i == 0 && j==0) diff = tempDiff; if (tempDiff <= diff) { diff = tempDiff; row = i; column = j; } if (diff == 0) break; } if (diff == 0) break; } scanParameters.freqResolution = filterBandwidthList[row][column]; //Set the channel filter bandwidth reg = TI_CC_SPIReadReg(TI_CCxxx0_MDMCFG4); reg &= ~(TI_CCxxx0_MDMCFG4_CHANBW_E + TI_CCxxx0_MDMCFG4_CHANBW_M); reg |= (chanBwE[row][column] << 4) + (chanBwM[row][column] << 6); TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4, reg); //Initialize the variables related to the frequency registers REG2:REG1:REG0 //Formula: f_carrier=(f_xosc/2^16)*FREQ[23:0] //TODO: To optimize, consider using Horner division code from SLAA329 //Link: http://www.ti.com/mcu/docs/litabsmultiplefilelist.tsp?sectionId=96&tabId=1502&literatureNumber=slaa329&docCategoryId=1&familyId=4 freqRegsBase=(((UINT32)scanParameters.startFreqMhz)<<16)/fXoscMhz; freqRegsBase+=(((UINT32)scanParameters.startFreqKhz)<<16)/(fXoscMhz*1000); freqRegsStep=(((UINT32)scanParameters.freqResolution)<<16)/(fXoscMhz*1000); //Set the channel spacing // reg = TI_CC_SPIReadReg(TI_CCxxx0_MDMCFG1); // reg &= ~TI_CCxxx0_MDMCFG1_CHANSPC_E_MASK; // reg |= chanSpcE[row][column]; // TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG1, reg); // TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG0, chanSpcM[row][column]); //Set the number of channels per Mhz //Parsing the modulation format //If it's a wrong or invalid value, use the first valid modulation format if (pconfigParameters->modFormat < sizeof(validModFormats) && validModFormats[pconfigParameters->modFormat]) scanParameters.modFormat = pconfigParameters->modFormat; else { for (i = 0; i < sizeof(validModFormats) && !validModFormats[i]; i++) ; scanParameters.modFormat = i; } //Set the modulation for the current scan reg = TI_CC_SPIReadReg(TI_CCxxx0_MDMCFG2); reg &= ~TI_CCxxx0_MDMCFG2_MODFORMAT_MASK; reg |= modFormatMDMCFG2[scanParameters.modFormat]; TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2, reg); //Parse AGC options //If the AGC is disabled, we manually set //all the gain stages, otherwise we ignore //those fields if(pconfigParameters->activateAGC){ scanParameters.activateAGC = TRUE; //Parse rssiWait if(pconfigParameters->rssiWait<MIN_WAIT_WITH_AGC || pconfigParameters->rssiWait>MAX_WAIT_WITH_AGC){ //Use default: AVG_WAIT_WITHOUT_AGC scanParameters.rssiWait=AVG_WAIT_WITH_AGC; } else{ scanParameters.rssiWait=pconfigParameters->rssiWait; } } else{ scanParameters.activateAGC = FALSE; //Freeze the AGC reg = TI_CC_SPIReadReg(TI_CCxxx0_AGCCTRL0); reg &= ~TI_CCxxx0_AGCCTRL0_AGCFREEZE_MASK; reg |= TI_CCxxx0_AGCCTRL0_AGCFREEZE_ALL; TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL0, reg); //Parse static gain options if (pconfigParameters->agcLnaGain < LNA_MIN_GAIN && pconfigParameters->agcLnaGain > LNA_MAX_GAIN) scanParameters.agcLnaGain = pconfigParameters->agcLnaGain; else scanParameters.agcLnaGain = LNA_MAX_GAIN; if (pconfigParameters->agcLna2Gain > LNA2_MIN_GAIN && pconfigParameters->agcLna2Gain < LNA2_MAX_GAIN) scanParameters.agcLna2Gain = pconfigParameters->agcLna2Gain; else scanParameters.agcLna2Gain = LNA2_MAX_GAIN; if (pconfigParameters->agcDvgaGain > DVGA_MIN_GAIN && pconfigParameters->agcDvgaGain < DVGA_MAX_GAIN) scanParameters.agcDvgaGain = pconfigParameters->agcDvgaGain; else scanParameters.agcDvgaGain = DVGA_MAX_GAIN; //Set static gain value reg = scanParameters.agcDvgaGain | (scanParameters.agcLna2Gain << 3) | (scanParameters.agcLna2Gain << 6); TI_CC_SPIWriteReg(TI_CCxxx0_AGCTEST, reg); //Parse rssiWait if(pconfigParameters->rssiWait<MIN_WAIT_WITHOUT_AGC || pconfigParameters->rssiWait>MAX_WAIT_WITHOUT_AGC){ //Use default: AVG_WAIT_WITH_AGC scanParameters.rssiWait=AVG_WAIT_WITH_AGC; } else{ scanParameters.rssiWait=pconfigParameters->rssiWait; } } /**Finished parsing parameters**/ //Everything OK, return pointer to the parameter structure return &scanParameters; }