Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
27b9a30
fix: fixed Target.derive (forgot fields)
samy-00007 Dec 21, 2025
4e2a743
start of implementation for mcxn947
samy-00007 Dec 21, 2025
7f5ef58
progress on mcnx947
samy-00007 Dec 22, 2025
83d7bee
renaming variable, fix baudrate computation and adds Reader / Writer
samy-00007 Dec 23, 2025
1b37740
better Module and Peripheral representation for syscon
samy-00007 Dec 30, 2025
79f6463
better clock and pin control
samy-00007 Dec 30, 2025
1b489db
Added LPI2c
samy-00007 Dec 30, 2025
6776384
minor clock improvement
samy-00007 Dec 30, 2025
59fb634
lpi2c: added I2C_Device interface
samy-00007 Dec 30, 2025
c664f0b
lpi2c: added some options
samy-00007 Jan 2, 2026
8ea7d2f
minor refactor
samy-00007 Jan 9, 2026
2cd5149
better module system
samy-00007 Jan 9, 2026
9b8ac58
fix type
samy-00007 Jan 9, 2026
9018e08
docs: added documentation for mcxn947
samy-00007 Jan 10, 2026
57e9862
switch tabs to spaces
samy-00007 Jan 10, 2026
b442ae3
mcxn947: add script to generate `Module`
samy-00007 Jan 10, 2026
e3a75f9
minor fix
samy-00007 Jan 10, 2026
3225f1e
mcxn947: add board specific code
samy-00007 Jan 10, 2026
f1ecdf3
mcxn947: move `hal.zig` and doc comment changes
samy-00007 Jan 10, 2026
a2dcc83
fix Target.derive: update with upstream change
samy-00007 Jan 10, 2026
e91ed90
forgot some tabs
samy-00007 Jan 10, 2026
80280d3
fix naming convention issues
samy-00007 Jan 18, 2026
2ca6781
forgot to init port in doc example
samy-00007 Jan 18, 2026
de0b1a8
feat: add examples for nxp mcxn947
samy-00007 Jan 18, 2026
929302a
zig fmt
samy-00007 Jan 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 7 additions & 17 deletions build-internals/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -100,23 +100,13 @@ pub const Target = struct {
from.chip.copy(allocator);

const ret = from.dep.builder.allocator.create(Target) catch @panic("out of memory");
ret.* = .{
.dep = from.dep,
.preferred_binary_format = options.preferred_binary_format orelse from.preferred_binary_format,
.zig_target = options.zig_target orelse from.zig_target,
.cpu = options.cpu orelse from.cpu,
.chip = chip,
.single_threaded = options.single_threaded orelse from.single_threaded,
.bundle_compiler_rt = options.bundle_compiler_rt orelse from.bundle_compiler_rt,
.bundle_ubsan_rt = options.bundle_ubsan_rt orelse from.bundle_ubsan_rt,
.ram_image = options.ram_image orelse from.ram_image,
.hal = options.hal orelse from.hal,
.board = options.board orelse from.board,
.linker_script = options.linker_script orelse from.linker_script,
.stack = options.stack orelse from.stack,
.entry = options.entry orelse from.entry,
.patch_elf = options.patch_elf orelse from.patch_elf,
};
ret.* = from.*;

inline for (std.meta.fields(DeriveOptions)) |field| {
const value = @field(options, field.name);
if (value) |val| @field(ret, field.name) = val;
}
ret.chip = chip;
return ret;
}
};
Expand Down
2 changes: 1 addition & 1 deletion core/src/mmio.zig
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn Mmio(comptime PackedT: type) type {

/// Set field `field_name` of this register to `value`.
/// A one-field version of modify(), more helpful if `field_name` is comptime calculated.
pub inline fn modify_one(addr: *volatile Self, comptime field_name: []const u8, value: anytype) void {
pub inline fn modify_one(addr: *volatile Self, comptime field_name: []const u8, value: @FieldType(underlying_type, field_name)) void {
var val = read(addr);
@field(val, field_name) = value;
write(addr, val);
Expand Down
8 changes: 6 additions & 2 deletions examples/nxp/mcx/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ pub fn build(b: *std.Build) void {
const mb = MicroBuild.init(b, mz_dep) orelse return;

const frdm_mcxa153 = mb.ports.mcx.chips.mcxa153;
const frdm_mcxn947 = mb.ports.mcx.chips.mcxn947;

const available_examples = [_]Example{
.{ .name = "blinky", .target = frdm_mcxa153, .file = "src/blinky.zig" },
.{ .name = "mcxa153_blinky", .target = frdm_mcxa153, .file = "src/mcxa153_blinky.zig" },
.{ .name = "mcxn947_blinky", .target = frdm_mcxn947, .file = "src/mcxn947_blinky.zig" },
.{ .name = "gpio_input", .target = frdm_mcxa153, .file = "src/gpio_input.zig" },
.{ .name = "lp_uart", .target = frdm_mcxn947, .file = "src/lp_uart.zig" },
.{ .name = "lp_i2c", .target = frdm_mcxn947, .file = "src/lp_i2c.zig" },
};

for (available_examples) |example| {
Expand All @@ -25,7 +29,7 @@ pub fn build(b: *std.Build) void {
if (!std.mem.containsAtLeast(u8, example.name, 1, selected_example))
continue;

// `add_firmware` basically works like addExecutable, but takes a
// `add_firmware` basically works like addExe66.2.366.2.3cutable, but takes a
// `microzig.Target` for target instead of a `std.zig.CrossTarget`.
//
// The target will convey all necessary information on the chip,
Expand Down
52 changes: 52 additions & 0 deletions examples/nxp/mcx/src/lp_i2c.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const microzig = @import("microzig");
const hal = microzig.hal;

const Pin = hal.Pin;
const FlexComm = hal.FlexComm;
const LP_I2C = FlexComm.LP_I2C;

// Init the two pins required for uart on the flexcomm 4 interface:
// - pin 0 of port 1 corresponds to FC3_P0, which is SDA for I2C
// - pin 1 of port 1 corresponds to FC3_P0, which is SCL for I2C
//
// see section 66.2.3 of the reference manual and the chip's pinout for more details
fn init_lpi2c_pins() void {
// FC3_P0
Pin.num(1, 0).configure()
.alt(2)
.set_pull(.up)
.enable_input_buffer()
.done();
// FC3_P1
Pin.num(1, 1).configure()
.alt(2)
.set_pull(.up)
.enable_input_buffer()
.done();
}

pub fn main() !void {
hal.Port.num(1).init(); // we init port 1 to edit the pin's config
init_lpi2c_pins();

// Provide the interface with the 12MHz clock divided by 1
FlexComm.num(3).set_clock(.FRO_12MHz, 1);
const i2c: LP_I2C = try .init(3, .Default);

const data = &.{ 0xde, 0xad, 0xbe, 0xef };

// Low level write
try i2c.send_blocking(0x10, data);

// Recommended:
// Using microzig's I2C_Device interface to write
const i2c_device = i2c.i2c_device();
try i2c_device.write(@enumFromInt(0x10), data);

// and read
var buffer: [4]u8 = undefined;
_ = try i2c_device.read(@enumFromInt(0x10), &buffer);

// or do both
try i2c_device.write_then_read(@enumFromInt(0x10), data, &buffer);
}
47 changes: 47 additions & 0 deletions examples/nxp/mcx/src/lp_uart.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const microzig = @import("microzig");
const hal = microzig.hal;

const Pin = hal.Pin;
const FlexComm = hal.FlexComm;
const LP_UART = FlexComm.LP_UART;

// Init the two pins required for uart on the flexcomm 4 interface:
// - pin 8 of port 1 corresponds to FC4_P0, which is RXD for uart
// - pin 9 of port 1 corresponds to FC4_P0, which is TXD for uart
//
// see section 66.2.3 of the reference manual and the chip's pinout for more details
fn init_pins() void {
// FC4_P0
Pin.num(1, 8).configure()
.alt(2) // select the flexcomm 4 interface for the pin
.enable_input_buffer()
.done();
// FC4_P1
Pin.num(1, 9).configure()
.alt(2) // select the flexcomm 4 interface for the pin
.enable_input_buffer()
.done();
}

pub fn main() !void {
hal.Port.num(1).init(); // we init port 1 to edit the pin's config
init_pins();

// Provide the interface with the 12MHz clock divided by 1
FlexComm.num(4).set_clock(.FRO_12MHz, 1);
const uart: LP_UART = try .init(4, .Default);

uart.transmit("This is a message using the low level interface\n");
uart.transmit("Send a message: ");

// We can also use zig's Io interface to read
var buffer: [16]u8 = undefined;
var reader = uart.reader(&buffer);
// the delimiter can depend on the config of the sender
const message = try reader.interface.takeDelimiterExclusive('\n');
reader.interface.toss(1); // toss the delimiter

// And to write
var writer = uart.writer(&.{});
try writer.interface.print("Successfully received \"{s}\"\n", .{message});
}
21 changes: 21 additions & 0 deletions examples/nxp/mcx/src/mcxn947_blinky.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const microzig = @import("microzig");
const hal = microzig.hal;

const pin_led_red = hal.GPIO.num(3, 12);

pub fn main() void {
pin_led_red.init();
pin_led_red.set_direction(.out);
pin_led_red.put(1); // Turn off

while (true) {
pin_led_red.toggle();
delay_cycles(96_000_000 / 80);
}
}

fn delay_cycles(cycles: u32) void {
for (0..cycles) |_| {
asm volatile ("nop");
}
}
48 changes: 35 additions & 13 deletions port/nxp/mcx/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ const Self = @This();

chips: struct {
mcxa153: *const microzig.Target,
mcxn947: *const microzig.Target,
},

boards: struct {
frdm_mcxa153: *const microzig.Target,
frdm_mcxn947: *const microzig.Target,
},

pub fn init(dep: *std.Build.Dependency) Self {
Expand All @@ -33,22 +35,42 @@ pub fn init(dep: *std.Build.Dependency) Self {
.{ .tag = .ram, .offset = 0x20000000, .length = 24 * 1024, .access = .rw },
},
},
.hal = .{ .root_source_file = b.path("src/hal.zig") },
.hal = .{ .root_source_file = b.path("src/mcxa153/hal.zig") },
};

return .{
.chips = .{
.mcxa153 = chip_mcxa153.derive(.{}),
},
.boards = .{
.frdm_mcxa153 = chip_mcxa153.derive(.{
.board = .{
.name = "FRDM Development Board for MCX A153",
.url = "https://www.nxp.com/part/FRDM-MCXA153",
.root_source_file = b.path("src/boards/frdm_mcxa153.zig"),
},
}),
const chip_mcxn947: microzig.Target = .{
.dep = dep,
.preferred_binary_format = .elf,
.zig_target = .{ .cpu_arch = .thumb, .cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m33 }, .os_tag = .freestanding, .abi = .eabi },
.chip = .{
// TODO: handle other core

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO style comments need to have a linked microzig issue on the same line.

.name = "MCXN947_cm33_core0",
.register_definition = .{ .svd = mcux_soc_svd.path("MCXN947/MCXN947_cm33_core0.xml") },
.memory_regions = &.{
// TODO: not sure about the accesses

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO style comments need to have a linked microzig issue on the same line.

// TODO: ROM

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO style comments need to have a linked microzig issue on the same line.

// TODO: secure vs non-secure

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO style comments need to have a linked microzig issue on the same line.

.{ .tag = .flash, .offset = 0x00000000, .length = 2 * 1024 * 1024, .access = .rx },
// .{ .tag = .ram, .offset = 0x04000000, .length = 96 * 1024, .access = .rwx, .name = "RAMX" },
.{ .tag = .ram, .offset = 0x20000000, .length = 416 * 1024, .access = .rwx, .name = "RAMA-H" },
// .{ .tag = .ram, .offset = 0x13000000, .length = 256 * 1024, .access = .r, .name = "ROM" },
},
},
// TODO: not need that ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO style comments need to have a linked microzig issue on the same line.

.stack = .{ .symbol_name = "end_of_stack" },
.linker_script = .{ .generate = .none, .file = b.path("linker.ld") },
.hal = .{ .root_source_file = b.path("src/mcxn947/hal/hal.zig") },
};

return .{
.chips = .{ .mcxa153 = chip_mcxa153.derive(.{}), .mcxn947 = chip_mcxn947.derive(.{}) },
.boards = .{ .frdm_mcxa153 = chip_mcxa153.derive(.{
.board = .{
.name = "FRDM Development Board for MCX A153",
.url = "https://www.nxp.com/part/FRDM-MCXA153",
.root_source_file = b.path("src/boards/frdm_mcxa153.zig"),
},
}), .frdm_mcxn947 = chip_mcxn947.derive(.{ .board = .{ .name = "FRDM Development Board for MCX N947", .url = "https://www.nxp.com/part/FRDM-MCXN947", .root_source_file = b.path("src/boards/frdm_mcxn947.zig") } }) },
};
}

Expand Down
Loading
Loading