8827|16

854

帖子

0

TA的资源

五彩晶圆(中级)

楼主
 

在S5pv210 uboot上增加I2C 读写功能 [复制链接]

#define CONFIG_CMD_I2C
//#undef CONFIG_S3C64XX_I2C                /* this board has H/W I2C */
#define CONFIG_S3C64XX_I2C
#ifdef CONFIG_S3C64XX_I2C
#define CONFIG_HARD_I2C                1
#define CFG_I2C_SPEED                50000
#define CFG_I2C_SLAVE                0x70
#endif



这样编译,就出错了。
'S3C64XX_I2C' undeclared (first use in this function)
咋回事呢。这个S5pv210 是不支持I2C的,这个功能需要从6410 上移植过来。
试试看吧。

最新回复

是的啊  详情 回复 发表于 2013-11-22 12:10
点赞 关注
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460

回复
举报

854

帖子

0

TA的资源

五彩晶圆(中级)

沙发
 

这个应该是一些名称改一下就可以了
6410 的是这个
/************************************************
* NAME            : S3C64XX.h
* Version  : 31.3.2003
*
* common stuff for SAMSUNG S3C64XX SoC
************************************************/
/* IIC (see manual chapter 20) */
typedef struct {
        S3C64XX_REG32        IICCON;
        S3C64XX_REG32        IICSTAT;
        S3C64XX_REG32        IICADD;
        S3C64XX_REG32        IICDS;
} /*__attribute__((__packed__))*/ S3C64XX_I2C;
S5PV210 是这个

/************************************************
* NAME            : S5PC11X.h
* Version  : 31.3.2003
*
* common stuff for SAMSUNG S5PC11X SoC
************************************************/
/* IIC (see manual chapter 20) */
typedef struct {
        S5PC11X_REG32        IICCON;
        S5PC11X_REG32        IICSTAT;
        S5PC11X_REG32        IICADD;
        S5PC11X_REG32        IICDS;
} /*__attribute__((__packed__))*/ S5PC11X_I2C;
 
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
 

回复

854

帖子

0

TA的资源

五彩晶圆(中级)

板凳
 
介绍几个主要命令
iprobe     检测所有在总线上的i2c设备号(相当好用的命令)
imw        i2c内存赋值,使用方法 imw 从机地址 数据地址 数据
              eg. imw 0x76 4 0x20
imd         观察i2c内存
imm        自动增加地址赋值
出来了。
嘿嘿,程序是挂上去了,但是还是找不到IIC的设备地址。
 
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
 
 

回复

854

帖子

0

TA的资源

五彩晶圆(中级)

4
 
【转帖请注明出处:blog.csdn.net/lanmanck】
看格式,介绍参数好了:
int i2c_read(u_int8_t chip, //芯片的i2c地址,不包含读写位
u_int32_t addr, //芯片内的读写地址,比如寄存器地址
int alen, //这个要看代码才知道是地址的长度。比如有的flash比较大就有16位地址。
              //uboot支持32位地址,不过要看驱动支不支持。0=8bit,1=16bit,2=32bit地址长度
u_int8_t *buf, //数据
int len)            //数据长度

通过代码可以看到,addr是在alen!=0的情况下采用的,所以如果只是读写8位地址的芯片,addr是没有用的。因此在读取之前可能需要用i2c_write先写一个寄存器地址,然后再调用i2c_read进行读取。
 
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
 
 

回复

854

帖子

0

TA的资源

五彩晶圆(中级)

5
 

修改CPU型号为S3C6410的mini6410开发板的uboot,使其支持I2C器件的读写。

通过阅读uboot顶层目录readme文件中和I2C相关部分,可以清楚知道系统支持I2C需要做的修改。

readme中和i2c相关的部分有

(1) #define enables commands: -------------------------

CFG_CMD_I2C * I2C serial bus support

此部分为i2c测试命令的支持。所以需要将mini6410.h文件中命令定义修改为

[cpp] view plaincopyprint?
  • /***********************************************************
  • * Command definition
  • ***********************************************************/
  • #define CONFIG_COMMANDS \
  • (CFG_CMD_I2C | \
  • CONFIG_CMD_DFL | \
  • CFG_CMD_CACHE | \
  • CFG_CMD_USB | \
  • CFG_CMD_REGINFO | \
  • CFG_CMD_LOADS | \
  • CFG_CMD_LOADB | \
  • CFG_CMD_ENV | \
  • CFG_CMD_NAND | \
  • CFG_CMD_PING | \
  • CFG_CMD_MOVINAND) \
  • & ~(CFG_CMD_AUTOSCRIPT | \
  • CFG_CMD_BOOTD | \
  • CFG_CMD_IMI | \
  • CFG_CMD_RUN | \
  • CFG_CMD_CCONFIG_COMMANDS ONSOLE | \
  • CFG_CMD_DOCG3P3 | \
  • CFG_CMD_EEPROM | \
  • 0)
