diff --git a/src/gpio.zig b/src/gpio.zig index a17df27..588a350 100644 --- a/src/gpio.zig +++ b/src/gpio.zig @@ -1,12 +1,67 @@ const regs = @import("atmega328p.zig").registers; -/// For now only supports PORTB -pub fn init(comptime pin: u8, comptime dir: enum { in, out }) void { +const MODE = enum { in, out }; + +// PORTB: pins D8 to D13 +fn init_portb(pin: u3, comptime dir: MODE) void { regs.PORTB.DDRB.* = @as(u8, @intFromEnum(dir)) << pin; } -pub fn toggle(comptime pin: u8) void { +pub fn toggle_portb(comptime pin: u3) void { var val = regs.PORTB.PORTB.*; val ^= 1 << pin; regs.PORTB.PORTB.* = val; } + +// PORTD: pins D0 TO D7 +fn init_portd(pin: u3, comptime dir: MODE) void { + regs.PORTD.DDRD.* = @as(u8, @intFromEnum(dir)) << pin; +} + +pub fn toggle_portd(comptime pin: u3) void { + var val = regs.PORTD.PORTD.*; + val ^= 1 << pin; + regs.PORTD.PORTD.* = val; +} + +// TODO: PORTC: analog pins + +pub const PIN = enum { + D0, + D1, + D2, + D3, + D4, + D5, + D6, + D7, + D8, + D9, + D10, + D11, + D12, + D13, + A0, + A1, + A3, + A4, + A5, +}; + +pub fn init(comptime pin: PIN, comptime dir: MODE) void { + const i = @intFromEnum(pin); + if (i <= 7) { + init_portd(@as(u3, @intCast(i)), dir); + } else if (i >= 8 and i <= 13) { + init_portb(@as(u3, @intCast(i - 8)), dir); + } +} + +pub fn toggle(comptime pin: PIN) void { + const i = comptime @intFromEnum(pin); + if (i <= 7) { + toggle_portd(@as(u3, @intCast(i))); + } else if (i >= 8 and i <= 13) { + toggle_portb(@as(u3, @intCast(i - 8))); + } +} diff --git a/src/main.zig b/src/main.zig index 7b73e1e..ceabb31 100644 --- a/src/main.zig +++ b/src/main.zig @@ -30,7 +30,8 @@ pub fn main() void { // var x: u8 = 255; // x += 1; - gpio.init(5, .out); + gpio.init(.D13, .out); + gpio.init(.D5, .out); while (true) { uart.write_ch(ch); @@ -41,7 +42,8 @@ pub fn main() void { uart.write("\r\n"); } - gpio.toggle(5); + gpio.toggle(.D13); + gpio.toggle(.D5); delay_cycles(50000); } }