Skip to content
Frank Bauernöppel edited this page Mar 3, 2017 · 18 revisions

configuration

Check that local.conf contained a line

ENABLE_I2C = "1"

when the image was built.

On the running RasPi: check/enable I2C in the config.txt file (reboot needed after change)

dtparam=i2c_arm=on         
dtparam=i2c_arm_baudrate=100000

dmesg | grep -i i2c should show a line like

[    1.998278] bcm2708_i2c 3f804000.i2c: BSC1 Controller at 0x3f804000 (irq 83) (baudrate 100000)

lsmod should show that kernel module i2c_bcm2708 is loaded.

testing I2C form the command line

To use the i2c-tools, load kernel module i2c-dev:

modprobe i2c-dev

And check for i2c devices on i2c bus 1, the i2c bus available on the expansion header:

root@raspberrypi3:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         

No i2c devices are connected in this example, but you may see i2c probing by using a scope.

using I2C from a C program

InvenSense MPU-9250

  • 9-axis sensor: 3-axis gyroscope, 3-axis accelerometer and 3-axis compass
  • on-chip µC capable of processing sensor fusion algorithms

Available on a convenient SparkFun IMU Breakout - MPU-9250 board: https://learn.sparkfun.com/tutorials/mpu-9250-hookup-guide

By default, the chip uses I2C address 0x68. After reset, register 0x75 ("WHO_AM_I") contains a unique value: 0x71.

edit a new file

root@raspberrypi3:~# vi mpu9250.c
#include <stdio.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>

int main()
{

  int file = open( "/dev/i2c-1", O_RDWR);
  if (file < 0) perror("open"); //TODO: error handling

  unsigned char inbuf[1];
  unsigned char outbuf[1];
  struct i2c_rdwr_ioctl_data packets;
  struct i2c_msg msg[2];

  // prepare the first i2c request (a write)
  msg[0].addr  = 0x68; // device address
  msg[0].flags = 0;    // type of request: 0=write
  msg[0].len   = sizeof(outbuf); // number of bytes to write
  msg[0].buf   = outbuf; // pointer to the first data byte
  outbuf[0]    = 0x75; // first data byte: register to read

  msg[1].addr  = 0x68; // device address
  msg[1].flags = I2C_M_RD | I2C_M_NOSTART; // read request without an intermediate start condition
  msg[1].len   = sizeof(inbuf);  // number of bytes to read
  msg[1].buf   = inbuf; // // pointer to the first byte to read

  // send both requests to the device
  packets.msgs      = msg;
  packets.nmsgs     = 2;
  if(ioctl(file, I2C_RDWR, &packets) < 0) perror("ioctl"); //TODO: error handling

  close(file);

  printf("reg[0x%02x]=0x%02x\n", outbuf[0], inbuf[0] );

  return 0;
}

compile with

root@raspberrypi3:~# gcc -o mpu9250 mpu9250.c

and run it

root@raspberrypi3:~# ./mpu9250
reg[0x75]=0x71

DS1307 real-time-clock

see http://www.netzmafia.de/skripten/hardware/RasPi/Projekt-RTC/

using I2C from a kernel module

PCA9685 LED (PWM) driver expander

https://github.com/raspberrypi/linux/blob/rpi-4.9.y/drivers/pwm/pwm-pca9685.c

DS1307 real-time-clock

driver: https://github.com/raspberrypi/linux/blob/rpi-4.9.y/drivers/rtc/rtc-ds1307.c

Clone this wiki locally