最近花了点时间在android平台调试了一下eeprom,做下记录,供同学们参考。该文基于原生驱动(kernel/msm-3.18/drivers/misc/eeprom/at24.c)做的调试。

内核代码修改:

diff--gita/kernel/msm-3.18/arch/arm/boot/dts/qcom/msm8917-qrd.dtsib/kernel/msm-3.18/arch/arm/boot/dts/qcom/msm8917-qrd.dtsi

old mode 100644

new mode 100755

index 0cad9a8..216345e

---a/kernel/msm-3.18/arch/arm/boot/dts/qcom/msm8917-qrd.dtsi

+++b/kernel/msm-3.18/arch/arm/boot/dts/qcom/msm8917-qrd.dtsi

@@ -256,6 +256,18 @@

};

};

+

+&i2c_5 {

+

+      at24c04@50 {

+               compatible ="atmel,24c04";

+               vdd-supply =<&pm8917_l23>;

+               reg = <0x50>;

+      };

+

+};

+

diff --gita/kernel/msm-3.18/drivers/misc/eeprom/at24.cb/kernel/msm-3.18/drivers/misc/eeprom/at24.c

old mode 100644

new mode 100755

index ca5a127..bf58efc

---a/kernel/msm-3.18/drivers/misc/eeprom/at24.c

+++b/kernel/msm-3.18/drivers/misc/eeprom/at24.c

@@ -23,6 +23,10 @@

#include <linux/of.h>

#include <linux/i2c.h>

#include <linux/platform_data/at24.h>

+#include<linux/regulator/consumer.h>

+#include <linux/gpio.h>

+#include <linux/of_gpio.h>

+

/*

*I2C EEPROMs from most vendors are inexpensive and mostly interchangeable.

@@ -130,6 +134,82 @@ static const structi2c_device_id at24_ids[] = {

};

MODULE_DEVICE_TABLE(i2c, at24_ids);

+

+

+struct sensor_regulator {

+      struct regulator *vreg;

+      const char *name;

+      u32     min_uV;

+       u32    max_uV;

+};

+

+static struct sensor_regulatorat24c04_vreg[] = {

+      {NULL, "vdd", 1800000, 1800000},

+};

+

+

+static int at24c04_config_regulator(structi2c_client *client, bool on)

+{

+      int rc = 0, i;

+      int num_vreg = sizeof(at24c04_vreg)/sizeof(struct sensor_regulator);

+

+      if (on) {

+               for (i = 0; i < num_vreg;i++) {

+                       at24c04_vreg[i].vreg =regulator_get(&client->dev,

+                                      at24c04_vreg[i].name);

+                       if(IS_ERR(at24c04_vreg[i].vreg)) {

+                               rc =PTR_ERR(at24c04_vreg[i].vreg);

+                              dev_err(&client->dev, "%s:regulator get failedrc=%d\n",

+                                              __func__, rc);

+                              at24c04_vreg[i].vreg = NULL;

+                               goto error_vdd;

+                       }

+                       if (regulator_count_voltages(at24c04_vreg[i].vreg)> 0) {

+                               rc =regulator_set_voltage(at24c04_vreg[i].vreg,

+                                      at24c04_vreg[i].min_uV, at24c04_vreg[i].max_uV);

+                               if (rc) {

+                                      dev_err(&client->dev,"%s:set_voltage failed rc=%d\n",

+                                                      __func__, rc);

+                                      regulator_put(at24c04_vreg[i].vreg);

+                                      at24c04_vreg[i].vreg = NULL;

+                                       gotoerror_vdd;

+                               }

+                       }

+                       rc =regulator_enable(at24c04_vreg[i].vreg);

+                       if (rc) {

+                              dev_err(&client->dev, "%s: regulator_enable failed rc=%d\n",

+                                              __func__, rc);

+                               if(regulator_count_voltages(at24c04_vreg[i].vreg)

+                                              > 0) {

+                                      regulator_set_voltage(at24c04_vreg[i].vreg,

+                                                      0, at24c04_vreg[i].max_uV);

+                               }

+                              regulator_put(at24c04_vreg[i].vreg);

+                              at24c04_vreg[i].vreg = NULL;

+                               goto error_vdd;

+                       }

+               }

+               return rc;

+      } else {

+               i = num_vreg;

+      }

+error_vdd:

+      while (--i >= 0) {

+               if(!IS_ERR_OR_NULL(at24c04_vreg[i].vreg)) {

+                       if(regulator_count_voltages(

+                               at24c04_vreg[i].vreg)> 0) {

+                              regulator_set_voltage(at24c04_vreg[i].vreg, 0,

+                                              at24c04_vreg[i].max_uV);

+                       }

+                      regulator_disable(at24c04_vreg[i].vreg);

+                      regulator_put(at24c04_vreg[i].vreg);

+                       at24c04_vreg[i].vreg =NULL;

+               }

+      }

+      return rc;

+}

+

/*-------------------------------------------------------------------------*/

