@@ -54,13 +54,7 @@ pub const Config = struct {
5454pub const StopBits = STOP ;
5555pub const DataBits = WordBits ;
5656
57- pub const Pins = struct {
58- tx : ? type = null ,
59- rx : ? type = null ,
60- };
61-
62- pub fn Uart (comptime index : UartNum , comptime uart_pins : Pins ) type {
63- _ = uart_pins ;
57+ pub fn Uart (comptime index : UartNum ) type {
6458 const regs = switch (index ) {
6559 .UART1 = > USART1 ,
6660 .UART2 = > USART2 ,
@@ -163,5 +157,81 @@ pub fn Uart(comptime index: UartNum, comptime uart_pins: Pins) type {
163157 const data_with_parity_bit : u9 = regs .RDR .read ().RDR ;
164158 return @as (u8 , @intCast (data_with_parity_bit & self .read_mask ()));
165159 }
160+
161+ fn writer_fn (self : * Self , buffer : []const u8 ) error {}! usize {
162+ for (buffer ) | byte | {
163+ self .tx (byte );
164+ }
165+ return buffer .len ;
166+ }
167+ };
168+ }
169+
170+ pub fn UartWriter (comptime index : UartNum ) type {
171+ return struct {
172+ uart : * Uart (index ),
173+ interface : std.Io.Writer ,
174+
175+ pub fn init (uart : * Uart (index ), buffer : []u8 ) UartWriter (index ) {
176+ return .{
177+ .uart = uart ,
178+ .interface = .{
179+ .vtable = &.{
180+ .drain = drain ,
181+ },
182+ .buffer = buffer ,
183+ },
184+ };
185+ }
186+
187+ pub fn drain (io_w : * std.Io.Writer , data : []const []const u8 , splat : usize ) std.Io.Writer.Error ! usize {
188+ const w : * UartWriter (index ) = @alignCast (@fieldParentPtr ("interface" , io_w ));
189+ var n : u32 = 0 ;
190+ if (io_w .buffer .len > 0 ) {
191+ _ = try w .uart .writer_fn (io_w .buffered ());
192+ n += io_w .consumeAll ();
193+ }
194+ for (data [0 .. data .len - 1 ]) | buf | {
195+ n += try w .uart .writer_fn (buf );
196+ }
197+ const pattern = data [data .len - 1 ];
198+ for (0.. splat ) | _ | {
199+ n += try w .uart .writer_fn (pattern );
200+ }
201+ return n ;
202+ }
203+ };
204+ }
205+
206+ var uart_logger : ? UartWriter (.UART1 ) = null ;
207+
208+ ///Set a specific uart instance to be used for logging.
209+ ///
210+ ///Allows system logging over uart via:
211+ ///pub const microzig_options = .{
212+ /// .logFn = hal.uart.log,
213+ ///};
214+ pub fn init_logger (uart : * Uart (.UART1 )) void {
215+ uart_logger = .init (uart , &.{});
216+ if (uart_logger ) | * logger | {
217+ var w = & logger .interface ;
218+ w .writeAll ("\r \n ================ STARTING NEW LOGGER ================\r \n " ) catch {};
219+ }
220+ }
221+
222+ ///Disables logging via the uart instance.
223+ pub fn deinit_logger () void {
224+ uart_logger = null ;
225+ }
226+
227+ pub fn log (comptime level : std.log.Level , comptime scope : @TypeOf (.EnumLiteral ), comptime format : []const u8 , args : anytype ) void {
228+ const prefix = comptime level .asText () ++ switch (scope ) {
229+ .default = > ": " ,
230+ else = > " (" ++ @tagName (scope ) ++ "): " ,
166231 };
232+
233+ if (uart_logger ) | * logger | {
234+ var w = & logger .interface ;
235+ w .print (prefix ++ format ++ "\r \n " , args ) catch {};
236+ }
167237}
0 commit comments