/* ***************************************************************************

* File name: eeprom_io.c

* Function: eeprom读写操作

* Description: 利用系统提供的I2C总线驱动实现eeprom设备的读写方法,

* 对外开放4个函数接口, 分别为:

* 单字节写入函数: int eeprom_byte_write(u8 pos, u8 data)

* 单字节读取函数: u8 eeprom_byte_read(u8 pos)

* 多字节写入函数: int eeprom_page_write(u8 pos, u8 *data, int size)

* 多字节读取函数: int eeprom_page_read(u8 pos, u8 *data, int size)

* Author & Date: Joshua Chan, 2011/12/18

* **************************************************************************/

#include

#include

#include

#include

#include

#include

#include "eeprom_io.h"

/* 对设备进行初始化设置, 设置超时时间及重发次数, 参数为设备文件描述符 */

static int eeprom_init(int fd)

{

ioctl(fd, I2C_TIMEOUT, 4);

ioctl(fd, I2C_RETRIES, 2);

return 0;

}

/* 初始化一个ioctl_st结构, 并预分配空间 */

static ioctl_st *ioctl_st_init(void)

{

ioctl_st *iocs;

iocs = malloc(sizeof(ioctl_st));

if (!(iocs)) {

perror("malloc iocs:");

return NULL;

}

iocs->msgs = malloc(I2C_MSG_SIZE * MAX_MSG_NR);

if (!(iocs->msgs)) {

perror("malloc iocs->msgs");

return NULL;

}

iocs->msgs[0].buf = malloc(EEPROM_PAGE_SIZE + 1);

if (!(iocs->msgs[0].buf)) {

perror("malloc iocs->msgs[0].buf");

return NULL;

}

iocs->msgs[1].buf = malloc(EEPROM_PAGE_SIZE + 1);

if (!(iocs->msgs[1].buf)) {

perror("malloc iocs->msgs[1].buf");

return NULL;

}

return iocs;

}

/* 销毁ioctl_st结构, 释放空间 */

static void ioctl_st_release(ioctl_st *iocs)

{

free(iocs->msgs[0].buf);

free(iocs->msgs[1].buf);

free(iocs->msgs);

free(iocs);

}

/* 根据eeprom_st结构生成page_read时序所需的ioctl_st结构 */

static void page_read_st_gen(ioctl_st *iocs, eeprom_st *eeps)

{

int size = eeps->len;

iocs->nmsgs = 2; //page_read需2次start信号

/* 第1次信号 */

iocs->msgs[0].addr = eeps->slave_addr; //填入slave_addr

iocs->msgs[0].flags = I2C_M_WR; //write标志

iocs->msgs[0].len = 1; //信号长度1字节

iocs->msgs[0].buf[0] = eeps->byte_addr; //填入byte_addr

/* 第2次信号 */

iocs->msgs[1].addr = eeps->slave_addr; //填入slave_addr

iocs->msgs[1].flags = I2C_M_RD; //read标志

iocs->msgs[1].len = size; //信号长度: 待读数据长度

memset(iocs->msgs[1].buf, 0, size); //先清零, 待读数据将自动存放于此

}

/* 用ioctl方法从eeprom中读取数据 */

static int page_read(int fd, ioctl_st *iocs, eeprom_st *eeps)

{

int ret;

int size = eeps->len;

page_read_st_gen(iocs, eeps);

ret = ioctl(fd, I2C_RDWR, (u32)iocs);

if (ret == -1) {

perror("ioctl");

return ret;

}

/* 将读取的数据从ioctl结构中复制到用户buf */

memcpy(eeps->buf, iocs->msgs[1].buf, size);

// printf("read byte ioctl ret = %d\n", ret);

return ret;

}

/* 从eeprom的pos位置开始读取size长度数据

@pos: eeprom的byte_address, 取值范围为0 ~ 255

@data: 接收数据的缓冲区

@size: 待读取的数据长度, 取值范围为1 ~ 16 */

int eeprom_page_read(u8 pos, u8 *data, int size)

