Table of contents
- I2C Port Numbers
- Examples and Tools
- 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: https://gitlab.com/voxl-public/libvoxl_io/blob/master/lib/include/voxl_io.h
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
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 Description: Command line tool for using i2c functionality via SDSP Usage: 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
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 : do voxl-i2c read 6 400000 0x68 59 14 done
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_iois already loaded in SDSP) or up to 100+ms (if
libvoxl_iois not loaded on SDSP).
- Once I2C port is open, reading / writing (
voxl_i2c_write) should take 1-2ms (assuming
libvoxl_iois already loaded in SDSP). However, since
voxl-i2ctool opens and closes the port every time, the minimum call time for
voxl-i2cread 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_ioon SDSP. SDSP will clean up and unload any library which is not used.
- For example, calling
voxl-i2cmultiple times (one after another) will result in loading and unloading
libvoxl_ioeach time, unless another process is continuously using
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.