/****************************************************/
**makefile
/****************************************************/
CROSS_COMPILE = arm-linux-gnueabi-
CFLAGS = -static
CC = $(CROSS_COMPILE)gcc
all : main.o
$(CC) $(CFLAGS) -o test main.o
main.o : main.c i2c.h
$(CC) -c main.c
clean :
rm main.o test
/****************************************************/
**delay.h
/****************************************************/
static inline void udelay(volatile int us)
{
volatile int i;
while(us--)
for(i = 30; i > 0; i--);
}
static inline void mdelay(volatile int ms)
{
while(ms--) {
udelay(700);
}
}
/****************************************************/
**main.c
/****************************************************/
#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 (0xA8 >> 1) /*Slave Device Address*/
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 short index, unsigned char * const data, unsigned char len )
{
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 short));
memcpy((tmp + sizeof(unsigned short)), data, len);
len += sizeof(unsigned short);
/***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 short start_word_address ,unsigned short write_data_length)
{
int i, ret = 0;
unsigned char write_data_buffer[1024];
unsigned short transmit_legth = 16;
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);
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);
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++) {
if (!isdigit(tmp[i]))
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'))) {
mode_type = 1; /*0: Read, 1: Write*/
if (str_isdigit(argv[1]) == 0) {
if (str_isxdigit(argv[2]) == 0) {
sscanf(argv[2], "%x", &test_value);
//printf("test_value = %08x\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;
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 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;
memcpy((write_api_cmd_buf + (0 * 4)), &test_value, 4);
i2c_transmit_data(fd, write_api_cmd_buf,(0x0000, 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%08X\n", *((unsigned long *)tmp_buffer + 0));
}
}
}
#endif
if (fd)
close(fd);
return 0;
}
沒有留言:
張貼留言