RFM95/96/97/98 shield library Part1

Register Read

Over the last couple of weeks I have been working on a Windows 10 IoT Core C# library for my Dragino LoRa GPS hat for Raspberry PI. I initially started with the Dragino.LoRa library but after some experimentation and hacking I decided to write my own library (which is usually not a good idea).


I wanted a lightweight LoRa only library (hopefully possible to backport to .NetMF) which didn’t try to hide how the Semtech 1276 chip functioned, and in the future could be configured to work with other vendors’ shields (dragino, electronictricks, elecrow, m2m).

I’m also working on an RFM69 Raspberry PI shield based on an electronictricks PCB populated with a RFM69HCW so I figured the experience of building a library would be useful.

The first step was to build a basic universal windows platform (UWP) background task to confirm that I could reliably communicate with the shield over SPI bus by reading a single register value (RegVersion the silicon version specified in the vendor datasheet).

// Copyright (c) July 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,
// See the License for the specific language governing permissions and
// limitations under the License.
namespace devMobile.IoT.Rfm9x.RegisterRead
   using System;
   using System.Diagnostics;
   using System.Threading.Tasks;
   using Windows.ApplicationModel.Background;
   using Windows.Devices.Gpio;
   using Windows.Devices.Spi;

   public sealed class StartupTask : IBackgroundTask
      private const int ChipSelectLine = 25;
      private SpiDevice rfm9XLoraModem;

      public void Run(IBackgroundTaskInstance taskInstance)
         // Have to setup the SPI bus with custom Chip Select line rather than std CE0/CE1
         SpiController spiController = SpiController.GetDefaultAsync().AsTask().GetAwaiter().GetResult();
         var settings = new SpiConnectionSettings(0)
            ClockFrequency = 500000,
            Mode = SpiMode.Mode0,

         GpioController gpioController = GpioController.GetDefault();
         GpioPin chipSelectGpioPin = gpioController.OpenPin(ChipSelectLine);

         rfm9XLoraModem = spiController.GetDevice(settings);

         while (true)
            byte[] writeBuffer = new byte[]{ 0x42 }; // RegVersion
            byte[] readBuffer = new byte[1];


            Debug.WriteLine("RegVersion {0:x2}", readBuffer[0]);


The dragino shield has the chip select (also know as slave select) line connected to pin 25 rather than the usual CS0 (pin 24) & CS1 (pin 26) so it has to be manually strobed.

'backgroundTaskHost.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\RegisterRead-uwpVS.Debug_ARM.Bryn.Lewis\System.Diagnostics.Debug.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
RegVersion 12
RegVersion 12

Next step was to dump all the registers of the HopeRF module.

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 )

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.