rp2pio – Hardware interface to RP2 series’ programmable IO (PIO) peripheral.

Note

This module is intended to be used with the adafruit_pioasm library. For an introduction and guide to working with PIO in CircuitPython, see this Learn guide.

Warning

Using PIO inputs on Raspberry Pi RP2350 A2 stepping has some limitations due to a GPIO hardware issue that causes excessive leakage current (~120uA). A pin can read as high even when driven or pulled low, if the input signal is high impedance or if an attached pull-down resistor is too weak (has too high a value). See the warning in digitalio for more information.

Available on these boards
  • 0xCB Helios
  • 42. Keebs Frood
  • 8086 USB Interposer
  • Adafruit Feather RP2040
  • Adafruit Feather RP2040 Adalogger
  • Adafruit Feather RP2040 CAN
  • Adafruit Feather RP2040 DVI
  • Adafruit Feather RP2040 Prop-Maker
  • Adafruit Feather RP2040 RFM
  • Adafruit Feather RP2040 Scorpio
  • Adafruit Feather RP2040 ThinkInk
  • Adafruit Feather RP2040 USB Host
  • Adafruit Feather RP2350
  • Adafruit Floppsy RP2040
  • Adafruit ItsyBitsy RP2040
  • Adafruit KB2040
  • Adafruit Macropad RP2040
  • Adafruit Metro RP2040
  • Adafruit Metro RP2350
  • Adafruit QT Py RP2040
  • Adafruit QT2040 Trinkey
  • Archi RP2040
  • Arduino Nano RP2040 Connect
  • BBQ20KBD
  • BLOK
  • Bradán Lane STUDIO Explorer Badge
  • COSMO-Pico
  • Challenger NB RP2040 WiFi
  • Challenger RP2040 LTE
  • Challenger RP2040 LoRa
  • Challenger RP2040 SD/RTC
  • Challenger RP2040 SubGHz
  • Challenger RP2040 WiFi
  • Challenger RP2040 WiFi/BLE
  • Challenger+ RP2350 BConnect
  • Challenger+ RP2350 WiFi6/BLE5
  • Cytron EDU PICO W
  • Cytron IRIV IO Controller
  • Cytron MOTION 2350 Pro
  • Cytron Maker Nano RP2040
  • Cytron Maker Pi RP2040
  • Cytron Maker Uno RP2040
  • Datanoise PicoADK
  • Datanoise PicoADK V2
  • E-Fidget
  • ELECFREAKS PICO:ED
  • Electrolama minik
  • EncoderPad RP2040
  • Fig Pi
  • HEIA-FR Picomo V2
  • Hack Club Sprig
  • LILYGO T-DISPLAY
  • Maple Computing Elite-Pi
  • Melopero Shake RP2040
  • Oak Dev Tech BREAD2040
  • Oak Dev Tech Cast-Away RP2040
  • Oak Dev Tech RPGA Feather
  • Pajenicko PicoPad
  • Pimoroni Badger 2040
  • Pimoroni Badger 2040 W
  • Pimoroni Inky Frame 5.7
  • Pimoroni Inky Frame 7.3
  • Pimoroni Interstate 75
  • Pimoroni Keybow 2040
  • Pimoroni Motor 2040
  • Pimoroni PGA2040
  • Pimoroni PGA2350
  • Pimoroni Pico DV Base W
  • Pimoroni Pico LiPo (16MB)
  • Pimoroni Pico LiPo (4MB)
  • Pimoroni Pico Plus 2
  • Pimoroni Pico dv Base
  • Pimoroni PicoSystem
  • Pimoroni Plasma 2040
  • Pimoroni Plasma 2040W
  • Pimoroni Plasma 2350
  • Pimoroni Servo 2040
  • Pimoroni Tiny 2040 (2MB)
  • Pimoroni Tiny 2040 (8MB)
  • Pimoroni Tiny 2350
  • Pimoroni Tiny FX
  • PyKey 18 Numpad
  • PyKey 44 Ergo
  • PyKey 60
  • PyKey 87 TKL
  • RF.Guru RP2040
  • RP2.65-F
  • RP2040 Stamp
  • RP2350 Stamp
  • RP2350 Stamp XL
  • Raspberry Breadstick
  • Raspberry Pi Pico
  • Raspberry Pi Pico 2
  • Raspberry Pi Pico W
  • Seeeduino XIAO RP2040
  • Seeeduino XIAO RP2350
  • Silicognition LLC RP2040-Shim
  • SparkFun MicroMod RP2040 Processor
  • SparkFun Pro Micro RP2040
  • SparkFun Pro Micro RP2350
  • SparkFun Thing Plus - RP2040
  • VCC-GND Studio YD RP2040
  • W5100S-EVB-Pico
  • W5500-EVB-Pico
  • WK-50 Trackball Keyboard
  • Waveshare RP2040-GEEK
  • Waveshare RP2040-LCD-0.96
  • Waveshare RP2040-LCD-1.28
  • Waveshare RP2040-One
  • Waveshare RP2040-PiZero
  • Waveshare RP2040-Plus (16MB)
  • Waveshare RP2040-Plus (4MB)
  • Waveshare RP2040-TOUCH-LCD-1.28
  • Waveshare RP2040-Tiny
  • Waveshare RP2040-Zero
  • WeAct Studio Pico
  • WeAct Studio Pico 16MB
  • WisdPi Ardu2040M
  • WisdPi Tiny RP2040
  • nullbits Bit-C PRO
  • splitkb.com Liatris
  • takayoshiotake Octave RP2040
  • uGame22

