Handle interrupt outside actual ISR
### Commit adapted from 2793a5a909
Handling an interrupt from the RFM69 inside an actual ISR given the
complexity of the handler appears to conflict with I2C devices, blocking
the Arduino indefinitely after a few seconds of concurrent use. In
general, complex ISRs are to be avoided.
This commit is contained in:
parent
c51a7c7b99
commit
3d4a8c99c4
19
RFM69.cpp
19
RFM69.cpp
|
|
@ -36,7 +36,7 @@ volatile uint8_t RFM69::PAYLOADLEN;
|
|||
volatile uint8_t RFM69::ACK_REQUESTED;
|
||||
volatile uint8_t RFM69::ACK_RECEIVED; // should be polled immediately after sending a packet with ACK request
|
||||
volatile int16_t RFM69::RSSI; // most accurate RSSI during reception (closest to the reception)
|
||||
volatile bool RFM69::_inISR;
|
||||
volatile bool RFM69::_haveData;
|
||||
RFM69* RFM69::selfPointer;
|
||||
|
||||
RFM69::RFM69(uint8_t slaveSelectPin, uint8_t interruptPin, bool isRFM69HW)
|
||||
|
|
@ -127,7 +127,6 @@ bool RFM69::initialize(uint8_t freqBand, uint8_t nodeID, uint8_t networkID)
|
|||
while (((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00) && millis()-start < timeout); // wait for ModeReady
|
||||
if (millis()-start >= timeout)
|
||||
return false;
|
||||
_inISR = false;
|
||||
attachInterrupt(_interruptNum, RFM69::isr0, RISING);
|
||||
|
||||
selfPointer = this;
|
||||
|
|
@ -376,7 +375,7 @@ void RFM69::interruptHandler() {
|
|||
}
|
||||
|
||||
// internal function
|
||||
void RFM69::isr0() { _inISR = true; selfPointer->interruptHandler(); _inISR = false; }
|
||||
void RFM69::isr0() { _haveData = true; }
|
||||
|
||||
// internal function
|
||||
void RFM69::receiveBegin() {
|
||||
|
|
@ -400,7 +399,10 @@ void RFM69::receiveBegin() {
|
|||
bool RFM69::receiveDone() {
|
||||
//ATOMIC_BLOCK(ATOMIC_FORCEON)
|
||||
//{
|
||||
noInterrupts(); // re-enabled in unselect() via setMode() or via receiveBegin()
|
||||
if (_haveData) {
|
||||
_haveData = false;
|
||||
interruptHandler();
|
||||
}
|
||||
if (_mode == RF69_MODE_RX && PAYLOADLEN > 0)
|
||||
{
|
||||
setMode(RF69_MODE_STANDBY); // enables interrupts
|
||||
|
|
@ -408,7 +410,6 @@ bool RFM69::receiveDone() {
|
|||
}
|
||||
else if (_mode == RF69_MODE_RX) // already in RX no payload yet
|
||||
{
|
||||
interrupts(); // explicitly re-enable interrupts
|
||||
return false;
|
||||
}
|
||||
receiveBegin();
|
||||
|
|
@ -471,7 +472,6 @@ void RFM69::writeReg(uint8_t addr, uint8_t value)
|
|||
|
||||
// select the RFM69 transceiver (save SPI settings, set CS low)
|
||||
void RFM69::select() {
|
||||
noInterrupts();
|
||||
#if defined (SPCR) && defined (SPSR)
|
||||
// save current SPI settings
|
||||
_SPCR = SPCR;
|
||||
|
|
@ -496,7 +496,6 @@ void RFM69::unselect() {
|
|||
SPCR = _SPCR;
|
||||
SPSR = _SPSR;
|
||||
#endif
|
||||
maybeInterrupts();
|
||||
}
|
||||
|
||||
// true = disable filtering to capture all frames on network
|
||||
|
|
@ -851,12 +850,6 @@ void RFM69::rcCalibration()
|
|||
while ((readReg(REG_OSC1) & RF_OSC1_RCCAL_DONE) == 0x00);
|
||||
}
|
||||
|
||||
inline void RFM69::maybeInterrupts()
|
||||
{
|
||||
// Only reenable interrupts if we're not being called from the ISR
|
||||
if (!_inISR) interrupts();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// ListenMode specific functions
|
||||
//=============================================================================
|
||||
|
|
|
|||
5
RFM69.h
5
RFM69.h
|
|
@ -207,9 +207,9 @@ class RFM69 {
|
|||
|
||||
protected:
|
||||
static void isr0();
|
||||
void virtual interruptHandler();
|
||||
void interruptHandler();
|
||||
virtual void interruptHook(uint8_t CTLbyte) {};
|
||||
static volatile bool _inISR;
|
||||
static volatile bool _haveData;
|
||||
virtual void sendFrame(uint8_t toAddress, const void* buffer, uint8_t size, bool requestACK=false, bool sendACK=false);
|
||||
|
||||
static RFM69* selfPointer;
|
||||
|
|
@ -230,7 +230,6 @@ class RFM69 {
|
|||
virtual void setHighPowerRegs(bool onOff);
|
||||
virtual void select();
|
||||
virtual void unselect();
|
||||
inline void maybeInterrupts();
|
||||
|
||||
#if defined(RF69_LISTENMODE_ENABLE)
|
||||
//=============================================================================
|
||||
|
|
|
|||
Loading…
Reference in New Issue