Linux I2C Driver - 使用str8131(6)static u_int32 I2C_Command(           u8 i2c_cmd_type, u16 slave_addr,            u16 write_data_len, u32 write_data,            u16 read_data_len, u32 *read_data){    long timeout;    // 把中斷的狀態清除為0和設定傳輸的 command    i2c_cmd_transfer.transfer_cmd = i2c_cmd_type;    i2c_cmd_transfer.error_status = 0;    i2c_cmd_transfer.action_done = 0;    // 設定不同動作的命令    switch (i2c_cmd_type)    {        case I2C_READ_ONLY_CMD:        {            i2c_cmd_transfer.write_data_len = 0;            i2c_cmd_transfer.read_data_len = read_data_len & I2C_MAX_DATA_LEN_FLAG;            i2c_cmd_transfer.slave_addr = slave_addr & 0xFE;        }break;        case I2C_WRITE_ONLY_CMD:        {            i2c_cmd_transfer.write_data_len = write_data_len & I2C_MAX_DATA_LEN_FLAG;            濾桶i2c_cmd_transfer.read_data_len = 0;            i2c_cmd_transfer.slave_addr = slave_addr & 0xFF;        }break;        case I2C_WRITE_READ_CMD:        {            i2c_cmd_transfer.write_data_len = write_data_len & I2C_MAX_DATA_LEN_FLAG;            i2c_cmd_transfer.read_data_len = read_data_len & I2C_MAX_DATA_LEN_FLAG;            i2c_cmd_transfer.slave_addr = slave_addr & 0xFF;        }break;        default:            TRACE("Unsupported command, command type=%d\n", i2c_cmd_type);               return -EIO;    }    // 清除前一個的 I2C 中斷暫存器的狀態    IO_OUT_WORD(I2C_INTERRUPT_STATUS_REG_ADDR, I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG);    // 開啟 I2C 中斷狀態暫存器    IO_OUT_WORD(I2C_INTERRUPT_ENABLE_REG_ADDR, I2C_BUS_ERROR_FLAG | I2C_ACTION_DONE_FLAG);// 是否要做寫入資料的動作,最大為 4 bytes    if (write_data_len > 0)    {        switch 長灘島(write_data_len)        {        case I2C_DATA_LEN_1_BYTE :            i2c_cmd_transfer.write_data = write_data & 0xFF;           break;        case I2C_DATA_LEN_2_BYTE :            i2c_cmd_transfer.write_data = write_data & 0xFFFF;           break;        case I2C_DATA_LEN_3_BYTE :            i2c_cmd_transfer.write_data = write_data & 0xFFFFFF;           break;        case I2C_DATA_LEN_4_BYTE :            i2c_cmd_transfer.write_data = write_data;        default :            i2c_cmd_transfer.write_data = write_data;           break;        }    }   // 硬體的傳輸動作    Hal_I2c_Dispatch_Transfer(&i2c_cmd_transfer);    // 等待中斷的發生   timeout = interruptible_sleep_on_timeout(&wait_queue, TWI_TIMEOUT);    if (timeout == 0) return 0x99;    // 查看租房子是否有錯誤    if (i2c_cmd_transfer.error_status && (i2c_cmd_transfer.error_status != 0xFF))    {        return (i2c_cmd_transfer.error_status);    }    TRACE("I2C bus is normal, i2c_cmd_type=%d\n", i2c_cmd_type);  //  是否要做讀取的動作,最大為 4 bytes    if (read_data_len > 0)    {        // Get the read data byte        i2c_cmd_transfer.read_data = IO_IN_WORD(I2C_READ_DATA_REG_ADDR);        switch (read_data_len)        {            case I2C_DATA_LEN_1_BYTE :                i2c_cmd_transfer.read_data &= 0xFF;              break;           case I2C_DATA_LEN_2_BYTE :               i2c_cmd_transfer.read_data &= 0xFFFF;              break;           case I2C_DATA_LEN_3_BYTE :               i2c_cmd_transfer.read_data &= 0xFFFFFF;        永慶房屋      break;           case I2C_DATA_LEN_4_BYTE :           default :              break;        }        // 回傳讀取的資料        *read_data = i2c_cmd_transfer.read_data;    }   return (0);}最後再附上 user-space的測試程式:#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <syslog.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <time.h>#include <stdint.h>#include <errno.h>//#include <linux/i2c.h>#include <linux/i2c-dev.h>#include <termios.h>//Share memory#include <sys/shm.h>#include <time.h>///fot ioctl#define WRITE_DATA_MODE 0#define READ_DATA_MODE  1#define SLAVE_ADDR 0x50int i2c_fd;//=====================================================================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 = ARMANI0;    /* 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;    }   // nDebugf("DPLL %#02X: %#02X\n", index, *buf)   return 0;}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;    }   // nDebugf("DPLL %#02X: %#02X\n", index, *buf)   return 0;}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;}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);}static char getch(){    char c;    while ((c = getchar()) == 結婚西裝'\n');    while (getchar() != '\n');    return c;}int main(int argc,char *argv[]){    char choice = 0;    uint8_t data=0, index=0;    uint8_t data_ary[128];    uint8_t len = 0;    const char *dev_i2c = "/dev/i2c";    int ret = 0;    if( (i2c_fd = open(dev_i2c, O_RDWR)) < 0)    {      printf("%d:It is failed to open %s => %s\n",  __LINE__, dev_i2c, strerror(errno));      return -1;    }    do    {        printf("\n===== i2c ====\n");        printf("(1) read string from i2c\n");        printf("(2) write string to  i2c\n");        printf("(3) write read from  i2c\n");        printf("(q) exit\n");        choice = getch();        printf("choice=%c\n", choice);        data = 0;        switch (choice)        {        case 燒烤'1':            printf("input index\n");            index = getch();            index -= 0x30;            printf("input length\n");            len = getch();            len -= 0x30;            memset(data_ary, 0, sizeof(data_ary));            i2c_read(index, data_ary, len);            printf("app = > read block, index=%d, data=%s\n", index, data_ary);            break;        case '2':            printf("input index\n");            index = getch();            index -= 0x30;            memset(data_ary, 0, sizeof(data_ary));            scanf("%s", data_ary);            i2c_write(index, data_ary, 借貸strlen(data_ary));            printf("app = > write block, index=%d, data=%s, len=%d\n", index, data_ary, strlen(data_ary));            break;        case '3':            printf("input index\n");            index = getch();            index -= 0x30;            printf("input length\n");            len = getch();            len -= 0x30;            memset(data_ary, 0, sizeof(data_ary));            i2c_write_read(index, data_ary, len);            printf("app = > write index and read block, index=%d, data=%s\n", index, data_ary);            break;        default:            break;        }    }while (choice != 'q');    close(i2c_fd);    return 0;}


.msgcontent 太平洋房屋.wsharing ul li { text-indent: 0; }



分享

Facebook
Plurk
YAHOO!

arrow
arrow
    全站熱搜

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