Skip to content
2 changes: 2 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const port_list: []const struct {
.{ .name = "rp2xxx", .dep_name = "port/raspberrypi/rp2xxx" },
.{ .name = "stm32", .dep_name = "port/stmicro/stm32" },
.{ .name = "ch32v", .dep_name = "port/wch/ch32v" },
.{ .name = "ch32h", .dep_name = "port/wch/ch32h" },
.{ .name = "msp430", .dep_name = "port/texasinstruments/msp430" },
.{ .name = "mspm0", .dep_name = "port/texasinstruments/mspm0" },
.{ .name = "tm4c", .dep_name = "port/texasinstruments/tm4c" },
Expand Down Expand Up @@ -70,6 +71,7 @@ pub const PortSelect = struct {
rp2xxx: bool = false,
stm32: bool = false,
ch32v: bool = false,
ch32h: bool = false,
msp430: bool = false,
mspm0: bool = false,
tm4c: bool = false,
Expand Down
1 change: 1 addition & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
.@"port/texasinstruments/mspm0" = .{ .path = "port/texasinstruments/mspm0", .lazy = true },
.@"port/texasinstruments/tm4c" = .{ .path = "port/texasinstruments/tm4c", .lazy = true },
.@"port/wch/ch32v" = .{ .path = "port/wch/ch32v", .lazy = true },
.@"port/wch/ch32h" = .{ .path = "port/wch/ch32h", .lazy = true },

.@"modules/riscv32-common" = .{ .path = "modules/riscv32-common" },
.@"modules/rtt" = .{ .path = "modules/rtt" },
Expand Down
44 changes: 44 additions & 0 deletions examples/wch/ch32h/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const std = @import("std");
const microzig = @import("microzig");

const MicroBuild = microzig.MicroBuild(.{
.ch32h = true,
});

fn add_example(b: *std.Build, mb: anytype, comptime name: []const u8, optimize: std.builtin.OptimizeMode) void {
const v3f = mb.add_firmware(.{
.name = "v3f",
.root_source_file = b.path("src/" ++ name ++ "_v3f.zig"),
.optimize = optimize,
.target = mb.ports.ch32h.chips.ch32h417_v3f,
});

const v5f = mb.add_firmware(.{
.name = "v5f",
.root_source_file = b.path("src/" ++ name ++ "_v5f.zig"),
.optimize = optimize,
.target = mb.ports.ch32h.chips.ch32h417_v5f,
});

const merged_bin = mb.ports.ch32h.merge(b, v3f.get_emitted_elf(), v5f.get_emitted_elf(), name ++ "_merged.bin");

const install = b.addInstallFileWithDir(merged_bin, .{ .custom = "firmware" }, name ++ ".bin");
b.getInstallStep().dependOn(&install.step);
}

const examples = [_][]const u8{
"blinky",
"interrupts",
"systick",
};

pub fn build(b: *std.Build) void {
const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .small });

const mz_dep = b.dependency("microzig", .{});
const mb = MicroBuild.init(b, mz_dep) orelse return;

inline for (examples) |example| {
add_example(b, mb, example, optimize);
}
}
14 changes: 14 additions & 0 deletions examples/wch/ch32h/build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.{
.name = .examples_wch_ch32h,
.fingerprint = 0x98c6b66930eca2b,
.version = "0.0.0",
.dependencies = .{
.microzig = .{ .path = "../../.." },
},

.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}
40 changes: 40 additions & 0 deletions examples/wch/ch32h/src/blinky_v3f.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const microzig = @import("microzig");

pub const panic = microzig.panic;

pub const std_options = microzig.std_options(.{});

comptime {
_ = microzig.export_startup();
}

const cpu = microzig.cpu;
const clock = microzig.hal.clock;
const gpio = microzig.hal.gpio;

const PFIC = microzig.chip.peripherals.PFIC;

fn delay(cycles: u32) void {
for (0..cycles) |_| {
asm volatile ("nop");
}
}

pub fn main() !void {
clock.init();
clock.enable_gpio(.c);

const pc2: gpio.Pin = .{ .port = .c, .number = 2 };
pc2.apply(.{
.mode = .{ .output = .general_purpose_open_drain },
.speed = .max_50MHz,
.pull = .disabled,
});

cpu.wakeup_v5f();

while (true) {
pc2.toggle();
delay(20_000_000);
}
}
34 changes: 34 additions & 0 deletions examples/wch/ch32h/src/blinky_v5f.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const microzig = @import("microzig");

pub const panic = microzig.panic;

pub const std_options = microzig.std_options(.{});

comptime {
_ = microzig.export_startup();
}

const gpio = microzig.hal.gpio;
const clock = microzig.hal.clock;

fn delay(cycles: u32) void {
for (0..cycles) |_| {
asm volatile ("nop");
}
}

