Exemplo n.º 1
0
Arquivo: RF22.cpp Projeto: 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();
    }
}
Exemplo n.º 2
0
// 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();
	}
    }
}
Exemplo n.º 3
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();
	}
}