Skip to content

Commit 3880986

Browse files
authored
rp2xxx: Implement flashless flash hal (#705)
1 parent 0039283 commit 3880986

File tree

11 files changed

+101
-71
lines changed

11 files changed

+101
-71
lines changed

examples/raspberrypi/rp2xxx/build.zig

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ pub fn build(b: *std.Build) void {
2525
.{ .target = raspberrypi.pico, .name = "pico_hd44780", .file = "src/rp2040_only/hd44780.zig" },
2626
.{ .target = raspberrypi.pico, .name = "pico_pcf8574", .file = "src/rp2040_only/pcf8574.zig" },
2727
.{ .target = raspberrypi.pico, .name = "pico_i2c_slave", .file = "src/rp2040_only/i2c_slave.zig" },
28+
2829
.{ .target = raspberrypi.pico_flashless, .name = "pico_flashless_blinky", .file = "src/blinky.zig" },
30+
.{ .target = raspberrypi.pico_flashless, .name = "pico_flashless_flash-program", .file = "src/rp2040_only/flash_program.zig" },
31+
2932
.{ .target = raspberrypi.pico2_arm_flashless, .name = "pico2_arm_flashless_blinky", .file = "src/blinky.zig" },
3033
.{ .target = raspberrypi.pico2_riscv_flashless, .name = "pico2_riscv_flashless_blinky", .file = "src/blinky.zig" },
31-
.{ .target = raspberrypi.pico2_arm_flashless, .name = "pico2_arm_flashless_system_timer", .file = "src/system_timer.zig" },
32-
.{ .target = raspberrypi.pico2_riscv_flashless, .name = "pico2_riscv_flashless_system_timer", .file = "src/system_timer.zig" },
34+
.{ .target = raspberrypi.pico2_arm_flashless, .name = "pico2_arm_flashless_system-timer", .file = "src/system_timer.zig" },
35+
.{ .target = raspberrypi.pico2_riscv_flashless, .name = "pico2_riscv_flashless_system-timer", .file = "src/system_timer.zig" },
3336

3437
.{ .target = raspberrypi.pico2_arm, .name = "pico2_arm_random_data", .file = "src/rp2350_only/random_data.zig" },
3538
.{ .target = raspberrypi.pico2_riscv, .name = "pico2_riscv_random_data", .file = "src/rp2350_only/random_data.zig" },

port/raspberrypi/rp2xxx/build.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ pub fn init(dep: *std.Build.Dependency) Self {
197197
.name = "RaspberryPi Pico (ram image)",
198198
.url = "https://www.raspberrypi.com/products/raspberry-pi-pico/",
199199
.root_source_file = b.path("src/boards/raspberry_pi_pico.zig"),
200+
// needed by the flash hal
201+
.imports = rp2040_bootrom_imports,
200202
},
201203
}),
202204
.pico2_arm = chip_rp2350_arm.derive(.{
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
pub const xosc_freq = 12_000_000;
22

3+
pub const bootrom = @import("shared/rp2040_bootrom.zig");
4+
35
comptime {
4-
_ = @import("shared/bootrom.zig");
6+
_ = bootrom;
57
}

port/raspberrypi/rp2xxx/src/boards/shared/bootrom.zig

Lines changed: 0 additions & 44 deletions
This file was deleted.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const std = @import("std");
2+
const microzig = @import("microzig");
3+
const chip = microzig.hal.compatibility.chip;
4+
5+
comptime {
6+
if (chip == .RP2040 and !microzig.config.ram_image) {
7+
_ = bootloader_data;
8+
}
9+
}
10+
11+
/// Raw stage2 bootrom
12+
pub const stage2_rom: []const u8 = @embedFile("bootloader");
13+
14+
pub export const bootloader_data: [256]u8 linksection(".boot2") = blk: {
15+
@setEvalBranchQuota(10_000);
16+
17+
var bootrom: [256]u8 = @splat(0xFF);
18+
@memcpy(bootrom[0..stage2_rom.len], stage2_rom);
19+
20+
// 2.8.1.3.1. Checksum
21+
// The last four bytes of the image loaded from flash (which we hope is a valid flash second stage) are a CRC32 checksum
22+
// of the first 252 bytes. The parameters of the checksum are:
23+
// • Polynomial: 0x04c11db7
24+
// • Input reflection: no
25+
// • Output reflection: no
26+
// • Initial value: 0xffffffff
27+
// • Final XOR: 0x00000000
28+
// • Checksum value appears as little-endian integer at end of image
29+
// The Bootrom makes 128 attempts of approximately 4ms each for a total of approximately 0.5 seconds before giving up
30+
// and dropping into USB code to load and checksum the second stage with varying SPI parameters. If it sees a checksum
31+
// pass it will immediately jump into the 252-byte payload which contains the flash second stage.
32+
const Hash = std.hash.crc.Crc(u32, .{
33+
.polynomial = 0x04c11db7,
34+
.initial = 0xffffffff,
35+
.reflect_input = false,
36+
.reflect_output = false,
37+
.xor_output = 0x00000000,
38+
});
39+
40+
std.mem.writeInt(u32, bootrom[252..256], Hash.hash(bootrom[0..252]), .little);
41+
42+
break :blk bootrom;
43+
};
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
pub const xosc_freq = 12_000_000;
22

3+
pub const bootrom = @import("shared/rp2040_bootrom.zig");
4+
35
comptime {
4-
_ = @import("shared/bootrom.zig");
6+
_ = bootrom;
57
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
pub const xosc_freq = 12_000_000;
22

3+
pub const bootrom = @import("shared/rp2040_bootrom.zig");
4+
35
comptime {
4-
_ = @import("shared/bootrom.zig");
6+
_ = bootrom;
57
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
pub const xosc_freq = 12_000_000;
22

3+
pub const bootrom = @import("shared/rp2040_bootrom.zig");
4+
35
comptime {
4-
_ = @import("shared/bootrom.zig");
6+
_ = bootrom;
57
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
pub const xosc_freq = 12_000_000;
22

3+
pub const bootrom = @import("shared/rp2040_bootrom.zig");
4+
35
comptime {
4-
_ = @import("shared/bootrom.zig");
6+
_ = bootrom;
57
}

port/raspberrypi/rp2xxx/src/hal.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub inline fn init() void {
9797
const is_fpu_used: bool = builtin.abi.float() == .hard;
9898

9999
/// Allows user to easily swap in their own clock config while still
100-
/// using the reccomended initialization sequence
100+
/// using the recommended initialization sequence
101101
pub fn init_sequence(comptime clock_cfg: clocks.config.Global) void {
102102
if (compatibility.chip == .RP2350 and
103103
compatibility.arch == .arm)

0 commit comments

Comments
 (0)