epio
A cycle-accurate RP2350 PIO emulator
Loading...
Searching...
No Matches
epio.h
Go to the documentation of this file.
1// Copyright (C) 2026 Piers Finlayson <piers@piers.rocks>
2//
3// MIT License
4
22#if !defined(EPIO_H)
23#define EPIO_H
24
25#include <stdint.h>
26#include <stddef.h>
27#define APIO_EMULATION 1
28#include <epio_wasm.h>
29#include <apio.h>
30
37typedef struct epio_t epio_t;
38
51typedef struct {
53 uint8_t first_instr;
55 uint8_t start_instr;
57 uint8_t end_instr;
59
67typedef struct {
69 uint32_t clkdiv;
71 uint32_t execctrl;
73 uint32_t shiftctrl;
75 uint32_t pinctrl;
77
94EPIO_EXPORT epio_t *epio_init(void);
95
101EPIO_EXPORT void epio_free(epio_t *epio);
102
114EPIO_EXPORT void epio_set_sm_debug(epio_t *epio, uint8_t block, uint8_t sm, epio_sm_debug_t *debug);
115
125EPIO_EXPORT void epio_get_sm_debug(epio_t *epio, uint8_t block, uint8_t sm, epio_sm_debug_t *debug);
126
138EPIO_EXPORT void epio_set_gpiobase(epio_t *epio, uint8_t block, uint32_t gpio_base);
139
147EPIO_EXPORT uint32_t epio_get_gpiobase(epio_t *epio, uint8_t block);
148
162EPIO_EXPORT void epio_set_sm_reg(epio_t *epio, uint8_t block, uint8_t sm, epio_sm_reg_t *reg);
163
175EPIO_EXPORT void epio_get_sm_reg(epio_t *epio, uint8_t block, uint8_t sm, epio_sm_reg_t *reg);
176
187EPIO_EXPORT void epio_enable_sm(epio_t *epio, uint8_t block, uint8_t sm);
188
198EPIO_EXPORT uint8_t epio_is_sm_enabled(epio_t *epio, uint8_t block, uint8_t sm);
199
211EPIO_EXPORT void epio_disable_sm(epio_t *epio, uint8_t block, uint8_t sm);
212
230EPIO_EXPORT void epio_set_instr(epio_t *epio, uint8_t block, uint8_t instr_num, uint16_t instr);
231
241EPIO_EXPORT uint16_t epio_get_instr(epio_t *epio, uint8_t block, uint8_t instr_num);
242
254EPIO_EXPORT void epio_step_cycles(epio_t *epio, uint32_t cycles);
255
263EPIO_EXPORT uint64_t epio_get_cycle_count(epio_t *epio);
264
271EPIO_EXPORT void epio_reset_cycle_count(epio_t *epio);
272
294EPIO_EXPORT int32_t epio_wait_tx_fifo(epio_t *epio, uint8_t block, uint8_t sm, int32_t count);
295
304EPIO_EXPORT uint8_t epio_tx_fifo_depth(epio_t *epio, uint8_t block, uint8_t sm);
305
314EPIO_EXPORT uint8_t epio_rx_fifo_depth(epio_t *epio, uint8_t block, uint8_t sm);
315
329EPIO_EXPORT uint32_t epio_pop_rx_fifo(epio_t *epio, uint8_t block, uint8_t sm);
330
344EPIO_EXPORT uint32_t epio_pop_tx_fifo(epio_t *epio, uint8_t block, uint8_t sm);
345
359EPIO_EXPORT void epio_push_tx_fifo(epio_t *epio, uint8_t block, uint8_t sm, uint32_t value);
360
374EPIO_EXPORT void epio_push_rx_fifo(epio_t *epio, uint8_t block, uint8_t sm, uint32_t value);
375
397EPIO_EXPORT void epio_drive_gpios_ext(epio_t *epio, uint64_t gpios, uint64_t level);
398
411void epio_set_gpio_input_inverted(epio_t *epio, uint8_t pin, uint8_t inverted);
412
420uint8_t epio_get_gpio_input_inverted(epio_t *epio, uint8_t pin);
421
433void epio_set_gpio_output_control(epio_t *epio, uint8_t pin, uint8_t block);
434
444void epio_clear_gpio_output_control(epio_t *epio, uint8_t pin, uint8_t block);
445
458uint8_t epio_block_can_control_gpio_output(epio_t *epio, uint8_t block, uint8_t pin);
459
470uint64_t epio_get_gpio_output_control(epio_t *epio, uint8_t block);
471
482EPIO_EXPORT uint8_t epio_get_gpio_input(epio_t *epio, uint8_t pin);
483
492EPIO_EXPORT void epio_init_gpios(epio_t *epio);
493
504EPIO_EXPORT void epio_set_gpio_force_input_low(epio_t *epio, uint8_t pin, uint8_t force_low);
505
516EPIO_EXPORT void epio_set_gpio_force_input_high(epio_t *epio, uint8_t pin, uint8_t force_high);
517
528EPIO_EXPORT uint8_t epio_get_gpio_force_input_low(epio_t *epio, uint8_t pin);
529
540EPIO_EXPORT uint8_t epio_get_gpio_force_input_high(epio_t *epio, uint8_t pin);
541
551EPIO_EXPORT void epio_set_gpio_input(epio_t *epio, uint8_t pin);
552
560EPIO_EXPORT void epio_set_gpio_output(epio_t *epio, uint8_t pin);
561
572EPIO_EXPORT void epio_set_gpio_input_level(epio_t *epio, uint8_t pin, uint8_t level);
573
583EPIO_EXPORT void epio_set_gpio_output_level(epio_t *epio, uint8_t pin, uint8_t level);
584
598EPIO_EXPORT uint64_t epio_read_pin_states(epio_t *epio);
599
614EPIO_EXPORT uint64_t epio_read_driven_pins(epio_t *epio);
615
640 epio_t *epio,
641 uint8_t dma_chan,
642 uint8_t read_block,
643 uint8_t read_sm,
644 uint8_t read_cycles,
645 uint8_t write_block,
646 uint8_t write_sm,
647 uint8_t write_cycles,
648 uint8_t bit_mode
649);
650
670EPIO_EXPORT uint8_t epio_sram_read_byte(epio_t *epio, uint32_t addr);
671
683EPIO_EXPORT void epio_sram_set(epio_t *epio, uint32_t addr, uint8_t *data, size_t len);
684
692EPIO_EXPORT uint16_t epio_sram_read_halfword(epio_t *epio, uint32_t addr);
693
701EPIO_EXPORT uint32_t epio_sram_read_word(epio_t *epio, uint32_t addr);
702
710EPIO_EXPORT void epio_sram_write_byte(epio_t *epio, uint32_t addr, uint8_t value);
711
719EPIO_EXPORT void epio_sram_write_halfword(epio_t *epio, uint32_t addr, uint16_t value);
720
728EPIO_EXPORT void epio_sram_write_word(epio_t *epio, uint32_t addr, uint32_t value);
729
758EPIO_EXPORT uint8_t epio_peek_sm_pc(epio_t *epio, uint8_t block, uint8_t sm);
759
771EPIO_EXPORT uint32_t epio_peek_sm_x(epio_t *epio, uint8_t block, uint8_t sm);
772
784EPIO_EXPORT uint32_t epio_peek_sm_y(epio_t *epio, uint8_t block, uint8_t sm);
785
797EPIO_EXPORT uint32_t epio_peek_sm_isr(epio_t *epio, uint8_t block, uint8_t sm);
798
810EPIO_EXPORT uint32_t epio_peek_sm_osr(epio_t *epio, uint8_t block, uint8_t sm);
811
823EPIO_EXPORT uint8_t epio_peek_sm_isr_count(epio_t *epio, uint8_t block, uint8_t sm);
824
838EPIO_EXPORT uint8_t epio_peek_sm_osr_count(epio_t *epio, uint8_t block, uint8_t sm);
839
851EPIO_EXPORT uint8_t epio_peek_sm_osr_empty(epio_t *epio, uint8_t block, uint8_t sm);
852
871EPIO_EXPORT uint8_t epio_peek_sm_stalled(epio_t *epio, uint8_t block, uint8_t sm);
872
889EPIO_EXPORT uint8_t epio_peek_sm_delay(epio_t *epio, uint8_t block, uint8_t sm);
890
903EPIO_EXPORT uint8_t epio_peek_sm_exec_pending(epio_t *epio, uint8_t block, uint8_t sm);
904
916EPIO_EXPORT uint16_t epio_peek_sm_exec_instr(epio_t *epio, uint8_t block, uint8_t sm);
917
930EPIO_EXPORT uint32_t epio_peek_block_irq(epio_t *epio, uint8_t block);
931
942EPIO_EXPORT uint8_t epio_peek_block_irq_num(epio_t *epio, uint8_t block, uint8_t irq_num);
943
959EPIO_EXPORT uint32_t epio_peek_rx_fifo(epio_t *epio, uint8_t block, uint8_t sm, uint8_t entry);
960
976EPIO_EXPORT uint32_t epio_peek_tx_fifo(epio_t *epio, uint8_t block, uint8_t sm, uint8_t entry);
977
996EPIO_EXPORT void epio_set_block_irq(epio_t *epio, uint8_t block, uint8_t irq_num);
997
1008EPIO_EXPORT void epio_clear_block_irq(epio_t *epio, uint8_t block, uint8_t irq_num);
1009
1030EPIO_EXPORT epio_t *epio_from_apio(void);
1031
1052EPIO_EXPORT int epio_disassemble_sm(epio_t *epio, uint8_t block, uint8_t sm, char *buffer, size_t buffer_size);
1053
1057#define NUM_GPIOS 48
1058_Static_assert(NUM_GPIOS <= 64, "NUM_GPIOS must be <= 64 to fit in uint64_t");
1059_Static_assert(NUM_GPIOS == APIO_MAX_GPIOS, "NUM_GPIOS must match APIO_MAX_GPIOS");
1060
1062#define NUM_PIO_BLOCKS 3
1063
1065#define NUM_SMS_PER_BLOCK 4
1066
1068#define MAX_FIFO_DEPTH 4
1069
1071#define NUM_DMA_CHANNELS 16
1072
1074#define NUM_IRQS_PER_BLOCK 8
1075
1077#define NUM_INSTRS_PER_BLOCK 32
1078
1079#endif // EPIO_H
struct epio_t epio_t
Opaque epio instance type.
Definition epio.h:37
#define NUM_GPIOS
Maximum number of supported GPIOs.
Definition epio.h:1057
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 epio_t * epio_from_apio(void)
Create an epio instance configured from the current 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_EXPORT uint64_t epio_get_cycle_count(epio_t *epio)
Return the total number of cycles executed since last reset.
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 void epio_reset_cycle_count(epio_t *epio)
Reset the cycle counter to zero.
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_step_cycles(epio_t *epio, uint32_t cycles)
Advance all enabled state machines by a number of clock cycles.
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 uint32_t epio_pop_rx_fifo(epio_t *epio, uint8_t block, uint8_t sm)
Pop a value from the RX FIFO.
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 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 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 uint32_t epio_pop_tx_fifo(epio_t *epio, uint8_t block, uint8_t sm)
Pop a value from the TX FIFO.
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 epio_t * epio_init(void)
Create and initialise a new epio instance.
EPIO_EXPORT void epio_disable_sm(epio_t *epio, uint8_t block, uint8_t sm)
Disable a state machine.
EPIO_EXPORT void epio_free(epio_t *epio)
Free an epio instance and all associated resources.
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_enable_sm(epio_t *epio, uint8_t block, uint8_t sm)
Enable a state machine for execution.
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 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_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_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 uint64_t epio_read_driven_pins(epio_t *epio)
Read the set of GPIO pins currently being driven by PIO.
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_output(epio_t *epio, uint8_t pin)
Configure a GPIO pin as an output.
uint64_t epio_get_gpio_output_control(epio_t *epio, uint8_t block)
Get the GPIO output control for a block.
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 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.
void epio_set_gpio_input_inverted(epio_t *epio, uint8_t pin, uint8_t inverted)
Set a GPIO pin as inverted or non-inverted.
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.
uint8_t epio_get_gpio_input_inverted(epio_t *epio, uint8_t pin)
Get the inversion state of a GPIO pin.
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.
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.
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.
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.
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 uint64_t epio_read_pin_states(epio_t *epio)
Read the current state of all GPIO pins.
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.
EPIO_EXPORT void epio_init_gpios(epio_t *epio)
Reset all GPIOs to their default (input, pulled-up) state.
EPIO_EXPORT void epio_set_gpio_input(epio_t *epio, uint8_t pin)
Configure a GPIO pin as an input.
void epio_clear_gpio_output_control(epio_t *epio, uint8_t pin, uint8_t block)
Clear GPIO output control for a pin.
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 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 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_x(epio_t *epio, uint8_t block, uint8_t sm)
Get the current X register value 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 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 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 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 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_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_pc(epio_t *epio, uint8_t block, uint8_t sm)
Get the current program counter (PC) for a state machine.
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_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_stalled(epio_t *epio, uint8_t block, uint8_t sm)
Check if a state machine is currently stalled.
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_block_irq(epio_t *epio, uint8_t block)
Get the current IRQ state bitmask for a PIO block.
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 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 uint8_t epio_sram_read_byte(epio_t *epio, uint32_t addr)
Read a byte 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_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 void epio_sram_write_word(epio_t *epio, uint32_t addr, uint32_t value)
Write a word (32-bit) to the emulated SRAM.
Debug information for a single PIO state machine.
Definition epio.h:51
uint8_t start_instr
Definition epio.h:55
uint8_t first_instr
Definition epio.h:53
uint8_t end_instr
Definition epio.h:57
Configurable registers for a single PIO state machine.
Definition epio.h:67
uint32_t shiftctrl
Definition epio.h:73
uint32_t pinctrl
Definition epio.h:75
uint32_t execctrl
Definition epio.h:71
uint32_t clkdiv
Definition epio.h:69