summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blink.zig66
-rw-r--r--build.zig78
-rw-r--r--init.zig27
-rw-r--r--linker.ld33
4 files changed, 204 insertions, 0 deletions
diff --git a/blink.zig b/blink.zig
new file mode 100644
index 0000000..4444427
--- /dev/null
+++ b/blink.zig
@@ -0,0 +1,66 @@
+const std = @import("std");
+
+const DDRB = @as(*volatile u8, @ptrFromInt(0x24));
+const PORTB = @as(*volatile u8, @ptrFromInt(0x25));
+
+const DELAY = 100;
+
+pub export fn delay(n: u32) void {
+ var i: u32 = 0;
+ while (i < n) : (i += 1) {
+ asm volatile ("nop" ::: "memory");
+ }
+}
+
+pub export fn blink(n: u32) void {
+ var i: u32 = 0;
+ DDRB.* = DDRB.* | (1 << 5);
+
+ while (i < n) : (i += 1) {
+ // Toggle PB5
+ PORTB.* ^= @as(u8, 1 << 5);
+ delay(100_000);
+ PORTB.* ^= @as(u8, 1 << 5);
+ delay(200_000);
+ }
+}
+
+pub export fn collatz(na: u32) u32 {
+ var n: u32 = na;
+ var c: u32 = 0;
+
+ while (n > 1) : (c += 1) {
+ if (n % 2 == 0) {
+ n /= 2;
+ } else {
+ n = n + n + n + 1;
+ }
+ }
+
+ return c;
+}
+
+pub export fn main() void {
+ var i: u32 = 0;
+ while (true) : (i += 1) {
+ const c = collatz(i);
+ blink(c);
+ delay(500_000);
+ }
+}
+
+pub export fn abort() void {
+ // Set PB5 (pin 13) as output
+ DDRB.* = DDRB.* | (1 << 5);
+
+ while (true) {
+ // Toggle PB5
+ PORTB.* ^= @as(u8, 1 << 5);
+
+ // Simple delay
+ var i: usize = 0;
+ while (i < DELAY) : (i += 1) {
+ asm volatile ("nop" ::: "memory");
+ }
+ }
+}
diff --git a/build.zig b/build.zig
new file mode 100644
index 0000000..0a65c1f
--- /dev/null
+++ b/build.zig
@@ -0,0 +1,78 @@
+const std = @import("std");
+const Builder = std.Build;
+
+pub fn build(b: *std.Build) !void {
+ const uno = std.zig.CrossTarget{
+ .cpu_arch = .avr,
+ .cpu_model = .{ .explicit = &std.Target.avr.cpu.atmega328p },
+ .os_tag = .freestanding,
+ .abi = .none,
+ };
+
+ const exe = b.addExecutable(.{
+ .name = "blink",
+ .root_source_file = b.path("blink.zig"),
+ .target = b.resolveTargetQuery(uno),
+ .optimize = .ReleaseSafe,
+ });
+
+ const init = b.addObject(.{
+ .name = "startup",
+ .root_source_file = b.path("init.zig"),
+ .target = b.resolveTargetQuery(uno),
+ .optimize = .ReleaseSafe
+ });
+
+ exe.addObject(init);
+ exe.setLinkerScriptPath(b.path("linker.ld"));
+
+ b.installArtifact(exe);
+
+ const tty = b.option(
+ []const u8,
+ "tty",
+ "Specify the port to which the Arduino is connected (defaults to /dev/ttyACM0)",
+ ) orelse "/dev/ttyACM0";
+
+ const bin_path = b.getInstallPath(.{ .custom = exe.installed_path orelse "./bin" }, exe.out_filename);
+
+ const flash_command = blk: {
+ var tmp = std.ArrayList(u8).init(b.allocator);
+ try tmp.appendSlice("-Uflash:w:");
+ try tmp.appendSlice(bin_path);
+ try tmp.appendSlice(":e");
+ break :blk try tmp.toOwnedSlice();
+ };
+
+ const upload = b.step("upload", "Upload the code to an Arduino device using avrdude");
+ const avrdude = b.addSystemCommand(&.{
+ "avrdude",
+ "-carduino",
+ "-patmega328p",
+ "-D",
+ "-P",
+ tty,
+ flash_command,
+ });
+ upload.dependOn(&avrdude.step);
+ avrdude.step.dependOn(&exe.step);
+
+ const objdump = b.step("objdump", "Show dissassembly of the code using avr-objdump");
+ const avr_objdump = b.addSystemCommand(&.{
+ "avr-objdump",
+ "-dh",
+ bin_path,
+ });
+ objdump.dependOn(&avr_objdump.step);
+ avr_objdump.step.dependOn(&exe.step);
+
+ const monitor = b.step("monitor", "Opens a monitor to the serial output");
+ const screen = b.addSystemCommand(&.{
+ "screen",
+ tty,
+ "115200",
+ });
+ monitor.dependOn(&screen.step);
+
+ b.default_step.dependOn(&exe.step);
+}
diff --git a/init.zig b/init.zig
new file mode 100644
index 0000000..be0bd10
--- /dev/null
+++ b/init.zig
@@ -0,0 +1,27 @@
+pub export fn _start() linksection(".vectors") callconv(.Naked) void {
+ asm volatile (
+ \\ rjmp reset ; jump to reset
+ \\ rjmp ext_int0
+ );
+}
+
+pub export const end_of_ram: u16 = 0x8FF;
+pub export fn reset() linksection(".vectors") callconv(.Naked) void {
+ asm volatile (
+ \\ sei
+ \\ rjmp main
+ );
+ // asm volatile (
+ // \\ ldi r16, hi8(%[ramend])
+ // \\ sts 0x3E, r16
+ // \\ ldi r16, lo8(%[ramend])
+ // \\ sts 0X3D, r16
+ // \\ sei
+ // \\ jmp main
+ // :
+ // : [ramend] "i" (end_of_ram)
+ // : "r16"
+ // );
+}
+
+pub export fn ext_int0() void {}
diff --git a/linker.ld b/linker.ld
new file mode 100644
index 0000000..ef5e46b
--- /dev/null
+++ b/linker.ld
@@ -0,0 +1,33 @@
+MEMORY
+{
+ flash (rx) : ORIGIN = 0, LENGTH = 32K
+ ram (rw!x) : ORIGIN = 0x100, LENGTH = 2K
+}
+
+SECTIONS
+{
+ .text :
+ {
+ KEEP(*(.vectors))
+
+ *(.text*)
+ } > flash
+
+ .data :
+ {
+ __data_start = .;
+ *(.rodata*)
+ *(.data*)
+ __data_end = .;
+ } > ram AT> flash
+
+ .bss (NOLOAD) :
+ {
+ __bss_start = .;
+ *(.bss*)
+ __bss_end = .;
+ } > ram
+ RAMEND = ORIGIN(ram) + LENGTH(ram);
+
+ __data_load_start = LOADADDR(.data);
+}