diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py index 4c5e8b7..8ed564b 100644 --- a/adafruit_pioasm.py +++ b/adafruit_pioasm.py @@ -234,7 +234,7 @@ def parse_rxfifo_brackets(arg, fifo_dir): max_delay = 2 ** (5 - sideset_count - sideset_enable) - 1 assembled = [] - for line in instructions: + for line in instructions: # pylint: disable=too-many-nested-blocks instruction = splitter(line.strip()) delay = 0 if ( @@ -299,21 +299,32 @@ def parse_rxfifo_brackets(arg, fifo_dir): assembled[-1] |= num assembled[-1] |= 0b11 << 5 # JMPPIN wait source else: + idx = 3 assembled[-1] |= WAIT_SOURCES.index(instruction[2]) << 5 - num = int(instruction[3], 0) - if not 0 <= num <= 31: - raise RuntimeError("Wait num out of range") + if source == "irq": + if instruction[idx] == "next": + require_version(1, "wait irq next") + assembled[-1] |= 0b11000 + idx += 1 + elif instruction[idx] == "prev": + require_version(1, "wait irq prev") + assembled[-1] |= 0b01000 + idx += 1 + + limit = 8 + # The flag index is decoded in the same way as the IRQ + # index field, decoding down from the two MSBs + if instruction[-1] == "rel": + if assembled[-1] & 0b11000: + raise RuntimeError("cannot use next/prev with rel") + assembled[-1] |= 0b10000 + else: + limit = 32 + num = int_in_range( + instruction[idx], 0, limit, "wait {instruction[2]}" + ) assembled[-1] |= num - # The flag index is decoded in the same way as the IRQ - # index field, decoding down from the two MSBs - if instruction[-1] == "next": - require_version(1, "wait irq next") - assembled[-1] |= 0b11000 - elif instruction[-1] == "prev": - require_version(1, "wait irq prev") - assembled[-1] |= 0b01000 - elif instruction[-1] == "rel": - assembled[-1] |= 0b10000 + elif instruction[0] == "in": # instr delay src count assembled.append(0b010_00000_000_00000) @@ -352,15 +363,15 @@ def parse_rxfifo_brackets(arg, fifo_dir): elif instruction[0] == "mov": # instr delay dst op src if instruction[1].startswith("rxfifo["): # mov rxfifo[], isr - assembled.append(0b100_00000_0001_0_000) + assembled.append(0b100_00000_0001_1_000) if instruction[2] != "isr": raise ValueError("mov rxfifo[] source must be isr") - assembled[-1] |= parse_rxfifo_brackets(instruction[1], "txput") + assembled[-1] ^= parse_rxfifo_brackets(instruction[1], "txput") elif instruction[2].startswith("rxfifo["): # mov osr, rxfifo[] - assembled.append(0b100_00000_1001_0_000) + assembled.append(0b100_00000_1001_1_000) if instruction[1] != "osr": raise ValueError("mov ,rxfifo[] target must be osr") - assembled[-1] |= parse_rxfifo_brackets(instruction[2], "txget") + assembled[-1] ^= parse_rxfifo_brackets(instruction[2], "txget") else: assembled.append(0b101_00000_000_00_000) assembled[-1] |= mov_destinations.index(instruction[1]) << 5 @@ -388,30 +399,35 @@ def parse_rxfifo_brackets(arg, fifo_dir): assembled.append(0b110_00000_0_0_0_00000) irq_type = 0 - if instruction[-1] == "prev": + idx = 1 + if instruction[idx] == "wait": + assembled[-1] |= 0x20 + idx += 1 + elif instruction[idx] == "clear": + assembled[-1] |= 0x40 + idx += 1 + + if instruction[idx] == "prev": irq_type = 1 require_version(1, "irq prev") - instruction.pop() - elif instruction[-1] == "next": + idx += 1 + elif instruction[idx] == "next": irq_type = 3 require_version(1, "irq next") - instruction.pop() - elif instruction[-1] == "rel": + idx += 1 + + if instruction[-1] == "rel": + if irq_type != 0: + raise RuntimeError("cannot use next/prev with rel") irq_type = 2 instruction.pop() assembled[-1] |= irq_type << 3 - num = int_in_range(instruction[-1], 0, 8, "irq index") + num = int_in_range(instruction[idx], 0, 8, "irq index") assembled[-1] |= num instruction.pop() - if len(instruction) > 1: # after rel has been removed - if instruction[-1] == "wait": - assembled[-1] |= 0x20 - elif instruction[-1] == "clear": - assembled[-1] |= 0x40 - # All other values are the default of set without waiting elif instruction[0] == "set": # instr delay dst data assembled.append(0b111_00000_000_00000) diff --git a/tests/test_version.py b/tests/test_version.py index c12711a..d2aa57f 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -115,9 +115,10 @@ def test_dot_set() -> None: def test_irq_v1() -> None: - assert_assembly_fails("irq 7 next") - assert_assembles_to(".pio_version 1\nirq 5 next", [0b110_00000_0_0_0_11_101]) - assert_assembles_to(".pio_version 1\nirq wait 1 prev", [0b110_00000_0_0_1_01_001]) + assert_assembly_fails("irq next 7") + assert_assembly_fails(".pio_version 1\nirq next 7 rel") + assert_assembles_to(".pio_version 1\nirq next 5", [0b110_00000_0_0_0_11_101]) + assert_assembles_to(".pio_version 1\nirq wait prev 1", [0b110_00000_0_0_1_01_001]) def test_mov_v1() -> None: @@ -125,8 +126,8 @@ def test_mov_v1() -> None: assert_assembly_fails(".pio_version 1\nmov osr, rxfifo[y]") prefix = ".pio_version 1\n.fifo putget\n" assert_assembly_fails(prefix + "mov osr, rxfifo[8]") - assert_assembles_to(prefix + "mov rxfifo[y], isr", [0b100_00000_0001_1_000]) - assert_assembles_to(prefix + "mov osr, rxfifo[1]", [0b100_00000_1001_0_001]) + assert_assembles_to(prefix + "mov rxfifo[y], isr", [0b100_00000_0001_0_000]) + assert_assembles_to(prefix + "mov osr, rxfifo[1]", [0b100_00000_1001_1_001]) assert_assembly_fails("mov pindirs, null", errtype=ValueError) assert_assembles_to(prefix + "mov pindirs, null", [0b101_00000_01100011]) @@ -134,12 +135,12 @@ def test_mov_v1() -> None: def test_wait_v1() -> None: assert_assembly_fails("wait 0 jmppin") - assert_assembly_fails("wait 0 irq 5 next") + assert_assembly_fails("wait 0 irq next 5") prefix = ".pio_version 1\n" assert_assembly_fails(prefix + "wait 0 jmppin +") assert_assembly_fails(prefix + "wait 0 jmppin + 7") assert_assembles_to(prefix + "wait 0 jmppin + 3", [0b001_00000_0_11_00011]) assert_assembles_to(prefix + "wait 1 jmppin", [0b001_00000_1_11_00000]) - assert_assembles_to(prefix + "wait 0 irq 5 next", [0b001_00000_0_10_11_101]) - assert_assembles_to(prefix + "wait 1 irq 4 prev", [0b001_00000_1_10_01_100]) + assert_assembles_to(prefix + "wait 0 irq next 5", [0b001_00000_0_10_11_101]) + assert_assembles_to(prefix + "wait 1 irq prev 4", [0b001_00000_1_10_01_100])