/*

@@ -142,6 +222,8 @@ static structi2c_client *at24_translate_offset(struct at24_data *at24,

{

unsigned i;

if (at24->chip.flags & AT24_FLAG_ADDR16) {

i = *offset >> 16;

*offset &= 0xffff;

@@ -162,6 +244,8 @@ static ssize_tat24_eeprom_read(struct at24_data *at24, char *buf,

unsigned long timeout, read_time;

int status, i;

memset(msg, 0, sizeof(msg));

/*

@@ -253,7 +337,7 @@ static ssize_tat24_eeprom_read(struct at24_data *at24, char *buf,

if (status == 2)

status = count;

}

-               dev_dbg(&client->dev,"read %zu@%d --> %d (%ld)\n",

+               pr_err("read%zu@%d --> %d (%ld)\n",

count, offset,status, jiffies);

if (status == count)

@@ -271,6 +355,8 @@ static ssize_tat24_read(struct at24_data *at24,

{

ssize_t retval = 0;

if (unlikely(!count))

return count;

@@ -305,6 +391,7 @@ static ssize_tat24_bin_read(struct file *filp, struct kobject *kobj,

char *buf, loff_t off, size_tcount)

{

struct at24_data *at24;

at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));

return at24_read(at24, buf, off, count);

@@ -328,6 +415,8 @@ static ssize_tat24_eeprom_write(struct at24_data *at24, const char *buf,

unsigned long timeout, write_time;

unsigned next_page;

/* Get corresponding I2C address and adjust offset */

client = at24_translate_offset(at24, &offset);

@@ -375,7 +464,8 @@ static ssize_tat24_eeprom_write(struct at24_data *at24, const char *buf,

if (status == 1)

status = count;

}

