This driver is a stripped down version of the Radiohead 1.45 driver, and covers fewer radios. Threading and an event queue have been added to make the ISR's more stable across architectures. Specifically The STM32L4 parts

Dependents:   Threaded_LoRa_Modem

Revision:
3:6ffa8c82a713
Parent:
1:dfeb5e8b199a
Child:
4:61db9344ce8c
--- a/RH_RF95.cpp	Sat May 29 19:02:55 2021 +0000
+++ b/RH_RF95.cpp	Mon May 31 02:49:19 2021 +0000
@@ -1,16 +1,21 @@
-// RH_RF22.cpp
+// RH_RF95.cpp
 //
 // Copyright (C) 2011 Mike McCauley
 // $Id: RH_RF95.cpp,v 1.8 2015/08/12 23:18:51 mikem Exp $
 
 #include <RH_RF95.h>
 
-// Interrupt vectors for the 3 Arduino interrupt pins
+// Interrupt vectors for up to 3 interrupt pins
 // Each interrupt can be handled by a different instance of RH_RF95, allowing you to have
-// 2 or more LORAs per Arduino
+// multiple LoRa radios
 RH_RF95* RH_RF95::_deviceForInterrupt[RH_RF95_NUM_INTERRUPTS] = {0, 0, 0};
 uint8_t RH_RF95::_interruptCount = 0; // Index into _deviceForInterrupt for next device
 
+// The mbed driver leverages threading and a queue to handle the ISR's
+#if (RH_PLATFORM == RH_PLATFORM_MBED)
+EventQueue queue(32 * EVENTS_EVENT_SIZE);
+Thread _isrThread;//( osPriorityHigh, OS_STACK_SIZE / 2 );
+#endif
 // These are indexed by the values of ModemConfigChoice
 // Stored in flash (program) memory to save SRAM
 PROGMEM static const RH_RF95::ModemConfig MODEM_CONFIG_TABLE[] =
@@ -34,7 +39,7 @@
 
 bool RH_RF95::init()
 {
-    printf("Initializing...\n");
+//    printf("Initializing...\n");
     if (!RHSPIDriver::init())
 	return false;
 
@@ -43,6 +48,8 @@
     int interruptNumber = digitalPinToInterrupt(_interruptPin);
     if (interruptNumber == NOT_AN_INTERRUPT)
 	return false;
+#else
+	_isrThread.start(callback(&queue, &EventQueue::dispatch_forever));
 #endif
 
 	
@@ -54,7 +61,7 @@
     // 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))
     {
-	printf("Mode:%x\n",spiRead(RH_RF95_REG_01_OP_MODE));
+	printf("Invalid Mode:%x\n",spiRead(RH_RF95_REG_01_OP_MODE));
 	return false; // No device present?
     }
 
@@ -63,6 +70,8 @@
     // ARM M4 requires the below. else pin interrupt doesn't work properly.
     // On all other platforms, its innocuous, belt and braces
     pinMode(_interruptPin, INPUT); 
+#else
+	_interruptPin.mode(PullDown);
 #endif
 
     // Set up interrupt handler
@@ -82,13 +91,12 @@
     _deviceForInterrupt[_myInterruptIndex] = this;
     
 #if (RH_PLATFORM == RH_PLATFORM_MBED)
-	_interruptPin.mode(PullDown);
     if (_myInterruptIndex == 0)
-		_interruptPin.rise(&isr0);
+		_interruptPin.rise(queue.event(isr0));
     else if (_myInterruptIndex == 1)
-		_interruptPin.rise(&isr1);
+		_interruptPin.rise(queue.event(isr1));
     else if (_myInterruptIndex == 2)
-		_interruptPin.rise(&isr2);
+		_interruptPin.rise(queue.event(isr2));
     else
 	return false; // Too many devices, not enough interrupt vectors
 #else
@@ -104,7 +112,7 @@
     // 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
-    printf("using ISR %d\n",_myInterruptIndex);
+//    printf("using ISR %d\n",_myInterruptIndex);
     spiWrite(RH_RF95_REG_0E_FIFO_TX_BASE_ADDR, 0);
     spiWrite(RH_RF95_REG_0F_FIFO_RX_BASE_ADDR, 0);
 
@@ -125,7 +133,7 @@
     setFrequency(434.0);
     // Lowish power
     setTxPower(13);
-	printf("Ready!\n");
+//	printf("Ready!\n");
     return true;
 }
 
@@ -136,6 +144,10 @@
 // We use this to get RxDone and TxDone interrupts
 void RH_RF95::handleInterrupt()
 {
+//    if( doISR == false)
+//    	return;
+//    	
+//    doISR = false;
     // 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))
@@ -172,6 +184,11 @@
     spiWrite(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags
 }
 
+void RH_RF95::manageISR(){
+	while(1)
+		_deviceForInterrupt[0]->handleInterrupt();
+	}
+
 // These are low level functions that call the interrupt handler for the correct
 // instance of RH_RF95.
 // 3 interrupts allows us to have 3 different devices
@@ -179,6 +196,8 @@
 {
     if (_deviceForInterrupt[0])
 	_deviceForInterrupt[0]->handleInterrupt();
+//	doISR = true;
+	
 }
 void RH_RF95::isr1()
 {
@@ -305,8 +324,9 @@
 {
     if (_mode != RHModeIdle)
     {
-	    printf("---- Idle\n");
+//	    printf("---- Idle\n");
 		spiWrite(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_STDBY);
+		delay(10);
 		_mode = RHModeIdle;
     }
 }
@@ -316,8 +336,9 @@
     
     if (_mode != RHModeSleep)
     {
-    	printf("---- Sleep\n");
+//    	printf("---- Sleep\n");
 		spiWrite(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP);
+		delay(10);
 		_mode = RHModeSleep;
     }
     return true;
@@ -327,9 +348,10 @@
 {
     if (_mode != RHModeRx)
     {
-    	printf("---- RX\n");
+//    	printf("---- RX\n");
 		spiWrite(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_RXCONTINUOUS);
-		spiWrite(RH_RF95_REG_40_DIO_MAPPING1, RH_RF95_DIOMAPPING1_DIO0MAPPING_01); // Interrupt on RxDone
+		spiWrite(RH_RF95_REG_40_DIO_MAPPING1, RH_RF95_DIOMAPPING1_DIO0MAPPING_00); // Interrupt on RxDone
+		delay(10);
 		_mode = RHModeRx;
     }
 }
@@ -338,9 +360,10 @@
 {
     if (_mode != RHModeTx)
     {
-    	printf("---- TX\n");
+//    	printf("---- TX\n");
 		spiWrite(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_TX);
 		spiWrite(RH_RF95_REG_40_DIO_MAPPING1, RH_RF95_DIOMAPPING1_DIO0MAPPING_00); // Interrupt on TxDone
+		delay(10);
 		_mode = RHModeTx;
     }
 }