#include <stdio.h>
#include <linux/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "delay.h"
#define I2C_RETRIES 0x0701
#define I2C_TIMEOUT 0x0702
#define I2C_RDWR 0x0707
#include <string.h>
#define STORAGE_DEV 0x56 /*Slave Device Address*/ //讀取位址是eeprom
struct i2c_msg {
unsigned short addr;
unsigned short flags;
#define I2C_M_TEN 0x0010
#define I2C_M_RD 0x0001
unsigned short len;
unsigned char *buf;
};
struct i2c_rdwr_ioctl_data{
struct i2c_msg *msgs;
int nmsgs;
};
struct i2c_rdwr_ioctl_data storage_data;
struct i2c_msg storage_msg[2];
int i2c_write(int fd, unsigned char slvAddr, unsigned char index, unsigned char * const data, unsigned char len )//將unsigned short index改為 unsigned char index
{
int ret;
unsigned char *tmp = (unsigned char*) malloc(1024);
if (tmp == NULL) {
perror("memory allocate error(write)!!");
return -1;
}
memcpy(tmp, (unsigned char *)&index, sizeof(unsigned char));
//printf("tmp firtst memcpy=%d\n",tmp);
memcpy((tmp + sizeof(unsigned char)), data, len);
//printf("tmp 2nd memcpy=%d\n",tmp);
len += sizeof(unsigned char);
/***write data to storage**/
storage_data.nmsgs = 1;
(storage_data.msgs[0]).len = len; // Data length
(storage_data.msgs[0]).addr = slvAddr;//Device Addr
(storage_data.msgs[0]).flags = 0; //write
(storage_data.msgs[0]).buf = tmp;
ret = ioctl(fd, I2C_RDWR, &storage_data);
if (tmp)
free(tmp);
return (ret < 0) ? -1 : 0;
}
int i2c_read(int fd, unsigned char slvAddr, unsigned short index, unsigned char *data, int len)
{
storage_data.nmsgs = 2;
(storage_data.msgs[0]).len = sizeof(unsigned short);
(storage_data.msgs[0]).addr = slvAddr;
(storage_data.msgs[0]).flags = 0; //Dummy write
(storage_data.msgs[0]).buf = (unsigned char *)&index;
(storage_data.msgs[1]).len = len;
(storage_data.msgs[1]).addr = slvAddr;
(storage_data.msgs[1]).flags = 1;
(storage_data.msgs[1]).buf = data;
if(ioctl(fd,I2C_RDWR, &storage_data) < 0){
perror("ioctl error");
return -1;
}
return 0;
}
int
i2c_transmit_data(int fd, unsigned char *data_ptr, unsigned char start_word_address ,unsigned char write_data_length)
{
int i, ret = 0;
unsigned char write_data_buffer[1024];
unsigned char transmit_legth = 4; //限制寫入的單位
memset(write_data_buffer, 0, 1024);
write_data_length = ((write_data_length > 1024) ? 1024 : write_data_length);
memcpy(write_data_buffer, data_ptr, write_data_length);
//printf("write_data_buffer=%s\n",write_data_buffer);
for (i = 0; i < write_data_length; i ++) {
if ((i % transmit_legth) == 0) {
int retry = 5;
do {
ret = i2c_write(fd, STORAGE_DEV, (start_word_address + i), (write_data_buffer + i), transmit_legth);
//i2c_write(fd, 0x56, 0x47, tmp_buffer1, 1 );
if(ret == 0) {
break;
}
mdelay(1);
} while (-- retry);
if (ret) {
printf("i2c write %i error!!!\n", i);
}
}
}
return ret;
}
int
i2c_receive_data(int fd, unsigned char *data_ptr, unsigned short start_word_address ,unsigned short read_data_length)
{
int i, ret = 0;
unsigned char read_data_buffer[1024];
unsigned short receive_legth = 16;
memset(read_data_buffer, 0x00, 1024);
read_data_length = ((read_data_length > 1024) ? 1024 : read_data_length);
for (i = 0; i < read_data_length; i ++) {
if ((i % receive_legth) == 0) {
int retry = 5;
do {
ret = i2c_read(fd, STORAGE_DEV, (start_word_address + i), (read_data_buffer + i), receive_legth);
if(ret == 0) {
break;
}
mdelay(1);
} while (-- retry);
if(ret == 0) {
#if 0
int count;
for (count = i; count < (i + receive_legth); count += 16) {
printf("%d. [%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x]\n", count
, read_data_buffer[count + 0]
, read_data_buffer[count + 1]
, read_data_buffer[count + 2]
, read_data_buffer[count + 3]
, read_data_buffer[count + 4]
, read_data_buffer[count + 5]
, read_data_buffer[count + 6]
, read_data_buffer[count + 7]
, read_data_buffer[count + 8]
, read_data_buffer[count + 9]
, read_data_buffer[count + 10]
, read_data_buffer[count + 11]
, read_data_buffer[count + 12]
, read_data_buffer[count + 13]
, read_data_buffer[count + 14]
, read_data_buffer[count + 15]
);
}
#endif
} else {
printf("i2c read %i error!!!\n", i);
}
}
}
if (ret == 0) {
memcpy(data_ptr, read_data_buffer, read_data_length);
}
return ret;
}
int str_isxdigit(char *tmp)
{
int i;
for (i = 0; i < strlen(tmp); i++) {
if (!isxdigit(tmp[i]))
return -1;
}
return 0;
}
int str_isdigit(char *tmp)
{
int i;
for (i = 0; i < strlen(tmp); i++) {//strlen是擷取字元長度 s[] = "You may go farther and fare worse."長度為 printf("%d\n", strlen(s)); =====>34
if (!isdigit(tmp[i])) //isdigit()判斷是否為數字還是字元,isdigit()為真是數字 isdigit()為假是字元
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
int fd = 0, ret = 0;
int mode_type = 0; /*0: Read, 1: Write*/
unsigned long test_value = 0;
if ((argc == 3) && ((argv[1][0] == 'w') || (argv[1][0] == 'W'))) { //&&是and ||是or ((argv[1][0] == 'w') || (argv[1][0] == 'W'))則一成立即可,與(argc == 3) 都必成立
mode_type = 1; /*0: Read, 1: Write*/
if (str_isdigit(argv[2]) == 0) { //str_isdigit(argv[1])錯誤改為str_isdigit(argv[2])
if (str_isxdigit(argv[2]) == 0) { //傳入值錯誤造成,且執行ret為真
sscanf(argv[2], "%lx", &test_value);
printf("test_value = %08lx\n", test_value);
} else {
ret = -1;
}
} else {
ret = -1;
}
}
else if ((argc == 2) && ((argv[1][0] == 'r') || (argv[1][0] == 'R'))) {
mode_type = 0; /*0: Read, 1: Write*/
}
else {
ret = -1;
}
if (ret) {
printf("%s r ==> Read Double Word.\n", argv[0]);
printf("%s w 0x12345678 ==> Write Double Word.\n", argv[0]);
return 0;
}
storage_data.nmsgs = 2;
storage_data.msgs = storage_msg;
printf("hello\n");
fd = open("/dev/i2c-0",O_RDWR);
if(fd < 0){
perror("open I2C Dev error!!");
exit(1);
}
ioctl(fd, I2C_TIMEOUT, 1);/*set timeout value*/
ioctl(fd, I2C_RETRIES, 2);/*set retry times*/
#if 1
if (mode_type == 1) /*0: Read, 1: Write*/
{
//I2C Write
//Step 1. Transfer da16
unsigned char write_api_cmd_buf[64]={
/*Byte 0, Byte 1, Byte 2, Byte 3*/
/*DW00*/ 0x00, 0x00, 0x00, 0x00,
};
unsigned char i2c_data_length = 4;
//memcpy((write_api_cmd_buf + (0 * 4)), &test_value, 4); //<=====看不懂(write_api_cmd_buf + (0 * 4)) ==memcpy( write_api_cmd_buf , &test_value, 4);
memcpy(write_api_cmd_buf + (0 * 4), &test_value, 4);
//memcpy(write_api_cmd_buf + (1 * 4), &test_value, 4); //實驗新增
//memcpy(write_api_cmd_buf + (2 * 4), &test_value, 4); //實驗新增
//memcpy(write_api_cmd_buf + (3 * 4), &test_value, 4); /實驗新增
//printf("write_api_cmd_buf=%s\n",write_api_cmd_buf);
//}
i2c_transmit_data(fd, write_api_cmd_buf,0x00, i2c_data_length);
#if 0
{
int i;
unsigned char tmp_buffer[1024];
memset(tmp_buffer, 0x00, 1024);
i2c_receive_data(fd, tmp_buffer, 0x0000, i2c_data_length);
}
#endif
}
#endif
#if 1
if (mode_type == 0) /*0: Read, 1: Write*/
{
//test Read
//Step 1. Receive data
unsigned char write_api_cmd_buf[64]={
/*Byte 0, Byte 1, Byte 2, Byte 3*/
/*DW00*/ 0x00, 0x00, 0x00, 0x00,
};
unsigned short i2c_data_length = 4;
//i2c_transmit_data(fd, write_api_cmd_buf, 0x0000, i2c_data_length);
{
int i, ret;
unsigned char tmp_buffer[64];
memset(tmp_buffer, 0x00, 64);
ret = i2c_receive_data(fd, tmp_buffer, 0x0000, i2c_data_length);
if (ret == 0) {
printf("Data ==> 0x%08lX\n", *((unsigned long *)tmp_buffer + 0));
}
}
}
#endif
if (fd)
close(fd);
return 0;
}