Skip to content

Conversation

@samy-00007
Copy link

@samy-00007 samy-00007 commented Jan 10, 2026

This PR add support for NXP mcxn947 chip (mcxnx4x in theory, but only tested on mcxn947).

Please note that this is essentially my first time doing embedded. Also, I did not check much on other ports for conventions since I did not know if I would do a PR.

There is also a bunch of TODOs in the code.

What is included:

  • a minor fix to Target.derive (it initially did not copy all the settings and used the default value for many, it seems to be fixed on main now though)
  • syscon functions to release / assert a module's reset and enable / disable its clock
  • basic Port and GPIO type (mostly taken from mcxa's port)
  • Pin and FlexComm type for configuration
  • LP_FlexComm Uart implementation:
    • support for 7 and 8 bit (9 and 10 should just require small changes to the read and write functions)
    • Io.Reader and Io.Writer interfaces
    • polling only
  • LP_FlexComm I2C implementation:
    • controller (master) mode only
    • standard mode only
    • I2C_Device interface
    • 7 bit addressing only, no support for match and other things
    • polling only
  • A few board-specific functions like a debug console (similar to the official SDK) and an example panic handler

I could not make the default linker script to work. I believe the issue comes from where the end of the stack is.

And I have no idea how to handle the second cpu core.

Edit: I have severely underestimated the number of TODOs I had left ...

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

🔍 Lint Results

Found 52 issues on changed lines in 9 files:

  • port/nxp/mcx/build.zig: 5 issues
  • port/nxp/mcx/src/boards/frdm_mcxn947.zig: 2 issues
  • port/nxp/mcx/src/mcxn947/hal/flexcomm.zig: 3 issues
  • port/nxp/mcx/src/mcxn947/hal/flexcomm/LPI2c.zig: 20 issues
  • port/nxp/mcx/src/mcxn947/hal/flexcomm/LPUart.zig: 15 issues
  • port/nxp/mcx/src/mcxn947/hal/gpio.zig: 1 issue
  • port/nxp/mcx/src/mcxn947/hal/pin.zig: 2 issues
  • port/nxp/mcx/src/mcxn947/hal/port.zig: 2 issues
  • port/nxp/mcx/src/mcxn947/hal/syscon.zig: 2 issues
ℹ️ Additional issues on unchanged lines
The following 2 issue(s) exist but are not on lines changed in this PR:

build-internals/build.zig:115: Suggestion: Rename `Cpu` to `CPU`, it _should_ be more in line with our [style guidelines](https://microzig.tech/docs/contributing/). This automation is not perfect so take it with a grain of salt.
core/src/mmio.zig:14: Suggestion: Rename `IntT` to `Int_T`, it _should_ be more in line with our [style guidelines](https://microzig.tech/docs/contributing/). This automation is not perfect so take it with a grain of salt.

.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.

.register_definition = .{ .svd = mcux_soc_svd.path("MCXN947/MCXN947_cm33_core0.xml") },
.memory_regions = &.{
// TODO: not sure about the accesses
// 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.

.memory_regions = &.{
// TODO: not sure about the accesses
// TODO: ROM
// 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 = .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.

/// Locking a pin prevent its config to be changed until the next system reset.
///
/// Not all config options are available for all pins (this function currently do no checks).
// TODO: check if features are available for a given pin

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.

///
/// Not all port have 32 pins available (this function currently do no checks).
pub fn get_gpio(port: Port, pin: u5) gpio.GPIO {
// TODO: check unavailable pins

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.

///
/// Not all port have 32 pins available (this function currently do no checks).
pub fn get_pin(port: Port, pin: u5) Pin {
// TODO: check unavailable pins

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.


// This enum can be automatically generated using `generate.zig`,
// but some fields have been manually added for conveniance (e.g. PORT5, GPIO5)
// TODO: some fields are probably missing, add them

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.

// This enum can be automatically generated using `generate.zig`,
// but some fields have been manually added for conveniance (e.g. PORT5, GPIO5)
// TODO: some fields are probably missing, add them
// TODO: use u8

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.

Copy link
Contributor

@mattnite mattnite left a comment

Choose a reason for hiding this comment

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

Great work for your first go at this!

For the linter comments, ignore the ones regarding TODOs, but please fix the ones for naming conventions.

The other thing I need from this PR, is examples, we don't have a HIL yet for this stuff, but by having examples we at least guard your work from bit rot. So please try to make some that show usage of your HAL. Examples have a similar structure to ports, under the examples directory in the root of the project.

@github-actions github-actions bot dismissed their stale review January 15, 2026 18:14

Updating with new lint results

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

🔍 Lint Results

Found 9 issues on changed lines in 4 files:

  • port/nxp/mcx/src/boards/frdm_mcxn947.zig: 1 issue
  • port/nxp/mcx/src/mcxn947/hal/flexcomm.zig: 2 issues
  • port/nxp/mcx/src/mcxn947/hal/flexcomm/LPI2c.zig: 3 issues
  • port/nxp/mcx/src/mcxn947/hal/flexcomm/LPUart.zig: 3 issues

/// pub const panic = board.panic;
/// ```
pub const panic = std.debug.FullPanic(struct {
pub fn panicFn(message: []const u8, first_trace_address: ?usize) noreturn {

Choose a reason for hiding this comment

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

Please change to panic_fn, in MicroZig we use snake case for function names.

pub const FlexComm = enum(u4) {
_,

pub const LPUart = @import("flexcomm/LPUart.zig").LPUart;

Choose a reason for hiding this comment

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

Suggestion: Rename LPUart to LP_UART, it should be more in line with our style guidelines. This automation is not perfect so take it with a grain of salt.

_,

pub const LPUart = @import("flexcomm/LPUart.zig").LPUart;
pub const LPI2c = @import("flexcomm/LPI2c.zig").LPI2c;

Choose a reason for hiding this comment

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

Suggestion: Rename LPI2c to LPI_2c, it should be more in line with our style guidelines. This automation is not perfect so take it with a grain of salt.

// TODO: 10 bit addressing
// TODO: better receive (with matching)
// TODO: SMBus
pub const LPI2c = enum(u4) {

Choose a reason for hiding this comment

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

Suggestion: Rename LPI2c to LPI_2c, it should be more in line with our style guidelines. This automation is not perfect so take it with a grain of salt.

pub const LPI2c = enum(u4) {
_,

pub const LPI2cTy = *volatile chip.types.peripherals.LPI2C0;

Choose a reason for hiding this comment

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

Suggestion: Rename LPI2cTy to LPI_2cTy, it should be more in line with our style guidelines. This automation is not perfect so take it with a grain of salt.



// Follows the linux kernel's approach
pub const I2cMsg = struct {

Choose a reason for hiding this comment

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

Suggestion: Rename I2cMsg to I2C_Msg, it should be more in line with our style guidelines. This automation is not perfect so take it with a grain of salt.


const chip = microzig.chip;
const peripherals = chip.peripherals;
const Io = std.Io;

Choose a reason for hiding this comment

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

Suggestion: Rename Io to IO, it should be more in line with our style guidelines. This automation is not perfect so take it with a grain of salt.


/// Uart interface. Currently only support 8 bit mode.
// TODO: 9 and 10 bit mode
pub const LPUart = enum(u4) {

Choose a reason for hiding this comment

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

Suggestion: Rename LPUart to LP_UART, it should be more in line with our style guidelines. This automation is not perfect so take it with a grain of salt.

pub const LPUart = enum(u4) {
_,

pub const LPUartTy = *volatile chip.types.peripherals.LPUART0;

Choose a reason for hiding this comment

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

Suggestion: Rename LPUartTy to LP_UART_Ty, it should be more in line with our style guidelines. This automation is not perfect so take it with a grain of salt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants