summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/uart/util.c29
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);
+}