User Tools

Site Tools


PIO (dis)assembler for RP2040

The idea:

PIO stand for Programmable Input Output. These are programmable state machines with a small shared program memory. Programs are built with only eight instructions. The behavior of those instructions can be modified with registers.

We define a (standalone) PIO forth style (dis)assembler for the RP2040. It can be used for writing direct executable programs and exportable HEX programs. These HEX programs can be used in conjunction with the mini-PIO control program.

One PIO state machine


The example code asumes a 32-bit machine that has 32-bit compile actions. It is also asumed that the code runs in RAM as noForth T on the RP2040 does. All PIO fuctionality can be used, and a PIO-module EXPORT function is provided. The PIO-assembler is (de)activated by the words {PIO and PIO}. Missing words in Generic Forth are:

+TO         ( n "name" -- )     - Add n to the contents of the value "name"
VOCABULARY  ( "name" -- )       - Define a named wordlist

The structure of PIO opcodes

Pink   = Opcode field
Yellow = Delay and/or side set field
Green  = Destination field
Blue   = Data field


All PIO instructions

✦ PIO opcodes
    in,         out,        push,       pull,       mov,        wait,
    irq,        set,        nop,        pio,        
✦  Optional arguments for each opcode
    []         side
✦ Conditionals
    x0<>?       x--?        y0<>?       y--?        x=y?        pin?
✦ Control structures
    if,         else,       then,      begin,      while,      repeat,
    again,      until,
✦ Labels
    one         two         one>        two>
✦ PIO directives
    clean-pio   =pio        sm          sync        restart
    =org        =set-pins   =out-pins   =side-pins  opt
    =in-pin     =jmp-pin    =inputs     =strength   side-pindirs
    wrap-target wrap        =steal      =autopush   =autopull
    =in-dir     =out-dir    clone       =exec       =clock-div
    =freq       export
✦ PIO external tools (mini-PIO.f)
    tx-depth    rx-depth    >txf        rxf>        set-pio
    sm-on       exec        freq        clock-div   sync
✦ PIO disassembler & state machine data
    mpsee       psee        .fifo       .sm

Usage example

An extra RS232 output driver in only 5 instructions!

: =BAUD ( b -- )    8 *  =freq ; \ Set baudrate for UART

clean-pio                   \ Empty code space, start at zero
0 0 {pio                    \ Use state machine-0 on PIO-0
    115200 =baud            \ 115k2
    26 1 =side-pins  opt    \ GPIO 26 for optional SIDE
    26 1 =out-pins          \ GPIO 26 for OUT & SET
    26 1 =set-pins
    1 pindirs set,              \ Pin is output!
        7 []  1 side  pull,     \ Stop bit, get data byte
        7 []  0 side 7 x set,   \ Start bit
            1 pins out,         \ Shift 8 bits out
        6 []  x--? until,       \ Until 8 bits are done
    0 =exec                 \ Start SM-0 code at address 0

UART control code

: PEMIT ( ch -- )   begin  0 tx-depth  3 < until  0 >txf ;
: PTYPE ( a u -- )  0 ?do  count pemit  loop  drop ;
: ABC   ( -- )      s" ABC " ptype ;


Back to PFW page


Alternative Implementations

Back to PFW page

en/pfw/assemblers_pio-assembler.txt · Last modified: 2023-09-05 06:33 by