Skip to content
Snippets Groups Projects
Commit 86b6f106 authored by Jonathan BAUDIN's avatar Jonathan BAUDIN
Browse files

UART class usable

parent 0eca3bd6
No related branches found
No related tags found
No related merge requests found
......@@ -82,6 +82,7 @@ typedef void (*voidFuncPtr)( void ) ;
#include "HardwareSerial.h"
#include "wiring_pulse.h"
#include "delay.h"
#include "Uart.h"
#endif // __cplusplus
......
#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);
......@@ -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
......
......@@ -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();
}
#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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment