diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2012-05-01 09:10:14 -0700 |
---|---|---|
committer | Vincent Palatin <vpalatin@chromium.org> | 2012-05-01 22:59:51 +0000 |
commit | 539c397fb16460561aa451d121041ed36c13a845 (patch) | |
tree | fd31a40a7e1e373262ef04d392d5742fe584ae83 /chip/stm32/uart.c | |
parent | 285fa08d10c2e5fce6e0db6f217a83b5a42e8004 (diff) | |
download | chrome-ec-539c397fb16460561aa451d121041ed36c13a845.tar.gz |
introducing chip variant for stm32 family [1/3]
just rename STM32L to STM32.
Most of the STM32L15x code is common with STM32F1xx.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BUG=chrome-os-partner:9057
TEST=make BOARD=daisy ; make BOARD=adv ; make BOARD=discovery
Change-Id: I819eff5fcd23deff57f5f6dedcf37e6c421b96c2
Diffstat (limited to 'chip/stm32/uart.c')
-rw-r--r-- | chip/stm32/uart.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/chip/stm32/uart.c b/chip/stm32/uart.c new file mode 100644 index 0000000000..48532474fe --- /dev/null +++ b/chip/stm32/uart.c @@ -0,0 +1,150 @@ +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* USART driver for Chrome EC */ + +#include <stdarg.h> + +#include "board.h" +#include "config.h" +#include "registers.h" +#include "task.h" +#include "uart.h" +#include "util.h" + +/* Baud rate for UARTs */ +#define BAUD_RATE 115200 + +/* Console USART index */ +#define UARTN CONFIG_CONSOLE_UART + +static int init_done; /* Initialization done? */ +static int should_stop; /* Last TX control action */ + + +int uart_init_done(void) +{ + return init_done; +} + +void uart_tx_start(void) +{ + STM32_USART_CR1(UARTN) |= 0x80; + should_stop = 0; + task_trigger_irq(STM32_IRQ_USART(UARTN)); +} + +void uart_tx_stop(void) +{ + STM32_USART_CR1(UARTN) &= ~0x80; + should_stop = 1; +} + +int uart_tx_stopped(void) +{ + return !(STM32_USART_CR1(UARTN) & 0x80); +} + +void uart_tx_flush(void) +{ + while (!(STM32_USART_SR(UARTN) & 0x80)) + ; +} + +int uart_tx_ready(void) +{ + return STM32_USART_SR(UARTN) & 0x80; +} + +int uart_rx_available(void) +{ + return STM32_USART_SR(UARTN) & 0x20; +} + +void uart_write_char(char c) +{ + /* we normally never wait here since uart_write_char is normally called + * when the buffer is ready, excepted when we insert a carriage return + * before a line feed in the interrupt routine. + */ + while (!uart_tx_ready()) ; + STM32_USART_DR(UARTN) = c; +} + +int uart_read_char(void) +{ + return STM32_USART_DR(UARTN); +} + +void uart_disable_interrupt(void) +{ + task_disable_irq(STM32_IRQ_USART(UARTN)); +} + +void uart_enable_interrupt(void) +{ + task_enable_irq(STM32_IRQ_USART(UARTN)); +} + +/* Interrupt handler for console USART */ +static void uart_interrupt(void) +{ + /* + * Disable the TX empty interrupt before filling the TX buffer since it + * needs an actual write to DR to be cleared. + */ + STM32_USART_CR1(UARTN) &= ~0x80; + + /* Read input FIFO until empty, then fill output FIFO */ + uart_process(); + + /* + * Re-enable TX empty interrupt only if it was not disabled by + * uart_process. + */ + if (!should_stop) + STM32_USART_CR1(UARTN) |= 0x80; +} +DECLARE_IRQ(STM32_IRQ_USART(UARTN), uart_interrupt, 1); + +int uart_init(void) +{ + /* + * Check that the UART parameters used for panic/watchdog are matching + * the console USART parameters. + */ + BUILD_ASSERT(STM32_USART_BASE(UARTN) == CONFIG_UART_ADDRESS); + + /* Enable USART clock */ + if (UARTN == 1) + STM32_RCC_APB2ENR |= 1 << 14; /* USART1 */ + else if (UARTN == 2) + STM32_RCC_APB1ENR |= 1 << 17; /* USART2 */ + else if (UARTN == 3) + STM32_RCC_APB1ENR |= 1 << 18; /* USART3 */ + + /* UART enabled, 8 Data bits, oversampling x16, no parity, + * RXNE interrupt, TX and RX enabled. + */ + STM32_USART_CR1(UARTN) = 0x202C; + + /* 1 stop bit, no fancy stuff */ + STM32_USART_CR2(UARTN) = 0x0000; + + /* DMA disabled, special modes disabled, error interrupt disabled */ + STM32_USART_CR3(UARTN) = 0x0000; + + /* Select the baud rate + * using x16 oversampling (OVER8 == 0) + */ + STM32_USART_BRR(UARTN) = DIV_ROUND_NEAREST(CPU_CLOCK, BAUD_RATE); + + /* Enable interrupts */ + task_enable_irq(STM32_IRQ_USART(UARTN)); + + init_done = 1; + + return EC_SUCCESS; +} |