Link Search Menu Expand Document


Table of contents

  1. Overview
  2. I2C Port Numbers
  3. Examples and Tools
    1. voxl-i2c
    2. 16-bit and 32-bit Register Access
  4. Performance
  5. Warnings and Limitations


All I2C ports that are broken out on VOXL’s headers are internally mapped to the Sensors DSP (SDSP). This also means that you cannot use I2C ports via /dev/i2c* as other embedded Linux systems may allow. We provide a simple library, libvoxl-io to enable communication with I2C functionality from the applications processor (Linux userspace). This layer hides the SDSP RPC calls and allows compiling programs that use I2C without the need of Hexagon DSP toolchain or build environment.

The libvoxl-io library header and API description can be found here:

The library is included with the VOXL Software Bundle.

I2C Port Numbers

I2C port numbers correspond directly with the BLSP numbers. Please see datasheet page for more details.

  • J1 : I2C8 (5V levels)
  • J7 : I2C6
  • J10 : I2C7
  • N/A : I2C3 is used to connect to on-board pressure sensor BMP-280
  • there are additional I2C ports, used for communication with cameras, and are not available to VOXL users.
  • J11 : I2C12 (WARNING I2C12 is not functioning. It is disabled in libvoxl_io)

Examples and Tools


This tool allows you to scan, read or write data from/to devices on I2C port from linux command line.

~ # voxl-i2c

	Command line tool for using i2c functionality via SDSP

  voxl-i2c scan <i2c_bus> <bit_rate> [register_address=0]
	Scan all i2c addresses (0-126)
	Print the value of specified register for detected devices

  voxl-i2c read <i2c_bus> <bit_rate> <i2c_address> <start_register> <read_size>
	Read data from i2c slave starting from start_register and print their values

  voxl-i2c write <i2c_bus> <bit_rate> <i2c_address> <start_register> <data>
	Write data to i2c slave starting from start_register
	Data should be provided as space-delimited array of uint8's

Usage Examples:

Read example (read some calibration data from on-board pressure sensor BMP-280 )

~ # voxl-i2c read 3 400000 118 0x88 10
7 110 144 104 24 252 222 148 40 214

Read and write example in a bash script (set up MPU6050 IMU and read raw data (assume sensor connected externally to I2C6))

set -e

#set mpu6050 to run mode
voxl-i2c write 6 400000 0x68 107 0
sleep 0.1

#set up sampling rates, gyro and accel ranges
voxl-i2c write 6 400000 0x68 26 0 0x18 0x18

#read 14 bytes (3 gyro, 3 accel, 1 temperature values.. 2 bytes each)
while :
        voxl-i2c read 6 400000 0x68 59 14

The output should be something like this..

0 25 1 101 8 51 243 16 255 188 0 2 0 2
0 21 1 83 8 55 243 32 255 218 255 242 0 1
0 19 1 84 8 38 243 48 255 191 0 2 0 4

16-bit and 32-bit Register Access

Accessing 16-bit (and 32-bit) registers is supported by libvoxl_io. However, please note that the register address is sent Least Significant Byte (LSB) first. So, if you are accessing a 16-bit register and the i2c device is expecting MSB first, then you need to byte swap order of byte0 and byte1 in the 4-byte register address before providing it to the i2c read/write calls. In case of 32-bit registers, the order of all 4 bytes needs to be reversed if i2c device expects MSB first.


  • Initializing I2C port (voxl_i2c_init) can take around 15-20 ms (if libvoxl_io is already loaded in SDSP) or up to 100+ms (if libvoxl_io is not loaded on SDSP).
  • Once I2C port is open, reading / writing (voxl_i2c_read and voxl_i2c_write) should take 1-2ms (assuming libvoxl_io is already loaded in SDSP). However, since voxl-i2c tool opens and closes the port every time, the minimum call time for voxl-i2c read or write is 20ms and can be higher depending on CPU load.
  • Actual I2C read and write calls on SDSP are much quicker (about 250us to execute one-byte read or write transaction), but CPU<->SDSP communication introduces additional delay, resulting in 1-2ms as seen on the CPU side.
  • “Loaded on SDSP” means there is another process currently using libvoxl_io on SDSP. SDSP will clean up and unload any library which is not used.
  • For example, calling voxl-i2c multiple times (one after another) will result in loading and unloading libvoxl_io each time, unless another process is continuously using libvoxl_io.

Warnings and Limitations

  • An I2C port should not be open concurrently by several processes, otherwise undesired behavior may occur (such as one process closing the port while another is still using it - would result in second process unable to continue using the process).
  • Concurrent usage of the same port by multiple processes is not prohibited by libvoxl_io, but has to be handled carefully, especially opening and closing the port. TODO: need to check what happens if you read / write at the same time from different threads / processes.

Next: VOXL Fan Control