diff --git a/src/main.zig b/src/main.zig index 0fe4497..64bc6d4 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3,7 +3,7 @@ //! is to delete this file and start with root.zig instead. //const std = @import("std"); -const gpio = packed struct { +const gpio_registers = packed struct { moder: u32, otyper: u32, ospeedr: u32, @@ -18,6 +18,34 @@ const gpio = packed struct { ascr: u32, }; +const gpio = struct { + port: *gpio_registers, + + const mode = enum { + input, + output, + alternate, + analog, + }; + + pub fn set_mode(self: gpio, pin: u4, m: mode) void { + self.port.moder &= ~(@as(u32, 0x3) << (2 * pin)); + + const mask: u32 = switch (m) { + .input => 0, + .output => 1, + .alternate => 2, + .analog => 3 + }; + + self.port.moder |= mask << (2 * pin); + } + + pub fn toggle(self: gpio, pin: u4) void { + self.port.odr ^= @as(u32, 1) << pin; + } +}; + const cpu = struct { pub fn interrupt_disable() void { asm volatile("cpsid i"); @@ -28,18 +56,17 @@ const cpu = struct { } }; -const gpioa: *gpio = @ptrFromInt(0x48000000); +const gpioa = gpio { .port = @ptrFromInt(0x48000000) }; const rcc: *[39]u32 = @ptrFromInt(0x40021000); export fn _start() callconv(.C) noreturn { cpu.interrupt_disable(); rcc[19] |= 1; // gpioaen - gpioa.moder &= ~@as(u32, 0x3 << (5 * 2)); - gpioa.moder |= (1 << (5 * 2)); + gpioa.set_mode(5, .output); while (true) { - gpioa.odr ^= (1 << 5); + gpioa.toggle(5); } }