diff --git a/cores/arduino/RingBuffer.cpp b/cores/arduino/RingBuffer.cpp
index 123f895edb16002394fd28308becf11e861dd2e4..f35e5df328ac8be463f84af98231bbcfc7bbe114 100644
--- a/cores/arduino/RingBuffer.cpp
+++ b/cores/arduino/RingBuffer.cpp
@@ -78,4 +78,9 @@ int RingBuffer::peek()
 int RingBuffer::nextIndex(int index)
 {
 	return (uint32_t)(index + 1) % SERIAL_BUFFER_SIZE;
+}
+
+int RingBuffer::isFull()
+{
+	return (nextIndex(_iTail) == _iHead);
 }
\ No newline at end of file
diff --git a/cores/arduino/RingBuffer.h b/cores/arduino/RingBuffer.h
index 030620b39f1250e2acc9eec75de5e8443a15cc3d..49bbe8cd6f8961d7e3e65e468e6fc51156fff734 100644
--- a/cores/arduino/RingBuffer.h
+++ b/cores/arduino/RingBuffer.h
@@ -41,6 +41,7 @@ class RingBuffer
 	int read_char();
 	int available();
 	int peek();
+	bool isFull();
 	
   private:
 	int nextIndex(int index);
diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp
index 298ed07ed79768fc469071e742fa04bd200c362f..d37396f86a6feaa50ef0e0eba305ab07f8c2e84e 100644
--- a/cores/arduino/SERCOM.cpp
+++ b/cores/arduino/SERCOM.cpp
@@ -8,103 +8,280 @@ SERCOM::SERCOM(Sercom* sercom)
 	sercomSpi = sercom->SPI;
 }
 
+/* 	=========================
+ *	===== Sercom UART
+ *	=========================
+*/
 void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
 {
 	resetUART();
 	
-	sercomUart->CTRLA.reg =		SERCOM_UART_CTRLA_MODE(mode) |
+	//Setting the CTRLA register
+	sercom->USART.CTRLA.reg =	SERCOM_UART_CTRLA_MODE(mode) |
 								SERCOM_USART_CTRLA_SAMPR(sampleRate);
 
+	//
 	if(mode == UART_INT_CLOCK)
 	{
 		uint32_t sampleRateValue;	
+		
 		if(sampleRate == SAMPLE_RATE_x16)
-		{
 			sampleRateValue = 16;
-		}
 		else if(sampleRate == SAMPLE_RATE_x8)
-		{
 			sampleRateValue = 8;
-		}
 		else
-		{
 			sampleRateValue = 3;
-		}
-
+		
 		//Asynchronous arithmetic mode
-		sercomUart->BAUD.reg = 65535 * ( 1 - sampleRateValue * (baudrate / SERCOM_FREQ_REF));
+		sercom->USART.BAUD.reg = 65535 * ( 1 - sampleRateValue * (baudrate / SERCOM_FREQ_REF));
 	}
 }
-void initFrame(SercomCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits)
+void initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits)
 {
-	sercomUart->CTRLA.reg |=	SERCOM_UART_CTRLA_FORM( (parityMode == NO_PARITY ? 0 : 1) ) |
+	//Setting the CTRLA register
+	sercom->USART.CTRLA.reg |=	SERCOM_UART_CTRLA_FORM( (parityMode == NO_PARITY ? 0 : 1) ) |
 								dataOrder << SERCOM_UART_CTRLA_DORD_Pos;
 
-	sercomUart->CTRLB.reg |=	SERCOM_UART_CTRLB_CHSIZE(charSize) |
+	//Setting the CRTLB register
+	sercom->USART.CTRLB.reg |=	SERCOM_UART_CTRLB_CHSIZE(charSize) |
 								nbStopBits << SERCOM_UART_CTRLB_SBMODE_Pos |
-								(parityMode == NO_PARITY ? 0 : parityMode) << SERCOM_UART_CTRLB_PMODE_Pos |;
+								(parityMode == NO_PARITY ? 0 : parityMode) << SERCOM_UART_CTRLB_PMODE_Pos; //If no parity use default value
 }
 