即 CFG_CMD_I2C从下面移动到上面,使 CONFIG_COMMANDS 支持i2c测试命令。 (2)对硬件I2C相关说明 [cpp] view plaincopyprint?
  • - I2C Support: CONFIG_HARD_I2C | CONFIG_SOFT_I2C
  • These enable I2C serial bus commands. Defining either of
  • (but not both of) CONFIG_HARD_I2C or CONFIG_SOFT_I2C will
  • include the appropriate I2C driver for the selected cpu.
  • //需要选择使用硬件I2C或软件I2C
  • This will allow you to use i2c commands at the u-boot
  • command line (as long as you set CFG_CMD_I2C in
  • CONFIG_COMMANDS) and communicate with i2c based realtime
  • clock chips. See common/cmd_i2c.c for a description of the
  • command line interface.
  • CONFIG_I2C_CMD_TREE is a recommended option that places
  • all I2C commands under a single 'i2c' root command. The
  • older 'imm', 'imd', 'iprobe' etc. commands are considered
  • deprecated and may disappear in the future.
  • CONFIG_HARD_I2C selects a hardware I2C controller.
  • CONFIG_SOFT_I2C configures u-boot to use a software (aka
  • bit-banging) driver instead of CPM or similar hardware
  • support for I2C.
  • There are several other quantities that must also be
  • defined when you define CONFIG_HARD_I2C or CONFIG_SOFT_I2C.
  • In both cases you will need to define CFG_I2C_SPEED
  • to be the frequency (in Hz) at which you wish your i2c bus
  • to run and CFG_I2C_SLAVE to be the address of this node (ie
  • the cpu's i2c node address).
  • //无论选择软件还是硬件I2C都要配置I2C SCK
  • //如果作为I2C从设备使用还需要配置从设备地址
[cpp] view plaincopyprint?
  • Now, the u-boot i2c code for the mpc8xx (cpu/mpc8xx/i2c.c)
  • sets the cpu up as a master node and so its address should
  • therefore be cleared to 0 (See, eg, MPC823e User's Manual
  • p.16-473). So, set CFG_I2C_SLAVE to 0.
  • That's all that's required for CONFIG_HARD_I2C.

有几个需要的宏定义需要在 mini6410.h 中进行添加,在mini6410.h文件中看到有如下代码

[cpp] view plaincopyprint?
  • #undef CONFIG_S3C64XX_I2C /* this board has H/W I2C */
  • #ifdef CONFIG_S3C64XX_I2C
  • #define CONFIG_HARD_I2C 1
  • #define CFG_I2C_SPEED 50000
  • #define CFG_I2C_SLAVE 0xFE
只需要把 #undef CONFIG_S3C64XX_I2C 改为 #define CONFIG_S3C64XX_I2C (3)开机初始化 开机时对i2c寄存器进行配置

[cpp] view plaincopyprint?
  • CFG_I2C_INIT_BOARD
  • When a board is reset during an i2c bus transfer
  • chips might think that the current transfer is still
  • in progress. On some boards it is possible to access
  • the i2c SCLK line directly, either by using the
  • processor pin as a GPIO or by having a second pin
  • connected to the bus. If this option is defined a
  • custom i2c_init_board() routine in boards/xxx/board.c
  • is run early in the boot sequence.
在 device.c的devices_init函数中发现有i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); 所以每次开机时都会运行此函数对i2c 进行配置。

添加以上这些后编译并下载uboot,进入uboot命令行,运行help命令能看到以下 I2C相关命令。

[cpp] view plaincopyprint?
  • imd - i2c memory display
  • imls - list all images found in flash
  • imm - i2c memory modify (auto-incrementing)
  • imw - memory write (fill)
  • inm - memory modify (constant address)
  • iprobe - probe to discover valid I2C chip addresses

当运行 iprobe命令时查找不到板子上的I2C器件地址的,并且用示波器测量发现SDA SCL上是没有波形的。

第一反应是程序运行路径和我想象的不一样,但通过打印调试信息发现程序运行路径是正确的。

通过阅读6410 datasheet I2C相关部分发现新问题。没有配置SDA/SCL使用的管脚,所以他们现在功能还是GPIO。

在mini6410.c中的board_init中添加GPIO配置

