From 86b6f1060ecdb4a7e958566e671426cc76bcb209 Mon Sep 17 00:00:00 2001
From: Jonathan BAUDIN <jonathan.baudin@atmel.com>
Date: Fri, 9 May 2014 19:51:30 +0200
Subject: [PATCH]  UART class usable

---
 cores/arduino/Arduino.h  |   1 +
 cores/arduino/SERCOM.cpp | 112 ++++++++++++++++++++-------------------
 cores/arduino/SERCOM.h   |   8 +--
 cores/arduino/Uart.cpp   |  16 +++---
 cores/arduino/Uart.h     |   3 +-
 5 files changed, 74 insertions(+), 66 deletions(-)

diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h
index 0eb5eeb1..d8096124 100644
--- a/cores/arduino/Arduino.h
+++ b/cores/arduino/Arduino.h
@@ -82,6 +82,7 @@ typedef void (*voidFuncPtr)( void ) ;
 #include "HardwareSerial.h"
 #include "wiring_pulse.h"
 #include "delay.h"
+#include "Uart.h"
 
 #endif // __cplusplus
 
diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp
index 4fdd9f44..cfd2577d 100644
--- a/cores/arduino/SERCOM.cpp
+++ b/cores/arduino/SERCOM.cpp
@@ -1,5 +1,12 @@
 #include "SERCOM.h"
 
