# gpio

> GPIO, PWM, I2C, and SPI access in Langoost for single-board computers like the Raspberry Pi — digital pins, hardware PWM, and the I2C and SPI buses.

# gpio

The `gpio` module drives hardware on single-board computers such as the
Raspberry Pi: digital pins (with internal pull-up/down and blocking edge waits),
hardware PWM, and the I²C and SPI buses. Pins and buses are referenced by an
integer **handle**. Import it with `import gpio`.

## Digital pins

| Function | Signature | Description |
| --- | --- | --- |
| `init` | `gpio.init() → bool` | Initialize the GPIO subsystem |
| `open` | `gpio.open(name: string) → int` | Open a pin by name (e.g. `"GPIO18"`); `-1` if unknown |
| `name` | `gpio.name(h: int) → string` | The pin's name (`""` if unknown) |
| `output` | `gpio.output(h: int, initLevel?: int) → bool` | Set as output; optional initial level `0`/`1` (defaults low) |
| `input` | `gpio.input(h: int, pull?: string) → bool` | Set as input; `pull` is `"up"`, `"down"`, or `"float"` |
| `read` | `gpio.read(h: int) → int` | Read the level (`0` or `1`) |
| `write` | `gpio.write(h: int, level: int) → bool` | Drive the level (`0` or `1`) |
| `waitEdge` | `gpio.waitEdge(h: int, edge: string, timeoutMs: int) → bool` | Block for an edge (`"rising"`, `"falling"`, `"both"`); `false` on timeout |
| `close` | `gpio.close(h: int) → bool` | Release the pin |

## gpio.pwm

Hardware PWM on the BCM2835 channels (GPIO12/13/18/19 on the Pi).

| Function | Signature | Description |
| --- | --- | --- |
| `set` | `gpio.pwm.set(h: int, dutyPct, freqHz) → bool` | Start PWM at a duty cycle (percent) and frequency |
| `stop` | `gpio.pwm.stop(h: int) → bool` | Stop PWM on the pin |

## gpio.i2c

| Function | Signature | Description |
| --- | --- | --- |
| `open` | `gpio.i2c.open(busNum: int) → int` | Open an I²C bus; `-1` on error |
| `write` | `gpio.i2c.write(h: int, addr: int, bytes: string) → bool` | Write bytes to a device |
| `read` | `gpio.i2c.read(h: int, addr: int, n: int) → string` | Read `n` bytes from a device |
| `tx` | `gpio.i2c.tx(h: int, addr: int, tx: string, nRead: int) → string` | Combined write-then-read with a repeated start (register-pointer sensors) |
| `close` | `gpio.i2c.close(h: int) → bool` | Close the bus |

## gpio.spi

| Function | Signature | Description |
| --- | --- | --- |
| `open` | `gpio.spi.open(bus: int, cs: int, speedHz: int, mode: int) → int` | Open an SPI device; `-1` on error |
| `transfer` | `gpio.spi.transfer(h: int, txBytes: string) → string` | Full-duplex transfer; returns the received bytes |
| `close` | `gpio.spi.close(h: int) → bool` | Close the device |

## Example

```goost
import gpio
import time

gpio.init()

// blink an LED on GPIO18
let led = gpio.open("GPIO18")
gpio.output(led)

let i = 0
while i < 10 {
    gpio.write(led, 1)
    time.timer.sleep(250)
    gpio.write(led, 0)
    time.timer.sleep(250)
    i += 1
}

// read a button on GPIO23 with an internal pull-up, wait for a press
let btn = gpio.open("GPIO23")
gpio.input(btn, "up")
if gpio.waitEdge(btn, "falling", 5000) {
    println("pressed")
}

gpio.close(led)
gpio.close(btn)
```