cpu/samd21: added cpu clock configuration

- choosable between PLL and internal 8MHz osciallator
- configurable to a wide range of frequencies
This commit is contained in:
Hauke Petersen 2015-05-19 18:12:40 +02:00
parent acb06d8fe8
commit 164721657d
6 changed files with 118 additions and 83 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2014 Freie Universität Berlin * Copyright (C) 2015 Freie Universität Berlin
* *
* This file is subject to the terms and conditions of the GNU Lesser * This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level * General Public License v2.1. See the file LICENSE in the top level
@ -14,22 +14,80 @@
* @brief Implementation of the CPU initialization * @brief Implementation of the CPU initialization
* *
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de> * @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @} * @}
*/ */
#include "cpu.h" #include "cpu.h"
#include "periph_conf.h"
void clk_init(void);
/** /**
* @brief Initialize the CPU, set IRQ priorities * @brief Configure clock sources and the cpu frequency
*/ */
static void clk_init(void)
{
/* enable clocks for the power, sysctrl and gclk modules */
PM->APBAMASK.reg = (PM_APBAMASK_PM | PM_APBAMASK_SYSCTRL |
PM_APBAMASK_GCLK);
/* adjust NVM wait states, see table 42.30 (p. 1070) in the datasheet */
#if (CLOCK_CORECLOCK > 24000000)
PM->APBAMASK.reg |= PM_AHBMASK_NVMCTRL;
NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_RWS(1);
PM->APBAMASK.reg &= ~PM_AHBMASK_NVMCTRL;
#endif
/* configure internal 8MHz oscillator to run without prescaler */
SYSCTRL->OSC8M.bit.PRESC = 0;
SYSCTRL->OSC8M.bit.ONDEMAND = 0;
SYSCTRL->OSC8M.bit.RUNSTDBY = 0;
SYSCTRL->OSC8M.bit.ENABLE = 1;
while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC8MRDY));
#if CLOCK_USE_PLL
/* reset the GCLK module so it is in a known state */
GCLK->CTRL.reg = GCLK_CTRL_SWRST;
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
/* setup generic clock 1 to feed DPLL with 1MHz */
GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(8) |
GCLK_GENDIV_ID(1));
GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |
GCLK_GENCTRL_SRC_OSC8M |
GCLK_GENCTRL_ID(1));
GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_GEN(1) |
GCLK_CLKCTRL_ID(1) |
GCLK_CLKCTRL_CLKEN);
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
/* enable PLL */
SYSCTRL->DPLLRATIO.reg = (SYSCTRL_DPLLRATIO_LDR(CLOCK_PLL_MUL));
SYSCTRL->DPLLCTRLB.reg = (SYSCTRL_DPLLCTRLB_REFCLK_GCLK);
SYSCTRL->DPLLCTRLA.reg = (SYSCTRL_DPLLCTRLA_ENABLE);
while(!(SYSCTRL->DPLLSTATUS.reg &
(SYSCTRL_DPLLSTATUS_CLKRDY | SYSCTRL_DPLLSTATUS_LOCK)) ==
(SYSCTRL_DPLLSTATUS_CLKRDY | SYSCTRL_DPLLSTATUS_LOCK));
/* select the PLL as source for clock generator 0 (CPU core clock) */
GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(CLOCK_PLL_DIV) |
GCLK_GENDIV_ID(0));
GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |
GCLK_GENCTRL_SRC_FDPLL96M |
GCLK_GENCTRL_ID(0));
#else /* do not use PLL, use internal 8MHz oscillator directly */
GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(CLOCK_DIV) |
GCLK_GENDIV_ID(0));
GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |
GCLK_GENCTRL_SRC_OSC8M |
GCLK_GENCTRL_ID(0));
#endif
/* make sure we synchronize clock generator 0 before we go on */
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
}
void cpu_init(void) void cpu_init(void)
{ {
/* pm clk enable */
PM->APBAMASK.reg = PM_APBAMASK_PM;
/* port clk enable */
PM->APBBMASK.reg |= PM_APBBMASK_PORT;
/* disable the watchdog timer */ /* disable the watchdog timer */
WDT->CTRL.bit.ENABLE = 0; WDT->CTRL.bit.ENABLE = 0;
/* initialize the Cortex-M core */ /* initialize the Cortex-M core */
@ -37,28 +95,3 @@ void cpu_init(void)
/* Initialise clock sources and generic clocks */ /* Initialise clock sources and generic clocks */
clk_init(); clk_init();
} }
/**
* @brief Initialise clock sources and generic clocks
*/
void clk_init(void)
{
PM->APBAMASK.reg |= PM_APBAMASK_SYSCTRL;
PM->APBAMASK.reg |= PM_APBAMASK_GCLK;
SYSCTRL->OSC8M.bit.PRESC = 0;
SYSCTRL->OSC8M.bit.ONDEMAND = 1;
SYSCTRL->OSC8M.bit.RUNSTDBY = 0;
SYSCTRL->OSC8M.bit.ENABLE = 1;
/* Software reset the module to ensure it is re-initialized correctly */
GCLK->CTRL.reg = GCLK_CTRL_SWRST;
while (GCLK->CTRL.reg & GCLK_CTRL_SWRST);
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
/* Select the correct generator */
*((uint8_t*)&GCLK->GENDIV.reg) = 0;
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC8M | GCLK_CLKCTRL_GEN_GCLK0);
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
}

