commit 09706d2cb7559581198b024d80e25c83fec32ee2
parent c80b2f6fe21d52e11336b80d92ddfd336758bd37
Author: Sylvia Ivory <git@sivory.net>
Date: Tue, 20 Jan 2026 18:07:33 -0800
Fix UART
Diffstat:
6 files changed, 31 insertions(+), 48 deletions(-)
diff --git a/build.zig b/build.zig
@@ -68,7 +68,7 @@ fn add_exe_real(exe_name: []const u8, path: std.Build.LazyPath, b: *std.Build) !
const boot = b.createModule(.{
.root_source_file = path,
.target = b.resolveTargetQuery(target),
- .optimize = .ReleaseSafe,
+ .optimize = .ReleaseSmall,
.unwind_tables = .none,
.single_threaded = true,
.error_tracing = false,
diff --git a/pi/mem.zig b/pi/mem.zig
@@ -25,13 +25,12 @@ const BarrierKind = enum {
const Operation = enum {
Read,
Write,
- General,
};
pub inline fn barrier(op: Operation) void {
switch (op) {
.Write => dmb(),
- .General | .Read => dsb(),
+ .Read => dsb(),
}
}
@@ -52,7 +51,7 @@ pub inline fn put_u32_barrier(
}
pub inline fn get_u32(address: *u32) u32 {
- return asm volatile ("str %[result], [%[address]]"
+ return asm volatile ("ldr %[result], [%[address]]"
: [result] "=r" (-> u32),
: [address] "r" (address),
);
diff --git a/pi/root.zig b/pi/root.zig
@@ -1 +1,2 @@
pub const mem = @import("./mem.zig");
+pub extern fn nop() void;
diff --git a/src/devices/gpio.zig b/src/devices/gpio.zig
@@ -120,8 +120,6 @@ fn wait(count: usize) void {
var c = count;
while (c != 0) {
c -= 1;
- // does this cook us?
- std.atomic.spinLoopHint();
}
}
diff --git a/src/devices/mini-uart.zig b/src/devices/mini-uart.zig
@@ -9,17 +9,17 @@ pub const Error = error{AlreadyInitialized} || gpio.Error;
// Page 8: Auxiliary peripherals Register Map
const BASE_ADDRESS: usize = mem.BASE_ADDRESS + 0x0021_5000;
const AUX_ENABLES: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_IO_REG: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_IER_REG: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_IIR_REG: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_LCR_REG: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_MCR_REG: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_LSR_REG: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_MSR_REG: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_SCRATCH: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_CNTL_REG: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_STAT_REG: usize = BASE_ADDRESS + 0x0004;
-const AUX_MU_BAUD_REG: usize = BASE_ADDRESS + 0x0004;
+const AUX_MU_IO_REG: usize = BASE_ADDRESS + 0x0040;
+const AUX_MU_IER_REG: usize = BASE_ADDRESS + 0x0044;
+const AUX_MU_IIR_REG: usize = BASE_ADDRESS + 0x0048;
+const AUX_MU_LCR_REG: usize = BASE_ADDRESS + 0x004C;
+const AUX_MU_MCR_REG: usize = BASE_ADDRESS + 0x0050;
+const AUX_MU_LSR_REG: usize = BASE_ADDRESS + 0x0054;
+const AUX_MU_MSR_REG: usize = BASE_ADDRESS + 0x0058;
+const AUX_MU_SCRATCH: usize = BASE_ADDRESS + 0x005C;
+const AUX_MU_CNTL_REG: usize = BASE_ADDRESS + 0x0060;
+const AUX_MU_STAT_REG: usize = BASE_ADDRESS + 0x0064;
+const AUX_MU_BAUD_REG: usize = BASE_ADDRESS + 0x0068;
const CLOCK_FREQ = 250_000_000;
@@ -34,20 +34,20 @@ const RxPin = enum(u8) {
Gpio37 = 37,
};
-var is_initialized = false;
+// var is_initialized = false;
pub fn initialize(baud: u32, tx_pin: TxPin, rx_pin: RxPin) Error!void {
- if (is_initialized) return Error.AlreadyInitialized;
+ // if (is_initialized) return Error.AlreadyInitialized;
// Set GPIO pins first (as specified by manual)
// Page 102 specifies which alt mode
const tx_fn: gpio.FunctionSelect = switch (tx_pin) {
- .Gpio14 => .alt_fn_0,
+ .Gpio14 => .alt_fn_5,
.Gpio32 => .alt_fn_3,
.Gpio36 => .alt_fn_2,
};
const rx_fn: gpio.FunctionSelect = switch (rx_pin) {
- .Gpio15 => .alt_fn_0,
+ .Gpio15 => .alt_fn_5,
.Gpio33 => .alt_fn_3,
.Gpio37 => .alt_fn_2,
};
@@ -75,7 +75,8 @@ pub fn initialize(baud: u32, tx_pin: TxPin, rx_pin: RxPin) Error!void {
// Set data size to 8 bits
// Page 14: AUX_MU_LCR_REG Register
// When bit 0 is 1, UART is in 8-bit mode, else 7-bit
- mem.put_u32(@ptrFromInt(AUX_MU_LCR_REG), 1);
+ // mem.put_u32(@ptrFromInt(AUX_MU_LCR_REG), 1);
+ mem.put_u32(@ptrFromInt(AUX_MU_LCR_REG), 3);
// Put RTS high (indicate request to send)
// Page 14: AUX_MU_MCR_REG Register
@@ -85,52 +86,50 @@ pub fn initialize(baud: u32, tx_pin: TxPin, rx_pin: RxPin) Error!void {
// Clear FIFO
// Page 12: AUX_MU_IER_REG Register (yes the page is mislabeled)
// When bit 1/2 is 1, receive/transmit will be cleared
- mem.put_u32(@ptrFromInt(AUX_MU_IIR_REG), 0x6);
+ mem.put_u32(@ptrFromInt(AUX_MU_IIR_REG), 0x06);
+ // mem.put_u32(@ptrFromInt(AUX_MU_IIR_REG), 0xC6);
// Set baud rate
// Page 11: 2.2.1 Mini UART Implementation Details
// The baudrate formula is given as (system_clock_freq)/(8 * (baudrate_reg + 1))
- mem.put_u32(@ptrFromInt(AUX_MU_BAUD_REG), CLOCK_FREQ / (8 * (baud + 1)));
+ mem.put_u32(@ptrFromInt(AUX_MU_BAUD_REG), CLOCK_FREQ / (8 * baud) - 1);
// Enable RX/TX again
// Page 17: AUX_MU_CNTL_REG Register
// When bit 0/1 is 1, UART receiver/transmitter is enabled
mem.put_u32(@ptrFromInt(AUX_MU_CNTL_REG), 0x3);
+ // mem.put_u32(@ptrFromInt(AUX_MU_CNTL_REG), 2);
- is_initialized = true;
+ // is_initialized = true;
}
fn can_write() bool {
// Check if FIFO can accept data
// Page 15: AUX_MU_LSR_REG Register
// Bit 5 is set when FIFO can accept at least 1 byte
- return mem.get_u32(@ptrFromInt(AUX_MU_LSR_REG)) & 0x20 != 0;
+ return (mem.get_u32(@ptrFromInt(AUX_MU_LSR_REG)) & 0x20) != 0;
}
fn can_read() bool {
// Check if FIFO has data
// Page 15: AUX_MU_LSR_REG Register
// Bit 1 is set when FIFO holds at least 1 byte
- return mem.get_u32(@ptrFromInt(AUX_MU_LSR_REG)) & 1;
+ return (mem.get_u32(@ptrFromInt(AUX_MU_LSR_REG)) & 1) == 1;
}
pub fn write_byte(byte: u8) void {
// TODO; support timeout
- while (!can_write()) {
- std.atomic.spinLoopHint();
- }
+ while (!can_write()) {}
// Write into FIFO
// Page 11: AUX_MU_IO_REG Register
// Bits 7:0 holds data from the FIFO
- mem.put_u32(@ptrFromInt(AUX_MU_IO_REG), @as(u32, byte));
+ mem.put_u32(@ptrFromInt(AUX_MU_IO_REG), @as(u32, byte) & 0xFF);
}
pub fn read_byte() u8 {
// TODO; support timeout
- while (!can_read()) {
- std.atomic.spinLoopHint();
- }
+ while (!can_read()) {}
// Read from FIFO
// Page 11: AUX_MU_IO_REG Register
diff --git a/start.s b/start.s
@@ -11,17 +11,3 @@ _start:
.align 8
nop:
bx lr
-
-.global put_u32
-.type put_u32, function
-.align 8
-put_u32:
- str r1,[r0]
- bx lr
-
-.global get_u32
-.type get_u32, function
-.align 8
-get_u32:
- ldr r0,[r0]
- bx lr