-void initPads(SercomUartTXPad txPad, SercomUartRXPad rxPad)
+void initPads(SercomUartTXPad txPad, SercomRXPad rxPad)
 {
-	sercomUart->CTRLA.reg |=	SERCOM_UART_CTRLA_TXPO(txPad) |
+	//Setting the CTRLA register
+	sercom->USART.CTRLA.reg |=	SERCOM_UART_CTRLA_TXPO(txPad) |
 								SERCOM_UART_CTRLA_RXPO(rxPad);
 
-	sercomUart->CTRLB.reg |=	SERCOM_UART_CTRLB_TXEN |
+	//Setting the CRTLB register (Enabling Transceiver and Receiver)
+	sercom->USART.CTRLB.reg |=	SERCOM_UART_CTRLB_TXEN |
 								SERCOM_UART_CTRLB_RXEN;
 }
 
 void SERCOM::resetUART()
 {
-	sercomUart->CTRLA.bit.SWRST = 0x1u;
-	while(sercomUart->CTRLA.bit.SWRST || sercomUart->SYNCBUSY.SWRST);
+	//Setting  the Software bit to 1
+	sercom->USART.CTRLA.bit.SWRST = 0x1u;
+	
+	//Wait for both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
+	while(sercom->USART.CTRLA.bit.SWRST || sercom->USART.SYNCBUSY.SWRST);
 }
 
 void SERCOM::enableUART()
 {
-	sercomUart->CTRLA.bit.ENABLE = 0x1u;
+	//Setting  the enable bit to 1
+	sercom->USART.CTRLA.bit.ENABLE = 0x1u;
+	
+	//Wait for then enable bit from SYNCBUSY is equal to 0;
+	while(sercom->USART.SYNCBUSY.bit.ENABLE);
 }
 
 void SERCOM::flushUART()
 {
-	while(sercomUart->INTFLAG.bit.DRE != SERCOM_USART_INTFLAG_DRE);
+	// Wait for transmission to complete
+	while(sercom->USART.INTFLAG.bit.DRE != SERCOM_USART_INTFLAG_DRE);
 }
 
 void SERCOM::clearStatusUART()
 {
-	sercomUart->STATUS.reg = SERCOM_USART_STATUS_RESETVALUE;
+	//Reset (with 0) the STATUS register
+	sercom->USART.STATUS.reg = SERCOM_USART_STATUS_RESETVALUE;
 }
 
 bool SERCOM::availableDataUART()
 {
-	return sercomUart->INTFLAG.bit.RXC;
+	//RXC : Receive Complete
+	return sercom->USART.INTFLAG.bit.RXC;
 }
 
 bool SERCOM::isBufferOverflowErrorUART()
 {
-	return sercomUart->STATUS.bit.BUFOVF;
+	//BUFOVF : Buffer Overflow
+	return sercom->USART.STATUS.bit.BUFOVF;
 }
 
 bool SERCOM::isFrameErrorUART()
 {
-	return sercomUart->STATUS.bit.FERR;
+	//FERR : Frame Error
+	return sercom->USART.STATUS.bit.FERR;
 }
 
 bool SERCOM::isParityErrorUART()
 {
-	return sercomUart->STATUS.bit.PERR;
+	//PERR : Parity Error
+	return sercom->USART.STATUS.bit.PERR;
+}
+
+bool SERCOM::isDataRegisterEmptyUART()
+{
+	//DRE : Data Register Empty
+	return sercom->USART.INTFLAG.bit.DRE;
 }
 
 uint8_t SERCOM::readDataUART()
 {
-	return sercomUart->DATA.bit.DATA;
+	return sercom->USART.DATA.bit.DATA;
 }
 
 int SERCOM::writeDataUART(uint8_t data)
 {
+	//Flush UART buffer
 	flushUART();
 
-	sercomUart->DATA.bit.DATA = data;
+	//Put data into DATA register
+	sercom->USART.DATA.bit.DATA = data;
 	return 1;
 }
 
