aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <clyne@bitgloo.com>2024-10-05 20:28:17 -0400
committerClyne Sullivan <clyne@bitgloo.com>2024-10-05 20:28:17 -0400
commit69c9c4a84d9c40ced2826ba450f85916f43721db (patch)
tree42a2283d332431e4bf69c74e400241dc700dbd9b
parentbf74c7079c74f33a174f21d5c58fdaf70c20b964 (diff)
abstract gpio driver
-rw-r--r--build.zig3
-rw-r--r--src/gpio.zig122
2 files changed, 76 insertions, 49 deletions
diff --git a/build.zig b/build.zig
index eacdb1e..00d19c4 100644
--- a/build.zig
+++ b/build.zig
@@ -12,7 +12,8 @@ pub fn build(b: *std.Build) void {
.name = "stm32",
.root_source_file = b.path("src/main.zig"),
.target = target,
- .optimize = .Debug, // .ReleaseSmall,
+ //.optimize = .Debug,
+ .optimize = .ReleaseSafe,
.linkage = .static,
});
diff --git a/src/gpio.zig b/src/gpio.zig
index cbb20fa..c0bf6ba 100644
--- a/src/gpio.zig
+++ b/src/gpio.zig
@@ -1,4 +1,26 @@
-const registers = packed struct {
+const mode = enum(u32) {
+ alternate_0 = 0,
+ alternate_1,
+ alternate_2,
+ alternate_3,
+ alternate_4,
+ alternate_5,
+ alternate_6,
+ alternate_7,
+ alternate_8,
+ alternate_9,
+ alternate_10,
+ alternate_11,
+ alternate_12,
+ alternate_13,
+ alternate_14,
+ alternate_15,
+ input,
+ output,
+ analog,
+};
+
+const driver_stm32 = packed struct {
moder: u32,
otyper: u32,
ospeedr: u32,
@@ -10,36 +32,10 @@ const registers = packed struct {
afr: u64,
brr: u32,
ascr: u32,
-};
-
-const driver = struct {
- port: *registers,
-
- const mode = enum(u32) {
- alternate_0 = 0,
- alternate_1,
- alternate_2,
- alternate_3,
- alternate_4,
- alternate_5,
- alternate_6,
- alternate_7,
- alternate_8,
- alternate_9,
- alternate_10,
- alternate_11,
- alternate_12,
- alternate_13,
- alternate_14,
- alternate_15,
- input,
- output,
- analog,
- };
- pub fn set_mode(self: driver, pin: u4, m: mode) void {
+ pub fn set_mode(self: *driver_stm32, pin: u4, m: mode) void {
const offset = 2 * @as(u5, pin);
- const moder = self.port.moder & ~(@as(u32, 3) << offset);
+ const moder = self.moder & ~(@as(u32, 3) << offset);
const mask: u32 = switch (m) {
.input => 0,
@@ -48,28 +44,28 @@ const driver = struct {
else => 2,
};
- self.port.moder = moder | (mask << offset);
+ self.moder = moder | (mask << offset);
if (mask == 2) {
const afr_offset = (4 * @as(u6, pin));
- const afr = self.port.afr & ~(@as(u64, 0xF) << afr_offset);
- self.port.afr = afr | (@as(u64, @intFromEnum(m)) << afr_offset);
+ const afr = self.afr & ~(@as(u64, 0xF) << afr_offset);
+ self.afr = afr | (@as(u64, @intFromEnum(m)) << afr_offset);
}
}
- pub fn toggle(self: driver, pin: u4) void {
- self.port.odr ^= @as(u32, 1) << pin;
+ pub fn toggle(self: *driver_stm32, pin: u4) void {
+ self.odr ^= @as(u32, 1) << pin;
}
- pub fn set(self: driver, pin: u4) void {
- self.port.odr |= @as(u32, 1) << pin;
+ pub fn set(self: *driver_stm32, pin: u4) void {
+ self.odr |= @as(u32, 1) << pin;
}
- pub fn clear(self: driver, pin: u4) void {
- self.port.odr &= ~(@as(u32, 1) << pin);
+ pub fn clear(self: *driver_stm32, pin: u4) void {
+ self.odr &= ~(@as(u32, 1) << pin);
}
- pub fn write(self: driver, pin: u4, val: bool) void {
+ pub fn write(self: *driver_stm32, pin: u4, val: bool) void {
if (val) {
self.set(pin);
} else {
@@ -77,17 +73,47 @@ const driver = struct {
}
}
+ pub fn read(self: driver_stm32, pin: u4) bool {
+ return (self.idr & @as(u32, 1) << pin) != 0;
+ }
+};
+
+const driver = struct {
+ const lld_type = driver_stm32;
+
+ lld: *lld_type,
+
+ pub fn set_mode(self: driver, pin: u4, m: mode) void {
+ self.lld.set_mode(pin, m);
+ }
+
+ pub fn toggle(self: driver, pin: u4) void {
+ self.lld.toggle(pin);
+ }
+
+ pub fn set(self: driver, pin: u4) void {
+ self.lld.set(pin);
+ }
+
+ pub fn clear(self: driver, pin: u4) void {
+ self.lld.clear(pin);
+ }
+
+ pub fn write(self: driver, pin: u4, val: bool) void {
+ self.lld.write(pin, val);
+ }
+
pub fn read(self: driver, pin: u4) bool {
- return (self.port.idr & @as(u32, 1) << pin) != 0;
+ return self.lld.read(pin);
}
};
-pub const gpioa = driver { .port = @ptrFromInt(0x48000000) };
-pub const gpiob = driver { .port = @ptrFromInt(0x48000400) };
-pub const gpioc = driver { .port = @ptrFromInt(0x48000800) };
-pub const gpiod = driver { .port = @ptrFromInt(0x48000C00) };
-pub const gpioe = driver { .port = @ptrFromInt(0x48001000) };
-pub const gpiof = driver { .port = @ptrFromInt(0x48001400) };
-pub const gpiog = driver { .port = @ptrFromInt(0x48001800) };
-pub const gpioh = driver { .port = @ptrFromInt(0x48001C00) };
+pub const gpioa = driver { .lld = @ptrFromInt(0x48000000) };
+pub const gpiob = driver { .lld = @ptrFromInt(0x48000400) };
+pub const gpioc = driver { .lld = @ptrFromInt(0x48000800) };
+pub const gpiod = driver { .lld = @ptrFromInt(0x48000C00) };
+pub const gpioe = driver { .lld = @ptrFromInt(0x48001000) };
+pub const gpiof = driver { .lld = @ptrFromInt(0x48001400) };
+pub const gpiog = driver { .lld = @ptrFromInt(0x48001800) };
+pub const gpioh = driver { .lld = @ptrFromInt(0x48001C00) };