rp2pio.pins_are_sequential(pins: List[microcontroller.Pin]) bool

Return True if the pins have sequential GPIO numbers, False otherwise

rp2pio.FifoType
rp2pio.FifoType_piov0
rp2pio.MovStatusType
rp2pio.MovStatusType_piov0
class rp2pio.StateMachine(program: circuitpython_typing.ReadableBuffer, frequency: int, *, pio_version: int = 0, may_exec: circuitpython_typing.ReadableBuffer | None = None, init: circuitpython_typing.ReadableBuffer | None = None, first_out_pin: microcontroller.Pin | None = None, out_pin_count: int = 1, initial_out_pin_state: int = 0, initial_out_pin_direction: int = 4294967295, first_in_pin: microcontroller.Pin | None = None, in_pin_count: int = 1, pull_in_pin_up: int = 0, pull_in_pin_down: int = 0, first_set_pin: microcontroller.Pin | None = None, set_pin_count: int = 1, initial_set_pin_state: int = 0, initial_set_pin_direction: int = 31, first_sideset_pin: microcontroller.Pin | None = None, sideset_pin_count: int = 1, initial_sideset_pin_state: int = 0, initial_sideset_pin_direction: int = 31, sideset_enable: bool = False, jmp_pin: microcontroller.Pin | None = None, jmp_pin_pull: digitalio.Pull | None = None, exclusive_pin_use: bool = True, auto_pull: bool = False, pull_threshold: int = 32, out_shift_right: bool = True, wait_for_txstall: bool = True, auto_push: bool = False, push_threshold: int = 32, in_shift_right: bool = True, user_interruptible: bool = True, wrap_target: int = 0, wrap: int = -1, offset: int = -1, fifo_type: FifoType = 'auto', mov_status_type: MovStatusType = 'txfifo', mov_status_n: int = 0)

A single PIO StateMachine

The programmable I/O peripheral on the RP2 series of microcontrollers is unique. It is a collection of generic state machines that can be used for a variety of protocols. State machines may be independent or coordinated. Program memory and IRQs are shared between the state machines in a particular PIO instance. They are independent otherwise.

This class is designed to facilitate sharing of PIO resources. By default, it is assumed that the state machine is used on its own and can be placed in either PIO. State machines with the same program will be placed in the same PIO if possible.

Construct a StateMachine object on the given pins with the given program.

The following parameters are usually supplied directly:

