While doing some stress testing I noticed an odd message go past in the Visual Studio output window. I had multiple devices sending addressed messages (both individual and broadcast) to the Adafruit RFM69 HCW Radio Bonnet, on my Windows 10 IoT Core device while it was sending a message every 5 seconds.
Received From 153 a 13 byte message Hello World:7 18:43:56.544 RegIrqFlags2 01100110 18:43:56.558 RegIrqFlags1 11011001 18:43:56.575 Address 0X66 01100110 Received From 102 a 15 byte message Hello World:162 The thread 0x254 has exited with code 0 (0x0). 18:43:57.699 Send-hello world 6:43:57 PM 18:43:57.699 RegIrqFlags2 01100110 18:43:57.731 RegIrqFlags1 10000000 18:43:57.747 Address 0X66 01100110 18:43:57.765 Send-Done Received From 102 a 15 byte message Hello Woooooooo 18:43:57.987 RegIrqFlags2 00001000 18:43:58.003 RegIrqFlags1 10110000 18:43:58.017 Transmit-Done Transmit-Done 18:43:58.825 RegIrqFlags2 01100110 18:43:58.838 RegIrqFlags1 11011001 18:43:58.857 Address 0X66 01100110 Received From 102 a 15 byte message Hello World:164 18:43:59.966 RegIrqFlags2 01100110 18:43:59.979 RegIrqFlags1 11011001 18:43:59.998 Address 0X66 01100110
The odd thing was that the RegIrqFlags2 CrcOk (bit 1) was set but the message was still corrupt.

After looking at the code I think the problem was the reading of the received message bytes from the device FIFO and the writing of bytes of message to be transmitted into the device FIFO overlapped. To stop this occurring again I have added code to synchronise access (using a Lock) to the FIFO.
private readonly Object Rfm9XRegFifoLock = new object(); ... private void ProcessPayloadReady(RegIrqFlags1 irqFlags1, RegIrqFlags2 irqFlags2) { byte? address = null; byte numberOfBytes; byte[] messageBytes; lock (Rfm9XRegFifoLock) { // Read the length of the buffer if variable length packets if (PacketFormat == RegPacketConfig1PacketFormat.VariableLength) { numberOfBytes = RegisterManager.ReadByte((byte)Rfm69HcwDevice.Registers.RegFifo); } else { numberOfBytes = PayloadLength; } // Remove the address from start of the payload if (AddressingEnabled) { address = RegisterManager.ReadByte((byte)Rfm69HcwDevice.Registers.RegFifo); Debug.WriteLine("{0:HH:mm:ss.fff} Address 0X{1:X2} {2}", DateTime.Now, address, Convert.ToString((byte)address, 2).PadLeft(8, '0')); numberOfBytes--; } // Allocate a buffer for the payload and read characters from the Fifo messageBytes = new byte[numberOfBytes]; for (int i = 0; i < numberOfBytes; i++) { messageBytes[i] = RegisterManager.ReadByte((byte)Rfm69HcwDevice.Registers.RegFifo); } } ... public void SendMessage(byte[] messageBytes) { #region Guard conditions #endregion lock (Rfm9XRegFifoLock) { SetMode(RegOpModeMode.StandBy); if (PacketFormat == RegPacketConfig1PacketFormat.VariableLength) { RegisterManager.WriteByte((byte)Registers.RegFifo, (byte)messageBytes.Length); } foreach (byte b in messageBytes) { this.RegisterManager.WriteByte((byte)Registers.RegFifo, b); } SetMode(RegOpModeMode.Transmit); } }
The code has been running for a day without any corrupted messages so the lock appears to be working. I can most probably reduce the duration which I hold the lock for but that will require some more stress testing.