.Net Meadow RFM95/96/97/98 LoRa library Part6

Receive Interrupt

This proof of concept (PoC) was to confirm I could configure the Semtech 127X then handle the received messages using a Meadow event handler. The event handler code is based on the implementation in my Windows IoT 10 Core library.

I had added a few Console.WriteLine statements (Debug.Print currently doesn’t work Dec 2019) so I could see what was going on. But, using Console.WriteLine in the event handler caused me some problems which I had to debug. The irqFlags bit mask indicated there was a message in the FIFO but it wasn’t displayed and the interrupt mask wasn’t getting reset. As a temporary fix I refactored the code so the Console.WriteLine was the last statement in the EventHandler(which may cause other issues).

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 = "";

         //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);
         }

         this.RegisterWriteByte(0x12, 0xff);// RegIrqFlags
         if (numberOfBytes > 0)
         {
            Console.WriteLine("Received {0} byte message {1}", numberOfBytes, messageText);
         }
      }
...
public class MeadowApp : App
{
private Rfm9XDevice rfm9XDevice;
  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(0x40, 0b00000000); // RegDioMapping1 0b00000000 DI0 RxReady & TxReady

     rfm9XDevice.RegisterWriteByte(0x01, 0b10000101); // RegOpMode set LoRa & RxContinuous

     rfm9XDevice.RegisterDump();

     Console.WriteLine("Receive-Wait");
     Task.Delay(-1).Wait();
  }
}

The output in the output debug window looked like this

'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\ReceiveInterrupt\bin\Debug\net472\App.exe'. Symbols loaded.
'App.exe' (CLR v4.0.30319: App.exe): Loaded 'C:\Users\BrynLewis\source\repos\RFM9X.Meadow\ReceiveInterrupt\bin\Debug\net472\Meadow.dll'. 
The program '[40348] App.exe: Program Trace' has exited with code 0 (0x0).
The program '[40348] App.exe' has exited with code 0 (0x0).
.
.
DirectRegisterAccess = True
.
.
Register dump
Register 0x00 - Value 0X6c - Bits 01101100
…
Register 0x42 - Value 0X12 - Bits 00010010
Receive-Wait
Received 15 byte message HeLoRa World! 0
Received 59 byte message ???LoRaIoT1Maduino2at 57.2,ah 67,wsa 1,wsg 3,wd 56.63,r 0.00,
Received 15 byte message HeLoRa World! 2
Received 15 byte message HeLoRa World! 4
Received 15 byte message HeLoRa World! 6
Received 15 byte message HeLoRa World! 8
Received 16 byte message HeLoRa World! 10

Next steps will be wiring up the transmit done interrupt, then building a full featured client based on my Windows 10 IoT Core library.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.