在嵌入式中,I2C设备的使用比较广泛,U-Boot集成了i2c的操作函数及命令。如下
> help i2c
i2c speed [speed] - show or set I2C bus speed
i2c dev [dev] - show or set current I2C bus
i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device
i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)
i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)
i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)
i2c crc32 chip address[.0, .1, .2] count - compute CRC32 checksum
i2c probe - show devices on the I2C bus
i2c reset - re-init the I2C Controller
i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device
i2c sdram chip - print SDRAM configuration information
> i2c dev // 查看当前的i2c总线
Current bus is 1
> iprobe // i2c设备地址探测
Valid chip addresses: 51 68
Excluded chip addresses: 20 21 38 39
> imd 0x51 0.0 // 读i2c设备
0000: 08 07 0d 0a 01 40 00 04 50 70 00 82 10 00 01 0e ......
Freescale的PowerPC芯片MPC8349E内部集成了两个i2c控制器,在MPC8349E-mITX开发板中用控制器I2C1连接M24256-BWMN6P
(i2c eeprom芯片,256kB大小),用I2C2连接了PCF8574(0x20, 0x21), DS1339U-33 RTC(0x39), DDR SPD eeprom(0x51)等。
其中M24256-BWMN6P这个i2c eeprom可以用来存储硬复位配置字HRCW,作为PowerPC启动时的复位配置字源。
一开始在板子上操作iprobe命令时,发现始终读写不了设备地址0x50,后来看了一下U-Boot实现i2c eeprom写HRCW的实现,
才明白iprobe命令是和i2c当前总线控制器有关,它只探测当前总线上的i2c设备。通过如下命令可以进行总线控制器的设置
。
> i2c dev 0
Setting bus to 0
> iprobe
Valid chip addresses: 50
Excluded chip addresses:
> imd 0x50 .2 17 // 从i2c eeprom的起始地址0开始开始读17个对象,等同于imd 0x50 0.2 17
0000: aa 55 aa 7c 02 40 04 04 00 00 7c 02 41 b4 60 a0 .`.
0010: 00 ff ff ff ff ff ff .......
> imm 0x50 .2
00000000: ff ? aa
00000001: ff ? .
> isdram 0x51
SPD data revision 1.1
Bytes used 0x80
Serial memory size 0x100
.....
在u-boot代码中如下实现HRCW对I2C EEPROM的写入。
// board/freescale/mpc8349itx/mpc8349itx.c
242 /*
243 * Miscellaneous late-boot configurations
244 *
245 * Make sure the EEPROM has the HRCW correctly programmed.
246 * Make sure the RTC is correctly programmed.
247 *
248 * The MPC8349E-mITX can be configured to load the HRCW from
249 * EEPROM instead of flash. This is controlled via jumpers
250 * LGPL0, 1, and 3. Normally, these jumpers are set to 000 (all
251 * jumpered), but if they're set to 001 or 010, then the HRCW is
252 * read from the "I2C EEPROM".
253 *
254 * This function makes sure that the I2C EEPROM is programmed
255 * correctly.
256 *
258 */
259 int misc_init_r(void) // 此函数在lib_ppc/board.c的board_init_r()中被调用
260 {
261 int rc = 0;
262
263 #ifdef CONFIG_HARD_I2C
264
265 unsigned int orig_bus = i2c_get_bus_num();
266 u8 i2c_data;
267
268 #ifdef CONFIG_SYS_I2C_RTC_ADDR
269 u8 ds1339_data[17];
270 #endif
271
272 #ifdef CONFIG_SYS_I2C_EEPROM_ADDR
273 static u8 eeprom_data[] = /* HRCW data */
274 {
275 0xAA, 0x55, 0xAA, /* Preamble */
276 0x7C, /* ACS=0, BYTE_EN=1111, CONT=1 */
277 0x02, 0x40, /* RCWL ADDR=0x0_0900 */
278 (CONFIG_SYS_HRCW_LOW >> 24) & 0xFF,
279 (CONFIG_SYS_HRCW_LOW >> 16) & 0xFF,
280 (CONFIG_SYS_HRCW_LOW >> 8) & 0xFF,
281 CONFIG_SYS_HRCW_LOW & 0xFF,
282 0x7C, /* ACS=0, BYTE_EN=1111, CONT=1 */
283 0x02, 0x41, /* RCWH ADDR=0x0_0904 */
284 (CONFIG_SYS_HRCW_HIGH >> 24) & 0xFF,
285 (CONFIG_SYS_HRCW_HIGH >> 16) & 0xFF,
286 (CONFIG_SYS_HRCW_HIGH >> 8) & 0xFF,
287 CONFIG_SYS_HRCW_HIGH & 0xFF
288 };
289
290 u8 data[sizeof(eeprom_data)];
291 #endif
292
293 printf("Board revision: ");
294 i2c_set_bus_num(1);
295 if (i2c_read(CONFIG_SYS_I2C_8574A_ADDR2, 0, 0, &i2c_data, sizeof(i2c_data)) == 0)
296 printf("%u.%u (PCF8475A)\n", (i2c_data & 0x02) >> 1, i2c_data & 0x01);
297 else if (i2c_read(CONFIG_SYS_I2C_8574_ADDR2, 0, 0, &i2c_data, sizeof(i2c_data)) == 0)
298 printf("%u.%u (PCF8475)\n", (i2c_data & 0x02) >> 1, i2c_data & 0x01);
299 else {
300 printf("Unknown\n");
301 rc = 1;
302 }
303
304 #ifdef CONFIG_SYS_I2C_EEPROM_ADDR
305 i2c_set_bus_num(0);
306
307 if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, data, sizeof(data)) == 0) {
308 if (memcmp(data, eeprom_data, sizeof(data)) != 0) {
309 if (i2c_write
310 (CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, eeprom_data,
311 sizeof(eeprom_data)) != 0) {
312 puts("Failure writing the HRCW to EEPROM via I2C.\n");
313 rc = 1;
314 }
315 }
316 } else {
317 puts("Failure reading the HRCW from EEPROM via I2C.\n");
318 rc = 1;
319 }
320 #endif
321
322 #ifdef CONFIG_SYS_I2C_RTC_ADDR
323 i2c_set_bus_num(1);
// ... skip
378 #endif
379
380 i2c_set_bus_num(orig_bus);
381 #endif
391 return rc;
392 }
读写函数说明:
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len);
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len);
/*
* Read/Write interface:
* chip: I2C chip address, range 0..127
* addr: Memory (register) address within the chip
* alen: Number of bytes to use for addr (typically 1, 2 for larger
* memories, 0 for register type devices with only one
* register)
* 其中alen 为1,说明chip是8bit的, 为2则是 16bit的。
* buffer: Where to read/write the data
* len: How many bytes to read/write
*
* Returns: 0 on success, not 0 on failure
*/
阅读(12850) | 评论(0) | 转发(0) |