{

int fd;

u8 *buf = data;

eeprom_st eeps;

ioctl_st *iocs = ioctl_st_init();

fd = open(DEV_PATH, O_RDONLY);

if (fd < 0) {

perror("open eeprom");

return 0;

}

/* 判断要读取数据的长度size有效性 */

if (size > 16)

size = 16;

else if (size < 1)

return 0;

if (size > (EEPROM_BLOCK_SIZE - pos))

size = EEPROM_BLOCK_SIZE - pos;

eeprom_init(fd);

eeps.slave_addr = eeprom_addr0;

eeps.byte_addr = pos;

eeps.len = size;

eeps.buf = buf;

page_read(fd, iocs, &eeps);

ioctl_st_release(iocs);

close(fd);

return size;

}

/* 根据eeprom_st结构生成page_write时序所需的ioctl_st结构 */

static void page_write_st_gen(ioctl_st *iocs, eeprom_st *eeps)

{

int size = eeps->len;

iocs->nmsgs = 1; //page_write只需1次start信号

iocs->msgs[0].addr = eeps->slave_addr; //填入slave_addr

iocs->msgs[0].flags = I2C_M_WR; //write标志

iocs->msgs[0].len = size + 1; //信号长度: 待写入数据长度 + byte_addr长度

iocs->msgs[0].buf[0] = eeps->byte_addr; //第1字节为byte_addr

memcpy((iocs->msgs[0].buf + 1), eeps->buf, size); //copy待写数据

}

/* 用ioctl方法向eeprom中写入数据 */

static int page_write(int fd, ioctl_st *iocs, eeprom_st *eeps)

{

int ret;

page_write_st_gen(iocs, eeps);

ret = ioctl(fd, I2C_RDWR, (u32)iocs);

if (ret == -1) {

perror("ioctl");

return ret;

}

printf("write byte ioctl ret = %d\n", ret);

return ret;

}

/* 自eeprom的pos位置开始写入数据

@pos: eeprom的byte_address, 取值范围为0 ~ 255

@data: 待写入的数据

@size: 待写入数据的长度, 取值范围为1 ~ 16 */

int eeprom_page_write(u8 pos, u8 *data, int size)

{

int fd;

u8 *buf = data;

eeprom_st eeps;

ioctl_st *iocs = ioctl_st_init();

fd = open(DEV_PATH, O_WRONLY);

if (fd < 0) {

perror("open eeprom");

return 0;

}

/* 判断要读取数据的长度size有效性 */

if (size > 16)

size = 16;

else if (size < 1)

return 0;

if (size > (EEPROM_BLOCK_SIZE - pos))

size = EEPROM_BLOCK_SIZE - pos;

eeprom_init(fd);

eeps.slave_addr = eeprom_addr0;

eeps.byte_addr = pos;

eeps.len = size;

eeps.buf = buf;

page_write(fd, iocs, &eeps);

ioctl_st_release(iocs);

close(fd);

return size;

}

/* 从eeprom的pos位置处读取1个字节

@pos: eeprom的byte_address, 取值范围为0 ~ 255

返回值为读取的字节数据 */

u8 eeprom_byte_read(u8 pos)

{

u8 buf;

eeprom_page_read(pos, &buf, 1);

return buf;

}

/* 将1个字节数据写入eeprom的pos位置

@pos: eeprom的byte_address, 取值范围为0 ~ 255

@data: 待写入的字节数据 */

int eeprom_byte_write(u8 pos, u8 data)

{

int ret;

u8 buf = data;

ret = eeprom_page_write(pos, &buf, 1);

return ret;

}

