Skip to content

GPIO and UART basics for nRF52832 #558

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 16 additions & 4 deletions examples/nordic/nrf5x/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,27 @@ pub fn build(b: *std.Build) void {
const mz_dep = b.dependency("microzig", .{});
const mb = MicroBuild.init(b, mz_dep) orelse return;

const nrf52840_dongle = mb.ports.nrf5x.boards.nordic.nrf52840_dongle;
const nrf52840_mdk = mb.ports.nrf5x.boards.nordic.nrf52840_mdk;
const pca10040 = mb.ports.nrf5x.boards.nordic.pca10040;

const available_examples = [_]Example{
.{ .target = mb.ports.nrf5x.boards.nordic.nrf52840_dongle, .name = "nrf52480-dongle_blinky", .file = "src/blinky.zig" },
.{ .target = mb.ports.nrf5x.boards.nordic.nrf52840_mdk, .name = "nrf52480-mdk_blinky", .file = "src/blinky.zig" },
.{ .target = pca10040, .name = "blinky", .file = "src/blinky.zig" },
.{ .target = nrf52840_dongle, .name = "blinky", .file = "src/blinky.zig" },
.{ .target = nrf52840_mdk, .name = "blinky", .file = "src/blinky.zig" },
.{ .target = pca10040, .name = "uart", .file = "src/uart.zig" },
};

for (available_examples) |example| {
const target = example.target;
const name = mb.builder.fmt("{s}_{s}", .{
if (target.board) |board| board.name else target.chip.name,
example.name,
});

// If we specify example, only select the ones that match
if (maybe_example) |selected_example|
if (!std.mem.containsAtLeast(u8, example.name, 1, selected_example))
if (!std.mem.containsAtLeast(u8, name, 1, selected_example))
continue;

// `add_firmware` basically works like addExecutable, but takes a
Expand All @@ -29,7 +41,7 @@ pub fn build(b: *std.Build) void {
// The target will convey all necessary information on the chip,
// cpu and potentially the board as well.
const fw = mb.add_firmware(.{
.name = example.name,
.name = name,
.target = example.target,
.optimize = optimize,
.root_source_file = b.path(example.file),
Expand Down
2 changes: 1 addition & 1 deletion examples/nordic/nrf5x/src/blinky.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const board = microzig.board;
fn delay(cycles: u32) void {
var i: u32 = 0;
while (i < cycles) : (i += 1) {
asm volatile ("nop");
std.mem.doNotOptimizeAway(i);
}
}

Expand Down
30 changes: 30 additions & 0 deletions examples/nordic/nrf5x/src/uart.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const std = @import("std");
const microzig = @import("microzig");
const board = microzig.board;
const nrf = microzig.hal;

const uart = nrf.uart.num(0);

pub fn main() !void {
board.init();

uart.apply(.{
.tx_pin = board.uart_tx,
.rx_pin = board.uart_rx,
.control_flow = .{
.cts_pin = board.uart_cts,
.rts_pin = board.uart_rts,
},
.baud_rate = .@"115200",
});

nrf.uart.init_logger(uart);
std.log.info("Hello world, I will send back bytes you send me", .{});

// now echo any bytes sent
var buf: [1]u8 = undefined;
while (true) {
uart.read_blocking(&buf);
uart.write_blocking(buf[0..]);
}
}
4 changes: 1 addition & 3 deletions examples/nxp/lpc/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Examples for the Port `nxp-lpc`

- [Blinky](src/blinky.zig) on [nRF52840 Dongle](https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle)
TODO: Implement this!

- [Blinky](src/blinky.zig) on [mbed LPD1768](https://os.mbed.com/platforms/mbed-LPC1768/)
57 changes: 34 additions & 23 deletions port/nordic/nrf5x/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ const microzig = @import("microzig/build-internals");
const Self = @This();

chips: struct {
nrf52840: *const microzig.Target,
nrf52832: *const microzig.Target,
nrf52840: *const microzig.Target,
},

boards: struct {
nordic: struct {
nrf52840_dongle: *const microzig.Target,
nrf52840_mdk: *const microzig.Target,
pca10040: *const microzig.Target,
},
},

Expand All @@ -24,7 +25,7 @@ pub fn init(dep: *std.Build.Dependency) Self {
.root_source_file = b.path("src/hal.zig"),
};

const chip_nrf52840: microzig.Target = .{
const chip_nrf52832: microzig.Target = .{
.dep = dep,
.preferred_binary_format = .elf,
.zig_target = .{
Expand All @@ -34,27 +35,22 @@ pub fn init(dep: *std.Build.Dependency) Self {
.abi = .eabi,
},
.chip = .{
.name = "nrf52840",
.url = "https://www.nordicsemi.com/products/nrf52840",
.name = "nrf52",
.url = "https://www.nordicsemi.com/products/nrf52832",
.register_definition = .{
.svd = nrfx.path("mdk/nrf52840.svd"),
// TODO: does this determine the name of the chips/x.zig?
.svd = nrfx.path("mdk/nrf52.svd"),
},
.memory_regions = &.{
.{ .offset = 0x00000000, .length = 0x100000, .kind = .flash },
.{ .offset = 0x20000000, .length = 0x40000, .kind = .ram },

// EXTFLASH
.{ .offset = 0x12000000, .length = 0x8000000, .kind = .flash },

// CODE_RAM
.{ .offset = 0x800000, .length = 0x40000, .kind = .ram },
.{ .offset = 0x00000000, .length = 0x80000, .kind = .flash },
.{ .offset = 0x20000000, .length = 0x10000, .kind = .ram },
},
.patches = @import("patches/nrf52840.zig").patches,
.patches = @import("patches/nrf52832.zig").patches,
},
.hal = hal,
.hal = .{ .root_source_file = b.path("src/hal.zig") },
};

const chip_nrf52832: microzig.Target = .{
const chip_nrf52840: microzig.Target = .{
.dep = dep,
.preferred_binary_format = .elf,
.zig_target = .{
Expand All @@ -64,22 +60,30 @@ pub fn init(dep: *std.Build.Dependency) Self {
.abi = .eabi,
},
.chip = .{
.name = "nrf52",
.url = "https://www.nordicsemi.com/products/nrf52832",
.name = "nrf52840",
.url = "https://www.nordicsemi.com/products/nrf52840",
.register_definition = .{
.svd = nrfx.path("mdk/nrf52.svd"),
.svd = nrfx.path("mdk/nrf52840.svd"),
},
.memory_regions = &.{
.{ .offset = 0x00000000, .length = 0x80000, .kind = .flash },
.{ .offset = 0x20000000, .length = 0x10000, .kind = .ram },
.{ .offset = 0x00000000, .length = 0x100000, .kind = .flash },
.{ .offset = 0x20000000, .length = 0x40000, .kind = .ram },

// EXTFLASH
.{ .offset = 0x12000000, .length = 0x8000000, .kind = .flash },

// CODE_RAM
.{ .offset = 0x800000, .length = 0x40000, .kind = .ram },
},
.patches = @import("patches/nrf52840.zig").patches,
},
.hal = hal,
};

return .{
.chips = .{
.nrf52840 = chip_nrf52840.derive(.{}),
.nrf52832 = chip_nrf52832.derive(.{}),
.nrf52840 = chip_nrf52840.derive(.{}),
},
.boards = .{
.nordic = .{
Expand All @@ -93,10 +97,17 @@ pub fn init(dep: *std.Build.Dependency) Self {
.nrf52840_mdk = chip_nrf52840.derive(.{
.board = .{
.name = "nRF52840 MDK USB Dongle",
.url = "https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle/introduction/",
.url = "https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle",
.root_source_file = b.path("src/boards/nrf52840-mdk.zig"),
},
}),
.pca10040 = chip_nrf52832.derive(.{
.board = .{
.name = "PCA10040",
Copy link
Collaborator

Choose a reason for hiding this comment

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

why this name? Why not nRF52-DK?

.url = "https://www.nordicsemi.com/Products/Development-hardware/nRF52-DK",
.root_source_file = b.path("src/boards/pca10040.zig"),
},
}),
},
},
};
Expand Down
4 changes: 2 additions & 2 deletions port/nordic/nrf5x/build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
.dependencies = .{
.@"microzig/build-internals" = .{ .path = "../../../build-internals" },
.nrfx = .{
.url = "https://github.com/NordicSemiconductor/nrfx/archive/refs/tags/v3.9.0.tar.gz",
.hash = "N-V-__8AAL14nQqnG5u7x0tgCPSFD6MxfgtRMqGawtXN3C0S",
.url = "https://github.com/NordicSemiconductor/nrfx/archive/refs/tags/v3.11.0.tar.gz",
.hash = "N-V-__8AABC-kgxbmC3Prd8fgisfbLs1giU34ofX1vz9bwaA",
},
},
.paths = .{
Expand Down
39 changes: 39 additions & 0 deletions port/nordic/nrf5x/patches/nrf52832.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const Patch = @import("microzig/build-internals").Patch;
Copy link
Collaborator

Choose a reason for hiding this comment

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

(so far) we could use the same patch file as 52840


pub const patches: []const Patch = &.{
.{
.add_enum = .{
.parent = "types.peripherals.P0",
.@"enum" = .{
.name = "Pull",
.bitsize = 2,
.fields = &.{
.{ .value = 0x0, .name = "disabled" },
.{ .value = 0x1, .name = "down" },
.{ .value = 0x2, .name = "up" },
},
},
},
},
.{ .set_enum_type = .{ .of = "types.peripherals.P0.PIN_CNF.PULL", .to = "types.peripherals.P0.Pull" } },
.{
.add_enum = .{
.parent = "types.peripherals.P0",
.@"enum" = .{
.name = "DriveStrength",
.bitsize = 3,
.fields = &.{
.{ .value = 0x0, .name = "SOS1" },
.{ .value = 0x1, .name = "HOS1" },
.{ .value = 0x2, .name = "SOH1" },
.{ .value = 0x3, .name = "HOH1" },
.{ .value = 0x4, .name = "DOS1" },
.{ .value = 0x5, .name = "DOH1" },
.{ .value = 0x6, .name = "SOD1" },
.{ .value = 0x7, .name = "HOD1" },
},
},
},
},
.{ .set_enum_type = .{ .of = "types.peripherals.P0.PIN_CNF.DRIVE", .to = "types.peripherals.P0.DriveStrength" } },
};
39 changes: 39 additions & 0 deletions port/nordic/nrf5x/src/boards/pca10040.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const microzig = @import("microzig");
const nrf = microzig.hal;
const gpio = nrf.gpio;

pub const led_active_state = 0;
pub const button_active_state = 0;
pub const button_pull = .pullup;

pub const leds: []const gpio.Pin = &.{ led1, led2, led3, led4 };
pub const led1 = gpio.num(0, 17);
pub const led2 = gpio.num(0, 18);
pub const led3 = gpio.num(0, 19);
pub const led4 = gpio.num(0, 20);

pub const buttons: []const gpio.Pin = &.{ button1, button2, button3, button4 };
pub const button1 = gpio.num(0, 13);
pub const button2 = gpio.num(0, 14);
pub const button3 = gpio.num(0, 15);
pub const button4 = gpio.num(0, 16);

// UART
pub const uart_rts = gpio.num(0, 5);
pub const uart_tx = gpio.num(0, 6);
pub const uart_cts = gpio.num(0, 7);
pub const uart_rx = gpio.num(0, 8);
pub const hwfc = true;

pub fn init() void {
for (leds) |led|
led.set_direction(.out);

for (buttons) |button|
button.set_direction(.in);

uart_rx.set_direction(.in);
uart_cts.set_direction(.in);
uart_rts.set_direction(.out);
uart_tx.set_direction(.out);
}
6 changes: 5 additions & 1 deletion port/nordic/nrf5x/src/hal.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
const microzig = @import("microzig");

pub const compatibility = @import("hal/compatibility.zig");
pub const gpio = @import("hal/gpio.zig");
// TODO: uart, adc, timers, pwm, rng, rtc, spi, interrupts, i2c, wdt, wifi, nfc, bt, zigbee
pub const uart = @import("hal/uart.zig");
// TODO: adc, timers, pwm, rng, rtc, spi, interrupts, i2c, wdt, wifi, nfc, bt, zigbee

test "hal tests" {
_ = gpio;
Expand Down
4 changes: 4 additions & 0 deletions port/nordic/nrf5x/src/hal/chip.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub const Chip = enum {
nrf52,
nrf52840,
};
13 changes: 13 additions & 0 deletions port/nordic/nrf5x/src/hal/compatibility.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const std = @import("std");
const microzig = @import("microzig");
const Chip = @import("chip.zig").Chip;

pub const chip: Chip = blk: {
if (std.mem.eql(u8, microzig.config.chip_name, "nrf52")) {
break :blk .nrf52;
} else if (std.mem.eql(u8, microzig.config.chip_name, "nrf52840")) {
break :blk .nrf52840;
} else {
@compileError(std.fmt.comptimePrint("Unsupported chip for nRF52 HAL: \"{s}\"", .{microzig.config.chip_name}));
}
};
Loading
Loading