Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 34 additions & 11 deletions port/raspberrypi/rp2xxx/src/hal/uart.zig
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ pub const instance = struct {
}
};

pub const TimeFrontier = union(enum) { timeout_us: u64, deadline: mdf.time.Deadline };

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe format this on multiple lines?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add here a

pub const no_deadline: TimeFrontier = .{ .deadline = .no_deadline };

so you can do .no_deadline directly when you don't want any deadline.


/// An API for interacting with the RP2040's UART driver.
///
/// Note: Assumes proper GPIO configuration, does NOT configure GPIO pins.
Expand All @@ -148,20 +150,28 @@ pub const UART = enum(u1) {

pub const Writer = struct {
uart: UART,
deadline: mdf.time.Deadline,
timeFrontier: TimeFrontier,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: fields should be snake case

interface: std.Io.Writer,

pub fn set_deadline(self: *Writer, deadline: mdf.time.Deadline) void {
self.*.timeFrontier = TimeFrontier{.deadline = deadline};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing self.* here is not necessary. Field access dereferences the pointer automatically

}
};

pub const Reader = struct {
uart: UART,
deadline: mdf.time.Deadline,
timeFrontier: TimeFrontier,
interface: std.Io.Reader,

pub fn set_deadline(self: *Reader, deadline: mdf.time.Deadline) void {
self.*.timeFrontier = TimeFrontier{.deadline = deadline};
}
};

pub fn writer(uart: UART, deadline: mdf.time.Deadline, buffer: []u8) Writer {
pub fn writer(uart: UART, timeFrontier: TimeFrontier, buffer: []u8) Writer {
return .{
.uart = uart,
.deadline = deadline,
.timeFrontier = timeFrontier,
.interface = .{
.buffer = buffer,
.vtable = &.{
Expand All @@ -171,10 +181,10 @@ pub const UART = enum(u1) {
};
}

pub fn reader(uart: UART, deadline: mdf.time.Deadline, buffer: []u8) Reader {
pub fn reader(uart: UART, timeFrontier: TimeFrontier, buffer: []u8) Reader {
return .{
.uart = uart,
.deadline = deadline,
.timeFrontier = timeFrontier,
.interface = .{
.buffer = buffer,
.seek = 0,
Expand All @@ -190,18 +200,24 @@ pub const UART = enum(u1) {
const uart_writer: *Writer = @alignCast(@fieldParentPtr("interface", w));
const uart = uart_writer.uart;

var deadline: mdf.time.Deadline = undefined;
switch (uart_writer.timeFrontier) {
.deadline => |d| deadline = d,
.timeout_us => |t| deadline = time.deadline_in_us(t)
}
Comment on lines +203 to +207

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: switch can be used as an expression so you could do

const deadline: mdf.time.Deadline = switch (uart_writer.time_frontier) {
    .deadline => |d| d,
    .timeout_us => |t| time.deadline_in_us(t),
};


// bytes from buffer are not included in count.
w.end -= uart.write_blocking(w.buffer[0..w.end], uart_writer.deadline) catch |err| switch (err) {
w.end -= uart.write_blocking(w.buffer[0..w.end], deadline) catch |err| switch (err) {
error.Timeout => unreachable,
};
assert(w.end == 0);

var n: usize = 0;
n += uart.writev_blocking(data[0 .. data.len - 1], uart_writer.deadline) catch |err| switch (err) {
n += uart.writev_blocking(data[0 .. data.len - 1], deadline) catch |err| switch (err) {
error.Timeout => unreachable,
};
for (0..splat) |_|
n += uart.write_blocking(data[data.len - 1], uart_writer.deadline) catch |err| switch (err) {
n += uart.write_blocking(data[data.len - 1], deadline) catch |err| switch (err) {
error.Timeout => unreachable,
};

Expand All @@ -211,10 +227,17 @@ pub const UART = enum(u1) {
fn stream(r: *std.Io.Reader, w: *std.Io.Writer, limit: std.Io.Limit) std.Io.Reader.StreamError!usize {
const uart_reader: *Reader = @alignCast(@fieldParentPtr("interface", r));
const uart = uart_reader.uart;

var deadline: mdf.time.Deadline = undefined;
switch (uart_reader.timeFrontier) {
.deadline => |d| deadline = d,
.timeout_us => |t| deadline = time.deadline_in_us(t)
}

return switch (limit) {
.nothing => 0,
else => {
const b = uart.read_word_blocking(uart_reader.deadline) catch return error.ReadFailed;
const b = uart.read_word_blocking(deadline) catch return error.ReadFailed;
try w.writeByte(b);
return 1;
},
Expand Down Expand Up @@ -559,7 +582,7 @@ var uart_logger: ?UART.Writer = null;
/// .logFn = hal.uart.log,
/// };
pub fn init_logger(uart: UART) void {
uart_logger = uart.writer(.no_deadline, &.{});
uart_logger = uart.writer(.{.deadline = .no_deadline}, &.{});

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can become uart.writer(.no_deadline). See the suggestion above

uart_logger.?.interface.writeAll("\r\n================ STARTING NEW LOGGER ================\r\n") catch {};
}

Expand Down
Loading