-               dev_dbg(&client->dev,"write %zu@%d --> %zd (%ld)\n",

+               mdelay(10);

if (status == count)

@@ -392,6 +482,7 @@ static ssize_tat24_write(struct at24_data *at24, const char *buf, loff_t off,

size_t count)

{

ssize_t retval = 0;

if (unlikely(!count))

return count;

@@ -427,6 +518,7 @@ static ssize_tat24_bin_write(struct file *filp, struct kobject *kobj,

char *buf, loff_t off, size_tcount)

{

struct at24_data *at24;

if (unlikely(off >= attr->size))

return -EFBIG;

@@ -447,6 +539,7 @@ static ssize_tat24_macc_read(struct memory_accessor *macc, char *buf,

off_t offset, size_tcount)

{

struct at24_data *at24 = container_of(macc, struct at24_data, macc);

return at24_read(at24, buf, offset, count);

}

@@ -455,6 +548,7 @@ static ssize_tat24_macc_write(struct memory_accessor *macc, const char *buf,

off_t offset, size_tcount)

{

struct at24_data *at24 = container_of(macc, struct at24_data, macc);

return at24_write(at24, buf, offset,count);

}

@@ -491,6 +585,17 @@ static intat24_probe(struct i2c_client *client, const struct i2c_device_id *id)

int err;

unsigned i, num_addresses;

kernel_ulong_t magic;

+

+      if (gpio_is_valid(50)) {

+               err = gpio_request(50,"at24c04_wp");

+               if (err) {

+                       printk("Unable torequest at24c04_wp gpio\n");

+                       }

+               err =gpio_direction_output(50,0);

+               }

if (client->dev.platform_data) {

chip = *(structat24_platform_data *)client->dev.platform_data;

@@ -571,6 +676,9 @@ static int at24_probe(structi2c_client *client, const struct i2c_device_id *id)

at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO :S_IRUSR;

at24->bin.read = at24_bin_read;

at24->bin.size = chip.byte_len;

+

+

+      at24c04_config_regulator(client, 1);

at24->macc.read = at24_macc_read;

@@ -623,7 +731,7 @@ static intat24_probe(struct i2c_client *client, const struct i2c_device_id *id)

i2c_set_clientdata(client, at24);

-      dev_info(&client->dev, "%zu byte %s EEPROM, %s, %ubytes/write\n",

+      dev_info(&client->dev, " %zu byte %s EEPROM, %s, %ubytes/write\n",

at24->bin.size,client->name,

writable ? "writable": "read-only", at24->write_max);

if (use_smbus == I2C_SMBUS_WORD_DATA ||

@@ -663,7 +771,7 @@ static intat24_remove(struct i2c_client *client)

/*-------------------------------------------------------------------------*/

static const struct of_device_idat24_of_match[] = {

-      { .compatible = "atmel,24c32", },

+      { .compatible = "atmel,24c04", },

{ }

};

MODULE_DEVICE_TABLE(of, at24_of_match);

(END)

以上有三点要做特别说明:

1、  原来的compatible是24c32,这里不要偷懒,一定要改成24c04,dtsi里也要设成24c04。

static const struct of_device_idat24_of_match[] = {

-      { .compatible = "atmel,24c32", },

+      { .compatible = "atmel,24c04", },

{ }

2、  WP管脚要设成低电平才能写:

+      if (gpio_is_valid(50)) {

+               err = gpio_request(50,"at24c04_wp");

+               if (err) {

+                       printk("Unable torequest at24c04_wp gpio\n");

+                       }

+               err =gpio_direction_output(50,0);

+               }

3、  在写函数里要加延时,不然会报I2C无ACK,(秉着一种严谨的态度,不给任何挑剔的机会):

-               dev_dbg(&client->dev,"write %zu@%d --> %zd (%ld)\n",

+               mdelay(10);

+               pr_err("write%zu@%d --> %zd (%ld)\n",

count, offset, status, jiffies);

最后上测试代码:

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

* 档名:at24c04-test.c

* 作者:yezelin.2007@163.com

* 日期:2018/07/11

* 描述:使用android内核提供的at24.c驱动读写板载AT24C04

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

#include <stdio.h>

#include <fcntl.h>

#include <sys/ioctl.h>

#include <linux/types.h>

#include <unistd.h>

#include <time.h>

int main()

{

intfd;

inti;

charwrite_data[8] = {

'A',0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,0x40

};

charread_data[256] = {0};

fd= open("/sys/bus/i2c/devices/5-0050/eeprom",O_RDWR);//这里需要改成你平台的路径

lseek(fd,0,SEEK_SET);

write(fd,write_data,8);

usleep(20000);

lseek(fd,0,SEEK_SET);

read(fd,read_data,8);

usleep(20000);

for(i=0;i<8;i++)

{

if(i%16== 0)

printf("\n");

printf("%02x",read_data[i]);

}

printf("\n");

}

效果展示:

Eeprom(at24c04)调试小记相关推荐

  1. GD32F303调试小记(三)之IIC(硬件IIC+PCF8563实时时钟)

    前言 前面的文章介绍了在单片机中常用的两种通信协议(USART和SPI),并给出了GD32F303对应的配置流程.这次介绍第三种常见的通信协议IIC.这此使用GD32的硬件IIC通信PCF8563实时 ...

  2. 嵌入式实操----基于RT1170 首板硬件之EEPROM AT24C16调试(十五)

    本文主要是通过迁移的思维,记录本人初次使用NXP MCUXpresso SDK API进行BSP开发 前面调通了SDRAM Flash GPIO之后,接下来调试EEPROM AT24C16功能,硬件设 ...

  3. GD32F303调试小记(一)之USART(接收中断、接收空闲中断+DMA、发送DMA)

    前言 之前写了GD32F103调试小记(二)之USART(接收中断.接收空闲中断+DMA.发送DMA)一文.这次我们来看看GD32F303的USART是如何配置的,结合这两篇文章,相信大家GD32的U ...

  4. GD32F303调试小记(二)之SPI(软件SPI、硬件SPI、硬件SPI+DMA)

    前言 目前有一个项目中用到了TFT-LCD,其驱动芯片为ILI9341.为更好的达到显示效果,在最终的代码中我们会使用单片机自带的硬件SPI+DMA模块(由于调试过程中SPI+DMA输出的波形没能驱屏 ...

  5. Intellij Idea远程调试小记

    最近在Spring开发中遇到一个小问题,导致代码每次跑到Biz层就出现跑空的情况,遂找力哥给讲解了以下Intellij Idea 远程调试的方法. 1.首先mvn编译参数: mvn clean pac ...

  6. TEB算法2-teb参数说明及调试小记

    TEB参数说明 一. 参数说明 1.Trajectory 2.Robot 3. GoalTolerance 4.Obstacles 5.Optimization 6. Homotopy Class P ...

  7. EEPROM(AT24C512)调试总结

    这两周一直在测试AT24C512,之前用的EEPROM是AT24C16,与其相比,AT24C512有一些改动: 1,寻址空间变大,数据地址由8位变为16位,因此写入时序需要加入高.低位地址写入; 2, ...

  8. WinCE开机logo调试小记

    PXA310的BSP中没有带开机Logo的功能,所以只能自己添加.但是在网上找资料,找来找去,都是三星的,于是很郁闷的想,怎么当初他们选芯片的时候没选三星的-- 没办法,只能硬着头皮上了.对比查找到的 ...

  9. 24lc024 EEPROM芯片调试

    当SCL为高时,sda由高到低的跳变,表示开始: 当SCL为高时,sda由低到高的掉变,表示停止: 单字节读写模式: 写数据: sda写数据时序:  START   1010000   ACK(低) ...

最新文章

  1. Specification使用notin
  2. 李世石宣布退役,高呼AI不可战胜:将举行史上首次让子人机大战
  3. 中国K12教育行业运营动向及未来发展战略分析报告2022年版
  4. 逆向入门--何为OEP
  5. python 知识点总结
  6. Postgres客户端编码问题
  7. centos7 安装 JDK环境
  8. 解锁windows phone 8以进行开发
  9. python计算坐标点欧式距离_计算机视觉课堂笔记-4
  10. 他曾经复读才考上三本,如今让华为开出 201 万年薪(其实还拒绝了 360 万 offer)...
  11. python md5算法调用与hashlib模块
  12. 使用OBS直播软件进行直播推流
  13. 只要一行代码,批量将Word转换为PDF!
  14. 睡眠 应该用 a加权 c加权_困成狗?谈谈睡眠研究的遗传发现之旅
  15. 姓名签名设计手写简单自己名字怎么写
  16. 关于树莓派DSI屏幕触摸不准的问题
  17. 神经网络文本分类技术实践总结
  18. 【C语言】指针终结者-初阶
  19. 和疫情赛跑 30 天,湖北武汉的程序员们怎么样了?
  20. 看日光穿过手指 享受芬芳的下午茶

热门文章

  1. 利用HTA文件绕过杀软及邮件钓⻥
  2. 世界上第一台通用计算机用途,世界上第一台计算机的作用?
  3. woo语言使用sockets模拟http请求
  4. K8S CNI及各CNI网络解决方案简述
  5. 人物专访 | 杜军:处在新基建时代,坚定做数字经济大厦奠基人
  6. draftsight不能输入中文的完美解决方法
  7. 信息系统项目管理-立项管理
  8. 【秋招纪实录】一篇特别正经的【TCL】求职经验分享
  9. 政府采购网上商城是不是未来的趋势
  10. 以前写的代码感觉很有用