⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 24cxx.c

📁 2440开发板的i2c驱动测试程序
💻 C
字号:
/***************************************************************************    copyright            : (C) by 2003-2004 Stefano Barbato    email                : stefano@codesink.org    $Id: 24cXX.h,v 1.6 2004/02/29 11:05:28 tat Exp $ ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <linux/fs.h>#include <sys/types.h>#include <sys/ioctl.h>#include <errno.h>#include <assert.h>#include <string.h>#include "24cXX.h"static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,                                      int size, union i2c_smbus_data *data){	struct i2c_smbus_ioctl_data args;	args.read_write = read_write;	args.command = command;	args.size = size;	args.data = data;	return ioctl(file,I2C_SMBUS,&args);}static inline __s32 i2c_smbus_write_quick(int file, __u8 value){	return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);}	static inline __s32 i2c_smbus_read_byte(int file){	union i2c_smbus_data data;	if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))		return -1;	else		return 0x0FF & data.byte;}static inline __s32 i2c_smbus_write_byte(int file, __u8 value){	return i2c_smbus_access(file,I2C_SMBUS_WRITE,value,	                        I2C_SMBUS_BYTE,NULL);}static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command){	union i2c_smbus_data data;	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,	                     I2C_SMBUS_BYTE_DATA,&data))		return -1;	else		return 0x0FF & data.byte;}static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,                                               __u8 value){	union i2c_smbus_data data;	data.byte = value;	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,	                        I2C_SMBUS_BYTE_DATA, &data);}static inline __s32 i2c_smbus_read_word_data(int file, __u8 command){	union i2c_smbus_data data;	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,	                     I2C_SMBUS_WORD_DATA,&data))		return -1;	else		return 0x0FFFF & data.word;}static inline __s32 i2c_smbus_write_word_data(int file, __u8 command,                                               __u16 value){	union i2c_smbus_data data;	data.word = value;	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,	                        I2C_SMBUS_WORD_DATA, &data);}static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value){	union i2c_smbus_data data;	data.word = value;	if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,	                     I2C_SMBUS_PROC_CALL,&data))		return -1;	else		return 0x0FFFF & data.word;}/* Returns the number of read bytes */static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,                                               __u8 *values){	union i2c_smbus_data data;	int i;	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,	                     I2C_SMBUS_BLOCK_DATA,&data))		return -1;	else {		for (i = 1; i <= data.block[0]; i++)			values[i-1] = data.block[i];		return data.block[0];	}}static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,                                                __u8 length, __u8 *values){	union i2c_smbus_data data;	int i;	if (length > 32)		length = 32;	for (i = 1; i <= length; i++)		data.block[i] = values[i-1];	data.block[0] = length;	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,	                        I2C_SMBUS_BLOCK_DATA, &data);}/* Returns the number of read bytes */static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,                                                  __u8 *values){	union i2c_smbus_data data;	int i;	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,	                      I2C_SMBUS_I2C_BLOCK_DATA,&data))		return -1;	else {		for (i = 1; i <= data.block[0]; i++)			values[i-1] = data.block[i];		return data.block[0];	}}static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,                                               __u8 length, __u8 *values){	union i2c_smbus_data data;	int i;	if (length > 32)		length = 32;	for (i = 1; i <= length; i++)		data.block[i] = values[i-1];	data.block[0] = length;	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,	                        I2C_SMBUS_I2C_BLOCK_DATA, &data);}/* Returns the number of read bytes */static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,                                                 __u8 length, __u8 *values){	union i2c_smbus_data data;	int i;	if (length > 32)		length = 32;	for (i = 1; i <= length; i++)		data.block[i] = values[i-1];	data.block[0] = length;	if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,	                     I2C_SMBUS_BLOCK_PROC_CALL,&data))		return -1;	else {		for (i = 1; i <= data.block[0]; i++)			values[i-1] = data.block[i];		return data.block[0];	}}static int i2c_write_1b(struct eeprom *e, __u8 buf){	int r;	// we must simulate a plain I2C byte write with SMBus functions	r = i2c_smbus_write_byte(e->fd, buf);	if(r < 0)		fprintf(stderr, "Error i2c_write_1b: %s\n", strerror(errno));	usleep(10);	return r;}static int i2c_write_2b(struct eeprom *e, __u8 buf[2]){	int r;	// we must simulate a plain I2C byte write with SMBus functions	r = i2c_smbus_write_byte_data(e->fd, buf[0], buf[1]);	if(r < 0)		fprintf(stderr, "Error i2c_write_2b: %s\n", strerror(errno));	usleep(10);	return r;}static int i2c_write_3b(struct eeprom *e, __u8 buf[3]){	int r;	// we must simulate a plain I2C byte write with SMBus functions	// the __u16 data field will be byte swapped by the SMBus protocol	r = i2c_smbus_write_word_data(e->fd, buf[0], buf[2] << 8 | buf[1]);	if(r < 0)		fprintf(stderr, "Error i2c_write_3b: %s\n", strerror(errno));	usleep(10);	return r;}#define CHECK_I2C_FUNC( var, label ) \	do { 	if(0 == (var & label)) { \		fprintf(stderr, "\nError: " \			#label " function is required. Program halted.\n\n"); \		exit(1); } \	} while(0);int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom* e){	int funcs, fd, r;	e->fd = e->addr = 0;	e->dev = 0;		fd = open(dev_fqn, O_RDWR);	if(fd <= 0)	{		fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));		return -1;	}	// get funcs list	if((r = ioctl(fd, I2C_FUNCS, &funcs) < 0))	{		fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));		return -1;	}		// check for req funcs	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE );	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE );	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE_DATA );	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE_DATA );	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_WORD_DATA );	CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_WORD_DATA );	// set working device	if( ( r = ioctl(fd, I2C_SLAVE, addr)) < 0)	{		fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno));		return -1;	}	e->fd = fd;	e->addr = addr;	e->dev = dev_fqn;	e->type = type;	return 0;}int eeprom_close(struct eeprom *e){	close(e->fd);	e->fd = -1;	e->dev = 0;	e->type = EEPROM_TYPE_UNKNOWN;	return 0;}#if 0int eeprom_24c32_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data){	__u8 buf[3] = { (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data };	return i2c_write_3b(e, buf);}int eeprom_24c32_read_current_byte(struct eeprom* e){	ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer	return i2c_smbus_read_byte(e->fd);}int eeprom_24c32_read_byte(struct eeprom* e, __u16 mem_addr){	int r;	ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer	__u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff };	r = i2c_write_2b(e, buf);	if (r < 0)		return r;	r = i2c_smbus_read_byte(e->fd);	return r;}#endifint eeprom_read_current_byte(struct eeprom* e){	ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer	return i2c_smbus_read_byte(e->fd);}int eeprom_read_byte(struct eeprom* e, __u16 mem_addr){	int r;	ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer	if(e->type == EEPROM_TYPE_8BIT_ADDR)	{		__u8 buf =  mem_addr & 0x0ff;		r = i2c_write_1b(e, buf);	} else if(e->type == EEPROM_TYPE_16BIT_ADDR) {		__u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff };		r = i2c_write_2b(e, buf);	} else {		fprintf(stderr, "ERR: unknown eeprom type\n");		return -1;	}	if (r < 0)		return r;	r = i2c_smbus_read_byte(e->fd);	return r;}int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data){	if(e->type == EEPROM_TYPE_8BIT_ADDR) {		__u8 buf[2] = { mem_addr & 0x00ff, data };		return i2c_write_2b(e, buf);	} else if(e->type == EEPROM_TYPE_16BIT_ADDR) {		__u8 buf[3] = 			{ (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data };		return i2c_write_3b(e, buf);	} 	fprintf(stderr, "ERR: unknown eeprom type\n");	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -