Difference between revisions of "Beaglebone black i2c"

From Teknologisk videncenter
Jump to: navigation, search
m (I2C Low level)
m (I2C Low level)
Line 60: Line 60:
 
//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        0x10
+
#define I2C_ADDR        0x03  // Grove DIP-switch 6 slave address default
  
 
int main( void ) {
 
int main( void ) {
Line 86: Line 86:
 
                         fprintf(stderr,"ERROR: open_i2c_dev failed: %s", strerror(errno));
 
                         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].addr = I2C_ADDR;
 
                 msgs[0].flags = 0;
 
                 msgs[0].flags = 0;
Line 91: Line 94:
 
                 msgs[0].buf = buf[0];
 
                 msgs[0].buf = buf[0];
 
                 buf[0][0] = 0x01;
 
                 buf[0][0] = 0x01;
 +
 +
                //msgs[1] read 10 bytes to buf
 
                 msgs[1].addr = I2C_ADDR;
 
                 msgs[1].addr = I2C_ADDR;
 
                 msgs[1].flags = 1;
 
                 msgs[1].flags = 1;
Line 108: Line 113:
 
         return(0);
 
         return(0);
 
}
 
}
 +
 
</source>
 
</source>
  

Revision as of 13:53, 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