@@ -60,9 +60,11 @@ pub const ReceiveError = error{
60
60
BreakError ,
61
61
ParityError ,
62
62
FramingError ,
63
- Timeout ,
64
63
};
65
64
65
+ pub const ReceiveNonBlockingError = ReceiveError || error {WouldBlock };
66
+ pub const ReceiveBlockingError = ReceiveError || error {Timeout };
67
+
66
68
pub const ErrorStates = packed struct (u4 ) {
67
69
overrun_error : bool = false ,
68
70
break_error : bool = false ,
@@ -143,7 +145,7 @@ pub const UART = enum(u1) {
143
145
_ ,
144
146
145
147
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 );
147
149
148
150
pub fn writer (uart : UART ) Writer {
149
151
return .{ .context = uart };
@@ -241,6 +243,37 @@ pub const UART = enum(u1) {
241
243
};
242
244
}
243
245
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
+
244
277
/// Write bytes to uart TX line and block until transaction is complete.
245
278
///
246
279
/// Note that this does NOT disable reception while this is happening,
@@ -338,7 +371,7 @@ pub const UART = enum(u1) {
338
371
/// Returns a transaction error immediately if it occurs and doesn't
339
372
/// complete the transaction. Errors are preserved for further inspection,
340
373
/// 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 {
342
375
return uart .readv_blocking (&.{buffer }, timeout );
343
376
}
344
377
@@ -352,7 +385,7 @@ pub const UART = enum(u1) {
352
385
/// Returns a transaction error immediately if it occurs and doesn't
353
386
/// complete the transaction. Errors are preserved for further inspection,
354
387
/// 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 {
356
389
const deadline = mdf .time .Deadline .init_relative (time .get_time_since_boot (), timeout );
357
390
358
391
var iter = microzig .utilities .Slice_Vector ([]u8 ).init (buffers ).iterator ();
@@ -367,14 +400,21 @@ pub const UART = enum(u1) {
367
400
}
368
401
369
402
/// 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 {
371
404
var byte : [1 ]u8 = undefined ;
372
405
try uart .read_blocking (& byte , timeout );
373
406
return byte [0 ];
374
407
}
375
408
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
+
376
416
/// 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 {
378
418
try uart .read_blocking (buffer , null );
379
419
return buffer .len ;
380
420
}
0 commit comments