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