const PERIPHERAL_BASE = @import("board.zig").PERIPHERAL_BASE; const FSEL = PERIPHERAL_BASE + 0x200000; const SET = PERIPHERAL_BASE + 0x20001c; const CLR = PERIPHERAL_BASE + 0x200028; const PULL = PERIPHERAL_BASE + 0x2000e4; const MAX_PIN = 53; fn call( pin: comptime_int, value: u32, base: comptime_int, field_size: comptime_int, ) void { const field_mask: u32 = (1 << field_size) - 1; if (pin > MAX_PIN) @compileError("invalid pin number"); const n_fields = 32 / field_size; const reg = base + (pin / n_fields) * 4; const shift = (pin % n_fields) * field_size; const mmio_ptr: *volatile u32 = @ptrFromInt(reg); var reg_val = mmio_ptr.*; reg_val &= ~(field_mask << shift); reg_val |= value << shift; mmio_ptr.* = reg_val; } pub fn write(pin: comptime_int, value: bool) void { if (value) { call(pin, 1, SET, 1); } else { call(pin, 1, CLR, 1); } } pub const Pull = enum { none, up, down, }; pub fn setPull(pin: comptime_int, pull: Pull) void { call(pin, @intFromEnum(pull), PULL, 2); } pub const Function = enum { input, output, alt5, alt4, alt0, alt1, alt2, alt3, }; pub fn setFunction(pin: comptime_int, function: Function) void { call(pin, @intFromEnum(function), FSEL, 3); }