Ejemplo n.º 1
0
// Assumption: there are at least RF22_RXFFAFULL_THRESHOLD in the RX FIFO
// That means it should only be called after a RXFFAFULL interrupt
void RF22::readNextFragment() {
	if (((uint16_t) _bufLen + RF22_RXFFAFULL_THRESHOLD) > RF22_MAX_MESSAGE_LEN)
		return; // Hmmm receiver overflow. Should never occur

// Read the RF22_RXFFAFULL_THRESHOLD octets that should be there
	spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, RF22_RXFFAFULL_THRESHOLD);
	_bufLen += RF22_RXFFAFULL_THRESHOLD;
}
Ejemplo n.º 2
0
// 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
}
Ejemplo n.º 3
0
uint8_t RFM69_checkRx()
{
    // Check IRQ register for payloadready flag (indicates RXed packet waiting in FIFO)
    if(spiRead(RFM69_REG_28_IRQ_FLAGS2) & RF_IRQFLAGS2_PAYLOADREADY) {
        // Get packet length from first byte of FIFO
        _bufLen = spiRead(RFM69_REG_00_FIFO)+1;
        // Read FIFO into our Buffer
        spiBurstRead(RFM69_REG_00_FIFO, _buf, RFM69_FIFO_SIZE);
        // Read RSSI register (should be of the packet? - TEST THIS)
        _lastRssi = -(spiRead(RFM69_REG_24_RSSI_VALUE)/2);
        // Clear the radio FIFO (found in HopeRF demo code)
        RFM69_clearFifo();
        return 1;
    }
    
    return 0;
}
Ejemplo n.º 4
0
// 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
}
Ejemplo n.º 5
0
// 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
	// Serial.println("debug|Interrupt from RFM!");
    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)) {
		// Serial.print("debug|Bad packet received - irq_flags: ");
		// Serial.println(irq_flags, BIN);
	    _rxBad++;
		spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags
		return;
		// after this point, we know that the data in the FIFO is corrupted
    }
	
	if (_mode == RHModeRx && irq_flags & RH_RF95_RX_DONE) {
	    // Have received a packet
        uint8_t len = spiRead(RH_RF95_REG_13_RX_NB_BYTES);
		
		// Serial.println("debug|RX interrupt - we got some data!");

	    // 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;

	    // 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 -94
	    _lastRssi = -137 + (uint8_t) spiRead(RH_RF95_REG_1A_PKT_RSSI_VALUE);

	    byte snr;
	    snr = spiRead(0x19);
		
	    if( snr & 0x80 ) {
			// The SNR sign bit is True
		    // 2's complement -> Invert and divide by 4
		    snr = ( ( ~snr + 1 ) & 0xFF ) >> 2;
            _lastSnr = -snr;
        } else {
Ejemplo n.º 6
0
Archivo: RF22.cpp Proyecto: Ygorf/RF22
// 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 0
    // Caution: Serial printing in this interrupt routine can cause mysterious crashes
    Serial.print("interrupt ");
    Serial.print(_lastInterruptFlags[0], HEX);
    Serial.print(" ");
    Serial.println(_lastInterruptFlags[1], HEX);
    if (_lastInterruptFlags[0] == 0 && _lastInterruptFlags[1] == 0)
	Serial.println("FUNNY: no interrupt!");
#endif

#if 0
    // TESTING: fake an RF22_IFFERROR
    static int counter = 0;
    if (_lastInterruptFlags[0] & RF22_IPKSENT && counter++ == 10)
    {
	_lastInterruptFlags[0] = RF22_IFFERROR;
	counter = 0;
    }
#endif

    if (_lastInterruptFlags[0] & RF22_IFFERROR)
    {
//	Serial.println("IFFERROR");  
	resetFifos(); // Clears the interrupt
	if (_mode == RF22_MODE_TX)
	    restartTransmit();
	else if (_mode == RF22_MODE_RX)
	    clearRxBuf();
    }
    // 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();
//	Serial.println("ITXFFAEM");  
    }
    if (_lastInterruptFlags[0] & RF22_IRXFFAFULL)
    {
	// Caution, any delay here may cause a FF overflow
	// Read some data from the Rx FIFO
	readNextFragment();
//	Serial.println("IRXFFAFULL"); 
    }
    if (_lastInterruptFlags[0] & RF22_IEXT)
    {
	// This is not enabled by the base code, but users may want to enable it
	handleExternalInterrupt();
//	Serial.println("IEXT"); 
    }
    if (_lastInterruptFlags[1] & RF22_IWUT)
    {
	// This is not enabled by the base code, but users may want to enable it
	handleWakeupTimerInterrupt();
//	Serial.println("IWUT"); 
    }
    if (_lastInterruptFlags[0] & RF22_IPKSENT)
    {
//	Serial.println("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)
    {
	uint8_t len = spiRead(RF22_REG_4B_RECEIVED_PACKET_LENGTH);
//	Serial.println("IPKVALID");   
//	Serial.println(len);   
//	Serial.println(_bufLen);   

	// 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 + _bufLen, len - _bufLen);
	_rxGood++;
	_bufLen = len;
	_mode = RF22_MODE_IDLE;
	_rxBufValid = true;
    }
    if (_lastInterruptFlags[0] & RF22_ICRCERROR)
    {
//	Serial.println("ICRCERR");  
	_rxBad++;
	clearRxBuf();
	resetRxFifo();
	_mode = RF22_MODE_IDLE;
	setModeRx(); // Keep trying
    }
    if (_lastInterruptFlags[1] & RF22_IPREAVAL)
    {
//	Serial.println("IPREAVAL");  
	_lastRssi = spiRead(RF22_REG_26_RSSI);
	clearRxBuf();
    }
}
Ejemplo n.º 7
0
//------------------------------------------------------------------------
uint16_t RF22_wutRead()
{
    uint8_t buf[2];
    spiBurstRead(RF22_REG_17_WAKEUP_TIMER_VALUE1, buf, 2);
    return ((uint16_t)buf[0] << 8) | buf[1]; // Dont rely on byte order
}
Ejemplo n.º 8
0
//------------------------------------------------------------------------
// 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)
    {
    	RF22_resetFifos(); // Clears the interrupt
        if (_mode == RF22_MODE_TX)
        {
        	RF22_restartTransmit();
        }
        else if (_mode == RF22_MODE_RX)
        {
        	RF22_clearRxBuf();
            //stop and start Rx
        	RF22_setModeIdle();
        	RF22_setModeRx();
        }
        // stop handling the remaining interruppts as something went wrong here
        return;
    }
    
    // Caution, any delay here may cause a FF underflow or overflow
    if (_lastInterruptFlags[0] & RF22_ITXFFAEM)
    {
    	RF22_sendNextFragment();
    }
  
    if (_lastInterruptFlags[0] & RF22_IRXFFAFULL)
    {
    	RF22_readNextFragment();
    }   
    if (_lastInterruptFlags[0] & RF22_IEXT)
    {
    	RF22_handleExternalInterrupt();
    }
    if (_lastInterruptFlags[1] & RF22_IWUT)
    {

    	RF22_handleWakeupTimerInterrupt();
    }    
    if (_lastInterruptFlags[0] & RF22_IPKSENT)
    {
        _txGood++;
        _mode = RF22_MODE_IDLE;
    }
   
    if (_lastInterruptFlags[0] & RF22_IPKVALID)
    {
        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;
            RF22_clearRxBuf();
            return; // Hmmm receiver buffer overflow.
        }
        spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, len - _bufLen);
        DISABLE_ALL_INTERRUPTS();    // Disable Interrupts
        _rxGood++;
        _bufLen = len;
        _mode = RF22_MODE_IDLE;
        _rxBufValid = true;
        // reset the fifo for next packet??
        //resetRxFifo();
        ENABLE_ALL_INTERRUPTS();     // Enable Interrupts
    }
    
    if (_lastInterruptFlags[0] & RF22_ICRCERROR) {
        _rxBad++;
        RF22_clearRxBuf();
        RF22_resetRxFifo();
        _mode = RF22_MODE_IDLE;
        RF22_setModeRx(); // Keep trying
    }
    
    if (_lastInterruptFlags[1] & RF22_IPREAVAL) {      
        _lastRssi = spiRead(RF22_REG_26_RSSI);
        RF22_clearRxBuf();


    }
}
Ejemplo n.º 9
0
uint8_t RF22::spiRead(uint8_t reg)
{
    uint8_t data;
    spiBurstRead (reg, &data, 1);
    return data;
}
Ejemplo n.º 10
0
// 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();
	}
}