Changed formatting and added new UART divsor calculation from OpenSBI.

This commit is contained in:
Jacob Pease 2024-07-25 13:04:27 -05:00
parent 336a413f31
commit a36e846b02

View File

@ -3,94 +3,93 @@
void write_reg_u8(uintptr_t addr, uint8_t value) void write_reg_u8(uintptr_t addr, uint8_t value)
{ {
volatile uint8_t *loc_addr = (volatile uint8_t *)addr; volatile uint8_t *loc_addr = (volatile uint8_t *)addr;
*loc_addr = value; *loc_addr = value;
} }
uint8_t read_reg_u8(uintptr_t addr) uint8_t read_reg_u8(uintptr_t addr)
{ {
return *(volatile uint8_t *)addr; return *(volatile uint8_t *)addr;
} }
int is_transmit_empty() int is_transmit_empty()
{ {
return read_reg_u8(UART_LSR) & 0x20; return read_reg_u8(UART_LSR) & 0x20;
} }
int is_receive_empty() int is_receive_empty()
{ {
return !(read_reg_u8(UART_LSR) & 0x1); return !(read_reg_u8(UART_LSR) & 0x1);
} }
void write_serial(char a) 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) 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_IER, 0x00); // Disable all interrupts
write_reg_u8(UART_LCR, 0x80); // Enable DLAB (set baud rate divisor) 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_DLL, divisor & 0xFF); // divisor (lo byte)
write_reg_u8(UART_DLM, (divisor >> 8) & 0xFF); // divisor (hi 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_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_FCR, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
} }
void print_uart(const char *str) void print_uart(const char *str)
{ {
const char *cur = &str[0]; const char *cur = &str[0];
while (*cur != '\0') while (*cur != '\0') {
{ write_serial((uint8_t)*cur);
write_serial((uint8_t)*cur); ++cur;
++cur; }
}
} }
uint8_t bin_to_hex_table[16] = { 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]) void bin_to_hex(uint8_t inp, uint8_t res[2])
{ {
res[1] = bin_to_hex_table[inp & 0xf]; res[1] = bin_to_hex_table[inp & 0xf];
res[0] = bin_to_hex_table[(inp >> 4) & 0xf]; res[0] = bin_to_hex_table[(inp >> 4) & 0xf];
return; return;
} }
void print_uart_int(uint32_t addr) void print_uart_int(uint32_t addr)
{ {
int i; int i;
for (i = 3; i > -1; i--) for (i = 3; i > -1; i--) {
{ uint8_t cur = (addr >> (i * 8)) & 0xff;
uint8_t cur = (addr >> (i * 8)) & 0xff; uint8_t hex[2];
uint8_t hex[2]; bin_to_hex(cur, hex);
bin_to_hex(cur, hex); write_serial(hex[0]);
write_serial(hex[0]); write_serial(hex[1]);
write_serial(hex[1]); }
}
} }
void print_uart_addr(uint64_t addr) void print_uart_addr(uint64_t addr)
{ {
int i; int i;
for (i = 7; i > -1; i--) for (i = 7; i > -1; i--) {
{ uint8_t cur = (addr >> (i * 8)) & 0xff;
uint8_t cur = (addr >> (i * 8)) & 0xff; uint8_t hex[2];
uint8_t hex[2]; bin_to_hex(cur, hex);
bin_to_hex(cur, hex); write_serial(hex[0]);
write_serial(hex[0]); write_serial(hex[1]);
write_serial(hex[1]); }
}
} }
void print_uart_byte(uint8_t byte) void print_uart_byte(uint8_t byte)
{ {
uint8_t hex[2]; uint8_t hex[2];
bin_to_hex(byte, hex); bin_to_hex(byte, hex);
write_serial(hex[0]); write_serial(hex[0]);
write_serial(hex[1]); write_serial(hex[1]);
} }