+/*	=========================
+ *	===== Sercom SPI
+ *	=========================
+*/
+void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
+{
+	resetSPI();
+	
+	//Setting the CTRLA register
+	sercom->SPI.CTRLA.reg =	SERCOM_SPI_CTRLA_MODE(SPI_MASTER_OPERATION) |
+							SERCOM_SPI_CTRLA_DOPO(mosi) |
+							SERCOM_SPI_CTRLA_DIPO(miso) |
+							dataOrder << SERCOM_SPI_CTRLA_DORD_Pos;
+	
+	//Setting the CTRLB register
+	sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) |
+							(0x1ul) << SERCOM_SPI_CTRLB_RXEN_Pos;	//Active the SPI receiver.
+}
+
+void SERCOM::initClock(SercomSpiClockMode clockMode, uint32_t baudrate)
+{
+	//Extract data from clockMode
+	int cpha, cpol;
+	
+	if((clockMode & (0x1ul)) == 0 )	
+		cpha = 0;
+	else
+		cpha = 1;
+		
+	if((clockMode & (0x2ul)) == 0)
+		cpol = 0;
+	else
+		cpol = 1;
+		
+	//Setting the CTRLA register
+	sercom->SPI.CTRLA.reg |=	cpha << SERCOM_SPI_CTRLA_CPHA_Pos |
+								cpol << SERCOM_SPI_CTRLA_CPOL_Pos;
+	
+	//Synchronous arithmetic
+	sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(baudrate);
+}
+
+void SERCOM::resetSPI()
+{
+	//Set the Software bit to 1
+	sercom->SPI.CTRLA.bit.SWRST = 0x1u;
+
+	//Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
+	while(sercom->SPI.CTRLA.bit.SWRST || sercom->SPI.SYNCBUSY.SWRST);
+}
+	
+void SERCOM::enableSPI()
+{
+	//Set the enable bit to 1
+	sercom->SPI.CTRLA.bit.ENABLE = 0x1ul;
+	
+	//Waiting then enable bit from SYNCBUSY is equal to 0;
+	while(sercom->SPI.SYNCBUSY.bit.ENABLE);
+}
+	
+void SERCOM::disableSPI()
+{
+	//Set the enable bit to 0
+	sercom->SPI.CTRLA.bit.ENABLE = 0x0ul;
+	
+	//Waiting then enable bit from SYNCBUSY is equal to 0;
+	while(sercom->SPI.SYNCBUSY.bit.ENABLE);
+}
+
+void setDataOrderSPI(SercomDataOrder dataOrder)
+{
+	//Register enable-protected
+	disableSPI();
+	
+	sercom->SPI.CTRLA.bit.DORD = dataOrder;
+	
+	enableSPI();
+}
+
+void setBaudrateSPI(uint8_t divider)
+{
+	//Can't divide by 0
+	if(baudrate == 0)
+		return;
+		
+	//Register enable-protected
+	disableSPI();
+	
+	sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(SERCOM_FREQ_REF / baudrate);
+	
+	enableSPI();
+}
+
+void setClockModeSPI(SercomSpiClockMode clockMode)
+{
+	int cpha, cpol;
+	if((clockMode & (0x1ul)) == 0)
+		cpha = 0;
+	else
+		cpha = 1;
+
+	if((clockMode & (0x2ul)) == 0)
+		cpol = 0;
+	else
+		cpol = 1;
+
+	//Register enable-protected
+	disableSPI();
+	
+	sercom->SPI.CTRLA.bit.CPOL = cpol;
+	sercom->SPI.CTRLA.bit.CPHA = cpha;
+	
+	enableSPI();
+}
+void writeDataSPI(uint8_t data)
+{
+	sercom->SPI.DATA.bit.DATA = data;
+}
+
+uint8_t readDataSPI()
+{
+	return sercom->SPI.DATA.bit.DATA;
+}
+
+bool SERCOM::isBufferOverflowErrorSPI()
+{
+	return sercom->SPI.STATUS.bit.BUFOVF;
+}
+
+bool SERCOM::isDataRegisterEmptySPI()
+{
+	//DRE : Data Register Empty
+	return sercom->SPI.INTFLAG.bit.DRE;
+}
+
+bool SERCOM::isTransmitCompleteSPI()
+{
+	//TXC : Transmit complete
+	return sercom->SPI.INTFLAG.bit.TXC;
+}
+
+bool SERCOM::isReceiveCompleteSPI()
+{
+	//RXC : Receive complete
+	return sercom->SPI.INTFLAG.bit.RXC;
+}
+
+uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate)
+{
+	return SERCOM_FREQ_REF / (2 * baudrate) - 1;
+}
diff --git a/cores/arduino/SERCOM.h b/cores/arduino/SERCOM.h
index db45139a464c4ac15e19cb2e58188ab56faf7224..a7df4cf1567ea401663776fdef0bfd74464f7400 100644
--- a/cores/arduino/SERCOM.h
+++ b/cores/arduino/SERCOM.h
@@ -49,7 +49,7 @@ typedef enum
 	5_BITS = 0x5u,
 	6_BITS,
 	7_BITS
