Re-reading the SX1231 datasheet

While trying to debug a deadlock in my RFM69 library I noticed in the logging that I was getting a receive interrupt while putting bytes in the FIFO for transmission.

Register 0x49 - Value 0X00 - Bits 00000000
Register 0x4a - Value 0X00 - Bits 00000000
Register 0x4b - Value 0X00 - Bits 00000000
Register 0x4c - Value 0X00 - Bits 00000000
Register 0x4d - Value 0X00 - Bits 00000000
...
22:58:47.192 Received To 0X22 a 33 byte message hello world RFM69-915-02 10-58-47 CRC Ok True
The thread 0x6a8 has exited with code 0 (0x0).
22:58:48.334 Send-hello world RFM69-915-01 10-58-48
22:58:48.351 Send-Done
22:58:48.388 Received To 0X22 a 33 byte message hello world RFM69-915-02 10-58-52 CRC Ok True
22:58:48.462 Transmit-Done
The thread 0xde4 has exited with code 0 (0x0).
22:58:53.427 Send-hello world RFM69-915-01 10-58-53
22:58:53.445 Send-Done
22:58:53.556 Transmit-Done
22:58:57.382 Received To 0X22 a 33 byte message hello world RFM69-915-02 10-58-57 CRC Ok True
The thread 0x17c has exited with code 0 (0x0).

After re-reading the RFM69CW/RFM69HCW module datasheet (based on the Semtech SX1231/SX1231H) I realised my code for loading the FIFO could be more efficient.

SX1231 Register map FIFO

Based on the timing diagram I could remove the loop which loads bytes in the FIFO for transmission.

The changes in my RFM69 library weren’t huge but I think they are also applicable to the RFM9X LoRa library as well

public void SendMessage(byte address, byte[] messageBytes)
{
#region Guard conditions
#endregion

	lock (Rfm9XRegFifoLock)
	{
		SetMode(RegOpModeMode.StandBy);

		if (PacketFormat == RegPacketConfig1PacketFormat.VariableLength)
		{
			RegisterManager.WriteByte((byte)Registers.RegFifo, (byte)(messageBytes.Length + 1)); // Additional byte for address 
		}

		RegisterManager.WriteByte((byte)Registers.RegFifo, address);

		foreach (byte b in messageBytes)
		{
				this.RegisterManager.WriteByte((byte)Registers.RegFifo, b);
		}

		SetMode(RegOpModeMode.Transmit);
	}
}

After modifications

public void SendMessage(byte address, byte[] messageBytes)
{
#region Guard conditions
...
#endregion

	SetDioPinMapping(dio0Mapping: Dio0Mapping.TransmitPacketSent);

	lock (Rfm9XRegFifoLock)
	{
		SetMode(RegOpModeMode.StandBy);

		if (PacketFormat == RegPacketConfig1PacketFormat.VariableLength)
		{
			RegisterManager.WriteByte((byte)Registers.RegFifo, (byte)(messageBytes.Length + 1)); // Additional byte for address 
		}

		RegisterManager.WriteByte((byte)Registers.RegFifo, address);

		this.RegisterManager.Write((byte)Registers.RegFifo, messageBytes);
	}
	SetMode(RegOpModeMode.Transmit);
}

After stress testing with several client devices this appears to have reduced the scope of a receive interrupt to occur while a packet was being loaded into the FIFO for transmission. I now need to dig deeper into the timing around entering different operational modes and selectively enabling event interrupts.

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.