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 = seo0; /* 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!
.msgcontent 建築設計.wsharing ul li { text-indent: 0; }
分享
Plurk
YAHOO!
全站熱搜
留言列表