-} SercomCharSize;
+} SercomUartCharSize;
 
 typedef enum
 {
@@ -57,7 +57,7 @@ typedef enum
 	PAD_1,
 	PAD_2,
 	PAD_3
-} SercomUartRXPad;
+} SercomRXPad;
 
 Vtypedef enum
 {
@@ -76,15 +76,25 @@ typedef enum
 
 typedef enum
 {
-	CPOL_0 = 0,
-	CPOL_1
-} SercomSpiCphaMode;
+	SPI_MODE_0 = 0,	// CPOL : 0  | CPHA : 0
+	SPI_MODE_1,		// CPOL : 0  | CPHA : 1
+	SPI_MODE_2,		// CPOL : 1  | CPHA : 0
+	SPI_MODE_3		// CPOL : 1  | CPHA : 1
+} SercomSpiClockMode;
 
 typedef enum
 {
-	CPHA_0 = 0,
-	CPHA_1
-} SercomSpiCpolMode;
+	PAD_0_SCK_1 = 0,
+	PAD_2_SCK_3,
+	PAD_3_SCK_1,
+	PAD_0_SCK_3
+} SercomSpiTXPad;
+
+typedef enum
+{
+	8_BITS = 0,
+	9_BITS = 1
+} SercomSpiCharSize;
 
 class SERCOM
 {
@@ -93,8 +103,8 @@ class SERCOM
 	
 		/* ========== UART ========== */
 		void initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate=0);
-		void initFrame(SercomCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits);
-		void initPads(SercomUartTXPad txPad, SercomUartRXPad rxPad);
+		void initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits);
+		void initPads(SercomUartTXPad txPad, SercomRXPad rxPad);
 		
 		void resetUART();
 		void enableUART();
@@ -104,17 +114,31 @@ class SERCOM
 		bool isBufferOverflowErrorUART();
 		bool isFrameErrorUART();
 		bool isParityErrorUART();
+		bool isDataRegisterEmptyUART()
 		uint8_t readDataUART();
 		int writeDataUART(uint8_t data);
 
 		/* ========== SPI ========== */
-		void initSPI();
+		void initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder);
+		void initClock(SercomSpiClockMode clockMode, uint32_t baudrate);
+		
+		void resetSPI();
+		void enableSPI();
+		void disableSPI();
+		void setDataOrderSPI(SercomDataOrder dataOrder);
+		void setBaudrateSPI(uint8_t divider);
+		void setClockModeSPI(SercomSpiClockMode clockMode);
+		void writeDataSPI(uint8_t data);
+		uint8_t readDataSPI();
+		bool isBufferOverflowErrorSPI();
+		bool isDataRegisterEmptySPI();
+		bool isTransmitCompleteSPI();
+		bool isReceiveCompleteSPI();
 		
 
 	private:
 		Sercom* sercom;
-		SercomUart* sercomUart;
-		SercomSpi* sercomSpi;
+		uint8_t calculateBaudrateSynchronous(uint32_t baudrate);
 };
 
 #endif
diff --git a/cores/arduino/SERCOMUart.cpp b/cores/arduino/SERCOMUart.cpp
index c3aa4a139514b64d407eb59df53a015328c4b304..ee3767e37b180bfdb174de62c6eaf6ee73ad9d3c 100644
--- a/cores/arduino/SERCOMUart.cpp
+++ b/cores/arduino/SERCOMUart.cpp
@@ -37,7 +37,12 @@ void SERCOMUart::IrqHandler()
 	{
 		rxBuffer.store_char(sercom->readDataUART())
 	}
-
+	
+	if(sercom->isDataRegisterEmptyUART())
+	{
+		writeDataUART(txBuffer.read_char());
+	}
+	
 	if(	sercom->isBufferOverflowErrorUART() ||
 		sercom->isFrameErrorUART() ||
 		sercom->isParityErrorUART())
@@ -46,7 +51,7 @@ void SERCOMUart::IrqHandler()
 	}
 }
 
-bool SERCOMUart::available()
+int SERCOMUart::available()
 {
 	return rxBuffer.available();
 }
@@ -63,7 +68,11 @@ int SERCOMUart::read()
 
 size_t SERCOMUart::write(uint8_t data)
 {
-	return sercom->writeDataUART(data);
+	if(txBuffer.isFull())
+		return 0;
+		
+	txBuffer.store_char(data);
+	return 1;
 }
 
 SercomNumberStopBit extractNbStopBit(uint8_t config)
