Skip to content

Commit

Permalink
Fix assembly of irq & mov rxfifo[] instructions to match sdk pioasm
Browse files Browse the repository at this point in the history
  • Loading branch information
jepler committed Sep 13, 2024
1 parent 89fc1a1 commit 679feb8
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 38 deletions.
76 changes: 46 additions & 30 deletions adafruit_pioasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
17 changes: 9 additions & 8 deletions tests/test_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,31 +115,32 @@ 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:
assert_assembly_fails("mov osr, rxfifo[y]")
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])


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])

0 comments on commit 679feb8

Please sign in to comment.