Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ fn pio_comparison(comptime source: []const u8) !void {
}

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

Expand All @@ -58,131 +59,105 @@ fn pio_comparison_chip(comptime chip: Chip, comptime source: []const u8) !void {
}

test "pio.comparison.addition" {
@setEvalBranchQuota(100_000);
try pio_comparison(@embedFile("comparison_tests/addition.pio"));
}

test "pio.comparison.apa102" {
@setEvalBranchQuota(100_000);
try pio_comparison(@embedFile("comparison_tests/apa102.pio"));
}

test "pio.comparison.blink" {
@setEvalBranchQuota(100_000);
try pio_comparison(@embedFile("comparison_tests/blink.pio"));
}

test "pio.comparison.clocked_input" {
@setEvalBranchQuota(100_000);
try pio_comparison(@embedFile("comparison_tests/clocked_input.pio"));
}

test "pio.comparison.differential_manchester" {
@setEvalBranchQuota(100_000);
try pio_comparison(@embedFile("comparison_tests/differential_manchester.pio"));
}

test "pio.comparison.hello" {
@setEvalBranchQuota(100_000);
try pio_comparison(@embedFile("comparison_tests/hello.pio"));
}

test "pio.comparison.hub75" {
@setEvalBranchQuota(100_000);
try pio_comparison(@embedFile("comparison_tests/hub75.pio"));
}

test "pio.comparison.i2c" {
@setEvalBranchQuota(100_000);
try pio_comparison(@embedFile("comparison_tests/i2c.pio"));
}

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

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

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

test "pio.comparison.nec_carrier_burst" {
@setEvalBranchQuota(100_000);
try pio_comparison(@embedFile("comparison_tests/nec_carrier_burst.pio"));
}

test "pio.comparison.nec_carrier_control" {
@setEvalBranchQuota(100_000);
try pio_comparison(@embedFile("comparison_tests/nec_carrier_control.pio"));
}

test "pio.comparison.nec_receive" {
@setEvalBranchQuota(12_000);
try pio_comparison(@embedFile("comparison_tests/nec_receive.pio"));
}

test "pio.comparison.pio_serialiser" {
@setEvalBranchQuota(3_000);
try pio_comparison(@embedFile("comparison_tests/pio_serialiser.pio"));
}

test "pio.comparison.pwm" {
@setEvalBranchQuota(6_000);
try pio_comparison(@embedFile("comparison_tests/pwm.pio"));
}

test "pio.comparison.quadrature_encoder" {
@setEvalBranchQuota(21_000);
try pio_comparison(@embedFile("comparison_tests/quadrature_encoder.pio"));
}

test "pio.comparison.resistor_dac" {
@setEvalBranchQuota(3_000);
try pio_comparison(@embedFile("comparison_tests/resistor_dac.pio"));
}

test "pio.comparison.spi" {
@setEvalBranchQuota(26_000);
try pio_comparison(@embedFile("comparison_tests/spi.pio"));
}

test "pio.comparison.squarewave" {
@setEvalBranchQuota(3_000);
try pio_comparison(@embedFile("comparison_tests/squarewave.pio"));
}

test "pio.comparison.squarewave_fast" {
@setEvalBranchQuota(3_000);
try pio_comparison(@embedFile("comparison_tests/squarewave_fast.pio"));
}

test "pio.comparison.squarewave_wrap" {
@setEvalBranchQuota(3_000);
try pio_comparison(@embedFile("comparison_tests/squarewave_wrap.pio"));
}

test "pio.comparison.st7789_lcd" {
@setEvalBranchQuota(6_000);
try pio_comparison(@embedFile("comparison_tests/st7789_lcd.pio"));
}

test "pio.comparison.uart_rx" {
@setEvalBranchQuota(12_000);
try pio_comparison(@embedFile("comparison_tests/uart_rx.pio"));
}

test "pio.comparison.uart_tx" {
@setEvalBranchQuota(7_000);
try pio_comparison(@embedFile("comparison_tests/uart_tx.pio"));
}

test "pio.comparison.ws2812" {
@setEvalBranchQuota(12_000);
try pio_comparison(@embedFile("comparison_tests/ws2812.pio"));
}
88 changes: 75 additions & 13 deletions port/raspberrypi/rp2xxx/src/hal/pio/assembler/encoder.zig
Original file line number Diff line number Diff line change
Expand Up @@ -181,20 +181,19 @@ pub fn Encoder(comptime chip: Chip, comptime options: Options) type {

break :outer error.DefineNotFound;
},
.expression => |expr_str| {
.expression => |expr_str| outer: {
const expr = try Expression.tokenize(expr_str, index, diags);
const result = try expr.evaluate(define_lists, diags);
if (result < 0 or result > std.math.maxInt(T)) {
diags.* = Diagnostics.init(
index,
"value of {} does not fit in a u{}",
.{
result, @bitSizeOf(T),
},
.{ result, @bitSizeOf(T) },
);
break :outer error.TooBig;
}

return @as(T, @intCast(result));
break :outer @as(T, @intCast(result));
},
};
}
Expand Down Expand Up @@ -462,20 +461,25 @@ pub fn Encoder(comptime chip: Chip, comptime options: Options) type {
}