diff --git a/cores/arduino/SERCOMUart.h b/cores/arduino/SERCOMUart.h
index c1c8d8dfe3d0f34a8241d26695909da10d13f8fd..7d845899e3fb75186d7ed8ba8599a1a77cfbf92b 100644
--- a/cores/arduino/SERCOMUart.h
+++ b/cores/arduino/SERCOMUart.h
@@ -25,6 +25,7 @@ class SERCOMUart
 	private:
 		SERCOM *sercom;
 		RingBuffer rxBuffer;
+		RingBuffer txBuffer;
 
 		SercomNumberStopBit extractNbStopBit(uint8_t config);
 		SercomCharSize extractCharSize(uint8_t config);
diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp
index 9517e22263a272b4dba3b6d7c2b3e8d42763c55e..a2a55c83814e7b48e8b746dfda26a69017054933 100644
--- a/libraries/SPI/SPI.cpp
+++ b/libraries/SPI/SPI.cpp
@@ -10,109 +10,79 @@
 
 #include "SPI.h"
 
-SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)) :
-	spi(_spi), id(_id), initCb(_initCb), initialized(false)
+SPIClass::SPIClass(SERCOM *sercom)
 {
-	// Empty
+	this->sercom = sercom;
 }
 
 void SPIClass::begin() {
-	init();
-
-	// NPCS control is left to the user
-
-	// Default speed set to 4Mhz
-	setClockDivider(BOARD_SPI_DEFAULT_SS, 21);
-	setDataMode(BOARD_SPI_DEFAULT_SS, SPI_MODE0);
-	setBitOrder(BOARD_SPI_DEFAULT_SS, MSBFIRST);
-}
-
-void SPIClass::begin(uint8_t _pin) {
-	init();
-
-	uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
-	PIO_Configure(
-		g_APinDescription[spiPin].pPort,
-		g_APinDescription[spiPin].ulPinType,
-		g_APinDescription[spiPin].ulPin,
-		g_APinDescription[spiPin].ulPinConfiguration);
-
-	// Default speed set to 4Mhz
-	setClockDivider(_pin, 21);
-	setDataMode(_pin, SPI_MODE0);
-	setBitOrder(_pin, MSBFIRST);
-}
-
-void SPIClass::init() {
-	if (initialized)
-		return;
-	initCb();
-	SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS);
-	SPI_Enable(spi);
-	initialized = true;
-}
-
-void SPIClass::end(uint8_t _pin) {
-	uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
-	// Setting the pin as INPUT will disconnect it from SPI peripheral
-	pinMode(spiPin, INPUT);
+	// Default speed set to 4Mhz, SPI mode set to MODE 0 and Bit order set to MSB first.
+	sercom->initSPI(PAD_0_SCK_1, PAD_2, 8_BITS, MSB_FIRST);
+	sercom->initClock(MODE_0, 4000000);
 }
 
 void SPIClass::end() {
-	SPI_Disable(spi);
-	initialized = false;
+	sercom->resetSPI();
 }
 
