diff --git a/examples/raspberrypi/rp2xxx/build.zig b/examples/raspberrypi/rp2xxx/build.zig index 30aca2a77..ea3b8c876 100644 --- a/examples/raspberrypi/rp2xxx/build.zig +++ b/examples/raspberrypi/rp2xxx/build.zig @@ -18,7 +18,6 @@ pub fn build(b: *std.Build) void { // RaspberryPi Boards: .{ .target = raspberrypi.pico, .name = "pico_board_blinky", .file = "src/board_blinky.zig" }, .{ .target = raspberrypi.pico, .name = "pico_flash-program", .file = "src/rp2040_only/flash_program.zig" }, - .{ .target = raspberrypi.pico, .name = "pico_flash-id", .file = "src/rp2040_only/flash_id.zig" }, .{ .target = raspberrypi.pico, .name = "pico_random", .file = "src/rp2040_only/random.zig" }, .{ .target = raspberrypi.pico, .name = "pico_rtc", .file = "src/rp2040_only/rtc.zig" }, .{ .target = raspberrypi.pico, .name = "pico_multicore", .file = "src/blinky_core1.zig" }, @@ -103,6 +102,7 @@ pub fn build(b: *std.Build) void { .{ .name = "net-udp", .file = "src/net/udp.zig" }, .{ .name = "net-tcp_client", .file = "src/net/tcp_client.zig" }, .{ .name = "net-tcp_server", .file = "src/net/tcp_server.zig" }, + .{ .name = "board-id", .file = "src/board_id.zig" }, }; var available_examples: std.array_list.Managed(Example) = .init(b.allocator); diff --git a/examples/raspberrypi/rp2xxx/src/rp2040_only/flash_id.zig b/examples/raspberrypi/rp2xxx/src/board_id.zig similarity index 66% rename from examples/raspberrypi/rp2xxx/src/rp2040_only/flash_id.zig rename to examples/raspberrypi/rp2xxx/src/board_id.zig index 894a4b9e5..6581fcd70 100644 --- a/examples/raspberrypi/rp2xxx/src/rp2040_only/flash_id.zig +++ b/examples/raspberrypi/rp2xxx/src/board_id.zig @@ -4,7 +4,6 @@ const microzig = @import("microzig"); const rp2xxx = microzig.hal; const time = rp2xxx.time; const gpio = rp2xxx.gpio; -const flash = rp2xxx.flash; const uart = rp2xxx.uart.instance.num(0); const uart_tx_pin = gpio.num(0); @@ -15,10 +14,11 @@ pub fn panic(message: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noretu while (true) {} } -pub const std_options = struct { - pub const log_level = .debug; - pub const logFn = rp2xxx.uart.log; +pub const microzig_options = microzig.Options{ + .log_level = .debug, + .logFn = rp2xxx.uart.log, }; +const log = std.log.scoped(.main); pub fn main() !void { // init uart logging @@ -29,9 +29,7 @@ pub fn main() !void { rp2xxx.uart.init_logger(uart); while (true) { - const serial_number = flash.id(); - const hex_serial_number = std.fmt.bytesToHex(&serial_number, .lower); - std.log.info("serial number: {s}", .{hex_serial_number}); + log.info("unique board id: {x}", .{rp2xxx.get_board_id()}); time.sleep_ms(1000); } } diff --git a/port/raspberrypi/rp2xxx/src/hal.zig b/port/raspberrypi/rp2xxx/src/hal.zig index 853cdb94d..6e8389e11 100644 --- a/port/raspberrypi/rp2xxx/src/hal.zig +++ b/port/raspberrypi/rp2xxx/src/hal.zig @@ -1,5 +1,4 @@ const builtin = @import("builtin"); -const std = @import("std"); const microzig = @import("microzig"); const SIO = microzig.chip.peripherals.SIO; @@ -144,6 +143,24 @@ pub fn get_cpu_id() u32 { return SIO.CPUID.read().CPUID; } +var board_id: ?[8]u8 = null; + +/// Unique board identifier. +/// On an RP2040-based board, the unique identifier is retrieved from the +/// external NOR flash device +/// On an RP2350-based board, the unique identifier is retrieved from OTP +/// memory. +pub fn get_board_id() [8]u8 { + if (board_id) |b| { + return b; + } + board_id = switch (compatibility.chip) { + .RP2040 => flash.id(), + .RP2350 => rom.get_board_id(), + }; + return board_id.?; +} + test "hal tests" { _ = pio; _ = usb; diff --git a/port/raspberrypi/rp2xxx/src/hal/rom.zig b/port/raspberrypi/rp2xxx/src/hal/rom.zig index 3c25ca48f..48f5d7b28 100644 --- a/port/raspberrypi/rp2xxx/src/hal/rom.zig +++ b/port/raspberrypi/rp2xxx/src/hal/rom.zig @@ -6,11 +6,8 @@ //! that would otherwise have to take up space in most user binaries. const std = @import("std"); -const microzig = @import("microzig"); const compatibility = @import("compatibility.zig"); -const arch = compatibility.arch; const chip = compatibility.chip; -const options = microzig.options.hal; /// Returns the ROM version number. pub inline fn get_version_number() u8 { @@ -213,3 +210,24 @@ pub fn reset_to_usb_boot() void { }, } } + +pub fn get_sys_info(out_buffer: [*]u32, out_buffer_word_size: u32, flags: u32) void { + switch (chip) { + .RP2040 => @compileError("not supported on this chip"), + .RP2350 => { + const f: *const signatures.get_sys_info = @ptrCast(@alignCast(lookup_function(.get_sys_info))); + const rc = f(out_buffer, out_buffer_word_size, flags); + std.debug.assert(rc == 4); + }, + } +} + +pub fn get_board_id() [8]u8 { + var out: [9]u32 = @splat(0); + get_sys_info(&out, out.len, 0x001); + var buf: [8]u8 = undefined; + for (std.mem.asBytes(out[2..])[0..8], 1..) |b, i| { + buf[8 - i] = b; + } + return buf; +}