Parameters:
  • program (ReadableBuffer) – the program to run with the state machine

  • frequency (int) – the target clock frequency of the state machine. Actual may be less. Use 0 for system clock speed.

  • init (ReadableBuffer) – a program to run once at start up. This is run after program is started so instructions may be intermingled

  • may_exec (ReadableBuffer) – Instructions that may be executed via StateMachine.run calls. Some elements of the StateMachine’s configuration are inferred from the instructions used; for instance, if there is no in or push instruction, then the StateMachine is configured without a receive FIFO. In this case, passing a may_exec program containing an in instruction such as in x, a receive FIFO will be configured.

  • first_out_pin (Pin) – the first pin to use with the OUT instruction

  • initial_out_pin_state (int) – the initial output value for out pins starting at first_out_pin

  • initial_out_pin_direction (int) – the initial output direction for out pins starting at first_out_pin

  • first_in_pin (Pin) – the first pin to use with the IN instruction

  • pull_in_pin_up (int) – a 1-bit in this mask sets pull up on the corresponding in pin

  • pull_in_pin_down (int) – a 1-bit in this mask sets pull down on the corresponding in pin. Setting both pulls enables a “bus keep” function, i.e. a weak pull to whatever is current high/low state of GPIO.

  • first_set_pin (Pin) – the first pin to use with the SET instruction

  • initial_set_pin_state (int) – the initial output value for set pins starting at first_set_pin

  • initial_set_pin_direction (int) – the initial output direction for set pins starting at first_set_pin

  • first_sideset_pin (Pin) – the first pin to use with a side set

  • initial_sideset_pin_state (int) – the initial output value for sideset pins starting at first_sideset_pin

  • initial_sideset_pin_direction (int) – the initial output direction for sideset pins starting at first_sideset_pin

  • sideset_enable (bool) – True when the top sideset bit is to enable. This should be used with the “.side_set # opt” directive

  • jmp_pin (Pin) – the pin which determines the branch taken by JMP PIN instructions

  • jmp_pin_pull (Pull) – The pull value for the jmp pin, default is no pull.

  • exclusive_pin_use (bool) – When True, do not share any pins with other state machines. Pins are never shared with other peripherals

  • wait_for_txstall (bool) – When True, writing data out will block until the TX FIFO and OSR are empty and an instruction is stalled waiting for more data. When False, data writes won’t wait for the OSR to empty (only the TX FIFO) so make sure you give enough time before deiniting or stopping the state machine.

  • user_interruptible (bool) – When True (the default), write(), readinto(), and write_readinto() can be interrupted by a ctrl-C. This is useful when developing a PIO program: if there is an error in the program that causes an infinite loop, you will be able to interrupt the loop. However, if you are writing to a device that can get into a bad state if a read or write is interrupted, you may want to set this to False after your program has been vetted.

  • offset (int) – A specific offset in the state machine’s program memory where the program must be loaded. The default value, -1, allows the program to be loaded at any offset. This is appropriate for most programs.

The following parameters are usually set via assembler directives and passed using a **program.pio_kwargs argument but may also be specified directly:

