Skip to content

Commit eccecc2

Browse files
rp2xxx: Add support for assembling RP2350-specific PIO (#320)
* rp2xxx: Update PIO for rp2350 * - Reorganized some of the comptime behavior surrounding CPU * Get pio comparison tests running on both cpu types * Fix PIO sm_set_shift_options * s/format/cpu * better error in tokenizer tests * Test expected index in define expect_define * More tests for both cpus * Add jmppin as valid source for wait * Test mov to pindirs * cleanup irq comp test * wip movrx * mov to rx working * Add movrx comparison tests * put ws2812 in both chips * wip: print diag and error * Fix error handling in rp2xxx pio assembler * Repro issue in diags * Fix diag issue * Cleanup diags * improve movtorx parsing and diag * Get movfromrx encoding and most tokenization working * Get tokenizing mov from rx to work * wip: Allow pio assemble to work at runtime * Revert "wip: Allow pio assemble to work at runtime" We currently depend on this stuff being comptime, would have to manage the memory if we wanted to support it running at runtime This reverts commit dc3b857. * irq rel * Fix mov from idx * cleanup * fix * Some cleanup --------- Co-authored-by: Hayden Riddiford <hayden@terrakaffe.com>
1 parent 33e66ef commit eccecc2

15 files changed

Lines changed: 1997 additions & 1498 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pub const Chip = enum {
2+
RP2040,
3+
RP2350,
4+
};

port/raspberrypi/rp2xxx/src/hal/compatibility.zig

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
const std = @import("std");
22
const microzig = @import("microzig");
3-
4-
pub const Chip = enum {
5-
RP2040,
6-
RP2350,
7-
};
3+
const Chip = @import("chip.zig").Chip;
84

95
pub const chip: Chip = blk: {
106
if (std.mem.eql(u8, microzig.config.chip_name, "RP2040")) {

port/raspberrypi/rp2xxx/src/hal/pio.zig

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const chip_specific = switch (chip) {
1212
.RP2350 => @import("pio/rp2350.zig"),
1313
};
1414
pub const StateMachine = common.StateMachine;
15-
pub const Instruction = common.Instruction;
15+
pub const Instruction = common.Instruction(chip);
1616
pub const PinMapping = common.PinMapping;
1717
pub const PinMappingOptions = common.PinMappingOptions;
1818
pub const StateMachineInitOptions = chip_specific.StateMachineInitOptions;
@@ -24,7 +24,9 @@ pub const assembler = @import("pio/assembler.zig");
2424
const encoder = @import("pio/assembler/encoder.zig");
2525

2626
pub const Program = assembler.Program;
27-
pub const assemble = assembler.assemble;
27+
pub inline fn assemble(comptime source: []const u8, comptime options: assembler.AssembleOptions) assembler.Output {
28+
return assembler.assemble(chip, source, options);
29+
}
2830

2931
pub fn num(n: u2) Pio {
3032
switch (chip) {

port/raspberrypi/rp2xxx/src/hal/pio/assembler.zig

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const std = @import("std");
22
const assert = std.debug.assert;
33

4+
const Chip = @import("../chip.zig").Chip;
45
const tokenizer = @import("assembler/tokenizer.zig");
56
const encoder = @import("assembler/encoder.zig");
67

@@ -71,9 +72,9 @@ pub const Diagnostics = struct {
7172
}
7273
};
7374

74-
pub fn assemble_impl(comptime source: []const u8, diags: *?Diagnostics, options: AssembleOptions) !Output {
75-
const tokens = try tokenizer.tokenize(source, diags, options.tokenize);
76-
const encoder_output = try encoder.encode(tokens.slice(), diags, options.encode);
75+
pub fn assemble_impl(comptime chip: Chip, comptime source: []const u8, diags: *?Diagnostics, options: AssembleOptions) !Output {
76+
const tokens = try tokenizer.tokenize(chip, source, diags, options.tokenize);
77+
const encoder_output = try encoder.encode(chip, tokens.slice(), diags, options.encode);
7778
var programs = std.BoundedArray(Program, options.encode.max_programs).init(0) catch unreachable;
7879
for (encoder_output.programs.slice()) |bounded|
7980
try programs.append(bounded.to_exported_program());
@@ -121,9 +122,9 @@ fn format_compile_error(comptime message: []const u8, comptime source: []const u
121122
});
122123
}
123124

124-
pub fn assemble(comptime source: []const u8, comptime options: AssembleOptions) Output {
125+
pub fn assemble(comptime chip: Chip, comptime source: []const u8, comptime options: AssembleOptions) Output {
125126
var diags: ?Diagnostics = null;
126-
return assemble_impl(source, &diags, options) catch |err| {
127+
return assemble_impl(chip, source, &diags, options) catch |err| {
127128
if (diags) |d|
128129
@compileError(format_compile_error(d.message.slice(), source, d.index));
129130
@compileError(@errorName(err));

port/raspberrypi/rp2xxx/src/hal/pio/assembler/comparison_tests.zig

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const std = @import("std");
22
const assembler = @import("../assembler.zig");
33
const tokenizer = @import("tokenizer.zig");
4+
const Chip = @import("../../chip.zig").Chip;
5+
46
const c = @cImport({
57
@cDefine("PICO_NO_HARDWARE", "1");
68
@cInclude("stdint.h");
@@ -12,7 +14,9 @@ const c = @cImport({
1214
@cInclude("comparison_tests/hello.pio.h");
1315
@cInclude("comparison_tests/hub75.pio.h");
1416
@cInclude("comparison_tests/i2c.pio.h");
17+
@cInclude("comparison_tests/irq.pio.h");
1518
@cInclude("comparison_tests/manchester_encoding.pio.h");
19+
@cInclude("comparison_tests/movrx.pio.h");
1620
@cInclude("comparison_tests/nec_carrier_burst.pio.h");
1721
@cInclude("comparison_tests/nec_carrier_control.pio.h");
1822
@cInclude("comparison_tests/nec_receive.pio.h");
@@ -31,7 +35,13 @@ const c = @cImport({
3135
});
3236

3337
fn pio_comparison(comptime source: []const u8) !void {
34-
const output = comptime assembler.assemble(source, .{});
38+
inline for (comptime .{ Chip.RP2040, Chip.RP2350 }) |chip| {
39+
try pio_comparison_chip(chip, source);
40+
}
41+
}
42+
43+
fn pio_comparison_chip(comptime chip: Chip, comptime source: []const u8) !void {
44+
const output = comptime assembler.assemble(chip, source, .{});
3545
try std.testing.expect(output.programs.len > 0);
3646

3747
inline for (output.programs) |program| {
@@ -87,11 +97,21 @@ test "pio.comparison.i2c" {
8797
try pio_comparison(@embedFile("comparison_tests/i2c.pio"));
8898
}
8999

100+
test "pio.comparison.irq" {
101+
@setEvalBranchQuota(22000);
102+
try pio_comparison_chip(.RP2350, @embedFile("comparison_tests/irq.pio"));
103+
}
104+
90105
test "pio.comparison.manchester_encoding" {
91106
@setEvalBranchQuota(11000);
92107
try pio_comparison(@embedFile("comparison_tests/manchester_encoding.pio"));
93108
}
94109

110+
test "pio.comparison.movrx" {
111+
@setEvalBranchQuota(11000);
112+
try pio_comparison_chip(.RP2350, @embedFile("comparison_tests/movrx.pio"));
113+
}
114+
95115
test "pio.comparison.nec_carrier_burst" {
96116
@setEvalBranchQuota(6000);
97117
try pio_comparison(@embedFile("comparison_tests/nec_carrier_burst.pio"));
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# PIO example programs for testing
22

3-
These were all taken from [the official pico examples repo](https://github.com/raspberrypi/pico-examples).
3+
These were all taken from [the official pico examples
4+
repo](https://github.com/raspberrypi/pico-examples).
5+
46
The headers are generated using `pioasm`.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.program irq
2+
.side_set 1
3+
4+
.wrap_target
5+
irq set 1 prev side 0
6+
irq set 1 rel side 0
7+
irq set 1 next side 0
8+
irq wait 1 prev side 0
9+
irq wait 1 rel side 0
10+
irq wait 1 next side 0
11+
irq clear 1 prev side 0
12+
irq clear 1 rel side 0
13+
irq clear 1 next side 0
14+
.wrap
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
// TODO: Exercise more? delays, optional sideset, etc?
4+
static const uint16_t irq_program_instructions[] = {
5+
0xc009, // irq set 1 prev side 0
6+
0xc011, // irq set 1 rel side 0
7+
0xc019, // irq set 1 next side 0
8+
0xc029, // irq wait 1 prev side 0
9+
0xc031, // irq wait 1 rel side 0
10+
0xc039, // irq wait 1 next side 0
11+
0xc049, // irq clear 1 prev side 0
12+
0xc051, // irq clear 1 rel side 0
13+
0xc059, // irq clear 1 next side 0
14+
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.program movrx
2+
3+
.wrap_target
4+
mov rxfifoy, isr
5+
mov rxfifo0, isr
6+
mov rxfifo1, isr
7+
mov rxfifo2, isr
8+
mov rxfifo3, isr
9+
10+
mov osr, rxfifoy
11+
mov osr, rxfifo0
12+
mov osr, rxfifo1
13+
mov osr, rxfifo2
14+
mov osr, rxfifo3
15+
.wrap
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
3+
static const uint16_t movrx_program_instructions[] = {
4+
// 0b1000_ssss_0001_yiii
5+
0x8018, // mov rxfifoy, isr
6+
0x8010, // mov rxfifo0, isr
7+
0x8011, // mov rxfifo1, isr
8+
0x8012, // mov rxfifo2, isr
9+
0x8013, // mov rxfifo3, isr
10+
// 0b1000_ssss_1001_yiii
11+
0x8098, // mov osr, rxfifoy
12+
0x8090, // mov osr, rxfifo0
13+
0x8091, // mov osr, rxfifo1
14+
0x8092, // mov osr, rxfifo2
15+
0x8093, // mov osr, rxfifo3
16+
};

0 commit comments

Comments
 (0)