Skip to content

Commit

Permalink
RP2040 I2C Refactor (ZigEmbeddedGroup#213)
Browse files Browse the repository at this point in the history
* Various performance improvements to I2C reads/writes related to how/when polling occurs
* Simplified API so that all reading/writing happens in 3 functions
* Corrected tranlation of baud rate to register settings
* Tweaked how I2C is "initalized" and "deinitialized"
* Moved most of the error handling responsibility onto the caller of the I2C API, for example code no longer calls `panic()`, but rather bubbles up an error to the caller for them to make a decision on
* Added "const correctness" to API
* Added comments being explicit about what features of the hardware this API doesn't support
* Removed const correctness stuff
* Changed from_instance_number namespace
* Changed translate_baudrate namespace + moved tests
* Changed some terminology!
* Updated some function names and reverted some design patterns after further discussion
* Fixed example and changed how instances are accessed
* Removed redundant calls to get_regs()

---------

Co-authored-by: Hayden Riddiford <hayden@terrakaffe.com>
  • Loading branch information
2 people authored and EliSauder committed Aug 27, 2024
1 parent 27cd7c0 commit f776b12
Show file tree
Hide file tree
Showing 6 changed files with 467 additions and 273 deletions.
1 change: 1 addition & 0 deletions bsp/raspberrypi/rp2040/src/hal.zig
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ pub fn get_cpu_id() u32 {
test "hal tests" {
_ = pio;
_ = usb;
_ = i2c;
}
4 changes: 2 additions & 2 deletions bsp/raspberrypi/rp2040/src/hal/adc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ pub const Input = enum(u3) {
switch (in) {
else => {
const pin = in.get_gpio_pin();
pin.set_function(.null);
pin.set_pull(null);
pin.set_function(.disabled);
pin.set_pull(.disabled);
pin.set_input_enabled(false);
},
.temp_sensor => {},
Expand Down
51 changes: 44 additions & 7 deletions bsp/raspberrypi/rp2040/src/hal/gpio.zig
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub const Function = enum(u5) {
pio1,
gpck,
usb,
null = 0x1f,
disabled = 0x1f,
};

pub const Direction = enum(u1) {
Expand Down Expand Up @@ -66,6 +66,7 @@ pub const Enabled = enum {
pub const Pull = enum {
up,
down,
disabled,
};

pub fn num(n: u5) Pin {
Expand Down Expand Up @@ -99,7 +100,7 @@ pub const Mask = enum(u30) {
}
}

pub fn set_pull(self: Mask, pull: ?Pull) void {
pub fn set_pull(self: Mask, pull: Pull) void {
const raw_mask = @intFromEnum(self);
for (0..@bitSizeOf(Mask)) |i| {
const bit = @as(u5, @intCast(i));
Expand All @@ -108,6 +109,24 @@ pub const Mask = enum(u30) {
}
}

pub fn set_slew_rate(self: Mask, slew_rate: SlewRate) void {
const raw_mask = @intFromEnum(self);
for (0..@bitSizeOf(Mask)) |i| {
const bit = @as(u5, @intCast(i));
if (0 != raw_mask & (@as(u32, 1) << bit))
num(bit).set_slew_rate(slew_rate);
}
}

pub fn set_schmitt_trigger(self: Mask, enabled: Enabled) void {
const raw_mask = @intFromEnum(self);
for (0..@bitSizeOf(Mask)) |i| {
const bit = @as(u5, @intCast(i));
if (0 != raw_mask & (@as(u32, 1) << bit))
num(bit).set_schmitt_trigger(enabled);
}
}

pub fn put(self: Mask, value: u32) void {
SIO.GPIO_OUT_XOR.raw = (SIO.GPIO_OUT.raw ^ value) & @intFromEnum(self);
}
Expand Down Expand Up @@ -167,14 +186,12 @@ pub const Pin = enum(u5) {
return @as(u32, 1) << @intFromEnum(gpio);
}

pub inline fn set_pull(gpio: Pin, pull: ?Pull) void {
pub inline fn set_pull(gpio: Pin, pull: Pull) void {
const pads_reg = gpio.get_pads_reg();

if (pull == null) {
pads_reg.modify(.{ .PUE = 0, .PDE = 0 });
} else switch (pull.?) {
switch (pull) {
.up => pads_reg.modify(.{ .PUE = 1, .PDE = 0 }),
.down => pads_reg.modify(.{ .PUE = 0, .PDE = 1 }),
.disabled => pads_reg.modify(.{ .PUE = 0, .PDE = 0 }),
}
}

Expand Down Expand Up @@ -231,4 +248,24 @@ pub const Pin = enum(u5) {
.padding = 0,
});
}

pub fn set_slew_rate(gpio: Pin, slew_rate: SlewRate) void {
const pads_reg = gpio.get_pads_reg();
pads_reg.modify(.{
.SLEWFAST = switch (slew_rate) {
.slow => @as(u1, 0),
.fast => @as(u1, 1),
},
});
}

pub fn set_schmitt_trigger(gpio: Pin, enabled: Enabled) void {
const pads_reg = gpio.get_pads_reg();
pads_reg.modify(.{
.SCHMITT = switch (enabled) {
.enabled => @as(u1, 1),
.disabled => @as(u1, 0),
},
});
}
};
Loading

0 comments on commit f776b12

Please sign in to comment.