From a36e846b0251f533ba2988da6ca2d95ce17b6e17 Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Thu, 25 Jul 2024 13:04:27 -0500 Subject: [PATCH] Changed formatting and added new UART divsor calculation from OpenSBI. --- fpga/zsbl/uart.c | 91 ++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/fpga/zsbl/uart.c b/fpga/zsbl/uart.c index 7ff40e516..1330bc1d9 100644 --- a/fpga/zsbl/uart.c +++ b/fpga/zsbl/uart.c @@ -3,94 +3,93 @@ void write_reg_u8(uintptr_t addr, uint8_t value) { - volatile uint8_t *loc_addr = (volatile uint8_t *)addr; - *loc_addr = value; + volatile uint8_t *loc_addr = (volatile uint8_t *)addr; + *loc_addr = value; } uint8_t read_reg_u8(uintptr_t addr) { - return *(volatile uint8_t *)addr; + return *(volatile uint8_t *)addr; } int is_transmit_empty() { - return read_reg_u8(UART_LSR) & 0x20; + return read_reg_u8(UART_LSR) & 0x20; } int is_receive_empty() { - return !(read_reg_u8(UART_LSR) & 0x1); + return !(read_reg_u8(UART_LSR) & 0x1); } void write_serial(char a) { - while (is_transmit_empty() == 0) {}; + while (is_transmit_empty() == 0) {}; - write_reg_u8(UART_THR, a); + write_reg_u8(UART_THR, a); } void init_uart(uint32_t freq, uint32_t baud) { - uint32_t divisor = freq / (baud << 4); + // Alternative divisor calculation. From OpenSBI code. + // Reduces error for every possible frequency. + uint32_t divisor = (freq + 8 * baud) /(baud << 4); - write_reg_u8(UART_IER, 0x00); // Disable all interrupts - write_reg_u8(UART_LCR, 0x80); // Enable DLAB (set baud rate divisor) - write_reg_u8(UART_DLL, divisor & 0xFF); // divisor (lo byte) - write_reg_u8(UART_DLM, (divisor >> 8) & 0xFF); // divisor (hi byte) - write_reg_u8(UART_LCR, 0x03); // 8 bits, no parity, one stop bit - write_reg_u8(UART_FCR, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + write_reg_u8(UART_IER, 0x00); // Disable all interrupts + write_reg_u8(UART_LCR, 0x80); // Enable DLAB (set baud rate divisor) + write_reg_u8(UART_DLL, divisor & 0xFF); // divisor (lo byte) + write_reg_u8(UART_DLM, (divisor >> 8) & 0xFF); // divisor (hi byte) + write_reg_u8(UART_LCR, 0x03); // 8 bits, no parity, one stop bit + write_reg_u8(UART_FCR, 0xC7); // Enable FIFO, clear them, with 14-byte threshold } void print_uart(const char *str) { - const char *cur = &str[0]; - while (*cur != '\0') - { - write_serial((uint8_t)*cur); - ++cur; - } + const char *cur = &str[0]; + while (*cur != '\0') { + write_serial((uint8_t)*cur); + ++cur; + } } uint8_t bin_to_hex_table[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; void bin_to_hex(uint8_t inp, uint8_t res[2]) { - res[1] = bin_to_hex_table[inp & 0xf]; - res[0] = bin_to_hex_table[(inp >> 4) & 0xf]; - return; + res[1] = bin_to_hex_table[inp & 0xf]; + res[0] = bin_to_hex_table[(inp >> 4) & 0xf]; + return; } void print_uart_int(uint32_t addr) { - int i; - for (i = 3; i > -1; i--) - { - uint8_t cur = (addr >> (i * 8)) & 0xff; - uint8_t hex[2]; - bin_to_hex(cur, hex); - write_serial(hex[0]); - write_serial(hex[1]); - } + int i; + for (i = 3; i > -1; i--) { + uint8_t cur = (addr >> (i * 8)) & 0xff; + uint8_t hex[2]; + bin_to_hex(cur, hex); + write_serial(hex[0]); + write_serial(hex[1]); + } } void print_uart_addr(uint64_t addr) { - int i; - for (i = 7; i > -1; i--) - { - uint8_t cur = (addr >> (i * 8)) & 0xff; - uint8_t hex[2]; - bin_to_hex(cur, hex); - write_serial(hex[0]); - write_serial(hex[1]); - } + int i; + for (i = 7; i > -1; i--) { + uint8_t cur = (addr >> (i * 8)) & 0xff; + uint8_t hex[2]; + bin_to_hex(cur, hex); + write_serial(hex[0]); + write_serial(hex[1]); + } } void print_uart_byte(uint8_t byte) { - uint8_t hex[2]; - bin_to_hex(byte, hex); - write_serial(hex[0]); - write_serial(hex[1]); + uint8_t hex[2]; + bin_to_hex(byte, hex); + write_serial(hex[0]); + write_serial(hex[1]); }