LowPowerLab Forum

Hardware support => Moteino => Topic started by: Charly86 on August 27, 2014, 04:19:21 AM

Title: Felix's RFM69 Library update and other IRQ problem
Post by: Charly86 on August 27, 2014, 04:19:21 AM
Felix,

I'm working with the new release of your RFM69 library and it's working fine.

I'm using dual RF gateway (with 1 RFM12B and 1 RFM69 on the same board) to send data to emoncms.
It's working fine until RFM12B (with my custom lib RFM12B_arssi) is on CS=5 IRQ=D3 and RFM69 on CS=10 and IRQ=2.
On my new board I reversed the module, this mean that  now
RFM12B is CS=10 IRQ=2 and
RFM69 is CS=5 and IRQ=3
Like this, nothing works for RFM12B, packets are not received by RFM12B module (which is by the way correctly detected by the library). So I suspected IRQ problem (80% of problem ;-) and found why it's not working.
Here is the fix, when you call select()/unselect() in RFM69 lib you enable/disable global IRQ with Interrupts()/noInterrupts() which prevent all software around to use any IRQ (not sure why, but it's the reason) so I modified your code to enable/disable only the RFM69 IRQ and everything is now working fine with other IRQ than the default one :

In my ino code I've done

// CS 5 / IRQ 3
#define RF69_CS  5
#define RF69_IRQ 3

// Instantiate RF69 Module
RFM69 radio69(RF69_CS, RF69_IRQ, false, RF69_IRQ-2);


and in RFM69.cpp library, replace
line with
noInterrupts();
by
bitClear(EIMSK, _interruptNum);
and lines with
Interrupts()
by
bitSet(EIMSK, _interruptNum);

This code just disable/enable the RFM69 IRQ and let any other IRQ untouched.
That's it and it works out of the box, no overhead, just one assembler instruction once compiled
And as a cherry on a cake, should work with 1284p also (don't have one  :(), just let me know.

Would you mind add the modification to your library on github if it works with mega also ?

thank's you for your help and great library




Title: Re: Felix's RFM69 Library update and other IRQ problem
Post by: Felix on August 27, 2014, 08:46:05 AM
Charly,
Thanks for your research. The purpose of noInterrupts is to stop any and all interrupts when doing some mission critical talking to RFM69. So disabling only the RFM69 interrupt is essentially removing all interrupt disabling safety since interrupts from RFM69 are not expected when talking to it (since talking to it is typically in response to a RFM69 interrupt).
So in light of this I don't think I can add this change since it's very important to keep interrupts disabled while the RFM69 is selected. I hope this makes sense.
Title: Re: Felix's RFM69 Library update and other IRQ problem
Post by: Charly86 on August 27, 2014, 09:46:16 AM
Felix,

you're absolutly right, we need to avoid interrupts that could mess up with SPI when we're talking to it (shame on me) but the global disable is the most conservative option stopping everything. For sure you will not have any problem with RFM69 but when mixing some other code we need to be sure there is no interaction.
From my view (that could be wrong) disabling interrupt only for other SPI devices is enought since SPI is hardware controlled interrupting while talking should not be a problem if other ISR routine is fast (no serial.print everywhere). Tell me if I'm wrong ?

I've investigated on Interrupts() NoInterrupts() code and it's just a sei cli command so for sure there is no overhead and just disable/enable global IRQ flag, leaving other IRQ configuration untouched so after an Interrupts() call all should works.

What I don' understand is why when RFM69 is on CS 10 IRQ 2 (so RFM12 on CS 5 IRQ 3) I have no problem and when RFM69 is on CS 5 IRQ 3 (so RFM12 on CS 10 IRQ 2) the problem occurs.

Very strange but il all case even if my modifications are working for me, it's not the good fix (moreover as I have RFM12B SPI device on same board talking SPI too) so please keep Felix's code untouched, I will continue my investigations.


Title: Re: Felix's RFM69 Library update and other IRQ problem
Post by: Felix on August 27, 2014, 10:35:15 AM
Interrupts can be of many different types. And they all interrupt whatever is running, unless disabled. We really dont want that to happen when interacting to RFM69.
CS10 is special. When you have SPI slaves you need to keep that as an output, pulled high.
The interrupt on RFM69 is active high while the RFM12B is active low. There is no reason why they should not work together on the same board, it has been done before: https://lowpowerlab.com/forum/index.php/topic,204.0.html
Title: Re: Felix's RFM69 Library update and other IRQ problem
Post by: Charly86 on August 27, 2014, 10:51:16 AM
Felix,

Interesting to see that he changed the IRQ/CS of RFM12B not of RFM69, and that was my first test and that is working fine.

The problem is if I do the reverse test, change IRQ/CS of RFM69 and leave default for RFM12B  :D