Index: rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/SERCOM.cpp
===================================================================
--- rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/SERCOM.cpp	(revision 136)
+++ rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/SERCOM.cpp	(revision 175)
@@ -1,8 +1,27 @@
+/*
+  Copyright (c) 2014 Arduino.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
 #include "SERCOM.h"
 #include "variant.h"
 
+
 SERCOM::SERCOM(Sercom* s)
 {
-	sercom = s;
+  sercom = s;
 }
 
@@ -13,6 +32,6 @@
 void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
 {
+  initClockNVIC();
   resetUART();
-  initClockNVIC();
 
   //Setting the CTRLA register
@@ -26,45 +45,38 @@
   if ( mode == UART_INT_CLOCK )
   {
-    uint16_t sampleRateValue ;
-
-    if ( sampleRate == SAMPLE_RATE_x16 )
-    {
-      sampleRateValue = 16 ;
+    uint16_t sampleRateValue;
+
+    if (sampleRate == SAMPLE_RATE_x16) {
+      sampleRateValue = 16;
+    } else {
+      sampleRateValue = 8;
     }
-    else
-    {
-      if ( sampleRate == SAMPLE_RATE_x8 )
-      {
-        sampleRateValue = 8 ;
-      }
-      else
-      {
-        sampleRateValue = 3 ;
-      }
-    }
-
-    // Asynchronous arithmetic mode
-    // 65535 * ( 1 - sampleRateValue * baudrate / SystemCoreClock);
-    // 65535 - 65535 * (sampleRateValue * baudrate / SystemCoreClock));
-    sercom->USART.BAUD.reg = 65535.0f * ( 1.0f - (float)(sampleRateValue) * (float)(baudrate) / (float)(SystemCoreClock));
+
+    // Asynchronous fractional mode (Table 24-2 in datasheet)
+    //   BAUD = fref / (sampleRateValue * fbaud)
+    // (multiply by 8, to calculate fractional piece)
+    uint32_t baudTimes8 = (SystemCoreClock * 8) / (sampleRateValue * baudrate);
+
+    sercom->USART.BAUD.FRAC.FP   = (baudTimes8 % 8);
+    sercom->USART.BAUD.FRAC.BAUD = (baudTimes8 / 8);
   }
 }
 void SERCOM::initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits)
 {
-	//Setting the CTRLA register
-	sercom->USART.CTRLA.reg |=	SERCOM_USART_CTRLA_FORM( (parityMode == SERCOM_NO_PARITY ? 0 : 1) ) |
-								dataOrder << SERCOM_USART_CTRLA_DORD_Pos;
-
-	//Setting the CTRLB register
-	sercom->USART.CTRLB.reg |=	SERCOM_USART_CTRLB_CHSIZE(charSize) |
-								nbStopBits << SERCOM_USART_CTRLB_SBMODE_Pos |
-								(parityMode == SERCOM_NO_PARITY ? 0 : parityMode) << SERCOM_USART_CTRLB_PMODE_Pos; //If no parity use default value
+  //Setting the CTRLA register
+  sercom->USART.CTRLA.reg |=	SERCOM_USART_CTRLA_FORM( (parityMode == SERCOM_NO_PARITY ? 0 : 1) ) |
+                dataOrder << SERCOM_USART_CTRLA_DORD_Pos;
+
+  //Setting the CTRLB register
+  sercom->USART.CTRLB.reg |=	SERCOM_USART_CTRLB_CHSIZE(charSize) |
+                nbStopBits << SERCOM_USART_CTRLB_SBMODE_Pos |
+                (parityMode == SERCOM_NO_PARITY ? 0 : parityMode) << SERCOM_USART_CTRLB_PMODE_Pos; //If no parity use default value
 }
 
 void SERCOM::initPads(SercomUartTXPad txPad, SercomRXPad rxPad)
 {
-	//Setting the CTRLA register
-	sercom->USART.CTRLA.reg |=	SERCOM_USART_CTRLA_TXPO(txPad) |
-								SERCOM_USART_CTRLA_RXPO(rxPad);
+  //Setting the CTRLA register
+  sercom->USART.CTRLA.reg |=	SERCOM_USART_CTRLA_TXPO(txPad) |
+                SERCOM_USART_CTRLA_RXPO(rxPad);
 
   // Enable Transceiver and Receiver
@@ -85,66 +97,76 @@
 void SERCOM::enableUART()
 {
-	//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);
+  //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()
 {
-	// Wait for transmission to complete
-	while(sercom->USART.INTFLAG.bit.DRE != SERCOM_USART_INTFLAG_DRE);
+  // Wait for transmission to complete
+  while(!sercom->USART.INTFLAG.bit.TXC);
 }
 
 void SERCOM::clearStatusUART()
 {
-	//Reset (with 0) the STATUS register
-	sercom->USART.STATUS.reg = SERCOM_USART_STATUS_RESETVALUE;
+  //Reset (with 0) the STATUS register
+  sercom->USART.STATUS.reg = SERCOM_USART_STATUS_RESETVALUE;
 }
 
 bool SERCOM::availableDataUART()
 {
-	//RXC : Receive Complete
-	return sercom->USART.INTFLAG.bit.RXC;
+  //RXC : Receive Complete
+  return sercom->USART.INTFLAG.bit.RXC;
+}
+
+bool SERCOM::isUARTError()
+{
+  return sercom->USART.INTFLAG.bit.ERROR;
+}
+
+void SERCOM::acknowledgeUARTError()
+{
+  sercom->USART.INTFLAG.bit.ERROR = 1;
 }
 
 bool SERCOM::isBufferOverflowErrorUART()
 {
-	//BUFOVF : Buffer Overflow
-	return sercom->USART.STATUS.bit.BUFOVF;
+  //BUFOVF : Buffer Overflow
+  return sercom->USART.STATUS.bit.BUFOVF;
 }
 
 bool SERCOM::isFrameErrorUART()
 {
-	//FERR : Frame Error
-	return sercom->USART.STATUS.bit.FERR;
+  //FERR : Frame Error
+  return sercom->USART.STATUS.bit.FERR;
 }
 
 bool SERCOM::isParityErrorUART()
 {
-	//PERR : Parity Error
-	return sercom->USART.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;
+  //DRE : Data Register Empty
+  return sercom->USART.INTFLAG.bit.DRE;
 }
 
 uint8_t SERCOM::readDataUART()
 {
-	return sercom->USART.DATA.bit.DATA;
+  return sercom->USART.DATA.bit.DATA;
 }
 
 int SERCOM::writeDataUART(uint8_t data)
 {
-	//Flush UART buffer
-	flushUART();
-
-	//Put data into DATA register
-	sercom->USART.DATA.reg = (uint16_t)data;
-	return 1;
+  // Wait for data register to be empty
+  while(!isDataRegisterEmptyUART());
+
+  //Put data into DATA register
+  sercom->USART.DATA.reg = (uint16_t)data;
+  return 1;
 }
 
@@ -155,58 +177,73 @@
 void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
 {
+  resetSPI();
+  initClockNVIC();
+
+  //Setting the CTRLA register
+  sercom->SPI.CTRLA.reg =	SERCOM_SPI_CTRLA_MODE_SPI_MASTER |
+                          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) |
+                          SERCOM_SPI_CTRLB_RXEN;	//Active the SPI receiver.
+
+
+}
+
+void SERCOM::initSPIslave(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
+{
 	resetSPI();
 	initClockNVIC();
 
-	//Setting the CTRLA register
-	sercom->SPI.CTRLA.reg =	SERCOM_SPI_CTRLA_MODE_SPI_MASTER |
-							            SERCOM_SPI_CTRLA_DOPO(mosi) |
-							            SERCOM_SPI_CTRLA_DIPO(miso) |
-							            dataOrder << SERCOM_SPI_CTRLA_DORD_Pos;
-
-	//Setting the CTRLB register
+	sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_SLAVE |
+							            SERCOM_SPI_CTRLA_DOPO(mosi) |  //provo a modificare
+							            SERCOM_SPI_CTRLA_DIPO(miso) |  //provo a modificare
+							            dataOrder << SERCOM_SPI_CTRLA_DORD_Pos;					            
+
 	sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) |
-							            SERCOM_SPI_CTRLB_RXEN;	//Active the SPI receiver.
-
-
+							            SERCOM_SPI_CTRLB_RXEN; 	//Active the SPI receiver.
+										
 }
 
 void SERCOM::initSPIClock(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);
+  //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()
 {
-	//Setting the Software Reset bit to 1
-	sercom->SPI.CTRLA.bit.SWRST = 1;
-
-	//Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
-	while(sercom->SPI.CTRLA.bit.SWRST || sercom->SPI.SYNCBUSY.bit.SWRST);
+  //Setting the Software Reset bit to 1
+  sercom->SPI.CTRLA.bit.SWRST = 1;
+
+  //Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
+  while(sercom->SPI.CTRLA.bit.SWRST || sercom->SPI.SYNCBUSY.bit.SWRST);
 }
 
 void SERCOM::enableSPI()
 {
-	//Setting the enable bit to 1
-	sercom->SPI.CTRLA.bit.ENABLE = 1;
-
-	while(sercom->SPI.SYNCBUSY.bit.ENABLE)
+  //Setting the enable bit to 1
+  sercom->SPI.CTRLA.bit.ENABLE = 1;
+
+  while(sercom->SPI.SYNCBUSY.bit.ENABLE)
   {
     //Waiting then enable bit from SYNCBUSY is equal to 0;
@@ -216,8 +253,8 @@
 void SERCOM::disableSPI()
 {
-	//Setting the enable bit to 0
-	sercom->SPI.CTRLA.bit.ENABLE = 0;
-
-	while(sercom->SPI.SYNCBUSY.bit.ENABLE)
+  //Setting the enable bit to 0
+  sercom->SPI.CTRLA.bit.ENABLE = 0;
+
+  while(sercom->SPI.SYNCBUSY.bit.ENABLE)
   {
     //Waiting then enable bit from SYNCBUSY is equal to 0;
@@ -227,47 +264,53 @@
 void SERCOM::setDataOrderSPI(SercomDataOrder dataOrder)
 {
-	//Register enable-protected
-	disableSPI();
-
-	sercom->SPI.CTRLA.bit.DORD = dataOrder;
-
-	enableSPI();
-}
-
-void SERCOM::setBaudrateSPI(uint8_t divider)
-{
-	//Can't divide by 0
-	if(divider == 0)
-		return;
-
-	//Register enable-protected
-	disableSPI();
-
-	sercom->SPI.BAUD.reg = calculateBaudrateSynchronous( SERCOM_FREQ_REF / divider );
-
-	enableSPI();
+  //Register enable-protected
+  disableSPI();
+
+  sercom->SPI.CTRLA.bit.DORD = dataOrder;
+
+  enableSPI();
+}
+
+SercomDataOrder SERCOM::getDataOrderSPI()
+{
+  return (sercom->SPI.CTRLA.bit.DORD ? LSB_FIRST : MSB_FIRST);
+}
+
+void SERCOM::setBaudrateSPI(uint16_t divider)
+{
+  //Can't divide by 0
+  if(divider == 0)
+    return;
+
+  //Register enable-protected
+  disableSPI();
+
+  sercom->SPI.BAUD.reg = calculateBaudrateSynchronous( SERCOM_FREQ_REF / divider );
+
+  enableSPI();
 }
 
 void SERCOM::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();
-}
+  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 SERCOM::writeDataSPI(uint8_t data)
 {
@@ -276,6 +319,5 @@
     // Waiting Data Registry Empty
   }
-
-	sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register
+  sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register
 
   while( sercom->SPI.INTFLAG.bit.TXC == 0 || sercom->SPI.INTFLAG.bit.DRE == 0 )
@@ -292,21 +334,33 @@
   }
 
-	return sercom->SPI.DATA.bit.DATA;  // Reading data
+  return sercom->SPI.DATA.bit.DATA;  // Reading data
 }
 
 bool SERCOM::isBufferOverflowErrorSPI()
 {
-	return sercom->SPI.STATUS.bit.BUFOVF;
+  return sercom->SPI.STATUS.bit.BUFOVF;
 }
 
 bool SERCOM::isDataRegisterEmptySPI()
 {
-	//DRE : Data Register Empty
-	return sercom->SPI.INTFLAG.bit.DRE;
-}
+  //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;
+  return SERCOM_FREQ_REF / (2 * baudrate) - 1;
 }
 
@@ -315,15 +369,14 @@
  *	===== Sercom WIRE
  *	=========================
-*/
-
+ */
 void SERCOM::resetWIRE()
 {
-	//I2CM OR I2CS, no matter SWRST is the same bit.
-
-	//Setting the Software bit to 1
-	sercom->I2CM.CTRLA.bit.SWRST = 1;
-
-	//Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
-	while(sercom->I2CM.CTRLA.bit.SWRST || sercom->I2CM.SYNCBUSY.bit.SWRST);
+  //I2CM OR I2CS, no matter SWRST is the same bit.
+
+  //Setting the Software bit to 1
+  sercom->I2CM.CTRLA.bit.SWRST = 1;
+
+  //Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
+  while(sercom->I2CM.CTRLA.bit.SWRST || sercom->I2CM.SYNCBUSY.bit.SWRST);
 }
 
