bool MaxRF22::init() { if (!RF22::init()) return false; setModemRegisters(&config); setFrequency(868.3, 0.035); /* Disable TX packet control, since the RF22 doesn't do proper * whitening so can't read the length header or CRC. We need RX packet * control so the RF22 actually sends pkvalid interrupts when the * manually set packet length is reached. */ // spiWrite(RF22_REG_2A_AFC_LIMITER, 0x1C); spiWrite(RF22_REG_30_DATA_ACCESS_CONTROL, RF22_MSBFRST | RF22_ENPACRX|RF22_ENPACTX); /* No packet headers, 4 sync words, fixed packet length */ spiWrite(RF22_REG_32_HEADER_CONTROL1, RF22_BCEN_NONE | RF22_HDCH_NONE); spiWrite(RF22_REG_33_HEADER_CONTROL2, RF22_HDLEN_0 | RF22_FIXPKLEN | RF22_SYNCLEN_4); setSyncWords(sync_words, sizeof(sync_words)); /* Detect preamble after 4 nibbles */ spiWrite(RF22_REG_35_PREAMBLE_DETECTION_CONTROL1, (0x4 << 3)); /* Send 8 bytes of preamble */ setPreambleLength(255); // in nibbles spiWrite(RF22_REG_3E_PACKET_LENGTH, 20); return true; }
bool RH_RF24::init() { if (!RHSPIDriver::init()) return false; // Determine the interrupt number that corresponds to the interruptPin int interruptNumber = digitalPinToInterrupt(_interruptPin); if (interruptNumber == NOT_AN_INTERRUPT) return false; #ifdef RH_ATTACHINTERRUPT_TAKES_PIN_NUMBER interruptNumber = _interruptPin; #endif // Initialise the radio power_on_reset(); cmd_clear_all_interrupts(); // Here we use a configuration generated by the Silicon Las Wireless Development Suite // in radio_config_Si4460.h // WE override a few things later that we ned to be sure of. configure(RFM26_CONFIGURATION_DATA); // Get the device type and check it // This also tests whether we are really connected to a device uint8_t buf[8]; if (!command(RH_RF24_CMD_PART_INFO, 0, 0, buf, sizeof(buf))) return false; // SPI error? Not connected? _deviceType = (buf[1] << 8) | buf[2]; // Check PART to be either 0x4460, 0x4461, 0x4463, 0x4464 if (_deviceType != 0x4460 && _deviceType != 0x4461 && _deviceType != 0x4463 && _deviceType != 0x4464) return false; // Unknown radio type, or not connected // Add by Adrien van den Bossche <*****@*****.**> for Teensy // ARM M4 requires the below. else pin interrupt doesn't work properly. // On all other platforms, its innocuous, belt and braces pinMode(_interruptPin, INPUT); // Set up interrupt handler // Since there are a limited number of interrupt glue functions isr*() available, // we can only support a limited number of devices simultaneously // ON some devices, notably most Arduinos, the interrupt pin passed in is actuallt the // interrupt number. You have to figure out the interruptnumber-to-interruptpin mapping // yourself based on knwledge of what Arduino board you are running on. if (_myInterruptIndex == 0xff) { // First run, no interrupt allocated yet if (_interruptCount <= RH_RF24_NUM_INTERRUPTS) _myInterruptIndex = _interruptCount++; else return false; // Too many devices, not enough interrupt vectors } _deviceForInterrupt[_myInterruptIndex] = this; if (_myInterruptIndex == 0) attachInterrupt(interruptNumber, isr0, FALLING); else if (_myInterruptIndex == 1) attachInterrupt(interruptNumber, isr1, FALLING); else if (_myInterruptIndex == 2) attachInterrupt(interruptNumber, isr2, FALLING); else return false; // Too many devices, not enough interrupt vectors // Ensure we get the interrupts we need, irrespective of whats in the radio_config uint8_t int_ctl[] = {RH_RF24_MODEM_INT_STATUS_EN | RH_RF24_PH_INT_STATUS_EN, 0xff, 0xff, 0x00 }; set_properties(RH_RF24_PROPERTY_INT_CTL_ENABLE, int_ctl, sizeof(int_ctl)); // RSSI Latching should be configured in MODEM_RSSI_CONTROL in radio_config // PKT_TX_THRESHOLD and PKT_RX_THRESHOLD should be set to about 0x30 in radio_config // Configure important RH_RF24 registers // Here we set up the standard packet format for use by the RH_RF24 library: // We will use FIFO Mode, with automatic packet generation // We have 2 fields: // Field 1 contains only the (variable) length of field 2, with CRC // Field 2 contains the variable length payload and the CRC // Hmmm, having no CRC on field 1 and CRC on field 2 causes CRC errors when resetting after an odd // number of packets! Anyway its prob a good thing at the cost of some airtime. // Hmmm, enabling WHITEN stops it working! uint8_t pkt_config1[] = { 0x00 }; set_properties(RH_RF24_PROPERTY_PKT_CONFIG1, pkt_config1, sizeof(pkt_config1)); uint8_t pkt_len[] = { 0x02, 0x01, 0x00 }; set_properties(RH_RF24_PROPERTY_PKT_LEN, pkt_len, sizeof(pkt_len)); uint8_t pkt_field1[] = { 0x00, 0x01, 0x00, RH_RF24_FIELD_CONFIG_CRC_START | RH_RF24_FIELD_CONFIG_SEND_CRC | RH_RF24_FIELD_CONFIG_CHECK_CRC | RH_RF24_FIELD_CONFIG_CRC_ENABLE }; set_properties(RH_RF24_PROPERTY_PKT_FIELD_1_LENGTH_12_8, pkt_field1, sizeof(pkt_field1)); uint8_t pkt_field2[] = { 0x00, sizeof(_buf), 0x00, RH_RF24_FIELD_CONFIG_CRC_START | RH_RF24_FIELD_CONFIG_SEND_CRC | RH_RF24_FIELD_CONFIG_CHECK_CRC | RH_RF24_FIELD_CONFIG_CRC_ENABLE }; set_properties(RH_RF24_PROPERTY_PKT_FIELD_2_LENGTH_12_8, pkt_field2, sizeof(pkt_field2)); // Clear all other fields so they are never used, irrespective of the radio_config uint8_t pkt_fieldn[] = { 0x00, 0x00, 0x00, 0x00 }; set_properties(RH_RF24_PROPERTY_PKT_FIELD_3_LENGTH_12_8, pkt_fieldn, sizeof(pkt_fieldn)); set_properties(RH_RF24_PROPERTY_PKT_FIELD_4_LENGTH_12_8, pkt_fieldn, sizeof(pkt_fieldn)); set_properties(RH_RF24_PROPERTY_PKT_FIELD_5_LENGTH_12_8, pkt_fieldn, sizeof(pkt_fieldn)); // The following can be changed later by the user if necessary. // Set up default configuration setCRCPolynomial(CRC_16_IBM); uint8_t syncwords[] = { 0x2d, 0xd4 }; setSyncWords(syncwords, sizeof(syncwords)); // Same as RF22's // Reasonably fast and reliable default speed and modulation setModemConfig(GFSK_Rb5Fd10); // 3 would be sufficient, but this is the same as RF22's // actualy, 4 seems to work much better for some modulations setPreambleLength(4); // An innocuous ISM frequency, same as RF22's setFrequency(434.0); // About 2.4dBm on RFM24: setTxPower(0x10); return true; }
boolean RF22::init() { // Wait for RF22 POR (up to 16msec) delay(16); // Initialise the slave select pin pinMode(_slaveSelectPin, OUTPUT); digitalWrite(_slaveSelectPin, HIGH); // start the SPI library: // Note the RF22 wants mode 0, MSB first and default to 1 Mbps _spi->begin(); _spi->setDataMode(SPI_MODE0); _spi->setBitOrder(MSBFIRST); _spi->setClockDivider(SPI_CLOCK_DIV16); // (16 Mhz / 16) = 1 MHz delay(100); // Software reset the device reset(); // Get the device type and check it // This also tests whether we are really connected to a device _deviceType = spiRead(RF22_REG_00_DEVICE_TYPE); if ( _deviceType != RF22_DEVICE_TYPE_RX_TRX && _deviceType != RF22_DEVICE_TYPE_TX) return false; // Set up interrupt handler if (_interrupt == 0) { _RF22ForInterrupt[0] = this; attachInterrupt(0, RF22::isr0, LOW); } else if (_interrupt == 1) { _RF22ForInterrupt[1] = this; attachInterrupt(1, RF22::isr1, LOW); } else return false; clearTxBuf(); clearRxBuf(); // Most of these are the POR default spiWrite(RF22_REG_7D_TX_FIFO_CONTROL2, RF22_TXFFAEM_THRESHOLD); spiWrite(RF22_REG_7E_RX_FIFO_CONTROL, RF22_RXFFAFULL_THRESHOLD); spiWrite(RF22_REG_30_DATA_ACCESS_CONTROL, RF22_ENPACRX | RF22_ENPACTX | RF22_ENCRC | RF22_CRC_CRC_16_IBM); // Configure the message headers // Here we set up the standard packet format for use by the RF22 library // 8 nibbles preamble // 2 SYNC words 2d, d4 // Header length 4 (to, from, id, flags) // 1 octet of data length (0 to 255) // 0 to 255 octets data // 2 CRC octets as CRC16(IBM), computed on the header, length and data // On reception the to address is check for validity against RF22_REG_3F_CHECK_HEADER3 // or the broadcast address of 0xff // If no changes are made after this, the transmitted // to address will be 0xff, the from address will be 0xff // and all such messages will be accepted. This permits the out-of the box // RF22 config to act as an unaddresed, unreliable datagram service spiWrite(RF22_REG_32_HEADER_CONTROL1, RF22_BCEN_HEADER3 | RF22_HDCH_HEADER3); spiWrite(RF22_REG_33_HEADER_CONTROL2, RF22_HDLEN_4 | RF22_SYNCLEN_2); setPreambleLength(8); uint8_t syncwords[] = { 0x2d, 0xd4 }; setSyncWords(syncwords, sizeof(syncwords)); setPromiscuous(false); // Check the TO header against RF22_DEFAULT_NODE_ADDRESS spiWrite(RF22_REG_3F_CHECK_HEADER3, RF22_DEFAULT_NODE_ADDRESS); // Set the default transmit header values setHeaderTo(RF22_DEFAULT_NODE_ADDRESS); setHeaderFrom(RF22_DEFAULT_NODE_ADDRESS); setHeaderId(0); setHeaderFlags(0); // Ensure the antenna can be switched automatically according to transmit and receive // This assumes GPIO0(out) is connected to TX_ANT(in) to enable tx antenna during transmit // This assumes GPIO1(out) is connected to RX_ANT(in) to enable rx antenna during receive spiWrite (RF22_REG_0B_GPIO_CONFIGURATION0, 0x12) ; // TX state spiWrite (RF22_REG_0C_GPIO_CONFIGURATION1, 0x15) ; // RX state // Enable interrupts spiWrite(RF22_REG_05_INTERRUPT_ENABLE1, RF22_ENTXFFAEM | RF22_ENRXFFAFULL | RF22_ENPKSENT | RF22_ENPKVALID | RF22_ENCRCERROR | RF22_ENFFERR); spiWrite(RF22_REG_06_INTERRUPT_ENABLE2, RF22_ENPREAVAL); // Set some defaults. An innocuous ISM frequency, and reasonable pull-in setFrequency(434.0, 0.05); // setFrequency(900.0); // Some slow, reliable default speed and modulation setModemConfig(FSK_Rb2_4Fd36); // setModemConfig(FSK_Rb125Fd125); // Minimum power setTxPower(RF22_TXPOW_8DBM); // setTxPower(RF22_TXPOW_17DBM); return true; }
bool RH_RF69::init() { if (!RHSPIDriver::init()) return false; // Determine the interrupt number that corresponds to the interruptPin int interruptNumber = digitalPinToInterrupt(_interruptPin); if (interruptNumber == NOT_AN_INTERRUPT) return false; // Get the device type and check it // This also tests whether we are really connected to a device // My test devices return 0x24 _deviceType = spiRead(RH_RF69_REG_10_VERSION); if (_deviceType == 00 || _deviceType == 0xff) return false; // Add by Adrien van den Bossche <*****@*****.**> for Teensy // ARM M4 requires the below. else pin interrupt doesn't work properly. // On all other platforms, its innocuous, belt and braces pinMode(_interruptPin, INPUT); // Set up interrupt handler // Since there are a limited number of interrupt glue functions isr*() available, // we can only support a limited number of devices simultaneously // ON some devices, notably most Arduinos, the interrupt pin passed in is actuallt the // interrupt number. You have to figure out the interruptnumber-to-interruptpin mapping // yourself based on knwledge of what Arduino board you are running on. _deviceForInterrupt[_interruptCount] = this; if (_interruptCount == 0) attachInterrupt(interruptNumber, isr0, RISING); else if (_interruptCount == 1) attachInterrupt(interruptNumber, isr1, RISING); else if (_interruptCount == 2) attachInterrupt(interruptNumber, isr2, RISING); else return false; // Too many devices, not enough interrupt vectors _interruptCount++; setModeIdle(); // Configure important RH_RF69 registers // Here we set up the standard packet format for use by the RH_RF69 library: // 4 bytes preamble // 2 SYNC words 2d, d4 // 2 CRC CCITT octets computed on the header, length and data (this in the modem config data) // 0 to 60 bytes data // RSSI Threshold -114dBm // We dont use the RH_RF69s address filtering: instead we prepend our own headers to the beginning // of the RH_RF69 payload spiWrite(RH_RF69_REG_3C_FIFOTHRESH, RH_RF69_FIFOTHRESH_TXSTARTCONDITION_NOTEMPTY | 0x0f); // thresh 15 is default // RSSITHRESH is default // spiWrite(RH_RF69_REG_29_RSSITHRESH, 220); // -110 dbM // SYNCCONFIG is default. SyncSize is set later by setSyncWords() // spiWrite(RH_RF69_REG_2E_SYNCCONFIG, RH_RF69_SYNCCONFIG_SYNCON); // auto, tolerance 0 // PAYLOADLENGTH is default // spiWrite(RH_RF69_REG_38_PAYLOADLENGTH, RH_RF69_FIFO_SIZE); // max size only for RX // PACKETCONFIG 2 is default spiWrite(RH_RF69_REG_6F_TESTDAGC, RH_RF69_TESTDAGC_CONTINUOUSDAGC_IMPROVED_LOWBETAOFF); // If high power boost set previously, disable it spiWrite(RH_RF69_REG_5A_TESTPA1, RH_RF69_TESTPA1_NORMAL); spiWrite(RH_RF69_REG_5C_TESTPA2, RH_RF69_TESTPA2_NORMAL); // The following can be changed later by the user if necessary. // Set up default configuration uint8_t syncwords[] = { 0x2d, 0xd4 }; setSyncWords(syncwords, sizeof(syncwords)); // Same as RF22's // Reasonably fast and reliable default speed and modulation setModemConfig(GFSK_Rb250Fd250); // 3 would be sufficient, but this is the same as RF22's setPreambleLength(4); // An innocuous ISM frequency, same as RF22's setFrequency(434.0); // No encryption setEncryptionKey(NULL); // +13dBm, same as power-on default setTxPower(13); return true; }
bool RH_RF22::init() { if (!RHSPIDriver::init()) return false; // Determine the interrupt number that corresponds to the interruptPin int interruptNumber = digitalPinToInterrupt(_interruptPin); if (interruptNumber == NOT_AN_INTERRUPT) return false; // Software reset the device reset(); // Get the device type and check it // This also tests whether we are really connected to a device _deviceType = spiRead(RH_RF22_REG_00_DEVICE_TYPE); if ( _deviceType != RH_RF22_DEVICE_TYPE_RX_TRX && _deviceType != RH_RF22_DEVICE_TYPE_TX) { return false; } // Add by Adrien van den Bossche <*****@*****.**> for Teensy // ARM M4 requires the below. else pin interrupt doesn't work properly. // On all other platforms, its innocuous, belt and braces pinMode(_interruptPin, INPUT); // Enable interrupt output on the radio. Interrupt line will now go high until // an interrupt occurs spiWrite(RH_RF22_REG_05_INTERRUPT_ENABLE1, RH_RF22_ENTXFFAEM | RH_RF22_ENRXFFAFULL | RH_RF22_ENPKSENT | RH_RF22_ENPKVALID | RH_RF22_ENCRCERROR | RH_RF22_ENFFERR); spiWrite(RH_RF22_REG_06_INTERRUPT_ENABLE2, RH_RF22_ENPREAVAL); // Set up interrupt handler // Since there are a limited number of interrupt glue functions isr*() available, // we can only support a limited number of devices simultaneously // On some devices, notably most Arduinos, the interrupt pin passed in is actually the // interrupt number. You have to figure out the interruptnumber-to-interruptpin mapping // yourself based on knowledge of what Arduino board you are running on. _deviceForInterrupt[_interruptCount] = this; if (_interruptCount == 0) attachInterrupt(interruptNumber, isr0, FALLING); else if (_interruptCount == 1) attachInterrupt(interruptNumber, isr1, FALLING); else if (_interruptCount == 2) attachInterrupt(interruptNumber, isr2, FALLING); else return false; // Too many devices, not enough interrupt vectors _interruptCount++; setModeIdle(); clearTxBuf(); clearRxBuf(); // Most of these are the POR default spiWrite(RH_RF22_REG_7D_TX_FIFO_CONTROL2, RH_RF22_TXFFAEM_THRESHOLD); spiWrite(RH_RF22_REG_7E_RX_FIFO_CONTROL, RH_RF22_RXFFAFULL_THRESHOLD); spiWrite(RH_RF22_REG_30_DATA_ACCESS_CONTROL, RH_RF22_ENPACRX | RH_RF22_ENPACTX | RH_RF22_ENCRC | (_polynomial & RH_RF22_CRC)); // Configure the message headers // Here we set up the standard packet format for use by the RH_RF22 library // 8 nibbles preamble // 2 SYNC words 2d, d4 // Header length 4 (to, from, id, flags) // 1 octet of data length (0 to 255) // 0 to 255 octets data // 2 CRC octets as CRC16(IBM), computed on the header, length and data // On reception the to address is check for validity against RH_RF22_REG_3F_CHECK_HEADER3 // or the broadcast address of 0xff // If no changes are made after this, the transmitted // to address will be 0xff, the from address will be 0xff // and all such messages will be accepted. This permits the out-of the box // RH_RF22 config to act as an unaddresed, unreliable datagram service spiWrite(RH_RF22_REG_32_HEADER_CONTROL1, RH_RF22_BCEN_HEADER3 | RH_RF22_HDCH_HEADER3); spiWrite(RH_RF22_REG_33_HEADER_CONTROL2, RH_RF22_HDLEN_4 | RH_RF22_SYNCLEN_2); setPreambleLength(8); uint8_t syncwords[] = { 0x2d, 0xd4 }; setSyncWords(syncwords, sizeof(syncwords)); setPromiscuous(false); // Set some defaults. An innocuous ISM frequency, and reasonable pull-in setFrequency(434.0, 0.05); // setFrequency(900.0); // Some slow, reliable default speed and modulation setModemConfig(FSK_Rb2_4Fd36); // setModemConfig(FSK_Rb125Fd125); setGpioReversed(false); // Lowish power setTxPower(RH_RF22_TXPOW_8DBM); return true; }
bool RF22::init() { //TODO check. wiringPiSetup(); // // Wait for RF22 POR (up to 16msec) // delay(16); if (wiringPiSPISetup(_slaveSelectPin, 1000000) == -1) { printf("Could not initialize SPI\n"); return false; } delay(20); // Software reset the device reset(); delay(1); // Get the device type and check it // This also tests whether we are really connected to a device _deviceType = spiRead(RF22_REG_00_DEVICE_TYPE); if (_deviceType != RF22_DEVICE_TYPE_RX_TRX && _deviceType != RF22_DEVICE_TYPE_TX) return false; // Set up interrupt handler if (_interrupt == 0) { _RF22ForInterrupt[0] = this; //attaching interrupt to gpio pins. see wiringPi.com -> gpio chart wiringPiISR(6, INT_EDGE_FALLING, RF22::isr0); } else if (_interrupt == 1) { _RF22ForInterrupt[1] = this; wiringPiISR(4, INT_EDGE_FALLING, RF22::isr1); } else return false; clearTxBuf(); clearRxBuf(); // Most of these are the POR default spiWrite(RF22_REG_7D_TX_FIFO_CONTROL2, RF22_TXFFAEM_THRESHOLD); spiWrite(RF22_REG_7E_RX_FIFO_CONTROL, RF22_RXFFAFULL_THRESHOLD); spiWrite(RF22_REG_30_DATA_ACCESS_CONTROL, RF22_ENPACRX | RF22_ENPACTX | RF22_ENCRC | RF22_CRC_CRC_16_IBM); // Configure the message headers // Here we set up the standard packet format for use by the RF22 library // 8 nibbles preamble // 2 SYNC words 2d, d4 // Header length 4 (to, from, id, flags) // 1 octet of data length (0 to 255) // 0 to 255 octets data // 2 CRC octets as CRC16(IBM), computed on the header, length and data // On reception the to address is check for validity against RF22_REG_3F_CHECK_HEADER3 // or the broadcast address of 0xff // If no changes are made after this, the transmitted // to address will be 0xff, the from address will be 0xff // and all such messages will be accepted. This permits the out-of the box // RF22 config to act as an unaddresed, unreliable datagram service spiWrite(RF22_REG_32_HEADER_CONTROL1, RF22_BCEN_HEADER3 | RF22_HDCH_HEADER3); spiWrite(RF22_REG_33_HEADER_CONTROL2, RF22_HDLEN_4 | RF22_SYNCLEN_2 | 0x1); setPreambleLength(8); uint8_t syncwords[] = { 0x2d, 0xd4 }; setSyncWords(syncwords, sizeof(syncwords)); setPromiscuous(false); // Check the TO header against RF22_DEFAULT_NODE_ADDRESS spiWrite(RF22_REG_3F_CHECK_HEADER3, RF22_DEFAULT_NODE_ADDRESS); // Set the default transmit header values setHeaderTo(RF22_DEFAULT_NODE_ADDRESS); setHeaderFrom(RF22_DEFAULT_NODE_ADDRESS); setHeaderId(0); setHeaderFlags(0); // Ensure the antenna can be switched automatically according to transmit and receive // This assumes GPIO0(out) is connected to TX_ANT(in) to enable tx antenna during transmit // This assumes GPIO1(out) is connected to RX_ANT(in) to enable rx antenna during receive spiWrite(RF22_REG_0B_GPIO_CONFIGURATION0, 0x12); // TX state spiWrite(RF22_REG_0C_GPIO_CONFIGURATION1, 0x15); // RX state //spiWrite(RF22_REG_0D_GPIO_CONFIGURATION2, 0x14); //raw data to port 4 have to activate it later? //put into a mode where the interrupt frequency is not as high as the clock of the rfm22. //the raspberry is connected to that pin and would freeze if an isr is registered. spiWrite(RF22_REG_0D_GPIO_CONFIGURATION2, 0x13); // Enable interrupts spiWrite(RF22_REG_05_INTERRUPT_ENABLE1, RF22_ENTXFFAEM | RF22_ENRXFFAFULL | RF22_ENPKSENT | RF22_ENPKVALID | RF22_ENCRCERROR | RF22_ENFFERR); spiWrite(RF22_REG_06_INTERRUPT_ENABLE2, RF22_ENPREAVAL); // Set some defaults. An innocuous ISM frequency, and reasonable pull-in setFrequency(434.0, 0.05); // setFrequency(900.0); // Some slow, reliable default speed and modulation setModemConfig(FSK_Rb2_4Fd36); // setModemConfig(FSK_Rb125Fd125); // Minimum power setTxPower(RF22_TXPOW_8DBM); // setTxPower(RF22_TXPOW_17DBM); return true; }