diff --git a/hal/uart.zig b/hal/uart.zig index 1a5a97f..47f342d 100644 --- a/hal/uart.zig +++ b/hal/uart.zig @@ -18,6 +18,8 @@ const NS16550A_THR: usize = 0x00; // Transmitter Holding Register const NS16550A_LSR: usize = 0x05; // Line Status Register const NS16550A_THRE: u8 = 1 << 5; // Transmitter Holding Register Empty const NS16550A_IER: usize = 0x01; // Interrupt Enable Register +const NS16550A_FCR: usize = 0x02; // FIFO Control Register +const NS16550A_LCR: usize = 0x03; // Line Control Register // Input Ring Buffer (256 bytes, power of 2 for fast masking) const INPUT_BUFFER_SIZE = 256; @@ -37,16 +39,22 @@ pub fn init() void { } pub fn init_riscv() void { - // Disable Interrupts to rely on Polling (prevents Interrupt Storms if Handler is missing) - const ier: *volatile u8 = @ptrFromInt(NS16550A_BASE + NS16550A_IER); + const base = NS16550A_BASE; + + // 1. Disable Interrupts + const ier: *volatile u8 = @ptrFromInt(base + NS16550A_IER); ier.* = 0x00; - // Drain FIFO - const lsr: *volatile u8 = @ptrFromInt(NS16550A_BASE + NS16550A_LSR); - const rbr: *volatile u8 = @ptrFromInt(NS16550A_BASE + NS16550A_THR); - while ((lsr.* & 0x01) != 0) { - _ = rbr.*; - } + // 2. Enable FIFO, clear them, with 14-byte threshold + const fcr: *volatile u8 = @ptrFromInt(base + NS16550A_FCR); + fcr.* = 0x07; + + // 3. Set LCR to 8N1 + const lcr: *volatile u8 = @ptrFromInt(base + NS16550A_LCR); + lcr.* = 0x03; + + // Capture any data already in hardware FIFO + poll_input(); } /// Poll UART hardware and move available bytes into ring buffer