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:
| M | src/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);