diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/drivers/uart/util.c | 29 | ||||
-rw-r--r-- | src/include/console/uart.h | 3 |
2 files changed, 32 insertions, 0 deletions
diff --git a/src/drivers/uart/util.c b/src/drivers/uart/util.c index c7b9ab21eb..d38f688da2 100644 --- a/src/drivers/uart/util.c +++ b/src/drivers/uart/util.c @@ -13,6 +13,8 @@ #include <console/console.h> #include <console/uart.h> +#include <types.h> +#include <timer.h> /* Calculate divisor. Do not floor but round to nearest integer. */ unsigned int uart_baudrate_divisor(unsigned int baudrate, @@ -53,3 +55,30 @@ unsigned int uart_platform_refclk(void) return 115200 * 16; } #endif + +/* Helper function to allow bitbanging an 8n1 UART. */ +void uart_bitbang_tx_byte(unsigned char data, void (*set_tx)(int line_state)) +{ + const int baud_rate = get_uart_baudrate(); + int i; + struct stopwatch sw; + stopwatch_init(&sw); + + /* Send start bit */ + set_tx(0); + while (stopwatch_duration_usecs(&sw) < MHz / baud_rate) + stopwatch_tick(&sw); + + /* 'i' counts the total bits sent at the end of the loop */ + for (i = 2; i < 10; i++) { + set_tx(data & 1); + data >>= 1; + while (stopwatch_duration_usecs(&sw) < i * MHz / baud_rate) + stopwatch_tick(&sw); + } + + /* Send stop bit */ + set_tx(1); + while (stopwatch_duration_usecs(&sw) < i * MHz / baud_rate) + stopwatch_tick(&sw); +} diff --git a/src/include/console/uart.h b/src/include/console/uart.h index 3bd390e75b..2e9c7b815c 100644 --- a/src/include/console/uart.h +++ b/src/include/console/uart.h @@ -46,6 +46,9 @@ unsigned int uart_baudrate_divisor(unsigned int baudrate, */ unsigned int uart_input_clock_divider(void); +/* Bitbang out one byte on an 8n1 UART through the output function set_tx(). */ +void uart_bitbang_tx_byte(unsigned char data, void (*set_tx)(int line_state)); + void uart_init(int idx); void uart_tx_byte(int idx, unsigned char data); void uart_tx_flush(int idx); |