Skip to content

Commit

Permalink
rp2xxx: Add support for assembling RP2350-specific PIO (#320)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
Grazfather and Hayden Riddiford authored Jan 17, 2025
1 parent 33e66ef commit eccecc2
Show file tree
Hide file tree
Showing 15 changed files with 1,997 additions and 1,498 deletions.
4 changes: 4 additions & 0 deletions port/raspberrypi/rp2xxx/src/hal/chip.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub const Chip = enum {
RP2040,
RP2350,
};
6 changes: 1 addition & 5 deletions port/raspberrypi/rp2xxx/src/hal/compatibility.zig
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
const std = @import("std");
const microzig = @import("microzig");

pub const Chip = enum {
RP2040,
RP2350,
};
const Chip = @import("chip.zig").Chip;

pub const chip: Chip = blk: {
if (std.mem.eql(u8, microzig.config.chip_name, "RP2040")) {
Expand Down
6 changes: 4 additions & 2 deletions port/raspberrypi/rp2xxx/src/hal/pio.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const chip_specific = switch (chip) {
.RP2350 => @import("pio/rp2350.zig"),
};
pub const StateMachine = common.StateMachine;
pub const Instruction = common.Instruction;
pub const Instruction = common.Instruction(chip);
pub const PinMapping = common.PinMapping;
pub const PinMappingOptions = common.PinMappingOptions;
pub const StateMachineInitOptions = chip_specific.StateMachineInitOptions;
Expand All @@ -24,7 +24,9 @@ pub const assembler = @import("pio/assembler.zig");
const encoder = @import("pio/assembler/encoder.zig");

pub const Program = assembler.Program;
pub const assemble = assembler.assemble;
pub inline fn assemble(comptime source: []const u8, comptime options: assembler.AssembleOptions) assembler.Output {
return assembler.assemble(chip, source, options);
}

pub fn num(n: u2) Pio {
switch (chip) {
Expand Down
11 changes: 6 additions & 5 deletions port/raspberrypi/rp2xxx/src/hal/pio/assembler.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const assert = std.debug.assert;

const Chip = @import("../chip.zig").Chip;
const tokenizer = @import("assembler/tokenizer.zig");
const encoder = @import("assembler/encoder.zig");

Expand Down Expand Up @@ -71,9 +72,9 @@ pub const Diagnostics = struct {
}
};

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

pub fn assemble(comptime source: []const u8, comptime options: AssembleOptions) Output {
pub fn assemble(comptime chip: Chip, comptime source: []const u8, comptime options: AssembleOptions) Output {
var diags: ?Diagnostics = null;
return assemble_impl(source, &diags, options) catch |err| {
return assemble_impl(chip, source, &diags, options) catch |err| {
if (diags) |d|
@compileError(format_compile_error(d.message.slice(), source, d.index));
@compileError(@errorName(err));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const std = @import("std");
const assembler = @import("../assembler.zig");
const tokenizer = @import("tokenizer.zig");
const Chip = @import("../../chip.zig").Chip;

const c = @cImport({
@cDefine("PICO_NO_HARDWARE", "1");
@cInclude("stdint.h");
Expand All @@ -12,7 +14,9 @@ const c = @cImport({
@cInclude("comparison_tests/hello.pio.h");
@cInclude("comparison_tests/hub75.pio.h");
@cInclude("comparison_tests/i2c.pio.h");
@cInclude("comparison_tests/irq.pio.h");
@cInclude("comparison_tests/manchester_encoding.pio.h");
@cInclude("comparison_tests/movrx.pio.h");
@cInclude("comparison_tests/nec_carrier_burst.pio.h");
@cInclude("comparison_tests/nec_carrier_control.pio.h");
@cInclude("comparison_tests/nec_receive.pio.h");
Expand All @@ -31,7 +35,13 @@ const c = @cImport({
});

fn pio_comparison(comptime source: []const u8) !void {
const output = comptime assembler.assemble(source, .{});
inline for (comptime .{ Chip.RP2040, Chip.RP2350 }) |chip| {
try pio_comparison_chip(chip, source);
}
}

fn pio_comparison_chip(comptime chip: Chip, comptime source: []const u8) !void {
const output = comptime assembler.assemble(chip, source, .{});
try std.testing.expect(output.programs.len > 0);

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

test "pio.comparison.irq" {
@setEvalBranchQuota(22000);
try pio_comparison_chip(.RP2350, @embedFile("comparison_tests/irq.pio"));
}

test "pio.comparison.manchester_encoding" {
@setEvalBranchQuota(11000);
try pio_comparison(@embedFile("comparison_tests/manchester_encoding.pio"));
}

test "pio.comparison.movrx" {
@setEvalBranchQuota(11000);
try pio_comparison_chip(.RP2350, @embedFile("comparison_tests/movrx.pio"));
}

test "pio.comparison.nec_carrier_burst" {
@setEvalBranchQuota(6000);
try pio_comparison(@embedFile("comparison_tests/nec_carrier_burst.pio"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# PIO example programs for testing

These were all taken from [the official pico examples repo](https://github.com/raspberrypi/pico-examples).
These were all taken from [the official pico examples
repo](https://github.com/raspberrypi/pico-examples).

The headers are generated using `pioasm`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.program irq
.side_set 1

.wrap_target
irq set 1 prev side 0
irq set 1 rel side 0
irq set 1 next side 0
irq wait 1 prev side 0
irq wait 1 rel side 0
irq wait 1 next side 0
irq clear 1 prev side 0
irq clear 1 rel side 0
irq clear 1 next side 0
.wrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

// TODO: Exercise more? delays, optional sideset, etc?
static const uint16_t irq_program_instructions[] = {
0xc009, // irq set 1 prev side 0
0xc011, // irq set 1 rel side 0
0xc019, // irq set 1 next side 0
0xc029, // irq wait 1 prev side 0
0xc031, // irq wait 1 rel side 0
0xc039, // irq wait 1 next side 0
0xc049, // irq clear 1 prev side 0
0xc051, // irq clear 1 rel side 0
0xc059, // irq clear 1 next side 0
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.program movrx

.wrap_target
mov rxfifoy, isr
mov rxfifo0, isr
mov rxfifo1, isr
mov rxfifo2, isr
mov rxfifo3, isr

mov osr, rxfifoy
mov osr, rxfifo0
mov osr, rxfifo1
mov osr, rxfifo2
mov osr, rxfifo3
.wrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

static const uint16_t movrx_program_instructions[] = {
// 0b1000_ssss_0001_yiii
0x8018, // mov rxfifoy, isr
0x8010, // mov rxfifo0, isr
0x8011, // mov rxfifo1, isr
0x8012, // mov rxfifo2, isr
0x8013, // mov rxfifo3, isr
// 0b1000_ssss_1001_yiii
0x8098, // mov osr, rxfifoy
0x8090, // mov osr, rxfifo0
0x8091, // mov osr, rxfifo1
0x8092, // mov osr, rxfifo2
0x8093, // mov osr, rxfifo3
};
Loading

0 comments on commit eccecc2

Please sign in to comment.