// C++ level interrupt handler for this instance // LORA is unusual in that it has several interrupt lines, and not a single, combined one. // On MiniWirelessLoRa, only one of the several interrupt lines (DI0) from the RFM95 is usefuly // connnected to the processor. // We use this to get RxDone and TxDone interrupts void RH_RF95::handleInterrupt() { // Read the interrupt register uint8_t irq_flags = spiRead(RH_RF95_REG_12_IRQ_FLAGS); if (_mode == RHModeRx && irq_flags & (RH_RF95_RX_TIMEOUT | RH_RF95_PAYLOAD_CRC_ERROR)) { _rxBad++; } else if (_mode == RHModeRx && irq_flags & RH_RF95_RX_DONE) { // Have received a packet uint8_t len = spiRead(RH_RF95_REG_13_RX_NB_BYTES); // Reset the fifo read ptr to the beginning of the packet spiWrite(RH_RF95_REG_0D_FIFO_ADDR_PTR, spiRead(RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR)); spiBurstRead(RH_RF95_REG_00_FIFO, _buf, len); _bufLen = len; spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags // Remember the last signal to noise ratio, LORA mode // Per page 111, SX1276/77/78/79 datasheet _lastSNR = (int8_t)spiRead(RH_RF95_REG_19_PKT_SNR_VALUE) / 4; // Remember the RSSI of this packet, LORA mode // this is according to the doc, but is it really correct? // weakest receiveable signals are reported RSSI at about -66 _lastRssi = spiRead(RH_RF95_REG_1A_PKT_RSSI_VALUE); // Adjust the RSSI, datasheet page 87 if (_lastSNR < 0) _lastRssi = _lastRssi + _lastSNR; else _lastRssi = (int)_lastRssi * 16 / 15; if (_usingHFport) _lastRssi -= 157; else _lastRssi -= 164; // We have received a message. validateRxBuf(); if (_rxBufValid) setModeIdle(); // Got one } else if (_mode == RHModeTx && irq_flags & RH_RF95_TX_DONE) { _txGood++; setModeIdle(); } else if (_mode == RHModeCad && irq_flags & RH_RF95_CAD_DONE) { _cad = irq_flags & RH_RF95_CAD_DETECTED; setModeIdle(); } // Sigh: on some processors, for some unknown reason, doing this only once does not actually // clear the radio's interrupt flag. So we do it twice. Why? spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags }
void RH_RF24::readNextFragment() { // Get the packet length from the RX FIFO length uint8_t fifo_info[1]; command(RH_RF24_CMD_FIFO_INFO, NULL, 0, fifo_info, sizeof(fifo_info)); uint8_t fifo_len = fifo_info[0]; // Check for overflow if ((_bufLen + fifo_len) > sizeof(_buf)) { // Overflow pending _rxBad++; setModeIdle(); clearRxFifo(); clearBuffer(); return; } // So we have room // Now read the fifo_len bytes from the RX FIFO // This is different to command() since we dont wait for CTS _spi.beginTransaction(); digitalWrite(_slaveSelectPin, LOW); _spi.transfer(RH_RF24_CMD_RX_FIFO_READ); uint8_t* p = _buf + _bufLen; uint8_t l = fifo_len; while (l--) *p++ = _spi.transfer(0); digitalWrite(_slaveSelectPin, HIGH); _spi.endTransaction(); _bufLen += fifo_len; }
bool RH_RF24::send(const uint8_t* data, uint8_t len) { if (len > RH_RF24_MAX_MESSAGE_LEN) return false; waitPacketSent(); // Make sure we dont interrupt an outgoing message setModeIdle(); // Prevent RX while filling the fifo // Put the payload in the FIFO // First the length in fixed length field 1. This wont appear in the receiver fifo since // we have turned off IN_FIFO in PKT_LEN _buf[0] = len + RH_RF24_HEADER_LEN; // Now the rest of the payload in variable length field 2 // First the headers _buf[1] = _txHeaderTo; _buf[2] = _txHeaderFrom; _buf[3] = _txHeaderId; _buf[4] = _txHeaderFlags; // Then the message memcpy(_buf + 1 + RH_RF24_HEADER_LEN, data, len); _bufLen = len + 1 + RH_RF24_HEADER_LEN; _txBufSentIndex = 0; // Set the field 2 length to the variable payload length uint8_t l[] = { (uint8_t)(len + RH_RF24_HEADER_LEN)}; set_properties(RH_RF24_PROPERTY_PKT_FIELD_2_LENGTH_7_0, l, sizeof(l)); sendNextFragment(); setModeTx(); return true; }
bool RH_RF95::send(const uint8_t* data, uint8_t len) { if (len > RH_RF95_MAX_MESSAGE_LEN) return false; waitPacketSent(); // Make sure we dont interrupt an outgoing message setModeIdle(); if (!waitCAD()) return false; // Check channel activity // Position at the beginning of the FIFO spiWrite(RH_RF95_REG_0D_FIFO_ADDR_PTR, 0); // The headers spiWrite(RH_RF95_REG_00_FIFO, _txHeaderTo); spiWrite(RH_RF95_REG_00_FIFO, _txHeaderFrom); spiWrite(RH_RF95_REG_00_FIFO, _txHeaderId); spiWrite(RH_RF95_REG_00_FIFO, _txHeaderFlags); // The message data spiBurstWrite(RH_RF95_REG_00_FIFO, data, len); spiWrite(RH_RF95_REG_22_PAYLOAD_LENGTH, len + RH_RF95_HEADER_LEN); setModeTx(); // Start the transmitter // when Tx is done, interruptHandler will fire and radio mode will return to STANDBY return true; }
// C++ level interrupt handler for this instance // LORA is unusual in that it has several interrupt lines, and not a single, combined one. // On MiniWirelessLoRa, only one of the several interrupt lines (DI0) from the RFM95 is usefuly // connnected to the processor. // We use this to get RxDone and TxDone interrupts void RH_RF95::handleInterrupt() { // Read the interrupt register uint8_t irq_flags = spiRead(RH_RF95_REG_12_IRQ_FLAGS); if (_mode == RHModeRx) { if (irq_flags & (RH_RF95_RX_TIMEOUT | RH_RF95_PAYLOAD_CRC_ERROR)) { _rxBad++; // Stay in RX mode } else if (irq_flags & RH_RF95_RX_DONE) { // Have received a packet uint8_t len = spiRead(RH_RF95_REG_13_RX_NB_BYTES); // Reset the fifo read ptr to the beginning of the packet spiWrite(RH_RF95_REG_0D_FIFO_ADDR_PTR, spiRead(RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR)); spiBurstRead(RH_RF95_REG_00_FIFO, _buf, len); _bufLen = len; spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xFF); // Clear all IRQ flags // Remember the RSSI of this packet // this is according to the doc, but is it really correct? // weakest receiveable signals are reported RSSI at about -66 _lastRssi = spiRead(RH_RF95_REG_1A_PKT_RSSI_VALUE) - 137; // We have received a message. validateRxBuf(); if (_rxBufValid) setModeIdle(); // Got one // else stay in RX mode } } else if (_mode == RHModeTx && (irq_flags & RH_RF95_TX_DONE)) { _txGood++; setModeIdle(); } spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xFF); // Clear all IRQ flags }
// C++ level interrupt handler for this instance // RH_RF69 is unusual in Mthat it has several interrupt lines, and not a single, combined one. // On Moteino, only one of the several interrupt lines (DI0) from the RH_RF69 is connnected to the processor. // We use this to get PACKETSDENT and PAYLOADRADY interrupts. void RH_RF69::handleInterrupt() { // Get the interrupt cause uint8_t irqflags2 = spiRead(RH_RF69_REG_28_IRQFLAGS2); if (_mode == RHModeTx && (irqflags2 & RH_RF69_IRQFLAGS2_PACKETSENT)) { // A transmitter message has been fully sent setModeIdle(); // Clears FIFO // Serial.println("PACKETSENT"); } // Must look for PAYLOADREADY, not CRCOK, since only PAYLOADREADY occurs _after_ AES decryption // has been done if (_mode == RHModeRx && (irqflags2 & RH_RF69_IRQFLAGS2_PAYLOADREADY)) { // A complete message has been received with good CRC _lastRssi = -((int8_t)(spiRead(RH_RF69_REG_24_RSSIVALUE) >> 1)); _lastPreambleTime = millis(); setModeIdle(); // Save it in our buffer readFifo(); // Serial.println("PAYLOADREADY"); }
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_RF95::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; // No way to check the device type :-( // Set sleep mode, so we can also set LORA mode: spiWrite(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE); delay(10); // Wait for sleep mode to take over from say, CAD // Check we are in sleep mode, with LORA set if (spiRead(RH_RF95_REG_01_OP_MODE) != (RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE)) { // Serial.println(spiRead(RH_RF95_REG_01_OP_MODE), HEX); return false; // No device present? } // 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++; // Set up FIFO // We configure so that we can use the entire 256 byte FIFO for either receive // or transmit, but not both at the same time spiWrite(RH_RF95_REG_0E_FIFO_TX_BASE_ADDR, 0); spiWrite(RH_RF95_REG_0F_FIFO_RX_BASE_ADDR, 0); // Packet format is preamble + explicit-header + payload + crc // Explicit Header Mode // payload is TO + FROM + ID + FLAGS + message data // RX mode is implmented with RXCONTINUOUS // max message data length is 255 - 4 = 251 octets // 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); setModeIdle(); // Set up default configuration // No Sync Words in LORA mode. // setModemConfig(Bw125Cr45Sf128); // Radio default setModemConfig(Bw125Cr48Sf4096); setPreambleLength(8); // Default is 8 // An innocuous ISM frequency, same as RF22's setFrequency(434.0); // Lowish power // setTxPower(13); setTxPower(20); 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 RH_RF95::init() { bool result = false; if (_resetPin != PIN_UNUSED) pinMode(_resetPin, INPUT); if (_powerPin != PIN_UNUSED) { pinMode(_powerPin, OUTPUT); digitalWrite(_powerPin, HIGH); if (_resetPin != PIN_UNUSED) while (digitalRead(_resetPin) != HIGH) ; delay(20); } 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; // Set sleep mode, so we can also set LORA mode: spiWrite(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE); delay(10); // Wait for sleep mode to take over from say, CAD _revision = spiRead(RH_RF95_REG_42_VERSION); // Check we are in sleep mode, with LORA set if (spiRead(RH_RF95_REG_01_OP_MODE) == (RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE)) { // 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_PULLDOWN); // 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_RF95_NUM_INTERRUPTS) _myInterruptIndex = _interruptCount++; // else Too many devices, not enough interrupt vectors } if (_myInterruptIndex < RH_RF95_NUM_INTERRUPTS) { _deviceForInterrupt[_myInterruptIndex] = this; if (_myInterruptIndex == 0) attachInterrupt(interruptNumber, isr0, RISING); else if (_myInterruptIndex == 1) attachInterrupt(interruptNumber, isr1, RISING); else if (_myInterruptIndex == 2) attachInterrupt(interruptNumber, isr2, RISING); // Set up FIFO // We configure so that we can use the entire 256 byte FIFO for either receive // or transmit, but not both at the same time spiWrite(RH_RF95_REG_0E_FIFO_TX_BASE_ADDR, 0); spiWrite(RH_RF95_REG_0F_FIFO_RX_BASE_ADDR, 0); result = true; } } if (result) { // Packet format is preamble + explicit-header + payload + crc // Explicit Header Mode // payload is TO + FROM + ID + FLAGS + message data // RX mode is implmented with RXCONTINUOUS // max message data length is 255 - 4 = 251 octets setModeIdle(); // Set up default configuration // No Sync Words in LORA mode. // setModemConfig(Bw125Cr45Sf128); // Radio default medium // setModemConfig(Bw125Cr48Sf4096); // slow and reliable? setModemConfig(Bw31_25Cr48Sf512); setPreambleLength(8); // Default is 8 setFrequency(434.0); // An innocuous ISM frequency, same as RF22's setTxPower(23); // Highest power } return result; }
// C++ level interrupt handler for this instance void RF22::handleInterrupt() { uint8_t _lastInterruptFlags[2]; // Read the interrupt flags which clears the interrupt spiBurstRead(RF22_REG_03_INTERRUPT_STATUS1, _lastInterruptFlags, 2); if (_lastInterruptFlags[0] & RF22_IFFERROR) { // cout << "RFM22 handleInterrupt(): IFFERROR\n"; resetFifos(); // Clears the interrupt if (_mode == RF22_MODE_TX) { restartTransmit(); } else if (_mode == RF22_MODE_RX) { clearRxBuf(); setModeIdle(); setModeRx(); } } // Caution, any delay here may cause a FF underflow or overflow if (_lastInterruptFlags[0] & RF22_ITXFFAEM) { // See if more data has to be loaded into the Tx FIFO sendNextFragment(); //cout << "RFM22 handleInterrupt(): ITXFFAEM\n"; } if (_lastInterruptFlags[0] & RF22_IRXFFAFULL) { // Caution, any delay here may cause a FF overflow // Read some data from the Rx FIFO readNextFragment(); cout << "RFM22 handleInterrupt(): IRXFFAFULL\n"; } if (_lastInterruptFlags[0] & RF22_IEXT) { // This is not enabled by the base code, but users may want to enable it handleExternalInterrupt(); cout << "RFM22 handleInterrupt(): IEXT\n"; } if (_lastInterruptFlags[1] & RF22_IWUT) { // This is not enabled by the base code, but users may want to enable it handleWakeupTimerInterrupt(); } if (_lastInterruptFlags[0] & RF22_IPKSENT) { _txGood++; // Transmission does not automatically clear the tx buffer. // Could retransmit if we wanted // RF22 transitions automatically to Idle _mode = RF22_MODE_IDLE; } if (_lastInterruptFlags[0] & RF22_IPKVALID) { // cout << "RFM22 handleInterrupt(): IPKVALID\n"; fflush(stdout); uint8_t len = spiRead(RF22_REG_4B_RECEIVED_PACKET_LENGTH); // May have already read one or more fragments // Get any remaining unread octets, based on the expected length // First make sure we dont overflow the buffer in the case of a stupid length // or partial bad receives if (len > RF22_MAX_MESSAGE_LEN || len < _bufLen) { _rxBad++; _mode = RF22_MODE_IDLE; clearRxBuf(); return; // Hmmm receiver buffer overflow. } spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf, 64); resetRxFifo(); setModeIdle(); setModeRx(); // spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, len - _bufLen); _rxGood++; _bufLen = len; _mode = RF22_MODE_IDLE; _rxBufValid = true; //notify registered dispatcherModule dispatcher->receiveMessage(this); } if (_lastInterruptFlags[0] & RF22_ICRCERROR) { cout << "RFM22 handleInterrupt(): ICRCERR\n"; _rxBad++; clearRxBuf(); resetRxFifo(); _mode = RF22_MODE_IDLE; setModeRx(); // Keep trying } if (_lastInterruptFlags[1] & RF22_IPREAVAL) { // cout << "RFM22 handleInterrupt(): IPREAVAL\n"; _lastRssi = spiRead(RF22_REG_26_RSSI); // clearRxBuf(); } }