Parameters:
  • out_pin_count (int) – the count of consecutive pins to use with OUT starting at first_out_pin

  • in_pin_count (int) – the count of consecutive pins to use with IN starting at first_in_pin

  • set_pin_count (int) – the count of consecutive pins to use with SET starting at first_set_pin

  • sideset_pin_count (int) – the count of consecutive pins to use with a side set starting at first_sideset_pin. Does not include sideset enable

  • pio_version (int) – The version of the PIO peripheral required by the program. The constructor will raise an error if the actual hardware is not compatible with this program version.

  • auto_push (bool) – When True, automatically save data from input shift register (ISR) into the rx FIFO when an IN instruction shifts more than push_threshold bits

  • push_threshold (int) – Number of bits to shift before saving the ISR value to the RX FIFO

  • in_shift_right (bool) – When True, data is shifted into the right side (LSB) of the ISR. It is shifted into the left (MSB) otherwise. NOTE! This impacts data alignment when the number of bytes is not a power of two (1, 2 or 4 bytes).

  • auto_pull (bool) – When True, automatically load data from the tx FIFO into the output shift register (OSR) when an OUT instruction shifts more than pull_threshold bits

  • pull_threshold (int) – Number of bits to shift before loading a new value into the OSR from the tx FIFO

  • out_shift_right (bool) – When True, data is shifted out the right side (LSB) of the OSR. It is shifted out the left (MSB) otherwise. NOTE! This impacts data alignment when the number of bytes is not a power of two (1, 2 or 4 bytes).

  • wrap_target (int) – The target instruction number of automatic wrap. Defaults to the first instruction of the program.

  • wrap (int) – The instruction after which to wrap to the wrap instruction. As a special case, -1 (the default) indicates the last instruction of the program.

  • fifo_type (FifoType) – How the program accessess the FIFOs. PIO version 0 only supports a subset of values.

  • mov_status_type (MovStatusType) – What condition the mov status instruction checks. PIO version 0 only supports a subset of values.

  • mov_status_n (MovStatusType) – The FIFO depth or IRQ the mov status instruction checks for. For mov_status irq this includes the encoding of the next/prev selection bits.

deinit() None

Turn off the state machine and release its resources.

__enter__() StateMachine

No-op used by Context Managers. Provided by context manager helper.

__exit__() None

Automatically deinitializes the hardware when exiting a context. See Lifetime and ContextManagers for more info.

restart() None

Resets this state machine, runs any init and enables the clock.

run(instructions: circuitpython_typing.ReadableBuffer) None

Runs all given instructions. They will likely be interleaved with in-memory instructions. Make sure this doesn’t wait for input!

This can be used to output internal state to the RX FIFO and then read with readinto.

stop() None

Stops the state machine clock. Use restart to enable it.

write(buffer: circuitpython_typing.ReadableBuffer, *, start: int = 0, end: int | None = None, swap: bool = False) None

Write the data contained in buffer to the state machine. If the buffer is empty, nothing happens.

Writes to the FIFO will match the input buffer’s element size. For example, bytearray elements will perform 8 bit writes to the PIO FIFO. The RP2040’s memory bus will duplicate the value into the other byte positions. So, pulling more data in the PIO assembly will read the duplicated values.

To perform 16 or 32 bits writes into the FIFO use an array.array with a type code of the desired size.

Parameters:
  • buffer (ReadableBuffer) – Write out the data in this buffer

  • start (int) – Start of the slice of buffer to write out: buffer[start:end]

  • end (int) – End of the slice; this index is not included. Defaults to len(buffer)

  • swap (bool) – For 2- and 4-byte elements, swap (reverse) the byte order

background_write(once: circuitpython_typing.ReadableBuffer | None = None, *, loop: circuitpython_typing.ReadableBuffer | None = None, swap: bool = False) None

Write data to the TX fifo in the background, with optional looping.

First, if any previous once or loop buffer has not been started, this function blocks until they have been started. This means that any once or loop buffer will be written at least once. Then the once and/or loop buffers are queued. and the function returns. The once buffer (if specified) will be written just once. Finally, the loop buffer (if specified) will continue being looped indefinitely.

Writes to the FIFO will match the input buffer’s element size. For example, bytearray elements will perform 8 bit writes to the PIO FIFO. The RP2040’s memory bus will duplicate the value into the other byte positions. So, pulling more data in the PIO assembly will read the duplicated values.

To perform 16 or 32 bits writes into the FIFO use an array.array with a type code of the desired size, or use memoryview.cast to change the interpretation of an existing buffer. To send just part of a larger buffer, slice a memoryview of it.

If a buffer is modified while it is being written out, the updated values will be used. However, because of interactions between CPU writes, DMA and the PIO FIFO are complex, it is difficult to predict the result of modifying multiple values. Instead, alternate between a pair of buffers.

Having both a once and a loop parameter is to support a special case in PWM generation where a change in duty cycle requires a special transitional buffer to be used exactly once. Most use cases will probably only use one of once or loop.

