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 },
};
const Port = enum(u8) {
B = 1,
C = 2,
D = 3,
};
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)
@compileError(invalid_format_msg);
@ -17,31 +23,41 @@ pub fn parsePin(comptime spec: []const u8) type {
@compileError(invalid_format_msg);
return struct {
pub const port: u8 = std.ascii.toUpper(spec[1]) - 'A';
pub const pin: u3 = @intCast(u3, spec[2] - '0');
pub const port: Port = std.meta.stringToEnum(Port, spec[1..2]) orelse @compileError(invalid_format_msg);
pub const pin: u3 = std.fmt.parseInt(u3, spec[2..3], 10) catch @compileError(invalid_format_msg);
};
}
pub const gpio = struct {
fn dirReg(comptime pin: type) *volatile u8 {
return @intToPtr(*volatile u8, 0x01);
}
fn portReg(comptime pin: type) *volatile u8 {
return @intToPtr(*volatile u8, 0x01);
}
fn pinReg(comptime pin: type) *volatile u8 {
return @intToPtr(*volatile u8, 0x01);
fn regs(comptime desc: type) type {
return struct {
const pin_addr = 3 * @enumToInt(desc.port) + 0x00;
const dir_addr = 3 * @enumToInt(desc.port) + 0x01;
const port_addr = 3 * @enumToInt(desc.port) + 0x02;
const pin = @intToPtr(*volatile u8, pin_addr);
const dir = @intToPtr(*volatile u8, dir_addr);
const port = @intToPtr(*volatile u8, port_addr);
};
}
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 {
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 {
return if ((pinReg(pin).* & (1 << pin.pin)) != 0)
return if ((regs(pin).pin.* & (1 << pin.pin)) != 0)
@as(u1, 1)
else
0;
@ -49,13 +65,25 @@ pub const gpio = struct {
pub fn write(comptime pin: type, state: u1) void {
if (state == 1) {
portReg(pin).* |= (1 << pin.pin);
asm volatile ("sbi %[port], %[pin]"
:
: [port] "I" (regs(pin).port_addr),
[pin] "I" (pin.pin)
);
} 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 {
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 {
const limit = 100_000;
var i: u24 = 0;
while (i < 100_000) : (i += 1) {
while (i < limit) : (i += 1) {
@import("std").mem.doNotOptimizeAway(i);
}
}

Loading…
Cancel
Save