micropython / micropython/micropython
rp2 PIO StateMachine jump table to produce instructions
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 22.1k
- Forks
- 9k
- Avg merge
- 6d 4h
- Merged PRs (30d)
- 16
Description
An enhancement to the Pi Pico StateMachine, add a method producing jmp instructions referencing labels in the state machine. This could then be used to direct a jump to various places without decisions in the PIO program. This is already possible, just semi-difficult: as far as I know, there is no way to get the address of a label besides manually counting instructions.
If this is already doable, it's not well documented that I could find, so this becomes just a documentation bug.
For example, consider communicating with the General Instruments AY-3-8930. This has a simple enough interface and, for the most part, requires writing 8 bits to an address/data bus and 2 bits to a control bus indicating whether the bus is idle, read, write, or address. The system can communicate with this through the TX FIFO by writing words of [data][operation][address], each 8 bits, but this gets complex:
- The program first writes the address, then must evaluate [operation] to determine if this is read or write
- The program must use
outto move the contents of the ISR into one register, and then use severalsetandjmpinstructions to decide where in the program to jump
Instead of these 24 bits, one could use the whole 32 bits in the FIFO, making [operation] a jmp instruction:
- The program first writes the address, then sets
xto 1 - On the next bus clock (next loop of the program), a
jmp (x_dec,"handle data")directs flow away from setting the address, instead to data handling - The data handling code uses
out (exec,16)to jump to the appropriate point in the code
This replaces the coded jump table with a single out instruction.
To get the jmp instruction, the StateMachine object would provide a member function to produce a jmp instruction using the particular label as a destination.
As for the example, this is the output section of a write-only PIO driver for the AY-3-8930. This uses 16-bit input of an address followed by data, and always writes.
# Set address
label("handle_output")
jmp(x_dec, "set_data")
out(pins,8) .side(0b11)
set(x, 0b1)
jmp("handle_clock")
# Set data
label("set_data")
out(pins,8) .side(0b10) [1]
jmp("handle_clock")
To expand this to read/write, I'd need to send another flag, copy it into y, and evaluate it against x:
# Set address
label("handle_output")
jmp(x_dec, "getset_data")
out(pins,8) .side(0b11)
set(x, 0b1)
jmp("handle_clock")
label("getset_data")
out(y,8)
set(x,0b0)
jmp(x_not_y, "get_data")
# Set data
label("set_data")
out(pins,8) .side(0b10) [1]
jmp("handle_clock")
# Get data
label("get_data")
out(pins,8) .side(0b01)
in(pins,8)
jmp("handle_clock")
Or by injecting a jmp:
# Set address
label("handle_output")
jmp(x_dec, "getset_data")
out(pins,8) .side(0b11)
set(x, 0b1)
jmp("handle_clock")
label("getset_data")
out(exec,16)
# Set data
label("set_data")
out(pins,8) .side(0b10) [1]
jmp("handle_clock")
# Get data
label("get_data")
out(pins,8) .side(0b01)
in(pins,8)
jmp("handle_clock")
This saves 2 instructions. For more complex protocols with multiple possible branch destinations, it saves 2 instructions per possible branch destination.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the rp2 StateMachine object and the existing PIO label and jump handling described in the issue. Review how out(exec,16) consumes an injected instruction and determine how a StateMachine method could produce a jmp targeting a label; done means callers can use the generated instruction for label-based dispatch without manually counting instructions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- embedded-iot
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100