RegisterManager Refactor
I had been meaning to refactor the code for accessing the registers of the RFM69CW/RFM69HCW module (based on the Semtech SX1231/SX1231H) registers for a while.

There is now a lot less code in the startup.cs file and the code for configuring the RFM69 is more obvious
/* Copyright ® 2019 July devMobile Software, All Rights Reserved MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE */ namespace devMobile.IoT.Rfm69Hcw.RefactorRegisterManager { using System; using System.Diagnostics; using System.Text; using System.Threading.Tasks; using Windows.ApplicationModel.Background; using Windows.Devices.Gpio; sealed class Rfm69HcwDevice { private GpioPin InterruptGpioPin = null; public RegisterManager RegisterManager = null; // Future refactor this will be made private public Rfm69HcwDevice(ChipSelectPin chipSelectPin, int resetPin, int interruptPin) { RegisterManager = new RegisterManager(chipSelectPin); // Factory reset pin configuration GpioController gpioController = GpioController.GetDefault(); GpioPin resetGpioPin = gpioController.OpenPin(resetPin); resetGpioPin.SetDriveMode(GpioPinDriveMode.Output); resetGpioPin.Write(GpioPinValue.High); Task.Delay(100); resetGpioPin.Write(GpioPinValue.Low); Task.Delay(10); // Interrupt pin for RX message & TX done notification InterruptGpioPin = gpioController.OpenPin(interruptPin); resetGpioPin.SetDriveMode(GpioPinDriveMode.Input); InterruptGpioPin.ValueChanged += InterruptGpioPin_ValueChanged; } private void InterruptGpioPin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs args) { if (args.Edge != GpioPinEdge.RisingEdge) { return; } byte irqFlags = RegisterManager.ReadByte(0x28); // RegIrqFlags2 Debug.WriteLine("{0:HH:mm:ss.fff} RegIrqFlags {1}", DateTime.Now, Convert.ToString((byte)irqFlags, 2).PadLeft(8, '0')); if ((irqFlags & 0b00000100) == 0b00000100) // PayLoadReady set { // Read the length of the buffer byte numberOfBytes = RegisterManager.ReadByte(0x0); // Allocate buffer for message byte[] messageBytes = new byte[numberOfBytes]; for (int i = 0; i < numberOfBytes; i++) { messageBytes[i] = RegisterManager.ReadByte(0x00); // RegFifo } string messageText = UTF8Encoding.UTF8.GetString(messageBytes); Debug.WriteLine("{0:HH:mm:ss} Received {1} byte message {2}", DateTime.Now, messageBytes.Length, messageText); } if ((irqFlags & 0b00001000) == 0b00001000) // PacketSent set { RegisterManager.WriteByte(0x01, 0b00010000); // RegOpMode set ReceiveMode Debug.WriteLine("{0:HH:mm:ss.fff} Transmit-Done", DateTime.Now); } } public void RegisterDump() { RegisterManager.Dump(0x0, 0x40); } } public sealed class StartupTask : IBackgroundTask { private const int ResetPin = 25; private const int InterruptPin = 22; private Rfm69HcwDevice rfm69Device = new Rfm69HcwDevice(ChipSelectPin.CS1, ResetPin, InterruptPin); const double RH_RF6M9HCW_FXOSC = 32000000.0; const double RH_RFM69HCW_FSTEP = RH_RF6M9HCW_FXOSC / 524288.0; public void Run(IBackgroundTaskInstance taskInstance) { //rfm69Device.RegisterDump(); // regOpMode standby rfm69Device.RegisterManager.WriteByte(0x01, 0b00000100); // BitRate MSB/LSB rfm69Device.RegisterManager.WriteByte(0x03, 0x34); rfm69Device.RegisterManager.WriteByte(0x04, 0x00); // Frequency deviation rfm69Device.RegisterManager.WriteByte(0x05, 0x02); rfm69Device.RegisterManager.WriteByte(0x06, 0x3d); // Calculate the frequency accoring to the datasheett byte[] bytes = BitConverter.GetBytes((uint)(915000000.0 / RH_RFM69HCW_FSTEP)); Debug.WriteLine("Byte Hex 0x{0:x2} 0x{1:x2} 0x{2:x2} 0x{3:x2}", bytes[0], bytes[1], bytes[2], bytes[3]); rfm69Device.RegisterManager.WriteByte(0x07, bytes[2]); rfm69Device.RegisterManager.WriteByte(0x08, bytes[1]); rfm69Device.RegisterManager.WriteByte(0x09, bytes[0]); // RegRxBW rfm69Device.RegisterManager.WriteByte(0x19, 0x2a); // RegDioMapping1 rfm69Device.RegisterManager.WriteByte(0x26, 0x01); // Setup preamble length to 16 (default is 3) RegPreambleMsb RegPreambleLsb rfm69Device.RegisterManager.WriteByte(0x2C, 0x0); rfm69Device.RegisterManager.WriteByte(0x2D, 0x10); // RegSyncConfig Set the Sync length and byte values SyncOn + 3 custom sync bytes rfm69Device.RegisterManager.WriteByte(0x2e, 0x90); // RegSyncValues1 thru RegSyncValues3 rfm69Device.RegisterManager.WriteByte(0x2f, 0xAA); rfm69Device.RegisterManager.WriteByte(0x30, 0x2D); rfm69Device.RegisterManager.WriteByte(0x31, 0xD4); // RegPacketConfig1 Variable length with CRC on rfm69Device.RegisterManager.WriteByte(0x37, 0x90); rfm69Device.RegisterDump(); while (true) { // Standby mode while loading message into FIFO rfm69Device.RegisterManager.WriteByte(0x01, 0b00000100); byte[] messageBuffer = UTF8Encoding.UTF8.GetBytes("hello world " + DateTime.Now.ToLongTimeString()); rfm69Device.RegisterManager.WriteByte(0x0, (byte)messageBuffer.Length); rfm69Device.RegisterManager.Write(0x0, messageBuffer); // Transmit mode once FIFO loaded rfm69Device.RegisterManager.WriteByte(0x01, 0b00001100); Debug.WriteLine("{0:HH:mm:ss.fff} Send-Done", DateTime.Now); Task.Delay(5000).Wait(); } } } }
I’ll modify the constructor reset pin support to see if I can get the Seegel Systeme hat working.
Register dump Register 0x00 - Value 0X00 - Bits 00000000 Register 0x01 - Value 0X04 - Bits 00000100 Register 0x02 - Value 0X00 - Bits 00000000 Register 0x03 - Value 0X34 - Bits 00110100 … Register 0x3e - Value 0X00 - Bits 00000000 Register 0x3f - Value 0X00 - Bits 00000000 Register 0x40 - Value 0X00 - Bits 00000000 19:58:52.828 Send-Done 19:58:53.022 RegIrqFlags 00001000 19:58:53.036 Transmit-Done 19:58:54.188 RegIrqFlags 01000110 19:58:54 Received 14 byte message Hello world:1 The thread 0xa10 has exited with code 0 (0x0). The thread 0xf90 has exited with code 0 (0x0). 19:58:57.652 RegIrqFlags 01000110 19:58:57 Received 14 byte message Hello world:2 19:58:57.892 Send-Done 19:58:58.039 RegIrqFlags 00001000 19:58:58.053 Transmit-Done 19:59:01.115 RegIrqFlags 01000110 19:59:01 Received 14 byte message Hello world:3 19:59:02.936 Send-Done 19:59:03.083 RegIrqFlags 00001000 19:59:03.096 Transmit-Done 19:59:04.577 RegIrqFlags 01000110 19:59:04 Received 14 byte message Hello world:4 The thread 0xa5c has exited with code 0 (0x0). 19:59:08.001 Send-Done 19:59:08.122 RegIrqFlags 01001000 19:59:08.139 Transmit-Done 19:59:11.504 RegIrqFlags 01000110 19:59:11 Received 14 byte message Hello world:6 The thread 0xb18 has exited with code 0 (0x0). 19:59:13.079 Send-Done 19:59:13.226 RegIrqFlags 00001000 19:59:13.240 Transmit-Done 19:59:14.966 RegIrqFlags 01000110 19:59:14 Received 14 byte message Hello world:7
Based how my rate of progress improved when I did this on the RFM9X library I really should have done this much earlier.