| 
				
			 | 
			
			 | 
			@@ -16,20 +16,9 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <Arduino.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// usingInterrupt(), and the actual clock speed names | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_HAS_TRANSACTION 1 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// define SPI_AVR_EIMSK for AVR boards with external interrupt pins | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if defined(__AVR__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if defined(EIMSK) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_AVR_EIMSK	 EIMSK | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(GICR) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_AVR_EIMSK	 GICR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(GIMSK) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_AVR_EIMSK	 GIMSK | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifndef LSBFIRST | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define LSBFIRST 0 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -42,11 +31,34 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_MODE2 0x08 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_MODE3 0x0C | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV4 0x00 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV16 0x01 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV64 0x02 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV128 0x03 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV2 0x04 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV8 0x05 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV32 0x06 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_MODE_MASK 0x0C  // CPOL = bit 3, CPHA = bit 2 on SPCR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_MASK 0x03  // SPR1 = bit 1, SPR0 = bit 0 on SPCR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_2XCLOCK_MASK 0x01  // SPI2X = bit 0 on SPSR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/**********************************************************/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/*     8 bit AVR-based boards                             */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/**********************************************************/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if defined(__AVR__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// define SPI_AVR_EIMSK for AVR boards with external interrupt pins | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if defined(EIMSK) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_AVR_EIMSK	 EIMSK | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(GICR) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_AVR_EIMSK	 GICR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(GIMSK) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_AVR_EIMSK	 GIMSK | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			class SPISettings { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			public: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -63,7 +75,6 @@ private: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					init_AlwaysInline(clock, bitOrder, dataMode); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if defined(__AVR__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				  __attribute__((__always_inline__)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// Clock settings are defined as follows. Note that this shows SPI2X | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -128,20 +139,188 @@ private: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint8_t spcr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint8_t spsr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				friend class SPIClass; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			class SPIClass { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			public: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Initialize the SPI library | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static void begin(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// If SPI is to used from within an interrupt, this function registers | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// that interrupt with the SPI library, so beginTransaction() can | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// prevent conflicts.  The input interruptNumber is the number used | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// with attachInterrupt.  If SPI is used from a different interrupt | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// (eg, a timer), interruptNumber should be 255. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static void usingInterrupt(uint8_t interruptNumber); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Before using SPI.transfer() or asserting chip select pins, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// this function is used to gain exclusive access to the SPI bus | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// and configure the correct settings. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void beginTransaction(SPISettings settings) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (interruptMode > 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						#ifdef SPI_AVR_EIMSK | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (interruptMode == 1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							interruptSave = SPI_AVR_EIMSK; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							SPI_AVR_EIMSK &= ~interruptMask; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							interruptSave = SREG; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							cli(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPCR = settings.spcr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPSR = settings.spsr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Write to the SPI bus (MOSI pin) and also receive (MISO pin) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static uint8_t transfer(uint8_t data) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPDR = data; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					asm volatile("nop"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					while (!(SPSR & _BV(SPIF))) ; // wait | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return SPDR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void transfer(void *buf, size_t count) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (count == 0) return; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					uint8_t *p = (uint8_t *)buf; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPDR = *p; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					while (--count > 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						uint8_t out = *(p + 1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						while (!(SPSR & _BV(SPIF))) ; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						uint8_t in = SPDR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPDR = out; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						*p++ = in; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					while (!(SPSR & _BV(SPIF))) ; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					*p = SPDR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// After performing a group of transfers and releasing the chip select | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// signal, this function allows others to access the SPI bus | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void endTransaction(void) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (interruptMode > 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						#ifdef SPI_AVR_EIMSK | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (interruptMode == 1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							SPI_AVR_EIMSK = interruptSave; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							SREG = interruptSave; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Disable the SPI bus | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static void end(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// This function is deprecated.	 New applications should use | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// beginTransaction() to configure SPI settings. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void setBitOrder(uint8_t bitOrder) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (bitOrder == LSBFIRST) SPCR |= _BV(DORD); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					else SPCR &= ~(_BV(DORD)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// This function is deprecated.	 New applications should use | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// beginTransaction() to configure SPI settings. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void setDataMode(uint8_t dataMode) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// This function is deprecated.	 New applications should use | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// beginTransaction() to configure SPI settings. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void setClockDivider(uint8_t clockDiv) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// These undocumented functions should not be used.  SPI.transfer() | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// polls the hardware flag which is automatically cleared as the | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// AVR responds to SPI's interrupt | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void attachInterrupt() { SPCR |= _BV(SPIE); } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			private: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				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 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// mapping of interrupt numbers to bits within SPI_AVR_EIMSK | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if defined(__AVR_ATmega32U4__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT0_MASK	 (1<<INT0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT1_MASK	 (1<<INT1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT2_MASK	 (1<<INT2) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT3_MASK	 (1<<INT3) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT4_MASK	 (1<<INT6) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT0_MASK	 (1<<INT0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT1_MASK	 (1<<INT1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT2_MASK	 (1<<INT2) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT3_MASK	 (1<<INT3) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT4_MASK	 (1<<INT4) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT5_MASK	 (1<<INT5) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT6_MASK	 (1<<INT6) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT7_MASK	 (1<<INT7) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(EICRA) && defined(EICRB) && defined(EIMSK) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT0_MASK	 (1<<INT4) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT1_MASK	 (1<<INT5) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT2_MASK	 (1<<INT0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT3_MASK	 (1<<INT1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT4_MASK	 (1<<INT2) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT5_MASK	 (1<<INT3) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT6_MASK	 (1<<INT6) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT7_MASK	 (1<<INT7) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #ifdef INT0 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT0_MASK	 (1<<INT0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #ifdef INT1 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT1_MASK	 (1<<INT1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #ifdef INT2 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT2_MASK	 (1<<INT2) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/**********************************************************/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/*     32 bit Teensy 3.0 and 3.1                          */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/**********************************************************/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(__arm__) && defined(TEENSYDUINO) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			class SPISettings { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			public: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (__builtin_constant_p(clock)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						init_AlwaysInline(clock, bitOrder, dataMode); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						init_MightInline(clock, bitOrder, dataMode); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPISettings() { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			private: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					init_AlwaysInline(clock, bitOrder, dataMode); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				  __attribute__((__always_inline__)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					uint32_t t, c = SPI_CTAR_FMSZ(7); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (bitOrder == LSBFIRST) c |= SPI_CTAR_LSBFE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (__builtin_constant_p(clock)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if        (clock >= F_BUS / 2) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							  | SPI_CTAR_CSSCK(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} else if (clock >= F_BUS / 3) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							  | SPI_CTAR_CSSCK(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} else if (clock >= F_BUS / 4) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} else if (clock >= F_BUS / 5) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							t = SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							t = SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							  | SPI_CTAR_CSSCK(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} else if (clock >= F_BUS / 6) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} else if (clock >= F_BUS / 8) { | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -199,7 +378,6 @@ private: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static const uint16_t ctar_div_table[23]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static const uint32_t ctar_clock_table[23]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint32_t ctar; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				friend class SPIClass; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -216,9 +394,7 @@ public: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// with attachInterrupt.  If SPI is used from a different interrupt | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// (eg, a timer), interruptNumber should be 255. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static void usingInterrupt(uint8_t interruptNumber); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				#if defined(__arm__) && defined(TEENSYDUINO) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static void usingInterrupt(IRQ_NUMBER_t interruptName); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Before using SPI.transfer() or asserting chip select pins, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// this function is used to gain exclusive access to the SPI bus | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -236,17 +412,12 @@ public: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							cli(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					#if defined(__AVR__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPCR = settings.spcr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPSR = settings.spsr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					#elif defined(__arm__) && defined(TEENSYDUINO) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (SPI0_CTAR0 != settings.ctar) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_CTAR0 = settings.ctar; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_CTAR1 = settings.ctar | SPI_CTAR_FMSZ(7); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_CTAR1 = settings.ctar| SPI_CTAR_FMSZ(8); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Write to the SPI bus (MOSI pin) and also receive (MISO pin) | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -291,32 +462,49 @@ public: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// This function is deprecated.	 New applications should use | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// beginTransaction() to configure SPI settings. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void setBitOrder(uint8_t bitOrder) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (bitOrder == LSBFIRST) SPCR |= _BV(DORD); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					else SPCR &= ~(_BV(DORD)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static void setBitOrder(uint8_t bitOrder); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// This function is deprecated.	 New applications should use | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// beginTransaction() to configure SPI settings. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void setDataMode(uint8_t dataMode) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static void setDataMode(uint8_t dataMode); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// This function is deprecated.	 New applications should use | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// beginTransaction() to configure SPI settings. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void setClockDivider(uint8_t clockDiv) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (clockDiv == SPI_CLOCK_DIV2) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						setClockDivider_noInline(SPISettings(8000000, MSBFIRST, SPI_MODE0).ctar); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} else if (clockDiv == SPI_CLOCK_DIV4) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						setClockDivider_noInline(SPISettings(4000000, MSBFIRST, SPI_MODE0).ctar); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} else if (clockDiv == SPI_CLOCK_DIV8) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						setClockDivider_noInline(SPISettings(2000000, MSBFIRST, SPI_MODE0).ctar); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} else if (clockDiv == SPI_CLOCK_DIV16) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						setClockDivider_noInline(SPISettings(1000000, MSBFIRST, SPI_MODE0).ctar); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} else if (clockDiv == SPI_CLOCK_DIV32) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						setClockDivider_noInline(SPISettings(500000, MSBFIRST, SPI_MODE0).ctar); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} else if (clockDiv == SPI_CLOCK_DIV64) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						setClockDivider_noInline(SPISettings(250000, MSBFIRST, SPI_MODE0).ctar); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} else { /* clockDiv == SPI_CLOCK_DIV128 */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						setClockDivider_noInline(SPISettings(125000, MSBFIRST, SPI_MODE0).ctar); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static void setClockDivider_noInline(uint32_t clk); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// These undocumented functions should not be used.  SPI.transfer() | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// polls the hardware flag which is automatically cleared as the | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// AVR responds to SPI's interrupt | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void attachInterrupt() { SPCR |= _BV(SPIE); } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void attachInterrupt() { } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void detachInterrupt() { } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if defined(__arm__) && defined(TEENSYDUINO) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline void setMOSI(uint8_t pin) __attribute__((always_inline)) { SPCR.setMOSI(pin); } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline void setMISO(uint8_t pin) __attribute__((always_inline)) { SPCR.setMISO(pin); } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline void setSCK(uint8_t pin) __attribute__((always_inline)) { SPCR.setSCK(pin); } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Teensy 3.x can use alternate pins for these 3 SPI signals. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void setMOSI(uint8_t pin) __attribute__((always_inline)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPCR.setMOSI(pin); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void setMISO(uint8_t pin) __attribute__((always_inline)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPCR.setMISO(pin); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				inline static void setSCK(uint8_t pin) __attribute__((always_inline)) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					SPCR.setSCK(pin); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			private: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static uint8_t interruptMode; // 0=none, 1=mask, 2=global | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -324,55 +512,10 @@ private: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				static uint8_t interruptSave; // temp storage, to restore state | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			extern SPIClass SPI; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV4 0x00 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV16 0x01 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV64 0x02 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV128 0x03 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV2 0x04 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV8 0x05 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SPI_CLOCK_DIV32 0x06 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// mapping of interrupt numbers to bits within SPI_AVR_EIMSK | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifdef SPI_AVR_EIMSK | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if defined(__AVR_ATmega32U4__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT0_MASK	 (1<<INT0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT1_MASK	 (1<<INT1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT2_MASK	 (1<<INT2) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT3_MASK	 (1<<INT3) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT4_MASK	 (1<<INT6) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT0_MASK	 (1<<INT0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT1_MASK	 (1<<INT1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT2_MASK	 (1<<INT2) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT3_MASK	 (1<<INT3) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT4_MASK	 (1<<INT4) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT5_MASK	 (1<<INT5) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT6_MASK	 (1<<INT6) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT7_MASK	 (1<<INT7) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(EICRA) && defined(EICRB) && defined(EIMSK) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT0_MASK	 (1<<INT4) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT1_MASK	 (1<<INT5) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT2_MASK	 (1<<INT0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT3_MASK	 (1<<INT1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT4_MASK	 (1<<INT2) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT5_MASK	 (1<<INT3) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT6_MASK	 (1<<INT6) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT7_MASK	 (1<<INT7) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #ifdef INT0 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT0_MASK	 (1<<INT0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #ifdef INT1 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT1_MASK	 (1<<INT1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #ifdef INT2 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #define SPI_INT2_MASK	 (1<<INT2) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  #endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif //SPI_AVR_EIMSK | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			extern SPIClass SPI; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif |