Why are Transmit Interrupts broken?
I had read about restrictions for interrupts pins e.g. PA1 & PB1 can’t be used at the same time, but PA1 and PB2 can, which got me thinking…
In my dragino shield based setup Arduino D2(PA1) is the interrupt(IRQ) line and Arduino D10(PB1) is chip select (CS) so I changed the pins with jumper wires just incase.

I tried several different configurations of CS and IRQ pins and none worked.
On other embedded .net platforms I have written Serial Peripheral Interface(SPI) based drivers for (e.g. Wilderness Labs Meadow and the nanoFramework) there had been issues with the use of device.Write vs. device. TransferFullDuplex (or its equivalent).
The RegisterWriteByte method in the event handler appeared to be the problem so I tried modifying it.
public void RegisterWriteByte(byte address, byte value)
{
byte[] writeBuffer = new byte[] { address |= RegisterAddressWriteMask, value };
Debug.Assert(rfm9XLoraModem != null);
rfm9XLoraModem.Write(writeBuffer);
}
Became
public void RegisterWriteByte(byte address, byte value)
{
byte[] writeBuffer = new byte[] { address |= RegisterAddressWriteMask, value };
byte[] readBuffer = new byte[2];
Debug.Assert(rfm9XLoraModem != null);
rfm9XLoraModem.TransferFullDuplex(writeBuffer, readBuffer);
}
In the diagnostic output I could see confirmations arriving
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Sending 13 bytes message Hello LoRa 1!
RegIrqFlags 0X08
Transmit-Done
Sending 13 bytes message Hello LoRa 2!
RegIrqFlags 0X08
Transmit-Done
Sending 13 bytes message Hello LoRa 3!
RegIrqFlags 0X08
Transmit-Done
Sending 13 bytes message Hello LoRa 4!
RegIrqFlags 0X08
Transmit-Done
Sending 13 bytes message Hello LoRa 5!
RegIrqFlags 0X08
Transmit-Done
Sending 13 bytes message Hello LoRa 6!
RegIrqFlags 0X08
Transmit-Done
This was clue it might be a timing problem, so I took a closer look at how the SPI port was configured. After some experimentation I found that by adding a small ChipSelectHoldTime the .Write statements worked.
When I went back and checked there had also been some timing “tweaks” required to get my .Net Microframework LoRa library to work reliably.
public Rfm9XDevice(string spiPortName, int chipSelectPin, int resetPin, int interruptPin)
{
GpioController gpioController = GpioController.GetDefault();
GpioPin chipSelectGpio = gpioController.OpenPin(chipSelectPin);
var settings = new SpiConnectionSettings()
{
ChipSelectType = SpiChipSelectType.Gpio,
ChipSelectLine = chipSelectGpio,
Mode = SpiMode.Mode0,
ClockFrequency = 500000,
ChipSelectActiveState = false,
//ChipSelectHoldTime = new TimeSpan(50),
//ChipSelectHoldTime = new TimeSpan(25),
//ChipSelectHoldTime = new TimeSpan(10),
ChipSelectHoldTime = new TimeSpan(5),
//ChipSelectHoldTime = new TimeSpan(1),
};
SpiController spiController = SpiController.FromName(spiPortName);
rfm9XLoraModem = spiController.GetDevice(settings);
// Factory reset pin configuration
GpioPin resetGpioPin = gpioController.OpenPin(resetPin);
resetGpioPin.SetDriveMode(GpioPinDriveMode.Output);
resetGpioPin.Write(GpioPinValue.Low);
Thread.Sleep(10);
resetGpioPin.Write(GpioPinValue.High);
Thread.Sleep(10);
// Interrupt pin for RX message & TX done notification
InterruptGpioPin = gpioController.OpenPin(interruptPin);
InterruptGpioPin.SetDriveMode(GpioPinDriveMode.Input);
InterruptGpioPin.ValueChanged += InterruptGpioPin_ValueChanged;
}
In the diagnostic output I could see confirmations arriving
...
Sending 16 bytes message Hello LoRa 1115!
RegIrqFlags 0X08
Transmit-Done
Sending 16 bytes message Hello LoRa 1116!
RegIrqFlags 0X08
Transmit-Done
Sending 16 bytes message Hello LoRa 1117!
RegIrqFlags 0X08
Transmit-Done
Sending 16 bytes message Hello LoRa 1118!
RegIrqFlags 0X08
Transmit-Done
Sending 16 bytes message Hello LoRa 1119!
RegIrqFlags 0X08
Transmit-Done
Sending 16 bytes message Hello LoRa 1120!
RegIrqFlags 0X08
Transmit-Done
Sending 16 bytes message Hello LoRa 1121!
RegIrqFlags 0X08
Transmit-Done
Sending 16 bytes message Hello LoRa 1122!
RegIrqFlags 0X08
The program '[13] TinyCLR application: Managed' has exited with code 0 (0x0).
After some soak testing it looks like the ChipSelectHoldTime modification works pretty reliably but I will need watch for issues.
EDIT: After a long walk I have updated the code to use TransferFullDuplex rather than add a ChipSelectHoldTime.
Pingback: TinyCLR OS V2 RC1 LoRa library Part4 | devMobile's blog