ZigEmbeddedGroup / regz

Generate zig code from ATDF or SVD files for microcontrollers.
MIT License
82 stars 29 forks source link

Mmio: expected type '*volatile , found '*align(1) volatile' #51

Open r4gus opened 2 years ago

r4gus commented 2 years ago

Hi,

first of all, thank you for your efforts. I encountered the following error when trying to access regs.DPLL[0].DPLLCTRLB using modify() (regs.DPLL[0].DPLLCTRLA works fine).

.\libs\microzig\src\modules\chips\atsame51j20a\atsame51j20a.zig:86:25: error: expected type '*volatile .chip.registers.Mmio(32,.chip.registers.struct:9277:33)', found '*align(1) volatile .chip.registers.Mmio(32,.chip.registers.struct:9277:33)'
    regs.OSCCTRL.DPLL[0].DPLLCTRLB.modify(.{.REFCLK = 1});
                        ^

The register file can be found here.

zig: 0.10.0-dev.3445+18440cb23 regz: main (last commit is 4b04e50cf14a3df87662dc79863e9b7e3dfc6591)

mattnite commented 2 years ago

Looking at the datasheet and the generated file, it looks like some padding is needed after DPLLCTRLA since it is 8 bits wide and B is 32 bits wide (looks like a classic overlook of an edge case). I can get to this later tonight, but can you try adding a u24 after DPLLCTRLA and a comptime assertion that B has the correct alignment wrt the beginning of the struct? (packed structs are broken in some cases, so it's good to double check)

r4gus commented 2 years ago

I tried adding the u24 after DPLLCTRLA but that doesn't fix the alignment issue. Also, DPLLCTRLB seems to be 4 byte alligned, but maybe I used `@alignOf`` wrong.

comptime {
    if (@alignOf(@TypeOf(micro.chip.regs.OSCCTRL.DPLL[0].DPLLCTRLB.raw))  != 4) {
        @compileError("incorrect alignment of DPLLCTRLB");
    }
}

I also tried to add padding to DPLLCTRLA directly:

    DPLLCTRLA: Mmio(32, packed struct {
            reserved0: u1,
            /// DPLL Enable
            ENABLE: u1,
            reserved1: u1,
            reserved2: u1,
            reserved3: u1,
            reserved4: u1,
            /// Run in Standby
            RUNSTDBY: u1,
            /// On Demand Control
            ONDEMAND: u1,
            padding0: u1
                ...
        }),

but then, accessing DPLLCTRLA using modify or read leads to the same error as stated above.

mattnite commented 2 years ago

you'd actually want to do something like

comptime {
    std.debug.assert(@bitOffsetOf(@TypeOf(micro.chip.regs.OSCCTRL.DPLL[0]), "DPLLCTRLB") % 4 == 0);
}

because that is asserting the alignment of the type, and we're interested in the alignment wrt the beginning of the struct that encapsulates it.

Also since the u24 doesn't work, try doing 24 u1's, that's a sure fire way to get around the packed struct bug in the stage 1 compiler. If that doesn't work then I need to rethink this API.

r4gus commented 2 years ago
comptime {
    std.debug.assert(@bitOffsetOf(@TypeOf(regs.OSCCTRL.DPLL[0]), "DPLLRATIO") % 4 == 0);
    std.debug.assert(@bitOffsetOf(@TypeOf(regs.OSCCTRL.DPLL[0]), "DPLLCTRLB") % 4 == 0);
}

regs.OSCCTRL.DPLL[0].DPLLCTRLB.modify(.{.FILTER = 0});

With u24

pub const DPLL = @intToPtr(*volatile [2]packed struct {
            /// DPLL Control A
            DPLLCTRLA: Mmio(8, packed struct {
                reserved0: u1,
                /// DPLL Enable
                ENABLE: u1,
                reserved1: u1,
                reserved2: u1,
                reserved3: u1,
                reserved4: u1,
                /// Run in Standby
                RUNSTDBY: u1,
                /// On Demand Control
                ONDEMAND: u1,
            }),

            padding0: u24,

           ...
}

Error:

.\libs\microzig\src\modules\chips\atsame51j20a\atsame51j20a.zig:137:25: error: expected type '*volatile .chip.registers.Mmio(32,.chip.registers.struct:9279:33)', found '*align(1:56:19) volatile .chip.registers.Mmio(32,.chip.registers.struct:9279:33)'
    regs.OSCCTRL.DPLL[0].DPLLCTRLB.modify(.{.FILTER = 0});
                        ^

with 24 x u1's

pub const DPLL = @intToPtr(*volatile [2]packed struct {
            /// DPLL Control A
            DPLLCTRLA: Mmio(8, packed struct {
                reserved0: u1,
                /// DPLL Enable
                ENABLE: u1,
                reserved1: u1,
                reserved2: u1,
                reserved3: u1,
                reserved4: u1,
                /// Run in Standby
                RUNSTDBY: u1,
                /// On Demand Control
                ONDEMAND: u1,
            }),

            padding0: u1,
            padding1: u1,
            padding2: u1,
            padding3: u1,
            padding4: u1,
            padding5: u1,
            padding6: u1,
            padding7: u1,
            padding8: u1,
            padding9: u1,
            padding10: u1,
            padding11: u1,
            padding12: u1,
            padding13: u1,
            padding14: u1,
            padding15: u1,
            padding16: u1,
            padding17: u1,
            padding18: u1,
            padding19: u1,
            padding20: u1,
            padding21: u1,
            padding22: u1,
            padding23: u1,

           ....
}

Error:

.\libs\microzig\src\modules\chips\atsame51j20a\atsame51j20a.zig:137:25: error: expected type '*volatile .chip.registers.Mmio(32,.chip.registers.struct:9302:33)', found '*align(1) volatile .chip.registers.Mmio(32,.chip.registers.struct:9302:33)'
    regs.OSCCTRL.DPLL[0].DPLLCTRLB.modify(.{.FILTER = 0});
                        ^