View File

@ -176,6 +176,7 @@ typedef union {
#define GCLK_GENCTRL_SRC_XOSC32K_Val 0x5u /**< \brief (GCLK_GENCTRL) XOSC32K oscillator output */ #define GCLK_GENCTRL_SRC_XOSC32K_Val 0x5u /**< \brief (GCLK_GENCTRL) XOSC32K oscillator output */
#define GCLK_GENCTRL_SRC_OSC8M_Val 0x6u /**< \brief (GCLK_GENCTRL) OSC8M oscillator output */ #define GCLK_GENCTRL_SRC_OSC8M_Val 0x6u /**< \brief (GCLK_GENCTRL) OSC8M oscillator output */
#define GCLK_GENCTRL_SRC_DFLL48M_Val 0x7u /**< \brief (GCLK_GENCTRL) DFLL48M output */ #define GCLK_GENCTRL_SRC_DFLL48M_Val 0x7u /**< \brief (GCLK_GENCTRL) DFLL48M output */
#define GCLK_GENCTRL_SRC_FDPLL96M_Val 0x8u /**< \brief (GCLK_GENCTRL) FDPLL96M output */
#define GCLK_GENCTRL_SRC_XOSC (GCLK_GENCTRL_SRC_XOSC_Val << GCLK_GENCTRL_SRC_Pos) #define GCLK_GENCTRL_SRC_XOSC (GCLK_GENCTRL_SRC_XOSC_Val << GCLK_GENCTRL_SRC_Pos)
#define GCLK_GENCTRL_SRC_GCLKIN (GCLK_GENCTRL_SRC_GCLKIN_Val << GCLK_GENCTRL_SRC_Pos) #define GCLK_GENCTRL_SRC_GCLKIN (GCLK_GENCTRL_SRC_GCLKIN_Val << GCLK_GENCTRL_SRC_Pos)
#define GCLK_GENCTRL_SRC_GCLKGEN1 (GCLK_GENCTRL_SRC_GCLKGEN1_Val << GCLK_GENCTRL_SRC_Pos) #define GCLK_GENCTRL_SRC_GCLKGEN1 (GCLK_GENCTRL_SRC_GCLKGEN1_Val << GCLK_GENCTRL_SRC_Pos)
@ -184,6 +185,7 @@ typedef union {
#define GCLK_GENCTRL_SRC_XOSC32K (GCLK_GENCTRL_SRC_XOSC32K_Val << GCLK_GENCTRL_SRC_Pos) #define GCLK_GENCTRL_SRC_XOSC32K (GCLK_GENCTRL_SRC_XOSC32K_Val << GCLK_GENCTRL_SRC_Pos)
#define GCLK_GENCTRL_SRC_OSC8M (GCLK_GENCTRL_SRC_OSC8M_Val << GCLK_GENCTRL_SRC_Pos) #define GCLK_GENCTRL_SRC_OSC8M (GCLK_GENCTRL_SRC_OSC8M_Val << GCLK_GENCTRL_SRC_Pos)
#define GCLK_GENCTRL_SRC_DFLL48M (GCLK_GENCTRL_SRC_DFLL48M_Val << GCLK_GENCTRL_SRC_Pos) #define GCLK_GENCTRL_SRC_DFLL48M (GCLK_GENCTRL_SRC_DFLL48M_Val << GCLK_GENCTRL_SRC_Pos)
#define GCLK_GENCTRL_SRC_FDPLL96M (GCLK_GENCTRL_SRC_FDPLL96M_Val << GCLK_GENCTRL_SRC_Pos)
#define GCLK_GENCTRL_GENEN_Pos 16 /**< \brief (GCLK_GENCTRL) Generic Clock Generator Enable */ #define GCLK_GENCTRL_GENEN_Pos 16 /**< \brief (GCLK_GENCTRL) Generic Clock Generator Enable */
#define GCLK_GENCTRL_GENEN (0x1u << GCLK_GENCTRL_GENEN_Pos) #define GCLK_GENCTRL_GENEN (0x1u << GCLK_GENCTRL_GENEN_Pos)
#define GCLK_GENCTRL_IDC_Pos 17 /**< \brief (GCLK_GENCTRL) Improve Duty Cycle */ #define GCLK_GENCTRL_IDC_Pos 17 /**< \brief (GCLK_GENCTRL) Improve Duty Cycle */

View File

@ -82,7 +82,7 @@ int i2c_init_master(i2c_t dev, i2c_speed_t speed)
pin_scl = I2C_SDA; pin_scl = I2C_SDA;
pin_sda = I2C_SCL; pin_sda = I2C_SCL;
i2c_pins = I2C_0_PINS; i2c_pins = I2C_0_PINS;
clock_source_speed = I2C_0_REF_F; clock_source_speed = CLOCK_CORECLOCK;
sercom_core = SERCOM3_GCLK_ID_CORE; sercom_core = SERCOM3_GCLK_ID_CORE;
sercom_gclk_id_slow = SERCOM3_GCLK_ID_SLOW ; sercom_gclk_id_slow = SERCOM3_GCLK_ID_SLOW ;
break; break;

View File

@ -66,9 +66,19 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
f_baud = 1000000; f_baud = 1000000;
break; break;
case SPI_SPEED_5MHZ: case SPI_SPEED_5MHZ:
#if CLOCK_CORECLOCK >= 5000000
f_baud = 5000000;
break;
#else
return -1; return -1;
#endif
case SPI_SPEED_10MHZ: case SPI_SPEED_10MHZ:
#if CLOCK_CORECLOCK >= 10000000
f_baud = 10000000;
break;
#else
return -1; return -1;
#endif
} }
switch(conf) switch(conf)
{ {
@ -172,7 +182,9 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
spi_dev->CTRLA.reg |= SERCOM_SPI_CTRLA_MODE_SPI_MASTER; spi_dev->CTRLA.reg |= SERCOM_SPI_CTRLA_MODE_SPI_MASTER;
while (spi_dev->SYNCBUSY.reg); while (spi_dev->SYNCBUSY.reg);
spi_dev->BAUD.bit.BAUD = (uint8_t) (((uint32_t) SPI_0_F_REF) / (2 * f_baud) - 1); /* Syncronous mode*/ spi_dev->BAUD.bit.BAUD = (uint8_t) (((uint32_t)CLOCK_CORECLOCK) / (2 * f_baud) - 1); /* Syncronous mode*/
spi_dev->CTRLA.reg |= (SERCOM_SPI_CTRLA_DOPO(dopo)) spi_dev->CTRLA.reg |= (SERCOM_SPI_CTRLA_DOPO(dopo))
| (SERCOM_SPI_CTRLA_DIPO(dipo)) | (SERCOM_SPI_CTRLA_DIPO(dipo))
| (cpha << SERCOM_SPI_CTRLA_CPHA_Pos) | (cpha << SERCOM_SPI_CTRLA_CPHA_Pos)

View File

@ -48,13 +48,27 @@ timer_conf_t config[TIMER_NUMOF];
*/ */
int timer_init(tim_t dev, unsigned int us_per_ticks, void (*callback)(int)) int timer_init(tim_t dev, unsigned int us_per_ticks, void (*callback)(int))
{ {
/* configure GCLK0 to feed TC3, TC4 and TC5 */; /* at the moment, the timer can only run at 1MHz */
GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (TC3_GCLK_ID << GCLK_CLKCTRL_ID_Pos))); if (us_per_ticks != 1) {
return -1;
}
/* select the clock generator depending on the main clock source:
* GCLK0 (1MHz) if we use the internal 8MHz oscillator
* GCLK1 (8MHz) if we use the PLL */
#if CLOCK_USE_PLL
/* configure GCLK1 (configured to 1MHz) to feed TC3, TC4 and TC5 */;
GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | (TC3_GCLK_ID << GCLK_CLKCTRL_ID_Pos)));
while (GCLK->STATUS.bit.SYNCBUSY); while (GCLK->STATUS.bit.SYNCBUSY);
/* TC4 and TC5 share the same channel */ /* TC4 and TC5 share the same channel */
GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | (TC4_GCLK_ID << GCLK_CLKCTRL_ID_Pos)));
#else
/* configure GCLK0 to feed TC3, TC4 and TC5 */;
GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (TC3_GCLK_ID << GCLK_CLKCTRL_ID_Pos)));
/* TC4 and TC5 share the same channel */
GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (TC4_GCLK_ID << GCLK_CLKCTRL_ID_Pos))); GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (TC4_GCLK_ID << GCLK_CLKCTRL_ID_Pos)));
#endif
while (GCLK->STATUS.bit.SYNCBUSY); while (GCLK->STATUS.bit.SYNCBUSY);
/* select the timer and enable the timer specific peripheral clocks */
switch (dev) { switch (dev) {
#if TIMER_0_EN #if TIMER_0_EN
@ -68,8 +82,13 @@ int timer_init(tim_t dev, unsigned int us_per_ticks, void (*callback)(int))
while (TIMER_0_DEV.CTRLA.bit.SWRST); while (TIMER_0_DEV.CTRLA.bit.SWRST);
/* choosing 16 bit mode */ /* choosing 16 bit mode */
TIMER_0_DEV.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT16_Val; TIMER_0_DEV.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT16_Val;
/* sourced by 8MHz with Presc 64 results in 125kHz clk */ #if CLOCK_USE_PLL
TIMER_0_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV64_Val; /* sourced by 1MHz with prescaler 1 results in... you know it :-) */
TIMER_0_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV1_Val;
#else
/* sourced by 8MHz with Presc 8 results in 1MHz clk */
TIMER_0_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV8_Val;
#endif
/* choose normal frequency operation */ /* choose normal frequency operation */
TIMER_0_DEV.CTRLA.bit.WAVEGEN = TC_CTRLA_WAVEGEN_NFRQ_Val; TIMER_0_DEV.CTRLA.bit.WAVEGEN = TC_CTRLA_WAVEGEN_NFRQ_Val;
break; break;
@ -87,8 +106,13 @@ int timer_init(tim_t dev, unsigned int us_per_ticks, void (*callback)(int))
TIMER_1_DEV.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT32_Val; TIMER_1_DEV.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT32_Val;
#if CLOCK_USE_PLL
/* sourced by 1MHz and prescaler 1 to reach 1MHz */
TIMER_1_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV1_Val;
#else
/* sourced by 8MHz with Presc 8 results in 1Mhz clk */ /* sourced by 8MHz with Presc 8 results in 1Mhz clk */
TIMER_1_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV8_Val; TIMER_1_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV8_Val;
#endif
/* choose normal frequency operation */ /* choose normal frequency operation */
TIMER_1_DEV.CTRLA.bit.WAVEGEN = TC_CTRLA_WAVEGEN_NFRQ_Val; TIMER_1_DEV.CTRLA.bit.WAVEGEN = TC_CTRLA_WAVEGEN_NFRQ_Val;
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2014 Freie Universität Berlin * Copyright (C) 2015 Freie Universität Berlin
* *
* This file is subject to the terms and conditions of the GNU Lesser * This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level * General Public License v2.1. See the file LICENSE in the top level
@ -15,6 +15,7 @@
* *
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de> * @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
* @author Troels Hoffmeyer <troels.d.hoffmeyer@gmail.com> * @author Troels Hoffmeyer <troels.d.hoffmeyer@gmail.com>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* *
* @} * @}
*/ */
@ -53,8 +54,6 @@ static inline void irq_handler(uart_t uartnum, SercomUsart *uart);
*/ */
static uart_conf_t uart_config[UART_NUMOF]; static uart_conf_t uart_config[UART_NUMOF];
static uint64_t _long_division(uint64_t n, uint64_t d);
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg) int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg)
{ {
/* initialize basic functionality */ /* initialize basic functionality */
@ -81,11 +80,7 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t t
int uart_init_blocking(uart_t uart, uint32_t baudrate) int uart_init_blocking(uart_t uart, uint32_t baudrate)
{ {
/* Calculate the BAUD value */ uint32_t baud = ((((uint32_t)CLOCK_CORECLOCK * 10) / baudrate) / 16);
uint64_t temp1 = ((16 * ((uint64_t)baudrate)) << 32);
uint64_t ratio = _long_division(temp1 , UART_0_REF_F);
uint64_t scale = ((uint64_t)1 << 32) - ratio;
uint64_t baud_calculated = (65536 * scale) >> 32;
switch (uart) { switch (uart) {
#if UART_0_EN #if UART_0_EN
@ -97,9 +92,6 @@ int uart_init_blocking(uart_t uart, uint32_t baudrate)
GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (SERCOM0_GCLK_ID_CORE << GCLK_CLKCTRL_ID_Pos))); GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (SERCOM0_GCLK_ID_CORE << GCLK_CLKCTRL_ID_Pos)));
while (GCLK->STATUS.bit.SYNCBUSY); while (GCLK->STATUS.bit.SYNCBUSY);
GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (SERCOM0_GCLK_ID_SLOW << GCLK_CLKCTRL_ID_Pos)));
while (GCLK->STATUS.bit.SYNCBUSY);
/* configure PINS to input/output*/ /* configure PINS to input/output*/
UART_0_PORT.DIRSET.reg = (1 << UART_0_TX_PIN); /* tx's direction is output */ UART_0_PORT.DIRSET.reg = (1 << UART_0_TX_PIN); /* tx's direction is output */
UART_0_PORT.PINCFG[UART_0_RX_PIN % 32].bit.INEN = true; /* buffer rx pin's value */ UART_0_PORT.PINCFG[UART_0_RX_PIN % 32].bit.INEN = true; /* buffer rx pin's value */
@ -117,20 +109,17 @@ int uart_init_blocking(uart_t uart, uint32_t baudrate)
/* set to LSB, asynchronous mode without parity, PAD0 Tx, PAD1 Rx, /* set to LSB, asynchronous mode without parity, PAD0 Tx, PAD1 Rx,
* 16x over-sampling, internal clk */ * 16x over-sampling, internal clk */
UART_0_DEV.CTRLA.reg = SERCOM_USART_CTRLA_DORD \ UART_0_DEV.CTRLA.reg = SERCOM_USART_CTRLA_DORD \
| SERCOM_USART_CTRLA_FORM(0x0) \
| SERCOM_USART_CTRLA_SAMPA(0x0) \
| SERCOM_USART_CTRLA_TXPO(0x0) \
| SERCOM_USART_CTRLA_RXPO(0x1) \ | SERCOM_USART_CTRLA_RXPO(0x1) \
| SERCOM_USART_CTRLA_SAMPR(0x0) \ | SERCOM_USART_CTRLA_SAMPR(0x1) \
| SERCOM_USART_CTRLA_MODE_USART_INT_CLK; | SERCOM_USART_CTRLA_MODE_USART_INT_CLK;
/* Set baud rate */
UART_0_DEV.BAUD.bit.BAUD = baud_calculated; UART_0_DEV.BAUD.FRAC.FP = (baud % 10);
UART_0_DEV.BAUD.FRAC.BAUD = (baud / 10);
/* enable receiver and transmitter, one stop bit*/ /* enable receiver and transmitter, one stop bit*/
UART_0_DEV.CTRLB.reg = (SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN); UART_0_DEV.CTRLB.reg = (SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);
while(UART_0_DEV.SYNCBUSY.bit.CTRLB); while(UART_0_DEV.SYNCBUSY.bit.CTRLB);
break; break;
#endif #endif
} }
@ -226,29 +215,4 @@ static inline void irq_handler(uint8_t uartnum, SercomUsart *dev)
} }
} }
static uint64_t _long_division(uint64_t n, uint64_t d)
{
int32_t i;
uint64_t q = 0, r = 0, bit_shift;
for (i = 63; i >= 0; i--) {
bit_shift = (uint64_t)1 << i;
r = r << 1;
if (n & bit_shift) {
r |= 0x01;
}
if (r >= d) {
r = r - d;
q |= bit_shift;
}
}
return q;
}
#endif /* UART_NUMOF */ #endif /* UART_NUMOF */