Having neither once nor loop terminates an existing background looping write after exactly a whole loop. This is in contrast to stop_background_write, which interrupts an ongoing DMA operation.

Parameters:
stop_background_write() None

Immediately stop a background write, if one is in progress. Any DMA in progress is halted, but items already in the TX FIFO are not affected.

writing: bool

Returns True if a background write is in progress

pending: int

Returns the number of pending buffers for background writing.

If the number is 0, then a StateMachine.background_write call will not block.

readinto(buffer: circuitpython_typing.WriteableBuffer, *, start: int = 0, end: int | None = None, swap: bool = False) None

Read into buffer. If the number of bytes to read is 0, nothing happens. The buffer includes any data added to the fifo even if it was added before this was called.

Reads from the FIFO will match the input buffer’s element size. For example, bytearray elements will perform 8 bit reads from the PIO FIFO. The alignment within the 32 bit value depends on in_shift_right. When in_shift_right is True, the upper N bits will be read. The lower bits will be read when in_shift_right is False.

To perform 16 or 32 bits writes into the FIFO use an array.array with a type code of the desired size.

Parameters:
  • buffer (WriteableBuffer) – Read data into this buffer

  • start (int) – Start of the slice of buffer to read into: buffer[start:end]

  • end (int) – End of the slice; this index is not included. Defaults to len(buffer)

  • swap (bool) – For 2- and 4-byte elements, swap (reverse) the byte order

write_readinto(buffer_out: circuitpython_typing.ReadableBuffer, buffer_in: circuitpython_typing.WriteableBuffer, *, out_start: int = 0, out_end: int | None = None, in_start: int = 0, in_end: int | None = None) None

Write out the data in buffer_out while simultaneously reading data into buffer_in. The lengths of the slices defined by buffer_out[out_start:out_end] and buffer_in[in_start:in_end] may be different. The function will return once both are filled. If buffer slice lengths are both 0, nothing happens.

Data transfers to and from the FIFOs will match the corresponding buffer’s element size. See write and readinto for details.

To perform 16 or 32 bits writes into the FIFO use an array.array with a type code of the desired size.

Parameters:
  • buffer_out (ReadableBuffer) – Write out the data in this buffer

  • buffer_in (WriteableBuffer) – Read data into this buffer

  • out_start (int) – Start of the slice of buffer_out to write out: buffer_out[out_start:out_end]

  • out_end (int) – End of the slice; this index is not included. Defaults to len(buffer_out)

  • in_start (int) – Start of the slice of buffer_in to read into: buffer_in[in_start:in_end]

  • in_end (int) – End of the slice; this index is not included. Defaults to len(buffer_in)

  • swap_out (bool) – For 2- and 4-byte elements, swap (reverse) the byte order for the buffer being transmitted (written)

  • swap_in (bool) – For 2- and 4-rx elements, swap (reverse) the byte order for the buffer being received (read)

clear_rxfifo() None

Clears any unread bytes in the rxfifo.

clear_txstall() None

Clears the txstall flag.

frequency: int

The actual state machine frequency. This may not match the frequency requested due to internal limitations.

txstall: bool

True when the state machine has stalled due to a full TX FIFO since the last clear_txstall call.

rxstall: bool

True when the state machine has stalled due to a full RX FIFO since the last clear_rxfifo call.

in_waiting: int

The number of words available to readinto

offset: int

The instruction offset where the program was actually loaded

pc: int

The current program counter of the state machine

rxfifo: memorymap.AddressRange

Access the state machine’s rxfifo directly

If the state machine’s fifo mode is txput then accessing this object reads values stored by the mov rxfifo[], isr PIO instruction, and the result of modifying it is undefined.

If the state machine’s fifo mode is txget then modifying this object writes values accessed by the mov osr, rxfifo[] PIO instruction, and the result of accessing it is undefined.

If this state machine’s mode is something else, then the property’s value is None.

Note: Since the txput and txget fifo mode does not exist on RP2040, this property will always be None.