commit 7da8e0126f36fa58ce158549609bac9061c68aea
parent bdaf157b915565ce2802382e16bf2dfdfcfbcdf4
Author: Sylvia Ivory <git@sivory.net>
Date: Sat, 31 Jan 2026 01:38:18 -0800
Directly write to Io.Writer for large buffers
Diffstat:
1 file changed, 45 insertions(+), 3 deletions(-)
diff --git a/pi/devices/mini-uart.zig b/pi/devices/mini-uart.zig
@@ -139,6 +139,32 @@ pub fn enable_interrupts() Error!void {
// var tx_list: std.ArrayList(u8) = .initBuffer(&tx_buffer);
var rx_list: StackRingBuffer(u8, 4096) = .init();
+var rx_writer: ?*std.Io.Writer = null;
+var rx_writer_written: usize = 0;
+
+pub fn switch_rx_writer(rx_w: ?*std.Io.Writer) !void {
+ const cs = mem.enter_critical_section();
+ defer cs.exit();
+
+ rx_writer_written = 0;
+
+ if (rx_w) |w| {
+ // Copy buffer into new writer
+ while (rx_list.pop()) |b| {
+ try w.writeByte(b);
+ rx_writer_written += 1;
+ }
+ }
+
+ rx_writer = rx_w;
+}
+
+pub fn get_rx_written() usize {
+ const cs = mem.enter_critical_section();
+ defer cs.exit();
+
+ return rx_writer_written;
+}
noinline fn uart_handler(pc: usize) void {
_ = pc;
@@ -156,7 +182,13 @@ noinline fn uart_handler(pc: usize) void {
if ((IIR & 0b100) != 0) {
// can't do anything with error
- rx_list.push(read_byte_raw()) catch {};
+ const b = read_byte_raw();
+ if (rx_writer) |w| {
+ rx_writer_written += 1;
+ w.writeByte(b) catch {};
+ } else {
+ rx_list.push(b) catch {};
+ }
}
// TODO; figure out why TX interrupts aren't working
@@ -310,8 +342,18 @@ fn stream(io_r: *std.Io.Reader, io_w: *std.Io.Writer, limit: std.Io.Limit) !usiz
_ = io_r;
if (limit.toInt()) |max| {
- for (0..max) |_| {
- try io_w.writeByte(read_byte_blocking(null).?);
+ if (max > 128) {
+ // Use direct writes when there's a large buffer
+ try switch_rx_writer(io_w);
+
+ while (get_rx_written() < max) {}
+
+ try switch_rx_writer(null);
+ } else {
+ // Small buffers should just read blocking
+ for (0..max) |_| {
+ try io_w.writeByte(read_byte_blocking(null).?);
+ }
}
return max;