Skip to content

Commit

Permalink
get pybadge building with zig-master branch of microzig
Browse files Browse the repository at this point in the history
  • Loading branch information
mattnite committed Mar 2, 2024
1 parent 18678c5 commit 7f0052c
Show file tree
Hide file tree
Showing 13 changed files with 331 additions and 304 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
zig-cache/
zig-out/
.DS_Store
31 changes: 25 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
# target extended-remote /dev/ttyACM{first}
# SYCL 2024 PCB Badge

# monitor swd_scan # searches for device
# attach 1
# file zig-out/firmware/pybadge-io.elf
#
## Getting Started

# $ sudo dfu-util -a 0 --dfuse-address 0x08000000:leave -R -D ~/Downloads/blackmagic-firmware-v1.10.0-rc1/blackpill-f401cc/blackmagic-blackpill-f401cc.bin ^C
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.


## Uploading firmware using a debugger

```
target extended-remote /dev/ttyACM{first}
monitor swd_scan # searches for device
attach 1
file zig-out/firmware/pybadge-io.elf
```

## Updating Black Magic Probe firmware

```
sudo dfu-util -a 0 --dfuse-address 0x08000000:leave -R -D ~/Downloads/blackmagic-firmware-v1.10.0-rc1/blackpill-f401cc/blackmagic-blackpill-f401cc.bin ^C
```
32 changes: 17 additions & 15 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
const atsam = @import("atsam");
const MicroZig = @import("microzig");
const std = @import("std");
const Build = std.Build;

const MicroZig = @import("microzig/build");
const atsam = @import("microzig/bsp/microchip/atsam");

pub const py_badge: MicroZig.Target = .{
.preferred_format = .elf,
.chip = atsam.chips.atsamd51j19,
.hal = null,
};

