Пример #1
0
void uart_write(uart_t uart, const uint8_t *data, size_t len)
{
    for (size_t i = 0; i < len; i++) {
        while (!(_uart(uart)->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)) {}
        _uart(uart)->DATA.reg = data[i];
    }
}
Пример #2
0
void uart_poweroff(uart_t uart)
{
    PM->APBCMASK.reg &= ~(PM_APBCMASK_SERCOM0 << _sercom_id(_uart(uart)));
    GCLK->CLKCTRL.reg = ((SERCOM0_GCLK_ID_CORE + _sercom_id(_uart(uart))) <<
                         GCLK_CLKCTRL_ID_Pos);
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
}
Пример #3
0
void uart_write(uart_t dev, const uint8_t *data, size_t len)
{
    for (size_t i = 0; i < len; i++) {
        while (!(_uart(dev)->STATUS & USART_STATUS_TXBL));
        _uart(dev)->TXDATA = data[i];
    }
}
static inline void rx_irq(int dev)
{
    if (_uart(dev)->IF & USART_IF_RXDATAV) {
        uint8_t data = (uint8_t)_uart(dev)->RXDATA;
        isr_ctx[dev].rx_cb(isr_ctx[dev].arg, data);
    }
    cortexm_isr_end();
}
Пример #5
0
void uart_poweron(uart_t uart)
{
    PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << _sercom_id(_uart(uart)));
    GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN |
                         GCLK_CLKCTRL_GEN_GCLK0 |
                         (SERCOM0_GCLK_ID_CORE + _sercom_id(_uart(uart))) <<
                          GCLK_CLKCTRL_ID_Pos);
    while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);
}
Пример #6
0
static inline void rx_irq(int dev)
{
    if (_uart(dev)->IF & USART_IF_RXDATAV) {
        uint8_t data = (uint8_t)_uart(dev)->RXDATA;
        isr_ctx[dev].rx_cb(isr_ctx[dev].arg, data);
    }
    if (sched_context_switch_request) {
        thread_yield();
    }
}
Пример #7
0
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
{
    /* initialize basic functionality */
    int res = init_base(uart, baudrate);
    if (res != 0) {
        return res;
    }

    /* register callbacks */
    uart_ctx[uart].rx_cb = rx_cb;
    uart_ctx[uart].arg = arg;
    /* configure interrupts and enable RX interrupt */
    _uart(uart)->INTENSET.reg = SERCOM_USART_INTENSET_RXC;
    NVIC_EnableIRQ(SERCOM0_IRQn + _sercom_id(_uart(uart)));
    return 0;
}
Пример #8
0
static inline void irq_handler(int dev)
{
    SercomUsart *uart = _uart(dev);

    if (uart->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC) {
        /* interrupt flag is cleared by reading the data register */
        uart_ctx[dev].rx_cb(uart_ctx[dev].arg, (uint8_t)(uart->DATA.reg));
    }
    else if (uart->INTFLAG.reg & SERCOM_USART_INTFLAG_ERROR) {
        /* clear error flag */
        uart->INTFLAG.reg = SERCOM_USART_INTFLAG_ERROR;
    }
    cortexm_isr_end();
}
Пример #9
0
static inline void irq_handler(int dev)
{
    SercomUsart *uart = _uart(dev);

    if (uart->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC) {
        /* interrupt flag is cleared by reading the data register */
        uart_ctx[dev].rx_cb(uart_ctx[dev].arg, (uint8_t)(uart->DATA.reg));
    }
    else if (uart->INTFLAG.reg & SERCOM_USART_INTFLAG_ERROR) {
        /* clear error flag */
        uart->INTFLAG.reg = SERCOM_USART_INTFLAG_ERROR;
    }
    if (sched_context_switch_request) {
        thread_yield();
    }
}
int uart_init(uart_t dev, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
{
    USART_TypeDef *uart;

    /* check if device is valid and get base register address */
    if (dev >= UART_NUMOF) {
        return UART_NODEV;
    }
    uart = _uart(dev);

    /* save interrupt callback context */
    isr_ctx[dev].rx_cb = rx_cb;
    isr_ctx[dev].arg = arg;

    /* power on the device */
    uart_poweron(dev);
    /* put device in asynchronous mode @ 16x oversampling (default UART) */
    uart->CTRL = 0;
    /* configure to default 8N1 configuration */
    uart->FRAME = (USART_FRAME_STOPBITS_ONE | USART_FRAME_DATABITS_EIGHT);
    /* configure the baudrate - this looks more complicated than it is, we just
     * multiply the HFPERCLK with 32 to cut down on rounding error when doing
     * the division afterwards... */
    uart->CLKDIV = (((CLOCK_HFPERCLK << 5) / (16 * baudrate) - 32) << 3);
    /* configure the pins */
    gpio_init(uart_config[dev].tx_pin, GPIO_OUT);
    if (rx_cb) {
        gpio_init(uart_config[dev].rx_pin, GPIO_IN);
        uart->ROUTE = ((uart_config[dev].loc << _USART_ROUTE_LOCATION_SHIFT) |
                       USART_ROUTE_RXPEN | USART_ROUTE_TXPEN);
    } else {
        uart->ROUTE = ((uart_config[dev].loc << _USART_ROUTE_LOCATION_SHIFT) |
                       USART_ROUTE_TXPEN);
    }
    if (rx_cb) {
        /* enable RX interrupt */
        NVIC_EnableIRQ(uart_config[dev].irq);
        NVIC_EnableIRQ(uart_config[dev].irq + 1);
        uart->IEN |= USART_IEN_RXDATAV;
        /* enable receiver and transmitter */
        uart->CMD = USART_CMD_TXEN | USART_CMD_RXEN;
    }
    else {
        uart->CMD = USART_CMD_TXEN;
    }
    return UART_OK;
}
Пример #11
0
static int init_base(uart_t uart, uint32_t baudrate)
{
    uint32_t baud;
    SercomUsart *dev;

    if ((unsigned int)uart >= UART_NUMOF) {
        return -1;
    }

    /* get the devices base register */
    dev = _uart(uart);
    /* calculate baudrate */
    baud =  ((((uint32_t)CLOCK_CORECLOCK * 10) / baudrate) / 16);
    /* enable sync and async clocks */
    uart_poweron(uart);
    /* configure pins */
    gpio_init(uart_config[uart].rx_pin, GPIO_IN);
    gpio_init_mux(uart_config[uart].rx_pin, uart_config[uart].mux);
    gpio_init(uart_config[uart].tx_pin, GPIO_OUT);
    gpio_init_mux(uart_config[uart].tx_pin, uart_config[uart].mux);
    /* reset the UART device */
    dev->CTRLA.reg = SERCOM_USART_CTRLA_SWRST;
    while (dev->SYNCBUSY.reg & SERCOM_USART_SYNCBUSY_SWRST) {}
    /* set asynchronous mode w/o parity, LSB first, TX and RX pad as specified
     * by the board in the periph_conf.h, x16 sampling and use internal clock */
    dev->CTRLA.reg = (SERCOM_USART_CTRLA_DORD |
                      SERCOM_USART_CTRLA_SAMPR(0x1) |
                      SERCOM_USART_CTRLA_TXPO(uart_config[uart].tx_pad) |
                      SERCOM_USART_CTRLA_RXPO(uart_config[uart].rx_pad) |
                      SERCOM_USART_CTRLA_MODE_USART_INT_CLK);
    /* set baudrate */
    dev->BAUD.FRAC.FP = (baud % 10);
    dev->BAUD.FRAC.BAUD = (baud / 10);
    /* enable receiver and transmitter, use 1 stop bit */
    dev->CTRLB.reg = (SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);
    while (dev->SYNCBUSY.reg & SERCOM_USART_SYNCBUSY_CTRLB) {}
    /* finally, enable the device */
    dev->CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
    return 0;
}
Пример #12
0
int uart_init_blocking(uart_t uart, uint32_t baudrate)
{
    uint32_t baud;
    SercomUsart *dev;

    if (uart < 0 || uart >= UART_NUMOF) {
        return -1;
    }

    /* get the devices base register */
    dev = _uart(uart);
    /* calculate baudrate */
    baud =  ((((uint32_t)CLOCK_CORECLOCK * 10) / baudrate) / 16);
    /* enable sync and async clocks */
    uart_poweron(uart);
    /* configure pins */
    gpio_init(uart_config[uart].rx_pin, GPIO_DIR_IN, GPIO_NOPULL);
    gpio_init_mux(uart_config[uart].rx_pin, uart_config[uart].mux);
    gpio_init(uart_config[uart].tx_pin, GPIO_DIR_OUT, GPIO_NOPULL);
    gpio_init_mux(uart_config[uart].tx_pin, uart_config[uart].mux);
    /* reset the UART device */
    dev->CTRLA.reg = SERCOM_USART_CTRLA_SWRST;
    while (dev->SYNCBUSY.reg & SERCOM_USART_SYNCBUSY_SWRST);
    /* set asynchronous mode w/o parity, LSB first, PAD0 to TX, PAD1 to RX and
     * use internal clock */
    dev->CTRLA.reg = (SERCOM_USART_CTRLA_DORD |
                      SERCOM_USART_CTRLA_RXPO(0x1) |
                      SERCOM_USART_CTRLA_SAMPR(0x1) |
                      SERCOM_USART_CTRLA_MODE_USART_INT_CLK);
    /* set baudrate */
    dev->BAUD.FRAC.FP = (baud % 10);
    dev->BAUD.FRAC.BAUD = (baud / 10);
    /* enable receiver and transmitter, use 1 stop bit */
    dev->CTRLB.reg = (SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);
    while (dev->SYNCBUSY.reg & SERCOM_USART_SYNCBUSY_CTRLB);
    /* finally, enable the device */
    dev->CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
    return 0;
}
Пример #13
0
int uart_write_blocking(uart_t uart, char data)
{
    while (!(_uart(uart)->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE));
    _uart(uart)->DATA.reg = (uint8_t)data;
    return 1;
}
Пример #14
0
int uart_write(uart_t uart, char data)
{
    _uart(uart)->DATA.reg = (uint8_t)data;
    return 1;
}
Пример #15
0
int uart_read_blocking(uart_t uart, char *data)
{
    while(!(_uart(uart)->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC));
    *data = (char)_uart(uart)->DATA.reg;
    return 1;
}
Пример #16
0
void uart_tx_begin(uart_t uart)
{
    _uart(uart)->INTENSET.reg = SERCOM_USART_INTENSET_TXC;
}