diff --git a/README.md b/README.md index 6714f93..ec100a2 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,7 @@ ## Getting Started -Temporarily this repo targets the `zig-master` branch of -[MicroZig](https://github.com/ZigEmbeddedGroup/microzig). In order to build this -repo, you must have it checked out, and `microzig` next to `sycl-badge-2024` in -your filesystem. Once this branch is merged it won't be as janky to build this -firmware. - +Check out the [Introduction](docs/introduction/README.md)! ## Uploading firmware using a debugger diff --git a/build.zig b/build.zig index fe5ae08..4996d3b 100644 --- a/build.zig +++ b/build.zig @@ -46,13 +46,17 @@ pub fn build(b: *Build) void { watch.linkFramework("CoreServices"); } + b.getInstallStep().dependOn(&b.addInstallArtifact(watch, .{ + .dest_dir = .disabled, + }).step); + var dep: std.Build.Dependency = .{ .builder = b }; const feature_test_cart = add_cart(&dep, b, .{ .name = "feature_test", .optimize = .ReleaseSmall, .root_source_file = .{ .path = "samples/feature_test.zig" }, }); - feature_test_cart.install(b); + const watch_run_step = feature_test_cart.install_with_watcher(&dep, b); const zeroman_cart = add_cart(&dep, b, .{ .name = "zeroman", @@ -61,13 +65,9 @@ pub fn build(b: *Build) void { }); add_zeroman_assets_step(b, zeroman_cart); zeroman_cart.install(b); - // - // TODO: parameterize: - const watch_run = b.addRunArtifact(watch); - watch_run.addArgs(&.{ "serve", b.graph.zig_exe, "--input-dir", b.pathFromRoot("samples"), "--cart", b.pathFromRoot("zig-out/bin/feature_test.wasm") }); const watch_step = b.step("watch", ""); - watch_step.dependOn(&watch_run.step); + watch_step.dependOn(&watch_run_step.step); const badge = mz.add_firmware(b, .{ .name = "badge", @@ -128,12 +128,25 @@ pub const Cart = struct { cart_lib: *Build.Step.Compile, options: CartOptions, - //watch_run_cmd: *std.Build.Step.Run, pub fn install(c: *const Cart, b: *Build) void { c.mz.install_firmware(b, c.fw, .{ .format = .{ .uf2 = .SAMD51 } }); b.installArtifact(c.wasm); } + + pub fn install_with_watcher(c: *const Cart, d: *Build.Dependency, b: *Build) *Build.Step.Run { + c.mz.install_firmware(b, c.fw, .{ .format = .{ .uf2 = .SAMD51 } }); + const install_artifact_step = b.addInstallArtifact(c.wasm, .{}); + b.getInstallStep().dependOn(&install_artifact_step.step); + + const watch_run = b.addRunArtifact(d.artifact("watch")); + // watch_run.addArgs(&.{ "serve", b.graph.zig_exe, "--input-dir", b.pathFromRoot(std.fs.path.dirname(options.root_source_file) orelse ""), "--cart", b.pathFromRoot("zig-out/bin/feature_test.wasm") }); + watch_run.addArgs(&.{ "serve", b.graph.zig_exe, "--input-dir" }); + watch_run.addFileArg(c.options.root_source_file.dirname()); + watch_run.addArgs(&.{ "--cart", b.getInstallPath(install_artifact_step.dest_dir.?, install_artifact_step.dest_sub_path) }); + + return watch_run; + } }; pub const CartOptions = struct { diff --git a/docs/introduction/README.md b/docs/introduction/README.md new file mode 100644 index 0000000..6440990 --- /dev/null +++ b/docs/introduction/README.md @@ -0,0 +1,17 @@ +# Introduction + +This guide will help you get up and running with the badge and fittingly help introduce you to other attendees. + +## Running + +## On the simulator + +The simulator is ideal for fast iteration as it supports live reloading. + +Run `zig build watch` and head to https://badgesim.microzig.tech/. + +## On hardware + +Once you're happy with what you've made, you'll need to flash it onto your badge! + +TODO diff --git a/docs/introduction/build.zig b/docs/introduction/build.zig new file mode 100644 index 0000000..501cb90 --- /dev/null +++ b/docs/introduction/build.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const badge = @import("sycl-badge"); + +pub fn build(b: *std.Build) void { + const dep = b.dependency("sycl-badge", .{}); + const feature_test_cart = badge.add_cart(dep, b, .{ + .name = "hello", + .optimize = .ReleaseSmall, + .root_source_file = .{ .path = "hello.zig" }, + }); + const watch_run_step = feature_test_cart.install_with_watcher(dep, b); + + const watch_step = b.step("watch", ""); + watch_step.dependOn(&watch_run_step.step); +} diff --git a/docs/introduction/build.zig.zon b/docs/introduction/build.zig.zon new file mode 100644 index 0000000..63fb3fa --- /dev/null +++ b/docs/introduction/build.zig.zon @@ -0,0 +1,14 @@ +.{ + .name = "sycl-badge-introduction", + .version = "0.0.0", + .paths = .{ + "hello.zig", + "build.zig", + }, + + .dependencies = .{ + .@"sycl-badge" = .{ + .path = "../..", + }, + }, +} diff --git a/docs/introduction/hello.zig b/docs/introduction/hello.zig new file mode 100644 index 0000000..b6b49c0 --- /dev/null +++ b/docs/introduction/hello.zig @@ -0,0 +1,10 @@ +const cart = @import("cart-api"); + +export fn update() void { + // Set background to a nice gray + @memset(cart.framebuffer, cart.DisplayColor{ + .red = 10, + .green = 20, + .blue = 10, + }); +} diff --git a/samples/feature_test.zig b/samples/feature_test.zig index 0d56b3c..8822b03 100644 --- a/samples/feature_test.zig +++ b/samples/feature_test.zig @@ -82,8 +82,6 @@ export fn update() void { }; } - // TODO: blit, blitSub - cart.blit(.{ .sprite = &.{ .{ .red = 31, .green = 0, .blue = 0 }, diff --git a/src/cart/api.zig b/src/cart/api.zig index 4f1b778..85632fc 100644 --- a/src/cart/api.zig +++ b/src/cart/api.zig @@ -22,14 +22,22 @@ const base = if (builtin.target.isWasm()) 0 else 0x20000000; pub const NeopixelColor = packed struct(u24) { blue: u8, green: u8, red: u8 }; /// RGB565, high color -pub const DisplayColor = packed struct(u16) { blue: u5, green: u6, red: u5 }; -const OptionalDisplayColor = enum(i32) { - none = -1, - _, - - inline fn from(color: ?DisplayColor) OptionalDisplayColor { - return if (color) |c| @enumFromInt(@as(u16, @bitCast(c))) else .none; - } +pub const DisplayColor = packed struct(u16) { + /// 0-31 + blue: u5, + /// 0-63 + green: u6, + /// 0-31 + red: u5, + + const Optional = enum(i32) { + none = -1, + _, + + inline fn from(color: ?DisplayColor) Optional { + return if (color) |c| @enumFromInt(@as(u16, @bitCast(c))) else .none; + } + }; }; pub const Controls = packed struct { @@ -71,9 +79,9 @@ const platform_specific = if (builtin.target.isWasm()) struct { extern fn blit(sprite: [*]const DisplayColor, x: i32, y: i32, width: u32, height: u32, src_x: u32, src_y: u32, stride: u32, flags: BlitOptions.Flags) void; extern fn line(color: DisplayColor, x1: i32, y1: i32, x2: i32, y2: i32) void; - extern fn oval(stroke_color: OptionalDisplayColor, fill_color: OptionalDisplayColor, x: i32, y: i32, width: u32, height: u32) void; - extern fn rect(stroke_color: OptionalDisplayColor, fill_color: OptionalDisplayColor, x: i32, y: i32, width: u32, height: u32) void; - extern fn text(text_color: DisplayColor, background_color: OptionalDisplayColor, str_ptr: [*]const u8, str_len: usize, x: i32, y: i32) void; + extern fn oval(stroke_color: DisplayColor.Optional, fill_color: DisplayColor.Optional, x: i32, y: i32, width: u32, height: u32) void; + extern fn rect(stroke_color: DisplayColor.Optional, fill_color: DisplayColor.Optional, x: i32, y: i32, width: u32, height: u32) void; + extern fn text(text_color: DisplayColor, background_color: DisplayColor.Optional, str_ptr: [*]const u8, str_len: usize, x: i32, y: i32) void; extern fn vline(color: DisplayColor, x: i32, y: i32, len: u32) void; extern fn hline(color: DisplayColor, x: i32, y: i32, len: u32) void; extern fn tone(frequency: u32, duration: u32, volume: u32, flags: ToneOptions.Flags) void; @@ -130,7 +138,6 @@ pub inline fn blit(options: BlitOptions) void { options.flags, ); } else { - @compileError("TODO"); // const rest: extern struct { // width: u32, // height: u32, @@ -188,8 +195,8 @@ pub const OvalOptions = struct { pub inline fn oval(options: OvalOptions) void { if (comptime builtin.target.isWasm()) { platform_specific.oval( - OptionalDisplayColor.from(options.stroke_color), - OptionalDisplayColor.from(options.fill_color), + DisplayColor.Optional.from(options.stroke_color), + DisplayColor.Optional.from(options.fill_color), options.x, options.y, options.width, @@ -220,8 +227,8 @@ pub const RectOptions = struct { pub inline fn rect(options: RectOptions) void { if (comptime builtin.target.isWasm()) { platform_specific.rect( - OptionalDisplayColor.from(options.stroke_color), - OptionalDisplayColor.from(options.fill_color), + DisplayColor.Optional.from(options.stroke_color), + DisplayColor.Optional.from(options.fill_color), options.x, options.y, options.width, @@ -252,7 +259,7 @@ pub inline fn text(options: TextOptions) void { if (comptime builtin.target.isWasm()) { platform_specific.text( options.text_color, - OptionalDisplayColor.from(options.background_color), + DisplayColor.Optional.from(options.background_color), options.str.ptr, options.str.len, options.x,