Implements blinky for AVR.

wch-ch32v003
Felix (xq) Queißner 3 years ago
parent 26681f7b30
commit 284d19814d

@ -8,8 +8,14 @@ pub const memory_regions = [_]micro_linker.MemoryRegion{
micro_linker.MemoryRegion{ .offset = 0x800100, .length = 2048, .kind = .ram }, micro_linker.MemoryRegion{ .offset = 0x800100, .length = 2048, .kind = .ram },
}; };
const Port = enum(u8) {
B = 1,
C = 2,
D = 3,
};
pub fn parsePin(comptime spec: []const u8) type { pub fn parsePin(comptime spec: []const u8) type {
const invalid_format_msg = "The given pin '" ++ spec ++ "' has an invalid format. Pins must follow the format \"P{Port}.{Pin}\" scheme."; const invalid_format_msg = "The given pin '" ++ spec ++ "' has an invalid format. Pins must follow the format \"P{Port}{Pin}\" scheme.";
if (spec.len != 3) if (spec.len != 3)
@compileError(invalid_format_msg); @compileError(invalid_format_msg);
@ -17,31 +23,41 @@ pub fn parsePin(comptime spec: []const u8) type {
@compileError(invalid_format_msg); @compileError(invalid_format_msg);
return struct { return struct {
pub const port: u8 = std.ascii.toUpper(spec[1]) - 'A'; pub const port: Port = std.meta.stringToEnum(Port, spec[1..2]) orelse @compileError(invalid_format_msg);
pub const pin: u3 = @intCast(u3, spec[2] - '0'); pub const pin: u3 = std.fmt.parseInt(u3, spec[2..3], 10) catch @compileError(invalid_format_msg);
}; };
} }
pub const gpio = struct { pub const gpio = struct {
fn dirReg(comptime pin: type) *volatile u8 { fn regs(comptime desc: type) type {
return @intToPtr(*volatile u8, 0x01); return struct {
} const pin_addr = 3 * @enumToInt(desc.port) + 0x00;
fn portReg(comptime pin: type) *volatile u8 { const dir_addr = 3 * @enumToInt(desc.port) + 0x01;
return @intToPtr(*volatile u8, 0x01); const port_addr = 3 * @enumToInt(desc.port) + 0x02;
}
fn pinReg(comptime pin: type) *volatile u8 { const pin = @intToPtr(*volatile u8, pin_addr);
return @intToPtr(*volatile u8, 0x01); const dir = @intToPtr(*volatile u8, dir_addr);
const port = @intToPtr(*volatile u8, port_addr);
};
} }
pub fn setOutput(comptime pin: type) void { pub fn setOutput(comptime pin: type) void {
dirReg(pin).* |= (1 << pin.pin); asm volatile ("sbi %[port], %[pin]"
:
: [port] "I" (regs(pin).dir_addr),
[pin] "I" (pin.pin)
);
} }
pub fn setInput(comptime pin: type) void { pub fn setInput(comptime pin: type) void {
dirReg(pin).* &= ~(@as(u8, 1) << pin.pin); asm volatile ("cbi %[port], %[pin]"
:
: [port] "I" (regs(pin).dir_addr),
[pin] "I" (pin.pin)
);
} }
pub fn read(comptime pin: type) u1 { pub fn read(comptime pin: type) u1 {
return if ((pinReg(pin).* & (1 << pin.pin)) != 0) return if ((regs(pin).pin.* & (1 << pin.pin)) != 0)
@as(u1, 1) @as(u1, 1)
else else
0; 0;
@ -49,13 +65,25 @@ pub const gpio = struct {
pub fn write(comptime pin: type, state: u1) void { pub fn write(comptime pin: type, state: u1) void {
if (state == 1) { if (state == 1) {
portReg(pin).* |= (1 << pin.pin); asm volatile ("sbi %[port], %[pin]"
:
: [port] "I" (regs(pin).port_addr),
[pin] "I" (pin.pin)
);
} else { } else {
portReg(pin).* &= ~@as(u8, 1 << pin.pin); asm volatile ("cbi %[port], %[pin]"
:
: [port] "I" (regs(pin).port_addr),
[pin] "I" (pin.pin)
);
} }
} }
pub fn toggle(comptime pin: type) void { pub fn toggle(comptime pin: type) void {
portReg(pin).* ^= (1 << pin.pin); asm volatile ("sbi %[port], %[pin]"
:
: [port] "I" (regs(pin).pin_addr),
[pin] "I" (pin.pin)
);
} }
}; };

@ -30,8 +30,10 @@ pub fn main() void {
} }
fn busyloop() void { fn busyloop() void {
const limit = 100_000;
var i: u24 = 0; var i: u24 = 0;
while (i < 100_000) : (i += 1) { while (i < limit) : (i += 1) {
@import("std").mem.doNotOptimizeAway(i); @import("std").mem.doNotOptimizeAway(i);
} }
} }

Loading…
Cancel
Save