sylveos

Toy Operating System
Log | Files | Refs

commit 031266dabb2c016249295510cae533e85d8bc198
parent bec24b32e7ba98c90eb70f25af83d5a11b184fb9
Author: Sylvia Ivory <git@sivory.net>
Date:   Tue, 13 Jan 2026 16:18:16 -0800

Use array indexes instead of switches

Diffstat:
Msrc/gpio.zig | 64++++++++++++++++++----------------------------------------------
1 file changed, 18 insertions(+), 46 deletions(-)

diff --git a/src/gpio.zig b/src/gpio.zig @@ -4,21 +4,10 @@ const util = @import("util.zig"); // Page 90, Table 6-1: GPIO Register Assignment const BASE_ADDR: u32 = 0x2020_0000; -const GPFSEL0: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x0000); -const GPFSEL1: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x0004); -const GPFSEL2: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x0008); -const GPFSEL3: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x000C); -const GPFSEL4: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x0010); -const GPFSEL5: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x0014); - -const GPSET0: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x001C); -const GPSET1: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x0020); - -const GPCLR0: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x0028); -const GPCLR1: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x002C); - -const GPLEV0: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x0034); -const GPLEV1: *volatile u32 = @ptrFromInt(BASE_ADDR + 0x0038); +const GPFSEL0: [*]volatile u32 = @ptrFromInt(BASE_ADDR + 0x0000); +const GPSET0: [*]volatile u32 = @ptrFromInt(BASE_ADDR + 0x001C); +const GPCLR0: [*]volatile u32 = @ptrFromInt(BASE_ADDR + 0x0028); +const GPLEV0: [*]volatile u32 = @ptrFromInt(BASE_ADDR + 0x0034); // Page 92, Table 6-2: GPIO Alternate function select register 0 // All function select registers reflect this bit layout @@ -35,26 +24,25 @@ const FunctionSelect = enum(u3) { }; fn fn_sel(pin: u8, sel: FunctionSelect) void { - // TODO; this can be array assignment - const address: *volatile u32 = switch (pin) { - 0...9 => GPFSEL0, - 10...19 => GPFSEL1, - 20...29 => GPFSEL2, - 30...39 => GPFSEL3, - 40...49 => GPFSEL4, - 50...53 => GPFSEL5, - else => @panic("pin out of range (0...53)"), - }; + if (pin > 53) @panic("pin out of range (0...53)"); + + const index = @divFloor(pin, 10); + const address: *volatile u32 = &GPFSEL0[index]; const offset: u5 = @truncate((pin % 10) * 3); const mask = ~(@as(u32, 0b111) << offset); - var state = address.*; // util.get_32(@ptrFromInt(address)); + var state = address.*; state &= mask; state |= (@as(u32, @intCast(@intFromEnum(sel))) << offset); - // util.put_32(@ptrFromInt(address), state); address.* = state; } +fn addr_get(pin: u8, address: [*]volatile u32) *volatile u32 { + if (pin > 53) @panic("pin out of range (0...53)"); + + return &address[@divFloor(pin, 32)]; +} + fn addr_bitset(pin: u8, address: *volatile u32) void { const offset: u5 = @truncate(pin % 32); const mask = (@as(u32, 1) << offset); @@ -66,24 +54,12 @@ fn addr_bitset(pin: u8, address: *volatile u32) void { // Turn on fn output_set(pin: u8) void { - const address: *volatile u32 = switch (pin) { - 0...31 => GPSET0, - 32...53 => GPSET1, - else => @panic("pin out of range (0...53)"), - }; - - addr_bitset(pin, address); + addr_bitset(pin, addr_get(pin, GPSET0)); } // Turn off fn output_clear(pin: u8) void { - const address: *volatile u32 = switch (pin) { - 0...31 => GPCLR0, - 32...53 => GPCLR1, - else => @panic("pin out of range (0...53)"), - }; - - addr_bitset(pin, address); + addr_bitset(pin, addr_get(pin, GPCLR0)); } pub fn set_output(pin: u8) void { @@ -103,11 +79,7 @@ pub fn set_off(pin: u8) void { } pub fn read(pin: u8) bool { - const address: *volatile u32 = switch (pin) { - 0...31 => GPLEV0, - 32...53 => GPLEV1, - else => @panic("pin out of range (0...53)"), - }; + const address = addr_get(pin, GPLEV0); const offset: u5 = @truncate(pin % 32); const mask = (@as(u32, 1) << offset);