// 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 }
bool RH_TCP::available() { if (_socket < 0) return false; checkForEvents(); if (_rxBufFull) { validateRxBuf(); _rxBufFull= false; } return _rxBufValid; }
// 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 void RH_RF24::handleInterrupt() { uint8_t status[8]; command(RH_RF24_CMD_GET_INT_STATUS, NULL, 0, status, sizeof(status)); // Decode and handle the interrupt bits we are interested in // if (status[0] & RH_RF24_INT_STATUS_CHIP_INT_STATUS) if (status[0] & RH_RF24_INT_STATUS_MODEM_INT_STATUS) { // if (status[4] & RH_RF24_INT_STATUS_INVALID_PREAMBLE) if (status[4] & RH_RF24_INT_STATUS_INVALID_SYNC) { // After INVALID_SYNC, sometimes the radio gets into a silly state and subsequently reports it for every packet // Need to reset the radio and clear the RX FIFO, cause sometimes theres junk there too _mode = RHModeIdle; clearRxFifo(); clearBuffer(); } } if (status[0] & RH_RF24_INT_STATUS_PH_INT_STATUS) { if (status[2] & RH_RF24_INT_STATUS_CRC_ERROR) { // CRC Error // Radio automatically went to _idleMode _mode = RHModeIdle; _rxBad++; clearRxFifo(); clearBuffer(); } if (status[2] & RH_RF24_INT_STATUS_PACKET_SENT) { _txGood++; // Transmission does not automatically clear the tx buffer. // Could retransmit if we wanted // RH_RF24 configured to transition automatically to Idle after packet sent _mode = RHModeIdle; clearBuffer(); } if (status[2] & RH_RF24_INT_STATUS_PACKET_RX) { // A complete message has been received with good CRC // Get the RSSI, configured to latch at sync detect in radio_config uint8_t modem_status[6]; command(RH_RF24_CMD_GET_MODEM_STATUS, NULL, 0, modem_status, sizeof(modem_status)); _lastRssi = modem_status[3]; _lastPreambleTime = millis(); // Save it in our buffer readNextFragment(); // And see if we have a valid message validateRxBuf(); // Radio will have transitioned automatically to the _idleMode _mode = RHModeIdle; } if (status[2] & RH_RF24_INT_STATUS_TX_FIFO_ALMOST_EMPTY) { // TX FIFO almost empty, maybe send another chunk, if there is one sendNextFragment(); } if (status[2] & RH_RF24_INT_STATUS_RX_FIFO_ALMOST_FULL) { // Some more data to read, get it readNextFragment(); } } }