From a2dd248c0726594fa547e8c7b471a4f031897914 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sat, 1 Jan 2022 14:26:55 -0800 Subject: [PATCH 01/10] Remove the "not available on PyPI yet" note. It appears to be obsolete given the validity of the link just below. --- README.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.rst b/README.rst index 9b83f08..96dcbc8 100644 --- a/README.rst +++ b/README.rst @@ -32,8 +32,6 @@ This is easily achieved by downloading Installing from PyPI ===================== -.. note:: This library is not available on PyPI yet. Install documentation is included - as a standard element. Stay tuned for PyPI availability! On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from PyPI `_. To install for current user: From e1e5e2a3ee23fa0b36f352a97ef0cb6358ab1512 Mon Sep 17 00:00:00 2001 From: Danny Staple Date: Sun, 2 Jan 2022 12:07:24 +0000 Subject: [PATCH 02/10] Add some helpful exception wrappers These make errors easier to fix. --- adafruit_pioasm.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py index 96fb8dd..e58d774 100644 --- a/adafruit_pioasm.py +++ b/adafruit_pioasm.py @@ -103,7 +103,9 @@ def assemble(text_program): raise SyntaxError(f"Invalid jmp target {repr(target)}") if len(instruction) > 2: - assembled[-1] |= CONDITIONS.index(instruction[1]) << 5 + try: + assembled[-1] |= CONDITIONS.index(instruction[1]) << 5 + raise SyntaxError(f"Invalid jmp condition {instruction[1]}") elif instruction[0] == "wait": # instr delay p sr index @@ -183,7 +185,10 @@ def assemble(text_program): elif instruction[0] == "set": # instr delay dst data assembled.append(0b111_00000_000_00000) - assembled[-1] |= SET_DESTINATIONS.index(instruction[1]) << 5 + try: + assembled[-1] |= SET_DESTINATIONS.index(instruction[1]) << 5 + except ValueError: + raise RuntimeError(f"Uknnown set destination {instruction[1]}") value = int(instruction[-1]) if not 0 <= value <= 31: raise RuntimeError("Set value out of range") From ac1cb9937d48917669a837b6e233784a45cabced Mon Sep 17 00:00:00 2001 From: Danny Staple Date: Sun, 2 Jan 2022 12:09:21 +0000 Subject: [PATCH 03/10] Copied incorrectly --- adafruit_pioasm.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py index e58d774..750248f 100644 --- a/adafruit_pioasm.py +++ b/adafruit_pioasm.py @@ -105,7 +105,8 @@ def assemble(text_program): if len(instruction) > 2: try: assembled[-1] |= CONDITIONS.index(instruction[1]) << 5 - raise SyntaxError(f"Invalid jmp condition {instruction[1]}") + except ValueError: + raise SyntaxError(f"Invalid jmp condition {instruction[1]}") elif instruction[0] == "wait": # instr delay p sr index From 0381b301195ac284039897bba4ca6ec7d132e092 Mon Sep 17 00:00:00 2001 From: Danny Staple Date: Sun, 2 Jan 2022 12:56:55 +0000 Subject: [PATCH 04/10] Fix the pylint, add in one other I've been using --- adafruit_pioasm.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py index 750248f..c3e9e08 100644 --- a/adafruit_pioasm.py +++ b/adafruit_pioasm.py @@ -105,8 +105,8 @@ def assemble(text_program): if len(instruction) > 2: try: assembled[-1] |= CONDITIONS.index(instruction[1]) << 5 - except ValueError: - raise SyntaxError(f"Invalid jmp condition {instruction[1]}") + except ValueError as exc: + raise SyntaxError(f"Invalid jmp condition {instruction[1]}") from exc elif instruction[0] == "wait": # instr delay p sr index @@ -154,7 +154,10 @@ def assemble(text_program): source = instruction[-1] source_split = mov_splitter(source) if len(source_split) == 1: - assembled[-1] |= MOV_SOURCES.index(source) + try: + assembled[-1] |= MOV_SOURCES.index(source) + except ValueError as exc: + raise RuntimeError("Invalid mov source:", source) from exc else: assembled[-1] |= MOV_SOURCES.index(source_split[1]) if source[:1] == "!": @@ -188,8 +191,8 @@ def assemble(text_program): assembled.append(0b111_00000_000_00000) try: assembled[-1] |= SET_DESTINATIONS.index(instruction[1]) << 5 - except ValueError: - raise RuntimeError(f"Uknnown set destination {instruction[1]}") + except ValueError as exc: + raise RuntimeError(f"Uknnown set destination {instruction[1]}") from exc value = int(instruction[-1]) if not 0 <= value <= 31: raise RuntimeError("Set value out of range") From fa2b8689ce498a89b6c621ed66031aa9df5ff5f3 Mon Sep 17 00:00:00 2001 From: Danny Staple Date: Sun, 2 Jan 2022 13:02:33 +0000 Subject: [PATCH 05/10] Typo spotted after tweeting... Doh --- adafruit_pioasm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py index c3e9e08..5b5c21b 100644 --- a/adafruit_pioasm.py +++ b/adafruit_pioasm.py @@ -192,7 +192,7 @@ def assemble(text_program): try: assembled[-1] |= SET_DESTINATIONS.index(instruction[1]) << 5 except ValueError as exc: - raise RuntimeError(f"Uknnown set destination {instruction[1]}") from exc + raise RuntimeError(f"Unknown set destination {instruction[1]}") from exc value = int(instruction[-1]) if not 0 <= value <= 31: raise RuntimeError("Set value out of range") From b0654228131f9d273d6bb62e2ab9486a479cb6b0 Mon Sep 17 00:00:00 2001 From: Danny Staple Date: Sun, 2 Jan 2022 13:22:11 +0000 Subject: [PATCH 06/10] Black reformat --- adafruit_pioasm.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py index 5b5c21b..8d530cc 100644 --- a/adafruit_pioasm.py +++ b/adafruit_pioasm.py @@ -106,7 +106,9 @@ def assemble(text_program): try: assembled[-1] |= CONDITIONS.index(instruction[1]) << 5 except ValueError as exc: - raise SyntaxError(f"Invalid jmp condition {instruction[1]}") from exc + raise SyntaxError( + f"Invalid jmp condition {instruction[1]}" + ) from exc elif instruction[0] == "wait": # instr delay p sr index From df0662297d8ae666b3b1c50f233590ebfde02577 Mon Sep 17 00:00:00 2001 From: Danny Staple Date: Sun, 2 Jan 2022 16:07:07 +0000 Subject: [PATCH 07/10] make my exceptions more consistent, and add tests. --- .gitignore | 1 + adafruit_pioasm.py | 8 ++++---- tests/testpioasm.py | 23 +++++++++++++++++++++-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 2c6ddfd..6559e83 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ bundles dist **/*.egg-info .vscode +.venv diff --git a/adafruit_pioasm.py b/adafruit_pioasm.py index 8d530cc..07137fe 100644 --- a/adafruit_pioasm.py +++ b/adafruit_pioasm.py @@ -106,8 +106,8 @@ def assemble(text_program): try: assembled[-1] |= CONDITIONS.index(instruction[1]) << 5 except ValueError as exc: - raise SyntaxError( - f"Invalid jmp condition {instruction[1]}" + raise ValueError( + f"Invalid jmp condition '{instruction[1]}'" ) from exc elif instruction[0] == "wait": @@ -159,7 +159,7 @@ def assemble(text_program): try: assembled[-1] |= MOV_SOURCES.index(source) except ValueError as exc: - raise RuntimeError("Invalid mov source:", source) from exc + raise ValueError(f"Invalid mov source '{source}'") from exc else: assembled[-1] |= MOV_SOURCES.index(source_split[1]) if source[:1] == "!": @@ -194,7 +194,7 @@ def assemble(text_program): try: assembled[-1] |= SET_DESTINATIONS.index(instruction[1]) << 5 except ValueError as exc: - raise RuntimeError(f"Unknown set destination {instruction[1]}") from exc + raise ValueError(f"Invalid set destination '{instruction[1]}'") from exc value = int(instruction[-1]) if not 0 <= value <= 31: raise RuntimeError("Set value out of range") diff --git a/tests/testpioasm.py b/tests/testpioasm.py index a15d01c..3ef3be5 100644 --- a/tests/testpioasm.py +++ b/tests/testpioasm.py @@ -29,8 +29,11 @@ class TestNop(unittest.TestCase): f"Assembling {source!r}: Expected {expected_bin}, got {actual_bin}", ) - def assertAssemblyFails(self, source): - self.assertRaises(RuntimeError, adafruit_pioasm.assemble, source) + def assertAssemblyFails(self, source, match=None, errtype=RuntimeError): + if match: + self.assertRaisesRegex(errtype, match, adafruit_pioasm.assemble, source) + else: + self.assertRaises(errtype, adafruit_pioasm.assemble, source) def testNonsense(self): self.assertAssemblyFails("nope") @@ -52,6 +55,18 @@ class TestNop(unittest.TestCase): ) self.assertAssemblesTo(".side_set 1 opt\nnop [1]", [0b101_00001_010_00_010]) + def testMov(self): + # non happy path + self.assertAssemblyFails( + "mov x, blah", match="Invalid mov source 'blah'", errtype=ValueError + ) + + def testSet(self): + # non happy path + self.assertAssemblyFails( + "set isr, 1", match="Invalid set destination 'isr'", errtype=ValueError + ) + def testJmp(self): self.assertAssemblesTo("l:\njmp l", [0b000_00000_000_00000]) self.assertAssemblesTo("l:\njmp 7", [0b000_00000_000_00111]) @@ -63,6 +78,10 @@ class TestNop(unittest.TestCase): self.assertAssemblesTo("jmp x!=y, l\nl:", [0b000_00000_101_00001]) self.assertAssemblesTo("jmp pin, l\nl:", [0b000_00000_110_00001]) self.assertAssemblesTo("jmp !osre, l\nl:", [0b000_00000_111_00001]) + # non happy path + self.assertAssemblyFails( + "jmp x--., l\nl:", match="Invalid jmp condition 'x--.'", errtype=ValueError + ) def testWait(self): self.assertAssemblesTo("wait 0 gpio 0", [0b001_00000_0_00_00000]) From fcfaf5f628de2d691eddf502989e3251ec871fd2 Mon Sep 17 00:00:00 2001 From: Danny Staple Date: Sat, 8 Jan 2022 14:37:02 +0000 Subject: [PATCH 08/10] Add a link to the PIO tutorial --- docs/index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index ed5921d..e08b9e0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -24,7 +24,8 @@ Table of Contents :caption: Tutorials Getting Started with Raspberry Pi Pico and CircuitPython - + An Introduction to RP2040 PIO with CircuitPython + .. toctree:: :caption: Related Products From c3fa9b65bd7c7454c10243629e555066e29670dc Mon Sep 17 00:00:00 2001 From: Danny Staple Date: Sat, 8 Jan 2022 15:50:28 +0000 Subject: [PATCH 09/10] Turns out, this dialect supports taking out spaces and the bang mark. --- tests/testpioasm.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/tests/testpioasm.py b/tests/testpioasm.py index 3ef3be5..8a3743f 100644 --- a/tests/testpioasm.py +++ b/tests/testpioasm.py @@ -18,7 +18,7 @@ def nice_opcode(o): return o[:3] + "_" + o[3:8] + "_" + o[8:] -class TestNop(unittest.TestCase): +class AssembleChecks(unittest.TestCase): def assertAssemblesTo(self, source, expected): actual = adafruit_pioasm.assemble(source) expected_bin = [nice_opcode(x) for x in expected] @@ -35,6 +35,8 @@ class TestNop(unittest.TestCase): else: self.assertRaises(errtype, adafruit_pioasm.assemble, source) + +class TestNop(AssembleChecks): def testNonsense(self): self.assertAssemblyFails("nope") @@ -55,12 +57,6 @@ class TestNop(unittest.TestCase): ) self.assertAssemblesTo(".side_set 1 opt\nnop [1]", [0b101_00001_010_00_010]) - def testMov(self): - # non happy path - self.assertAssemblyFails( - "mov x, blah", match="Invalid mov source 'blah'", errtype=ValueError - ) - def testSet(self): # non happy path self.assertAssemblyFails( @@ -94,3 +90,23 @@ class TestNop(unittest.TestCase): self.assertAssemblesTo("wait 0 irq 0 rel", [0b001_00000_0_10_10000]) self.assertAssemblesTo("wait 1 irq 0", [0b001_00000_1_10_00000]) self.assertAssemblesTo("wait 0 irq 1 rel", [0b001_00000_0_10_10001]) + + +class TestMov(AssembleChecks): + def testMovNonHappy(self): + # non happy path + self.assertAssemblyFails( + "mov x, blah", match="Invalid mov source 'blah'", errtype=ValueError + ) + + def testMovInvert(self): + # test moving and inverting + self.assertAssemblesTo("mov x, ~ x", [0b101_00000_001_01_001]) + self.assertAssemblesTo("mov x, ~ x", [0b101_00000_001_01_001]) + self.assertAssemblesTo("mov x, ~x", [0b101_00000_001_01_001]) + self.assertAssemblesTo("mov x, !x", [0b101_00000_001_01_001]) + + def testMovReverse(self): + # test moving and reversing bits + self.assertAssemblesTo("mov x, :: x", [0b101_00000_001_10_001]) + self.assertAssemblesTo("mov x, ::x", [0b101_00000_001_10_001]) From 1b7d7377eeb153cd3963ba9245bbefe6651219b1 Mon Sep 17 00:00:00 2001 From: Danny Staple Date: Sat, 8 Jan 2022 15:56:48 +0000 Subject: [PATCH 10/10] Fix the CI failure --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index e08b9e0..96d9e30 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -25,7 +25,7 @@ Table of Contents Getting Started with Raspberry Pi Pico and CircuitPython An Introduction to RP2040 PIO with CircuitPython - + .. toctree:: :caption: Related Products