[cpp] view plaincopyprint?
  • //i2c pin config
  • reg = readl(GPBCON);
  • reg &= ~(0xf << 20);
  • reg |= (0x2 << 20);
  • writel(reg, GPBCON);
  • reg = readl(GPBCON);
  • reg &= ~(0xf << 24);
  • reg |= (0x2 << 24);
  • writel(reg, GPBCON);
  • reg = readl(GPBPUD);
  • reg &= ~(0x3 << 10);
  • writel(reg, GPBPUD);
  • reg = readl(GPBPUD);
  • reg &= ~(0x3 << 12);
  • writel(reg, GPBPUD);
编译并重现下载后 发现iprobe命令还是没有反应,也没有波形。

怀疑I2C寄存器的配置有问题,通过测试发现寄存器读出来的内容和自己配置的数据不一致。

i2c.c文件中对寄存器读写采用的方法如下。

[cpp] view plaincopyprint?
  • S3C64XX_I2C *const i2c = S3C64XX_GetBase_I2C ();//0x7F004000 chan 0 base address
[cpp] view plaincopyprint?
  • i2c->IICSTAT = 0 //写
[cpp] view plaincopyprint?
  • status = i2c->IICCON; //读
此种方式的读和写都存在问题。改为用readl 和 writel函数操作。

重新编译下载uboot。i2c各操作命令运行正常。

总结器件驱动调试方法步骤

1、通过打印信息判断程序运行路径是否正确

2、使用示波器观察有无波形及波形是否正确

3、读取寄存器观察配置是否正确

http://blog.csdn.net/mayaoyao11/article/details/7409274 这篇文章相当不错。嘿嘿。明天估计能出结果。
 
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
 
 

回复

285

帖子

0

TA的资源

一粒金砂(中级)

6
 
不错,介绍得很详细

点评

你是哪个版的斑竹? 嘿嘿,多谢顶贴。 这个是我要用,我也是跟着来整整的。  详情 回复 发表于 2013-11-20 22:30
 
 
 

回复

468

帖子

0

TA的资源

纯净的硅(高级)

7
 
原帖由 qin552011373 于 2013-11-20 17:38 发表
不错,介绍得很详细
你是哪个版的斑竹?
嘿嘿,多谢顶贴。
这个是我要用,我也是跟着来整整的。

点评

模拟的啊,做得很不错呢,我加你的群了呢,顺便请多多照应哈:victory:  详情 回复 发表于 2013-11-21 12:03
 
个人签名
 
 

回复

854

帖子

0

TA的资源

五彩晶圆(中级)

8
 
  1. void i2c_init (int speed, int slaveadd)
  2. {
  3.         S5PC11X_I2C *const i2c = S5PC11X_GetBase_I2C ();
  4.         ulong freq, pres = 16, div;
  5.         int i, status;

  6.         /* wait for some time to give previous transfer a chance to finish */

  7.         i = I2C_TIMEOUT * 1000;
  8.         status = i2c->IICSTAT;
  9.         while ((i > 0) && (status & I2CSTAT_BSY)) {
  10.                 udelay (1000);
  11.                 status = i2c->IICSTAT;
  12.                 i--;
  13.         }

  14.         /* calculate prescaler and divisor values */
  15.         freq = get_PCLK ();
  16.        
  17. #if 0       
  18.         if ((freq / pres / (16 + 1)) > speed)
  19.                 /* set prescaler to 512 */
  20.                 pres = 512;

  21.         div = 0;
  22.         while ((freq / pres / (div + 1)) > speed)
  23.                 div++;

  24. #else
  25.         if (((freq>>4)/speed)>0xf) {
  26.                 pres        =        1;
  27.                 div                =        (freq>>9)/speed;                //        PCLK/512/freq
  28.         } else {
  29.                 pres        =        0;
  30.                 div                =        (freq>>4)/speed;                //        PCLK/16/freq
  31.         }       
  32. #endif
  33.         /* set prescaler, divisor according to freq, also set
  34.          * ACKGEN, IRQ */
  35.         i2c->IICCON = (pres<<6) | (1<<5) | (div&0xf);

  36.         /* init to SLAVE REVEIVE and set slaveaddr */
  37.         i2c->IICSTAT = 0;
  38.         i2c->IICADD = slaveadd;
  39.         /* program Master Transmit (and implicit STOP) */
  40.         i2c->IICSTAT = I2C_MODE_MT | I2C_TXRX_ENA;

  41. }
复制代码
已经运行到这里,IIC设备电源也已经打开但是
输入iprobe命令很久也查找不到IIC的 设备地址
U-boot@SMDKV210# iprobe
Valid chip addresses:
U-boot@SMDKV210#

再看看。
 
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
 
 

回复

285

帖子

0