linux中i2c读写函数,Linux下的eeprom读写操作(IIC)相关推荐

  1. linux中脚本退出函数,Linux 命令 shell 脚本之09(函数)

    1.使用函数 [oracle@XAG143 myshell]$ cat test_fun1.sh #!/bin/bash # using a function in a script function ...

  2. linux内核的延时函数,linux中内核延时函数 (转)

    第一类延时函数原型是:(忙等) void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(unsi ...

  3. linux中进程退出函数:exit()和_exit()的区别

    linux中进程退出函数:exit()和_exit()的区别 (1)_exit()执行后立即返回给内核,而exit()要先执行一些清除操作,然后将控制权交给内核. (2)调用_exit函数时,其会关闭 ...

  4. Linux中 C++ main函数参数argc和argv含义及用法

    Linux中 C++ main函数参数argc和argv含义及用法 简介 argc 是 argument count的缩写,表示传入main函数的参数个数: argv 是 argument vecto ...

  5. 在linux中使用getch()函数

    #include <termio.h>int getch(void) {struct termios tm, tm_old;int fd = 0, ch;if (tcgetattr(fd, ...

  6. 时间基础概念及Linux中的时间函数

    时间基础概念及Linux中的时间函数 时间相关概念 GMT 时间 UTC 时间 时区 `Time Zone` 夏令时 `DST` 本地时间 `localtime` Linux 系统中的时间 时钟基础概 ...

  7. linux中的umask 函数

    我们创建文件的默认权限是怎么来的?如何改变这个默认权限呢? umask是什么? 当我们登录系统之后创建一个文件总是有一个默认权限的,那么这个权限是怎么来的呢?这就是umask干的事情.umask设置了 ...

  8. linux之getcwd函数解析,如何在Linux 中使用getcwd()函数

    如何在Linux 中使用getcwd()函数 发布时间:2021-03-15 17:35:21 来源:亿速云 阅读:106 作者:Leah 这期内容当中小编将会给大家带来有关如何在Linux 中使用g ...

  9. linux运行getch吗,在linux中使用getch()函数

    http://blog.csdn.net/xiaoweige207/article/details/6206265 由于在Linux中没有conio.h文件,所以不能直接用getch()函数,下面介绍 ...

  10. linux中的sleep函数和delay函数

    对于做过单片机程序的朋友来说,delay是很常见的函数,通常就是while或者for循环,进行空指令的执行,由于单片机的晶振固定,一个机器周期的时间是固定的,执行多少个空指令, 就可以完成多少个机器周 ...

最新文章

  1. python打印空心平行四边形的面积公式_打印等腰三角形和空心平行四边形
  2. 就是现在!2020 求职加薪手册,人手一份!
  3. 面试中常问的List去重问题,你都答对了吗?
  4. Hello Blazor:(2)集成Tailwind CSS续——nuget包方式
  5. leetcode python3 简单题155. Min Stack
  6. python自学网站-自学Python网站推荐 从入门到精通
  7. 【转】android 常用theme
  8. 科学实证与理论研究方法
  9. SecureCRT的下载与使用
  10. 100套大数据可视化模板
  11. Matlab多项式基本运算(1)( polyval和polyvalm的区别)
  12. linux的交换空间是什么意思,Linux交换空间是什么
  13. 【juns项目】信用卡数据项目2-2:数据设计
  14. 桃子CCD视觉高速喷射点胶机,用它你就会爱上它
  15. GPS与GPRS模块功差之千里
  16. 基于tkinter界面requests爬虫实现的学生事务管理平台自动填写系统
  17. PAT-Head of Hangs
  18. Android开发——菜单(Menu)-——上下文菜单(ContextMenu)、 弹出菜单(PopupMenu)
  19. windows10 导入 oracle11g dmp文件方法(详细!!!)
  20. unity - 打出的IPA包太大

热门文章

  1. 激光散斑血流仪的数据处理
  2. Apache Tomcat安装教程
  3. 最初的北漂生活之回忆
  4. python爬虫捕鱼网站_Python爬虫从太平洋地震工程研究中心数据库自动下载地震波时程...
  5. Unity资源-音效初识
  6. 易遨房地产中介管理系统 v6.0 erp标准版 bt
  7. 房屋中介对计算机专业的应用,开发房产中介系统的目的和意义是什么
  8. mysql 数据库大小与内存关系_【MYSQL】CPU资源和可用内存大小对数据库性能的影响...
  9. 【VLSI DSP】课程总结
  10. DVBBS sp2 漏洞