-void SPIClass::setBitOrder(uint8_t _pin, BitOrder _bitOrder) {
-	uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
-	bitOrder[ch] = _bitOrder;
+void setBitOrder(BitOrder order)
+{
+	if(order == LSBFIRST)
+		sercom->setDataOrderSPI(LSB_FIRST);
+	else
+		sercom->setDataOrderSPI(MSB_FIRST);
 }
 
-void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) {
-	uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
-	mode[ch] = _mode | SPI_CSR_CSAAT;
-	// SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
-	// transfer. Some device needs that for working properly.
-	SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
+void setDataMode(uint8_t mode)
+{
+	switch(mode)
+	{
+		case SPI_MODE0:
+			sercom->setClockModeSPI(MODE_0);
+			break;
+			
+		case SPI_MODE1:
+			sercom->setClockModeSPI(MODE_1);
+			break;
+			
+		case SPI_MODE2:
+			sercom->setClockModeSPI(MODE_2);
+			break;
+			
+		case SPI_MODE3:
+			sercom->setClockModeSPI(MODE_3);
+			break;
+		
+		default:
+			break;
+	}
 }
 
-void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) {
-	uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
-	divider[ch] = _divider;
-	// SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
-	// transfer. Some device needs that for working properly.
-	SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
+void setClockDivider(uint8_t div)
+{
+	sercom->setBaudrateSPI(div);
 }
 
-byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
-	uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
-	// Reverse bit order
-	if (bitOrder[ch] == LSBFIRST)
-		_data = __REV(__RBIT(_data));
-	uint32_t d = _data | SPI_PCS(ch);
-	if (_mode == SPI_LAST)
-		d |= SPI_TDR_LASTXFER;
-
-	// SPI_Write(spi, _channel, _data);
-    while ((spi->SPI_SR & SPI_SR_TDRE) == 0)
-    	;
-    spi->SPI_TDR = d;
-
-    // return SPI_Read(spi);
-    while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
-    	;
-    d = spi->SPI_RDR;
-	// Reverse bit order
-	if (bitOrder[ch] == LSBFIRST)
-		d = __REV(__RBIT(d));
-    return d & 0xFF;
+byte SPIClass::transfer(uint8_t _data)
+{
+	//Can writing new data?
+	while(!sercom->isDataRegisterEmptySPI());
+	
+	//Writing the data
+	sercom->writeDataSPI(data);
+	
+	//Data sent? new data to read?
+	while(!sercom->isTransmitCompleteSPI() || !sercom->isReceiveCompleteSPI());
+	
+	//Read data
+	return sercom->readDataSPI();
 }
 
-void SPIClass::attachInterrupt(void) {
+void SPIClass::attachInterrupt() {
 	// Should be enableInterrupt()
 }
 
-void SPIClass::detachInterrupt(void) {
+void SPIClass::detachInterrupt() {
 	// Should be disableInterrupt()
 }
 
diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h
index 735bd4bf9a517af2c6a5e7f68bf7dde9bf00fdc3..9f3830bf03397d16c40cebc46ea303ef9a0117bd 100644
--- a/libraries/SPI/SPI.h
+++ b/libraries/SPI/SPI.h
@@ -12,57 +12,29 @@
 #define _SPI_H_INCLUDED
 
 #include "variant.h"
-#include <stdio.h>
-
-#define SPI_MODE0 0x02
-#define SPI_MODE1 0x00
-#define SPI_MODE2 0x03
-#define SPI_MODE3 0x01
+#include "SERCOM.h"
 
-enum SPITransferMode {
-	SPI_CONTINUE,
-	SPI_LAST
-};
+#include <stdio.h>
 
 class SPIClass {
   public:
-	SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void));
+	SPIClass(SERCOM *sercom);
 
-	byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST) { return transfer(BOARD_SPI_DEFAULT_SS, _data, _mode); }
-	byte transfer(byte _channel, uint8_t _data, SPITransferMode _mode = SPI_LAST);
+	byte transfer(uint8_t _data);
 
 	// SPI Configuration methods
+	void attachInterrupt();
+	void detachInterrupt();
 
-	void attachInterrupt(void);
-	void detachInterrupt(void);
-
-	void begin(void);
-	void end(void);
-
-	// Attach/Detach pin to/from SPI controller
-	void begin(uint8_t _pin);
-	void end(uint8_t _pin);
-
-	// These methods sets a parameter on a single pin
-	void setBitOrder(uint8_t _pin, BitOrder);
-	void setDataMode(uint8_t _pin, uint8_t);
-	void setClockDivider(uint8_t _pin, uint8_t);
-
-	// These methods sets the same parameters but on default pin BOARD_SPI_DEFAULT_SS
-	void setBitOrder(BitOrder _order) { setBitOrder(BOARD_SPI_DEFAULT_SS, _order); };
-	void setDataMode(uint8_t _mode) { setDataMode(BOARD_SPI_DEFAULT_SS, _mode); };
-	void setClockDivider(uint8_t _div) { setClockDivider(BOARD_SPI_DEFAULT_SS, _div); };
+	void begin();
+	void end();
+	
+	void setBitOrder(BitOrder order);
+	void setDataMode(uint8_t mode);
+	void setClockDivider(uint8_t div);
 
   private:
-	void init();
-
-	Spi *spi;
-	uint32_t id;
-	BitOrder bitOrder[SPI_CHANNELS_NUM];
-	uint32_t divider[SPI_CHANNELS_NUM];
-	uint32_t mode[SPI_CHANNELS_NUM];
-	void (*initCb)(void);
-	bool initialized;
+	SERCOM *sercom;
 };
 
 #if SPI_INTERFACES_COUNT > 0