diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 4bd72df..40d4278 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -151,3 +151,45 @@ void SPIClass::usingInterrupt(uint8_t interruptNumber) interrupts(); } +void SPIClass::notUsingInterrupt(uint8_t interruptNumber) +{ + // Once in mode 2 we can't go back to 0 without a proper reference count + if (interruptMode == 2) + return; + uint8_t mask = 0; + uint8_t sreg = SREG; + noInterrupts(); // Protect from a scheduler and prevent transactionBegin + switch (interruptNumber) { + #ifdef SPI_INT0_MASK + case 0: mask = SPI_INT0_MASK; break; + #endif + #ifdef SPI_INT1_MASK + case 1: mask = SPI_INT1_MASK; break; + #endif + #ifdef SPI_INT2_MASK + case 2: mask = SPI_INT2_MASK; break; + #endif + #ifdef SPI_INT3_MASK + case 3: mask = SPI_INT3_MASK; break; + #endif + #ifdef SPI_INT4_MASK + case 4: mask = SPI_INT4_MASK; break; + #endif + #ifdef SPI_INT5_MASK + case 5: mask = SPI_INT5_MASK; break; + #endif + #ifdef SPI_INT6_MASK + case 6: mask = SPI_INT6_MASK; break; + #endif + #ifdef SPI_INT7_MASK + case 7: mask = SPI_INT7_MASK; break; + #endif + default: + break; + // this case can't be reached + } + interruptMask &= ~mask; + if (!interruptMask) + interruptMode = 0; + SREG = sreg; +} diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index c8d4ce3..2f9b565 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -20,6 +20,9 @@ // usingInterrupt(), and SPISetting(clock, bitOrder, dataMode) #define SPI_HAS_TRANSACTION 1 +// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method +#define SPI_HAS_NOTUSINGINTERRUPT 1 + // Uncomment this line to add detection of mismatched begin/end transactions. // A mismatch occurs if other libraries fail to use SPI.endTransaction() for // each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn @@ -154,6 +157,13 @@ public: // with attachInterrupt. If SPI is used from a different interrupt // (eg, a timer), interruptNumber should be 255. static void usingInterrupt(uint8_t interruptNumber); + // And this does the opposite. + static void notUsingInterrupt(uint8_t interruptNumber); + // Note: the usingInterrupt and notUsingInterrupt functions should + // not to be called from ISR context or inside a transaction. + // For details see: + // https://github.com/arduino/Arduino/pull/2381 + // https://github.com/arduino/Arduino/pull/2449 // Before using SPI.transfer() or asserting chip select pins, // this function is used to gain exclusive access to the SPI bus