diff --git a/hardware/arduino/avr/libraries/SPI/SPI.cpp b/hardware/arduino/avr/libraries/SPI/SPI.cpp
index ef13e2ae9..4bd72dfdb 100644
--- a/hardware/arduino/avr/libraries/SPI/SPI.cpp
+++ b/hardware/arduino/avr/libraries/SPI/SPI.cpp
@@ -2,6 +2,7 @@
  * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
  * Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
  * Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
+ * Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
  * SPI Master library for arduino.
  *
  * This file is free software; you can redistribute it and/or modify
@@ -14,6 +15,7 @@
 
 SPIClass SPI;
 
+uint8_t SPIClass::initialized = 0;
 uint8_t SPIClass::interruptMode = 0;
 uint8_t SPIClass::interruptMask = 0;
 uint8_t SPIClass::interruptSave = 0;
@@ -23,32 +25,51 @@ uint8_t SPIClass::inTransactionFlag = 0;
 
 void SPIClass::begin()
 {
-  // Set SS to high so a connected chip will be "deselected" by default
-  digitalWrite(SS, HIGH);
+  uint8_t sreg = SREG;
+  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
+  if (!initialized) {
+    // Set SS to high so a connected chip will be "deselected" by default
+    digitalWrite(SS, HIGH);
 
-  // When the SS pin is set as OUTPUT, it can be used as
-  // a general purpose output port (it doesn't influence
-  // SPI operations).
-  pinMode(SS, OUTPUT);
+    // When the SS pin is set as OUTPUT, it can be used as
+    // a general purpose output port (it doesn't influence
+    // SPI operations).
+    pinMode(SS, OUTPUT);
 
-  // Warning: if the SS pin ever becomes a LOW INPUT then SPI
-  // automatically switches to Slave, so the data direction of
-  // the SS pin MUST be kept as OUTPUT.
-  SPCR |= _BV(MSTR);
-  SPCR |= _BV(SPE);
+    // Warning: if the SS pin ever becomes a LOW INPUT then SPI
+    // automatically switches to Slave, so the data direction of
+    // the SS pin MUST be kept as OUTPUT.
+    SPCR |= _BV(MSTR);
+    SPCR |= _BV(SPE);
 
-  // Set direction register for SCK and MOSI pin.
-  // MISO pin automatically overrides to INPUT.
-  // By doing this AFTER enabling SPI, we avoid accidentally
-  // clocking in a single bit since the lines go directly
-  // from "input" to SPI control.  
-  // http://code.google.com/p/arduino/issues/detail?id=888
-  pinMode(SCK, OUTPUT);
-  pinMode(MOSI, OUTPUT);
+    // Set direction register for SCK and MOSI pin.
+    // MISO pin automatically overrides to INPUT.
+    // By doing this AFTER enabling SPI, we avoid accidentally
+    // clocking in a single bit since the lines go directly
+    // from "input" to SPI control.
+    // http://code.google.com/p/arduino/issues/detail?id=888
+    pinMode(SCK, OUTPUT);
+    pinMode(MOSI, OUTPUT);
+  }
+  initialized++; // reference count
+  SREG = sreg;
 }
 
 void SPIClass::end() {
-  SPCR &= ~_BV(SPE);
+  uint8_t sreg = SREG;
+  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
+  // Decrease the reference counter
+  if (initialized)
+    initialized--;
+  // If there are no more references disable SPI
+  if (!initialized) {
+    SPCR &= ~_BV(SPE);
+    interruptMode = 0;
+    #ifdef SPI_TRANSACTION_MISMATCH_LED
+    inTransactionFlag = 0;
+    #endif
+  }
+  SREG = sreg;
 }
 
 // mapping of interrupt numbers to bits within SPI_AVR_EIMSK
diff --git a/hardware/arduino/avr/libraries/SPI/SPI.h b/hardware/arduino/avr/libraries/SPI/SPI.h
index 24ebc125e..c8d4ce3b6 100644
--- a/hardware/arduino/avr/libraries/SPI/SPI.h
+++ b/hardware/arduino/avr/libraries/SPI/SPI.h
@@ -2,6 +2,7 @@
  * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
  * Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
  * Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
+ * Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
  * SPI Master library for arduino.
  *
  * This file is free software; you can redistribute it and/or modify
@@ -281,6 +282,7 @@ public:
   inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }
 
 private:
+  static uint8_t initialized;
   static uint8_t interruptMode; // 0=none, 1=mask, 2=global
   static uint8_t interruptMask; // which interrupts to mask
   static uint8_t interruptSave; // temp storage, to restore state