pub fn build(b: *std.Build) void {
const mz = MicroZig.init(b, "microzig");
pub fn build(b: *Build) void {
const mz = MicroZig.init(b, .{});
const optimize = b.standardOptimizeOption(.{});

const fw_options = b.addOptions();
Expand All @@ -25,16 +27,16 @@ pub fn build(b: *std.Build) void {
var modified_py_badge = py_badge;
modified_py_badge.chip.memory_regions = modified_memory_regions;

const fw = mz.addFirmware(b, .{
const fw = mz.add_firmware(b, .{
.name = "pybadge-io",
.target = modified_py_badge,
.optimize = optimize,
.source_file = .{ .path = "src/main.zig" },
});
fw.artifact.step.dependOn(&fw_options.step);
fw.modules.app.dependencies.put("options", fw_options.createModule()) catch @panic("out of memory");
mz.installFirmware(b, fw, .{});
mz.installFirmware(b, fw, .{ .format = .{ .uf2 = .SAMD51 } });
fw.modules.app.addImport("options", fw_options.createModule());
mz.install_firmware(b, fw, .{});
mz.install_firmware(b, fw, .{ .format = .{ .uf2 = .SAMD51 } });
}

pub const Cart = struct {
Expand All @@ -45,12 +47,12 @@ pub const Cart = struct {
pub const CartOptions = struct {
name: []const u8,
optimize: std.builtin.OptimizeMode,
source_file: std.Build.LazyPath,
source_file: Build.LazyPath,
};

pub fn addCart(
d: *std.Build.Dependency,
b: *std.Build,
pub fn add_cart(
d: *Build.Dependency,
b: *Build,
options: CartOptions,
) *Cart {
const cart_lib = b.addStaticLibrary(.{
Expand Down Expand Up @@ -85,7 +87,7 @@ pub fn addCart(
return cart;
}

pub fn installCart(b: *std.Build, cart: *Cart) void {
cart.mz.installFirmware(b, cart.fw, .{});
cart.mz.installFirmware(b, cart.fw, .{ .format = .{ .uf2 = .SAMD51 } });
pub fn install_cart(b: *Build, cart: *Cart) void {
cart.mz.install_firmware(b, cart.fw, .{});
cart.mz.install_firmware(b, cart.fw, .{ .format = .{ .uf2 = .SAMD51 } });
}
10 changes: 4 additions & 6 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@
},

.dependencies = .{
.microzig = .{
.url = "https://github.com/ZigEmbeddedGroup/microzig/archive/57e4379062e396b354d70d5b924d5da2e8905bd4.tar.gz",
.hash = "1220b8b04be6b97020eb19fca51b3cb44c33f5a619c3e36fc48faab8b15261dfff2a",
.@"microzig/build" = .{
.path = "../microzig/build",
},
.atsam = .{
.url = "https://github.com/ZigEmbeddedGroup/microchip-atsam/archive/93ddffbcbe7a0b849cca610ee933210280d731b4.tar.gz",
.hash = "12209a965a8aaf3a80b224fc3b796b7a21af86e3550373227db86615b6fa09b642cf",
.@"microzig/bsp/microchip/atsam" = .{
.path = "../microzig/bsp/microchip/atsam",
},
},
}
24 changes: 12 additions & 12 deletions src/Port.zig
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,27 @@ pub const Group = enum { A, B };
pub const Direction = enum { in, out };
pub const Level = enum { low, high };

pub inline fn setDir(port: Port, dir: Direction) void {
pub inline fn set_dir(port: Port, dir: Direction) void {
switch (dir) {
.in => port.groupPtr().DIRCLR.write(.{ .DIRCLR = @as(u32, 1) << port.pin }),
.out => port.groupPtr().DIRSET.write(.{ .DIRSET = @as(u32, 1) << port.pin }),
.in => port.group_ptr().DIRCLR.write(.{ .DIRCLR = @as(u32, 1) << port.pin }),
.out => port.group_ptr().DIRSET.write(.{ .DIRSET = @as(u32, 1) << port.pin }),
}
}

pub inline fn write(port: Port, level: Level) void {
switch (level) {
.low => port.groupPtr().OUTCLR.write(.{ .OUTCLR = @as(u32, 1) << port.pin }),
.high => port.groupPtr().OUTSET.write(.{ .OUTSET = @as(u32, 1) << port.pin }),
.low => port.group_ptr().OUTCLR.write(.{ .OUTCLR = @as(u32, 1) << port.pin }),
.high => port.group_ptr().OUTSET.write(.{ .OUTSET = @as(u32, 1) << port.pin }),
}
}

pub inline fn read(port: Port) Level {
return @enumFromInt(port.groupPtr().IN.read().IN >> port.pin & 1);
return @enumFromInt(port.group_ptr().IN.read().IN >> port.pin & 1);
}

pub const Mux = enum(u4) { A, B, C, D, E, F, G, H, I, J, K, L, M, N };
pub inline fn setMux(port: Port, mux: Mux) void {
const pmux = &port.groupPtr().PMUX[port.pin / 2];
pub inline fn set_mux(port: Port, mux: Mux) void {
const pmux = &port.group_ptr().PMUX[port.pin / 2];
switch (@as(u1, @truncate(port.pin))) {
0 => pmux.modify(.{ .PMUXE = .{
.value = @as(io_types.PORT.PORT_PMUX__PMUXE, @enumFromInt(@intFromEnum(mux))),
Expand All @@ -93,15 +93,15 @@ pub inline fn setMux(port: Port, mux: Mux) void {
.value = @as(io_types.PORT.PORT_PMUX__PMUXO, @enumFromInt(@intFromEnum(mux))),
} }),
}
port.configPtr().modify(.{ .PMUXEN = 1 });
port.config_ptr().modify(.{ .PMUXEN = 1 });
}

const PinCfg = @typeInfo(std.meta.FieldType(io_types.PORT.GROUP, .PINCFG)).Array.child;
pub inline fn configPtr(port: Port) *volatile PinCfg {
return &port.groupPtr().PINCFG[port.pin];
pub inline fn config_ptr(port: Port) *volatile PinCfg {
return &port.group_ptr().PINCFG[port.pin];
}

fn groupPtr(port: Port) *volatile io_types.PORT.GROUP {
fn group_ptr(port: Port) *volatile io_types.PORT.GROUP {
return &io.PORT.GROUP[@intFromEnum(port.group)];
}

Expand Down
28 changes: 14 additions & 14 deletions src/audio.zig
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ pub const Channel = struct {
pub fn init() void {
@setCold(true);

Port.A0.setDir(.out);
Port.AVCC.setDir(.in);
Port.SPKR_EN.setDir(.out);
Port.A0.set_dir(.out);
Port.AVCC.set_dir(.in);
Port.SPKR_EN.set_dir(.out);
Port.SPKR_EN.write(.low);

io.MCLK.APBDMASK.modify(.{ .DAC_ = 1 });
Expand All @@ -39,8 +39,8 @@ pub fn init() void {
});
io.DAC.CTRLA.write(.{ .SWRST = 1, .ENABLE = 0, .padding = 0 });
while (io.DAC.SYNCBUSY.read().SWRST != 0) {}
Port.A0.setMux(.B);
Port.AVCC.setMux(.B);
Port.A0.set_mux(.B);
Port.AVCC.set_mux(.B);
io.DAC.CTRLB.write(.{ .DIFF = 0, .REFSEL = .{ .value = .VREFPU }, .padding = 0 });
io.DAC.EVCTRL.write(.{
.STARTEI0 = 1,
Expand Down Expand Up @@ -208,16 +208,16 @@ pub fn init() void {
});
io.EVSYS.USER[EVSYS.USER.DAC_START0].write(.{ .CHANNEL = EVSYS.CHANNEL.AUDIO + 1, .padding = 0 });

dma.initAudio();
dma.init_audio();
while (io.DAC.STATUS.read().READY0 != 1) {}
Port.SPKR_EN.write(.high);
io.NVIC.ISER[32 / 32].write(.{ .SETENA = 1 << 32 % 32 });
}

pub fn mix() void {
pub fn mix() callconv(.C) void {
var local_channels = channels.*;
for (&sample_buffer[
(dma.getAudioPart() + sample_buffer.len - 1) % sample_buffer.len
(dma.get_audio_part() + sample_buffer.len - 1) % sample_buffer.len
]) |*out_sample| {
var sample: i32 = 0;
inline for (&local_channels) |*channel| {
Expand Down Expand Up @@ -262,18 +262,18 @@ pub fn mix() void {
out_sample.* = @intCast((sample >> 16) - std.math.minInt(i16));
}
channels.* = local_channels;
dma.ackAudio();
dma.ack_audio();
}

pub fn setChannel(channel: usize, state: Channel) void {
pub fn set_channel(channel: usize, state: Channel) void {
io.NVIC.ICER[32 / 32].write(.{ .CLRENA = 1 << 32 % 32 });
channels[channel] = state;
io.NVIC.ISER[32 / 32].write(.{ .SETENA = 1 << 32 % 32 });
}

pub fn playNote(channel: usize, note: Note) void {
pub fn play_note(channel: usize, note: Note) void {
const sample_rate: f32 = 44100.0;
setChannel(channel, .{
set_channel(channel, .{
.duty = 1 << 31,
.phase = 0,
.phase_step = @intFromFloat(0x1p32 / sample_rate * note.frequency + 0.5),
Expand All @@ -295,7 +295,7 @@ pub fn playNote(channel: usize, note: Note) void {
});
}

pub fn playSong(channels_notes: []const []const Note) void {
pub fn play_song(channels_notes: []const []const Note) void {
var time: f32 = 0.0;
var channels_note_index = [1]usize{0} ** channels.len;
var channels_note_start = [1]f32{0.0} ** channels.len;
Expand All @@ -317,7 +317,7 @@ pub fn playSong(channels_notes: []const []const Note) void {
if (note_index.* > notes.len) continue;
const note = notes[note_index.* - 1];
note_start.* = next_note_time;
playNote(channel_index, .{
play_note(channel_index, .{
.duration = @max(note.duration - 0.04, 0.0),
.frequency = note.frequency,
});
Expand Down
Loading

0 comments on commit 7f0052c

Please sign in to comment.