///////////////////////////////////// // initialize the radio interface // // stick with me, this goes on for a while // "may you live with interesting radios" // void init_radio(void) { init_leds(); // Add Bitlash functions specific to this radio // addBitlashFunction("degf", (bitlash_function) func_degf); addBitlashFunction("freq", (bitlash_function) func_setfreq); addBitlashFunction("rfget", (bitlash_function) func_rfget); addBitlashFunction("rfset", (bitlash_function) func_rfset); // Set output mode for outputs // TODO: Ensure SS is set to output if L01_CSN moves off SS! L01_PORT_DD |= (1<<L01_CE | 1<<L01_CSN | 1<<MOSI | 1<<L01_SCK); // Set MISO as an input L01_PORT_DD &= ~(1<<MISO); L01_PORT &= ~(1<<MISO); // turn off the internal pullup rf_end(); // Set -CSN high to deselect radio // Initialize SPI interface to the radio #if F_CPU == 8000000 // Enable SPI; be the Master; SPI mode 0; set up for 8/2 prescale for 4 MHz clock SPCR = 0<<SPIE | 1<<SPE | 1<<MSTR | 0<<CPOL | 0<<CPHA | 0<<SPR1 | 0<<SPR0; SPSR = 1<<SPI2X; // set 2x mode to make /4 into /2, so 4 MHz #elif F_CPU == 16000000 //// Enable SPI; be the Master; SPI mode 0; set up for 16/4 prescale for 4 MHz clock SPCR = 0<<SPIE | 1<<SPE | 1<<MSTR | 0<<CPOL | 0<<CPHA | 0<<SPR1 | 0<<SPR0; SPSR = 0<<SPI2X; // 16 MHz does _not_ need 2X mode #else unsupported F_CPU #endif // clear the status and data registers int junk = SPSR; junk = SPDR; // For RFM22: set CE low to enable radio (it's ~STBY) rf_enable(); // Got radio? for (;;) { rf_set_register(REG_OP_MODE_1, 1<<SWRES); // Reset the radio delay(1000); // Verify we have a radio, and it is the right type byte device_type = rf_read_register(REG_DEVICE_TYPE); byte device_version = rf_read_register(REG_VERSION_CODE); //printHex(device_type); speol(); //printHex(device_version); speol(); if ((device_type == DEVICE_TYPE_RXTX) && ((device_version == DEVICE_RFM22_VER_2) || (device_version == DEVICE_RFM22B))) { sp("RFM22 go!"); speol(); break; } else { sp("No radio."); speol(); } } // // Set up radio registers for transmit and receive // // Disable ENPOR and ENCHIPRDY interrupt sources // which are enabled by default rf_set_register(REG_INTERRUPT_ENABLE_2, 0); //set_ready_mode(); // Configure GPIO0-1 for tx-rx antenna switching rf_set_register(REG_GPIO0_CONFIG, (3<<GPIODRV | 1<<PUP | 0x12)); // GPIO0 is TX-State -> TX-Ant control rf_set_register(REG_GPIO1_CONFIG, (3<<GPIODRV | 1<<PUP | 0x15)); // GPIO1 is RX-State -> RX-Ant control // Configure GPIO2 for 10MHz system clock output rf_set_register(REG_MCLK_OUTPUT, MCLK_10MHZ); // Data Access Control setup // default for REG_DATA_ACCESS_CONTROL is fine: use the packet engine & crc checks // rf_set_register(REG_DATA_ACCESS_CONTROL, (1<<ENPACRX | 1<<ENPACTX | 1<<ENCRC | CRC_CRC16); // Frequency setup // // For North America, the default frequency band "fb" is 0x15 or 21 // so 21 * 20 MHz = 420 MHz offset + 480 Mhz base = 900 MHz band // // the default carrier frequency setting "fc" is 0xBB80 = 48000 // 48000/64000 = 0.75 * 2 * 10000 = 15000 // giving 900 + 15 = 915 MHz as default frequency // // TODO: ignoring frequency offset registers for the moment // // This is equivalent to the default setting: // // rf_set_register(REG_FREQUENCY_BAND_SELECT, (1<<SBSEL | 1<<HBSEL | 0x15)); // rf_set_register(REG_NOMINAL_CARRIER_FREQUENCY_HI, 0xbb); // rf_set_register(REG_NOMINAL_CARRIER_FREQUENCY_LO, 0x80); // or: rfset(0x75,0x75); rfset(0x76,0xbb); rfset(0x77,0x80) // // Decoding the example from the sample transmit/receive code for 434 MHz // band select low band with offset of 19 // 240 + 19*10 = 430 // // the remaining 4 mhz is to be found in the r76/77 carrier center freq // 0x6400 = 25600 // 25600/64000 = 0.4 // 0.4 * 10000 = 4000 // // This is the equivalent code to set 434 MHz using our defines: //rf_set_register(REG_FREQUENCY_BAND_SELECT, (1<<SBSEL | 0<<HBSEL | 0x13)); //rf_set_register(REG_NOMINAL_CARRIER_FREQUENCY_HI, 0x64); //rf_set_register(REG_NOMINAL_CARRIER_FREQUENCY_LO, 0x00); // or from the console: rfset(0x75,0x53); rfset(0x76,0x64); rfset(0x77,0x00) // TX Data Rate Setup // // this fragment from the example sets up for 4800 bps: // spi_write(0x6e, 0x27); // Tx data rate 1 // spi_write(0x6f, 0x52); // Tx data rate 0 // // for HBSEL=1, TX_DR = 1000 * txdr / 2^16 // for HBSEL=0, TX_DR = 1000 * txdr / 2^21 // // the default on this sample part is 0x0a3d => 39.9938 kbps, call it 40kbps // // inverting the formula: // value = (baud/1000)*(2^21)/1000 for baud < 30000 // value = (baud/1000)*(2^16)/1000 for baud >= 30000 // // these values are copied from the file doc/rfm-22-calculations.ods: // // baud divisor divisor, hex // 1200 2516 09D4 // 2400 5033 13A9 // 4800 10066 2752 // 9600 20132 4EA4 // // 40000 2621 0A3D <-- this is the default 6e/6f setting // 57600 3774 0EBE // 64000 4194 1062 // 96000 6291 1893 // 100000 6553 1999 // 128000 8388 20C4 // // Configure the data rate // #define TX_DATA_RATE 40000 //#define TX_DATA_RATE 100000 #if TX_DATA_RATE == 40000 // 40kbps is the factory setting; // take all the defaults but turn on FIFO and FSK rf_set_register(REG_MODULATION_MODE_CONTROL_2, (0<<TRCLK | MOD_FIFO<<DTMOD | 0<<ENINV | 0<<FD_8 | MOD_FSK<<MODTYP)); #elif TX_DATA_RATE == 100000 // Set data rate to 100000 bps // NOTE: don't forget to double check the TXDTRTSCALE bit in 0x70 if you set below 30k rf_set_register(REG_TX_DATA_RATE_HI, 0x19); rf_set_register(REG_TX_DATA_RATE_LO, 0x99); // Frequency Deviation setup // // value in increments of 625 Hz // default of 0x20 gives 0x20 = 32 * 625 Hz = 20 KHz // example uses 45k/625 = 72 // #define TX_DEVIATION 50000 #if TX_DEVIATION == 50000 // for 100kbps, with deviation at 50 kHz = 50000/625 = 80 = 0x050 // NOTE: high bit goes in REG_MODULATION_CONTROL_2 as FD_8 rf_set_register(REG_FREQUENCY_DEVIATION, 0x50); // Set up for FIFO io and FSK modulation // NOTE: high bit of deviation is here! rf_set_register(REG_MODULATION_MODE_CONTROL_2, (0<<TRCLK | MOD_FIFO<<DTMOD | 0<<ENINV | 0<<FD_8 | MOD_FSK<<MODTYP)); // Set up RX Modem Configuration per Table 16 // // For 100kbps/100kHz settings: rf_set_register(REG_IF_FILTER_BANDWIDTH, (1<<DWN3_BYPASS | 0<<NDEC_EXP | 0xf<<FILSET)); rf_set_register(REG_CLOCK_RECOVERY_OVERSAMPLING_RATE, 0x78); rf_set_register(REG_CLOCK_RECOVERY_OFFSET_2, (0<<RXOSR_8_10 | 0<<STALLCTRL | 1<<NCOFF_16_19)); rf_set_register(REG_CLOCK_RECOVERY_OFFSET_1,(0x11)); rf_set_register(REG_CLOCK_RECOVERY_OFFSET_0,(0x11)); rf_set_register(REG_CLOCK_RECOVERY_GAIN_1,(0x04)); rf_set_register(REG_CLOCK_RECOVERY_GAIN_0,(0x46)); #elif TX_DEVIATION == 300000 // for 100kbps, set deviation at 300 kHz = 300000/625 = 480 = 0x1e0 // NOTE: high bit goes in REG_MODULATION_CONTROL_2 as FD_8 rf_set_register(REG_FREQUENCY_DEVIATION, 0xe0); // Set up for FIFO io and FSK modulation // NOTE: high bit of deviation is here! rf_set_register(REG_MODULATION_MODE_CONTROL_2, (0<<TRCLK | MOD_FIFO<<DTMOD | 0<<ENINV | 1<<FD_8 | MOD_FSK<<MODTYP)); // Set up RX Modem Configuration per Table 16 // // For 100kbps/300kHz settings: rf_set_register(REG_IF_FILTER_BANDWIDTH, (1<<DWN3_BYPASS | 0<<NDEC_EXP | 0xe<<FILSET)); rf_set_register(REG_CLOCK_RECOVERY_OVERSAMPLING_RATE, 0x78); rf_set_register(REG_CLOCK_RECOVERY_OFFSET_2, (0<<RXOSR_8_10 | 0<<STALLCTRL | 1<<NCOFF_16_19)); rf_set_register(REG_CLOCK_RECOVERY_OFFSET_1,(0x11)); rf_set_register(REG_CLOCK_RECOVERY_OFFSET_0,(0x11)); rf_set_register(REG_CLOCK_RECOVERY_GAIN_1,(0x00)); rf_set_register(REG_CLOCK_RECOVERY_GAIN_0,(0xb8)); #else unsupported TX_DEVIATION #endif #else unsupported TX_DATA_RATE #endif // Header Configuration // // Enable header checking and broadcast matching on all address bytes rf_set_register(REG_HEADER_CONTROL_1, (0xf<<BCEN | 0xf<<HDCH)); // Set up for 4 byte header, variable packet length, 2 byte sync, 0 for MSB Preamble Length // (default is 0x22: HDLEN 010 Header 3 and 2; Sync Word 3 and 2) // rf_set_register(REG_HEADER_CONTROL_2, (4<<HDLEN | 0<<FIXPKLEN | 1<<SYNCLEN | 0<<PREALEN8)); // Preamble Length // the default preamble length is 8 nibbles / 32 bits // the sample transmit / receive code provided by HopeRF uses 64 nibbles instead(!) // the table on page 43 recommends 40 bits (10 nibbles), so we use that here // // TODO: test with shorter preamble for performance // rf_set_register(REG_PREAMBLE_LENGTH, (40/4)); // Preamble Detect Threshold // // DOCBUG: possible doc issue regarding preamble threshold: // rfget(0x35) is 0x20 at bootup; this is 4<<3, not 5<<3 per doc p.106 // (not to mention register 0x35 is missing from the summary table) // 4 nibbles is 16 bits, but on page 42 it is recommended to use 20 bits // so we set PREATH to 20 bits here; that's 5 nibbles // rf_set_register(REG_PREAMBLE_DETECTION_CONTROL_1, (20/4)<<PREATH); // Sync Pattern and Length // we use the default sync pattern of 2dd4 with 2 byte check // Enable the radio so rf_set_rx_address is a pass-thru below radio_go = 1; // mark the radio as UP // Receive address setup: listen on NOOB, and the broadcast address, // until setid() is called to provide an updated address. // If setid() was called before now, use the cached value. // (Tx address is set up per packet) // rf_set_rx_address((*nodeid) ? nodeid : (char *) DEFAULT_RX_ADDRESS); set_rx_mode(); // engage the receiver and off we go }
int main (void) { SystemInit(); #if ACMP_TEST == TRUE // -------------------------------------------- // analog comparator // -------------------------------------------- acmp_io_config(); #if CONFIG_ENABLE_DRIVER_ACMP0==TRUE analog_pin_enable(AIN0, MASK_ENABLE); analog_pin_enable(AIN1, MASK_ENABLE); acmp0_done = 0; // comparator0 test //comparator_init(ACMP0, VDD_1, ACMPO_0_GEN_INT, acmp0_test_cb); //comparator_init(ACMP0, VDD_8, ACMPO_1_GEN_INT, acmp0_test_cb); //comparator_init(ACMP0, VDD_15, ACMPO_0_GEN_INT, acmp0_test_cb); comparator_init(ACMP0, EXT_REF, ACMPO_1_GEN_INT, acmp0_test_cb); while (acmp0_done == 0); #endif #if CONFIG_ENABLE_DRIVER_ACMP1==TRUE analog_pin_enable(AIN2, MASK_ENABLE); analog_pin_enable(AIN3, MASK_ENABLE); acmp1_done = 0; // comparator1 test //comparator_init(ACMP1, VDD_1, ACMPO_0_GEN_INT, acmp1_test_cb); comparator_init(ACMP1, VDD_8, ACMPO_0_GEN_INT, acmp1_test_cb); //comparator_init(ACMP1, VDD_15, ACMPO_0_GEN_INT, acmp1_test_cb); while (acmp1_done == 0); #endif #endif #if RF_SWEEP_TEST == TRUE // -------------------------------------------- // analog RF // -------------------------------------------- int mask = SYSCON_MASK_DIS_REF_PLL | SYSCON_MASK_DIS_LO_VCO | SYSCON_MASK_DIS_LO_PLL | SYSCON_MASK_DIS_PA; syscon_SetPGCR1WithMask(QN_SYSCON, mask, MASK_DISABLE); rf_enable(RF_TX, MASK_ENABLE, MASK_ENABLE, 0x1F); rf_tx_power_level_set(TX_GAIN_LEVLE10); for (int i = 0; i < 40; i++) { rf_set_freq(RF_TX, i); delay(10000); } #endif while (1) /* Loop forever */ { } }