improve GPIO API (#59)

wch-ch32v003
Matt Knight 1 year ago committed by GitHub
parent d05e8779b8
commit a2ccaff13f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,9 +5,8 @@ const assert = std.debug.assert;
const microzig = @import("microzig"); const microzig = @import("microzig");
const ADC = microzig.chip.peripherals.ADC; const ADC = microzig.chip.peripherals.ADC;
const rp2040 = microzig.hal; const gpio = @import("gpio.zig");
const gpio = rp2040.gpio; const resets = @import("resets.zig");
const resets = rp2040.resets;
pub const temperature_sensor = struct { pub const temperature_sensor = struct {
pub inline fn init() void { pub inline fn init() void {

@ -1,7 +1,6 @@
const std = @import("std"); const std = @import("std");
const pll = @import("pll.zig"); const pll = @import("pll.zig");
const util = @import("util.zig");
const assert = std.debug.assert; const assert = std.debug.assert;
// TODO: remove // TODO: remove

@ -63,7 +63,7 @@ pub const Enabled = enum {
enabled, enabled,
}; };
pub const PullUpDown = enum { pub const Pull = enum {
up, up,
down, down,
}; };
@ -76,12 +76,45 @@ pub fn num(n: u5) Pin {
} }
pub fn mask(m: u32) Mask { pub fn mask(m: u32) Mask {
_ = m; return @intToEnum(Mask, m);
@panic("TODO");
} }
pub const Mask = enum(u30) { pub const Mask = enum(u30) {
_, _,
pub fn set_function(self: Mask, function: Function) void {
const raw_mask = @enumToInt(self);
for (0..@bitSizeOf(Mask)) |i| {
const bit = @intCast(u5, i);
if (0 != raw_mask & (@as(u32, 1) << bit))
num(bit).set_function(function);
}
}
pub fn set_direction(self: Mask, direction: Direction) void {
const raw_mask = @enumToInt(self);
switch (direction) {
.out => SIO.GPIO_OE_SET.raw = raw_mask,
.in => SIO.GPIO_OE_CLR.raw = raw_mask,
}
}
pub fn set_pull(self: Mask, pull: ?Pull) void {
const raw_mask = @enumToInt(self);
for (0..@bitSizeOf(Mask)) |i| {
const bit = @intCast(u5, i);
if (0 != raw_mask & (@as(u32, 1) << bit))
num(bit).set_pull(pull);
}
}
pub fn put(self: Mask, value: u32) void {
SIO.GPIO_OUT_XOR.raw = (SIO.GPIO_OUT.raw ^ value) & @enumToInt(self);
}
pub fn read(self: Mask) u32 {
return SIO.GPIO_IN.raw & @enumToInt(self);
}
}; };
pub const Pin = enum(u5) { pub const Pin = enum(u5) {
@ -134,12 +167,12 @@ pub const Pin = enum(u5) {
return @as(u32, 1) << @enumToInt(gpio); return @as(u32, 1) << @enumToInt(gpio);
} }
pub inline fn set_pull(gpio: Pin, mode: ?PullUpDown) void { pub inline fn set_pull(gpio: Pin, pull: ?Pull) void {
const pads_reg = gpio.get_pads_reg(); const pads_reg = gpio.get_pads_reg();
if (mode == null) { if (pull == null) {
pads_reg.modify(.{ .PUE = 0, .PDE = 0 }); pads_reg.modify(.{ .PUE = 0, .PDE = 0 });
} else switch (mode.?) { } else switch (pull.?) {
.up => pads_reg.modify(.{ .PUE = 1, .PDE = 0 }), .up => pads_reg.modify(.{ .PUE = 1, .PDE = 0 }),
.down => pads_reg.modify(.{ .PUE = 0, .PDE = 1 }), .down => pads_reg.modify(.{ .PUE = 0, .PDE = 1 }),
} }
@ -171,6 +204,11 @@ pub const Pin = enum(u5) {
0; 0;
} }
pub inline fn set_input_enabled(pin: Pin, enabled: bool) void {
const pads_reg = pin.get_pads_reg();
pads_reg.modify(.{ .IE = @boolToInt(enabled) });
}
pub inline fn set_function(gpio: Pin, function: Function) void { pub inline fn set_function(gpio: Pin, function: Function) void {
const pads_reg = gpio.get_pads_reg(); const pads_reg = gpio.get_pads_reg();
pads_reg.modify(.{ pads_reg.modify(.{
@ -193,33 +231,4 @@ pub const Pin = enum(u5) {
.padding = 0, .padding = 0,
}); });
} }
//pub fn set_drive_strength(gpio: Gpio, drive: DriveStrength) void {
// _ = drive;
// const pads_reg = gpio.get_pads_reg();
// pads_reg.modify(.{
// .DRIVE = .{
// .value = .@"12mA",
// },
// });
//}
}; };
// setting both uplls enables a "bus keep" function, a weak pull to whatever
// is current high/low state of GPIO
//pub fn setPulls(gpio: u32, up: bool, down: bool) void {}
//
//pub fn pullUp(gpio: u32) void {}
//
//pub fn pullDown(gpio: u32) void {}
//pub fn disablePulls(gpio: u32) void {}
//pub fn setIrqOver(gpio: u32, value: u32) void {}
//pub fn setOutOver(gpio: u32, value: u32) void {}
//pub fn setInOver(gpio: u32, value: u32) void {}
//pub fn setOeOver(gpio: u32, value: u32) void {}
//pub fn setInputEnabled(gpio: u32, enabled: Enabled) void {}
//pub fn setinputHysteresisEnabled(gpio: u32, enabled: Enabled) void {}
//pub fn setSlewRate(gpio: u32, slew_rate: SlewRate) void {}
//pub fn setIrqEnabled(gpio: u32, events: IrqEvents) void {}
//pub fn acknowledgeIrq(gpio: u32, events: IrqEvents) void {}

@ -19,16 +19,16 @@ const xor_bits = @as(u32, 0x1) << 12;
const set_bits = @as(u32, 0x2) << 12; const set_bits = @as(u32, 0x2) << 12;
const clear_bits = @as(u32, 0x3) << 12; const clear_bits = @as(u32, 0x3) << 12;
pub fn clear_alias_raw(ptr: anytype) *u32 { pub fn clear_alias_raw(ptr: anytype) *volatile u32 {
return @intToPtr(*u32, @ptrToInt(ptr) | clear_bits); return @intToPtr(*volatile u32, @ptrToInt(ptr) | clear_bits);
} }
pub fn set_alias_raw(ptr: anytype) *u32 { pub fn set_alias_raw(ptr: anytype) *volatile u32 {
return @intToPtr(*u32, @ptrToInt(ptr) | set_bits); return @intToPtr(*volatile u32, @ptrToInt(ptr) | set_bits);
} }
pub fn xor_alias_raw(ptr: anytype) *u32 { pub fn xor_alias_raw(ptr: anytype) *volatile u32 {
return @intToPtr(*u32, @ptrToInt(ptr) | xor_bits); return @intToPtr(*volatile u32, @ptrToInt(ptr) | xor_bits);
} }
pub fn clear_alias(ptr: anytype) @TypeOf(ptr) { pub fn clear_alias(ptr: anytype) @TypeOf(ptr) {
@ -42,3 +42,7 @@ pub fn set_alias(ptr: anytype) @TypeOf(ptr) {
pub fn xor_alias(ptr: anytype) @TypeOf(ptr) { pub fn xor_alias(ptr: anytype) @TypeOf(ptr) {
return @intToPtr(@TypeOf(ptr), @ptrToInt(ptr) | xor_bits); return @intToPtr(@TypeOf(ptr), @ptrToInt(ptr) | xor_bits);
} }
pub inline fn tight_loop_contents() void {
asm volatile ("" ::: "memory");
}

@ -48,7 +48,7 @@ pub const Pin = enum {
function: Function = .SIO, function: Function = .SIO,
direction: ?gpio.Direction = null, direction: ?gpio.Direction = null,
drive_strength: ?gpio.DriveStrength = null, drive_strength: ?gpio.DriveStrength = null,
pull: ?gpio.PullUpDown = null, pull: ?gpio.Pull = null,
slew_rate: ?gpio.SlewRate = null, slew_rate: ?gpio.SlewRate = null,
// input/output enable // input/output enable
// schmitt trigger // schmitt trigger

@ -8,7 +8,7 @@ const gpio = @import("gpio.zig");
const clocks = @import("clocks.zig"); const clocks = @import("clocks.zig");
const resets = @import("resets.zig"); const resets = @import("resets.zig");
const time = @import("time.zig"); const time = @import("time.zig");
const util = @import("util.zig"); const hw = @import("hw.zig");
const SpiRegs = microzig.chip.types.peripherals.SPI0; const SpiRegs = microzig.chip.types.peripherals.SPI0;
@ -101,7 +101,7 @@ pub const SPI = enum(u1) {
// push-on-full, but continues shifting. Safe if SSPIMSC_RORIM is not set. // push-on-full, but continues shifting. Safe if SSPIMSC_RORIM is not set.
for (src) |s| { for (src) |s| {
while (!spi.is_writable()) { while (!spi.is_writable()) {
util.tight_loop_contents(); hw.tight_loop_contents();
} }
spi_regs.SSPDR.write_raw(s); spi_regs.SSPDR.write_raw(s);
} }
@ -111,7 +111,7 @@ pub const SPI = enum(u1) {
_ = spi_regs.SSPDR.read(); _ = spi_regs.SSPDR.read();
} }
while (spi_regs.SSPSR.read().BSY == 1) { while (spi_regs.SSPSR.read().BSY == 1) {
util.tight_loop_contents(); hw.tight_loop_contents();
} }
while (spi.is_readable()) { while (spi.is_readable()) {
_ = spi_regs.SSPDR.read(); _ = spi_regs.SSPDR.read();

@ -1,18 +0,0 @@
pub fn xor_alias(ptr: anytype) @TypeOf(ptr) {
const xor_addr = @ptrToInt(ptr) | (1 << 12);
return @ptrCast(@TypeOf(ptr), xor_addr);
}
pub fn set_alias(ptr: anytype) @TypeOf(ptr) {
const set_addr = @ptrToInt(ptr) | (2 << 12);
return @ptrCast(@TypeOf(ptr), set_addr);
}
pub fn clear_alias(ptr: anytype) @TypeOf(ptr) {
const clear_addr = @ptrToInt(ptr) | (3 << 12);
return @ptrCast(@TypeOf(ptr), clear_addr);
}
pub inline fn tight_loop_contents() void {
asm volatile ("" ::: "memory");
}
Loading…
Cancel
Save