Skip to content

API GPIO

THE_ORONCO edited this page May 21, 2022 · 3 revisions

GPIO

GPIO stands for "General Purpose Input Output", and allows machines to communicate with each other. PICO-8 maps bytes in the range 0x5f80โ€ฆ0x5fff to GPIO pins that can be

POKE()ed (to output a value -- e.g. to make an LED light up) or PEEK()ed (e.g. to read the state of a switch).

GPIO means different things for different host platforms:

platform mapping
CHIP 0x5f80โ€ฆ0x5f87 mapped to xio-p0โ€ฆxio-p7
Pocket CHIP 0x5f82โ€ฆ0x5f87 mapped to GPIO1โ€ฆGPIO6. xio-p0 & p1 are exposed inside the prototyping area inside the case.
Raspberry Pi 0x5f80โ€ฆ0x5f9f mapped to wiringPi pins 0โ€ฆ31. See http://wiringpi.com/pins/ for mappings on different models. Also: watch out for BCM vs. WiringPi GPIO indexing!

CHIP and Raspberry Pi values are all digital: 0 (LOW) and 255 (HIGH)

A program to blink any LEDs attached on and off:

T = 0
FUNCTION _DRAW()
    CLS(5)
    FOR I=0,7 DO
    VAL = 0
    IF (T % 2 < 1) VAL = 255
    POKE(0X5F80 + I, VAL)
    CIRCFILL(20+I*12,64,4,VAL/11)
    END
    T += 0.1
END

Serial

For more precise timing, the SERIAL() command can be used. GPIO writes are buffered and dispatched at the end of each frame, allowing clock cycling at higher and/or more regular speeds than is possible by manually bit-banging using POKE() calls.

SERIAL(CHANNEL, ADDRESS, LENGTH)

CHANNEL description
0x000โ€ฆ0x0fe corresponds to GPIO pin numbers; send 0x00 for LOW or 0xFF for HIGH
0x0ff delay; length is taken to mean "duration" in microseconds (excl. overhead)
0x400โ€ฆ0x401 ws281x LED string (experimental)

ADDRESS: The PICO-8 memory location to read from / write to.

LENGTH: Number of bytes to send. 1/8ths are allowed to send partial bit strings.

For example, to send a byte one bit at a time to a typical APA102 LED string:

VAL = 42          -- VALUE TO SEND
DAT = 16 CLK = 15 -- DATA AND CLOCK PINS DEPEND ON DEVICE
POKE(0X4300,0)    -- DATA TO SEND (SINGLE BYTES: 0 OR 0XFF)
POKE(0X4301,0XFF)
FOR B=0,7 DO
    -- SEND THE BIT (HIGH FIRST)
    SERIAL(DAT, BAND(VAL, SHL(1,7-B))>0 AND 0X4301 OR 0X4300, 1)
    -- CYCLE THE CLOCK
    SERIAL(CLK, 0X4301)
    SERIAL(0XFF, 5) -- DELAY 5
    SERIAL(CLK, 0X4300)
    SERIAL(0XFF, 5) -- DELAY 5
END

Additional channels are available for bytestreams to and from the host operating system. These are intended to be most useful for UNIX-like environments while developing toolchains, and are not available while running a BBS or exported cart [1]. Maximum transfer rate in all cases is 64k/sec (blocks CPU).

CHANNEL description
0x800 dropped file (stat(120) returns TRUE when data is available)
0x802 dropped image (stat(121) returns TRUE when data is available)
0x804 stdin
0x805 stdout
0x806 file specified with: pico8 -i filename
0x807 file specified with: pico8 -o filename

Image files dropped into PICO-8 show up on channel 0x802 as a bytestream with a special format: The first 4 bytes are the image's width and height (2 bytes each little-endian, like PEEK2), followed by the image in reading order, one byte per pixel, colour-fitted to the display palette at the time the file was dropped.

[1] Channels 0x800 and 0x802 are available from exported binaries, but with a maximum file size of 256k, or 128x128 for images.

HTML

Cartridges exported as HTML / .js use a global array of integers (pico8_gpio) to represent GPIO pins. The shell HTML should define the array:

var pico8_gpio = Array(128);
Clone this wiki locally