Transmit and Receive with Interrupts
For the final iteration of the “nasty” test harness I got the interrupts working for the transmitting and receiving of messages. It’s not quite simultaneous, the code sends a message every 10 seconds then goes back to receive continuous mode after each message has been sent.
public Rfm9XDevice(IIODevice device, ISpiBus spiBus, IPin chipSelectPin, IPin resetPin, IPin interruptPin) { // Chip select pin configuration ChipSelectGpioPin = device.CreateDigitalOutputPort(chipSelectPin, initialState: true); if (ChipSelectGpioPin == null) { Console.WriteLine("ChipSelectGpioPin == null"); } // Factory reset pin configuration IDigitalOutputPort resetGpioPin = device.CreateDigitalOutputPort(resetPin); if (resetGpioPin == null) { Console.WriteLine("resetGpioPin == null"); } resetGpioPin.State = false; Task.Delay(10); resetGpioPin.State = true; Task.Delay(10); // Interrupt pin for RX message & TX done notification InterruptGpioPin = device.CreateDigitalInputPort(interruptPin, InterruptMode.EdgeRising); InterruptGpioPin.Changed += InterruptGpioPin_ValueChanged; Rfm9XLoraModem = new SpiPeripheral(spiBus, ChipSelectGpioPin); if (Rfm9XLoraModem == null) { Console.WriteLine("Rfm9XLoraModem == null"); } } private void InterruptGpioPin_ValueChanged(object sender, DigitalInputPortEventArgs args) { byte irqFlags = this.RegisterReadByte(0x12); // RegIrqFlags byte numberOfBytes = 0; string messageText = ""; bool transmitDone = false; //Console.WriteLine(string.Format("RegIrqFlags:{0}", Convert.ToString(irqFlags, 2).PadLeft(8, '0'))); if ((irqFlags & 0b01000000) == 0b01000000) { //Console.WriteLine("Receive-Message"); byte currentFifoAddress = this.RegisterReadByte(0x10); // RegFifiRxCurrent this.RegisterWriteByte(0x0d, currentFifoAddress); // RegFifoAddrPtr numberOfBytes = this.RegisterReadByte(0x13); // RegRxNbBytes byte[] messageBytes = this.RegisterRead(0x00, numberOfBytes); // RegFifo messageText = UTF8Encoding.UTF8.GetString(messageBytes); } if ((irqFlags & 0b00001000) == 0b00001000) // TxDone { this.RegisterWriteByte(0x01, 0b10000101); // RegOpMode set LoRa & RxContinuous transmitDone = true; } this.RegisterWriteByte(0x40, 0b00000000); // RegDioMapping1 0b00000000 DI0 RxReady & TxReady this.RegisterWriteByte(0x12, 0xff);// RegIrqFlags if (numberOfBytes > 0) { Console.WriteLine("Received {0} byte message {1}", numberOfBytes, messageText); } if(transmitDone) { Console.WriteLine("Transmit-Done"); } } ... public class MeadowApp : App<F7Micro, MeadowApp> { private Rfm9XDevice rfm9XDevice; private byte NessageCount = Byte.MaxValue; public MeadowApp() { ISpiBus spiBus = Device.CreateSpiBus(500); if (spiBus == null) { Console.WriteLine("spiBus == null"); } rfm9XDevice = new Rfm9XDevice(Device, spiBus, Device.Pins.D09, Device.Pins.D11, Device.Pins.D10); // Put device into LoRa + Sleep mode rfm9XDevice.RegisterWriteByte(0x01, 0b10000000); // RegOpMode // Set the frequency to 915MHz byte[] frequencyWriteBytes = { 0xE4, 0xC0, 0x00 }; // RegFrMsb, RegFrMid, RegFrLsb rfm9XDevice.RegisterWrite(0x06, frequencyWriteBytes); rfm9XDevice.RegisterWriteByte(0x0F, 0x0); // RegFifoRxBaseAddress rfm9XDevice.RegisterWriteByte(0x09, 0b10000000); // RegPaConfig rfm9XDevice.RegisterWriteByte(0x01, 0b10000101); // RegOpMode set LoRa & RxContinuous while (true) { rfm9XDevice.RegisterWriteByte(0x0E, 0x0); // RegFifoTxBaseAddress // Set the Register Fifo address pointer rfm9XDevice.RegisterWriteByte(0x0D, 0x0); // RegFifoAddrPtr string messageText = "W10 IoT Core LoRa! " + NessageCount.ToString(); NessageCount -= 1; // load the message into the fifo byte[] messageBytes = UTF8Encoding.UTF8.GetBytes(messageText); rfm9XDevice.RegisterWrite(0x0, messageBytes); // RegFifo // Set the length of the message in the fifo rfm9XDevice.RegisterWriteByte(0x22, (byte)messageBytes.Length); // RegPayloadLength Console.WriteLine("Sending {0} bytes message {1}", messageBytes.Length, messageText); rfm9XDevice.RegisterWriteByte(0x40, 0b01000000); // RegDioMapping1 0b00000000 DI0 RxReady & TxReady rfm9XDevice.RegisterWriteByte(0x01, 0b10000011); // RegOpMode Debug.WriteLine("Sending {0} bytes message {1}", messageBytes.Length, messageText); Task.Delay(10000).Wait(); } }
The diagnostic output shows inbound and outbound messages (Arduino then Meadow diagnostics)
21:15:56.070 -> 0x1: 0x81 21:15:56.070 -> 0x2: 0x1A … 21:15:57.527 -> 0x7E: 0x0 21:15:57.527 -> 0x7F: 0x0 21:15:57.527 -> LoRa init succeeded. 21:15:58.101 -> Sending HeLoRa World! 0 21:16:06.958 -> Message: W10 IoT Core LoRa! 254 21:16:06.991 -> RSSI: -60 21:16:06.991 -> Snr: 9.50 21:16:06.991 -> 21:16:09.062 -> Sending HeLoRa World! 2 21:16:17.184 -> Message: W10 IoT Core LoRa! 253 21:16:17.218 -> RSSI: -61 21:16:17.218 -> Snr: 9.75 21:16:17.218 -> 21:16:19.876 -> Sending HeLoRa World! 4 21:16:21.946 -> Message: ⸮LoRaIoT1Maduino2at 65.3,ah 70,wsa 6,wsg 12,wd 167.25,r 0.00, 21:16:22.014 -> RSSI: -76 21:16:22.014 -> Snr: 9.50 21:16:22.014 -> 21:16:27.406 -> Message: W10 IoT Core LoRa! 252 21:16:27.429 -> RSSI: -60 21:16:27.429 -> Snr: 9.50 21:16:27.429 -> 21:16:30.153 -> Sending HeLoRa World! 6
'App.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'. 'App.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\BrynLewis\source\repos\RFM9X.Meadow\ReceiveTransmitInterrupt\bin\Debug\net472\App.exe'. Symbols loaded. 'App.exe' (CLR v4.0.30319: App.exe): Loaded 'C:\Users\BrynLewis\source\repos\RFM9X.Meadow\ReceiveTransmitInterrupt\bin\Debug\net472\Meadow.dll'. The program '[42104] App.exe: Program Trace' has exited with code 0 (0x0). The program '[42104] App.exe' has exited with code 0 (0x0). . . DirectRegisterAccess = True . . Sending 22 bytes message W10 IoT Core LoRa! 255 Transmit-Done Received 15 byte message HeLoRa World! 0 Sending 22 bytes message W10 IoT Core LoRa! 254 Transmit-Done Received 15 byte message HeLoRa World! 2 Sending 22 bytes message W10 IoT Core LoRa! 253 Transmit-Done Received 15 byte message HeLoRa World! 4 Received 61 byte message ???LoRaIoT1Maduino2at 65.3,ah 70,wsa 6,wsg 12,wd 167.25,r 0.00, Sending 22 bytes message W10 IoT Core LoRa! 252 Transmit-Done Received 15 byte message HeLoRa World! 6 Sending 22 bytes message W10 IoT Core LoRa! 251 Transmit-Done Received 15 byte message HeLoRa World! 8 Sending 22 bytes message W10 IoT Core LoRa! 250 Transmit-Done Received 16 byte message HeLoRa World! 10 Sending 22 bytes message W10 IoT Core LoRa! 249 Transmit-Done Received 16 byte message HeLoRa World! 12 Received 40 byte message ???LoRaIoT1#)#???c???h 55,t 24.9,s 3,v 4.01 Sending 22 bytes message W10 IoT Core LoRa! 248 Transmit-Done Received 16 byte message HeLoRa World! 14 Sending 22 bytes message W10 IoT Core LoRa! 247 Transmit-Done Received 16 byte message ???LoRaIoT1Maduino Sending 22 bytes message W10 IoT Core LoRa! 246 Transmit-Done Received 16 byte message HeLoRa World! 18 Sending 22 bytes message W10 IoT Core LoRa! 245 Transmit-Done Received 16 byte message HeLoRa World! 20 Sending 22 bytes message W10 IoT Core LoRa! 244 Transmit-Done Received 16 byte message HeLoRa World! 22 Sending 22 bytes message W10 IoT Core LoRa! 243 Transmit-Done Received 16 byte message HeLoRa World! 24 Sending 22 bytes message W10 IoT Core LoRa! 242 Transmit-Done
The RegIrqFlags 01011000 indicates the RxDone, ValidHeader, and TxDone flags were set which was what I was expecting. Note the interference, the 46 byte packet
Next step is some refactoring to extract the register access code and merging with my Windows 10 IoT Core RMF9X library code base.