fn calc_delay_side_set(
program_settings: ?SideSet,
sideset_settings: ?SideSet,
side_set_opt: ?u5,
delay_opt: ?u5,
) !u5 {
// TODO: error for side_set/delay collision
const delay: u5 = if (delay_opt) |delay| delay else 0;
return if (program_settings) |settings|
if (settings.optional)
if (side_set_opt) |side_set|
0x10 | (side_set << @as(u3, 4) - settings.count) | delay
const bits_needed = std.math.log2_int_ceil(u6, @as(u6, delay) + 1);

return if (sideset_settings) |sideset|
if (sideset.optional)
if (sideset.count + bits_needed > 4)
error.SideSetDelayCollision
else if (side_set_opt) |side_set|
0x10 | (side_set << @as(u3, 4) - sideset.count) | delay
else
delay
else if (sideset.count + bits_needed > 5)
error.SideSetDelayCollision
else
(side_set_opt.? << @as(u3, 5) - settings.count) | delay
(side_set_opt.? << @as(u3, 5) - sideset.count) | delay
else
delay;
}
Expand Down Expand Up @@ -680,6 +684,7 @@ pub fn Instruction(comptime chip: Chip) type {
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
const expectEqualStrings = std.testing.expectEqualStrings;
const expectError = std.testing.expectError;

fn encode_bounded_output_impl(comptime chip: Chip, source: []const u8, diags: *?assembler.Diagnostics) !Encoder(chip, .{}).Output {
const tokens = try tokenizer.tokenize(chip, source, diags, .{});
Expand All @@ -690,7 +695,7 @@ fn encode_bounded_output_impl(comptime chip: Chip, source: []const u8, diags: *?
fn encode_bounded_output(comptime chip: Chip, source: []const u8) !Encoder(chip, .{}).Output {
var diags: ?assembler.Diagnostics = null;
return encode_bounded_output_impl(chip, source, &diags) catch |err| if (diags) |d| blk: {
std.log.err("error at index {}: {s}", .{ d.index, d.message.slice() });
std.log.info("error at index {}: {s}", .{ d.index, d.message.slice() });
break :blk err;
} else err;
}
Expand Down Expand Up @@ -1021,6 +1026,14 @@ test "encode.evaluate.bit reversal" {
try expectEqual(@as(i128, 0x80000000), output.global_defines.get(0).value);
}

test "encode.evaluate.value size" {
const bits = encode_bounded_output(.RP2040,
\\.program delay_too_big
\\nop [32]
);
try expectError(error.TooBig, bits);
}

test "encode.jmp.label" {
const output = try encode_bounded_output(.RP2040,
\\.program arst
Expand Down Expand Up @@ -1104,6 +1117,55 @@ test "encode.jmp.label origin" {
}
}

test "encode.error.sideset delay collision" {
const collision = encode_bounded_output(.RP2040,
\\.program sideset_delay_collision
\\.side_set 2
\\nop side 3 [8]
);
try expectError(error.SideSetDelayCollision, collision);

const collision2 = encode_bounded_output(.RP2040,
\\.program sideset_delay_collision
\\.side_set 1
\\nop side 3 [31]
);
try expectError(error.SideSetDelayCollision, collision2);

const collision3 = encode_bounded_output(.RP2040,
\\.program sideset_delay_collision
\\.side_set 1 opt
\\nop side 3 [31]
);
try expectError(error.SideSetDelayCollision, collision3);

_ = try encode_bounded_output(.RP2040,
\\.program sideset_delay_collision
\\.side_set 2
\\nop side 3 [7]
);

_ = try encode_bounded_output(.RP2040,
\\.program sideset_delay_collision
\\nop [31]
);
}

test "encode.error.sideset opt delay collision" {
const collision = encode_bounded_output(.RP2040,
\\.program sideset_delay_collision
\\.side_set 2, opt
\\nop side 3 [4]
);
try expectError(error.SideSetDelayCollision, collision);

_ = try encode_bounded_output(.RP2040,
\\.program sideset_delay_collision
\\.side_set 2, opt
\\nop side 3 [3]
);
}

//test "encode.error.duplicated program name" {}
//test "encode.error.duplicated define" {}
//test "encode.error.multiple side_set" {}
Expand Down
Loading