@@ -371,13 +424,11 @@
   sercom->I2CS.CTRLA.bit.MODE = I2C_SLAVE_OPERATION ;
 
-  // Enable Quick Command
-  sercom->I2CM.CTRLB.bit.QCEN = 1 ;
-
   sercom->I2CS.ADDR.reg = SERCOM_I2CS_ADDR_ADDR( ucAddress & 0x7Ful ) | // 0x7F, select only 7 bits
-                          SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ;        // 0x3FF all bits set
+                          SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ;    // 0x3FF all bits set
 
   // Set the interrupt register
-  sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_AMATCH |             // Address Match
-                              SERCOM_I2CS_INTENSET_DRDY ;               // Data Ready
+  sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_PREC |   // Stop
+                              SERCOM_I2CS_INTENSET_AMATCH | // Address Match
+                              SERCOM_I2CS_INTENSET_DRDY ;   // Data Ready
 
   while ( sercom->I2CM.SYNCBUSY.bit.SYSOP != 0 )
@@ -395,9 +446,13 @@
 
   // Set master mode and enable SCL Clock Stretch mode (stretch after ACK bit)
-  sercom->I2CM.CTRLA.reg =  SERCOM_I2CM_CTRLA_MODE( I2C_MASTER_OPERATION );
+  sercom->I2CM.CTRLA.reg =  SERCOM_I2CM_CTRLA_MODE( I2C_MASTER_OPERATION )/* |
+                            SERCOM_I2CM_CTRLA_SCLSM*/ ;
 
   // Enable Smart mode and Quick Command
