Recently I've been working to improve the Arduino SPI library, to better support multiple SPI devices with different settings, and SPI devices requiring interrupts.
Today I discovered a new problem while testing the HopeRF RFM69 wireless module.
Click "Read more" for details and the workaround I found....
First, this article is meant to publically document what I've found and invite conversation with anyone else who might have experienced similar issues. It's very difficult to know if this problem is caused by buggy software, faulty hardware, or radio interference. Please comment below, or on this forum thread, if you have any insight or opinions.
In a nutshell, I've been working on new Arduino SPI library functions to allow SPI devices with different settings and usage of attachInterrupt, where the interrupt routine uses SPI.transfer(), to hopefully work together. With the SPI library from Arduino 1.0.5 & 1.5.7, usage from within an interrupt routine can occur while the main program is using SPI.transfer with another device's chip select active, and of course each device might need very different SPI settings.
As part of this testing, I've been working with the Ethernet library using a WIZ820io module and the RadioHead library with a RFM69W wireless module. The Ethernet library used with Teensy has a patch to allow either W5100 or W5200 chips, so the normally unsupported WIZ820io works fine. In my testing, I've patched both libraries to use the new SPI.beginTransaction() and SPI.endTransaction() functions, and RadioHead uses SPI.usingInterrupt(), to let those 2 functions know which interrupt needs to be masked while the Ethernet library is using SPI.
So a caveat is that I've working with 3 patched libraries. There's a lot of uncertainty here.
My test program uses a Teensy 3.1 to send a request to another board running RadioHead's "rf69_server" example, and also a HTTP request to fetch a web page. Then it tries to receive both of them. I'll attach the code below.
The RFM69 is unable to receive while the Ethernet library polls the WIZ820io. I spent hours carefully checking the waveforms on my oscilloscope. At first I thought this must be a bug in my code. But it's easy to see the 2 chip selects never assert simultaeously, as they might if SPI.beginTransaction didn't mask the interrupt while Ethetnet uses SPI. It's easy to see the other device is sending the reply, because its LED blinks when it transmits on its RFM69. They're sitting right next to each other on my desk (the first photo) and with a line uncommented in the code to cause the Ethernet polling to wait 20 ms, the radio reply is always received correctly.
Finally, in an act of desparation, I build this little hack to force the SCK signal low at the RFM69 when its NSS chip select is idle (high).
Amazingly, this works! It allows the RFM69 to receive, while the Ethenet module is polling.
I'm still not ready to conclude the RFM69 has a hardware bug, where activity at the SCK input, which ought to be ignored while NSS is high, might be causing it to miss incoming radio data.
It's entirely possible the communication could be creating radio interference. My little adaptor board has a ground plane between the RFM69 and the digital signals (I'm a little paranoid of messing up RF stuff).
It's also possible my software has a bug, even though the waveforms appear to be fine on a scope. I might have missed something.
Anyway, here's a quick schematic for that little circuit.
I also created a new adaptor board with this circuit.
Here are my patched copies of these libraries:
At this point, the big question is whether I've made a mistake somewhere (entirely likely), or if the RFM69 module really has some sort of issue where SPI bus usage by other devices, with the RFM69's NSS signal high, causes trouble with radio reception?
If you've used the RFM69 or similar HopeRF modules on a SPI bus with a lot of other activity, please reply or comment on the forum thread. I'd really like to hear about your experiences.