From 19975bb80e0a062dc08ef5c95a545d2c6236e12e Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Sat, 31 Jan 2026 23:57:56 +0100 Subject: [PATCH 01/13] speed up cache regen by not compiling sqlite twice --- tools/regz/build.zig | 7 ------- tools/regz/build.zig.zon | 4 ---- 2 files changed, 11 deletions(-) diff --git a/tools/regz/build.zig b/tools/regz/build.zig index 1570f018b..7d2ef742c 100644 --- a/tools/regz/build.zig +++ b/tools/regz/build.zig @@ -16,19 +16,12 @@ pub fn build(b: *Build) !void { .iconv = false, }); - const sqlite3_dep = b.dependency("sqlite3", .{ - .target = target, - .optimize = .ReleaseSafe, - }); - const sqlite3_lib = sqlite3_dep.artifact("sqlite3"); - const zqlite_dep = b.dependency("zqlite", .{ .target = target, .optimize = optimize, }); const zqlite = zqlite_dep.module("zqlite"); - zqlite.linkLibrary(sqlite3_lib); const regz = b.addExecutable(.{ .name = "regz", diff --git a/tools/regz/build.zig.zon b/tools/regz/build.zig.zon index 154dc6eaa..bdb2a6424 100644 --- a/tools/regz/build.zig.zon +++ b/tools/regz/build.zig.zon @@ -13,10 +13,6 @@ .url = "git+https://github.com/mattnite/zig-build-libxml2.git#5474281ad4d173ed298ee789c7dce4f5edb78e10", .hash = "libxml2-0.0.0-Kr0Y1Ac4ngAiRuFTS2qMO9j-KZsD0PKFKKXoZjynTHLq", }, - .sqlite3 = .{ - .url = "git+https://github.com/allyourcodebase/sqlite3#8f840560eae88ab66668c6827c64ffbd0d74ef37", - .hash = "sqlite3-3.51.0-DMxLWssOAABZ8cAvU_LfBIbp0kZjm824PU8sSLXpEDdr", - }, .zqlite = .{ .url = "git+https://github.com/karlseguin/zqlite.zig#b44ed5cdc64859b08446c246f307e65ebe2b2d9c", .hash = "zqlite-0.0.0-RWLaY_y_mADh2LdbDrG_2HT2dBAcsAR8Jig_7-dOJd0B", From 0d097f11ae4bbd1d801f1e32890d76df89eb7374 Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Sun, 1 Feb 2026 04:14:53 +0100 Subject: [PATCH 02/13] reduce use of Mmio --- port/raspberrypi/rp2xxx/patches/rp2040.zon | 187 +++++++++++++ port/raspberrypi/rp2xxx/patches/rp2350.zon | 305 ++++++++++++++++++++- port/raspberrypi/rp2xxx/src/hal/gpio.zig | 75 +---- port/raspberrypi/rp2xxx/src/hal/usb.zig | 8 +- 4 files changed, 488 insertions(+), 87 deletions(-) diff --git a/port/raspberrypi/rp2xxx/patches/rp2040.zon b/port/raspberrypi/rp2xxx/patches/rp2040.zon index 75af11c9e..bb46f181c 100644 --- a/port/raspberrypi/rp2xxx/patches/rp2040.zon +++ b/port/raspberrypi/rp2xxx/patches/rp2040.zon @@ -1,4 +1,191 @@ .{ + .{ .add_enum_and_apply = .{ + .parent = "types.peripherals.IO_BANK0", + .@"enum" = .{ + .name = "Override", + .bitsize = 2, + .fields = .{ + .{ .value = 0, .name = "normal" }, + .{ .value = 1, .name = "invert" }, + .{ .value = 2, .name = "low" }, + .{ .value = 3, .name = "high" }, + }, + }, + .apply_to = .{ + "types.peripherals.IO_BANK0.GPIO0_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO0_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO0_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO0_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO1_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO1_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO1_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO1_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO2_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO2_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO2_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO2_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO3_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO3_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO3_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO3_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO4_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO4_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO4_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO4_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO5_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO5_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO5_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO5_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO6_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO6_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO6_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO6_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO7_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO7_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO7_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO7_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO8_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO8_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO8_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO8_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO9_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO9_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO9_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO9_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO10_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO10_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO10_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO10_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO11_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO11_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO11_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO11_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO12_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO12_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO12_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO12_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO13_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO13_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO13_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO13_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO14_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO14_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO14_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO14_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO15_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO15_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO15_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO15_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO16_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO16_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO16_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO16_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO17_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO17_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO17_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO17_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO18_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO18_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO18_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO18_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO19_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO19_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO19_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO19_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO20_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO20_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO20_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO20_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO21_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO21_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO21_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO21_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO22_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO22_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO22_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO22_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO23_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO23_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO23_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO23_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO24_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO24_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO24_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO24_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO25_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO25_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO25_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO25_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO26_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO26_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO26_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO26_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO27_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO27_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO27_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO27_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO28_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO28_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO28_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO28_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO29_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO29_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO29_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO29_CTRL.OUTOVER", + }, + } }, + .{ .add_enum_and_apply = .{ + .parent = "types.peripherals.IO_BANK0", + .@"enum" = .{ + .name = "Function", + .bitsize = 5, + .fields = .{ + .{ .value = 0, .name = "xip" }, + .{ .value = 1, .name = "spi" }, + .{ .value = 2, .name = "uart" }, + .{ .value = 3, .name = "i2c" }, + .{ .value = 4, .name = "pwm" }, + .{ .value = 5, .name = "sio" }, + .{ .value = 6, .name = "pio0" }, + .{ .value = 7, .name = "pio1" }, + .{ .value = 8, .name = "gpck" }, + .{ .value = 9, .name = "usb" }, + .{ .value = 0x1f, .name = "disabled" }, + }, + }, + .apply_to = .{ + "types.peripherals.IO_BANK0.GPIO0_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO1_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO2_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO3_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO4_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO5_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO6_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO7_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO8_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO9_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO10_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO11_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO12_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO13_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO14_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO15_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO16_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO17_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO18_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO19_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO20_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO21_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO22_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO23_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO24_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO25_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO26_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO27_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO28_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO29_CTRL.FUNCSEL", + }, + } }, .{ .add_enum_and_apply = .{ .parent = "types.peripherals.USB_DPRAM", .@"enum" = .{ diff --git a/port/raspberrypi/rp2xxx/patches/rp2350.zon b/port/raspberrypi/rp2xxx/patches/rp2350.zon index 2f28af5b9..093aa5c9a 100644 --- a/port/raspberrypi/rp2xxx/patches/rp2350.zon +++ b/port/raspberrypi/rp2xxx/patches/rp2350.zon @@ -1,19 +1,300 @@ .{ - .{ - .add_enum = .{ - .parent = "types.peripherals.PADS_BANK0", - .@"enum" = .{ - .name = "DriveStrength", - .bitsize = 2, - .fields = .{ - .{ .value = 0x0, .name = "2mA" }, - .{ .value = 0x1, .name = "4mA" }, - .{ .value = 0x2, .name = "8mA" }, - .{ .value = 0x3, .name = "12mA" }, + .{ .add_enum_and_apply = .{ + .parent = "types.peripherals.IO_BANK0", + .@"enum" = .{ + .name = "Override", + .bitsize = 2, + .fields = .{ + .{ .value = 0, .name = "normal" }, + .{ .value = 1, .name = "invert" }, + .{ .value = 2, .name = "low" }, + .{ .value = 3, .name = "high" }, + }, + }, + .apply_to = .{ + "types.peripherals.IO_BANK0.GPIO0_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO0_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO0_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO0_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO1_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO1_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO1_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO1_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO2_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO2_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO2_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO2_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO3_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO3_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO3_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO3_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO4_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO4_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO4_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO4_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO5_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO5_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO5_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO5_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO6_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO6_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO6_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO6_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO7_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO7_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO7_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO7_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO8_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO8_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO8_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO8_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO9_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO9_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO9_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO9_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO10_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO10_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO10_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO10_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO11_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO11_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO11_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO11_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO12_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO12_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO12_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO12_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO13_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO13_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO13_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO13_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO14_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO14_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO14_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO14_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO15_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO15_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO15_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO15_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO16_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO16_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO16_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO16_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO17_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO17_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO17_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO17_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO18_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO18_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO18_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO18_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO19_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO19_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO19_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO19_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO20_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO20_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO20_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO20_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO21_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO21_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO21_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO21_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO22_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO22_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO22_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO22_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO23_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO23_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO23_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO23_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO24_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO24_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO24_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO24_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO25_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO25_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO25_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO25_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO26_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO26_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO26_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO26_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO27_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO27_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO27_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO27_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO28_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO28_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO28_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO28_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO29_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO29_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO29_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO29_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO30_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO30_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO30_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO30_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO31_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO31_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO31_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO31_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO32_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO32_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO32_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO32_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO33_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO33_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO33_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO33_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO34_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO34_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO34_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO34_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO35_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO35_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO35_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO35_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO36_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO36_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO36_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO36_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO37_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO37_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO37_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO37_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO38_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO38_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO38_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO38_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO39_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO39_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO39_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO39_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO40_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO40_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO40_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO40_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO41_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO41_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO41_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO41_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO42_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO42_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO42_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO42_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO43_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO43_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO43_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO43_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO44_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO44_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO44_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO44_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO45_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO45_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO45_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO45_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO46_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO46_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO46_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO46_CTRL.OUTOVER", + "types.peripherals.IO_BANK0.GPIO47_CTRL.INOVER", + "types.peripherals.IO_BANK0.GPIO47_CTRL.IRQOVER", + "types.peripherals.IO_BANK0.GPIO47_CTRL.OEOVER", + "types.peripherals.IO_BANK0.GPIO47_CTRL.OUTOVER", + }, + } }, + .{ .add_enum_and_apply = .{ + .parent = "types.peripherals.IO_BANK0", + .@"enum" = .{ + .name = "Function", + .bitsize = 5, + .fields = .{ + .{ .value = 0, .name = "hstx" }, + .{ .value = 1, .name = "spi" }, + .{ .value = 2, .name = "uart" }, + .{ .value = 3, .name = "i2c" }, + .{ .value = 4, .name = "pwm" }, + .{ .value = 5, .name = "sio" }, + .{ .value = 6, .name = "pio0" }, + .{ .value = 7, .name = "pio1" }, + .{ .value = 8, .name = "pio2" }, + .{ + .value = 9, + .name = "gpck", + .description = "Also QMI_CS1 and Trace", }, + .{ .value = 10, .name = "usb" }, + .{ .value = 11, .name = "uart_alt" }, + .{ .value = 0x1f, .name = "disabled" }, }, }, - }, + .apply_to = .{ + "types.peripherals.IO_BANK0.GPIO0_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO1_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO2_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO3_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO4_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO5_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO6_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO7_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO8_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO9_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO10_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO11_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO12_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO13_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO14_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO15_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO16_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO17_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO18_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO19_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO20_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO21_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO22_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO23_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO24_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO25_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO26_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO27_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO28_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO29_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO30_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO31_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO32_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO33_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO34_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO35_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO36_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO37_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO38_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO39_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO40_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO41_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO42_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO43_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO44_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO45_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO46_CTRL.FUNCSEL", + "types.peripherals.IO_BANK0.GPIO47_CTRL.FUNCSEL", + }, + } }, + .{ .add_enum = .{ + .parent = "types.peripherals.PADS_BANK0", + .@"enum" = .{ + .name = "DriveStrength", + .bitsize = 2, + .fields = .{ + .{ .value = 0x0, .name = "2mA" }, + .{ .value = 0x1, .name = "4mA" }, + .{ .value = 0x2, .name = "8mA" }, + .{ .value = 0x3, .name = "12mA" }, + }, + }, + } }, .{ .set_enum_type = .{ .of = "types.peripherals.PADS_BANK0.GPIO0.DRIVE", .to = "types.peripherals.PADS_BANK0.DriveStrength" } }, .{ .set_enum_type = .{ .of = "types.peripherals.PADS_BANK0.GPIO1.DRIVE", .to = "types.peripherals.PADS_BANK0.DriveStrength" } }, .{ .set_enum_type = .{ .of = "types.peripherals.PADS_BANK0.GPIO2.DRIVE", .to = "types.peripherals.PADS_BANK0.DriveStrength" } }, diff --git a/port/raspberrypi/rp2xxx/src/hal/gpio.zig b/port/raspberrypi/rp2xxx/src/hal/gpio.zig index 4cb8a9102..7126bf601 100644 --- a/port/raspberrypi/rp2xxx/src/hal/gpio.zig +++ b/port/raspberrypi/rp2xxx/src/hal/gpio.zig @@ -15,55 +15,19 @@ const NUM_BANK0_GPIOS = switch (chip) { .RP2350 => 48, }; -pub const Function = - switch (chip) { - .RP2040 => enum(u5) { - xip = 0, - spi, - uart, - i2c, - pwm, - sio, - pio0, - pio1, - gpck, - usb, - disabled = 0x1f, - }, - .RP2350 => enum(u5) { - hstx = 0, - spi, - uart, - i2c, - pwm, - sio, - pio0, - pio1, - pio2, - gpck, // Also QMI_CS1 and Trace - usb, - uart_alt, - disabled = 0x1f, - }, - }; pub const Direction = enum(u1) { in, out, }; -pub const Override = enum(u2) { - normal, - invert, - low, - high, -}; - pub const SlewRate = enum(u1) { slow, fast, }; +pub const Function = microzig.chip.types.peripherals.IO_BANK0.Function; +pub const Override = microzig.chip.types.peripherals.IO_BANK0.Override; pub const DriveStrength = microzig.chip.types.peripherals.PADS_BANK0.DriveStrength; pub const Pull = enum { @@ -259,37 +223,10 @@ pub const Mask = pub const Pin = enum(u6) { _, - pub const Regs = - switch (chip) { - .RP2040 => extern struct { - status: @TypeOf(IO_BANK0.GPIO0_STATUS), - ctrl: microzig.mmio.Mmio(packed struct(u32) { - FUNCSEL: Function, - reserved8: u3 = 0, - OUTOVER: Override, - reserved12: u2 = 0, - OEOVER: Override, - reserved16: u2 = 0, - INOVER: Override, - reserved28: u10 = 0, - IRQOVER: Override, - padding: u2 = 0, - }), - }, - .RP2350 => extern struct { - status: @TypeOf(IO_BANK0.GPIO0_STATUS), - ctrl: microzig.mmio.Mmio(packed struct(u32) { - FUNCSEL: Function, - reserved12: u7 = 0, - OUTOVER: Override, - OEOVER: Override, - INOVER: Override, - reserved28: u10 = 0, - IRQOVER: Override, - padding: u2 = 0, - }), - }, - }; + pub const Regs = struct { + status: @TypeOf(IO_BANK0.GPIO0_STATUS), + ctrl: @TypeOf(IO_BANK0.GPIO0_CTRL), + }; pub const RegsArray = switch (chip) { .RP2040 => *volatile [30]Regs, diff --git a/port/raspberrypi/rp2xxx/src/hal/usb.zig b/port/raspberrypi/rp2xxx/src/hal/usb.zig index 24c7afc2c..a8fc03c61 100644 --- a/port/raspberrypi/rp2xxx/src/hal/usb.zig +++ b/port/raspberrypi/rp2xxx/src/hal/usb.zig @@ -62,12 +62,8 @@ fn PerEndpoint(T: type) type { }; } -// It would be nice to instead generate those arrays automatically with a regz patch. -const BufferControlMmio = microzig.mmio.Mmio(@TypeOf(peripherals.USB_DPRAM.EP0_IN_BUFFER_CONTROL).underlying_type); -const buffer_control: *volatile [16]PerEndpoint(BufferControlMmio) = @ptrCast(&peripherals.USB_DPRAM.EP0_IN_BUFFER_CONTROL); - -const EndpointControlMimo = microzig.mmio.Mmio(@TypeOf(peripherals.USB_DPRAM.EP1_IN_CONTROL).underlying_type); -const endpoint_control: *volatile [15]PerEndpoint(EndpointControlMimo) = @ptrCast(&peripherals.USB_DPRAM.EP1_IN_CONTROL); +const buffer_control: *volatile [16]PerEndpoint(@TypeOf(peripherals.USB_DPRAM.EP0_IN_BUFFER_CONTROL)) = @ptrCast(&peripherals.USB_DPRAM.EP0_IN_BUFFER_CONTROL); +const endpoint_control: *volatile [15]PerEndpoint(@TypeOf(peripherals.USB_DPRAM.EP1_IN_CONTROL)) = @ptrCast(&peripherals.USB_DPRAM.EP1_IN_CONTROL); // +++++++++++++++++++++++++++++++++++++++++++++++++ // Code From 205861476fb7f95e1f05035e593a5dcac3b0ba0e Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Sun, 1 Feb 2026 04:21:27 +0100 Subject: [PATCH 03/13] Mmio -> OldMmio in non-generated code --- core/src/cpus/cortex_m.zig | 8 +-- core/src/cpus/cortex_m/m0.zig | 8 +-- core/src/cpus/cortex_m/m0plus.zig | 18 +++--- core/src/cpus/cortex_m/m3.zig | 24 ++++---- core/src/cpus/cortex_m/m33.zig | 28 +++++----- core/src/cpus/cortex_m/m4.zig | 28 +++++----- core/src/cpus/cortex_m/m55.zig | 22 ++++---- core/src/cpus/cortex_m/m7.zig | 56 +++++++++---------- core/src/mmio.zig | 2 + .../espressif/esp/src/hal/clocks/esp32_c3.zig | 2 +- port/raspberrypi/rp2xxx/src/hal/gpio.zig | 1 - port/stmicro/stm32/src/hals/STM32L47X/lcd.zig | 4 +- 12 files changed, 101 insertions(+), 100 deletions(-) diff --git a/core/src/cpus/cortex_m.zig b/core/src/cpus/cortex_m.zig index 2a8e2e425..7221ebf8e 100644 --- a/core/src/cpus/cortex_m.zig +++ b/core/src/cpus/cortex_m.zig @@ -1155,7 +1155,7 @@ pub const types = struct { /// System Timer (SysTick). pub const SysTick = extern struct { /// Control and Status Register. - CTRL: mmio.Mmio(packed struct(u32) { + CTRL: mmio.OldMmio(packed struct(u32) { /// Enables the counter: /// 0 = counter disabled. /// 1 = counter enabled. @@ -1176,20 +1176,20 @@ pub const types = struct { reserved1: u15 = 0, }), /// Reload Value Register. - LOAD: mmio.Mmio(packed struct(u32) { + LOAD: mmio.OldMmio(packed struct(u32) { /// Value to load into the VAL register when the counter is enabled and when it reaches 0. RELOAD: u24, reserved0: u8 = 0, }), /// Current Value Register. - VAL: mmio.Mmio(packed struct(u32) { + VAL: mmio.OldMmio(packed struct(u32) { /// Reads return the current value of the SysTick counter. /// A write of any value clears the field to 0, and also clears the CTRL.COUNTFLAG bit to 0. CURRENT: u24, reserved0: u8 = 0, }), /// Calibration Register. - CALIB: mmio.Mmio(packed struct(u32) { + CALIB: mmio.OldMmio(packed struct(u32) { /// Reload value for 10ms (100Hz) timing, subject to system clock skew errors. If the value /// reads as zero, the calibration value is not known. TENMS: u24, diff --git a/core/src/cpus/cortex_m/m0.zig b/core/src/cpus/cortex_m/m0.zig index 1e5d8927c..c9a7c7b42 100644 --- a/core/src/cpus/cortex_m/m0.zig +++ b/core/src/cpus/cortex_m/m0.zig @@ -9,7 +9,7 @@ pub const SystemControlBlock = extern struct { /// CPUID Base Register. CPUID: u32, /// Interrupt Control and State Register. - ICSR: mmio.Mmio(packed struct(u32) { + ICSR: mmio.OldMmio(packed struct(u32) { /// Contains the active exception number: /// 0 = Thread mode /// Nonzero = The exception number[a] of the currently active exception. @@ -79,7 +79,7 @@ pub const SystemControlBlock = extern struct { }), reserved0: u32 = 0, /// Application Interrupt and Reset Control Register. - AIRCR: mmio.Mmio(packed struct { + AIRCR: mmio.OldMmio(packed struct { reserved0: u1 = 0, /// Reserved for debug use. This bit reads as 0. When writing to the register you must /// write 0 to this bit, otherwise behavior is Unpredictable. @@ -101,7 +101,7 @@ pub const SystemControlBlock = extern struct { VECTKEY: u16, }), /// System Control Register. - SCR: mmio.Mmio(packed struct(u32) { + SCR: mmio.OldMmio(packed struct(u32) { reserved0: u1 = 0, /// Indicates sleep-on-exit when returning from Handler mode to Thread mode: /// 0 = do not sleep when returning to Thread mode. @@ -130,7 +130,7 @@ pub const SystemControlBlock = extern struct { reserved2: u27 = 0, }), /// Configuration Control Register. - CCR: mmio.Mmio(packed struct(u32) { + CCR: mmio.OldMmio(packed struct(u32) { reserved0: u3 = 0, /// Always reads as one, indicates that all unaligned accesses generate a HardFault. UNALIGN_TRP: u1, diff --git a/core/src/cpus/cortex_m/m0plus.zig b/core/src/cpus/cortex_m/m0plus.zig index 7aedb4113..b28c9f475 100644 --- a/core/src/cpus/cortex_m/m0plus.zig +++ b/core/src/cpus/cortex_m/m0plus.zig @@ -9,7 +9,7 @@ pub const SystemControlBlock = extern struct { /// CPUID Base Register. CPUID: u32, /// Interrupt Control and State Register. - ICSR: mmio.Mmio(packed struct(u32) { + ICSR: mmio.OldMmio(packed struct(u32) { /// Contains the active exception number: /// 0 = Thread mode /// Nonzero = The exception number[a] of the currently active exception. @@ -80,7 +80,7 @@ pub const SystemControlBlock = extern struct { /// Vector Table Offset Register. VTOR: u32, /// Application Interrupt and Reset Control Register. - AIRCR: mmio.Mmio(packed struct { + AIRCR: mmio.OldMmio(packed struct { reserved0: u1 = 0, /// Reserved for debug use. This bit reads as 0. When writing to the register you must /// write 0 to this bit, otherwise behavior is Unpredictable. @@ -102,7 +102,7 @@ pub const SystemControlBlock = extern struct { VECTKEY: u16, }), /// System Control Register. - SCR: mmio.Mmio(packed struct(u32) { + SCR: mmio.OldMmio(packed struct(u32) { reserved0: u1 = 0, /// Indicates sleep-on-exit when returning from Handler mode to Thread mode: /// 0 = do not sleep when returning to Thread mode. @@ -131,7 +131,7 @@ pub const SystemControlBlock = extern struct { reserved2: u27 = 0, }), /// Configuration Control Register. - CCR: mmio.Mmio(packed struct(u32) { + CCR: mmio.OldMmio(packed struct(u32) { reserved0: u3 = 0, /// Always reads as one, indicates that all unaligned accesses generate a HardFault. UNALIGN_TRP: u1, @@ -196,7 +196,7 @@ pub const NestedVectorInterruptController = extern struct { pub const MemoryProtectionUnit = extern struct { /// MPU Type Register - TYPE: mmio.Mmio(packed struct(u32) { + TYPE: mmio.OldMmio(packed struct(u32) { /// Indicates support for unified or separate instructions and data address regions. SEPARATE: u1, reserved0: u7 = 0, @@ -207,7 +207,7 @@ pub const MemoryProtectionUnit = extern struct { reserved1: u8 = 0, }), /// MPU Control Register - CTRL: mmio.Mmio(packed struct(u32) { + CTRL: mmio.OldMmio(packed struct(u32) { /// Enables the MPU ENABLE: u1, /// Enables of operation of MPU during HardFault and MNIHandlers. @@ -217,13 +217,13 @@ pub const MemoryProtectionUnit = extern struct { reserved0: u29 = 0, }), /// MPU Region Number Register - RNR: mmio.Mmio(packed struct(u32) { + RNR: mmio.OldMmio(packed struct(u32) { /// Indicates the memory region accessed by MPU RBAR and PMU RLAR. REGION: u8, reserved0: u24 = 0, }), /// MPU Region Base Address Register - RBAR: mmio.Mmio(packed struct(u32) { + RBAR: mmio.OldMmio(packed struct(u32) { /// MPU region field. REGION: u4, /// MPU region number valid bit. @@ -232,7 +232,7 @@ pub const MemoryProtectionUnit = extern struct { ADDR: u27, }), /// MPU Attribute and Size Register - RASR: mmio.Mmio(packed struct(u32) { + RASR: mmio.OldMmio(packed struct(u32) { /// Region enable bit. ENABLE: u1, /// Specifies the size of the MPU region. The minimum permitted value is 7 (b00111). diff --git a/core/src/cpus/cortex_m/m3.zig b/core/src/cpus/cortex_m/m3.zig index 7ec731d22..bdb164abb 100644 --- a/core/src/cpus/cortex_m/m3.zig +++ b/core/src/cpus/cortex_m/m3.zig @@ -9,7 +9,7 @@ pub const SystemControlBlock = extern struct { /// CPUID Base Register. CPUID: u32, /// Interrupt Control and State Register. - ICSR: mmio.Mmio(packed struct(u32) { + ICSR: mmio.OldMmio(packed struct(u32) { VECTACTIVE: u9, reserved0: u2 = 0, RETTOBASE: u1, @@ -28,7 +28,7 @@ pub const SystemControlBlock = extern struct { /// Vector Table Offset Register. VTOR: u32, /// Application Interrupt and Reset Control Register. - AIRCR: mmio.Mmio(packed struct { + AIRCR: mmio.OldMmio(packed struct { VECTRESET: u1, VECTCLRACTIVE: u1, SYSRESETREQ: u1, @@ -39,7 +39,7 @@ pub const SystemControlBlock = extern struct { VECTKEY: u16, }), /// System Control Register. - SCR: mmio.Mmio(packed struct { + SCR: mmio.OldMmio(packed struct { reserved0: u1 = 0, SLEEPONEXIT: u1, SLEEPDEEP: u1, @@ -48,7 +48,7 @@ pub const SystemControlBlock = extern struct { reserved2: u27 = 0, }), /// Configuration Control Register. - CCR: mmio.Mmio(packed struct(u32) { + CCR: mmio.OldMmio(packed struct(u32) { NONBASETHRDENA: u1, USERSETMPEND: u1, reserved0: u1 = 0, @@ -62,9 +62,9 @@ pub const SystemControlBlock = extern struct { /// System Handlers Priority Registers. SHPR: [3]u32, /// System Handler Control and State Register. - SHCSR: mmio.Mmio(shared.scb.SHCSR), + SHCSR: mmio.OldMmio(shared.scb.SHCSR), /// Configurable Fault Status Register. - CFSR: mmio.Mmio(packed struct(u32) { + CFSR: mmio.OldMmio(packed struct(u32) { /// MemManage Fault Register. MMFSR: shared.scb.MMFSR, /// BusFault Status Register. @@ -73,7 +73,7 @@ pub const SystemControlBlock = extern struct { UFSR: shared.scb.UFSR, }), /// HardFault Status Register. - HFSR: mmio.Mmio(shared.scb.HFSR), + HFSR: mmio.OldMmio(shared.scb.HFSR), reserved1: u32 = 0, /// MemManage Fault Address Register. MMFAR: u32, @@ -108,7 +108,7 @@ pub const NestedVectorInterruptController = extern struct { pub const MemoryProtectionUnit = extern struct { /// MPU Type Register - TYPE: mmio.Mmio(packed struct(u32) { + TYPE: mmio.OldMmio(packed struct(u32) { /// Indicates support for unified or separate instructions and data address regions. SEPARATE: u1, reserved0: u7 = 0, @@ -119,7 +119,7 @@ pub const MemoryProtectionUnit = extern struct { reserved1: u8 = 0, }), /// MPU Control Register - CTRL: mmio.Mmio(packed struct(u32) { + CTRL: mmio.OldMmio(packed struct(u32) { /// Enables the MPU ENABLE: u1, /// Enables of operation of MPU during HardFault and MNIHandlers. @@ -129,7 +129,7 @@ pub const MemoryProtectionUnit = extern struct { reserved0: u29 = 0, }), /// MPU Region Number Register - RNR: mmio.Mmio(packed struct(u32) { + RNR: mmio.OldMmio(packed struct(u32) { /// Indicates the memory region accessed by MPU RBAR and PMU RLAR. REGION: u8, reserved0: u24 = 0, @@ -151,7 +151,7 @@ pub const MemoryProtectionUnit = extern struct { /// MPU Alias 3 Region Attribute and Size Register RASR_A3: RASR_Register, - pub const RBAR_Register = mmio.Mmio(packed struct(u32) { + pub const RBAR_Register = mmio.OldMmio(packed struct(u32) { /// MPU region field. REGION: u4, /// MPU region number valid bit. @@ -160,7 +160,7 @@ pub const MemoryProtectionUnit = extern struct { ADDR: u27, }); - pub const RASR_Register = mmio.Mmio(packed struct(u32) { + pub const RASR_Register = mmio.OldMmio(packed struct(u32) { /// Region enable bit. ENABLE: u1, /// Specifies the size of the MPU protection region. diff --git a/core/src/cpus/cortex_m/m33.zig b/core/src/cpus/cortex_m/m33.zig index 3e93d5f96..fb0f4eeb1 100644 --- a/core/src/cpus/cortex_m/m33.zig +++ b/core/src/cpus/cortex_m/m33.zig @@ -18,7 +18,7 @@ pub const SystemControlBlock = extern struct { /// CPUID Base Register. CPUID: u32, /// Interrupt Control and State Register. - ICSR: mmio.Mmio(packed struct(u32) { + ICSR: mmio.OldMmio(packed struct(u32) { /// Contains the active exception number: /// 0 = Thread mode /// Nonzero = The exception number[a] of the currently active exception. @@ -109,7 +109,7 @@ pub const SystemControlBlock = extern struct { /// Vector Table Offset Register. VTOR: u32, /// Application Interrupt and Reset Control Register. - AIRCR: mmio.Mmio(packed struct { + AIRCR: mmio.OldMmio(packed struct { reserved0: u1 = 0, /// Reserved for debug use. This bit reads as 0. When writing to the register you must /// write 0 to this bit, otherwise behavior is Unpredictable. @@ -160,7 +160,7 @@ pub const SystemControlBlock = extern struct { VECTKEY: u16, }), /// System Control Register. - SCR: mmio.Mmio(packed struct(u32) { + SCR: mmio.OldMmio(packed struct(u32) { reserved0: u1 = 0, /// Indicates sleep-on-exit when returning from Handler mode to Thread mode: /// 0 = do not sleep when returning to Thread mode. @@ -192,7 +192,7 @@ pub const SystemControlBlock = extern struct { reserved1: u27 = 0, }), /// Configuration and Control Register. - CCR: mmio.Mmio(packed struct(u32) { + CCR: mmio.OldMmio(packed struct(u32) { reserved0: u1 = 0, /// User set pending determines if unpriviledged access to the STIR generates a fault. USERSETMPEND: u1, @@ -219,9 +219,9 @@ pub const SystemControlBlock = extern struct { /// System Handler Priority Registers. SHPR: [12]u8, /// System Handler Control and State Register. - SHCSR: mmio.Mmio(shared.scb.SHCSR), + SHCSR: mmio.OldMmio(shared.scb.SHCSR), /// Configurable Fault Status Register. - CFSR: mmio.Mmio(packed struct(u32) { + CFSR: mmio.OldMmio(packed struct(u32) { /// MemManage Fault Register. MMFSR: shared.scb.MMFSR, /// BusFault Status Register. @@ -230,7 +230,7 @@ pub const SystemControlBlock = extern struct { UFSR: shared.scb.UFSR, }), /// HardFault Status Register. - HFSR: mmio.Mmio(shared.scb.HFSR), + HFSR: mmio.OldMmio(shared.scb.HFSR), reserved0: u32 = 0, /// MemManage Fault Address Register. MMFAR: u32, @@ -240,7 +240,7 @@ pub const SystemControlBlock = extern struct { _AFSR: u32, reserved1: [18]u32, /// Coprocessor Access Control Register. - CPACR: mmio.Mmio(packed struct(u32) { + CPACR: mmio.OldMmio(packed struct(u32) { CP0: Privilege, CP1: Privilege, CP2: Privilege, @@ -269,7 +269,7 @@ pub const SystemControlBlock = extern struct { }; pub const FloatingPointUnit = extern struct { - FPCCR: mmio.Mmio(packed struct(u32) { + FPCCR: mmio.OldMmio(packed struct(u32) { LSPACT: u1, USER: u1, S: u1, @@ -382,7 +382,7 @@ pub const SecurityAttributionUnit = extern struct { pub const MemoryProtectionUnit = extern struct { /// MPU Type Register. - TYPE: mmio.Mmio(packed struct(u32) { + TYPE: mmio.OldMmio(packed struct(u32) { /// Indicates support for unified or separate instructions and data address regions. SEPARATE: u1, reserved0: u7 = 0, @@ -391,7 +391,7 @@ pub const MemoryProtectionUnit = extern struct { reserved1: u16 = 0, }), /// MPU Control Register. - CTRL: mmio.Mmio(packed struct(u32) { + CTRL: mmio.OldMmio(packed struct(u32) { /// Enables the MPU ENABLE: u1, /// Enables of operation of MPU during HardFault and MNIHandlers. @@ -401,7 +401,7 @@ pub const MemoryProtectionUnit = extern struct { reserved0: u29 = 0, }), /// MPU Region Number Register. - RNR: mmio.Mmio(packed struct(u32) { + RNR: mmio.OldMmio(packed struct(u32) { /// Indicates the memory region accessed by MPU RBAR and PMU RLAR. REGION: u8, reserved0: u24 = 0, @@ -429,7 +429,7 @@ pub const MemoryProtectionUnit = extern struct { MPU_MAIR1: u32, /// MPU Region Address Register format. - pub const RBAR_Register = mmio.Mmio(packed struct(u32) { + pub const RBAR_Register = mmio.OldMmio(packed struct(u32) { /// Execute Never defines if code can be executed from this region. XN: u1, /// Access permissions. @@ -442,7 +442,7 @@ pub const MemoryProtectionUnit = extern struct { }); /// MPU Region Limit Address Register format. - pub const RLAR_Register = mmio.Mmio(packed struct(u32) { + pub const RLAR_Register = mmio.OldMmio(packed struct(u32) { /// Enable the region. EN: u1, /// Attribue Index associates a set of attributes in the MPU MAIR0 and MPU MAIR1 fields. diff --git a/core/src/cpus/cortex_m/m4.zig b/core/src/cpus/cortex_m/m4.zig index 0fb631508..2e2cbc9cc 100644 --- a/core/src/cpus/cortex_m/m4.zig +++ b/core/src/cpus/cortex_m/m4.zig @@ -9,7 +9,7 @@ pub const SystemControlBlock = extern struct { /// CPUID Base Register. CPUID: u32, /// Interrupt Control and State Register. - ICSR: mmio.Mmio(packed struct(u32) { + ICSR: mmio.OldMmio(packed struct(u32) { VECTACTIVE: u9, reserved0: u2 = 0, RETTOBASE: u1, @@ -28,7 +28,7 @@ pub const SystemControlBlock = extern struct { /// Vector Table Offset Register. VTOR: u32, /// Application Interrupt and Reset Control Register. - AIRCR: mmio.Mmio(packed struct { + AIRCR: mmio.OldMmio(packed struct { VECTRESET: u1, VECTCLRACTIVE: u1, SYSRESETREQ: u1, @@ -39,7 +39,7 @@ pub const SystemControlBlock = extern struct { VECTKEY: u16, }), /// System Control Register. - SCR: mmio.Mmio(packed struct { + SCR: mmio.OldMmio(packed struct { reserved0: u1 = 0, SLEEPONEXIT: u1, SLEEPDEEP: u1, @@ -48,7 +48,7 @@ pub const SystemControlBlock = extern struct { reserved2: u27 = 0, }), /// Configuration Control Register. - CCR: mmio.Mmio(packed struct(u32) { + CCR: mmio.OldMmio(packed struct(u32) { NONBASETHRDENA: u1, USERSETMPEND: u1, reserved0: u1 = 0, @@ -62,9 +62,9 @@ pub const SystemControlBlock = extern struct { /// System Handlers Priority Registers. SHP: [12]u8, /// System Handler Contol and State Register. - SHCSR: mmio.Mmio(shared.scb.SHCSR), + SHCSR: mmio.OldMmio(shared.scb.SHCSR), /// Configurable Fault Status Register. - CFSR: mmio.Mmio(packed struct(u32) { + CFSR: mmio.OldMmio(packed struct(u32) { /// MemManage Fault Register. MMFSR: shared.scb.MMFSR, /// BusFault Status Register. @@ -73,7 +73,7 @@ pub const SystemControlBlock = extern struct { UFSR: shared.scb.UFSR, }), /// HardFault Status Register. - HFSR: mmio.Mmio(shared.scb.HFSR), + HFSR: mmio.OldMmio(shared.scb.HFSR), /// Debug Fault Status Register. DFSR: u32, /// MemManage Fault Address Register. @@ -83,7 +83,7 @@ pub const SystemControlBlock = extern struct { /// Auxilary Feature Register. AFSR: u32, reserved0: [18]u32, - CPACR: mmio.Mmio(packed struct(u32) { + CPACR: mmio.OldMmio(packed struct(u32) { reserved0: u20, CP10: Privilege, CP11: Privilege, @@ -126,7 +126,7 @@ pub const NestedVectorInterruptController = extern struct { pub const MemoryProtectionUnit = extern struct { /// MPU Type Register. - TYPE: mmio.Mmio(packed struct(u32) { + TYPE: mmio.OldMmio(packed struct(u32) { /// Indicates support for unified or separate instructions and data address regions. SEPARATE: u1, reserved0: u7 = 0, @@ -137,7 +137,7 @@ pub const MemoryProtectionUnit = extern struct { reserved1: u8 = 0, }), /// MPU Control Register. - CTRL: mmio.Mmio(packed struct(u32) { + CTRL: mmio.OldMmio(packed struct(u32) { /// Enables the MPU. ENABLE: u1, /// Enables of operation of MPU during HardFault and MNIHandlers. @@ -147,7 +147,7 @@ pub const MemoryProtectionUnit = extern struct { reserved0: u29 = 0, }), /// MPU Region Number Register. - RNR: mmio.Mmio(packed struct(u32) { + RNR: mmio.OldMmio(packed struct(u32) { /// Indicates the memory region accessed by MPU RBAR and PMU RLAR. REGION: u8, reserved0: u24 = 0, @@ -169,7 +169,7 @@ pub const MemoryProtectionUnit = extern struct { /// MPU Alias 3 Region Attribute and Size Register. RASR_A3: RASR_Register, - pub const RBAR_Register = mmio.Mmio(packed struct(u32) { + pub const RBAR_Register = mmio.OldMmio(packed struct(u32) { /// MPU region field. REGION: u4, /// MPU region number valid bit. @@ -178,7 +178,7 @@ pub const MemoryProtectionUnit = extern struct { ADDR: u27, }); - pub const RASR_Register = mmio.Mmio(packed struct(u32) { + pub const RASR_Register = mmio.OldMmio(packed struct(u32) { /// Region enable bit. ENABLE: u1, /// Specifies the size of the MPU protection region. @@ -204,7 +204,7 @@ pub const MemoryProtectionUnit = extern struct { }; pub const FloatingPointUnit = extern struct { - FPCCR: mmio.Mmio(packed struct(u32) { + FPCCR: mmio.OldMmio(packed struct(u32) { LSPACT: u1, USER: u1, reserved0: u1 = 0, diff --git a/core/src/cpus/cortex_m/m55.zig b/core/src/cpus/cortex_m/m55.zig index 467adfc9f..ed8518705 100644 --- a/core/src/cpus/cortex_m/m55.zig +++ b/core/src/cpus/cortex_m/m55.zig @@ -13,7 +13,7 @@ pub const SystemControlBlock = extern struct { /// CPUID Base Register. CPUID: u32, /// Interrupt Control and State Register. - ICSR: mmio.Mmio(packed struct(u32) { + ICSR: mmio.OldMmio(packed struct(u32) { /// Contains the active exception number: /// 0 = Thread mode /// Nonzero = The exception number[a] of the currently active exception. @@ -104,7 +104,7 @@ pub const SystemControlBlock = extern struct { /// Vector Table Offset Register. VTOR: u32, /// Application Interrupt and Reset Control Register. - AIRCR: mmio.Mmio(packed struct { + AIRCR: mmio.OldMmio(packed struct { reserved0: u1 = 0, /// Reserved for debug use. This bit reads as 0. When writing to the register you must /// write 0 to this bit, otherwise behavior is Unpredictable. @@ -157,7 +157,7 @@ pub const SystemControlBlock = extern struct { /// System Control Register. SCR: u32, /// Configuration and Control Register. - CCR: mmio.Mmio(packed struct(u32) { + CCR: mmio.OldMmio(packed struct(u32) { reserved0: u1 = 0, /// User set pending determines if unpriviledged access to the STIR generates a fault. USERSETMPEND: u1, @@ -184,9 +184,9 @@ pub const SystemControlBlock = extern struct { /// System Handler Priority Registers. SHPR: [12]u8, /// System Handler Control and State Register. - SHCSR: mmio.Mmio(shared.scb.SHCSR), + SHCSR: mmio.OldMmio(shared.scb.SHCSR), /// Configurable Fault Status Register. - CFSR: mmio.Mmio(packed struct(u32) { + CFSR: mmio.OldMmio(packed struct(u32) { /// MemManage Fault Register. MMFSR: shared.scb.MMFSR, /// BusFault Status Register. @@ -195,7 +195,7 @@ pub const SystemControlBlock = extern struct { UFSR: shared.scb.UFSR, }), /// HardFault Status Register. - HFSR: mmio.Mmio(shared.scb.HFSR), + HFSR: mmio.OldMmio(shared.scb.HFSR), /// Debug Fault Status Register. DFSR: u32, /// MemManage Fault Address Register. @@ -273,7 +273,7 @@ pub const SecurityAttributionUnit = extern struct { pub const MemoryProtectionUnit = extern struct { /// MPU Type Register. - TYPE: mmio.Mmio(packed struct(u32) { + TYPE: mmio.OldMmio(packed struct(u32) { /// Indicates support for unified or separate instructions and data address regions. SEPARATE: u1, reserved0: u7 = 0, @@ -282,7 +282,7 @@ pub const MemoryProtectionUnit = extern struct { reserved1: u16 = 0, }), /// MPU Control Register. - CTRL: mmio.Mmio(packed struct(u32) { + CTRL: mmio.OldMmio(packed struct(u32) { /// Enables the MPU ENABLE: u1, /// Enables of operation of MPU during HardFault and MNIHandlers. @@ -292,7 +292,7 @@ pub const MemoryProtectionUnit = extern struct { reserved0: u29 = 0, }), /// MPU Region Number Register. - RNR: mmio.Mmio(packed struct(u32) { + RNR: mmio.OldMmio(packed struct(u32) { /// Indicates the memory region accessed by MPU RBAR and PMU RLAR. REGION: u8, reserved0: u24 = 0, @@ -320,7 +320,7 @@ pub const MemoryProtectionUnit = extern struct { MPU_MAIR1: u32, /// MPU Region Address Register format. - pub const RBAR_Register = mmio.Mmio(packed struct(u32) { + pub const RBAR_Register = mmio.OldMmio(packed struct(u32) { /// Execute Never defines if code can be executed from this region. XN: u1, /// Access permissions. @@ -333,7 +333,7 @@ pub const MemoryProtectionUnit = extern struct { }); /// MPU Region Limit Address Register format. - pub const RLAR_Register = mmio.Mmio(packed struct(u32) { + pub const RLAR_Register = mmio.OldMmio(packed struct(u32) { /// Enable the region. EN: u1, /// Attribue Index associates a set of attributes in the MPU MAIR0 and MPU MAIR1 fields. diff --git a/core/src/cpus/cortex_m/m7.zig b/core/src/cpus/cortex_m/m7.zig index 9127054ed..43e44131c 100644 --- a/core/src/cpus/cortex_m/m7.zig +++ b/core/src/cpus/cortex_m/m7.zig @@ -9,7 +9,7 @@ pub const SystemControlBlock = extern struct { /// CPUID Base Register CPUID: u32, /// Interrupt Control and State Register - ICSR: mmio.Mmio(packed struct(u32) { + ICSR: mmio.OldMmio(packed struct(u32) { VECTACTIVE: u9, reserved0: u2 = 0, RETTOBASE: u1, @@ -28,7 +28,7 @@ pub const SystemControlBlock = extern struct { /// Vector Table Offset Register VTOR: u32, /// Application Interrupt and Reset Control Register - AIRCR: mmio.Mmio(packed struct(u32) { + AIRCR: mmio.OldMmio(packed struct(u32) { /// Reserved for Debug use. Must be written as 0. VECTRESET: u1, // WO /// Reserved for Debug use. Must be written as 0. @@ -47,7 +47,7 @@ pub const SystemControlBlock = extern struct { /// System Control Register SCR: u32, /// Configuration Control Register - CCR: mmio.Mmio(packed struct(u32) { + CCR: mmio.OldMmio(packed struct(u32) { NONBASETHRDENA: u1, USERSETMPEND: u1, reserved0: u1 = 0, @@ -67,7 +67,7 @@ pub const SystemControlBlock = extern struct { }), /// System Handler Priority Register 1 (SHPR1) - SHPR1: mmio.Mmio(packed struct(u32) { + SHPR1: mmio.OldMmio(packed struct(u32) { /// Priority of system handler 4, MemManage PRI_4: u8, /// Priority of system handler 5, BusFault @@ -79,7 +79,7 @@ pub const SystemControlBlock = extern struct { }), /// System Handler Priority Register 2 (SHPR2) - SHPR2: mmio.Mmio(packed struct(u32) { + SHPR2: mmio.OldMmio(packed struct(u32) { /// Reserved bits [23:0] reserved0: u24 = 0, /// Priority of system handler 11, SVCall @@ -87,7 +87,7 @@ pub const SystemControlBlock = extern struct { }), /// System Handler Priority Register 3 (SHPR3) - SHPR3: mmio.Mmio(packed struct(u32) { + SHPR3: mmio.OldMmio(packed struct(u32) { /// Reserved bits [15:0] reserved0: u16 = 0, /// Priority of system handler 14, PendSV @@ -97,9 +97,9 @@ pub const SystemControlBlock = extern struct { }), /// System Handler Contol and State Register - SHCSR: mmio.Mmio(shared.scb.SHCSR), + SHCSR: mmio.OldMmio(shared.scb.SHCSR), /// Configurable Fault Status Register - CFSR: mmio.Mmio(packed struct(u32) { + CFSR: mmio.OldMmio(packed struct(u32) { /// MemManage Fault Register. MMFSR: shared.scb.MMFSR, /// BusFault Status Register. @@ -114,7 +114,7 @@ pub const SystemControlBlock = extern struct { /// UsageFault Status Register UFSR: u32, /// HardFault Status Register - HFSR: mmio.Mmio(shared.scb.HFSR), + HFSR: mmio.OldMmio(shared.scb.HFSR), /// MemManage Fault Address Register MMAR: u32, /// BusFault Address Register @@ -170,7 +170,7 @@ pub const NestedVectorInterruptController = extern struct { pub const MemoryProtectionUnit = extern struct { /// MPU Type Register - TYPE: mmio.Mmio(packed struct(u32) { + TYPE: mmio.OldMmio(packed struct(u32) { SEPARATE: u1, reserved0: u7 = 0, DREGION: u8, @@ -178,14 +178,14 @@ pub const MemoryProtectionUnit = extern struct { reserved1: u8 = 0, }), /// MPU Control Register - CTRL: mmio.Mmio(packed struct(u32) { + CTRL: mmio.OldMmio(packed struct(u32) { ENABLE: u1, HFNMIENA: u1, PRIVDEFENA: u1, padding: u29 = 0, }), /// MPU RNRber Register - RNR: mmio.Mmio(packed struct(u32) { + RNR: mmio.OldMmio(packed struct(u32) { REGION: u8, padding: u24 = 0, }), @@ -206,13 +206,13 @@ pub const MemoryProtectionUnit = extern struct { /// MPU Alias 3 Region Attribute and Size Register RASR_A3: RASR_Register, - pub const RBAR_Register = mmio.Mmio(packed struct(u32) { + pub const RBAR_Register = mmio.OldMmio(packed struct(u32) { REGION: u4, VALID: u1, ADDR: u27, }); - pub const RASR_Register = mmio.Mmio(packed struct(u32) { + pub const RASR_Register = mmio.OldMmio(packed struct(u32) { /// Region enable bit ENABLE: u1, /// Region Size @@ -239,7 +239,7 @@ pub const MemoryProtectionUnit = extern struct { pub const DebugRegisters = extern struct { /// Debyg Halting Control and Status Register - DHCSR: mmio.Mmio(packed struct { + DHCSR: mmio.OldMmio(packed struct { reserved0: u6 = 0, S_RESET_ST: u1, S_RETIRE_ST: u1, @@ -258,18 +258,18 @@ pub const DebugRegisters = extern struct { }), /// Debug Core Register Selector Register /// TODO: Reserved have values ? see armv7-m reference manual - DCRSR: mmio.Mmio(packed struct { + DCRSR: mmio.OldMmio(packed struct { reserved0: u15 = 0, REGWnR: u1, reserved1: u9 = 0, REGSEL: u7, }), /// Debug Core Register Data Register - DCRDR: mmio.Mmio(packed struct { + DCRDR: mmio.OldMmio(packed struct { DBGTMP: u32, }), /// Debug exception and Monitor Control Register - DEMCR: mmio.Mmio(packed struct { + DEMCR: mmio.OldMmio(packed struct { reserved0: u7 = 0, TRCENA: u1, reserved1: u4 = 0, @@ -292,7 +292,7 @@ pub const DebugRegisters = extern struct { pub const ITM = extern struct { /// Stimulus Port Registers (0-255) - STIM: [256]mmio.Mmio(packed union { + STIM: [256]mmio.OldMmio(packed union { WRITE_U8: u8, WRITE_U16: u16, WRITE_U32: u32, @@ -305,21 +305,21 @@ pub const ITM = extern struct { reserved0: [640]u32, // Padding to 0xE00 /// Trace Enable Registers (0-7) - TER: [8]mmio.Mmio(packed struct(u32) { + TER: [8]mmio.OldMmio(packed struct(u32) { STIMENA: u32, // Enable bits for stimulus ports }), reserved1: [10]u32, // Padding to 0xE40 /// Trace Privilege Register - TPR: mmio.Mmio(packed struct(u32) { + TPR: mmio.OldMmio(packed struct(u32) { PRIVMASK: u32, // Privilege mask for stimulus ports }), reserved2: [15]u32, // Padding to 0xE80 /// Trace Control Register - TCR: mmio.Mmio(packed struct(u32) { + TCR: mmio.OldMmio(packed struct(u32) { ITMENA: u1, // ITM enable TSENA: u1, // Local timestamp enable SYNCENA: u1, // Sync packet enable @@ -337,28 +337,28 @@ pub const ITM = extern struct { pub const TPIU = extern struct { /// Supported Parallel Port Sizes Register - SSPSR: mmio.Mmio(packed struct(u32) { + SSPSR: mmio.OldMmio(packed struct(u32) { SWIDTH: u32, }), /// Current Parallel Port Size Register - CSPSR: mmio.Mmio(packed struct(u32) { + CSPSR: mmio.OldMmio(packed struct(u32) { CWIDTH: u32, }), reserved0: [2]u32, /// Asynchronous Clock Prescaler Register - ACPR: mmio.Mmio(packed struct(u32) { + ACPR: mmio.OldMmio(packed struct(u32) { SWOSCALER: u16, padding: u16 = 0, }), reserved1: [55]u32, /// Selected Pin Protocol Register - SPPR: mmio.Mmio(packed struct(u32) { + SPPR: mmio.OldMmio(packed struct(u32) { TXMODE: u2, padding: u30 = 0, }), reserved2: [524]u32, /// TPIU Type Register - TYPE: mmio.Mmio(packed struct(u32) { + TYPE: mmio.OldMmio(packed struct(u32) { reserved0: u6 = 0, FIFOSZ: u3, PTINVALID: u1, @@ -371,7 +371,7 @@ pub const TPIU = extern struct { }; pub const FloatingPointUnit = extern struct { - FPCCR: mmio.Mmio(packed struct(u32) { + FPCCR: mmio.OldMmio(packed struct(u32) { LSPACT: u1, USER: u1, S: u1, diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 98c08579a..8ff90808a 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -1,6 +1,8 @@ const std = @import("std"); const assert = std.debug.assert; +pub const OldMmio = Mmio; + pub fn Mmio(comptime PackedT: type) type { @setEvalBranchQuota(2_000); diff --git a/port/espressif/esp/src/hal/clocks/esp32_c3.zig b/port/espressif/esp/src/hal/clocks/esp32_c3.zig index 5a9eb7ca9..ffe27f9f5 100644 --- a/port/espressif/esp/src/hal/clocks/esp32_c3.zig +++ b/port/espressif/esp/src/hal/clocks/esp32_c3.zig @@ -240,7 +240,7 @@ fn bbpll_configure(pll_freq: CpuClockSource.PllClock.PllFreq) void { } const I2C_ANA_MST_TYPE = extern struct { - ANA_CONF0: microzig.mmio.Mmio(packed struct { + ANA_CONF0: microzig.mmio.OldMmio(packed struct { reserved0: u2, BBPLL_STOP_FORCE_HIGH: u1, BBPLL_STOP_FORCE_LOW: u1, diff --git a/port/raspberrypi/rp2xxx/src/hal/gpio.zig b/port/raspberrypi/rp2xxx/src/hal/gpio.zig index 7126bf601..3f677f866 100644 --- a/port/raspberrypi/rp2xxx/src/hal/gpio.zig +++ b/port/raspberrypi/rp2xxx/src/hal/gpio.zig @@ -15,7 +15,6 @@ const NUM_BANK0_GPIOS = switch (chip) { .RP2350 => 48, }; - pub const Direction = enum(u1) { in, out, diff --git a/port/stmicro/stm32/src/hals/STM32L47X/lcd.zig b/port/stmicro/stm32/src/hals/STM32L47X/lcd.zig index eef142bbc..53f24e1cc 100644 --- a/port/stmicro/stm32/src/hals/STM32L47X/lcd.zig +++ b/port/stmicro/stm32/src/hals/STM32L47X/lcd.zig @@ -2,11 +2,11 @@ const microzig = @import("microzig"); const LCD = microzig.chip.peripherals.LCD; -const LCD_COM_L = microzig.mmio.Mmio(packed struct(u32) { +const LCD_COM_L = microzig.mmio.OldMmio(packed struct(u32) { SEG0T31: u32, }); -const LCD_COM_H = microzig.mmio.Mmio(packed struct(u32) { +const LCD_COM_H = microzig.mmio.OldMmio(packed struct(u32) { SEG32T44: u12, reserved: u20, }); From d644a36c809bf573fb39fedb179d381688758cb3 Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Sun, 1 Feb 2026 15:04:18 +0100 Subject: [PATCH 04/13] Add access field to Mmio --- core/src/mmio.zig | 30 ++++++++++++++++++++++++++++-- tools/regz/src/gen.zig | 31 +++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 8ff90808a..842de6b91 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -1,9 +1,35 @@ const std = @import("std"); const assert = std.debug.assert; -pub const OldMmio = Mmio; +pub fn OldMmio(comptime PackedT: type) type { + var access: MmioAccess(PackedT) = undefined; + for (@typeInfo(PackedT).@"struct".fields) |fld| + @field(access, fld.name) = .read_write; + return Mmio(PackedT, access); +} + +pub const Access = enum { + read_only, + read_write, +}; + +pub fn MmioAccess(comptime PackedT: type) type { + @setEvalBranchQuota(20_000); + const info = @typeInfo(PackedT).@"struct"; + var field_names: [info.fields.len][:0]const u8 = undefined; + for (&field_names, info.fields) |*dst, src| + dst.* = src.name; + return @import("../src/core/usb.zig").Struct( + .auto, + null, + &field_names, + &@splat(Access), + &@splat(.{}), + ); +} -pub fn Mmio(comptime PackedT: type) type { +pub fn Mmio(comptime PackedT: type, access: MmioAccess(PackedT)) type { + _ = access; @setEvalBranchQuota(2_000); const size = @bitSizeOf(PackedT); diff --git a/tools/regz/src/gen.zig b/tools/regz/src/gen.zig index c5bff78d1..f45661ddc 100644 --- a/tools/regz/src/gen.zig +++ b/tools/regz/src/gen.zig @@ -1147,7 +1147,7 @@ fn write_register( register.size_bits, }); - try write_fields(db, arena, fields, register.size_bits, register_reset, writer); + try write_fields_and_access(db, arena, fields, register.size_bits, register_reset, writer); try writer.writeAll("}),\n"); } else if (array_prefix.len != 0) { try writer.print("{f}: {s}u{},\n", .{ @@ -1193,7 +1193,7 @@ fn get_field_default(field: Database.StructField, maybe_register_reset: ?Registe return (register_reset.value & field_mask) >> @intCast(field.offset_bits); } -fn write_fields( +fn write_fields_and_access( db: *Database, arena: Allocator, fields: []const Database.StructField, @@ -1235,6 +1235,19 @@ fn write_fields( var offset: u64 = 0; + const AccessType = enum { + read_only, + read_write, + }; + + const RegAndAccess = union(enum) { + normal: struct { []const u8, AccessType }, + reserved: u8, + padding, + }; + + var access: std.ArrayList(RegAndAccess) = .empty; + for (expanded_fields.items) |field| { log.debug("next field: offset={} field.offset_bits={}", .{ offset, field.offset_bits }); if (offset > field.offset_bits) { @@ -1260,6 +1273,7 @@ fn write_fields( if (offset < field.offset_bits) { try writer.print("reserved{}: u{} = 0,\n", .{ field.offset_bits, field.offset_bits - offset }); offset = field.offset_bits; + try access.append(arena, .{ .reserved = field.offset_bits }); } assert(offset == field.offset_bits); @@ -1330,6 +1344,8 @@ fn write_fields( log.debug("adding size bits to offset: offset={} field.size_bits={}", .{ offset, field.size_bits }); offset += field.size_bits; + + try access.append(arena, .{ .normal = .{ field.name, .read_write } }); } log.debug("before padding: offset={} register_size_bits={}", .{ offset, register_size_bits }); @@ -1337,10 +1353,19 @@ fn write_fields( if (offset < register_size_bits) { log.debug("writing padding", .{}); try writer.print("padding: u{} = 0,\n", .{register_size_bits - offset}); + try access.append(arena, .padding); } else { log.debug("No padding", .{}); } + try writer.writeAll("}, .{\n"); + + for (access.items) |it| switch (it) { + .normal => |data| try writer.print(".{s} = .{t},\n", data), + .reserved => |num| try writer.print(".reserved{} = .read_only,\n", .{num}), + .padding => try writer.writeAll(".padding = .read_only,\n"), + }; + try out_writer.writeAll(buf.written()); } @@ -1795,6 +1820,8 @@ test "gen.peripheral instantiation" { }, &vfs); } +// TODO: Adapt tests to new Mmio + test "gen.peripherals with a shared type" { var db = try tests.peripherals_with_shared_type(std.testing.allocator); defer db.destroy(); From 56a18626bd00bb537bd6f9a8e407606246f552bd Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Sun, 1 Feb 2026 16:02:00 +0100 Subject: [PATCH 05/13] remove unused Mmio.toggle --- core/src/mmio.zig | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 842de6b91..3906c3c38 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -83,43 +83,5 @@ pub fn Mmio(comptime PackedT: type, access: MmioAccess(PackedT)) type { } write(addr, val); } - - /// In field `field_name` of struct `val`, toggle (only) all bits that are set in `value`. - inline fn toggle_field(val: anytype, comptime field_name: []const u8, value: anytype) void { - const FieldType = @TypeOf(@field(val, field_name)); - switch (@typeInfo(FieldType)) { - .int => { - @field(val, field_name) = @field(val, field_name) ^ value; - }, - .@"enum" => |enum_info| { - // same as for the .Int case, but casting to and from the u... tag type U of the enum FieldType - const U = enum_info.tag_type; - @field(val, field_name) = - @as(FieldType, @enumFromInt(@as(U, @intFromEnum(@field(val, field_name))) ^ - @as(U, @intFromEnum(@as(FieldType, value))))); - }, - else => |T| { - @compileError("unsupported register field type '" ++ @typeName(T) ++ "'"); - }, - } - } - - /// In field `field_name` of this register, toggle (only) all bits that are set in `value`. - /// A one-field version of toggle(), more helpful if `field_name` is comptime calculated. - pub inline fn toggle_one(addr: *volatile Self, comptime field_name: []const u8, value: anytype) void { - var val = read(addr); - toggle_field(&val, field_name, value); - write(addr, val); - } - - /// For each `.Field = value` entry of `fields`: - /// In field `F` of this register, toggle (only) all bits that are set in `value`. - pub inline fn toggle(addr: *volatile Self, fields: anytype) void { - var val = read(addr); - inline for (@typeInfo(@TypeOf(fields)).@"struct".fields) |field| { - toggle_field(&val, field.name, @field(fields, field.name)); - } - write(addr, val); - } }; } From 1cb0480d7245cd96e48f91433355fc2e9efd1ca0 Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Sun, 1 Feb 2026 17:50:04 +0100 Subject: [PATCH 06/13] Mmio: do more checks on underlying_type --- core/src/mmio.zig | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 3906c3c38..29ae76217 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -32,17 +32,33 @@ pub fn Mmio(comptime PackedT: type, access: MmioAccess(PackedT)) type { _ = access; @setEvalBranchQuota(2_000); - const size = @bitSizeOf(PackedT); - if ((size % 8) != 0) - @compileError("size must be divisible by 8!"); + const IntT, const reg_fields = switch (@typeInfo(PackedT)) { + .@"struct" => |info| .{ switch (info.layout) { + .@"packed" => info.backing_integer.?, + else => @compileError("Struct must be packed"), + }, info.fields }, + else => @compileError("Unsupported type: " ++ @typeName(PackedT)), + }; + _ = reg_fields; + + if (@bitSizeOf(PackedT) != 8 * @sizeOf(PackedT)) + @compileError("Size in bits must be divisible by 8"); - if (!std.math.isPowerOfTwo(size / 8)) - @compileError("size must encode a power of two number of bytes!"); + if (!std.math.isPowerOfTwo(@sizeOf(PackedT))) + @compileError("Size in bytes must be a power of two"); - const IntT = std.meta.Int(.unsigned, size); + if (@alignOf(PackedT) != @sizeOf(PackedT)) + @compileError("PackedT must be naturally aligned"); - if (@sizeOf(PackedT) != (size / 8)) - @compileError(std.fmt.comptimePrint("IntT and PackedT must have the same size!, they are {} and {} bytes respectively", .{ size / 8, @sizeOf(PackedT) })); + if (@sizeOf(IntT) != @sizeOf(PackedT)) @compileError(std.fmt.comptimePrint( + "IntT and PackedT must have the same size, they are {} and {} bytes respectively", + .{ @sizeOf(IntT), @sizeOf(PackedT) }, + )); + + if (@bitSizeOf(IntT) != @bitSizeOf(PackedT)) @compileError(std.fmt.comptimePrint( + "IntT and PackedT must have the same bitsize, they are {} and {} bits respectively", + .{ @bitSizeOf(IntT), @bitSizeOf(PackedT) }, + )); return extern struct { const Self = @This(); @@ -56,9 +72,6 @@ pub fn Mmio(comptime PackedT: type, access: MmioAccess(PackedT)) type { } pub inline fn write(addr: *volatile Self, val: PackedT) void { - comptime { - assert(@bitSizeOf(PackedT) == @bitSizeOf(IntT)); - } addr.write_raw(@bitCast(val)); } From d1de386e6c9b3006fa72c177479453376266478c Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Sun, 1 Feb 2026 17:50:44 +0100 Subject: [PATCH 07/13] remove Mmio.write_raw in favor of just accessing the .raw field --- core/src/mmio.zig | 6 +--- .../espressif/esp/src/hal/clocks/esp32_c3.zig | 3 +- port/espressif/esp/src/hal/i2c.zig | 8 +++--- port/espressif/esp/src/hal/spi.zig | 8 +++--- port/espressif/esp/src/hal/system.zig | 16 +++++------ port/nordic/nrf5x/src/hal/clocks.zig | 15 ++++++---- port/nordic/nrf5x/src/hal/spim.zig | 6 ++-- port/nordic/nrf5x/src/hal/time.zig | 10 ++++--- port/nxp/mcx/src/mcxa153/hal/gpio.zig | 10 +++---- port/nxp/mcx/src/mcxa153/hal/syscon.zig | 28 ++++++++----------- .../mcx/src/mcxn947/hal/flexcomm/LP_I2C.zig | 5 ++-- port/nxp/mcx/src/mcxn947/hal/gpio.zig | 8 +++--- port/nxp/mcx/src/mcxn947/hal/pin.zig | 2 +- port/nxp/mcx/src/mcxn947/hal/syscon.zig | 8 +++--- port/raspberrypi/rp2xxx/src/hal/i2c_slave.zig | 4 +-- .../raspberrypi/rp2xxx/src/hal/pio/common.zig | 2 +- port/raspberrypi/rp2xxx/src/hal/resets.zig | 10 +++---- port/raspberrypi/rp2xxx/src/hal/spi.zig | 10 +++---- .../rp2xxx/src/hal/system_timer.zig | 4 +-- port/raspberrypi/rp2xxx/src/hal/uart.zig | 4 +-- port/raspberrypi/rp2xxx/src/hal/usb.zig | 12 ++++---- .../stmicro/stm32/src/hals/common/gpio_v2.zig | 10 +++---- port/wch/ch32v/src/hals/dma.zig | 15 +++++----- port/wch/ch32v/src/hals/i2c.zig | 6 ++-- port/wch/ch32v/src/hals/usart.zig | 4 +-- 25 files changed, 108 insertions(+), 106 deletions(-) diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 29ae76217..1ac355e2f 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -72,11 +72,7 @@ pub fn Mmio(comptime PackedT: type, access: MmioAccess(PackedT)) type { } pub inline fn write(addr: *volatile Self, val: PackedT) void { - addr.write_raw(@bitCast(val)); - } - - pub inline fn write_raw(addr: *volatile Self, val: IntT) void { - addr.raw = val; + addr.raw = @bitCast(val); } /// Set field `field_name` of this register to `value`. diff --git a/port/espressif/esp/src/hal/clocks/esp32_c3.zig b/port/espressif/esp/src/hal/clocks/esp32_c3.zig index ffe27f9f5..266178d90 100644 --- a/port/espressif/esp/src/hal/clocks/esp32_c3.zig +++ b/port/espressif/esp/src/hal/clocks/esp32_c3.zig @@ -153,9 +153,10 @@ fn switch_to_xtal(div: u10) void { } fn apb_freq_update(freq: u32) void { + // Why not just use the underlying register fields? const value = ((freq >> 12) & @as(u32, std.math.maxInt(u16))) | (((freq >> 12) & @as(u32, std.math.maxInt(u16))) << 16); - RTC_CNTL.STORE5.write_raw(value); + RTC_CNTL.STORE5.raw = value; } fn rom_cpu_frequency_update(freq: u32) void { diff --git a/port/espressif/esp/src/hal/i2c.zig b/port/espressif/esp/src/hal/i2c.zig index 7e565df8a..bf23c2504 100644 --- a/port/espressif/esp/src/hal/i2c.zig +++ b/port/espressif/esp/src/hal/i2c.zig @@ -147,13 +147,13 @@ pub const I2C = struct { self.reset(); // Disable all I2C interrupts - regs.INT_ENA.write_raw(0); + regs.INT_ENA.raw = 0; // Clear all I2C interrupts self.clear_interrupts(); // Configure controller - regs.CTR.write_raw(0); + regs.CTR.raw = 0; regs.CTR.modify(.{ .MS_MODE = 1, // Set I2C controller to master mode .SDA_FORCE_OUT = 1, // Use open drain output for SDA @@ -236,7 +236,7 @@ pub const I2C = struct { fn reset_command_list(self: I2C) void { // Reset all command registers for (0..self.get_regs().COMD.len) |i| - self.get_regs().COMD[@intCast(i)].write_raw(0); + self.get_regs().COMD[@intCast(i)].raw = 0; } /// Set the filter threshold in clock cycles @@ -343,7 +343,7 @@ pub const I2C = struct { /// Clear all interrupts inline fn clear_interrupts(self: I2C) void { - self.get_regs().INT_CLR.write_raw(0x3ffff); + self.get_regs().INT_CLR.raw = 0x3ffff; } inline fn start_transmission(self: I2C) void { diff --git a/port/espressif/esp/src/hal/spi.zig b/port/espressif/esp/src/hal/spi.zig index bda596b81..f5c880176 100644 --- a/port/espressif/esp/src/hal/spi.zig +++ b/port/espressif/esp/src/hal/spi.zig @@ -129,7 +129,7 @@ pub const SPI = enum(u2) { }); // this also enables using all 16 words - regs.USER.write_raw(0); + regs.USER.raw = 0; regs.CLK_GATE.modify(.{ .MST_CLK_ACTIVE = 1, @@ -143,11 +143,11 @@ pub const SPI = enum(u2) { }); // this also disables all cs lines - regs.MISC.write_raw(0); + regs.MISC.raw = 0; - regs.SLAVE.write_raw(0); + regs.SLAVE.raw = 0; - regs.CLOCK.write_raw(config.get_clock_config()); + regs.CLOCK.raw = config.get_clock_config(); regs.DMA_INT_CLR.modify(.{ .TRANS_DONE_INT_CLR = 1, diff --git a/port/espressif/esp/src/hal/system.zig b/port/espressif/esp/src/hal/system.zig index a1643d8ca..831f6fc92 100644 --- a/port/espressif/esp/src/hal/system.zig +++ b/port/espressif/esp/src/hal/system.zig @@ -85,16 +85,16 @@ pub fn init() void { pub fn clocks_enable_set(mask: PeripheralMask) void { var current_mask: u64 = @bitCast(@as(u64, SYSTEM.PERIP_CLK_EN0.raw) | ((@as(u64, SYSTEM.PERIP_CLK_EN1.raw) << 32))); current_mask |= @as(u43, @bitCast(mask)); - SYSTEM.PERIP_CLK_EN0.write_raw(@intCast(current_mask & 0xffff_ffff)); - SYSTEM.PERIP_CLK_EN1.write_raw(@intCast(current_mask >> 32)); + SYSTEM.PERIP_CLK_EN0.raw = @intCast(current_mask & 0xffff_ffff); + SYSTEM.PERIP_CLK_EN1.raw = @intCast(current_mask >> 32); } /// Clears the bits in the mask of the PERIP_CLK_ENx registers. pub fn clocks_enable_clear(mask: PeripheralMask) void { var current_mask: u64 = @bitCast(@as(u64, SYSTEM.PERIP_CLK_EN0.raw) | ((@as(u64, SYSTEM.PERIP_CLK_EN1.raw) << 32))); current_mask &= ~@as(u43, @bitCast(mask)); - SYSTEM.PERIP_CLK_EN0.write_raw(@intCast(current_mask & 0xffff_ffff)); - SYSTEM.PERIP_CLK_EN1.write_raw(@intCast(current_mask >> 32)); + SYSTEM.PERIP_CLK_EN0.raw = @intCast(current_mask & 0xffff_ffff); + SYSTEM.PERIP_CLK_EN1.raw = @intCast(current_mask >> 32); } /// Sets and clears the bits in the mask of the PERIP_RST_ENx registers. Resets the peripherals. @@ -107,16 +107,16 @@ pub fn peripheral_reset(mask: PeripheralMask) void { pub fn peripheral_reset_set(mask: PeripheralMask) void { var current_mask: u64 = @bitCast(@as(u64, SYSTEM.PERIP_RST_EN0.raw) | ((@as(u64, SYSTEM.PERIP_RST_EN1.raw) << 32))); current_mask |= @as(u43, @bitCast(mask)); - SYSTEM.PERIP_RST_EN0.write_raw(@intCast(current_mask & 0xffff_ffff)); - SYSTEM.PERIP_RST_EN1.write_raw(@intCast(current_mask >> 32)); + SYSTEM.PERIP_RST_EN0.raw = @intCast(current_mask & 0xffff_ffff); + SYSTEM.PERIP_RST_EN1.raw = @intCast(current_mask >> 32); } /// Clears the bits in the mask of the PERIP_RST_ENx registers. pub fn peripheral_reset_clear(mask: PeripheralMask) void { var current_mask: u64 = @bitCast(@as(u64, SYSTEM.PERIP_RST_EN0.raw) | ((@as(u64, SYSTEM.PERIP_RST_EN1.raw) << 32))); current_mask &= ~@as(u43, @bitCast(mask)); - SYSTEM.PERIP_RST_EN0.write_raw(@intCast(current_mask & 0xffff_ffff)); - SYSTEM.PERIP_RST_EN1.write_raw(@intCast(current_mask >> 32)); + SYSTEM.PERIP_RST_EN0.raw = @intCast(current_mask & 0xffff_ffff); + SYSTEM.PERIP_RST_EN1.raw = @intCast(current_mask >> 32); } /// Enable clocks and release peripherals from reset. diff --git a/port/nordic/nrf5x/src/hal/clocks.zig b/port/nordic/nrf5x/src/hal/clocks.zig index cbddea02d..d9a45daaa 100644 --- a/port/nordic/nrf5x/src/hal/clocks.zig +++ b/port/nordic/nrf5x/src/hal/clocks.zig @@ -16,25 +16,27 @@ const version: enum { pub const hfxo = struct { pub fn start() void { + // Consider patching the svd switch (version) { .nrf51 => { CLOCK.TASKS_HFCLKSTART = 1; while (CLOCK.EVENTS_HFCLKSTARTED == 0) {} }, .nrf52 => { - CLOCK.TASKS_HFCLKSTART.write_raw(1); + CLOCK.TASKS_HFCLKSTART.raw = 1; while (CLOCK.EVENTS_HFCLKSTARTED.raw == 0) {} }, } } pub fn stop() void { + // Consider patching the svd switch (version) { .nrf51 => { CLOCK.TASKS_HFCLKSTOP = 1; }, .nrf52 => { - CLOCK.TASKS_HFCLKSTOP.write_raw(1); + CLOCK.TASKS_HFCLKSTOP.raw = 1; }, } } @@ -63,13 +65,14 @@ pub const lfclk = struct { }; pub fn calibrate() void { + // Consider patching the svd switch (version) { .nrf51 => { CLOCK.TASKS_CAL = 1; while (CLOCK.EVENTS_DONE == 0) {} }, .nrf52 => { - CLOCK.TASKS_CAL.write_raw(1); + CLOCK.TASKS_CAL.raw(1); while (CLOCK.EVENTS_DONE.raw == 0) {} }, } @@ -131,25 +134,27 @@ pub const lfclk = struct { } pub fn start() void { + // Consider patching the svd switch (version) { .nrf51 => { CLOCK.TASKS_LFCLKSTART = 1; while (CLOCK.EVENTS_LFCLKSTARTED == 0) {} }, .nrf52 => { - CLOCK.TASKS_LFCLKSTART.write_raw(1); + CLOCK.TASKS_LFCLKSTART.raw = 1; while (CLOCK.EVENTS_LFCLKSTARTED.raw == 0) {} }, } } pub fn stop() void { + // Consider patching the svd switch (version) { .nrf51 => { CLOCK.TASKS_LFCLKSTOP = 1; }, .nrf52 => { - CLOCK.TASKS_LFCLKSTOP.write_raw(1); + CLOCK.TASKS_LFCLKSTOP.raw = 1; }, } } diff --git a/port/nordic/nrf5x/src/hal/spim.zig b/port/nordic/nrf5x/src/hal/spim.zig index f410a26bc..aa21e7b23 100644 --- a/port/nordic/nrf5x/src/hal/spim.zig +++ b/port/nordic/nrf5x/src/hal/spim.zig @@ -174,7 +174,7 @@ pub const SPIM = enum(u1) { } regs.ENABLE.write(.{ .ENABLE = .Enabled }); - regs.INTENCLR.write_raw(0xFFFFFFFF); + regs.INTENCLR.raw = 0xFFFF_FFFF; } pub fn write_blocking(spi: SPIM, data: []const u8, timeout: ?Duration) TransactionError!void { @@ -240,10 +240,10 @@ pub const SPIM = enum(u1) { fn prepare_dma_transfer(spi: SPIM, tx: []const u8, rx: []u8) TransactionError!void { const regs = spi.get_regs(); - regs.RXD.PTR.write_raw(@intFromPtr(rx.ptr)); + regs.RXD.PTR.raw = @intFromPtr(rx.ptr); regs.RXD.MAXCNT.write(.{ .MAXCNT = @truncate(rx.len) }); - regs.TXD.PTR.write_raw(@intFromPtr(tx.ptr)); + regs.TXD.PTR.raw = @intFromPtr(tx.ptr); regs.TXD.MAXCNT.write(.{ .MAXCNT = @truncate(tx.len) }); regs.EVENTS_END.write(.{ .EVENTS_END = .NotGenerated }); diff --git a/port/nordic/nrf5x/src/hal/time.zig b/port/nordic/nrf5x/src/hal/time.zig index f1f8ea0c0..7aec18246 100644 --- a/port/nordic/nrf5x/src/hal/time.zig +++ b/port/nordic/nrf5x/src/hal/time.zig @@ -51,14 +51,15 @@ pub fn init() void { rtc.CC[COMPARE_INDEX].write(.{ .COMPARE = 0x800000 }); // Clear counter, then start timer + // Consider patching the svd switch (version) { .nrf51 => { rtc.TASKS_CLEAR = 1; rtc.TASKS_START = 1; }, .nrf52 => { - rtc.TASKS_CLEAR.write_raw(1); - rtc.TASKS_START.write_raw(1); + rtc.TASKS_CLEAR.raw = 1; + rtc.TASKS_START.raw = 1; }, } @@ -70,6 +71,7 @@ pub fn init() void { /// the elapsed time. pub fn rtc_interrupt() callconv(.c) void { switch (version) { + // Consider patching the svd .nrf51 => { if (rtc.EVENTS_OVRFLW == 1) { rtc.EVENTS_OVRFLW = 0; @@ -83,12 +85,12 @@ pub fn rtc_interrupt() callconv(.c) void { }, .nrf52 => { if (rtc.EVENTS_OVRFLW.raw == 1) { - rtc.EVENTS_OVRFLW.write_raw(0); + rtc.EVENTS_OVRFLW.raw = 0; next_period(); } if (rtc.EVENTS_COMPARE[COMPARE_INDEX].raw == 1) { - rtc.EVENTS_COMPARE[COMPARE_INDEX].write_raw(0); + rtc.EVENTS_COMPARE[COMPARE_INDEX].raw = 0; next_period(); } }, diff --git a/port/nxp/mcx/src/mcxa153/hal/gpio.zig b/port/nxp/mcx/src/mcxa153/hal/gpio.zig index 8e50b97b6..600ef8022 100644 --- a/port/nxp/mcx/src/mcxa153/hal/gpio.zig +++ b/port/nxp/mcx/src/mcxa153/hal/gpio.zig @@ -27,7 +27,7 @@ pub const GPIO = enum(u7) { const old: u32 = regs.PDOR.raw; const new = @as(u32, output) << gpio.get_pin(); - regs.PDOR.write_raw(old & ~gpio.get_mask() | new); + regs.PDOR.raw = old & ~gpio.get_mask() | new; } pub fn get(gpio: GPIO) bool { @@ -40,7 +40,7 @@ pub const GPIO = enum(u7) { const regs = gpio.get_regs(); const old: u32 = regs.PTOR.raw; - regs.PTOR.write_raw(old | gpio.get_mask()); + regs.PTOR.raw = old | gpio.get_mask(); } pub fn set_direction(gpio: GPIO, direction: Direction) void { @@ -48,7 +48,7 @@ pub const GPIO = enum(u7) { const old: u32 = regs.PDDR.raw; const new = @as(u32, @intFromEnum(direction)) << gpio.get_pin(); - regs.PDDR.write_raw(old & ~gpio.get_mask() | new); + regs.PDDR.raw = old & ~gpio.get_mask() | new; } pub fn set_interrupt_config(gpio: GPIO, trigger: InterruptConfig) void { @@ -56,7 +56,7 @@ pub const GPIO = enum(u7) { const irqc = @as(u32, @intFromEnum(trigger)) << 16; const isf = @as(u32, 1) << 24; - regs.ICR[gpio.get_pin()].write_raw(irqc | isf); + regs.ICR[gpio.get_pin()].raw = irqc | isf; } pub fn get_interrupt_flag(gpio: GPIO) bool { @@ -69,7 +69,7 @@ pub const GPIO = enum(u7) { const regs = gpio.get_regs(); const old: u32 = regs.ISFR0.raw; - regs.ISFR0.write_raw(old | gpio.get_mask()); + regs.ISFR0.raw = old | gpio.get_mask(); } fn get_regs(gpio: GPIO) *volatile chip.types.peripherals.GPIO0 { diff --git a/port/nxp/mcx/src/mcxa153/hal/syscon.zig b/port/nxp/mcx/src/mcxa153/hal/syscon.zig index 82f56c532..e4a168694 100644 --- a/port/nxp/mcx/src/mcxa153/hal/syscon.zig +++ b/port/nxp/mcx/src/mcxa153/hal/syscon.zig @@ -15,12 +15,11 @@ pub fn enable_clock(comptime peripheral: Peripheral) void { defer freeze_clock_configuration(); switch (peripheral.cc()) { - 0 => chip.peripherals.MRCC0.MRCC_GLB_CC0_SET.write_raw( + 0 => chip.peripherals.MRCC0.MRCC_GLB_CC0_SET.raw = @as(u32, @bitCast(chip.peripherals.MRCC0.MRCC_GLB_CC0_SET)) | peripheral.mask(), - ), - 1 => chip.peripherals.MRCC0.MRCC_GLB_CC1_SET.write_raw( + + 1 => chip.peripherals.MRCC0.MRCC_GLB_CC1_SET.raw = @as(u32, @bitCast(chip.peripherals.MRCC0.MRCC_GLB_CC1_SET)) | peripheral.mask(), - ), } } @@ -29,12 +28,11 @@ pub fn disable_clock(comptime peripheral: Peripheral) void { defer freeze_clock_configuration(); switch (peripheral.cc()) { - 0 => chip.peripherals.MRCC0.MRCC_GLB_CC0_CLR.write_raw( + 0 => chip.peripherals.MRCC0.MRCC_GLB_CC0_CLR.raw = @as(u32, @bitCast(chip.peripherals.MRCC0.MRCC_GLB_CC0_CLR)) | peripheral.mask(), - ), - 1 => chip.peripherals.MRCC0.MRCC_GLB_CC1_CLR.write_raw( + + 1 => chip.peripherals.MRCC0.MRCC_GLB_CC1_CLR.raw = @as(u32, @bitCast(chip.peripherals.MRCC0.MRCC_GLB_CC1_CLR)) | peripheral.mask(), - ), } } @@ -43,12 +41,11 @@ pub fn reset_release(comptime peripheral: Peripheral) void { defer freeze_clock_configuration(); switch (peripheral.cc()) { - 0 => chip.peripherals.MRCC0.MRCC_GLB_RST0_SET.write_raw( + 0 => chip.peripherals.MRCC0.MRCC_GLB_RST0_SET.raw = @as(u32, @bitCast(chip.peripherals.MRCC0.MRCC_GLB_RST0_SET)) | peripheral.mask(), - ), - 1 => chip.peripherals.MRCC0.MRCC_GLB_RST1_SET.write_raw( + + 1 => chip.peripherals.MRCC0.MRCC_GLB_RST1_SET.raw = @as(u32, @bitCast(chip.peripherals.MRCC0.MRCC_GLB_RST1_SET)) | peripheral.mask(), - ), } } @@ -57,12 +54,11 @@ pub fn reset_assert(comptime peripheral: Peripheral) void { defer freeze_clock_configuration(); switch (peripheral.cc()) { - 0 => chip.peripherals.MRCC0.MRCC_GLB_RST0_CLR.write_raw( + 0 => chip.peripherals.MRCC0.MRCC_GLB_RST0_CLR.raw = @as(u32, @bitCast(chip.peripherals.MRCC0.MRCC_GLB_RST0_CLR)) | peripheral.mask(), - ), - 1 => chip.peripherals.MRCC0.MRCC_GLB_RST1_CLR.write_raw( + + 1 => chip.peripherals.MRCC0.MRCC_GLB_RST1_CLR.raw = @as(u32, @bitCast(chip.peripherals.MRCC0.MRCC_GLB_RST1_CLR)) | peripheral.mask(), - ), } } diff --git a/port/nxp/mcx/src/mcxn947/hal/flexcomm/LP_I2C.zig b/port/nxp/mcx/src/mcxn947/hal/flexcomm/LP_I2C.zig index 9c74160d3..acae9659a 100644 --- a/port/nxp/mcx/src/mcxn947/hal/flexcomm/LP_I2C.zig +++ b/port/nxp/mcx/src/mcxn947/hal/flexcomm/LP_I2C.zig @@ -147,7 +147,7 @@ pub const LP_I2C = enum(u4) { } pub fn clear_flags(i2c: LP_I2C) void { - i2c.get_regs().MSR.write_raw(0); + i2c.get_regs().MSR.raw = 0; } fn reset_fifos(i2c: LP_I2C) void { @@ -369,7 +369,8 @@ pub const LP_I2C = enum(u4) { flags = i2c.get_regs().MSR.read(); try i2c.check_flags(); } - i2c.get_regs().MSR.write_raw(1 << 9); + // Why nut use the underlying struct? + i2c.get_regs().MSR.raw = 1 << 9; } fn wait_for_tx_space(i2c: LP_I2C) Error!void { diff --git a/port/nxp/mcx/src/mcxn947/hal/gpio.zig b/port/nxp/mcx/src/mcxn947/hal/gpio.zig index dce1d4e95..58a9986c0 100644 --- a/port/nxp/mcx/src/mcxn947/hal/gpio.zig +++ b/port/nxp/mcx/src/mcxn947/hal/gpio.zig @@ -33,9 +33,9 @@ pub const GPIO = enum(u8) { const new: u32 = @as(u32, 1) << gpio.get_pin(); if (output == 1) - regs.PSOR.write_raw(new) + regs.PSOR.raw = new else - regs.PCOR.write_raw(new); + regs.PCOR.raw = new; } /// Returns the logical input of the GPIO. @@ -49,7 +49,7 @@ pub const GPIO = enum(u8) { pub fn toggle(gpio: GPIO) void { const regs = gpio.get_regs(); - regs.PTOR.write_raw(gpio.get_mask()); + regs.PTOR.raw = gpio.get_mask(); } pub fn set_direction(gpio: GPIO, direction: Direction) void { @@ -57,7 +57,7 @@ pub const GPIO = enum(u8) { const old: u32 = regs.PDDR.raw; const new = @as(u32, @intFromEnum(direction)) << gpio.get_pin(); - regs.PDDR.write_raw((old & ~gpio.get_mask()) | new); + regs.PDDR.raw = (old & ~gpio.get_mask()) | new; } /// Returns the gpio's control register diff --git a/port/nxp/mcx/src/mcxn947/hal/pin.zig b/port/nxp/mcx/src/mcxn947/hal/pin.zig index 93c141e90..abd3da96d 100644 --- a/port/nxp/mcx/src/mcxn947/hal/pin.zig +++ b/port/nxp/mcx/src/mcxn947/hal/pin.zig @@ -36,7 +36,7 @@ pub const Pin = enum(u8) { const base = @intFromPtr(&pin.get_port().get_regs().PCR0); const reg: PinTy = @ptrFromInt(base + pin.get_n() * @as(u32, 4)); - reg.write_raw(@as(u16, @bitCast(config))); + reg.raw = @as(u16, @bitCast(config)); } /// Returns the pin configurator (essentially a builder). diff --git a/port/nxp/mcx/src/mcxn947/hal/syscon.zig b/port/nxp/mcx/src/mcxn947/hal/syscon.zig index 22f4afaf8..06891ab42 100644 --- a/port/nxp/mcx/src/mcxn947/hal/syscon.zig +++ b/port/nxp/mcx/src/mcxn947/hal/syscon.zig @@ -18,7 +18,7 @@ pub fn module_enable_clock(module: Module) void { if (!module.can_control_clock()) return; const reg = &chip.peripherals.SYSCON0.AHBCLKCTRLSET[module.cc()]; - reg.write_raw(@as(u32, 1) << module.offset()); + reg.raw = @as(u32, 1) << module.offset(); } /// Disables the module's clock. @@ -27,7 +27,7 @@ pub fn module_disable_clock(module: Module) void { if (!module.can_control_clock()) return; const reg = &chip.peripherals.SYSCON0.AHBCLKCTRLCLR[module.cc()]; - reg.write_raw(@as(u32, 1) << module.offset()); + reg.raw = @as(u32, 1) << module.offset(); } // same as for `module_enable_clock` @@ -38,7 +38,7 @@ pub fn module_reset_assert(module: Module) void { if (!module.can_reset()) return; const reg = &chip.peripherals.SYSCON0.PRESETCTRLSET[module.cc()]; - reg.write_raw(@as(u32, 1) << module.offset()); + reg.raw = @as(u32, 1) << module.offset(); } /// Release the module's reset. @@ -47,7 +47,7 @@ pub fn module_reset_release(module: Module) void { if (!module.can_reset()) return; const reg = &chip.peripherals.SYSCON0.PRESETCTRLCLR[module.cc()]; - reg.write_raw(@as(u32, 1) << module.offset()); + reg.raw = @as(u32, 1) << module.offset(); } // This enum can be automatically generated using `generate.zig`, diff --git a/port/raspberrypi/rp2xxx/src/hal/i2c_slave.zig b/port/raspberrypi/rp2xxx/src/hal/i2c_slave.zig index a3fdd9145..a57ce9561 100644 --- a/port/raspberrypi/rp2xxx/src/hal/i2c_slave.zig +++ b/port/raspberrypi/rp2xxx/src/hal/i2c_slave.zig @@ -295,13 +295,13 @@ fn isr_common(self: *Self) void { // If we have no more data, fill the TX FIFO with zeros while (self.regs.IC_STATUS.read().TFNF == .NOT_FULL) { - self.regs.IC_DATA_CMD.write_raw(0); + self.regs.IC_DATA_CMD.raw = 0; } } else { // Fill the TX FIFO with data from the transfer buffer while (self.transfer_index < self.transfer_length and self.regs.IC_STATUS.read().TFNF == .NOT_FULL) { - self.regs.IC_DATA_CMD.write_raw(@intCast(self.transfer_buffer[self.transfer_index])); + self.regs.IC_DATA_CMD.raw = @intCast(self.transfer_buffer[self.transfer_index]); self.transfer_index += 1; } } diff --git a/port/raspberrypi/rp2xxx/src/hal/pio/common.zig b/port/raspberrypi/rp2xxx/src/hal/pio/common.zig index 8a2a58d9a..4d6d06ac1 100644 --- a/port/raspberrypi/rp2xxx/src/hal/pio/common.zig +++ b/port/raspberrypi/rp2xxx/src/hal/pio/common.zig @@ -217,7 +217,7 @@ pub fn PioImpl(EnumType: type, chip: Chip) type { const mask = @as(u32, 1) << index; var val = self.get_regs().INPUT_SYNC_BYPASS.raw; val |= mask; - self.get_regs().INPUT_SYNC_BYPASS.write_raw(val); + self.get_regs().INPUT_SYNC_BYPASS.raw = val; } pub fn get_sm_regs(self: EnumType, sm: StateMachine) *volatile StateMachine.Regs { diff --git a/port/raspberrypi/rp2xxx/src/hal/resets.zig b/port/raspberrypi/rp2xxx/src/hal/resets.zig index 6aafe637f..59c6fd92d 100644 --- a/port/raspberrypi/rp2xxx/src/hal/resets.zig +++ b/port/raspberrypi/rp2xxx/src/hal/resets.zig @@ -85,24 +85,24 @@ pub const Mask = pub fn reset(mask: Mask) void { const raw_mask: u32 = @bitCast(mask); - RESETS.RESET.write_raw(raw_mask); - RESETS.RESET.write_raw(0); + RESETS.RESET.raw = raw_mask; + RESETS.RESET.raw = 0; wait_for_reset_done(mask); } pub inline fn reset_block(mask: Mask) void { - hw.set_alias(RESETS).RESET.write_raw(@bitCast(mask)); + hw.set_alias(RESETS).RESET.raw = @bitCast(mask); } pub inline fn unreset_block(mask: Mask) void { - hw.clear_alias(RESETS).RESET.write_raw(@bitCast(mask)); + hw.clear_alias(RESETS).RESET.raw = @bitCast(mask); } pub fn unreset_block_wait(mask: Mask) void { const raw_mask: u32 = @bitCast(mask); - hw.clear_alias(RESETS).RESET.write_raw(raw_mask); + hw.clear_alias(RESETS).RESET.raw = raw_mask; wait_for_reset_done(mask); } diff --git a/port/raspberrypi/rp2xxx/src/hal/spi.zig b/port/raspberrypi/rp2xxx/src/hal/spi.zig index 7c0c7ea5f..c6bdd10bb 100644 --- a/port/raspberrypi/rp2xxx/src/hal/spi.zig +++ b/port/raspberrypi/rp2xxx/src/hal/spi.zig @@ -213,7 +213,7 @@ pub const SPI = enum(u1) { var count: usize = 0; while (spi.is_writable()) { const element = src_iter.next_element() orelse break; - spi_regs.SSPDR.write_raw(element.value); + spi_regs.SSPDR.raw = element.value; count += 1; } spi_regs.SSPCR1.modify(.{ @@ -230,7 +230,7 @@ pub const SPI = enum(u1) { }); var tx_remaining = repeat_count; while (tx_remaining > 0 and spi.is_writable()) { - spi_regs.SSPDR.write_raw(repeated_byte); + spi_regs.SSPDR.raw = repeated_byte; tx_remaining -= 1; } spi_regs.SSPCR1.modify(.{ @@ -279,7 +279,7 @@ pub const SPI = enum(u1) { while (rx_remaining > 0 or tx_remaining > 0) { if (tx_remaining > 0 and spi.is_writable() and rx_remaining < tx_remaining + fifo_depth) { const element = src_iter.next_element() orelse unreachable; - spi_regs.SSPDR.write_raw(element.value); + spi_regs.SSPDR.raw = element.value; tx_remaining -= 1; } if (rx_remaining > 0 and spi.is_readable()) { @@ -330,7 +330,7 @@ pub const SPI = enum(u1) { while (!spi.is_writable()) { hw.tight_loop_contents(); } - spi_regs.SSPDR.write_raw(element.value); + spi_regs.SSPDR.raw = element.value; } // Drain RX FIFO, then wait for shifting to finish (which may be *after* @@ -387,7 +387,7 @@ pub const SPI = enum(u1) { tx_remaining -= spi.prime_tx_fifo_repeated(PacketType, repeated_tx_data, tx_remaining); while (rx_remaining > 0 or tx_remaining > 0) { if (tx_remaining > 0 and spi.is_writable() and rx_remaining < tx_remaining + fifo_depth) { - spi_regs.SSPDR.write_raw(repeated_tx_data); + spi_regs.SSPDR.raw = repeated_tx_data; tx_remaining -= 1; } if (rx_remaining > 0 and spi.is_readable()) { diff --git a/port/raspberrypi/rp2xxx/src/hal/system_timer.zig b/port/raspberrypi/rp2xxx/src/hal/system_timer.zig index 9b9a2a955..c58ba8055 100644 --- a/port/raspberrypi/rp2xxx/src/hal/system_timer.zig +++ b/port/raspberrypi/rp2xxx/src/hal/system_timer.zig @@ -43,13 +43,13 @@ pub const Timer = enum(u1) { /// Enables or disables the interrupt for the given alarm. pub fn set_interrupt_enabled(timer: Timer, alarm: Alarm, enable: bool) void { const regs = timer.get_regs(); - regs.INTE.write_raw(@as(u4, @intFromBool(enable)) << @intFromEnum(alarm)); + regs.INTE.raw = @as(u4, @intFromBool(enable)) << @intFromEnum(alarm); } /// Clears the interrupt flag for the given alarm. pub fn clear_interrupt(timer: Timer, alarm: Alarm) void { const regs = timer.get_regs(); - regs.INTR.write_raw(@as(u4, 1) << @intFromEnum(alarm)); + regs.INTR.raw = @as(u4, 1) << @intFromEnum(alarm); } /// Schedules an alarm to be triggered when the low word of the timer diff --git a/port/raspberrypi/rp2xxx/src/hal/uart.zig b/port/raspberrypi/rp2xxx/src/hal/uart.zig index fcb96054e..2d25fe90e 100644 --- a/port/raspberrypi/rp2xxx/src/hal/uart.zig +++ b/port/raspberrypi/rp2xxx/src/hal/uart.zig @@ -213,7 +213,7 @@ pub const UART = enum(u1) { }); var tx_remaining = src.len; while (tx_remaining > 0 and uart.is_writeable()) { - uart_regs.UARTDR.write_raw(src[src.len - tx_remaining]); + uart_regs.UARTDR.raw = src[src.len - tx_remaining]; tx_remaining -= 1; } uart_regs.UARTCR.modify(.{ @@ -306,7 +306,7 @@ pub const UART = enum(u1) { while (!uart.is_writeable()) { try deadline.check(time.get_time_since_boot()); } - uart_regs.UARTDR.write_raw(payload[offset]); + uart_regs.UARTDR.raw = payload[offset]; offset += 1; } } diff --git a/port/raspberrypi/rp2xxx/src/hal/usb.zig b/port/raspberrypi/rp2xxx/src/hal/usb.zig index a8fc03c61..7de5411b5 100644 --- a/port/raspberrypi/rp2xxx/src/hal/usb.zig +++ b/port/raspberrypi/rp2xxx/src/hal/usb.zig @@ -174,17 +174,17 @@ pub fn Polled(config: Config) type { // Clear the control portion of DPRAM. This may not be necessary -- the // datasheet is ambiguous -- but the C examples do it, and so do we. - peripherals.USB_DPRAM.SETUP_PACKET_LOW.write_raw(0); - peripherals.USB_DPRAM.SETUP_PACKET_HIGH.write_raw(0); + peripherals.USB_DPRAM.SETUP_PACKET_LOW.raw = 0; + peripherals.USB_DPRAM.SETUP_PACKET_HIGH.raw = 0; for (1..config.max_endpoints_count) |i| { - endpoint_control[i - 1].in.write_raw(0); - endpoint_control[i - 1].out.write_raw(0); + endpoint_control[i - 1].in.raw = 0; + endpoint_control[i - 1].out.raw = 0; } for (0..config.max_endpoints_count) |i| { - buffer_control[i].in.write_raw(0); - buffer_control[i].out.write_raw(0); + buffer_control[i].in.raw = 0; + buffer_control[i].out.raw = 0; } // Mux the controller to the onboard USB PHY. I was surprised that there are diff --git a/port/stmicro/stm32/src/hals/common/gpio_v2.zig b/port/stmicro/stm32/src/hals/common/gpio_v2.zig index fba4909f6..dae67f03e 100644 --- a/port/stmicro/stm32/src/hals/common/gpio_v2.zig +++ b/port/stmicro/stm32/src/hals/common/gpio_v2.zig @@ -136,7 +136,7 @@ pub const Pin = enum(usize) { const pin: u5 = @intCast(@intFromEnum(gpio) % 16); const modMask: u32 = gpio.mask_2bit(); - port.PUPDR.write_raw((port.PUPDR.raw & ~modMask) | @as(u32, @intFromEnum(bias)) << (pin << 1)); + port.PUPDR.raw = (port.PUPDR.raw & ~modMask) | @as(u32, @intFromEnum(bias)) << (pin << 1); } pub inline fn set_speed(gpio: Pin, speed: OSPEEDR) void { @@ -144,7 +144,7 @@ pub const Pin = enum(usize) { const pin: u5 = @intCast(@intFromEnum(gpio) % 16); const modMask: u32 = gpio.mask_2bit(); - port.OSPEEDR.write_raw((port.OSPEEDR.raw & ~modMask) | @as(u32, @intFromEnum(speed)) << (pin << 1)); + port.OSPEEDR.raw = (port.OSPEEDR.raw & ~modMask) | @as(u32, @intFromEnum(speed)) << (pin << 1); } pub inline fn set_moder(gpio: Pin, moder: MODER) void { @@ -152,14 +152,14 @@ pub const Pin = enum(usize) { const pin: u5 = @intCast(@intFromEnum(gpio) % 16); const modMask: u32 = gpio.mask_2bit(); - port.MODER.write_raw((port.MODER.raw & ~modMask) | @as(u32, @intFromEnum(moder)) << (pin << 1)); + port.MODER.raw = (port.MODER.raw & ~modMask) | @as(u32, @intFromEnum(moder)) << (pin << 1); } pub inline fn set_output_type(gpio: Pin, otype: OT) void { const port = gpio.get_port(); const pin: u5 = @intCast(@intFromEnum(gpio) % 16); - port.OTYPER.write_raw((port.OTYPER.raw & ~gpio.mask()) | @as(u32, @intFromEnum(otype)) << pin); + port.OTYPER.raw = (port.OTYPER.raw & ~gpio.mask()) | @as(u32, @intFromEnum(otype)) << pin; } pub inline fn set_alternate_function(gpio: Pin, afr: AF) void { @@ -167,7 +167,7 @@ pub const Pin = enum(usize) { const pin: u5 = @intCast(@intFromEnum(gpio) % 16); const afrMask: u32 = @as(u32, 0b1111) << ((pin % 8) << 2); const register = if (pin > 7) &port.AFR[1] else &port.AFR[0]; - register.write_raw((register.raw & ~afrMask) | @as(u32, @intFromEnum(afr)) << ((pin % 8) << 2)); + register.raw = (register.raw & ~afrMask) | @as(u32, @intFromEnum(afr)) << ((pin % 8) << 2); } pub fn from_port(port: Port, pin: u4) Pin { diff --git a/port/wch/ch32v/src/hals/dma.zig b/port/wch/ch32v/src/hals/dma.zig index 32687c725..3b4a05f70 100644 --- a/port/wch/ch32v/src/hals/dma.zig +++ b/port/wch/ch32v/src/hals/dma.zig @@ -227,7 +227,7 @@ pub const Channel = enum(u3) { // Clear all interrupt flags for this channel. There are four interrupts per channel, so we // shift by 4 * (channel - 1). Channel enum is 1-indexed, so subtract 1 for bit position. const flag_shift: u5 = (@as(u5, @intFromEnum(chan)) - 1) * 4; - regs.INTFCR.write_raw(@as(u32, 0b1111) << flag_shift); + regs.INTFCR.raw = @as(u32, 0b1111) << flag_shift; // NOTE: DIR bit affects transfer direction even in MEM2MEM mode (undocumented behavior): // - Always place the peripheral address in PADDR when a peripheral is involved. @@ -239,14 +239,14 @@ pub const Channel = enum(u3) { // Periph→Mem: PADDR=read (periph), MADDR=write (memory), DIR=0 // Mem→Mem: PADDR=read (source), MADDR=write (dest), DIR=0 if (H.is_peripheral(WriteType)) { - regs.MADDR.write_raw(read_addr); - regs.PADDR.write_raw(write_addr); + regs.MADDR.raw = read_addr; + regs.PADDR.raw = write_addr; } else { - regs.MADDR.write_raw(write_addr); - regs.PADDR.write_raw(read_addr); + regs.MADDR.raw = write_addr; + regs.PADDR.raw = read_addr; } // Set the amount of data to transfer - regs.CNTR.write_raw(count); + regs.CNTR.raw = count; // Set the priority regs.CFGR.modify(.{ .PL = @intFromEnum(config.priority) }); // Set the rest of the config @@ -323,7 +323,8 @@ pub const Channel = enum(u3) { pub fn clear_complete_flag(comptime chan: Channel) void { const regs = chan.get_regs(); const flag_shift: u5 = (@as(u5, @intFromEnum(chan)) - 1) * 4; - regs.INTFCR.write_raw(@as(u32, 0b0010) << flag_shift); // Clear only TCIF + // Why not use the underlying struct? + regs.INTFCR.raw = @as(u32, 0b0010) << flag_shift; // Clear only TCIF } pub fn get_remaining_count(comptime chan: Channel) u16 { diff --git a/port/wch/ch32v/src/hals/i2c.zig b/port/wch/ch32v/src/hals/i2c.zig index 62f18a5a5..ef1b57ad4 100644 --- a/port/wch/ch32v/src/hals/i2c.zig +++ b/port/wch/ch32v/src/hals/i2c.zig @@ -178,7 +178,7 @@ pub const I2C = enum(u1) { } // Write clock configuration - regs.CKCFGR.write_raw(ccr); + regs.CKCFGR.raw = ccr; // Enable peripheral first i2c.enable(); @@ -231,7 +231,7 @@ pub const I2C = enum(u1) { /// Send 7-bit address with direction bit inline fn send_address(i2c: I2C, addr: Address, direction: enum { write, read }) void { const addr_byte = @as(u8, @intFromEnum(addr)) << 1 | @intFromBool(direction == .read); - i2c.get_regs().DATAR.write_raw(addr_byte); + i2c.get_regs().DATAR.raw = addr_byte; } /// Common wait for STAR1/STAR2 flag with timeout @@ -330,7 +330,7 @@ pub const I2C = enum(u1) { try i2c.wait_flag_star1("TxE", 1, deadline); // Write data to DATAR - regs.DATAR.write_raw(element.value); + regs.DATAR.raw = element.value; } // Wait for BTF (Byte Transfer Finished) - ensures last byte is transmitted diff --git a/port/wch/ch32v/src/hals/usart.zig b/port/wch/ch32v/src/hals/usart.zig index f71655363..d796815c4 100644 --- a/port/wch/ch32v/src/hals/usart.zig +++ b/port/wch/ch32v/src/hals/usart.zig @@ -242,7 +242,7 @@ pub const USART = enum(u2) { const fraction = ((fraction_part * 16 + 50) / 100) & 0x0F; const brr_value = (mantissa << 4) | fraction; - regs.BRR.write_raw(@intCast(brr_value)); + regs.BRR.raw = @intCast(brr_value); } /// Check if transmit data register is empty (can write) @@ -262,7 +262,7 @@ pub const USART = enum(u2) { /// Write a single byte (non-blocking) pub inline fn write_byte(usart: USART, byte: u8) void { - usart.get_regs().DATAR.write_raw(byte); + usart.get_regs().DATAR.raw = byte; } /// Read a single byte (non-blocking) From c7480a78634d6a0cf31b9401f965655cb0510060 Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Sun, 1 Feb 2026 18:09:47 +0100 Subject: [PATCH 08/13] rename addr in Mmio to self --- core/src/mmio.zig | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 1ac355e2f..08db6ea40 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -61,36 +61,38 @@ pub fn Mmio(comptime PackedT: type, access: MmioAccess(PackedT)) type { )); return extern struct { - const Self = @This(); - raw: IntT, pub const underlying_type = PackedT; - pub inline fn read(addr: *volatile Self) PackedT { - return @bitCast(addr.raw); + pub inline fn read(self: *volatile @This()) PackedT { + return @bitCast(self.raw); } - pub inline fn write(addr: *volatile Self, val: PackedT) void { - addr.raw = @bitCast(val); + pub inline fn write(self: *volatile @This(), val: PackedT) void { + self.raw = @bitCast(val); } /// Set field `field_name` of this register to `value`. /// A one-field version of modify(), more helpful if `field_name` is comptime calculated. - pub inline fn modify_one(addr: *volatile Self, comptime field_name: []const u8, value: @FieldType(underlying_type, field_name)) void { - var val = read(addr); + pub inline fn modify_one( + self: *volatile @This(), + comptime field_name: []const u8, + value: @FieldType(underlying_type, field_name), + ) void { + var val = self.read(); @field(val, field_name) = value; - write(addr, val); + self.write(val); } /// For each `.Field = value` entry of `fields`: /// Set field `Field` of this register to `value`. - pub inline fn modify(addr: *volatile Self, fields: anytype) void { - var val = read(addr); + pub inline fn modify(self: *volatile @This(), fields: anytype) void { + var val = self.read(); inline for (@typeInfo(@TypeOf(fields)).@"struct".fields) |field| { @field(val, field.name) = @field(fields, field.name); } - write(addr, val); + self.write(val); } }; } From 774ee655841333e443c027bfbf3eb03051f7ab79 Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Mon, 2 Feb 2026 01:35:17 +0100 Subject: [PATCH 09/13] initial implementation of register access types --- core/src/mmio.zig | 180 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 170 insertions(+), 10 deletions(-) diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 08db6ea40..8bda69602 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -8,9 +8,59 @@ pub fn OldMmio(comptime PackedT: type) type { return Mmio(PackedT, access); } -pub const Access = enum { - read_only, - read_write, +/// Access type of a single field. Special and illegal have +/// the same functionality, but display different error messages. +pub const Access = struct { + /// Effect of reading the field + pub const Read = enum { + /// Reading does not affect the field value. + unaffected, + /// Reading changes the field value in an implementation-defined way. + special, + /// This register should never be read from. + illegal, + // There exist more! + }; + + pub const Write = enum { + /// Writing sets the field value to what was written. + normal, + /// Writing has no effect. + ignored, + /// Write 1 to set, 0 to leave unaffected. + set_mask, + /// Write 1 to clear, 0 to leave unaffected. + clear_mask, + /// Write 1 to toggle, 0 to leave unaffected. + toggle_mask, + /// Writing changes the this field in an implementation-defined way. + special, + /// This register should never be written to. + illegal, + // There exist more! + }; + + read: Read, + write: Write, + + pub const read_only: @This() = .{ .read = .unaffected, .write = .ignored }; + pub const read_write: @This() = .{ .read = .unaffected, .write = .normal }; + pub const write_only: @This() = .{ .read = .illegal, .write = .normal }; +}; + +/// If a field is not null, it contains the name of one of the registers +/// that prevent this capability, so that a nice error message can be displayed. +const Capabilities = struct { + /// If null, register can be read from. + read: ?[:0]const u8 = null, + /// If null, register can be written to. + write: ?[:0]const u8 = null, + /// If null, register can have bits set by a write operation. + set_mask: ?[:0]const u8 = null, + /// If null, register can have bits cleared by a write operation. + clear_mask: ?[:0]const u8 = null, + /// If null, register can have bits toggled by a write operation. + toggle_mask: ?[:0]const u8 = null, }; pub fn MmioAccess(comptime PackedT: type) type { @@ -28,8 +78,7 @@ pub fn MmioAccess(comptime PackedT: type) type { ); } -pub fn Mmio(comptime PackedT: type, access: MmioAccess(PackedT)) type { - _ = access; +pub fn Mmio(comptime PackedT: type, access_type: MmioAccess(PackedT)) type { @setEvalBranchQuota(2_000); const IntT, const reg_fields = switch (@typeInfo(PackedT)) { @@ -39,7 +88,6 @@ pub fn Mmio(comptime PackedT: type, access: MmioAccess(PackedT)) type { }, info.fields }, else => @compileError("Unsupported type: " ++ @typeName(PackedT)), }; - _ = reg_fields; if (@bitSizeOf(PackedT) != 8 * @sizeOf(PackedT)) @compileError("Size in bits must be divisible by 8"); @@ -64,12 +112,58 @@ pub fn Mmio(comptime PackedT: type, access: MmioAccess(PackedT)) type { raw: IntT, pub const underlying_type = PackedT; + const capabilities: Capabilities = blk: { + var ret: Capabilities = .{}; + for (reg_fields) |field| { + const a: Access = @field(access_type, field.name); + switch (a.read) { + .unaffected => {}, + .special, .illegal => ret.read = field.name, + } + switch (a.write) { + .normal => { + ret.set_mask = field.name; + ret.clear_mask = field.name; + ret.toggle_mask = field.name; + }, + .ignored => {}, + .set_mask => { + ret.write = field.name; + ret.clear_mask = field.name; + ret.toggle_mask = field.name; + }, + .clear_mask => { + ret.write = field.name; + ret.set_mask = field.name; + ret.toggle_mask = field.name; + }, + .toggle_mask => { + ret.write = field.name; + ret.set_mask = field.name; + ret.clear_mask = field.name; + }, + .special, .illegal => { + ret.write = field.name; + ret.set_mask = field.name; + ret.clear_mask = field.name; + ret.toggle_mask = field.name; + }, + } + break :blk ret; + } + }; pub inline fn read(self: *volatile @This()) PackedT { + if (capabilities.read) |name| + reg_type_op_error(name, "reading from the register"); + return @bitCast(self.raw); } pub inline fn write(self: *volatile @This(), val: PackedT) void { + if (capabilities.write) |name| + reg_type_op_error(name, "writing to the register"); + self.raw = @bitCast(val); } @@ -80,19 +174,85 @@ pub fn Mmio(comptime PackedT: type, access: MmioAccess(PackedT)) type { comptime field_name: []const u8, value: @FieldType(underlying_type, field_name), ) void { - var val = self.read(); + if (capabilities.read orelse capabilities.write) |name| + reg_type_op_error(name, "modifying this register by read-modify-write"); + + if (@field(access_type, field_name).write != .normal) + reg_type_op_error(field_name, "modifying this field by read-modify-write"); + + var val: PackedT = @bitCast(self.raw); @field(val, field_name) = value; - self.write(val); + self.raw = @bitCast(val); } /// For each `.Field = value` entry of `fields`: /// Set field `Field` of this register to `value`. + /// This is implemented using read-modify-write. pub inline fn modify(self: *volatile @This(), fields: anytype) void { - var val = self.read(); + if (capabilities.read orelse capabilities.write) |name| + reg_type_op_error(name, "modifying this register by read-modify-write"); + + self.modify_passed_value_and_write( + @bitCast(@as(IntT, 0)), + fields, + .normal, + "modifying this field by read-modify-write", + ); + } + + pub inline fn set_mask(self: *volatile @This(), fields: anytype) void { + if (capabilities.set_mask) |name| + reg_type_op_error(name, "setting bits in this register by masking"); + + self.modify_passed_value_and_write( + @bitCast(@as(IntT, 0)), + fields, + .set_mask, + "setting bits in this field by masking", + ); + } + + pub inline fn clear_mask(self: *volatile @This(), fields: anytype) void { + if (capabilities.clear_mask) |name| + reg_type_op_error(name, "clearing bits in this register by masking"); + + self.modify_passed_value_and_write( + @bitCast(@as(IntT, 0)), + fields, + .clear_mask, + "clearing bits in this field by masking", + ); + } + + inline fn modify_passed_value_and_write( + self: *volatile @This(), + initial: PackedT, + fields: anytype, + allowed_write_access: Access.Write, + comptime action: [:0]const u8, + ) void { + var val = initial; inline for (@typeInfo(@TypeOf(fields)).@"struct".fields) |field| { + if (@field(access_type, field.name).write != allowed_write_access) + reg_type_op_error(field.name, action); @field(val, field.name) = @field(fields, field.name); } - self.write(val); + self.raw = @bitCast(val); + } + + fn reg_type_op_error(comptime reg_name: [:0]const u8, comptime action: []const u8) noreturn { + const a = @field(access_type, reg_name); + @compileError( + "Register field's \"" ++ reg_name ++ "\" access type is read: " ++ + @tagName(a.read) ++ ", write: " ++ @tagName(a.write) ++ ",\nso " ++ action ++ + \\ is not possible. + \\ + \\If you think the access type is wrong, you can add a svd patch + \\in port/.../.../patches or to your build.zig directly. + \\ + \\-freference-trace may be useful to locate where this was called. + , + ); } }; } From e34ae3a065dc7166809dce9ccb88b784429a9b37 Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Mon, 2 Feb 2026 01:46:12 +0100 Subject: [PATCH 10/13] mark padding and reserved fields as read only --- core/src/mmio.zig | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 8bda69602..03192f834 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -2,9 +2,13 @@ const std = @import("std"); const assert = std.debug.assert; pub fn OldMmio(comptime PackedT: type) type { + const startsWith = std.mem.startsWith; + var access: MmioAccess(PackedT) = undefined; - for (@typeInfo(PackedT).@"struct".fields) |fld| - @field(access, fld.name) = .read_write; + for (@typeInfo(PackedT).@"struct".fields) |fld| { + const read_only = startsWith(u8, fld.name, "reserved") or startsWith(u8, fld.name, "padding"); + @field(access, fld.name) = if (read_only) .read_only else .read_write; + } return Mmio(PackedT, access); } From d16c3d34f20696a6bc6e43a79cb7c2177e71e899 Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Mon, 2 Feb 2026 05:29:35 +0100 Subject: [PATCH 11/13] output correct access type from regz --- core/src/mmio.zig | 23 +++++++++++++++-------- tools/regz/src/gen.zig | 25 +++++++++++++++---------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 03192f834..618b2d1d3 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -17,8 +17,10 @@ pub fn OldMmio(comptime PackedT: type) type { pub const Access = struct { /// Effect of reading the field pub const Read = enum { - /// Reading does not affect the field value. - unaffected, + /// Reading returns the currently stored field value and does not affect it. + normal, + /// Reading is not an error, but the returned value is meaningless. + garbage, /// Reading changes the field value in an implementation-defined way. special, /// This register should never be read from. @@ -47,9 +49,10 @@ pub const Access = struct { read: Read, write: Write, - pub const read_only: @This() = .{ .read = .unaffected, .write = .ignored }; - pub const read_write: @This() = .{ .read = .unaffected, .write = .normal }; - pub const write_only: @This() = .{ .read = .illegal, .write = .normal }; + pub const read_only: @This() = .{ .read = .normal, .write = .ignored }; + pub const read_write: @This() = .{ .read = .normal, .write = .normal }; + pub const write_only: @This() = .{ .read = .garbage, .write = .normal }; + pub const reserved: @This() = .{ .read = .garbage, .write = .ignored }; }; /// If a field is not null, it contains the name of one of the registers @@ -121,7 +124,7 @@ pub fn Mmio(comptime PackedT: type, access_type: MmioAccess(PackedT)) type { for (reg_fields) |field| { const a: Access = @field(access_type, field.name); switch (a.read) { - .unaffected => {}, + .normal, .garbage => {}, .special, .illegal => ret.read = field.name, } switch (a.write) { @@ -178,7 +181,9 @@ pub fn Mmio(comptime PackedT: type, access_type: MmioAccess(PackedT)) type { comptime field_name: []const u8, value: @FieldType(underlying_type, field_name), ) void { - if (capabilities.read orelse capabilities.write) |name| + if (capabilities.read) |name| + reg_type_op_error(name, "modifying this register by read-modify-write"); + if (capabilities.write) |name| reg_type_op_error(name, "modifying this register by read-modify-write"); if (@field(access_type, field_name).write != .normal) @@ -193,7 +198,9 @@ pub fn Mmio(comptime PackedT: type, access_type: MmioAccess(PackedT)) type { /// Set field `Field` of this register to `value`. /// This is implemented using read-modify-write. pub inline fn modify(self: *volatile @This(), fields: anytype) void { - if (capabilities.read orelse capabilities.write) |name| + if (capabilities.read) |name| + reg_type_op_error(name, "modifying this register by read-modify-write"); + if (capabilities.write) |name| reg_type_op_error(name, "modifying this register by read-modify-write"); self.modify_passed_value_and_write( diff --git a/tools/regz/src/gen.zig b/tools/regz/src/gen.zig index f45661ddc..f7452f7fb 100644 --- a/tools/regz/src/gen.zig +++ b/tools/regz/src/gen.zig @@ -1235,13 +1235,11 @@ fn write_fields_and_access( var offset: u64 = 0; - const AccessType = enum { - read_only, - read_write, - }; - const RegAndAccess = union(enum) { - normal: struct { []const u8, AccessType }, + normal: struct { + name: []const u8, + access: ?Database.Access, + }, reserved: u8, padding, }; @@ -1345,7 +1343,7 @@ fn write_fields_and_access( log.debug("adding size bits to offset: offset={} field.size_bits={}", .{ offset, field.size_bits }); offset += field.size_bits; - try access.append(arena, .{ .normal = .{ field.name, .read_write } }); + try access.append(arena, .{ .normal = .{ .name = field.name, .access = field.access } }); } log.debug("before padding: offset={} register_size_bits={}", .{ offset, register_size_bits }); @@ -1361,9 +1359,16 @@ fn write_fields_and_access( try writer.writeAll("}, .{\n"); for (access.items) |it| switch (it) { - .normal => |data| try writer.print(".{s} = .{t},\n", data), - .reserved => |num| try writer.print(".reserved{} = .read_only,\n", .{num}), - .padding => try writer.writeAll(".padding = .read_only,\n"), + .normal => |data| { + const access_str = switch (data.access orelse .read_write) { + .read_write_once, .read_write => "read_write", + .read_only => "read_only", + .write_only, .write_once => "write_only", + }; + try writer.print(".{s} = .{s},\n", .{ data.name, access_str }); + }, + .reserved => |num| try writer.print(".reserved{} = .reserved,\n", .{num}), + .padding => try writer.writeAll(".padding = .reserved,\n"), }; try out_writer.writeAll(buf.written()); From c4a988b67c0f5e2a4244d647679ec8870debcb5b Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Mon, 2 Feb 2026 05:30:23 +0100 Subject: [PATCH 12/13] redo mmio operations --- core/src/mmio.zig | 212 +++++++++++++++++++++------------------------- 1 file changed, 95 insertions(+), 117 deletions(-) diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 618b2d1d3..21caae89f 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -55,20 +55,12 @@ pub const Access = struct { pub const reserved: @This() = .{ .read = .garbage, .write = .ignored }; }; -/// If a field is not null, it contains the name of one of the registers -/// that prevent this capability, so that a nice error message can be displayed. -const Capabilities = struct { - /// If null, register can be read from. - read: ?[:0]const u8 = null, - /// If null, register can be written to. - write: ?[:0]const u8 = null, - /// If null, register can have bits set by a write operation. - set_mask: ?[:0]const u8 = null, - /// If null, register can have bits cleared by a write operation. - clear_mask: ?[:0]const u8 = null, - /// If null, register can have bits toggled by a write operation. - toggle_mask: ?[:0]const u8 = null, -}; +fn check_type_has_all_fields(T: type, fields: anytype) void { + inline for (@typeInfo(@TypeOf(fields)).@"struct".fields) |field| { + if (!@hasField(T, field.name)) + @compileError("Field " ++ field.name ++ " not present in " ++ @typeName(T)); + } +} pub fn MmioAccess(comptime PackedT: type) type { @setEvalBranchQuota(20_000); @@ -119,59 +111,24 @@ pub fn Mmio(comptime PackedT: type, access_type: MmioAccess(PackedT)) type { raw: IntT, pub const underlying_type = PackedT; - const capabilities: Capabilities = blk: { - var ret: Capabilities = .{}; - for (reg_fields) |field| { - const a: Access = @field(access_type, field.name); - switch (a.read) { - .normal, .garbage => {}, - .special, .illegal => ret.read = field.name, - } - switch (a.write) { - .normal => { - ret.set_mask = field.name; - ret.clear_mask = field.name; - ret.toggle_mask = field.name; - }, - .ignored => {}, - .set_mask => { - ret.write = field.name; - ret.clear_mask = field.name; - ret.toggle_mask = field.name; - }, - .clear_mask => { - ret.write = field.name; - ret.set_mask = field.name; - ret.toggle_mask = field.name; - }, - .toggle_mask => { - ret.write = field.name; - ret.set_mask = field.name; - ret.clear_mask = field.name; - }, - .special, .illegal => { - ret.write = field.name; - ret.set_mask = field.name; - ret.clear_mask = field.name; - ret.toggle_mask = field.name; - }, - } - break :blk ret; - } - }; + const all_zeros: PackedT = @bitCast(@as(IntT, 0)); pub inline fn read(self: *volatile @This()) PackedT { - if (capabilities.read) |name| - reg_type_op_error(name, "reading from the register"); - + comptime for (reg_fields) |field| + switch (@field(access_type, field.name).read) { + .normal, .garbage, .special => {}, + .illegal => reg_type_op_error(field.name, "reading from any fields of the register"), + }; return @bitCast(self.raw); } - pub inline fn write(self: *volatile @This(), val: PackedT) void { - if (capabilities.write) |name| - reg_type_op_error(name, "writing to the register"); - - self.raw = @bitCast(val); + pub inline fn write(self: *volatile @This(), w: PackedT) void { + comptime for (reg_fields) |field| + switch (@field(access_type, field.name).write) { + .normal, .ignored, .set_mask, .clear_mask, .toggle_mask, .special => {}, + .illegal => reg_type_op_error(field.name, "writing to any fields of the register"), + }; + self.raw = @bitCast(w); } /// Set field `field_name` of this register to `value`. @@ -181,74 +138,95 @@ pub fn Mmio(comptime PackedT: type, access_type: MmioAccess(PackedT)) type { comptime field_name: []const u8, value: @FieldType(underlying_type, field_name), ) void { - if (capabilities.read) |name| - reg_type_op_error(name, "modifying this register by read-modify-write"); - if (capabilities.write) |name| - reg_type_op_error(name, "modifying this register by read-modify-write"); - - if (@field(access_type, field_name).write != .normal) - reg_type_op_error(field_name, "modifying this field by read-modify-write"); - - var val: PackedT = @bitCast(self.raw); - @field(val, field_name) = value; - self.raw = @bitCast(val); + // Replace with @Struct when migrating to zig 0.16 + var fields: @import("core/usb.zig").Struct( + .auto, + null, + &.{field_name}, + &.{@TypeOf(value)}, + &.{.{}}, + ) = undefined; + @field(fields, field_name) = value; + self.modify(fields); } /// For each `.Field = value` entry of `fields`: /// Set field `Field` of this register to `value`. /// This is implemented using read-modify-write. pub inline fn modify(self: *volatile @This(), fields: anytype) void { - if (capabilities.read) |name| - reg_type_op_error(name, "modifying this register by read-modify-write"); - if (capabilities.write) |name| - reg_type_op_error(name, "modifying this register by read-modify-write"); - - self.modify_passed_value_and_write( - @bitCast(@as(IntT, 0)), - fields, - .normal, - "modifying this field by read-modify-write", - ); + check_type_has_all_fields(PackedT, fields); + const Fields = @TypeOf(fields); + + const r = self.read(); + var w: PackedT = undefined; + inline for (reg_fields) |field| { + const access = @field(access_type, field.name); + @field(w, field.name) = if (@hasField(Fields, field.name)) + // Overwrite this field + if (access.write == .normal and (access.read == .normal or access.read == .garbage)) + @field(fields, field.name) + else + reg_type_op_error(field.name, "modifying this field by read-modify-write") + else switch (access.write) { + // Leave field unchanged + .normal => if (access.read == .normal) + @field(r, field.name) + else + // This should actually be: + // reg_type_op_error(field.name, "modifying any field in this register by read-modify-write") + @field(all_zeros, field.name), + // Preserve old functionality + .ignored => @field(r, field.name), + // Write zeros so that nothing happens + .set_mask, .clear_mask, .toggle_mask => @field(all_zeros, field.name), + else => reg_type_op_error(field.name, "modifying any field in this register by read-modify-write"), + }; + } + self.write(w); } pub inline fn set_mask(self: *volatile @This(), fields: anytype) void { - if (capabilities.set_mask) |name| - reg_type_op_error(name, "setting bits in this register by masking"); - - self.modify_passed_value_and_write( - @bitCast(@as(IntT, 0)), - fields, - .set_mask, - "setting bits in this field by masking", - ); + check_type_has_all_fields(PackedT, fields); + const Fields = @TypeOf(fields); + + var w: PackedT = undefined; + inline for (reg_fields) |field| { + const access = @field(access_type, field.name); + @field(w, field.name) = if (@hasField(Fields, field.name)) + // Set bits in this field + if (access.write == .set_mask) + @field(fields, field.name) + else + reg_type_op_error(field.name, "setting bits of this field by masking") + else switch (access.write) { + // Write zeros so that nothing happens + .ignored, .set_mask, .clear_mask, .toggle_mask => @field(all_zeros, field.name), + else => reg_type_op_error(field.name, "setting bits of any field in this register by masking"), + }; + } + self.write(w); } pub inline fn clear_mask(self: *volatile @This(), fields: anytype) void { - if (capabilities.clear_mask) |name| - reg_type_op_error(name, "clearing bits in this register by masking"); - - self.modify_passed_value_and_write( - @bitCast(@as(IntT, 0)), - fields, - .clear_mask, - "clearing bits in this field by masking", - ); - } - - inline fn modify_passed_value_and_write( - self: *volatile @This(), - initial: PackedT, - fields: anytype, - allowed_write_access: Access.Write, - comptime action: [:0]const u8, - ) void { - var val = initial; - inline for (@typeInfo(@TypeOf(fields)).@"struct".fields) |field| { - if (@field(access_type, field.name).write != allowed_write_access) - reg_type_op_error(field.name, action); - @field(val, field.name) = @field(fields, field.name); + check_type_has_all_fields(PackedT, fields); + const Fields = @TypeOf(fields); + + var w: PackedT = undefined; + inline for (reg_fields) |field| { + const access = @field(access_type, field.name); + @field(w, field.name) = if (@hasField(Fields, field.name)) + // Clear bits in this field + if (access.write == .clear_mask) + @field(fields, field.name) + else + reg_type_op_error(field.name, "clearing bits of this field by masking") + else switch (access.write) { + // Write zeros so that nothing happens + .ignored, .set_mask, .clear_mask, .toggle_mask => @field(all_zeros, field.name), + else => reg_type_op_error(field.name, "clearing bits of any field in this register by masking"), + }; } - self.raw = @bitCast(val); + self.write(w); } fn reg_type_op_error(comptime reg_name: [:0]const u8, comptime action: []const u8) noreturn { From 269cf1eb4b28dd3b626a637e4aea7ae3e96f475d Mon Sep 17 00:00:00 2001 From: Piotr Fila Date: Mon, 2 Feb 2026 21:06:30 +0100 Subject: [PATCH 13/13] fix some CI issues --- core/src/mmio.zig | 5 ++++- port/nordic/nrf5x/src/hal/clocks.zig | 2 +- port/wch/ch32v/src/cpus/qingkev2-rv32ec.zig | 1 - port/wch/ch32v/src/cpus/qingkev3-rv32imac.zig | 1 - tools/regz/src/gen.zig | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/mmio.zig b/core/src/mmio.zig index 21caae89f..0272f5ce4 100644 --- a/core/src/mmio.zig +++ b/core/src/mmio.zig @@ -135,7 +135,7 @@ pub fn Mmio(comptime PackedT: type, access_type: MmioAccess(PackedT)) type { /// A one-field version of modify(), more helpful if `field_name` is comptime calculated. pub inline fn modify_one( self: *volatile @This(), - comptime field_name: []const u8, + comptime field_name: [:0]const u8, value: @FieldType(underlying_type, field_name), ) void { // Replace with @Struct when migrating to zig 0.16 @@ -154,6 +154,7 @@ pub fn Mmio(comptime PackedT: type, access_type: MmioAccess(PackedT)) type { /// Set field `Field` of this register to `value`. /// This is implemented using read-modify-write. pub inline fn modify(self: *volatile @This(), fields: anytype) void { + @setEvalBranchQuota(10_000); check_type_has_all_fields(PackedT, fields); const Fields = @TypeOf(fields); @@ -186,6 +187,7 @@ pub fn Mmio(comptime PackedT: type, access_type: MmioAccess(PackedT)) type { } pub inline fn set_mask(self: *volatile @This(), fields: anytype) void { + @setEvalBranchQuota(10_000); check_type_has_all_fields(PackedT, fields); const Fields = @TypeOf(fields); @@ -208,6 +210,7 @@ pub fn Mmio(comptime PackedT: type, access_type: MmioAccess(PackedT)) type { } pub inline fn clear_mask(self: *volatile @This(), fields: anytype) void { + @setEvalBranchQuota(10_000); check_type_has_all_fields(PackedT, fields); const Fields = @TypeOf(fields); diff --git a/port/nordic/nrf5x/src/hal/clocks.zig b/port/nordic/nrf5x/src/hal/clocks.zig index d9a45daaa..839802230 100644 --- a/port/nordic/nrf5x/src/hal/clocks.zig +++ b/port/nordic/nrf5x/src/hal/clocks.zig @@ -72,7 +72,7 @@ pub const lfclk = struct { while (CLOCK.EVENTS_DONE == 0) {} }, .nrf52 => { - CLOCK.TASKS_CAL.raw(1); + CLOCK.TASKS_CAL.raw = 1; while (CLOCK.EVENTS_DONE.raw == 0) {} }, } diff --git a/port/wch/ch32v/src/cpus/qingkev2-rv32ec.zig b/port/wch/ch32v/src/cpus/qingkev2-rv32ec.zig index 7ae681cee..227a6dc79 100644 --- a/port/wch/ch32v/src/cpus/qingkev2-rv32ec.zig +++ b/port/wch/ch32v/src/cpus/qingkev2-rv32ec.zig @@ -69,7 +69,6 @@ pub inline fn system_init(comptime chip: anytype) void { // RCC->CFGR0 &= (uint32_t)0xF8FF0000; RCC.CFGR0.modify(.{ .SW = 0, - .SWS = 0, .HPRE = 0, .ADCPRE = 0, .MCO = 0, diff --git a/port/wch/ch32v/src/cpus/qingkev3-rv32imac.zig b/port/wch/ch32v/src/cpus/qingkev3-rv32imac.zig index e839eb843..7d1b45a33 100644 --- a/port/wch/ch32v/src/cpus/qingkev3-rv32imac.zig +++ b/port/wch/ch32v/src/cpus/qingkev3-rv32imac.zig @@ -102,7 +102,6 @@ pub inline fn system_init(comptime chip: anytype) void { // RCC->CFGR0 &= (uint32_t)0xF8FF0000; RCC.CFGR0.modify(.{ .SW = 0, - .SWS = 0, .HPRE = 0, .ADCPRE = 0, .MCO = 0, diff --git a/tools/regz/src/gen.zig b/tools/regz/src/gen.zig index f7452f7fb..ab37404f9 100644 --- a/tools/regz/src/gen.zig +++ b/tools/regz/src/gen.zig @@ -1365,7 +1365,7 @@ fn write_fields_and_access( .read_only => "read_only", .write_only, .write_once => "write_only", }; - try writer.print(".{s} = .{s},\n", .{ data.name, access_str }); + try writer.print(".{f} = .{s},\n", .{ std.zig.fmtId(data.name), access_str }); }, .reserved => |num| try writer.print(".reserved{} = .reserved,\n", .{num}), .padding => try writer.writeAll(".padding = .reserved,\n"),