Exemplo n.º 1
0
Arquivo: uart.c Projeto: daniel-k/RIOT
int uart_init_blocking(uart_t uart, uint32_t baudrate)
{
    /* Calculate the BAUD value */
    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) {
#if UART_0_EN
        case UART_0:
            /* Enable the peripheral channel */
            GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg |= GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0;

            while (!(GCLK->PCHCTRL[SERCOM3_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN)) {
                /* Wait for clock synchronization */
            }

            MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM3;
            /* configure PINS to input/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 */

            /* enable PMUX for pins and set to config C. */
            UART_0_PORT.WRCONFIG.reg = PORT_WRCONFIG_WRPINCFG \
                                        | PORT_WRCONFIG_WRPMUX \
                                        | PORT_WRCONFIG_PMUX(0x2) \
                                        | PORT_WRCONFIG_PMUXEN \
                                        | UART_0_PINS;

            UART_0_DEV.CTRLA.bit.ENABLE = 0; //Disable to write, need to sync tho
            while(UART_0_DEV.SYNCBUSY.bit.ENABLE);

            /* set to LSB, asynchronous mode without parity, PAD0 Tx, PAD1 Rx,
             * 16x over-sampling, internal clk */
            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_SAMPR(0x0) \
                                    | SERCOM_USART_CTRLA_MODE(0x1) \
                                    | (UART_0_RUNSTDBY ? SERCOM_USART_CTRLA_RUNSTDBY : 0);

            /* Set baud rate */
            UART_0_DEV.BAUD.bit.BAUD = baud_calculated;

            /* enable receiver and transmitter, one stop bit*/
            UART_0_DEV.CTRLB.reg = (SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);
            while(UART_0_DEV.SYNCBUSY.bit.CTRLB);

            break;
#endif
    }

    uart_poweron(uart);
    return 0;
}
Exemplo n.º 2
0
Arquivo: uart.c Projeto: A-Paul/RIOT
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
{
    assert(uart < UART_NUMOF);

    /* save ISR context */
    isr_ctx[uart].rx_cb     = rx_cb;
    isr_ctx[uart].arg       = arg;
    isr_ctx[uart].data_mask = 0xFF;

    uart_init_pins(uart, rx_cb);

    /* enable the clock */
    uart_poweron(uart);

    /* reset UART configuration -> defaults to 8N1 mode */
    dev(uart)->CR1 = 0;
    dev(uart)->CR2 = 0;
    dev(uart)->CR3 = 0;

#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L4)
    switch (uart_config[uart].type) {
        case STM32_USART:
            uart_init_usart(uart, baudrate);
            break;
#ifdef MODULE_PERIPH_LPUART
        case STM32_LPUART:
            uart_init_lpuart(uart, baudrate);
            break;
#endif
        default:
            return UART_NODEV;
    }
#else
    uart_init_usart(uart, baudrate);
#endif

    /* enable RX interrupt if applicable */
    if (rx_cb) {
        NVIC_EnableIRQ(uart_config[uart].irqn);
        dev(uart)->CR1 = (USART_CR1_UE | USART_CR1_TE | RXENABLE);
    }
    else {
        dev(uart)->CR1 = (USART_CR1_UE | USART_CR1_TE);
    }

#ifdef MODULE_STM32_PERIPH_UART_HW_FC
    if (uart_config[uart].cts_pin != GPIO_UNDEF) {
        /* configure hardware flow control */
        dev(uart)->CR3 = (USART_CR3_RTSE | USART_CR3_CTSE);
    }
#endif

    return UART_OK;
}
Exemplo n.º 3
0
int uart_init_blocking(uart_t uart, uint32_t baudrate)
{
    uint32_t baud =  ((((uint32_t)CLOCK_CORECLOCK * 10) / baudrate) / 16);

    switch (uart) {
#if UART_0_EN
        case UART_0:
            /* Turn on power manager for sercom */
            PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0;

            /* configure GCLK0 to feed sercom0 */;
            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);

            /* configure PINS to input/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 */

            /* enable PMUX for pins and set to config D. See spec p. 12 */
            UART_0_PORT.WRCONFIG.reg = PORT_WRCONFIG_WRPINCFG \
                                        | PORT_WRCONFIG_WRPMUX \
                                        | PORT_WRCONFIG_PMUX(0x3) \
                                        | PORT_WRCONFIG_PMUXEN \
                                        | UART_0_PINS;

            UART_0_DEV.CTRLA.bit.ENABLE = 0; //Disable to write, need to sync tho
            while(UART_0_DEV.SYNCBUSY.bit.ENABLE);

            /* set to LSB, asynchronous mode without parity, PAD0 Tx, PAD1 Rx,
             * 16x over-sampling, internal clk */
            UART_0_DEV.CTRLA.reg = SERCOM_USART_CTRLA_DORD \
                                    | SERCOM_USART_CTRLA_RXPO(0x1) \
                                    | SERCOM_USART_CTRLA_SAMPR(0x1) \
                                    | SERCOM_USART_CTRLA_MODE_USART_INT_CLK;


            UART_0_DEV.BAUD.FRAC.FP = (baud % 10);
            UART_0_DEV.BAUD.FRAC.BAUD = (baud / 10);

            /* enable receiver and transmitter, one stop bit*/
            UART_0_DEV.CTRLB.reg = (SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);
            while(UART_0_DEV.SYNCBUSY.bit.CTRLB);
            break;
#endif
    }

    uart_poweron(uart);
    return 0;
}
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;
}
Exemplo n.º 5
0
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
{
    Uart *dev;

    /* make sure given device is valid */
    if (uart >= UART_NUMOF) {
        return UART_NODEV;
    }

    /* get base register */
    dev = uart_config[uart].dev;

    /* register callback */
    ctx[uart].rx_cb = rx_cb;
    ctx[uart].arg = arg;

    /* enable clock */
    uart_poweron(uart);

    /* configure pins
       TODO: optimize once GPIO refactoring is merged */
    uart_config[uart].rx_port->PIO_PDR = (1 << uart_config[uart].rx_pin);
    uart_config[uart].rx_port->PIO_ABSR &= ~(1 << uart_config[uart].rx_pin);
    uart_config[uart].tx_port->PIO_ABSR |=  (uart_config[uart].mux <<
                                             uart_config[uart].rx_pin);
    uart_config[uart].tx_port->PIO_PDR = (1 << uart_config[uart].tx_pin);
    uart_config[uart].tx_port->PIO_ABSR &= ~(1 << uart_config[uart].tx_pin);
    uart_config[uart].tx_port->PIO_ABSR |=  (uart_config[uart].mux <<
                                             uart_config[uart].tx_pin);

    /* configure baud rate and set mode to 8N1 */
    dev->UART_BRGR = (CLOCK_CORECLOCK / (16 * baudrate));
    dev->UART_MR = UART_MR_PAR_NO | US_MR_CHRL_8_BIT;
    dev->UART_CR = UART_CR_RXEN | UART_CR_TXEN | UART_CR_RSTSTA;

    /* enable RX interrupt */
    NVIC_EnableIRQ(uart_config[uart].irqn);
    dev->UART_IER = UART_IER_RXRDY;

    return UART_OK;
}
Exemplo n.º 6
0
Arquivo: uart.c Projeto: aabadie/RIOT
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;
}
Exemplo n.º 7
0
Arquivo: uart.c Projeto: daniel-k/RIOT
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;
}
Exemplo n.º 8
0
void at_dev_poweron(at_dev_t *dev)
{
    uart_poweron(dev->uart);
}
Exemplo n.º 9
0
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
{
    USART_TypeDef *dev;
    DMA_Stream_TypeDef *stream;
    float divider;
    uint16_t mantissa;
    uint8_t fraction;

    /* check if given UART device does exist */
    if ((unsigned int)uart >= UART_NUMOF) {
        return -1;
    }

    /* get UART base address */
    dev = _dev(uart);
    /* remember callback addresses and argument */
    uart_ctx[uart].rx_cb = rx_cb;
    uart_ctx[uart].arg = arg;
    /* init TX lock and DMA synchronization mutex */
    mutex_init(&_tx_lock[uart]);
    mutex_init(&_tx_dma_sync[uart]);
    mutex_lock(&_tx_dma_sync[uart]);

    /* configure pins */
    gpio_init(uart_config[uart].rx_pin, GPIO_IN);
    gpio_init(uart_config[uart].tx_pin, GPIO_OUT);
    gpio_init_af(uart_config[uart].rx_pin, uart_config[uart].af);
    gpio_init_af(uart_config[uart].tx_pin, uart_config[uart].af);
    /* enable UART clock */
    uart_poweron(uart);

    /* calculate and set baudrate */
    if (uart_config[uart].bus == APB1) {
        divider = CLOCK_APB1 / (16 * baudrate);
    }
    else {
        divider = CLOCK_APB2 / (16 * baudrate);
    }
    mantissa = (uint16_t)divider;
    fraction = (uint8_t)((divider - mantissa) * 16);
    dev->BRR = ((mantissa & 0x0fff) << 4) | (0x0f & fraction);
    /* configure UART to 8N1 and enable receive and transmit mode */
    dev->CR3 = USART_CR3_DMAT;
    dev->CR2 = 0;
    dev->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
    /* configure the DMA stream for transmission */
    dma_poweron(uart_config[uart].dma_stream);
    stream = dma_stream(uart_config[uart].dma_stream);
    stream->CR = ((uart_config[uart].dma_chan << 25) |
                  DMA_SxCR_PL_0 |
                  DMA_SxCR_MINC |
                  DMA_SxCR_DIR_0 |
                  DMA_SxCR_TCIE);
    stream->PAR = (uint32_t)&(dev->DR);
    stream->FCR = 0;
    /* enable global and receive interrupts */
    NVIC_EnableIRQ(uart_config[uart].irqn);
    dma_isr_enable(uart_config[uart].dma_stream);
    dev->CR1 |= USART_CR1_RXNEIE;
    return 0;
}
Exemplo n.º 10
0
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
{
    uint16_t mantissa;
    uint8_t fraction;
    uint32_t clk;

    assert(uart < UART_NUMOF);

    /* save ISR context */
    isr_ctx[uart].rx_cb = rx_cb;
    isr_ctx[uart].arg   = arg;

    /* configure TX pin */
    gpio_init(uart_config[uart].tx_pin, GPIO_OUT);
    /* set TX pin high to avoid garbage during further initialization */
    gpio_set(uart_config[uart].tx_pin);
#ifdef CPU_FAM_STM32F1
    gpio_init_af(uart_config[uart].tx_pin, GPIO_AF_OUT_PP);
#else
    gpio_init_af(uart_config[uart].tx_pin, uart_config[uart].tx_af);
#endif
    /* configure RX pin */
    if (rx_cb) {
        gpio_init(uart_config[uart].rx_pin, GPIO_IN);
#ifndef CPU_FAM_STM32F1
        gpio_init_af(uart_config[uart].rx_pin, uart_config[uart].rx_af);
#endif
    }
#ifdef MODULE_STM32_PERIPH_UART_HW_FC
    if (uart_config[uart].cts_pin != GPIO_UNDEF) {
        gpio_init(uart_config[uart].cts_pin, GPIO_IN);
        gpio_init(uart_config[uart].rts_pin, GPIO_OUT);
#ifdef CPU_FAM_STM32F1
        gpio_init_af(uart_config[uart].rts_pin, GPIO_AF_OUT_PP);
#else
        gpio_init_af(uart_config[uart].cts_pin, uart_config[uart].cts_af);
        gpio_init_af(uart_config[uart].rts_pin, uart_config[uart].rts_af);
#endif
    }
#endif

    /* enable the clock */
    uart_poweron(uart);

    /* reset UART configuration -> defaults to 8N1 mode */
    dev(uart)->CR1 = 0;
    dev(uart)->CR2 = 0;
    dev(uart)->CR3 = 0;

    /* calculate and apply baudrate */
    clk = periph_apb_clk(uart_config[uart].bus) / baudrate;
    mantissa = (uint16_t)(clk / 16);
    fraction = (uint8_t)(clk - (mantissa * 16));
    dev(uart)->BRR = ((mantissa & 0x0fff) << 4) | (fraction & 0x0f);

    /* enable RX interrupt if applicable */
    if (rx_cb) {
        NVIC_EnableIRQ(uart_config[uart].irqn);
        dev(uart)->CR1 = (USART_CR1_UE | USART_CR1_TE | RXENABLE);
    }
    else {
        dev(uart)->CR1 = (USART_CR1_UE | USART_CR1_TE);
    }

#ifdef MODULE_STM32_PERIPH_UART_HW_FC
    if (uart_config[uart].cts_pin != GPIO_UNDEF) {
        /* configure hardware flow control */
        dev(uart)->CR3 = (USART_CR3_RTSE | USART_CR3_CTSE);
    }
#endif

    return UART_OK;
}