diff options
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/uart/util.c | 29 |
1 files changed, 29 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); +} |