pub fn main() !void {
const pc3: gpio.Pin = .{ .port = .c, .number = 3 };
pc3.apply(.{
.mode = .{ .output = .general_purpose_open_drain },
.speed = .max_50MHz,
.pull = .disabled,
});

while (true) {
pc3.put(1);
delay(120_000_000);
pc3.put(0);
delay(120_000_000);
}
}
56 changes: 56 additions & 0 deletions examples/wch/ch32h/src/interrupts_v3f.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const microzig = @import("microzig");

pub const panic = microzig.panic;

pub const std_options = microzig.std_options(.{});

comptime {
_ = microzig.export_startup();
}

const cpu = microzig.cpu;
const clock = microzig.hal.clock;
const gpio = microzig.hal.gpio;

const PFIC = microzig.chip.peripherals.PFIC;

pub const microzig_options: microzig.Options = .{
.interrupts = .{ .SW = sw_handler },
};

const pc2: gpio.Pin = .{ .port = .c, .number = 2 };

fn sw_handler() callconv(cpu.riscv_calling_convention) void {
cpu.interrupt.clear_pending(.SW);

pc2.toggle();
}

fn delay(cycles: u32) void {
for (0..cycles) |_| {
asm volatile ("nop");
}
}

pub fn main() !void {
clock.init();
clock.enable_gpio(.c);

pc2.apply(.{
.mode = .{ .output = .general_purpose_open_drain },
.speed = .max_50MHz,
.pull = .disabled,
});

cpu.interrupt.enable(.SW);

if (cpu.current_core() != .v3f)
@panic("unexpected current core");

cpu.wakeup_v5f();

while (true) {
cpu.interrupt.set_pending(.SW);
delay(20_000_000);
}
}
36 changes: 36 additions & 0 deletions examples/wch/ch32h/src/interrupts_v5f.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const microzig = @import("microzig");

pub const panic = microzig.panic;

pub const std_options = microzig.std_options(.{});

comptime {
_ = microzig.export_startup();
}

const cpu = microzig.cpu;
const gpio = microzig.hal.gpio;
const clock = microzig.hal.clock;

fn delay(cycles: u32) void {
for (0..cycles) |_| {
asm volatile ("nop");
}
}

pub fn main() !void {
if (cpu.current_core() != .v5f)
@panic("unexpected current core");

const pc3 = gpio.Pin{ .port = .c, .number = 2 };
pc3.apply(.{
.mode = .{ .output = .general_purpose_open_drain },
.speed = .max_50MHz,
.pull = .disabled,
});

while (true) {
pc3.toggle();
delay(120_000_000);
}
}
58 changes: 58 additions & 0 deletions examples/wch/ch32h/src/systick_v3f.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const microzig = @import("microzig");

pub const panic = microzig.panic;

pub const std_options = microzig.std_options(.{});

comptime {
_ = microzig.export_startup();
}

const cpu = microzig.cpu;
const clock = microzig.hal.clock;
const gpio = microzig.hal.gpio;
const time = microzig.hal.time;

const PFIC = microzig.chip.peripherals.PFIC;

pub const microzig_options: microzig.Options = .{
.interrupts = .{
.SysTick1 = systick_handler,
},
};

const pc2: gpio.Pin = .{ .port = .c, .number = 2 };

// By default, systick1 is allocated to v5f.
// Here we demonstrate how to change this!
const stk = time.systick1;

fn systick_handler() callconv(cpu.riscv_calling_convention) void {
stk.clear_pending();
pc2.toggle();
}

pub fn main() !void {
clock.init();
clock.enable_gpio(.c);

pc2.apply(.{
.mode = .{ .output = .general_purpose_open_drain },
.speed = .max_50MHz,
.pull = .disabled,
});

stk.apply(.{
.core = .v3f,
.mode = .up,
.clock_source = .hclk,
.auto_reload = true,
.compare_value = 100_000_000,
});
stk.enable_interrupt();
stk.enable();

cpu.wakeup_v5f();

while (true) {}
}
48 changes: 48 additions & 0 deletions examples/wch/ch32h/src/systick_v5f.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const microzig = @import("microzig");

pub const panic = microzig.panic;

pub const std_options = microzig.std_options(.{});

comptime {
_ = microzig.export_startup();
}

const cpu = microzig.cpu;
const gpio = microzig.hal.gpio;
const clock = microzig.hal.clock;
const time = microzig.hal.time;

pub const microzig_options: microzig.Options = .{
.interrupts = .{
.SysTick0 = systick_handler,
},
};

const pc3: gpio.Pin = .{ .port = .c, .number = 3 };
const stk = time.systick0;

fn systick_handler() callconv(cpu.riscv_calling_convention) void {
stk.clear_pending();
pc3.toggle();
}

pub fn main() !void {
pc3.apply(.{
.mode = .{ .output = .general_purpose_open_drain },
.speed = .max_50MHz,
.pull = .disabled,
});

stk.apply(.{
.core = .v5f,
.mode = .up,
.clock_source = .hclk,
.auto_reload = true,
.compare_value = 50_000_000,
});
stk.enable_interrupt();
stk.enable();

while (true) {}
}
Loading
Loading