Sunday, January 7, 2018

I2C client Driver and I2C User App

I2C Linux 





root@embsys-VirtualBox:/boot/grub# tree /sys/class/i2c*---->IMP:i2c-0 and i2c-1 are two i2c master each suppports upto- 0x03-0x77 slaves.
/sys/class/i2c-adapter
├── i2c-0 -> ../../devices/pci0000:00/0000:00:07.0/i2c-0--->Master 1---> Can have multiple Slave ( 0x03-0x77)
└── i2c-1 -> ../../devices/i2c-1--------------------------->Master 2---> Can have multiple Slave  ( 0x03-0x77)
/sys/class/i2c-dev
├── i2c-0 -> ../../devices/pci0000:00/0000:00:07.0/i2c-0/i2c-dev/i2c-0
└── i2c-1 -> ../../devices/i2c-1/i2c-dev/i2c-1

I2C User Space Application to Interact with I2C Client Driver.

#include

1./* Which I2C Adapter/Master to Open*/
fd = open(/dev/i2c-1, O_RDWR)0---->use  i2cdetect -l or /sys/class/i2c-dev/

2./*Check functionality of I2C master*/
if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
        /* Some kind of error handling */
        exit(1);
  }
  if (!(funcs & I2C_FUNC_I2C)) {
        /* Plain read/write not available  only use smbus_..*/
        exit(1);
}

3./*address of I2CSlave device on this Bus*/
int addr = 0x40;
/* Send I2C slave address to Master for communication*/
ioctl(fd, I2C_SLAVE, addr)

4./* Write to I2C slave Device*/
a) i2c_smbus_write_word_data(fd, reg, 0x6543)
   ( Preferred Way)
or
b)  buf[0] = reg; /Addres location inside I2c Slave device
     buf[1] = 0x43;
     buf[2] = 0x65;
    write(file, buf, 3) != 3)

5./*Read from i2c slave */
a)int result;
  resutl = i2c_smbus_read_word_data(fd, reg)
  ( result contains data/(preferred way)
or
b)read(file, buf, 1)
( buf[0] contains data);


* IMPORTANT: because of the use of inline functions, you *have* to use
'-O' or some variation when you compile your program!

Why to use SMBUS Protocl
The Linux I2C stack was originally written to support access to hardware monitoring chips on PC motherboards, and thus used to embed some assumptions
that were more appropriate to SMBus (and PCs) than to I2C. All adapters understand SMBus level commands, but only some of them understand plain I2C!


I2C Client Driver

1. Create i2c_device_id table

static struct i2c_device_id foo_idtable[] = {
    { "foo", my_id_for_foo },
    {}
};

MODULE_DEVICE_TABLE(i2c, foo_idtable);

2.Create I2c_drive structure with table passing , and probe/remove function.
static struct i2c_driver foo_driver = {
    .driver = {
        .name    = "foo", /* name should match name of module*/
        .owner  =  THIS_MODULE;
    },

    .id_table    = foo_idtable,
    .probe        = foo_probe,
    .remove        = foo_remove,
}


3.Init /exit
with i2c_add_driver and i2c_del_driver

static int __init foo_init(void)
{
    return i2c_add_driver(&foo_driver);
}
module_init(foo_init);

static void __exit foo_cleanup(void)
{
    i2c_del_driver(&foo_driver);
}
module_exit(foo_cleanup);

or Better to use a macro for all these in single Line

module_i2c_driver(foo_driver);


4. Read/write

you can use
a) smbus function
b) plain i2c function

>Plain I2C communication
int i2c_master_send(struct i2c_client *client, const char *buf, int count);
int i2c_master_recv(struct i2c_client *client, char *buf, int count);

>SMBUS Functuons
i2c_smbus_read_word/byte/block_data(client, reg);
i2c_smbus_write_word/byte/block_data(client, reg,value);

It is recommened to use smbus functions as all devices supports this only few supports i2c variant.

5.Probe/REmove
-Initialize Hadware 
The probe function is called when an entry in the id_table name field
matches the device's name. It is passed the entry that was matched so
the driver knows which one in the table matched.

- you can here setclient data
    /* store the value */
    void i2c_set_clientdata(struct i2c_client *client, void *data);
    /* retrieve the value */
      void *i2c_get_clientdata(const struct i2c_client *client);
- Also check for cabability
    The i2c core provides two functions for this: i2c_check_functionality() checks whether a particular function is supported,
    and i2c_get_functionality() returns a mask containing all of adapter’s supported functions.
-Memory Allocation 









No comments:

Post a Comment

Featured Post

XDP - Getting Started with XDP (Linux)