Tuesday, 8 March 2016

U-boot fails to load env from I2C eeprom if SPI is enabled

U-boot failed to load environment from an I2C eeprom with the following errors:

U-Boot SPL 2015.10-00002-gfedeb03-dirty (Mar 08 2016 - 13:05:30)
reading args
spl_load_image_fat_os: error reading image args, err - -1
reading u-boot.img
reading u-boot.img


U-Boot 2015.10-00002-gfedeb03-dirty (Mar 08 2016 - 13:05:30 +0000)

       Watchdog enabled
I2C:   ready
DRAM:  512 MiB
MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
i2c_read: error waiting for addr ACK (status=0x116)
*** Error - default environment is too large

Net:   <ethaddr> not set. Validating first E-fuse MAC
Phy 0 not found
cpsw
Error: cpsw address not set.
, usb_ether
Error: usb_ether address not set.

env_buf [32 bytes] too small for value of "bootcmd"
Hit any key to stop autoboot:  0 

On investigation, adding a debug output I found that the wrong I2C address was being read:
I2C read: addr:0 len:4 alen:1 chip:0x00

My configuration defines the env on an eeprom at 0x50:
/* EEPROM (24C16) */
#define CONFIG_CMD_EEPROM
#define CONFIG_ENV_IS_IN_EEPROM
#define CONFIG_I2C_ENV_EEPROM_BUS 1
#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* Main EEPROM */
#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1
#define CONFIG_SYS_I2C_MULTI_EEPROMS
#define CONFIG_SYS_EEPROM_PAGE_WRITE_ENABLE
#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 3  /* 8 Byte write page */
#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 10
#define CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW 0x07

Looking at the section of code at include/common.h:483:
#if defined(CONFIG_SPI) || !defined(CONFIG_SYS_I2C_EEPROM_ADDR)
# define CONFIG_SYS_DEF_EEPROM_ADDR 0
#else
#if !defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
# define CONFIG_SYS_DEF_EEPROM_ADDR CONFIG_SYS_I2C_EEPROM_ADDR
#endif
#endif /* CONFIG_SPI || !defined(CONFIG_SYS_I2C_EEPROM_ADDR) */

The logic is a bit confusing but appears to set CONFIG_SYS_DEF_EEPROM_ADDR to 0 if CONFIG_SPI is defined but I don't have CONFIG_SPI defined!

On closer inspection, an included default config for the SoC I was using had defined this so simply adding:
#undef CONFIG_SPI

Resolved the issue :-) 

1 comment:

  1. Ourinjection molding engineers have huge expertise in manufacturingand serving to customers bring their concept or product to fruition. We work best white gel pens hand in hand with you and ask all the best questions to give you the instruments your product needs to succeed and do the job you designed it for in focused environments. A multi-cavity mould is designed to make quantity of} equivalent elements per cycle. This type of mould is costlier because of|as a outcome of} it takes longer to cut with each cavity that is added. Large volume productions are typically achieved with {this type of|this kind of|this kind of} mould {because|as a outcome of|as a outcome of} each mould cycle may be made to provide much more than a single cavity mould, aiding in manufacturing speed. Today, attitudes in enterprise have shifted to be more about, "How rapidly capable to} get me this?" People don’t like to purchase a lot of things that they don’t want right away.

    ReplyDelete