Difference between revisions of "Beaglebone black i2c"

From Teknologisk videncenter
Jump to: navigation, search
m (I2C Low level)
m (I2C Low level)
Line 23: Line 23:
  
 
<source lang=c>
 
<source lang=c>
/*
 
 
  * Module...: seeed_dip6.c
 
  * Module...: seeed_dip6.c
 
  * Version..: 0.1 (Beta - unfinished)
 
  * Version..: 0.1 (Beta - unfinished)
Line 44: Line 43:
 
  */
 
  */
 
#include <stdio.h>
 
#include <stdio.h>
 +
 
#include <unistd.h>
 
#include <unistd.h>
 +
 
#include <sys/ioctl.h>
 
#include <sys/ioctl.h>
 +
 
#include <stdlib.h>
 
#include <stdlib.h>
 +
 
#include <errno.h>
 
#include <errno.h>
 +
 
#include <string.h>
 
#include <string.h>
 +
 
#include <sys/ioctl.h>
 
#include <sys/ioctl.h>
 +
 
#include <linux/i2c.h>
 
#include <linux/i2c.h>
 +
 
#include <linux/i2c-dev.h>
 
#include <linux/i2c-dev.h>
 +
 
#include <sys/types.h>
 
#include <sys/types.h>
 +
 
#include <sys/stat.h>
 
#include <sys/stat.h>
 +
 
#include <fcntl.h>
 
#include <fcntl.h>
 
  
  
 
//Device specific information. (Perhaps better as command options or config file)
 
//Device specific information. (Perhaps better as command options or config file)
#define I2C_BUS     "/dev/i2c-2"
+
#define I2C_BUS "/dev/i2c-2"
#define I2C_ADDR       0x03   // Grove DIP-switch 6 slave address default
+
#define I2C_ADDR 0x03 // Grove DIP-switch 6 slave address default
  
int main( void ) {
+
int main(void) {
        int file;
+
  int file;
                int nmsgs_sent;
+
  int nmsgs_sent;
                unsigned int len;
+
  unsigned int len;
                int i;
+
  int i;
                char buf[2][20];
+
  char buf[2][20];
                struct i2c_msg msgs[I2C_RDRW_IOCTL_MAX_MSGS]; // I2C_RDRW_IOCTL_MAX_MSGS defined in linx/i2c-dev.h
+
  struct i2c_msg msgs[I2C_RDRW_IOCTL_MAX_MSGS]; // I2C_RDRW_IOCTL_MAX_MSGS defined in linx/i2c-dev.h
                struct i2c_rdwr_ioctl_data rdwr;
+
  struct i2c_rdwr_ioctl_data rdwr;
  
                // init msgs's
+
  // init msgs's
                for (i = 0; i < I2C_RDRW_IOCTL_MAX_MSGS; i++)
+
  for (i = 0; i < I2C_RDRW_IOCTL_MAX_MSGS; i++)
                msgs[i].buf = NULL;
+
    msgs[i].buf = NULL;
  
 +
  // Maybe errer just assumes bus number
 +
  file = open(I2C_BUS, O_RDWR);
 +
  if (file < 0) { // If error
 +
    fprintf(stderr, "ERROR: opening %s - %s\n", I2C_BUS, strerror(errno));
 +
    exit(1);
 +
  }
  
                // Maybe errer just assumes bus number
+
  if (file < 0)
                file = open(I2C_BUS,O_RDWR);
+
    fprintf(stderr, "ERROR: open_i2c_dev failed: %s", strerror(errno));
        if (file < 0) { // If error
 
                        fprintf(stderr, "ERROR: opening %s - %s\n", I2C_BUS, strerror(errno));
 
            exit(1);
 
        }
 
  
                if (file < 0)
+
  // Build IOCTL operation message structure. (What you want to do)
                        fprintf(stderr,"ERROR: open_i2c_dev failed: %s", strerror(errno));
 
  
                // Build IOCTL operation message structure. (What you want to do)
+
  //msgs[0] Write one byte - Command in buf[0] - flags 0 = write
 +
  msgs[0].addr = I2C_ADDR;
 +
  msgs[0].flags = 0;
 +
  msgs[0].len = 1;
 +
  msgs[0].buf = buf[0];
 +
  buf[0][0] = 0x01;
  
                //msgs[0] Write one byte - Command in buf[0] - flags 0 = write
+
  //msgs[1] read 10 bytes to buf
                msgs[0].addr = I2C_ADDR;
+
  msgs[1].addr = I2C_ADDR;
                msgs[0].flags = 0;
+
  msgs[1].flags = 1;
                msgs[0].len = 1;
+
  msgs[1].len = 10;
                msgs[0].buf = buf[0];
+
  msgs[1].buf = buf[1];
                buf[0][0] = 0x01;
 
  
                //msgs[1] read 10 bytes to buf
+
  rdwr.msgs = msgs;
                msgs[1].addr = I2C_ADDR;
+
  rdwr.nmsgs = 2;
                msgs[1].flags = 1;
+
  nmsgs_sent = ioctl(file, I2C_RDWR, & rdwr);
                msgs[1].len = 10;
+
  if (nmsgs_sent != 2) {
                msgs[1].buf = buf[1];
+
    fprintf(stderr, "ERRORi in line %d: Wrong number of messages: %d\n", __LINE__, nmsgs_sent);
 
+
    exit(0);
 
+
  }
                rdwr.msgs = msgs;
+
  for (i = 0; i < 10; i++)
                rdwr.nmsgs = 2;
+
    printf("Read 0x2d: %x\n", buf[1][i]);
                nmsgs_sent = ioctl(file, I2C_RDWR, &rdwr);
+
  return (0);
                if (nmsgs_sent != 2) {
 
                        fprintf(stderr, "ERRORi in line %d: Wrong number of messages: %d\n",__LINE__,nmsgs_sent);
 
                        exit(0);
 
                }
 
                for (i=0; i < 10; i++)
 
                        printf("Read 0x2d: %x\n", buf[1][i]);
 
        return(0);
 
 
}
 
}
 
 
</source>
 
