Eeprom(at24c04)调试小记
最近花了点时间在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)调试小记相关推荐
- GD32F303调试小记(三)之IIC(硬件IIC+PCF8563实时时钟)
前言 前面的文章介绍了在单片机中常用的两种通信协议(USART和SPI),并给出了GD32F303对应的配置流程.这次介绍第三种常见的通信协议IIC.这此使用GD32的硬件IIC通信PCF8563实时 ...
- 嵌入式实操----基于RT1170 首板硬件之EEPROM AT24C16调试(十五)
本文主要是通过迁移的思维,记录本人初次使用NXP MCUXpresso SDK API进行BSP开发 前面调通了SDRAM Flash GPIO之后,接下来调试EEPROM AT24C16功能,硬件设 ...
- GD32F303调试小记(一)之USART(接收中断、接收空闲中断+DMA、发送DMA)
前言 之前写了GD32F103调试小记(二)之USART(接收中断.接收空闲中断+DMA.发送DMA)一文.这次我们来看看GD32F303的USART是如何配置的,结合这两篇文章,相信大家GD32的U ...
- GD32F303调试小记(二)之SPI(软件SPI、硬件SPI、硬件SPI+DMA)
前言 目前有一个项目中用到了TFT-LCD,其驱动芯片为ILI9341.为更好的达到显示效果,在最终的代码中我们会使用单片机自带的硬件SPI+DMA模块(由于调试过程中SPI+DMA输出的波形没能驱屏 ...
- Intellij Idea远程调试小记
最近在Spring开发中遇到一个小问题,导致代码每次跑到Biz层就出现跑空的情况,遂找力哥给讲解了以下Intellij Idea 远程调试的方法. 1.首先mvn编译参数: mvn clean pac ...
- TEB算法2-teb参数说明及调试小记
TEB参数说明 一. 参数说明 1.Trajectory 2.Robot 3. GoalTolerance 4.Obstacles 5.Optimization 6. Homotopy Class P ...
- EEPROM(AT24C512)调试总结
这两周一直在测试AT24C512,之前用的EEPROM是AT24C16,与其相比,AT24C512有一些改动: 1,寻址空间变大,数据地址由8位变为16位,因此写入时序需要加入高.低位地址写入; 2, ...
- WinCE开机logo调试小记
PXA310的BSP中没有带开机Logo的功能,所以只能自己添加.但是在网上找资料,找来找去,都是三星的,于是很郁闷的想,怎么当初他们选芯片的时候没选三星的-- 没办法,只能硬着头皮上了.对比查找到的 ...
- 24lc024 EEPROM芯片调试
当SCL为高时,sda由高到低的跳变,表示开始: 当SCL为高时,sda由低到高的掉变,表示停止: 单字节读写模式: 写数据: sda写数据时序: START 1010000 ACK(低) ...
最新文章
- Specification使用notin
- 李世石宣布退役,高呼AI不可战胜:将举行史上首次让子人机大战
- 中国K12教育行业运营动向及未来发展战略分析报告2022年版
- 逆向入门--何为OEP
- python 知识点总结
- Postgres客户端编码问题
- centos7 安装 JDK环境
- 解锁windows phone 8以进行开发
- python计算坐标点欧式距离_计算机视觉课堂笔记-4
- 他曾经复读才考上三本,如今让华为开出 201 万年薪(其实还拒绝了 360 万 offer)...
- python md5算法调用与hashlib模块
- 使用OBS直播软件进行直播推流
- 只要一行代码,批量将Word转换为PDF!
- 睡眠 应该用 a加权 c加权_困成狗?谈谈睡眠研究的遗传发现之旅
- 姓名签名设计手写简单自己名字怎么写
- 关于树莓派DSI屏幕触摸不准的问题
- 神经网络文本分类技术实践总结
- 【C语言】指针终结者-初阶
- 和疫情赛跑 30 天,湖北武汉的程序员们怎么样了?
- 看日光穿过手指 享受芬芳的下午茶