.Net MicroFramework LoRa library Part9

Receive and Transmit Interrupts

For the second to last development iteration of my RFM9X LoRa NetMF library client I have got the interrupt handler working for transmitting and receiving messages. My code sends a message every 10 seconds then goes back to waiting in receive mode .

//---------------------------------------------------------------------------------
// Copyright (c) August 2018, devMobile Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//---------------------------------------------------------------------------------
namespace devMobile.IoT.NetMF.Rfm9X.ReceiveTransmitInterrupt
{
   using System;
   using System.Text;
   using System.Threading;
   using Microsoft.SPOT;
   using Microsoft.SPOT.Hardware;
   using SecretLabs.NETMF.Hardware.Netduino;

   public sealed class Rfm9XDevice
   {
      private const byte RegisterAddressReadMask = 0X7f;
      private const byte RegisterAddressWriteMask = 0x80;

      private SPI Rfm9XLoraModem = null;
      private OutputPort ResetGpioPin = null;
      private InterruptPort InterruptPin = null;

      public Rfm9XDevice(Cpu.Pin chipSelect, Cpu.Pin resetPin, Cpu.Pin interruptPin)
      {
         // Factory reset pin configuration
         ResetGpioPin = new OutputPort(Pins.GPIO_PIN_D9, true);
         ResetGpioPin.Write(false);
         Thread.Sleep(10);
         ResetGpioPin.Write(true);
         Thread.Sleep(10);

         this.Rfm9XLoraModem = new SPI(new SPI.Configuration(chipSelect, false, 0, 0, false, false, 2000, SPI.SPI_module.SPI1));

         InterruptPin = new InterruptPort(interruptPin, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeHigh);

         InterruptPin.OnInterrupt += InterruptPin_OnInterrupt;

         Thread.Sleep(100);
      }

      public Rfm9XDevice(Cpu.Pin chipSelect, Cpu.Pin reset)
      {
         // Factory reset pin configuration
         ResetGpioPin = new OutputPort(Pins.GPIO_PIN_D9, true);
         ResetGpioPin.Write(false);
         Thread.Sleep(10);
         ResetGpioPin.Write(true);
         Thread.Sleep(10);

         this.Rfm9XLoraModem = new SPI(new SPI.Configuration(chipSelect, false, 0, 0, false, false, 2000, SPI.SPI_module.SPI1));

         Thread.Sleep(100);
      }

      public Byte RegisterReadByte(byte registerAddress)
      {
         byte[] writeBuffer = new byte[] { registerAddress };
         byte[] readBuffer = new byte[1];
         Debug.Assert(Rfm9XLoraModem != null);

         Rfm9XLoraModem.WriteRead(writeBuffer, readBuffer, 1);

         return readBuffer[0];
      }

      public ushort RegisterReadWord(byte address)
      {
         byte[] writeBuffer = new byte[] { address &= RegisterAddressReadMask };
         byte[] readBuffer = new byte[2];
         Debug.Assert(Rfm9XLoraModem != null);

         readBuffer[0] = RegisterReadByte(address);
         readBuffer[1] = RegisterReadByte(address += 1);

         return (ushort)(readBuffer[1] + (readBuffer[0] << 8));
      }

      public byte[] RegisterRead(byte address, int length)
      {
         byte[] writeBuffer = new byte[] { address &= RegisterAddressReadMask };
         byte[] readBuffer = new byte[length];
         Debug.Assert(Rfm9XLoraModem != null);

         for (byte index = 0; index < length; index++)
         {
            readBuffer[index] = RegisterReadByte(address += 1);
         }

         return readBuffer;
      }

      public void RegisterWriteByte(byte address, byte value)
      {
         byte[] writeBuffer = new byte[] { address |= RegisterAddressWriteMask, value };
         Debug.Assert(Rfm9XLoraModem != null);

         Rfm9XLoraModem.Write(writeBuffer);
      }

      public void RegisterWriteWord(byte address, ushort value)
      {
         byte[] valueBytes = BitConverter.GetBytes(value);
         byte[] writeBuffer = new byte[] { address |= RegisterAddressWriteMask, valueBytes[0], valueBytes[1] };
         Debug.Assert(Rfm9XLoraModem != null);

         Rfm9XLoraModem.Write(writeBuffer);
      }