+// Constants for Clock multiplexers
+#define GENERIC_CLOCK_SERCOM0	(0x14ul)
+#define GENERIC_CLOCK_SERCOM1	(0x15ul)
+#define GENERIC_CLOCK_SERCOM2	(0x16ul)
+#define GENERIC_CLOCK_SERCOM3	(0x17ul)
+#define GENERIC_CLOCK_SERCOM4	(0x18ul)
+#define GENERIC_CLOCK_SERCOM5	(0x19ul)
 
 SERCOM::SERCOM(Sercom* s)
 {
@@ -10,27 +17,23 @@ SERCOM::SERCOM(Sercom* s)
  *	===== Sercom UART
  *	=========================
 */
-// Constants for Clock multiplexers
-#define GENERIC_CLOCK_SERCOM0	(0x14ul)
-#define GENERIC_CLOCK_SERCOM1	(0x15ul)
-#define GENERIC_CLOCK_SERCOM2	(0x16ul)
-#define GENERIC_CLOCK_SERCOM3	(0x17ul)
-#define GENERIC_CLOCK_SERCOM4	(0x18ul)
-#define GENERIC_CLOCK_SERCOM5	(0x19ul)
 
 void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
-{
+{		
 	resetUART();
 	initClock();
 	
+	
 	//Setting the CTRLA register
 	sercom->USART.CTRLA.reg =	SERCOM_USART_CTRLA_MODE(mode) |
 								SERCOM_USART_CTRLA_SAMPR(sampleRate);
 
 	//Setting the Interrupt register
-	sercom->USART.INTENSET.reg =	SERCOM_USART_INTENSET_DRE |  //Data Register Empty
-									SERCOM_USART_INTENSET_RXC |  //Received complete
+	sercom->USART.INTENSET.reg =	SERCOM_USART_INTENSET_RXC |  //Received complete
 									SERCOM_USART_INTENSET_ERROR; //All others errors
+									
+	NVIC_EnableIRQ(SERCOM0_IRQn);
+	NVIC_SetPriority (SERCOM0_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
 	
 	if(mode == UART_INT_CLOCK)
 	{
@@ -45,11 +48,11 @@ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint
 		
 		//Asynchronous arithmetic mode
 		//sercom->USART.BAUD.reg = 65535 * ( 1 - sampleRateValue * division(baudrate,SERCOM_FREQ_REF));
-		int tmpBaud = (baudrate / SERCOM_FREQ_REF);
+		uint16_t tmpBaud = (baudrate / SERCOM_FREQ_REF);
 		tmpBaud = ( 1 - sampleRateValue * tmpBaud);
 		tmpBaud = (65535ul) * tmpBaud;
 		
-		tmpBaud = 40369;
+		tmpBaud = 63019;
 		sercom->USART.BAUD.reg = tmpBaud;
 	}
 }
@@ -338,47 +341,6 @@ uint32_t SERCOM::division(uint32_t dividend, uint32_t divisor)
     //return answer;
 }
 
-void SERCOM::initClock()
-{
-	uint8_t clockId;
-	
-	if(sercom == SERCOM0)
-	{
-		clockId = GENERIC_CLOCK_SERCOM0;
-	}
-	else if(sercom == SERCOM1)
-	{
-		clockId = GENERIC_CLOCK_SERCOM1;
-	}
-	else if(sercom == SERCOM2)
-	{
-		clockId = GENERIC_CLOCK_SERCOM2;
-	}
-	else if(sercom == SERCOM3)
-	{
-		clockId = GENERIC_CLOCK_SERCOM3;
-	}
-	else if(sercom == SERCOM4)
-	{
-		clockId = GENERIC_CLOCK_SERCOM4;
-	}
-	else if(sercom == SERCOM5)
-	{
-		clockId = GENERIC_CLOCK_SERCOM5;
-	}
-	
-	//Setting clock
-	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOM0)
-	                    GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
-	                    GCLK_CLKCTRL_CLKEN ;
-						
-
-	while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
-	{
-		/* Wait for synchronization */
-	}
-}
-
 
 /*	=========================
  *	===== Sercom WIRE
@@ -572,6 +534,48 @@ uint8_t SERCOM::readDataWIRE()
 		return sercom->I2CS.DATA.reg;
 }
 
+
+void SERCOM::initClock()
+{
+	uint8_t clockId;
+	
+	if(sercom == SERCOM0)
+	{
+		clockId = GENERIC_CLOCK_SERCOM0;
+	}
+	else if(sercom == SERCOM1)
+	{
+		clockId = GENERIC_CLOCK_SERCOM1;
+	}
+	else if(sercom == SERCOM2)
+	{
+		clockId = GENERIC_CLOCK_SERCOM2;
+	}
+	else if(sercom == SERCOM3)
+	{
+		clockId = GENERIC_CLOCK_SERCOM3;
+	}
+	else if(sercom == SERCOM4)
+	{
+		clockId = GENERIC_CLOCK_SERCOM4;
+	}
+	else if(sercom == SERCOM5)
+	{
+		clockId = GENERIC_CLOCK_SERCOM5;
+	}
+	
+	//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 */
+	}
+}
+
 /*	=========================
  *	===== SERCOM DEFINITION
  *	=========================
@@ -581,4 +585,4 @@ SERCOM * SERCOM::sercom1 = new SERCOM(SERCOM1);
 SERCOM * SERCOM::sercom2 = new SERCOM(SERCOM2);
 SERCOM * SERCOM::sercom3 = new SERCOM(SERCOM3);
 SERCOM * SERCOM::sercom4 = new SERCOM(SERCOM4);
-SERCOM * SERCOM::sercom5 = new SERCOM(SERCOM5);
\ No newline at end of file
+SERCOM * SERCOM::sercom5 = new SERCOM(SERCOM5);
diff --git a/cores/arduino/SERCOM.h b/cores/arduino/SERCOM.h
index 86b2a2ca..c756d81b 100644
--- a/cores/arduino/SERCOM.h
+++ b/cores/arduino/SERCOM.h
@@ -61,10 +61,10 @@ typedef enum
 
 typedef enum
 {
-	UART_TX_PAD_0 = 0,	//Only for Intern Clock
-	UART_TX_PAD_1 = 0,	//Only for Extern Clock
-	UART_TX_PAD_2 = 1,  //Only for Intern Clock
-	UART_TX_PAD_3 = 1	//Only for Extern Clock
+	UART_TX_PAD_0 = 0x0ul,	//Only for UART
+	UART_TX_PAD_2 = 0x1ul,  //Only for UART
+	//UART_TX_PAD_1 = 0x0ul,	//DON'T USE
+	//UART_TX_PAD_3 = 0x1ul	//DON'T USE
 } SercomUartTXPad;
 
 typedef enum
diff --git a/cores/arduino/Uart.cpp b/cores/arduino/Uart.cpp
index 954a126a..819d07be 100644
--- a/cores/arduino/Uart.cpp
+++ b/cores/arduino/Uart.cpp
@@ -4,6 +4,8 @@
 Uart::Uart(SERCOM *sercom)
 {
 	this->sercom = sercom;
+	pinPeripheral(0, PIO_SERCOM);
+	pinPeripheral(1, PIO_SERCOM);
 }
 
 void Uart::begin(unsigned long baudrate)
@@ -15,7 +17,8 @@ void Uart::begin(unsigned long baudrate, uint8_t config)
 {
 	sercom->initUART(UART_INT_CLOCK, SAMPLE_RATE_x16, baudrate);
 	sercom->initFrame(extractCharSize(config), LSB_FIRST, extractParity(config), extractNbStopBit(config));
-	sercom->initPads(UART_TX_PAD_0, SERCOM_RX_PAD_2);
+	sercom->initPads(UART_TX_PAD_2, SERCOM_RX_PAD_3);
+	
 	
 	sercom->enableUART();
 }
@@ -38,11 +41,6 @@ void Uart::IrqHandler()
 		rxBuffer.store_char(sercom->readDataUART());
 	}
 	
-	if(sercom->isDataRegisterEmptyUART())
-	{
-		sercom->writeDataUART(txBuffer.read_char());
-	}
-	
 	if(	sercom->isBufferOverflowErrorUART() ||
 		sercom->isFrameErrorUART() ||
 		sercom->isParityErrorUART())
@@ -139,4 +137,8 @@ Uart Serial = Uart(SERCOM::sercom0);
 void SERCOM0_Handler()
 {
 	Serial.IrqHandler();
-}
\ No newline at end of file
+}
+void SERCOM5_Handler()
+{
+	Serial.IrqHandler();
+}
diff --git a/cores/arduino/Uart.h b/cores/arduino/Uart.h
index 84ea558d..64f8ec03 100644
--- a/cores/arduino/Uart.h
+++ b/cores/arduino/Uart.h
@@ -1,6 +1,8 @@
 #ifndef _SERCOM_UART_CLASS
 #define _SERCOM_UART_CLASS
 
+#include "wiring_digital.h"
+
 #include "HardwareSerial.h"
 #include "SERCOM.h"
 #include "RingBuffer.h"
@@ -29,7 +31,6 @@ class Uart : public HardwareSerial
 	private:
 		SERCOM *sercom;
 		RingBuffer rxBuffer;
-		RingBuffer txBuffer;
 
 		SercomNumberStopBit extractNbStopBit(uint8_t config);
 		SercomUartCharSize extractCharSize(uint8_t config);
-- 
GitLab