Skip to content

Commit dd14eb6

Browse files
committed
add set_interrupts_enabled and non blocking read
1 parent 8241eb2 commit dd14eb6

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

port/raspberrypi/rp2xxx/src/hal/uart.zig

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,11 @@ pub const ReceiveError = error{
6060
BreakError,
6161
ParityError,
6262
FramingError,
63-
Timeout,
6463
};
6564

65+
pub const ReceiveNonBlockingError = ReceiveError || error{WouldBlock};
66+
pub const ReceiveBlockingError = ReceiveError || error{Timeout};
67+
6668
pub const ErrorStates = packed struct(u4) {
6769
overrun_error: bool = false,
6870
break_error: bool = false,
@@ -143,7 +145,7 @@ pub const UART = enum(u1) {
143145
_,
144146

145147
pub const Writer = std.io.GenericWriter(UART, TransmitError, generic_writer_fn);
146-
pub const Reader = std.io.GenericReader(UART, ReceiveError, generic_reader_fn);
148+
pub const Reader = std.io.GenericReader(UART, ReceiveBlockingError, generic_reader_fn);
147149

148150
pub fn writer(uart: UART) Writer {
149151
return .{ .context = uart };
@@ -241,6 +243,37 @@ pub const UART = enum(u1) {
241243
};
242244
}
243245

246+
/// Enables/disables interrupts for a given UART.
247+
pub inline fn set_interrupts_enabled(uart: UART, enable: struct {
248+
rim: ?bool = null,
249+
ctsm: ?bool = null,
250+
dcdm: ?bool = null,
251+
dsrm: ?bool = null,
252+
rx: ?bool = null,
253+
tx: ?bool = null,
254+
rt: ?bool = null,
255+
fe: ?bool = null,
256+
pe: ?bool = null,
257+
be: ?bool = null,
258+
oe: ?bool = null,
259+
}) void {
260+
const uart_regs = uart.get_regs();
261+
const reg = uart_regs.UARTIMSC.read();
262+
uart_regs.UARTIMSC.write(.{
263+
.RIMIM = if (enable.rim) |e| @intFromBool(e) else reg.RIMIM,
264+
.CTSMIM = if (enable.ctsm) |e| @intFromBool(e) else reg.CTSMIM,
265+
.DCDMIM = if (enable.dcdm) |e| @intFromBool(e) else reg.DCDMIM,
266+
.DSRMIM = if (enable.dsrm) |e| @intFromBool(e) else reg.DSRMIM,
267+
.TXIM = if (enable.tx) |e| @intFromBool(e) else reg.TXIM,
268+
.RXIM = if (enable.rx) |e| @intFromBool(e) else reg.RXIM,
269+
.RTIM = if (enable.rt) |e| @intFromBool(e) else reg.RTIM,
270+
.FEIM = if (enable.fe) |e| @intFromBool(e) else reg.FEIM,
271+
.PEIM = if (enable.pe) |e| @intFromBool(e) else reg.PEIM,
272+
.BEIM = if (enable.be) |e| @intFromBool(e) else reg.BEIM,
273+
.OEIM = if (enable.oe) |e| @intFromBool(e) else reg.OEIM,
274+
});
275+
}
276+
244277
/// Write bytes to uart TX line and block until transaction is complete.
245278
///
246279
/// Note that this does NOT disable reception while this is happening,
@@ -338,7 +371,7 @@ pub const UART = enum(u1) {
338371
/// Returns a transaction error immediately if it occurs and doesn't
339372
/// complete the transaction. Errors are preserved for further inspection,
340373
/// so must be cleared with clear_errors() before another transaction is attempted.
341-
pub fn read_blocking(uart: UART, buffer: []u8, timeout: ?mdf.time.Duration) ReceiveError!void {
374+
pub fn read_blocking(uart: UART, buffer: []u8, timeout: ?mdf.time.Duration) ReceiveBlockingError!void {
342375
return uart.readv_blocking(&.{buffer}, timeout);
343376
}
344377

@@ -352,7 +385,7 @@ pub const UART = enum(u1) {
352385
/// Returns a transaction error immediately if it occurs and doesn't
353386
/// complete the transaction. Errors are preserved for further inspection,
354387
/// so must be cleared with clear_errors() before another transaction is attempted.
355-
pub fn readv_blocking(uart: UART, buffers: []const []u8, timeout: ?mdf.time.Duration) ReceiveError!void {
388+
pub fn readv_blocking(uart: UART, buffers: []const []u8, timeout: ?mdf.time.Duration) ReceiveBlockingError!void {
356389
const deadline = mdf.time.Deadline.init_relative(time.get_time_since_boot(), timeout);
357390

358391
var iter = microzig.utilities.Slice_Vector([]u8).init(buffers).iterator();
@@ -367,14 +400,21 @@ pub const UART = enum(u1) {
367400
}
368401

369402
/// Convenience function for waiting for a single byte to come across the RX line.
370-
pub fn read_word(uart: UART, timeout: ?mdf.time.Duration) ReceiveError!u8 {
403+
pub fn read_word_blocking(uart: UART, timeout: ?mdf.time.Duration) ReceiveBlockingError!u8 {
371404
var byte: [1]u8 = undefined;
372405
try uart.read_blocking(&byte, timeout);
373406
return byte[0];
374407
}
375408

409+
/// Read a single byte from the RX line if available otherwise returns
410+
/// `error.WouldBlock`.
411+
pub fn read_word(uart: UART) ReceiveNonBlockingError!u8 {
412+
if (!uart.is_readable()) return ReceiveNonBlockingError.WouldBlock;
413+
return try uart.read_rx_fifo_with_error_check();
414+
}
415+
376416
/// Wraps read_blocking() for use as a GenericReader
377-
fn generic_reader_fn(uart: UART, buffer: []u8) ReceiveError!usize {
417+
fn generic_reader_fn(uart: UART, buffer: []u8) ReceiveBlockingError!usize {
378418
try uart.read_blocking(buffer, null);
379419
return buffer.len;
380420
}

0 commit comments

Comments
 (0)