ON THIS PAGE

  • OAK4 SoM Development Guide
  • Device Tree Overlay Configuration
  • I2C Configuration Example
  • Connecting a BME280 Sensor via I2C
  • Compiling the Overlay
  • SPI Configuration Example
  • Troubleshooting

OAK4 SoM Development Guide

Luxonis OAK 4 SoM device supports flexible peripheral configuration, allowing users to enable or disable I2C, SPI, and UART functionality on a variety of pins.By default, most pins are configured as general-purpose I/O (GPIO). However, users can reconfigure supported pins to function as peripheral interfaces. It's important to note that not all pins support all peripherals. The table below outlines which QUPv3 and I2CHUB engines are available and how each can be configured.If your use case requires a configuration not listed in the table or if the pins are marked as "Not currently exposed", please contact Luxonis technical support to help with creating a custom configuration with different exposed options.
QUPv3 engineModePinsNote
QUPv3_SE0I2C
  • SDA: GPIO28
  • SCL: GPIO29
QUPv3_SE1SPI
  • MISO: GPIO32
  • MOSI: GPIO33
  • SCLK: GPIO34
  • CS0: GPIO35
QUPv3_SE2SPI
  • MISO: GPIO36
  • MOSI: GPIO37
  • SCLK: GPIO38
  • CS0: GPIO39
  • CS1: GPIO40
  • CS2: GPIO41
  • CS3: GPIO42
QUPv3_SE3//Not currently exposed
QUPv3_SE4I2C
  • SDA: GPIO44
  • SCL: GPIO45
Enabled by default
QUPv3_SE5I2C
  • SDA: GPIO52
  • SCL: GPIO53
QUPv3_SE6//Not currently exposed
QUPv3_SE7UART
  • TX: GPIO26
  • RX: GPIO27
QUPv3_SE8I2C
  • SDA: GPIO0
  • SCL: GPIO1
QUPv3_SE9I3C
  • SDA: GPIO60
  • SCL: GPIO61
QUPv3_SE10SPI
  • MISO: GPIO64
  • MOSI: GPIO65
  • SCLK: GPIO66
  • CS0: GPIO67
QUPv3_SE11SPI
  • MISO: GPIO68
  • MOSI: GPIO69
  • SCLK: GPIO70
  • CS0: GPIO71
QUPv3_SE12I2C
  • SDA: GPIO2
  • SCL: GPIO3
Enabled by default
QUPv3_SE13//Not currently exposed
QUPv3_SE14UART
  • CTS: GPIO76
  • RFR: GPIO77
  • TX: GPIO78
  • RX: GPIO79
High-speed UART, hardware flow control
QUPv3_SE15//Not currently exposed
I2CHUB_SE0//Not currently exposed
I2CHUB_SE1//Not currently exposed
I2CHUB_SE2I2C
  • SDA: GPIO20
  • SCL: GPIO21
Enabled by default
I2CHUB_SE3I2C
  • SDA: GPIO22
  • SCL: GPIO23
I2CHUB_SE4I2C
  • SDA: GPIO4
  • SCL: GPIO5
I2CHUB_SE5//Not currently exposed
I2CHUB_SE6//Not currently exposed
I2CHUB_SE7//Not currently exposed
I2CHUB_SE8//Not currently exposed
I2CHUB_SE9//Not currently exposed

Device Tree Overlay Configuration

Peripheral configuration is achieved through Device Tree Overlays (DTOs), which are applied at boot time. Overlays must be placed in the /persist/custom/dtbo directory on the device. During boot, the system applies all overlays found in this directory to achieve the desired pin configuration. Files in this folder also survive OTA update and do not get deleted.

I2C Configuration Example

Connecting a BME280 Sensor via I2C

Suppose you want to connect a Bosch BME280 pressure sensor using GPIO52 (SDA) and GPIO53 (SCL). According to the table above, these pins are managed by the QUPv3 SE5 engine.To enable this interface, create a device tree overlay (e.g. bme280.dts) in your working directory:
Dts
1/dts-v1/;
2/plugin/;
3
4/ {
5  fragment@0 {
6    target = <&qupv3_se5_i2c>;
7    __overlay__ {
8      status = "ok";
9      #address-cells = <1>;
10      #size-cells = <0>;
11
12      bme280@76 {
13        compatible = "bosch,bme280";
14        reg = <0x76>;
15      };
16    };
17  };
18};
The important line is status = "ok"; which actually enables the selected I2C engine. Without it, the peripheral remains disabled.
Note: For target, use &qupv3_seX_i2c for QUP engines, and &qupv3_hub_i2cX for HUB engines, where X is the engine index.

Compiling the Overlay

Use the SDK Docker container to compile the source. Run the following inside your working directory:
Command Line
1docker run --rm \
2  -v /etc/passwd:/etc/passwd:ro \
3  -v /etc/shadow:/etc/shadow:ro \
4  -v "$PWD":"$PWD" \
5  -w "$PWD" \
6  --user=$(id -u):$(id -g) --group-add 27 \
7  luxonis/luxonis-os-rvc4:<SDK_version>-public \
8  /bin/bash -c "dtc -@ -I dts -O dtb -o bme280.dtbo bme280.dts"
Note: <SDK_version> must match the version of OS with which the target device was flashed (eg. 1.8.0). You can also use latest if you are using the latest OS release.
Transfer the compiled .dtbo file to the target device:
Command Line
1scp /app/test-overlay/bme280.dtbo user@<device-ip>:/persist/custom/dtbo/
Then reboot the device. Upon boot, the overlay will be applied automatically. Verify that the I2C device has been registered by inspecting /sys/bus/i2c/devices/.

SPI Configuration Example

Enabling an SPI interface follows the same approach. Here's an example DTO for enabling SPI on QUPv3 SE1:
Dts
1/dts-v1/;
2/plugin/;
3
4/ {
5  fragment@0 {
6    target = <&qupv3_se1_spi>;
7    __overlay__ {
8      status = "ok";
9    };
10  };
11};
Compile and transfer the overlay:
Command Line
1docker run --rm \
2  -v /etc/passwd:/etc/passwd:ro \
3  -v /etc/shadow:/etc/shadow:ro \
4  -v "$PWD":"$PWD" \
5  -w "$PWD" \
6  --user=$(id -u):$(id -g) --group-add 27 \
7  luxonis/luxonis-os-rvc4:latest-public \
8  /bin/bash -c "dtc -@ -I dts -O dtb -o spi-overlay.dtbo spi-overlay.dts"
Command Line
1scp spi_se1.dtbo user@<device-ip>:/persist/custom/dtbo/
Reboot the device and the SPI interface should be enabled.

Troubleshooting

If an unsupported peripheral configuration is attempted—e.g., assigning a peripheral to an incompatible QUPv3 engine—the device may fail to boot. In such cases, the TrustZone engine is preventing the system from proceeding.To recover:
  1. Enter Emergency Download Mode (EDL).
  2. Re-flash the device with a known-good image.
For steps on how to perform Full OS Flash, check out the following page: Full OS Flash.To aid in debugging, inspect kernel messages using dmesg:
Command Line
1dmesg | less
Look for errors related to device tree parsing, peripheral activation, or security policy violations. Optionally, check the logs from device tree overlay loading script:
Command Line
1journalctl -u apply-overlays.service