TA的资源

一粒金砂(中级)

9
 

回复 7楼gooogleman 的帖子

模拟的啊,做得很不错呢,我加你的群了呢,顺便请多多照应哈

点评

这是uboot上从6410 移植过来的,我的不是模拟的哦。是硬件自带的。  详情 回复 发表于 2013-11-21 12:39
 
 
 

回复

854

帖子

0

TA的资源

五彩晶圆(中级)

10
 
囧,终于搞定了,uboot也不少bug ,代码的一些优化了,啥的。写有些问题。
改了之后就OK了。
U-boot@SMDKV210# iprobe
Valid chip addresses: 50
U-boot@SMDKV210# iprobe
Valid chip addresses: 350
输入iproe 命令两秒钟就查询了外设的ID了。
 
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
 
 

回复

854

帖子

0

TA的资源

五彩晶圆(中级)

11
 
原帖由 qin552011373 于 2013-11-21 12:03 发表
模拟的啊,做得很不错呢,我加你的群了呢,顺便请多多照应哈
这是uboot上从6410 移植过来的,我的不是模拟的哦。是硬件自带的。

点评

我意思是我是模拟那边的版主:hug:  详情 回复 发表于 2013-11-21 13:09
 
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
 
 

回复

285

帖子

0

TA的资源

一粒金砂(中级)

12
 

回复 11楼Wince.Android 的帖子

我意思是我是模拟那边的版主

点评

:faint::faint::faint::faint:  详情 回复 发表于 2013-11-21 23:35
 
 
 

回复

854

帖子

0

TA的资源

五彩晶圆(中级)

13
 

首先,通过JTAG将Uboot下载到开发板上,然后通过超级终端与开发板进行交互,这里,常用的命令有:

iprobe:探测连接到I2C上的设备地址(是该设备的I2C地址,非物理地址)

imw  从机地址  设备寄存器地址  数据  //向I2C设备指定的寄存器中写入数据  eg:   imw  60   5  0xff

imd   从机地址  设备寄存器地址  读取数据量  //从I2C设备指定的寄存器读出数据  eg :imd  60  5 8  显示: 05   05  05   05   05  05  05  05

然后,进入Uboot后,打入命令iprobe ,然后返回所以的I2C设备地址,这里显示  00    48    54    60  在IM25板上,目前有I2C转UART6,地址为  48; 9551 接5路LED,地址为  60 。


点亮LED灯

输入Uboot命令:imw 60   5  0×00  // 60为9551地址, 5为寄存器LS0地址,赋值0X00,让L0-L3点亮

同样道理   :输入命令 imw 60  6  0×00//将 L4点亮

默认情况下 LS0,LS1值为0X55,灯全熄灭

通过以上两步,五路LED灯全部点亮

使LED灯闪烁

输入Uboot命令: imw 60  4   80  // 4为PWM1寄存器地址 80为给PWM1赋的值,通过上面的公式可以设置闪烁频率,这里设置值为80。

然后使五路灯工作在PWM1模式下

输入命令

imw  60  5  0xff//使LS0控制的L0-L3工作在PWM1模式下

imw 60   6   0xff //使LS1控制的L4工作在PWM1模式下

可以看到五路灯开始闪烁,证明9551可以正常工作了。搞定了。

 
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
 
 

回复

468

帖子

0

TA的资源

纯净的硅(高级)

14
 
原帖由 qin552011373 于 2013-11-21 13:09 发表
我意思是我是模拟那边的版主

点评

:victory: :victory: :victory: 趁着双十一买了几本书,打算深入学一下系统的知识,还请哥哥姐姐弟弟妹妹们多多照顾  详情 回复 发表于 2013-11-22 08:04
 
个人签名
 
 

回复

285

帖子

0

TA的资源

一粒金砂(中级)

15
 

回复 14楼gooogleman 的帖子

趁着双十一买了几本书,打算深入学一下系统的知识,还请哥哥姐姐弟弟妹妹们多多照顾

点评

电工,一切都是基础  详情 回复 发表于 2013-11-22 08:57
 
 
 

回复

854

帖子

0

TA的资源

五彩晶圆(中级)

16
 
原帖由 qin552011373 于 2013-11-22 08:04 发表
趁着双十一买了几本书,打算深入学一下系统的知识,还请哥哥姐姐弟弟妹妹们多多照顾
电工,一切都是基础

点评

:Laugh: :Laugh: 是的啊  详情 回复 发表于 2013-11-22 12:10
 
个人签名如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
 
 

回复

285

帖子

0

TA的资源

一粒金砂(中级)

17
 

回复 16楼Wince.Android 的帖子

是的啊
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表