Beyond GPIO and servo control, Origin provides first-class syntax for the three serial protocols that are standard on every Raspberry Pi: I2C, SPI, and UART. These protocol primitives follow the same parenthesis-free, English-like style as all Origin statements. WriteDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/boblio-max/origin/llms.txt
Use this file to discover all available pages before exploring further.
i2c.read 0x40, 0x00 and Origin generates the correct smbus2 call under the hood — no imports, no bus setup, and no teardown required in your script.
Parenthesis-Free Syntax
All three protocol namespaces use dot-method syntax with space- or comma-separated arguments — the same convention asset pin and set servo.angle. Arguments follow the method name directly, and parentheses are optional:
i2c, spi, and uart as hardware primitive namespaces and produces a HardwarePrimitiveNode in the AST. The interpreter then emits a call to the corresponding _execute_<namespace>_<method>(...) Python runtime function — for example, i2c.read 0x40, 0x00 becomes _execute_i2c_read(64, 0).
I2C
I2C (Inter-Integrated Circuit) is a two-wire serial bus. On the Raspberry Pi, I2C1 uses BCM GPIO 2 (SDA, physical pin 3) and BCM GPIO 3 (SCL, physical pin 5). Most sensors, display drivers, and PWM controllers (like the PCA9685) communicate over I2C. Origin’s I2C primitives are backed by the smbus2 library. Each call opens bus 1, performs the read or write, and returns. The underlying smbus2 calls are:i2c.read <addr>, <reg>→bus.read_byte_data(addr, reg)— reads one byte from registerregi2c.read <addr>, <reg>, <size>→bus.read_i2c_block_data(addr, reg, size)— readssizebytes starting atregi2c.write <addr>, <reg>, <data>→bus.write_byte_data(addr, reg, data)(integer) orbus.write_i2c_block_data(addr, reg, data)(list)
Read
addr— the 7-bit I2C device address (e.g.0x40)reg— the register address to read from (e.g.0x00)size— optional number of bytes to read; defaults to1
size is 1, or a list of bytes when size is greater than 1.
Example — read one byte from register 0x00 of an I2C temperature sensor at address 0x48:
0x00 from a device at 0x40:
Write
addr— the 7-bit I2C device addressreg— the register address to write todata— an integer byte value or a list of bytes
0x01 to register 0x00 of a sensor at 0x48:
0x00 of a device at 0x40:
Hexadecimal Addresses
Origin’s lexer handles hexadecimal literals natively. Addresses like0x40, 0x48, 0x68, and 0x76 are parsed as integers — no conversion or prefix stripping needed:
I2C requires the interface to be enabled on your Raspberry Pi. Run
sudo raspi-config, go to Interface Options → I2C, and enable it. You may need to reboot. The smbus2 library must also be installed: pip install smbus2. When smbus2 is not installed, i2c.read silently returns 0 and i2c.write does nothing.SPI
SPI (Serial Peripheral Interface) is a four-wire synchronous bus commonly used for high-speed devices such as ADCs, DACs, displays, and SD card controllers. The Raspberry Pi exposes SPI0 on BCM pins 10 (MOSI), 9 (MISO), 11 (SCLK), and 8 (CE0). Origin’s SPI primitives generate calls to_execute_spi_read(n) and _execute_spi_write(data) in the translated Python output.
Read
n bytes from the SPI bus.
Example — read 2 bytes from a connected SPI ADC:
Write
data to the SPI bus.
Example — send a command byte to an SPI device:
Enable SPI in
raspi-config under Interface Options → SPI before using spi.read or spi.write. SPI requires the target device to be correctly wired to the Pi’s SPI0 header.UART
UART (Universal Asynchronous Receiver-Transmitter) provides serial communication over two wires: TX (transmit) and RX (receive). On the Raspberry Pi, the primary UART is available on BCM GPIO 14 (TX, physical pin 8) and BCM GPIO 15 (RX, physical pin 10). Origin’s UART primitives generate calls to_execute_uart_read(n) and _execute_uart_write(data) in the translated Python output.
Read
n bytes from the UART serial port.
Example — read a single byte from a UART-connected device:
Write
data to the UART serial port.
Example — send a command byte to a UART peripheral:
Enable UART in
raspi-config under Interface Options → Serial Port. Disable the serial console but enable the serial hardware interface when prompted. On some Pi models the default UART is shared with Bluetooth; consult the official Raspberry Pi documentation for your specific board to redirect the primary UART if needed.Complete Example: Reading an I2C Sensor in a Loop
This script reads a single-byte measurement from register0x00 of an I2C sensor at address 0x48 every second and prints the raw value, repeating twenty times.
Wire the I2C sensor
Connect the sensor’s SDA to physical pin 3 (BCM 2) and SCL to physical pin 5 (BCM 3). Connect VCC and GND to appropriate 3.3 V and GND pins.
Confirm the device address
Run
i2cdetect -y 1 on your Pi. Your sensor should appear at 0x48 in the output grid. If it appears at a different address, update sensor_addr in the script accordingly.Enable I2C and install smbus2
Enable I2C in
raspi-config if not already done, then run pip install smbus2.