88// Interrupt vectors for the 3 Arduino interrupt pins
99// Each interrupt can be handled by a different instance of RH_RF69, allowing you to have
1010// 2 or more RF69s per Arduino
11+ #ifndef RH_RF69_IRQLESS
1112RH_RF69* RH_RF69::_deviceForInterrupt[RH_RF69_NUM_INTERRUPTS] = {0 , 0 , 0 };
1213uint8_t RH_RF69::_interruptCount = 0 ; // Index into _deviceForInterrupt for next device
14+ #endif
1315
1416// These are indexed by the values of ModemConfigChoice
1517// Stored in flash (program) memory to save SRAM
@@ -45,6 +47,10 @@ PROGMEM static const RH_RF69::ModemConfig MODEM_CONFIG_TABLE[] =
4547 { CONFIG_FSK, 0x00 , 0x80 , 0x10 , 0x00 , 0xe0 , 0xe0 , CONFIG_WHITE}, // FSK_Rb250Fd250
4648 { CONFIG_FSK, 0x02 , 0x40 , 0x03 , 0x33 , 0x42 , 0x42 , CONFIG_WHITE}, // FSK_Rb55555Fd50
4749
50+ // MOTEINO
51+ // REGAFCBW set to default 0x8A, No DC-free encoding/decoding performed
52+ { CONFIG_FSK, 0x02 , 0x40 , 0x03 , 0x33 , 0x42 , 0x8A , CONFIG_NOWHITE}, // FSK_MOTEINO
53+
4854 // 02, 03, 04, 05, 06, 19, 1a, 37
4955 // GFSK (BT=1.0), No Manchester, whitening, CRC, no address filtering
5056 // AFC BW == RX BW == 2 x bit rate
@@ -87,33 +93,56 @@ RH_RF69::RH_RF69(uint8_t slaveSelectPin, uint8_t interruptPin, RHGenericSPI& spi
8793 :
8894 RHSPIDriver(slaveSelectPin, spi)
8995{
96+ #ifndef RH_RF69_IRQLESS
9097 _interruptPin = interruptPin;
91- _idleMode = RH_RF69_OPMODE_MODE_STDBY;
9298 _myInterruptIndex = 0xff ; // Not allocated yet
99+ #endif
100+ _idleMode = RH_RF69_OPMODE_MODE_STDBY;
93101}
94102
95103void RH_RF69::setIdleMode (uint8_t idleMode)
96104{
97105 _idleMode = idleMode;
98106}
99107
100- bool RH_RF69::init ()
108+ // Set configuration to be moteino compatible
109+ void RH_RF69::setConfigMoteino ()
110+ {
111+ setModemConfig (FSK_MOTEINO);
112+ setPreambleLength (3 );
113+ spiWrite (RH_RF69_REG_29_RSSITHRESH, 220 );
114+ spiWrite (RH_RF69_REG_3D_PACKETCONFIG2, RH_RF69_PACKETCONFIG2_RXRESTARTDELAY_2BITS | RH_RF69_PACKETCONFIG2_AUTORXRESTARTON);
115+ // default moteino Frequency For 433 MHz
116+ setFrequency (433.0 );
117+
118+ // Moteino default network ID is 1
119+ uint8_t syncwords[] = { 0x2d , 1 };
120+ setSyncWords (syncwords, sizeof (syncwords));
121+ // spiWrite(RH_RF69_REG_07_FRFMSB, 0x6C);
122+ // spiWrite(RH_RF69_REG_08_FRFMID, 0x40);
123+ // spiWrite(RH_RF69_REG_09_FRFLSB, 0x00);
124+ }
125+
126+ bool RH_RF69::init (void )
101127{
102128 if (!RHSPIDriver::init ())
103129 return false ;
104130
131+ #ifndef RH_RF69_IRQLESS
105132 // Determine the interrupt number that corresponds to the interruptPin
106133 int interruptNumber = digitalPinToInterrupt (_interruptPin);
107134 if (interruptNumber == NOT_AN_INTERRUPT)
108135 return false ;
136+ #endif
109137
110138 // Get the device type and check it
111139 // This also tests whether we are really connected to a device
112140 // My test devices return 0x24
113- _deviceType = spiRead (RH_RF69_REG_10_VERSION);
114- if (_deviceType == 00 ||
115- _deviceType == 0xff )
116- return false ;
141+ _deviceType = spiRead (RH_RF69_REG_10_VERSION);
142+ if (_deviceType == 00 || _deviceType == 0xff )
143+ return false ;
144+
145+ #ifndef RH_RF69_IRQLESS
117146
118147 // Add by Adrien van den Bossche <[email protected] > for Teensy 119148 // ARM M4 requires the below. else pin interrupt doesn't work properly.
@@ -144,6 +173,7 @@ bool RH_RF69::init()
144173 else
145174 return false ; // Too many devices, not enough interrupt vectors
146175
176+ #endif
147177 setModeIdle ();
148178
149179 // Configure important RH_RF69 registers
@@ -172,7 +202,6 @@ bool RH_RF69::init()
172202 // Set up default configuration
173203 uint8_t syncwords[] = { 0x2d , 0xd4 };
174204 setSyncWords (syncwords, sizeof (syncwords)); // Same as RF22's
175- // Reasonably fast and reliable default speed and modulation
176205 setModemConfig (GFSK_Rb250Fd250);
177206
178207 // 3 would be sufficient, but this is the same as RF22's
@@ -184,23 +213,27 @@ bool RH_RF69::init()
184213 // +13dBm, same as power-on default
185214 setTxPower (13 );
186215
216+ // override and set config to moteino
217+ setConfigMoteino ();
218+
187219 return true ;
188220}
189221
190222// C++ level interrupt handler for this instance
191223// RH_RF69 is unusual in Mthat it has several interrupt lines, and not a single, combined one.
192224// On Moteino, only one of the several interrupt lines (DI0) from the RH_RF69 is connnected to the processor.
193225// We use this to get PACKETSDENT and PAYLOADRADY interrupts.
226+ #ifndef RH_RF69_IRQLESS
194227void RH_RF69::handleInterrupt ()
195228{
196229 // Get the interrupt cause
197230 uint8_t irqflags2 = spiRead (RH_RF69_REG_28_IRQFLAGS2);
198231 if (_mode == RHModeTx && (irqflags2 & RH_RF69_IRQFLAGS2_PACKETSENT))
199232 {
233+ // Serial.println("PACKETSENT");
200234 // A transmitter message has been fully sent
201235 setModeIdle (); // Clears FIFO
202236 _txGood++;
203- // Serial.println("PACKETSENT");
204237 }
205238 // Must look for PAYLOADREADY, not CRCOK, since only PAYLOADREADY occurs _after_ AES decryption
206239 // has been done
@@ -210,12 +243,14 @@ void RH_RF69::handleInterrupt()
210243 _lastRssi = -((int8_t )(spiRead (RH_RF69_REG_24_RSSIVALUE) >> 1 ));
211244 _lastPreambleTime = millis ();
212245
246+ // Serial.println("PAYLOADREADY");
213247 setModeIdle ();
248+
214249 // Save it in our buffer
215250 readFifo ();
216- // Serial.println("PAYLOADREADY");
217251 }
218252}
253+ #endif
219254
220255// Low level function reads the FIFO and checks the address
221256// Caution: since we put our headers in what the RH_RF69 considers to be the payload, if encryption is enabled
@@ -231,18 +266,20 @@ void RH_RF69::readFifo()
231266 payloadlen >= RH_RF69_HEADER_LEN)
232267 {
233268 _rxHeaderTo = _spi.transfer (0 );
234- // Check addressing
269+ // Check addressing
235270 if (_promiscuous ||
236271 _rxHeaderTo == _thisAddress ||
237272 _rxHeaderTo == RH_BROADCAST_ADDRESS)
238273 {
239274 // Get the rest of the headers
240275 _rxHeaderFrom = _spi.transfer (0 );
241- _rxHeaderId = _spi.transfer (0 );
276+ _rxHeaderId = _spi.transfer (0 );
242277 _rxHeaderFlags = _spi.transfer (0 );
278+
243279 // And now the real payload
244280 for (_bufLen = 0 ; _bufLen < (payloadlen - RH_RF69_HEADER_LEN); _bufLen++)
245- _buf[_bufLen] = _spi.transfer (0 );
281+ _buf[_bufLen] = _spi.transfer (0 );
282+
246283 _rxGood++;
247284 _rxBufValid = true ;
248285 }
@@ -255,6 +292,7 @@ void RH_RF69::readFifo()
255292// These are low level functions that call the interrupt handler for the correct
256293// instance of RH_RF69.
257294// 3 interrupts allows us to have 3 different devices
295+ #ifndef RH_RF69_IRQLESS
258296void RH_RF69::isr0 ()
259297{
260298 if (_deviceForInterrupt[0 ])
@@ -270,6 +308,7 @@ void RH_RF69::isr2()
270308 if (_deviceForInterrupt[2 ])
271309 _deviceForInterrupt[2 ]->handleInterrupt ();
272310}
311+ #endif
273312
274313int8_t RH_RF69::temperatureRead ()
275314{
@@ -307,6 +346,17 @@ int8_t RH_RF69::rssiRead()
307346
308347void RH_RF69::setOpMode (uint8_t mode)
309348{
349+ /*
350+ Serial.print("\r\nsetOpMode ");
351+ if (mode & 0x40) Serial.print(" ListOn");
352+ if (mode & 0x20) Serial.print(" ListAbrt");
353+ if ((mode & 0x1C) == 0x00) Serial.print(" Sleep");
354+ if ((mode & 0x1C) == 0x04) Serial.print(" Standby");
355+ if ((mode & 0x1C) == 0x08) Serial.print(" FS");
356+ if ((mode & 0x1C) == 0x0C) Serial.print(" TX");
357+ if ((mode & 0x1C) == 0x10) Serial.print(" RX");
358+ */
359+
310360 uint8_t opmode = spiRead (RH_RF69_REG_01_OPMODE);
311361 opmode &= ~RH_RF69_OPMODE_MODE;
312362 opmode |= (mode & RH_RF69_OPMODE_MODE);
@@ -369,6 +419,12 @@ void RH_RF69::setModeTx()
369419 spiWrite (RH_RF69_REG_5A_TESTPA1, RH_RF69_TESTPA1_BOOST);
370420 spiWrite (RH_RF69_REG_5C_TESTPA2, RH_RF69_TESTPA2_BOOST);
371421 }
422+
423+ /*
424+ Serial.print(" 5A_PA1=0x"); Serial.print(spiRead(RH_RF69_REG_5A_TESTPA1),HEX);
425+ Serial.print(" 5C_PA2=0x"); Serial.print(spiRead(RH_RF69_REG_5C_TESTPA2),HEX);
426+ Serial.print(" TxPower=0x"); Serial.println(spiRead(RH_RF69_REG_11_PALEVEL),HEX);
427+ */
372428 spiWrite (RH_RF69_REG_25_DIOMAPPING1, RH_RF69_DIOMAPPING1_DIO0MAPPING_00); // Set interrupt line 0 PacketSent
373429 setOpMode (RH_RF69_OPMODE_MODE_TX); // Clears FIFO
374430 _mode = RHModeTx;
@@ -428,6 +484,15 @@ bool RH_RF69::setModemConfig(ModemConfigChoice index)
428484 return true ;
429485}
430486
487+ bool RH_RF69::getModemConfig (ModemConfigChoice index, ModemConfig* config)
488+ {
489+ if (index > (signed int )(sizeof (MODEM_CONFIG_TABLE) / sizeof (ModemConfig)))
490+ return false ;
491+
492+ memcpy_P (config, &MODEM_CONFIG_TABLE[index], sizeof (RH_RF69::ModemConfig));
493+
494+ return true ;
495+ }
431496void RH_RF69::setPreambleLength (uint16_t bytes)
432497{
433498 spiWrite (RH_RF69_REG_2C_PREAMBLEMSB, bytes >> 8 );
@@ -464,10 +529,31 @@ void RH_RF69::setEncryptionKey(uint8_t* key)
464529
465530bool RH_RF69::available ()
466531{
467- if (_mode == RHModeTx)
468- return false ;
469- setModeRx (); // Make sure we are receiving
470- return _rxBufValid;
532+ #ifdef RH_RF69_IRQLESS
533+ // Must look for PAYLOADREADY, not CRCOK, since only PAYLOADREADY occurs _after_ AES decryption
534+ // has been done
535+
536+ // Get the interrupt state
537+ uint8_t irqflags2 = spiRead (RH_RF69_REG_28_IRQFLAGS2);
538+
539+ if (_mode == RHModeRx && (irqflags2 & RH_RF69_IRQFLAGS2_PAYLOADREADY))
540+ {
541+ // A complete message has been received with good CRC
542+ _lastRssi = -((int8_t )(spiRead (RH_RF69_REG_24_RSSIVALUE) >> 1 ));
543+ _lastPreambleTime = millis ();
544+
545+ setModeIdle ();
546+
547+ // Save it in our buffer
548+ readFifo ();
549+ }
550+ #endif
551+
552+ if (_mode == RHModeTx)
553+ return false ;
554+
555+ setModeRx (); // Make sure we are receiving
556+ return _rxBufValid;
471557}
472558
473559bool RH_RF69::recv (uint8_t * buf, uint8_t * len)
@@ -507,14 +593,33 @@ bool RH_RF69::send(const uint8_t* data, uint8_t len)
507593 _spi.transfer (_txHeaderFlags);
508594 // Now the payload
509595 while (len--)
510- _spi.transfer (*data++);
596+ _spi.transfer (*data++);
511597 digitalWrite (_slaveSelectPin, HIGH);
512598 ATOMIC_BLOCK_END;
513599
514600 setModeTx (); // Start the transmitter
515601 return true ;
516602}
517603
604+ #ifdef RH_RF69_IRQLESS
605+ bool RH_RF69::waitPacketSent ()
606+ {
607+ // If we are not currently in transmit mode, there is no packet to wait for
608+ if (_mode != RHModeTx)
609+ return false ;
610+
611+ while (!(spiRead (RH_RF69_REG_28_IRQFLAGS2) & RH_RF69_IRQFLAGS2_PACKETSENT)){
612+ YIELD;
613+ }
614+
615+ // A transmitter message has been fully sent
616+ setModeIdle (); // Clears FIFO
617+ _txGood++;
618+ return true ;
619+ }
620+ #endif
621+
622+
518623uint8_t RH_RF69::maxMessageLength ()
519624{
520625 return RH_RF69_MAX_MESSAGE_LEN;
0 commit comments