07-06-2023, 01:59 AM
Hi @lupyuen yes I can picture you teaching this topic, just by the quality and fun approach of your articles
I think it could be a great idea! there is certainly plenty of stuff still to work on, it has taken me a week to get VOL+/- working, and that is just the buttons hehe. btw here is the Zig code I ended up with using the Register approach I mentioned. I am not keen of uppercase naming and KEYADC prefixing everywhere, but at the same time I like that the code can be easily cross referenced to the A64 User Manual. Anyway I am sure the corporate paid influencers will spoil Zig before I make it to the next level
but I like the enum that doesnt impact the packed struct size. The Zig compiler is also keeping an eye on the packed struct size matching u32, nice.
and the Reg32:
![Smile Smile](https://forum.pine64.org/images/smilies/smile.png)
![Wink Wink](https://forum.pine64.org/images/smilies/wink.png)
Code:
pub const CTRL_REG = packed struct(u32) {
KEYADC_EN: bool = false,
_1: u1 = 0,
KEYADC_SAMPLE_RATE: u2 = 0,
LEVELB_VOL: u2 = 0,
KEYADC_HOLD_EN: bool = false,
KEYADC_HOLD_KEY_EN: bool = false,
LEVELA_B_CNT: u4 = 0,
KEY_MODE_SELECT: Mode = Mode.NORMAL,
_2: u2 = 0,
CONTINUE_TIME_SELECT: u4 = 0,
_3: u2 = 0,
_4: u2 = 0,
FIRST_CONVERT_DLY: u8 = 0,
pub const Mode = enum(u2) {
NORMAL = 0b00,
SINGLE = 0b01,
CONTINUE = 0b10,
};
pub fn asU32(self: CTRL_REG) u32 {
return @bitCast(u32, self);
}
pub fn fromU32(v: u32) CTRL_REG {
return @bitCast(CTRL_REG, v);
}
};
pub fn enable() void {
//enable KEYADC
var ctrl = CTRL_REG.fromU32(KEYADC_CTRL.read());
ctrl.KEYADC_EN = true;
ctrl.KEY_MODE_SELECT = CTRL_REG.Mode.SINGLE;
KEYADC_CTRL.write(ctrl.asU32());
//enable all interrupts
KEYADC_INTC.write(INTC_FlagsAll.asU32());
}
Code:
pub const Reg32 = struct {
ptr: *volatile u32,
pub fn init(addr: usize) Reg32 {
return Reg32{ .ptr = @intToPtr(*volatile u32, addr) };
}
pub fn read(self: Reg32) u32 {
return self.ptr.*;
}
pub fn write(self: Reg32, v: u32) void {
self.ptr.* = v;
}
};