修改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文件中命令定义修改为
/*********************************************************** * 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测试命令。
- 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从设备使用还需要配置从设备地址
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文件中看到有如下代码
#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
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相关命令。
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配置
//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文件中对寄存器读写采用的方法如下。
S3C64XX_I2C *const i2c = S3C64XX_GetBase_I2C ();//0x7F004000 chan 0 base address
i2c->IICSTAT = 0 //写
status = i2c->IICCON; //读此种方式的读和写都存在问题。改为用readl 和 writel函数操作。
重新编译下载uboot。i2c各操作命令运行正常。
总结器件驱动调试方法步骤
1、通过打印信息判断程序运行路径是否正确
2、使用示波器观察有无波形及波形是否正确
3、读取寄存器观察配置是否正确
由于不能上传附件 有需要patch文件的可以留下邮箱