| 
				
			 | 
			
			 | 
			@@ -140,34 +140,122 @@ void SPIClass::usingInterrupt(uint8_t interruptNumber) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/**********************************************************/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/*     32 bit Teensy 3.0 and 3.1			  */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/*     32 bit Teensy 3.x				  */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/**********************************************************/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISK) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			SPIClass SPI; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint8_t SPIClass::interruptMasksUsed = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint32_t SPIClass::interruptMask[(NVIC_NUM_INTERRUPTS+31)/32]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint32_t SPIClass::interruptSave[(NVIC_NUM_INTERRUPTS+31)/32]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifdef SPI_TRANSACTION_MISMATCH_LED | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint8_t SPIClass::inTransactionFlag = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#if defined(__MK20DX128__) || defined(__MK20DX256__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void _spi_dma_rxISR0(void) {/*SPI.dma_rxisr();*/} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SIM_SCGC6, SIM_SCGC6_SPI0, 4, IRQ_SPI0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				32767, DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_spi_dma_rxISR0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				12, 8, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				11, 7, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				13, 14, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				10, 2, 9, 6, 20, 23, 21, 22, 15, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2,  2, 2,  2,  2,  2,  2,  2,  2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				0x1, 0x1, 0x2, 0x2, 0x4, 0x4, 0x8, 0x8, 0x10 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			SPIClass SPI((uintptr_t)&KINETISK_SPI0, (uintptr_t)&SPIClass::spi0_hardware); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#elif defined(__MK64FX512__) || defined(__MK66FX1M0__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void _spi_dma_rxISR0(void) {/*SPI.dma_rxisr();*/} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void _spi_dma_rxISR1(void) {/*SPI1.dma_rxisr();*/} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void _spi_dma_rxISR2(void) {/*SPI2.dma_rxisr();*/} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SIM_SCGC6, SIM_SCGC6_SPI0, 4, IRQ_SPI0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				32767, DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_spi_dma_rxISR0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				12, 8, 39, 255, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 2, 2, 0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				11, 7, 28, 255, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 2, 2, 0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				13, 14, 27, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 2, 2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				10, 2, 9, 6, 20, 23, 21, 22, 15, 26, 45, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2,  2, 2,  2,  2,  2,  2,  2,  2,   2,   3, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				0x1, 0x1, 0x2, 0x2, 0x4, 0x4, 0x8, 0x8, 0x10, 0x1, 0x20 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			const SPIClass::SPI_Hardware_t SPIClass::spi1_hardware = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SIM_SCGC6, SIM_SCGC6_SPI1, 1, IRQ_SPI1, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				#if defined(__MK66FX1M0__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				32767, DMAMUX_SOURCE_SPI1_TX, DMAMUX_SOURCE_SPI1_RX, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				#else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// T3.5 does not have good DMA support on 1 and 2 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				511, 0, DMAMUX_SOURCE_SPI1, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_spi_dma_rxISR1, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				1, 5, 61, 59, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 7, 2, 7, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				0, 21, 61, 59, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 7, 7, 2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				32, 20, 60, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 7, 2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				6, 31, 58, 62, 63, 255, 255, 255, 255, 255, 255, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				7,  2,  2,  2,  2,  0,  0,  0,  0,   0,   0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				0x1, 0x1, 0x2, 0x1, 0x4, 0, 0, 0, 0, 0, 0 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			const SPIClass::SPI_Hardware_t SPIClass::spi2_hardware = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SIM_SCGC3, SIM_SCGC3_SPI2, 1, IRQ_SPI2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				#if defined(__MK66FX1M0__) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				32767, DMAMUX_SOURCE_SPI2_TX, DMAMUX_SOURCE_SPI2_RX, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				#else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// T3.5 does not have good DMA support on 1 and 2 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				511, 0, DMAMUX_SOURCE_SPI2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				_spi_dma_rxISR2, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				45, 51, 255, 255, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 2, 0, 0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				44, 52, 255, 255, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 2, 0, 0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				46, 53, 255, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2, 2, 0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				43, 54, 55, 255, 255, 255, 255, 255, 255, 255, 255, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				2,  2,  2,  0,  0,  0,  0,  0,  0,   0,   0, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				0x1, 0x2, 0x1, 0, 0, 0, 0, 0, 0, 0, 0 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//SPIClass SPI((uintptr_t)&KINETISK_SPI0, SPIClass::spi0_hardware); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			SPIClass SPI((uintptr_t)&KINETISK_SPI0, (uintptr_t)&SPIClass::spi0_hardware); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//SPIClass SPI1((uintptr_t)&KINETISK_SPI1, SPIClass::spi1_hardware); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//SPIClass SPI2((uintptr_t)&KINETISK_SPI2, SPIClass::spi2_hardware); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::begin() | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SIM_SCGC6 |= SIM_SCGC6_SPI0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPI0_CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPCR.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				volatile uint32_t *reg; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				hardware().clock_gate_register |= hardware().clock_gate_mask; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				port().CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				port().CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				port().MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				*reg = PORT_PCR_MUX(hardware().mosi_mux[mosi_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				reg = portConfigRegister(hardware().miso_pin[miso_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				*reg= PORT_PCR_MUX(hardware().miso_mux[miso_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				reg = portConfigRegister(hardware().sck_pin[sck_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				*reg = PORT_PCR_MUX(hardware().sck_mux[sck_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::end() { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPCR.disable_pins(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::end() | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				volatile uint32_t *reg; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				//SPCR.disable_pins(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				*reg = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				reg = portConfigRegister(hardware().miso_pin[miso_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				*reg = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				reg = portConfigRegister(hardware().sck_pin[sck_pin_index]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				*reg = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::usingInterrupt(IRQ_NUMBER_t interruptName) | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -226,26 +314,26 @@ const uint32_t SPISettings::ctar_clock_table[23] = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static void updateCTAR(uint32_t ctar) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::updateCTAR(uint32_t ctar) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (SPI0_CTAR0 != ctar) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					uint32_t mcr = SPI0_MCR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (port().CTAR0 != ctar) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					uint32_t mcr = port().MCR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (mcr & SPI_MCR_MDIS) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_CTAR0 = ctar; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_CTAR1 = ctar | SPI_CTAR_FMSZ(8); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						port().CTAR0 = ctar; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						port().CTAR1 = ctar | SPI_CTAR_FMSZ(8); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_CTAR0 = ctar; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_CTAR1 = ctar | SPI_CTAR_FMSZ(8); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						SPI0_MCR = mcr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						port().CTAR0 = ctar; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						port().CTAR1 = ctar | SPI_CTAR_FMSZ(8); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						port().MCR = mcr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::setBitOrder(uint8_t bitOrder) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SIM_SCGC6 |= SIM_SCGC6_SPI0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint32_t ctar = SPI0_CTAR0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				hardware().clock_gate_register |= hardware().clock_gate_mask; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint32_t ctar = port().CTAR0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (bitOrder == LSBFIRST) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					ctar |= SPI_CTAR_LSBFE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} else { | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -256,17 +344,17 @@ void SPIClass::setBitOrder(uint8_t bitOrder) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::setDataMode(uint8_t dataMode) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SIM_SCGC6 |= SIM_SCGC6_SPI0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				hardware().clock_gate_register |= hardware().clock_gate_mask; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				//uint32_t ctar = port().CTAR0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// TODO: implement with native code | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				//SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::setClockDivider_noInline(uint32_t clk) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SIM_SCGC6 |= SIM_SCGC6_SPI0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint32_t ctar = SPI0_CTAR0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				hardware().clock_gate_register |= hardware().clock_gate_mask; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint32_t ctar = port().CTAR0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				ctar &= (SPI_CTAR_CPOL | SPI_CTAR_CPHA | SPI_CTAR_LSBFE); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (ctar & SPI_CTAR_CPHA) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					clk = (clk & 0xFFFF0FFF) | ((clk & 0xF000) >> 4); | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -277,6 +365,11 @@ void SPIClass::setClockDivider_noInline(uint32_t clk) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint8_t SPIClass::pinIsChipSelect(uint8_t pin) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (pin == hardware().cs_pin[i]) return hardware().cs_mask[i]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				switch (pin) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				  case 10: return 0x01; // PTC4 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				  case 2:  return 0x01; // PTD0 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -292,8 +385,8 @@ uint8_t SPIClass::pinIsChipSelect(uint8_t pin) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				  case 45: return 0x20; // CS5 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			*/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2) | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -309,6 +402,15 @@ bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			// setCS() is not intended for use from normal Arduino programs/sketches. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint8_t SPIClass::setCS(uint8_t pin) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (pin == hardware().cs_pin[i]) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						volatile uint32_t *reg = portConfigRegister(pin); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						*reg = PORT_PCR_MUX(hardware().cs_mux[i]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						return hardware().cs_mask[i]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				switch (pin) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				  case 10: CORE_PIN10_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTC4 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				  case 2:  CORE_PIN2_CONFIG  = PORT_PCR_MUX(2); return 0x01; // PTD0 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -325,8 +427,44 @@ uint8_t SPIClass::setCS(uint8_t pin) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			*/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::setMOSI(uint8_t pin) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (pin != hardware().mosi_pin[mosi_pin_index]) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if  (pin == hardware().mosi_pin[i]) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							mosi_pin_index = i; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							return; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::setMISO(uint8_t pin) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (pin != hardware().miso_pin[miso_pin_index]) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if  (pin == hardware().miso_pin[i]) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							miso_pin_index = i; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							return; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::setSCK(uint8_t pin) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (pin != hardware().sck_pin[sck_pin_index]) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if  (pin == hardware().sck_pin[i]) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							sck_pin_index = i; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							return; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void SPIClass::transfer(void *buf, size_t count) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -334,19 +472,19 @@ void SPIClass::transfer(void *buf, size_t count) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint8_t *p_write = (uint8_t *)buf; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint8_t *p_read = p_write; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				size_t count_read = count; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				bool lsbfirst = (SPI0_CTAR0 & SPI_CTAR_LSBFE) ? true : false; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				bool lsbfirst = (port().CTAR0 & SPI_CTAR_LSBFE) ? true : false; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Lets clear the reader queue | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				uint32_t sr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// Now lets loop while we still have data to output | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (count & 1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (count > 1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						KINETISK_SPI0.PUSHR = *p_write++ | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						port().PUSHR = *p_write++ | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						KINETISK_SPI0.PUSHR = *p_write++ | SPI_PUSHR_CTAS(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						port().PUSHR = *p_write++ | SPI_PUSHR_CTAS(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					count--; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -356,15 +494,15 @@ void SPIClass::transfer(void *buf, size_t count) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					w |= *p_write++; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (lsbfirst) w = __builtin_bswap16(w); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (count == 2) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						KINETISK_SPI0.PUSHR = w | SPI_PUSHR_CTAS(1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						port().PUSHR = w | SPI_PUSHR_CTAS(1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					else	 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						KINETISK_SPI0.PUSHR = w | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						port().PUSHR = w | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					count -= 2; // how many bytes to output. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// Make sure queue is not full before pushing next byte out | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					do { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						sr = KINETISK_SPI0.SR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						sr = port().SR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (sr & 0xF0)  { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							uint16_t w = KINETISK_SPI0.POPR;  // Read any pending RX bytes in | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							uint16_t w = port().POPR;  // Read any pending RX bytes in | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							if (count_read & 1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								*p_read++ = w;  // Read any pending RX bytes in | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								count_read--; | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -380,9 +518,9 @@ void SPIClass::transfer(void *buf, size_t count) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				// now lets wait for all of the read bytes to be returned... | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				while (count_read) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					sr = KINETISK_SPI0.SR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					sr = port().SR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (sr & 0xF0)  { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						uint16_t w = KINETISK_SPI0.POPR;  // Read any pending RX bytes in | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						uint16_t w = port().POPR;  // Read any pending RX bytes in | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (count_read & 1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							*p_read++ = w;  // Read any pending RX bytes in | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							count_read--; |