|
epio
A cycle-accurate RP2350 PIO emulator
|
epio - A cycle-accurate RP2350 PIO emulator. More...
#include <stdint.h>#include <stddef.h>#include <epio_wasm.h>#include <apio.h>
Go to the source code of this file.
Classes | |
| struct | epio_sm_debug_t |
| Debug information for a single PIO state machine. More... | |
| struct | epio_sm_reg_t |
| Configurable registers for a single PIO state machine. More... | |
Typedefs | |
| typedef struct epio_t | epio_t |
| Opaque epio instance type. | |
Enumerations | |
| enum | epio_float_mode_t { EPIO_FLOAT_LOW = 0 , EPIO_FLOAT_HIGH = 1 , EPIO_FLOAT_RANDOM = 2 } |
| Controls the value returned when reading an undriven GPIO pin that has been explicitly configured with no pull resistor (PULL_NONE). More... | |
Functions | |
| EPIO_EXPORT epio_t * | epio_init (void) |
| Create and initialise a new epio instance. | |
| EPIO_EXPORT void | epio_free (epio_t *epio) |
| Free an epio instance and all associated resources. | |
| EPIO_EXPORT void | epio_set_sm_debug (epio_t *epio, uint8_t block, uint8_t sm, epio_sm_debug_t *debug) |
| Sets debug information for a specific state machine. | |
| EPIO_EXPORT void | epio_get_sm_debug (epio_t *epio, uint8_t block, uint8_t sm, epio_sm_debug_t *debug) |
| Gets the debug information for a specific state machine. | |
| EPIO_EXPORT void | epio_set_gpiobase (epio_t *epio, uint8_t block, uint32_t gpio_base) |
| Set the GPIO base for a PIO block. | |
| EPIO_EXPORT uint32_t | epio_get_gpiobase (epio_t *epio, uint8_t block) |
| Get the GPIO base for a PIO block. | |
| EPIO_EXPORT void | epio_set_sm_reg (epio_t *epio, uint8_t block, uint8_t sm, epio_sm_reg_t *reg) |
| Set the SM configuration registers for a state machine. | |
| EPIO_EXPORT void | epio_get_sm_reg (epio_t *epio, uint8_t block, uint8_t sm, epio_sm_reg_t *reg) |
| Read the current SM configuration registers for a state machine. | |
| EPIO_EXPORT void | epio_enable_sm (epio_t *epio, uint8_t block, uint8_t sm) |
| Enable a state machine for execution. | |
| EPIO_EXPORT uint8_t | epio_is_sm_enabled (epio_t *epio, uint8_t block, uint8_t sm) |
| Check if a state machine is enabled. | |
| EPIO_EXPORT void | epio_disable_sm (epio_t *epio, uint8_t block, uint8_t sm) |
| Disable a state machine. | |
| EPIO_EXPORT void | epio_set_instr (epio_t *epio, uint8_t block, uint8_t instr_num, uint16_t instr) |
| Write a PIO instruction into the instruction memory of a block. | |
| EPIO_EXPORT uint16_t | epio_get_instr (epio_t *epio, uint8_t block, uint8_t instr_num) |
| Read a PIO instruction from the instruction memory of a block. | |
| EPIO_EXPORT void | epio_force_sm_instr (epio_t *epio, uint8_t block, uint8_t sm, uint16_t instr) |
| Emulate a write to a state machine's SMx_INSTR register. | |
| EPIO_EXPORT void | epio_step_cycles (epio_t *epio, uint32_t cycles) |
| Advance all enabled state machines by a number of clock cycles. | |
| EPIO_EXPORT uint64_t | epio_get_cycle_count (epio_t *epio) |
| Return the total number of cycles executed since last reset. | |
| EPIO_EXPORT void | epio_reset_cycle_count (epio_t *epio) |
| Reset the cycle counter to zero. | |
| EPIO_EXPORT int32_t | epio_wait_tx_fifo (epio_t *epio, uint8_t block, uint8_t sm, int32_t count) |
Wait for a maximum of count cycles until the TX FIFO of a state machine has an entry pushed to it. | |
| EPIO_EXPORT uint8_t | epio_tx_fifo_depth (epio_t *epio, uint8_t block, uint8_t sm) |
| Return the current number of entries in the TX FIFO. | |
| EPIO_EXPORT uint8_t | epio_rx_fifo_depth (epio_t *epio, uint8_t block, uint8_t sm) |
| Return the current number of entries in the RX FIFO. | |
| EPIO_EXPORT uint32_t | epio_pop_rx_fifo (epio_t *epio, uint8_t block, uint8_t sm) |
| Pop a value from the RX FIFO. | |
| EPIO_EXPORT uint32_t | epio_pop_tx_fifo (epio_t *epio, uint8_t block, uint8_t sm) |
| Pop a value from the TX FIFO. | |
| EPIO_EXPORT void | epio_push_tx_fifo (epio_t *epio, uint8_t block, uint8_t sm, uint32_t value) |
| Push a value into the TX FIFO. | |
| EPIO_EXPORT void | epio_push_rx_fifo (epio_t *epio, uint8_t block, uint8_t sm, uint32_t value) |
| Push a value directly into the RX FIFO from the host. | |
| EPIO_EXPORT void | epio_drive_gpios_ext (epio_t *epio, uint64_t gpios, uint64_t level) |
| Drive a set of GPIOs to specified levels from an external source. | |
| void | epio_set_gpio_input_inverted (epio_t *epio, uint8_t pin, uint8_t inverted) |
| Set a GPIO pin as inverted or non-inverted. | |
| uint8_t | epio_get_gpio_input_inverted (epio_t *epio, uint8_t pin) |
| Get the inversion state of a GPIO pin. | |
| void | epio_set_gpio_output_control (epio_t *epio, uint8_t pin, uint8_t block) |
| Set GPIO output control for a pin to a specific block. | |
| void | epio_clear_gpio_output_control (epio_t *epio, uint8_t pin, uint8_t block) |
| Clear GPIO output control for a pin. | |
| uint8_t | epio_block_can_control_gpio_output (epio_t *epio, uint8_t block, uint8_t pin) |
| Check if a block can control the output of a GPIO pin. | |
| uint64_t | epio_get_gpio_output_control (epio_t *epio, uint8_t block) |
| Get the GPIO output control for a block. | |
| EPIO_EXPORT uint8_t | epio_get_gpio_input (epio_t *epio, uint8_t pin) |
| Read the current input level of a single GPIO pin. | |
| EPIO_EXPORT void | epio_init_gpios (epio_t *epio) |
| Reset all GPIOs to their hardware reset defaults. | |
| EPIO_EXPORT void | epio_set_gpio_force_input_low (epio_t *epio, uint8_t pin, uint8_t force_low) |
| Force a GPIO pin configured as an input to present a low level. | |
| EPIO_EXPORT void | epio_set_gpio_force_input_high (epio_t *epio, uint8_t pin, uint8_t force_high) |
| Force a GPIO pin configured as an input to present a high level. | |
| EPIO_EXPORT uint8_t | epio_get_gpio_force_input_low (epio_t *epio, uint8_t pin) |
| Get whether a GPIO pin configured as an input has a forced input level low. | |
| EPIO_EXPORT uint8_t | epio_get_gpio_force_input_high (epio_t *epio, uint8_t pin) |
| Get whether a GPIO pin configured as an input has a forced input level high. | |
| EPIO_EXPORT void | epio_set_gpio_input (epio_t *epio, uint8_t pin) |
| Configure a GPIO pin as an input. | |
| EPIO_EXPORT void | epio_set_gpio_output (epio_t *epio, uint8_t pin) |
| Configure a GPIO pin as an output. | |
| EPIO_EXPORT void | epio_set_gpio_input_level (epio_t *epio, uint8_t pin, uint8_t level) |
| Set the level of a GPIO configured as an input. | |
| EPIO_EXPORT void | epio_set_gpio_output_level (epio_t *epio, uint8_t pin, uint8_t level) |
| Set the level of a GPIO configured as an output. | |
| EPIO_EXPORT uint64_t | epio_read_pin_states (epio_t *epio) |
| Read the current state of all GPIO pins. | |
| EPIO_EXPORT uint64_t | epio_read_driven_pins (epio_t *epio) |
| Read the set of GPIO pins currently being driven by PIO. | |
| EPIO_EXPORT uint64_t | epio_read_pull_up_pins (epio_t *epio) |
| Return a bitmask of all GPIO pins that have a pull-up configured. | |
| EPIO_EXPORT uint64_t | epio_read_pull_down_pins (epio_t *epio) |
| Return a bitmask of all GPIO pins that have a pull-down configured. | |
| EPIO_EXPORT void | epio_set_gpio_pull_up (epio_t *epio, uint8_t pin, uint8_t enable) |
| Enable or disable a pull-up resistor on a GPIO pin. | |
| EPIO_EXPORT void | epio_set_gpio_pull_down (epio_t *epio, uint8_t pin, uint8_t enable) |
| Enable or disable a pull-down resistor on a GPIO pin. | |
| EPIO_EXPORT void | epio_set_gpio_pull_none (epio_t *epio, uint8_t pin) |
| Disable both pull-up and pull-down resistors on a GPIO pin. | |
| EPIO_EXPORT uint8_t | epio_get_gpio_pull_up (epio_t *epio, uint8_t pin) |
| Get the pull-up state of a GPIO pin. | |
| EPIO_EXPORT uint8_t | epio_get_gpio_pull_down (epio_t *epio, uint8_t pin) |
| Get the pull-down state of a GPIO pin. | |
| EPIO_EXPORT void | epio_set_gpio_input_only (epio_t *epio, uint8_t pin, uint8_t input_only) |
| Mark a GPIO pin as input-only (output driver disabled). | |
| EPIO_EXPORT uint8_t | epio_get_gpio_input_only (epio_t *epio, uint8_t pin) |
| Get the input-only state of a GPIO pin. | |
| EPIO_EXPORT void | epio_set_gpio_drive (epio_t *epio, uint8_t pin, uint8_t strength) |
| Set the drive strength for a GPIO output pin. | |
| EPIO_EXPORT uint8_t | epio_get_gpio_drive (epio_t *epio, uint8_t pin) |
| Get the configured drive strength for a GPIO output pin. | |
| EPIO_EXPORT void | epio_set_gpio_slew_fast (epio_t *epio, uint8_t pin, uint8_t fast) |
| Set the slew rate for a GPIO output pin. | |
| EPIO_EXPORT uint8_t | epio_get_gpio_slew_fast (epio_t *epio, uint8_t pin) |
| Get the configured slew rate for a GPIO output pin. | |
| EPIO_EXPORT void | epio_set_float_mode (epio_t *epio, epio_float_mode_t mode) |
| Set the float mode for undriven PULL_NONE pins. | |
| EPIO_EXPORT void | epio_set_float_seed (epio_t *epio, uint32_t seed) |
| Seed the PRNG used by EPIO_FLOAT_RANDOM float mode. | |
| EPIO_EXPORT void | epio_dma_setup_read_pio_chain (epio_t *epio, uint8_t dma_chan, uint8_t read_block, uint8_t read_sm, uint8_t read_cycles, uint8_t write_block, uint8_t write_sm, uint8_t write_cycles, uint8_t bit_mode) |
| Configure a DMA channel (pair) for PIO read access to SRAM. | |
| EPIO_EXPORT void | epio_dma_setup_capture_pio_ring (epio_t *epio, uint8_t dma_chan, uint8_t src_block, uint8_t src_sm, uint8_t src_cycles, uint32_t ring_base, uint8_t ring_size_log2, uint8_t bit_mode) |
| Configure a DMA channel for PIO-capture into a circular SRAM ring. | |
| EPIO_EXPORT uint8_t ** | epio_dma_capture_write_slot (epio_t *epio, uint8_t dma_chan) |
| Get the address of a capture channel's live host write pointer. | |
| EPIO_EXPORT uint8_t * | epio_get_sram_ptr (epio_t *epio) |
| Get a direct pointer to the emulated SRAM buffer. | |
| EPIO_EXPORT uint8_t | epio_sram_read_byte (epio_t *epio, uint32_t addr) |
| Read a byte from the emulated SRAM. | |
| EPIO_EXPORT void | epio_sram_set (epio_t *epio, uint32_t addr, uint8_t *data, size_t len) |
| Write a block of data into the emulated SRAM. | |
| EPIO_EXPORT uint16_t | epio_sram_read_halfword (epio_t *epio, uint32_t addr) |
| Read a halfword (16-bit) from the emulated SRAM. | |
| EPIO_EXPORT uint32_t | epio_sram_read_word (epio_t *epio, uint32_t addr) |
| Read a word (32-bit) from the emulated SRAM. | |
| EPIO_EXPORT void | epio_sram_write_byte (epio_t *epio, uint32_t addr, uint8_t value) |
| Write a byte to the emulated SRAM. | |
| EPIO_EXPORT void | epio_sram_write_halfword (epio_t *epio, uint32_t addr, uint16_t value) |
| Write a halfword (16-bit) to the emulated SRAM. | |
| EPIO_EXPORT void | epio_sram_write_word (epio_t *epio, uint32_t addr, uint32_t value) |
| Write a word (32-bit) to the emulated SRAM. | |
| EPIO_EXPORT uint8_t | epio_peek_sm_pc (epio_t *epio, uint8_t block, uint8_t sm) |
| Get the current program counter (PC) for a state machine. | |
| EPIO_EXPORT uint32_t | epio_peek_sm_x (epio_t *epio, uint8_t block, uint8_t sm) |
| Get the current X register value for a state machine. | |
| EPIO_EXPORT uint32_t | epio_peek_sm_y (epio_t *epio, uint8_t block, uint8_t sm) |
| Get the current Y register value for a state machine. | |
| EPIO_EXPORT uint32_t | epio_peek_sm_isr (epio_t *epio, uint8_t block, uint8_t sm) |
| Get the current Input Shift Register (ISR) value for a state machine. | |
| EPIO_EXPORT uint32_t | epio_peek_sm_osr (epio_t *epio, uint8_t block, uint8_t sm) |
| Get the current Output Shift Register (OSR) value for a state machine. | |
| EPIO_EXPORT uint8_t | epio_peek_sm_isr_count (epio_t *epio, uint8_t block, uint8_t sm) |
| Get the current ISR bit counter for a state machine. | |
| EPIO_EXPORT uint8_t | epio_peek_sm_osr_count (epio_t *epio, uint8_t block, uint8_t sm) |
| Get the current OSR bit counter for a state machine. | |
| EPIO_EXPORT uint8_t | epio_peek_sm_osr_empty (epio_t *epio, uint8_t block, uint8_t sm) |
| Check whether the OSR is considered empty for a state machine. | |
| EPIO_EXPORT uint8_t | epio_peek_sm_stalled (epio_t *epio, uint8_t block, uint8_t sm) |
| Check if a state machine is currently stalled. | |
| EPIO_EXPORT uint8_t | epio_peek_sm_delay (epio_t *epio, uint8_t block, uint8_t sm) |
| Get the current delay counter for a state machine. | |
| EPIO_EXPORT uint8_t | epio_peek_sm_exec_pending (epio_t *epio, uint8_t block, uint8_t sm) |
| Check if a state machine has a pending EXEC instruction. | |
| EPIO_EXPORT uint16_t | epio_peek_sm_exec_instr (epio_t *epio, uint8_t block, uint8_t sm) |
| Get the pending EXEC instruction for a state machine. | |
| EPIO_EXPORT uint32_t | epio_peek_block_irq (epio_t *epio, uint8_t block) |
| Get the current IRQ state bitmask for a PIO block. | |
| EPIO_EXPORT uint8_t | epio_peek_block_irq_num (epio_t *epio, uint8_t block, uint8_t irq_num) |
| Check if a specific IRQ flag is set for a PIO block. | |
| EPIO_EXPORT uint32_t | epio_peek_rx_fifo (epio_t *epio, uint8_t block, uint8_t sm, uint8_t entry) |
| Peek at an entry in the RX FIFO of a state machine without popping it. | |
| EPIO_EXPORT uint32_t | epio_peek_tx_fifo (epio_t *epio, uint8_t block, uint8_t sm, uint8_t entry) |
| Peek at an entry in the TX FIFO of a state machine without popping it. | |
| EPIO_EXPORT void | epio_set_block_irq (epio_t *epio, uint8_t block, uint8_t irq_num) |
| Set an IRQ flag for a PIO block. | |
| EPIO_EXPORT void | epio_clear_block_irq (epio_t *epio, uint8_t block, uint8_t irq_num) |
| Clear an IRQ flag for a PIO block. | |
| EPIO_EXPORT epio_t * | epio_from_apio (void) |
| Create an epio instance configured from the current apio state. | |
| EPIO_EXPORT void | epio_update_from_apio (epio_t *epio) |
| Update a live epio instance from the current accumulated apio state. | |
| EPIO_EXPORT int | epio_disassemble_sm (epio_t *epio, uint8_t block, uint8_t sm, char *buffer, size_t buffer_size) |
| Disassemble the instructions of a state machine. | |
epio - A cycle-accurate RP2350 PIO emulator.
epio emulates RP2350 PIO state machines on non-RP2350 hosts, enabling deterministic testing and verification of PIO programs without real hardware. It supports all 12 PIO state machines across 3 PIO blocks, running simultaneously.
If used in conjunction with apio, an epio instance can be configured automatically via epio_from_apio(). Otherwise, the instance can be configured manually using the Global API.
Opaque epio instance type.
All API functions operate on a pointer to this type. Create with epio_init() or epio_from_apio(), and destroy with epio_free().
| enum epio_float_mode_t |
Controls the value returned when reading an undriven GPIO pin that has been explicitly configured with no pull resistor (PULL_NONE).
Does not affect pins with an explicit pull-up or pull-down configured. Default: EPIO_FLOAT_HIGH.
| Enumerator | |
|---|---|
| EPIO_FLOAT_LOW | Undriven PULL_NONE pins read as 0. |
| EPIO_FLOAT_HIGH | Undriven PULL_NONE pins read as 1 (default). |
| EPIO_FLOAT_RANDOM | Undriven PULL_NONE pins return a PRNG value. |
| EPIO_EXPORT uint8_t ** epio_dma_capture_write_slot | ( | epio_t * | epio, |
| uint8_t | dma_chan | ||
| ) |
Get the address of a capture channel's live host write pointer.
Returns a pointer to the capture channel's internal host pointer, which tracks the current ring write position and advances (wrapping) as the ring fills. Intended for emulator test seams that need to observe how far a capture channel has written without polling every cycle.
| epio | The epio instance. |
| dma_chan | A DMA channel previously configured with epio_dma_setup_capture_pio_ring(). |
| EPIO_EXPORT void epio_dma_setup_capture_pio_ring | ( | epio_t * | epio, |
| uint8_t | dma_chan, | ||
| uint8_t | src_block, | ||
| uint8_t | src_sm, | ||
| uint8_t | src_cycles, | ||
| uint32_t | ring_base, | ||
| uint8_t | ring_size_log2, | ||
| uint8_t | bit_mode | ||
| ) |
Configure a DMA channel for PIO-capture into a circular SRAM ring.
Sets up a single "capture" DMA channel that drains the source state machine's RX FIFO into a circular ring buffer in emulated SRAM, mirroring the RP2350 address-monitor DMA. Each pushed word is written into the ring (as an 8-, 16- or 32-bit entry) src_cycles cycles after it is popped, and the channel's write position advances, wrapping within the ring. A consumer can poll the write position to observe how far the ring has filled.
| epio | The epio instance. |
| dma_chan | DMA channel number (0 to NUM_DMA_CHANNELS-1). |
| src_block | PIO block index of the source SM (0 to NUM_PIO_BLOCKS-1). |
| src_sm | Source SM index (0 to NUM_SMS_PER_BLOCK-1). |
| src_cycles | Transfer latency in cycles (>= 1). |
| ring_base | RP2350 SRAM address of the ring buffer. Must be aligned to the ring size (1 << ring_size_log2). |
| ring_size_log2 | Log2 of the ring size in bytes. |
| bit_mode | Entry size in bits: 8, 16 or 32. |
| EPIO_EXPORT void epio_dma_setup_read_pio_chain | ( | epio_t * | epio, |
| uint8_t | dma_chan, | ||
| uint8_t | read_block, | ||
| uint8_t | read_sm, | ||
| uint8_t | read_cycles, | ||
| uint8_t | write_block, | ||
| uint8_t | write_sm, | ||
| uint8_t | write_cycles, | ||
| uint8_t | bit_mode | ||
| ) |
Configure a DMA channel (pair) for PIO read access to SRAM.
This sets up the specified DMA channel for use by PIO programs that read from SRAM.
| epio | The epio instance. |
| dma_chan | DMA channel number (0 to NUM_DMA_CHANNELS-1). |
| read_block | PIO block index for the read side of the channel (0 to NUM_PIO_BLOCKS-1). |
| read_sm | State machine index for the read side of the channel (0 to NUM_SMS_PER_BLOCK-1). |
| read_cycles | Number of cycles for the read side of the channel (1 to 255). |
| write_block | PIO block index for the write side of the channel (0 to NUM_PIO_BLOCKS-1). |
| write_sm | State machine index for the write side of the channel (0 to NUM_SMS_PER_BLOCK-1). |
| write_cycles | Number of cycles for the write side of the channel (1 to 255). |
| bit_mode | Bit mode for the channel: 8, 16 or 32. |