+  //sercom->I2CM.CTRLB.reg =  SERCOM_I2CM_CTRLB_SMEN /*| SERCOM_I2CM_CTRLB_QCEN*/ ;
+
 
   // Enable all interrupts
+//  sercom->I2CM.INTENSET.reg = SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB | SERCOM_I2CM_INTENSET_ERROR ;
 
   // Synchronous arithmetic baudrate
@@ -407,21 +462,33 @@
 void SERCOM::prepareNackBitWIRE( void )
 {
-  // Send a NACK
-  sercom->I2CM.CTRLB.bit.ACKACT = 1;
+  if(isMasterWIRE()) {
+    // Send a NACK
+    sercom->I2CM.CTRLB.bit.ACKACT = 1;
+  } else {
+    sercom->I2CS.CTRLB.bit.ACKACT = 1;
+  }
 }
 
 void SERCOM::prepareAckBitWIRE( void )
 {
-  // Send an ACK
-  sercom->I2CM.CTRLB.bit.ACKACT = 0;
-}
-
-void SERCOM::prepareCommandBitsWire(SercomMasterCommandWire cmd)
-{
-  sercom->I2CM.CTRLB.bit.CMD = cmd;
-
-  while(sercom->I2CM.SYNCBUSY.bit.SYSOP)
-  {
-    // Waiting for synchronization
+  if(isMasterWIRE()) {
+    // Send an ACK
+    sercom->I2CM.CTRLB.bit.ACKACT = 0;
+  } else {
+    sercom->I2CS.CTRLB.bit.ACKACT = 0;
+  }
+}
+
+void SERCOM::prepareCommandBitsWire(uint8_t cmd)
+{
+  if(isMasterWIRE()) {
+    sercom->I2CM.CTRLB.bit.CMD = cmd;
+
+    while(sercom->I2CM.SYNCBUSY.bit.SYSOP)
+    {
+      // Waiting for synchronization
+    }
+  } else {
+    sercom->I2CS.CTRLB.bit.CMD = cmd;
   }
 }
@@ -432,9 +499,11 @@
   address = (address << 0x1ul) | flag;
 
-  // Wait idle bus mode
-  while ( !isBusIdleWIRE() );
+
+  // Wait idle or owner bus mode
+  while ( !isBusIdleWIRE() && !isBusOwnerWIRE() );
 
   // Send start and address
   sercom->I2CM.ADDR.bit.ADDR = address;
+  
 
   // Address Transmitted
@@ -450,4 +519,10 @@
     while( !sercom->I2CM.INTFLAG.bit.SB )
     {
+        // If the slave NACKS the address, the MB bit will be set.
+        // In that case, send a stop condition and return false.
+        if (sercom->I2CM.INTFLAG.bit.MB) {
+            sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition
+            return false;
+        }
       // Wait transmission complete
     }
@@ -471,65 +546,77 @@
 bool SERCOM::sendDataMasterWIRE(uint8_t data)
 {
-	//Send data
-	sercom->I2CM.DATA.bit.DATA = data;
-
-	//Wait transmission successful
-	while(!sercom->I2CM.INTFLAG.bit.MB);
-
-	//Problems on line? nack received?
-	if(sercom->I2CM.STATUS.bit.RXNACK)
-		return false;
-	else
-		return true;
+  //Send data
+  sercom->I2CM.DATA.bit.DATA = data;
+
+  //Wait transmission successful
+  while(!sercom->I2CM.INTFLAG.bit.MB) {
+
+    // If a bus error occurs, the MB bit may never be set.
+    // Check the bus error bit and bail if it's set.
+    if (sercom->I2CM.STATUS.bit.BUSERR) {
+      return false;
+    }
+  }
+
+  //Problems on line? nack received?
+  if(sercom->I2CM.STATUS.bit.RXNACK)
+    return false;
+  else
+    return true;
 }
 
 bool SERCOM::sendDataSlaveWIRE(uint8_t data)
 {
-	//Send data
-	sercom->I2CS.DATA.bit.DATA = data;
-
-	//Wait data transmission successful
-	while(!sercom->I2CS.INTFLAG.bit.DRDY);
-
-	//Problems on line? nack received?
-	if(sercom->I2CS.STATUS.bit.RXNACK)
-		return false;
-	else
-		return true;
+  //Send data
+  sercom->I2CS.DATA.bit.DATA = data;
+
+  //Wait data transmission successful
+  while(!sercom->I2CS.INTFLAG.bit.DRDY);
+
+  //Problems on line? nack received?
+  if(sercom->I2CS.STATUS.bit.RXNACK)
+    return false;
+  else
+    return true;
 }
 
 bool SERCOM::isMasterWIRE( void )
 {
-	return sercom->I2CS.CTRLA.bit.MODE == I2C_MASTER_OPERATION;
+  return sercom->I2CS.CTRLA.bit.MODE == I2C_MASTER_OPERATION;
 }
 
 bool SERCOM::isSlaveWIRE( void )
 {
-	return sercom->I2CS.CTRLA.bit.MODE == I2C_SLAVE_OPERATION;
+  return sercom->I2CS.CTRLA.bit.MODE == I2C_SLAVE_OPERATION;
 }
 
 bool SERCOM::isBusIdleWIRE( void )
 {
-	return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_IDLE_STATE;
+  return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_IDLE_STATE;
+}
+
+bool SERCOM::isBusOwnerWIRE( void )
+{
+  return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_OWNER_STATE;
 }
 
 bool SERCOM::isDataReadyWIRE( void )
 {
-	return sercom->I2CS.INTFLAG.bit.DRDY;
+  return sercom->I2CS.INTFLAG.bit.DRDY;
 }
 
 bool SERCOM::isStopDetectedWIRE( void )
 {
-	return sercom->I2CS.INTFLAG.bit.PREC;
+  return sercom->I2CS.INTFLAG.bit.PREC;
 }
 
 bool SERCOM::isRestartDetectedWIRE( void )
 {
-	return sercom->I2CS.STATUS.bit.SR;
+  return sercom->I2CS.STATUS.bit.SR;
 }
 
 bool SERCOM::isAddressMatch( void )
 {
-	return sercom->I2CS.INTFLAG.bit.AMATCH;
+  return sercom->I2CS.INTFLAG.bit.AMATCH;
 }
 
@@ -546,8 +633,8 @@
 int SERCOM::availableWIRE( void )
 {
-	if(isMasterWIRE())
-		return sercom->I2CM.INTFLAG.bit.SB;
-	else
-		return sercom->I2CS.INTFLAG.bit.DRDY;
+  if(isMasterWIRE())
+    return sercom->I2CM.INTFLAG.bit.SB;
+  else
+    return sercom->I2CS.INTFLAG.bit.DRDY;
 }
 
@@ -572,51 +659,56 @@
 void SERCOM::initClockNVIC( void )
 {
-	uint8_t clockId = 0;
-	IRQn_Type IdNvic;
-
-	if(sercom == SERCOM0)
-	{
-		clockId = GCM_SERCOM0_CORE;
-		IdNvic = SERCOM0_IRQn;
-	}
-	else if(sercom == SERCOM1)
-	{
-		clockId = GCM_SERCOM1_CORE;
-		IdNvic = SERCOM1_IRQn;
-	}
-	else if(sercom == SERCOM2)
-	{
-		clockId = GCM_SERCOM2_CORE;
-		IdNvic = SERCOM2_IRQn;
-	}
-	else if(sercom == SERCOM3)
-	{
-		clockId = GCM_SERCOM3_CORE;
-		IdNvic = SERCOM3_IRQn;
-	}
-	else if(sercom == SERCOM4)
-	{
-		clockId = GCM_SERCOM4_CORE;
-		IdNvic = SERCOM4_IRQn;
-	}
-	else if(sercom == SERCOM5)
-	{
-		clockId = GCM_SERCOM5_CORE;
-		IdNvic = SERCOM5_IRQn;
-	}
-
-	// Setting NVIC
-	NVIC_EnableIRQ(IdNvic);
-	NVIC_SetPriority (IdNvic, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority */
-
-	//Setting clock
-	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) |       // Generic Clock 0 (SERCOMx)
-						          GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
-						          GCLK_CLKCTRL_CLKEN ;
-
-	while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
-	{
-		/* Wait for synchronization */
-	}
-
-}
+  uint8_t clockId = 0;
+  IRQn_Type IdNvic=PendSV_IRQn ; // Dummy init to intercept potential error later
+
+  if(sercom == SERCOM0)
+  {
+    clockId = GCM_SERCOM0_CORE;
+    IdNvic = SERCOM0_IRQn;
+  }
+  else if(sercom == SERCOM1)
+  {
+    clockId = GCM_SERCOM1_CORE;
+    IdNvic = SERCOM1_IRQn;
+  }
+  else if(sercom == SERCOM2)
+  {
+    clockId = GCM_SERCOM2_CORE;
+    IdNvic = SERCOM2_IRQn;
+  }
+  else if(sercom == SERCOM3)
+  {
+    clockId = GCM_SERCOM3_CORE;
+    IdNvic = SERCOM3_IRQn;
+  }
+  else if(sercom == SERCOM4)
+  {
+    clockId = GCM_SERCOM4_CORE;
+    IdNvic = SERCOM4_IRQn;
+  }
+  else if(sercom == SERCOM5)
+  {
+    clockId = GCM_SERCOM5_CORE;
+    IdNvic = SERCOM5_IRQn;
+  }
+
+  if ( IdNvic == PendSV_IRQn )
+  {
+    // We got a problem here
+    return ;
+  }
+
+  // Setting NVIC
+  NVIC_EnableIRQ(IdNvic);
+  NVIC_SetPriority (IdNvic, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority */
+
+  //Setting clock
+  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx)
+                      GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
+                      GCLK_CLKCTRL_CLKEN ;
+
+  while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
+  {
+    /* Wait for synchronization */
+  }
+}
