示例#1
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
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
文件: RH_RF95.cpp 项目: x893/LoRa
// 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
}
示例#6
0
// 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");
    }
示例#7
0
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;
}
示例#8
0
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;
}
示例#9
0
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;
}
示例#10
0
文件: RH_RF95.cpp 项目: x893/LoRa
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;
}
示例#11
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();
	}
}