smol-gilbraltar/serial.c

48 lines
1.2 KiB
C
Raw Normal View History

2024-12-20 22:45:12 +00:00
#include <serial.h>
#include <clock.h>
#include <mem.h>
#define DEFAULT_BAUDRATE 115200
void gilbraltar_serial_init(void) {
uint32_t baudrate = DEFAULT_BAUDRATE;
uint32_t clock_rate = gilbraltar_get_clock(2);
uint32_t baud16 = baudrate * 16;
uint32_t int_div = clock_rate / baud16;
uint32_t fract_div_2 = (clock_rate % baud16) * 8 / baudrate;
uint32_t fract_div = fract_div_2 / 2 + fract_div_2 % 2;
write32(ARM_UART0_IMSC, 0);
write32(ARM_UART0_ICR, 0x7ff);
write32(ARM_UART0_IBRD, int_div);
write32(ARM_UART0_FBRD, fract_div);
write32(ARM_UART0_LCRH, (1 << 4) | (3 << 5));
write32(ARM_UART0_CR, (1 << 0) | (1 << 8) | (1 << 9));
}
void gilbraltar_serial_send(uint8_t chr) {
while (1)
if (!(read32(ARM_UART0_FR) & 0x20)) break;
write32(ARM_UART0_DR, chr);
}
uint8_t gilbraltar_serial_recv(void) {
while (1)
if (!(read32(ARM_UART0_FR) & 0x10)) break;
return (read32(ARM_UART0_DR) & 0xff);
}
void gilbraltar_serial_puts(const char *str) {
while (*str) gilbraltar_serial_send(*str++);
}
void gilbraltar_serial_putchar(int chr) {
gilbraltar_serial_send(chr & 0xff);
}
void gilbraltar_serial_write(const char *str, size_t len) {
while (len--) gilbraltar_serial_send(*str++);
}