Voil
After spending some time to read all the comments regarding the SPI library interrupt issue and improvement, let me summarise my findings expecting to clarify this topic.
Motivations:ESP micro-controllers allow concurrent usage of Ethernet Wireless and RFM69 Wireless modules and is a cheap alternative to Arduino WiFi Shield to build Ethernet/RFM Gateways.
The RFM69 library is compatible with the ESP8266 devices such as WeMos, NodeMCU, HUZZA, etc… more precisely the ESP8266 SPI library (currently 2.3.0).
See
https://lowpowerlab.com/forum/projects/(update)-rfm69-library-for-esp8266-moteino-compatible!/75/(Beside possible SPI clock speed adjustment; see
https://bitbucket.org/xoseperez/rfm69gw), and below:
SPI depreciated functions).
For Ethernet wired configuration, using RFM69 transceivers and Arduino Ethernet board based on WizNet5100 (Arduino Ethernet or Arduino Ethernet Shield) there are SPI interrupt conflicts that are hanging sketches; this issue is solved by a new version of the SPI library and RFM69 library patch (currently not implemented).
Goal:To have a RFM69 library operable in both Arduino Ethernet and ESP8266 environments.
Current issues: Arduino AVR environment.When using SPI interrupts (case of W5100 and RFM69), interrupts conflicts may occurs.
This problem is described by
http://dorkbotpdx.org/blog/paul/spi_transactions_in_arduinoThe workaround is a new SPI library (since Arduino IDE 1.5.8 )
This new library implements 3 new functions while accessing (select / unselect SPI):
From synchronous access:
SPI.beginTransaction(SPISettings);
SPI.endTransaction(); For asynchronous access:
SPI.usingInterrupt(number);Which are well documented, see
http://www.pjrc.com/teensy/td_libs_SPI.htmlTo activate conditionally these new functions, for compatibility with older IDE compilers, a statement SPI_HAS_TRANSACTION is defined in the new SPI library.
A patch using these functions for the RFM69 library was submitted by kiwisincebirth (see
https://github.com/kiwisincebirth/RFM69) but was never actually implemented.
So the first fix is to ensure that this patch is working in an environment where an RFM transceiver is activated together with an Ethernet shield.
ESP environmentIf the SPI_HAS_TRANSACTION i.e: SPI.beginTransaction(SPISettings) and SPI.endTransaction() is implemented in the ESP8266 SPI library (2.3.0), the (SPI.usingInterrupt(number) is not, which is a first issue.
Also, the kiwisincebirth patch makes access to an AVR register: SREG (Status Register) this register doesn’t exit as such in the ESP8266 which is a second issue.
Moreover the kiwi patch which is working for Arduino AVR, was removed for an obscure reason to fit the ESP environment see
https://github.com/esp8266/Arduino/issues/1943 and
https://github.com/LowPowerLab/RFM69/commit/ec90680e008c366dc7340ec1aada3942f8592707So the second fix is to ensure that the patched RFM69 library is still working with the ESP8266 SPI library.
Note:The RFM69 library uses references to other registers such as SPCR (SPI Control register) and SPSR (SPI Status Register). However conditional access to these registers is made (typically via : if defined (SPCR) && defined (SPSR)). Because SPCR and SPSR are not defined in the ESP8266 library, this is not causing a problem.
Current approachWith this approach the new SPI functions will be activated according to the SPI library version using “#ifdef SPI_HAS_TRANSACTION”
Saving and restoring the SREG is more likely unnecessary (was verified during tests), but for backward compatibility, reference to this register is made conditional for AVR environment.
Now, to avoid activating the function SPI.usingInterrupt(number), an extra test is done to one the processor type (typically ESP8266) using “#if defined (SPI_HAS_TRANSACTION) && !defined (ESP8266)" before activating this function.
Depreciated SPI functions in RFM69 LibrarySmall library improvements may be applied.
1. Explicit reference to Interrupt Number, which could be replaced by: digitalPinToInterrupt(interrupt_pin)
2. SPI functions such as:
SPI.setDataMode();
SPI.setBitOrder();
SPI.setClockDivider();
Are replaced by SPISettings(speed, bit_order, mode) see
https://www.arduino.cc/en/Reference/SPISettings (which by the way is also implemented in the ESP library).
This feature allows to use the appropriate speed for a SPI device independent of the processor clock
Conclusions:The RFM69 library issues described above are not related to a MOTEINO environment but related to the usage of this library with SPI Ethernet controller or ESP controllers.
One has to decide if this library update is to be implemented or not in the frame of MOTEINO.
My point of view is that it should be implemented to make usage of the new Arduino SPI library functions (MOTEINO uses AVR processors), despite the fact that the ESP SPI library is not implementing the SPI.usingInterrupt(number) function (or a similar dummy function) see
http://www.esp8266.com/viewtopic.php?f=28&t=11998&sid=59d9547d624a26a1de38a1e6ebbf3932#p56001f=28&t=11998&sid=59d9547d624a26a1de38a1e6ebbf3932In this case the only solution for people wanting to use the RFM69 library for ESP micro-controller is to adapt the library avoiding to activate SPI.usingInterrupt(number) controlling the environment using “if defined (ESP8266) statement”.
TestsI did tests with an Arduino ATMEGA2560, Arduino Ethernet Shield and RFM69HW transceiver as network coordinator (sending converted RFM messages via Ethernet MQTT to a Raspberry OpenHab broker) for my Home automation MOTEINO RFM69 nodes . This version is currently running in my operational environment, without problems.
I have also loaded an ESP-12 with a similar gateway sketch, I use the Struct_send.ino sketch from the RFM69 library to send RFM data that are forwarded via Wifi to my Raspberry Broker without problems.
I plan to replace my coordinator by WeMOs module on a Charles-Henry Hallard WeMos-RFM gateway, I will keep you inform if I encounter new problems.
For the record I have posted a RFM69.cpp and RFM69.h updated library on
https://github.com/rrobinet/RFM69_Libary where my modifications are clearly indicated (!!! ROB)
NB: RFM_ATC library was not tested because of compilation errors, but this is another story (I must admit that I did not spend too much time to debug that one)