Skip to content

Commit 666f4ef

Browse files
committed
Merge remote-tracking branch 'origin/main' into program-object
2 parents 9707333 + fbafe00 commit 666f4ef

File tree

5 files changed

+54
-8
lines changed

5 files changed

+54
-8
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ bundles
1616
dist
1717
**/*.egg-info
1818
.vscode
19+
.venv

README.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ This is easily achieved by downloading
3232

3333
Installing from PyPI
3434
=====================
35-
.. note:: This library is not available on PyPI yet. Install documentation is included
36-
as a standard element. Stay tuned for PyPI availability!
3735

3836
On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from
3937
PyPI <https://pypi.org/project/adafruit-circuitpython-pioasm/>`_. To install for current user:

adafruit_pioasm.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,12 @@ def __init__(self, text_program: str) -> None:
115115
raise SyntaxError(f"Invalid jmp target {repr(target)}")
116116

117117
if len(instruction) > 2:
118-
assembled[-1] |= CONDITIONS.index(instruction[1]) << 5
118+
try:
119+
assembled[-1] |= CONDITIONS.index(instruction[1]) << 5
120+
except ValueError as exc:
121+
raise ValueError(
122+
f"Invalid jmp condition '{instruction[1]}'"
123+
) from exc
119124

120125
elif instruction[0] == "wait":
121126
# instr delay p sr index
@@ -163,7 +168,10 @@ def __init__(self, text_program: str) -> None:
163168
source = instruction[-1]
164169
source_split = mov_splitter(source)
165170
if len(source_split) == 1:
166-
assembled[-1] |= MOV_SOURCES.index(source)
171+
try:
172+
assembled[-1] |= MOV_SOURCES.index(source)
173+
except ValueError as exc:
174+
raise ValueError(f"Invalid mov source '{source}'") from exc
167175
else:
168176
assembled[-1] |= MOV_SOURCES.index(source_split[1])
169177
if source[:1] == "!":
@@ -195,7 +203,10 @@ def __init__(self, text_program: str) -> None:
195203
elif instruction[0] == "set":
196204
# instr delay dst data
197205
assembled.append(0b111_00000_000_00000)
198-
assembled[-1] |= SET_DESTINATIONS.index(instruction[1]) << 5
206+
try:
207+
assembled[-1] |= SET_DESTINATIONS.index(instruction[1]) << 5
208+
except ValueError as exc:
209+
raise ValueError(f"Invalid set destination '{instruction[1]}'") from exc
199210
value = int(instruction[-1])
200211
if not 0 <= value <= 31:
201212
raise RuntimeError("Set value out of range")

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Table of Contents
2424
:caption: Tutorials
2525

2626
Getting Started with Raspberry Pi Pico and CircuitPython <https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython>
27+
An Introduction to RP2040 PIO with CircuitPython <https://learn.adafruit.com/intro-to-rp2040-pio-with-circuitpython>
2728

2829
.. toctree::
2930
:caption: Related Products

tests/testpioasm.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def nice_opcode(o):
1818
return o[:3] + "_" + o[3:8] + "_" + o[8:]
1919

2020

21-
class TestNop(unittest.TestCase):
21+
class AssembleChecks(unittest.TestCase):
2222
def assertAssemblesTo(self, source, expected):
2323
actual = adafruit_pioasm.assemble(source)
2424
expected_bin = [nice_opcode(x) for x in expected]
@@ -29,13 +29,18 @@ def assertAssemblesTo(self, source, expected):
2929
f"Assembling {source!r}: Expected {expected_bin}, got {actual_bin}",
3030
)
3131

32-
def assertAssemblyFails(self, source):
33-
self.assertRaises(RuntimeError, adafruit_pioasm.assemble, source)
32+
def assertAssemblyFails(self, source, match=None, errtype=RuntimeError):
33+
if match:
34+
self.assertRaisesRegex(errtype, match, adafruit_pioasm.assemble, source)
35+
else:
36+
self.assertRaises(errtype, adafruit_pioasm.assemble, source)
3437

3538
def assertPioKwargs(self, source, **kw):
3639
program = adafruit_pioasm.Program(source)
3740
self.assertEqual(kw, program.pio_kwargs)
3841

42+
43+
class TestNop(AssembleChecks):
3944
def testNonsense(self):
4045
self.assertAssemblyFails("nope")
4146

@@ -64,6 +69,12 @@ def testSidesetOpt(self):
6469
".side_set 1 opt\nnop side 0 [7]", [0b101_10111_010_00_010]
6570
)
6671

72+
def testSet(self):
73+
# non happy path
74+
self.assertAssemblyFails(
75+
"set isr, 1", match="Invalid set destination 'isr'", errtype=ValueError
76+
)
77+
6778
def testJmp(self):
6879
self.assertAssemblesTo("l:\njmp l", [0b000_00000_000_00000])
6980
self.assertAssemblesTo("l:\njmp 7", [0b000_00000_000_00111])
@@ -75,6 +86,10 @@ def testJmp(self):
7586
self.assertAssemblesTo("jmp x!=y, l\nl:", [0b000_00000_101_00001])
7687
self.assertAssemblesTo("jmp pin, l\nl:", [0b000_00000_110_00001])
7788
self.assertAssemblesTo("jmp !osre, l\nl:", [0b000_00000_111_00001])
89+
# non happy path
90+
self.assertAssemblyFails(
91+
"jmp x--., l\nl:", match="Invalid jmp condition 'x--.'", errtype=ValueError
92+
)
7893

7994
def testWait(self):
8095
self.assertAssemblesTo("wait 0 gpio 0", [0b001_00000_0_00_00000])
@@ -99,3 +114,23 @@ def testCls(self):
99114
self.assertPioKwargs("", sideset_count=0, sideset_enable=False)
100115
self.assertPioKwargs(".side_set 1", sideset_count=1, sideset_enable=False)
101116
self.assertPioKwargs(".side_set 3 opt", sideset_count=3, sideset_enable=True)
117+
118+
119+
class TestMov(AssembleChecks):
120+
def testMovNonHappy(self):
121+
# non happy path
122+
self.assertAssemblyFails(
123+
"mov x, blah", match="Invalid mov source 'blah'", errtype=ValueError
124+
)
125+
126+
def testMovInvert(self):
127+
# test moving and inverting
128+
self.assertAssemblesTo("mov x, ~ x", [0b101_00000_001_01_001])
129+
self.assertAssemblesTo("mov x, ~ x", [0b101_00000_001_01_001])
130+
self.assertAssemblesTo("mov x, ~x", [0b101_00000_001_01_001])
131+
self.assertAssemblesTo("mov x, !x", [0b101_00000_001_01_001])
132+
133+
def testMovReverse(self):
134+
# test moving and reversing bits
135+
self.assertAssemblesTo("mov x, :: x", [0b101_00000_001_10_001])
136+
self.assertAssemblesTo("mov x, ::x", [0b101_00000_001_10_001])

0 commit comments

Comments
 (0)