      public void RegisterWrite(byte address, byte[] bytes)
      {
         byte[] writeBuffer = new byte[1 + bytes.Length];
         Debug.Assert(Rfm9XLoraModem != null);

         Array.Copy(bytes, 0, writeBuffer, 1, bytes.Length);
         writeBuffer[0] = address |= RegisterAddressWriteMask;

         Rfm9XLoraModem.Write(writeBuffer);
      }

      public void RegisterDump()
      {
         Debug.Print("---Registers 0x00 thru 0x42---");
         for (byte registerIndex = 0; registerIndex  4];

         // Mask off the upper 4 bits to get the rest of it.
         hexString += hexChars[singlebyte & 0x0F];

         return hexString;
      }

      private static string WordToHexString(ushort singleword)
      {
         string hexString = string.Empty;

         byte[] bytes = BitConverter.GetBytes(singleword);

         hexString += ByteToHexString(bytes[1]);

         hexString += ByteToHexString(bytes[0]);

         return hexString;
      }

      public class Program
      {
         public static void Main()
         {
            Rfm9XDevice rfm9XDevice = new Rfm9XDevice(Pins.GPIO_PIN_D10, Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D2);
            byte MessageCount = Byte.MinValue;

            // Put device into LoRa + Sleep mode
            rfm9XDevice.RegisterWriteByte(0x01, 0x80); // RegOpMode 

            // Set the frequency to 915MHz
            byte[] frequencyWriteBytes = { 0xE4, 0xC0, 0x00 }; // RegFrMsb, RegFrMid, RegFrLsb
            rfm9XDevice.RegisterWrite(0x06, frequencyWriteBytes);

            rfm9XDevice.RegisterWriteByte(0x0F, 0x0); // RegFifoRxBaseAddress 

            // More power - PA_BOOST
            rfm9XDevice.RegisterWriteByte(0x09, 0x80); // RegPaConfig

            //rfm9XDevice.RegisterWriteByte(0x40, 0x0);

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

            while (true)
            {
               rfm9XDevice.RegisterWriteByte(0x0E, 0x0); // RegFifoTxBaseAddress 

               // Set the Register Fifo address pointer
               rfm9XDevice.RegisterWriteByte(0x0D, 0x0); // RegFifoAddrPtr 

               string messageText = "Hello NetMF LoRa! " + MessageCount.ToString() ;
               MessageCount += 1;

               // load the message into the fifo
               byte[] messageBytes = UTF8Encoding.UTF8.GetBytes(messageText);
               foreach (byte b in messageBytes)
               {
                  rfm9XDevice.RegisterWriteByte(0x0, b); // RegFifo
               }

               // Set the length of the message in the fifo
               rfm9XDevice.RegisterWriteByte(0x22, (byte)messageBytes.Length); // RegPayloadLength

               rfm9XDevice.RegisterWriteByte(0x40, 0x40); // RegDioMapping1 

               /// Set the mode to LoRa + Transmit
               rfm9XDevice.RegisterWriteByte(0x01, 0x83); // RegOpMode
               Debug.Print("Sending " + messageBytes.Length + " bytes message " + messageText);

               Thread.Sleep(10000);
            }
         }
      }
   }
}

On the Netduino3 device messages were being sent and received

The thread '' (0x2) has exited with code 0 (0x0).
Sending 19 bytes message Hello NetMF LoRa! 0
RegIrqFlags 08
Transmit-Done
Sending 19 bytes message Hello NetMF LoRa! 1
RegIrqFlags 08
Transmit-Done
Sending 19 bytes message Hello NetMF LoRa! 2
RegIrqFlags 08
Transmit-Done
Sending 19 bytes message Hello NetMF LoRa! 3
RegIrqFlags 08
Transmit-Done
RegIrqFlags 50
Receive-Message
Received 15 byte message HeLoRa World! 0
RegIrqFlags 50
Receive-Message
Received 15 byte message HeLoRa World! 2
Sending 19 bytes message Hello NetMF LoRa! 4
RegIrqFlags 08
Transmit-Done
RegIrqFlags 50
Receive-Message

On my Windows 10 Core device I could see messages arriving

RegIrqFlags 01010000
RX-Done
Received 19 byte message Hello NetMF LoRa! 1
The thread 0x168 has exited with code 0 (0x0).
RegIrqFlags 01010000
RX-Done
Received 19 byte message Hello NetMF LoRa! 2
The thread 0x8 has exited with code 0 (0x0).
RegIrqFlags 01010000
RX-Done

This library is going to be quite a bit smaller/lighter than my Windows 10 IoT Core one so the next so next step event handlers and refactoring.

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