</source>
  

Revision as of 15:05, 11 November 2023


Detect i2c devices

Use with a little care - read the i2cdetect man page

root@beaglebone:/home/debian/bin# i2cdetect -y -r 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
  • --" Means no answer on probe
  • "UU" Means probing was skipped, because a device driver uses the address
  • "Number" - A n i2c device was found

I2C Low level

See: /usr/include/linux/i2c.h for i2c_msg structure and flags and i2c_rdwr_ioctl_data

 * Module...: seeed_dip6.c
 * Version..: 0.1 (Beta - unfinished)
 * Author...: Henrik Thomsen/Mercantec <heth@mercantec.dk
 * Date.....: 10. nov 2023
 *
 * Abstract.: Implementation of Seeed Grove Sensor "I2C High
 *            Accuracy Temperature sensor" based on MCP-9808
 *            Implementet in user space using libi2c
 * Mod. log.: 01-06-2021: Could not compile. Got i2c_smbus_read_word_data undefined.
                              Include <i2c/smbus.h> should be include. (Worked in 2020)

 * License..: Free open software but WITHOUT ANY WARRANTY.
 * Terms....: see http://www.gnu.org/licenses
 *
 * Documentation - see https://mars.merhot.dk/w/index.php/Grove_I2C_High_Accuracy_Temerature_Sensor_-_Seeed
 *
 * REMEMBER: Install the libi2c-dev package to compile this file
 * Compile this example with: gcc -li2c seeed_dip6.c  -o seeed_dip6
 */
#include <stdio.h>

#include <unistd.h>

#include <sys/ioctl.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/ioctl.h>

#include <linux/i2c.h>

#include <linux/i2c-dev.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>


//Device specific information. (Perhaps better as command options or config file)
#define I2C_BUS "/dev/i2c-2"
#define I2C_ADDR 0x03 // Grove DIP-switch 6 slave address default

int main(void) {
  int file;
  int nmsgs_sent;
  unsigned int len;
  int i;
  char buf[2][20];
  struct i2c_msg msgs[I2C_RDRW_IOCTL_MAX_MSGS]; // I2C_RDRW_IOCTL_MAX_MSGS defined in linx/i2c-dev.h
  struct i2c_rdwr_ioctl_data rdwr;

  // init msgs's
  for (i = 0; i < I2C_RDRW_IOCTL_MAX_MSGS; i++)
    msgs[i].buf = NULL;

  // Maybe errer just assumes bus number
  file = open(I2C_BUS, O_RDWR);
  if (file < 0) { // If error
    fprintf(stderr, "ERROR: opening %s - %s\n", I2C_BUS, strerror(errno));
    exit(1);
  }

  if (file < 0)
    fprintf(stderr, "ERROR: open_i2c_dev failed: %s", strerror(errno));

  // Build IOCTL operation message structure. (What you want to do)

  //msgs[0] Write one byte - Command in buf[0] - flags 0 = write
  msgs[0].addr = I2C_ADDR;
  msgs[0].flags = 0;
  msgs[0].len = 1;
  msgs[0].buf = buf[0];
  buf[0][0] = 0x01;

  //msgs[1] read 10 bytes to buf
  msgs[1].addr = I2C_ADDR;
  msgs[1].flags = 1;
  msgs[1].len = 10;
  msgs[1].buf = buf[1];

  rdwr.msgs = msgs;
  rdwr.nmsgs = 2;
  nmsgs_sent = ioctl(file, I2C_RDWR, & rdwr);
  if (nmsgs_sent != 2) {
    fprintf(stderr, "ERRORi in line %d: Wrong number of messages: %d\n", __LINE__, nmsgs_sent);
    exit(0);
  }
  for (i = 0; i < 10; i++)
    printf("Read 0x2d: %x\n", buf[1][i]);
  return (0);
}

I2C device drivers