diff options
| author | wires <wires@noreply.wires.systems> | 2025-10-06 06:07:10 -0400 |
|---|---|---|
| committer | wires <wires@noreply.wires.systems> | 2025-10-06 06:07:10 -0400 |
| commit | 2379c573da65fd13d4e5bd16619b321744ac37fe (patch) | |
| tree | 9552f19b902fe9626b6c9e644f131d7bad8bdd0e /src/gpio.zig | |
| parent | get building on 0.15.1 (diff) | |
| download | zosimos-2379c573da65fd13d4e5bd16619b321744ac37fe.tar.gz | |
blocking serial messages
Diffstat (limited to 'src/gpio.zig')
| -rw-r--r-- | src/gpio.zig | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/gpio.zig b/src/gpio.zig new file mode 100644 index 0000000..ba54394 --- /dev/null +++ b/src/gpio.zig @@ -0,0 +1,62 @@ +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); +} |