Skip to content

Pretty print and bugfix #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 2, 2022
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
55 changes: 52 additions & 3 deletions adafruit_pioasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,17 @@ class Program: # pylint: disable=too-few-public-methods

"""

def __init__(self, text_program: str) -> None:
def __init__(self, text_program: str, *, build_debuginfo=False) -> None:
"""Converts pioasm text to encoded instruction bytes"""
# pylint: disable=too-many-branches,too-many-statements,too-many-locals
assembled = []
program_name = None
labels = {}
linemap = []
instructions = []
sideset_count = 0
sideset_enable = 0
for line in text_program.split("\n"):
for i, line in enumerate(text_program.split("\n")):
line = line.strip()
if not line:
continue
Expand All @@ -75,6 +76,7 @@ def __init__(self, text_program: str) -> None:
elif line:
# Only add as an instruction if the line isn't empty
instructions.append(line)
linemap.append(i)

max_delay = 2 ** (5 - sideset_count - sideset_enable) - 1
assembled = []
Expand Down Expand Up @@ -219,12 +221,59 @@ def __init__(self, text_program: str) -> None:
# print(bin(assembled[-1]))

self.pio_kwargs = {
"sideset_count": sideset_count,
"sideset_pin_count": sideset_count,
"sideset_enable": sideset_enable,
}

self.assembled = array.array("H", assembled)

if build_debuginfo:
self.debuginfo = (linemap, text_program)
else:
self.debuginfo = None

def print_c_program(self, name, qualifier="const"):
"""Print the program into a C program snippet"""
if self.debuginfo is None:
linemap = None
program_lines = None
else:
linemap = self.debuginfo[0][:] # Use a copy since we destroy it
program_lines = self.debuginfo[1].split("\n")

print(
f"{qualifier} int {name}_sideset_pin_count = {self.pio_kwargs['sideset_pin_count']};"
)
print(
f"{qualifier} bool {name}_sideset_enable = {self.pio_kwargs['sideset_enable']};"
)
print(f"{qualifier} uint16_t {name}[] = " + "{")
last_line = 0
if linemap:
for inst in self.assembled:
next_line = linemap[0]
del linemap[0]
while last_line < next_line:
line = program_lines[last_line]
if line:
print(f" // {line}")
last_line += 1
line = program_lines[last_line]
print(f" 0x{inst:04x}, // {line}")
last_line += 1
while last_line < len(program_lines):
line = program_lines[last_line]
if line:
print(f" // {line}")
last_line += 1
else:
for i in range(0, len(self.assembled), 8):
print(
" " + ", ".join("0x%04x" % i for i in self.assembled[i : i + 8])
)
print("};")
print()


def assemble(program_text: str) -> array.array:
"""Converts pioasm text to encoded instruction bytes
Expand Down
28 changes: 28 additions & 0 deletions examples/pioasm_print_c_program.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: 2021 Scott Shawcroft, written for Adafruit Industries
# SPDX-FileCopyrightText: 2022 Jeff Epler, written for Adafruit Industries
#
# SPDX-License-Identifier: MIT

import adafruit_pioasm

# NeoPixels are 800khz bit streams. Zeroes are 1/3 duty cycle (~416ns) and ones
# are 2/3 duty cycle (~833ns).
text_program = """
.program ws2812
.side_set 1
.wrap_target
bitloop:
out x 1 side 0 [1]; Side-set still takes place when instruction stalls
jmp !x do_zero side 1 [1]; Branch on the bit we shifted out. Positive pulse
do_one:
jmp bitloop side 1 [1]; Continue driving high, for a long pulse
do_zero:
nop side 0 [1]; Or drive low, for a short pulse
.wrap
"""

program = adafruit_pioasm.Program(text_program, build_debuginfo=True)
program.print_c_program("pio_ws2812", qualifier="static const")

program = adafruit_pioasm.Program(text_program, build_debuginfo=False)
program.print_c_program("pio_ws2812_short")
8 changes: 5 additions & 3 deletions tests/testpioasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,11 @@ def testLimits(self):
self.assertAssemblyFails(".side_set 1 opt\nnop side 0 [8]")

def testCls(self):
self.assertPioKwargs("", sideset_count=0, sideset_enable=False)
self.assertPioKwargs(".side_set 1", sideset_count=1, sideset_enable=False)
self.assertPioKwargs(".side_set 3 opt", sideset_count=3, sideset_enable=True)
self.assertPioKwargs("", sideset_pin_count=0, sideset_enable=False)
self.assertPioKwargs(".side_set 1", sideset_pin_count=1, sideset_enable=False)
self.assertPioKwargs(
".side_set 3 opt", sideset_pin_count=3, sideset_enable=True
)


class TestMov(AssembleChecks):
Expand Down