rp2 — functionality specific to the RP2040

The rp2 module contains functions and classes specific to the RP2040, as used in the Raspberry Pi Pico.

See the RP2040 Python datasheet for more information, and pico-micropython-examples for example code.

PIO assembly language instructions

PIO state machines are programmed in a custom assembly language with nine core PIO-machine instructions. In MicroPython, PIO assembly routines are written as a Python function with the decorator @rp2.asm_pio(), and they use Python syntax. Such routines support standard Python variables and arithmetic, as well as the following custom functions that encode PIO instructions and direct the assembler. See sec 3.4 of the RP2040 datasheet for further details.

wrap_target()

Specify the location where execution continues after program wrapping. By default this is the start of the PIO routine.

wrap()

Specify the location where the program finishes and wraps around. If this directive is not used then it is added automatically at the end of the PIO routine. Wrapping does not cost any execution cycles.

label(label)

Define a label called label at the current location. label can be a string or integer.

word(instr, label=None)

Insert an arbitrary 16-bit word in the assembled output.

  • instr: the 16-bit value

  • label: if given, look up the label and logical-or the label’s value with instr

jmp(…)

This instruction takes two forms:

jmp(label)
  • label: label to jump to unconditionally

jmp(cond, label)
  • cond: the condition to check, one of:

    • not_x, not_y: true if register is zero

    • x_dec, y_dec: true if register is non-zero, and do post decrement

    • x_not_y: true if X is not equal to Y

    • pin: true if the input pin is set

    • not_osre: true if OSR is not empty (hasn’t reached its threshold)

  • label: label to jump to if condition is true

wait(polarity, src, index)

Block, waiting for high/low on a pin or IRQ line.

  • polarity: 0 or 1, whether to wait for a low or high value

  • src: one of: gpio (absolute pin), pin (pin relative to StateMachine’s in_base argument), irq

  • index: 0-31, the index for src

in_(src, bit_count)

Shift data in from src to ISR.

  • src: one of: pins, x, y, null, isr, osr

  • bit_count: number of bits to shift in (1-32)

out(dest, bit_count)

Shift data out from OSR to dest.

  • dest: one of: pins, x, y, pindirs, pc, isr, exec

  • bit_count: number of bits to shift out (1-32)

push(…)

Push ISR to the RX FIFO, then clear ISR to zero. This instruction takes the following forms:

  • push()

  • push(block)

  • push(noblock)

  • push(iffull)

  • push(iffull, block)

  • push(iffull, noblock)

If block is used then the instruction stalls if the RX FIFO is full. The default is to block. If iffull is used then it only pushes if the input shift count has reached its threshold.

pull(…)

Pull from the TX FIFO into OSR. This instruction takes the following forms:

  • pull()

  • pull(block)

  • pull(noblock)

  • pull(ifempty)

  • pull(ifempty, block)

  • pull(ifempty, noblock)

If block is used then the instruction stalls if the TX FIFO is empty. The default is to block. If ifempty is used then it only pulls if the output shift count has reached its threshold.

mov(dest, src)

Move into dest the value from src.

  • dest: one of: pins, x, y, exec, pc, isr, osr

  • src: one of: pins, x, y, null, status, isr, osr; this argument can be optionally modified by wrapping it in invert() or reverse() (but not both together)

irq(…)

Set or clear an IRQ flag. This instruction takes two forms:

irq(index)
  • index: 0-7, or rel(0) to rel(7)

irq(mode, index)
  • mode: one of: block, clear

  • index: 0-7, or rel(0) to rel(7)

If block is used then the instruction stalls until the flag is cleared by another entity. If clear is used then the flag is cleared instead of being set. Relative IRQ indices add the state machine ID to the IRQ index with modulo-4 addition. IRQs 0-3 are visible from to the processor, 4-7 are internal to the state machines.

set(dest, data)

Set dest with the value data.

  • dest: pins, x, y, pindirs

  • data: value (0-31)

nop()

This is a pseudoinstruction that assembles to mov(y, y) and has no side effect.

.side(value)

This is a modifier which can be applied to any instruction, and is used to control side-set pin values.

  • value: the value (bits) to output on the side-set pins

.delay(value)

This is a modifier which can be applied to any instruction, and specifies how many cycles to delay for after the instruction executes.

  • value: cycles to delay, 0-31 (maximum value reduced if side-set pins are used)

[value]

This is a modifier and is equivalent to .delay(value).