修改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?
[cpp] view plaincopyprint?
- status = i2c->IICCON; //读
此种方式的读和写都存在问题。改为用readl 和 writel函数操作。
重新编译下载uboot。i2c各操作命令运行正常。
总结器件驱动调试方法步骤 1、通过打印信息判断程序运行路径是否正确 2、使用示波器观察有无波形及波形是否正确 3、读取寄存器观察配置是否正确
http://blog.csdn.net/mayaoyao11/article/details/7409274
这篇文章相当不错。嘿嘿。明天估计能出结果。 |