Merge pull request #37 from jepler/pretty-print-and-bugfix

Pretty print and bugfix
This commit is contained in:
Scott Shawcroft 2022-02-02 12:05:41 -08:00 committed by GitHub
commit ad782006ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 6 deletions

View file

@ -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
@ -75,6 +76,7 @@ class Program: # pylint: disable=too-few-public-methods
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 = []
@ -219,12 +221,59 @@ class Program: # pylint: disable=too-few-public-methods
# 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

View file

@ -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")

View file

@ -111,9 +111,11 @@ class TestNop(AssembleChecks):
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):