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.