Linux I2C Driver - 使用str8131(2)首先我們要先看在 user space 如何讀寫 i2c。在user-space時寫測試i2c的程式,首先要include <linux/i2c-dev.h>這個檔案。因為我們需要i2c_msg和 i2c_rdwr_ioctl_data這兩個struct。讀取 i2c:uint32_t i2c_read(uint8_t index, uint8_t *buf, uint8_t len){    uint32_t ret;   struct i2c_msg  msg[2];   struct i2c_rdwr_ioctl_data queue;   queue.msgs = msg;   queue.nmsgs = 2;   queue.msgs[0].len = 1;   queue.msgs[0].addr = SLAVE_ADDR;   售屋網queue.msgs[0].flags = 0;    /* write */   queue.msgs[0].buf = &index;   queue.msgs[1].len = len;   queue.msgs[1].addr = SLAVE_ADDR;   queue.msgs[1].flags = I2C_M_RD;   queue.msgs[1].buf = buf;   ret = ioctl(i2c_fd, I2C_RDWR, (uint32_t)&queue);   if (ret < 0) {       printf("Error dring I2C_RDWR ioctl with error code: %d\n", ret);      return ret;    }   return 0;}寫辦公室出租入i2c:uint32_t i2c_write(uint8_t index, uint8_t *data, uint8_t len){    uint32_t        ret;    uint8_t         *temp;    struct i2c_msg  msg;    struct i2c_rdwr_ioctl_data queue;    temp = (uint8_t*) malloc(sizeof(uint8_t) * len+1);    temp[0] = index;    if (data != NULL)        memcpy(temp+1, data, len);    queue.msgs 房屋買賣= &msg;    queue.nmsgs = 1;    queue.msgs->len = len+1;    queue.msgs->addr = SLAVE_ADDR;    queue.msgs->flags = 0;    /* write */    queue.msgs->buf = temp;    ret = ioctl(i2c_fd, I2C_RDWR, (uint32_t)&queue);    if (ret < 0) {        printf("Error dring I2C_RDWR ioctl with error code: %d\n", ret);        return 澎湖民宿ret;    }    return 0;}首先有一個 SLAVE_ADDR,這個是要看電路圖才知道,一般是一個7 bit的位址,假設這裡電路圖上寫的是EEPROM的I2C Slave address: 1010000B那程式裡應該就是類似 #define SLAVE_ADDR 0x50我們在這裡使用這個位址,透過i2c ,來讀寫 EEPROM。我們先來看這兩個函式,有 struct i2c_msg 和 struct i2c_rdwr_ioctl_data 這兩個架構,在這裡重要的是 struct i2c_msg 這個結構,因為在後面時,我們主要是就用它來判斷使用要做的動作(讀、寫),和資料的傳輸。而struct i2c_rdwr_ioctl_data主要是用來表示這次的ioctl帶的i2c_msg 有幾個。struct 吳哥窟i2c_msg的定義如下:struct i2c_msg {    __u16 addr;    /* slave address            */     __u16 flags;        #define I2C_M_TEN    0x10    /* we have a ten bit chip address    */#define I2C_M_RD    0x01#define I2C_M_NOSTART    0x4000#define I2C_M_REV_DIR_ADDR    0x2000#define I2C_M_IGNORE_NAK    0x1000#define 租屋I2C_M_NO_RD_ACK        0x0800     __u16 len;        /* msg length                */     __u8 *buf;        /* pointer to msg data            */};含有一個 addr表示要讀寫的slave裝置,這裡是EEPROM。flags表示設定的狀態,len就是buf資料的長度,buf就是傳輸的資料。一般在要讀時,要先寫入要讀的index,然後再開始讀取,所以上面的 代償i2c_read 才會宣告成兩個messages,第一個的buf填的是要寫入的index,第二個的buf是要讀取的資料。但這樣但要讀取大量資料時,很沒有效率。每次都要做寫入的動作,在這裡比較好的方法是寫入index 一次,然後不斷的讀取。我們還需要一個 read_only的函式:uint32_t i2c_read_only(uint8_t *buf, uint8_t len){    uint32_t ret;   uint8_t  temp = index;   struct i2c_msg  msg;   struct i2c_rdwr_ioctl_data queue;   queue.msgs = &msg;   queue.nmsgs = 1;   queue.msgs->len = 酒店經紀len;   queue.msgs->addr = SLAVE_ADDR;   queue.msgs->flags = I2C_M_RD;   queue.msgs->buf = buf;   ret = ioctl(i2c_fd, I2C_RDWR, (uint32_t)&queue);   if (ret < 0) {       printf("Error dring I2C_RDWR ioctl with error code: %d\n", ret);      return ret;    }   return 0;}這裡只傳當 driver 一個讀取的訊息,但如果只呼叫這個函式是讀不到資料的,因為裝置不知道你要從那一個index開始讀取?所以再實做一個函式如負債整合下:uint32_t i2c_write_read(uint8_t index, uint8_t *data, uint8_t len){    uint32_t        ret;    ret = i2c_write(index, NULL, 0);    if (ret != 0) return ret;    return i2c_read_only(data, len);}先寫入要讀取的index,然後不斷的讀取資料。和上面的 i2c_read不同的是,減少了每次index的寫入,讓裝置自已移動index,可以大大的提升效能。實際上要看等會driver的實做,就更能明白這兩個的讀取的差別。


.msgcontent .wsharing ul li { text-indent: 0; }



分享
買屋
Facebook
Plurk
YAHOO!

arrow
arrow
    全站熱搜

    fs26fsivcb 發表在 痞客邦 留言(0) 人氣()