From 8e2a8cbc997923173a99ca351ff326105ebc7d76 Mon Sep 17 00:00:00 2001
From: Thibaut VIARD <thibaut.viard@atmel.com>
Date: Tue, 14 Oct 2014 16:16:27 +0200
Subject: [PATCH]  Adding a test on serial port init

Signed-off-by: Thibaut VIARD <thibaut.viard@atmel.com>
---
 cores/arduino/SERCOM.cpp | 373 ++++++++++++++++++++-------------------
 1 file changed, 189 insertions(+), 184 deletions(-)

diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp
index 9a53c041..d54c755a 100644
--- a/cores/arduino/SERCOM.cpp
+++ b/cores/arduino/SERCOM.cpp
@@ -21,7 +21,7 @@
 
 SERCOM::SERCOM(Sercom* s)
 {
-	sercom = s;
+  sercom = s;
 }
 
 /* 	=========================
@@ -69,21 +69,21 @@ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint
 }
 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 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 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
   sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN ;
@@ -102,68 +102,68 @@ void SERCOM::resetUART()
 
 void SERCOM::enableUART()
 {
-	//Setting  the enable bit to 1
-	sercom->USART.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);
+  //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.DRE != SERCOM_USART_INTFLAG_DRE);
 }
 
 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::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();
+  //Flush UART buffer
+  flushUART();
 
-	//Put data into DATA register
-	sercom->USART.DATA.reg = (uint16_t)data;
-	return 1;
+  //Put data into DATA register
+  sercom->USART.DATA.reg = (uint16_t)data;
+  return 1;
 }
 
 /*	=========================
@@ -172,60 +172,60 @@ int SERCOM::writeDataUART(uint8_t data)
 */
 void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
 {
-	resetSPI();
-	initClockNVIC();
+  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 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.
+  //Setting the CTRLB register
+  sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) |
+                          SERCOM_SPI_CTRLB_RXEN;	//Active the SPI receiver.
 
 
 }
 
 void SERCOM::initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate)
 {
-	//Extract data from clockMode
-	int cpha, cpol;
+  //Extract data from clockMode
+  int cpha, cpol;
 
-	if((clockMode & (0x1ul)) == 0 )
-		cpha = 0;
-	else
-		cpha = 1;
+  if((clockMode & (0x1ul)) == 0 )
+    cpha = 0;
+  else
+    cpha = 1;
 
-	if((clockMode & (0x2ul)) == 0)
-		cpol = 0;
-	else
-		cpol = 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 );
+  //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);
+  //Synchronous arithmetic
+  sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(baudrate);
 }
 
 void SERCOM::resetSPI()
 {
-	//Setting the Software Reset bit to 1
-	sercom->SPI.CTRLA.bit.SWRST = 1;
+  //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);
+  //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;
+  //Setting the enable bit to 1
+  sercom->SPI.CTRLA.bit.ENABLE = 1;
 
-	while(sercom->SPI.SYNCBUSY.bit.ENABLE)
+  while(sercom->SPI.SYNCBUSY.bit.ENABLE)
   {
     //Waiting then enable bit from SYNCBUSY is equal to 0;
   }
@@ -233,10 +233,10 @@ void SERCOM::enableSPI()
 
 void SERCOM::disableSPI()
 {
-	//Setting the enable bit to 0
-	sercom->SPI.CTRLA.bit.ENABLE = 0;
+  //Setting the enable bit to 0
+  sercom->SPI.CTRLA.bit.ENABLE = 0;
 
-	while(sercom->SPI.SYNCBUSY.bit.ENABLE)
+  while(sercom->SPI.SYNCBUSY.bit.ENABLE)
   {
     //Waiting then enable bit from SYNCBUSY is equal to 0;
   }
@@ -244,49 +244,50 @@ void SERCOM::disableSPI()
 
 void SERCOM::setDataOrderSPI(SercomDataOrder dataOrder)
 {
-	//Register enable-protected
-	disableSPI();
+  //Register enable-protected
+  disableSPI();
 
-	sercom->SPI.CTRLA.bit.DORD = dataOrder;
+  sercom->SPI.CTRLA.bit.DORD = dataOrder;
 
-	enableSPI();
+  enableSPI();
 }
 
 void SERCOM::setBaudrateSPI(uint8_t divider)
 {
-	//Can't divide by 0
-	if(divider == 0)
-		return;
+  //Can't divide by 0
+  if(divider == 0)
+    return;
 
-	//Register enable-protected
-	disableSPI();
+  //Register enable-protected
+  disableSPI();
 
-	sercom->SPI.BAUD.reg = calculateBaudrateSynchronous( SERCOM_FREQ_REF / divider );
+  sercom->SPI.BAUD.reg = calculateBaudrateSynchronous( SERCOM_FREQ_REF / divider );
 
-	enableSPI();
+  enableSPI();
 }
 
 void SERCOM::setClockModeSPI(SercomSpiClockMode clockMode)
 {
-	int cpha, cpol;
-	if((clockMode & (0x1ul)) == 0)
-		cpha = 0;
-	else
-		cpha = 1;
+  int cpha, cpol;
+  if((clockMode & (0x1ul)) == 0)
+    cpha = 0;
+  else
+    cpha = 1;
 
-	if((clockMode & (0x2ul)) == 0)
-		cpol = 0;
-	else
-		cpol = 1;
+  if((clockMode & (0x2ul)) == 0)
+    cpol = 0;
+  else
+    cpol = 1;
 
-	//Register enable-protected
-	disableSPI();
+  //Register enable-protected
+  disableSPI();
 
-	sercom->SPI.CTRLA.bit.CPOL = cpol;
-	sercom->SPI.CTRLA.bit.CPHA = cpha;
+  sercom->SPI.CTRLA.bit.CPOL = cpol;
+  sercom->SPI.CTRLA.bit.CPHA = cpha;
 
-	enableSPI();
+  enableSPI();
 }
+
 void SERCOM::writeDataSPI(uint8_t data)
 {
   while( sercom->SPI.INTFLAG.bit.DRE == 0 )
@@ -294,7 +295,7 @@ void SERCOM::writeDataSPI(uint8_t data)
     // 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 )
   {
@@ -309,18 +310,18 @@ uint16_t SERCOM::readDataSPI()
     // Waiting Complete Reception
   }
 
-	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()
@@ -337,24 +338,23 @@ bool SERCOM::isDataRegisterEmptySPI()
 
 uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate)
 {
-	return SERCOM_FREQ_REF / (2 * baudrate) - 1;
+  return SERCOM_FREQ_REF / (2 * baudrate) - 1;
 }
 
 
 /*	=========================
  *	===== Sercom WIRE
  *	=========================
-*/
-
+ */
 void SERCOM::resetWIRE()
 {
-	//I2CM OR I2CS, no matter SWRST is the same bit.
+  //I2CM OR I2CS, no matter SWRST is the same bit.
 
-	//Setting the Software bit to 1
-	sercom->I2CM.CTRLA.bit.SWRST = 1;
+  //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);
+  //Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
+  while(sercom->I2CM.CTRLA.bit.SWRST || sercom->I2CM.SYNCBUSY.bit.SWRST);
 }
 
 void SERCOM::enableWIRE()
@@ -504,67 +504,67 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
 
 bool SERCOM::sendDataMasterWIRE(uint8_t data)
 {
-	//Send data
-	sercom->I2CM.DATA.bit.DATA = data;
+  //Send data
+  sercom->I2CM.DATA.bit.DATA = data;
 
-	//Wait transmission successful
-	while(!sercom->I2CM.INTFLAG.bit.MB);
+  //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;
+  //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;
+  //Send data
+  sercom->I2CS.DATA.bit.DATA = data;
 
-	//Wait data transmission successful
-	while(!sercom->I2CS.INTFLAG.bit.DRDY);
+  //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;
+  //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::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;
 }
 
 bool SERCOM::isMasterReadOperationWIRE( void )
@@ -579,10 +579,10 @@ bool SERCOM::isRXNackReceivedWIRE( void )
 
 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;
 }
 
 uint8_t SERCOM::readDataWIRE( void )
@@ -605,52 +605,57 @@ uint8_t SERCOM::readDataWIRE( void )
 
 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 */
+  }
 }
-- 
GitLab