From 2722649975ab36bbb7e42a48d516929f94dcb11c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 1 Feb 2022 10:34:51 -0600 Subject: [PATCH 1/3] Fix name of parameter in pio_kwargs --- adafruit_pioasm.py | 2 +- tests/testpioasm.py | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py index 85a5deb..5c3e7cc 100644 --- a/adafruit_pioasm.py +++ b/adafruit_pioasm.py @@ -219,7 +219,7 @@ 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, } diff --git a/tests/testpioasm.py b/tests/testpioasm.py index 0069b0e..722c10e 100644 --- a/tests/testpioasm.py +++ b/tests/testpioasm.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021 Jeff Epler, written for Adafruit Industries +# SPDX-FileCopyrightText: 2021 Jeff Epler, written for Adafruit Industriessideset_pin_count # # SPDX-License-Identifier: MIT @@ -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): From ac5290f6c7fd452c6bd7fb5c4745f12146ad6a04 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 1 Feb 2022 10:49:49 -0600 Subject: [PATCH 2/3] Add pretty-printing of PIO programs (into C for now) --- adafruit_pioasm.py | 53 ++++++++++++++++++++++++++++-- examples/pioasm_print_c_program.py | 28 ++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 examples/pioasm_print_c_program.py diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py index 5c3e7cc..d63f5c0 100644 --- a/adafruit_pioasm.py +++ b/adafruit_pioasm.py @@ -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 @@ 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 = [] @@ -225,6 +227,53 @@ def __init__(self, text_program: str) -> None: 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 diff --git a/examples/pioasm_print_c_program.py b/examples/pioasm_print_c_program.py new file mode 100644 index 0000000..7cada38 --- /dev/null +++ b/examples/pioasm_print_c_program.py @@ -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") From 5736f5034bb9ee3db9b18091e5ab00190ad4bcdd Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 1 Feb 2022 16:50:15 -0600 Subject: [PATCH 3/3] Update testpioasm.py --- tests/testpioasm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testpioasm.py b/tests/testpioasm.py index 722c10e..629a780 100644 --- a/tests/testpioasm.py +++ b/tests/testpioasm.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021 Jeff Epler, written for Adafruit Industriessideset_pin_count +# SPDX-FileCopyrightText: 2021 Jeff Epler, written for Adafruit Industries # # SPDX-License-Identifier: MIT