Skip to main content

i2c-device-hub

Functional read-out of every populated device on the EVK sensor/power I²C bus, each through its real chip driver — not a raw register poke. The "prove the whole board is usable" demo: one bus, many ICs, each brought up and read for a real value.

It completes the I²C trio: i2c-scanner probes addresses for ACKs, i2c-master reads one known sensor, and this one drives the full populated set with a per-device verdict plus a final RESULT tally.

Source: examples/peripheral-io/i2c-device-hub/.

Devices exercised

Addresses come from the e1m-evk board preset's populated set.

DeviceRoleAddressWhat's read
ICM-42670IMU0x69WHO_AM_I + a live accel sample
BMI323IMU0x68CHIP_ID + a live accel sample
BMP581Barometer0x47CHIP_ID + a raw pressure/temperature sample
INA236 ×6Rail monitorsper railBus voltage (mV) + current (µA) per rail
TAS2563 ×2I²S smart-amps0x4d / 0x4eRevision + ACTIVE-mode config readback
TCA6408AI/O expander0x20 (TCAL9538 0x72 alt)Config + input port
24C128EEPROM0x50First 16 bytes

The six INA236 rails are +3V3, +1V8, +VIO, +VCAM0, +VCAM1, and +5V — each with its own shunt value and max-current bound from the board header.

Each device is independent: a missing or DNP part is reported and skipped, never fatal. The final line reports answered/attemptedPASS when all answered, PARTIAL otherwise.

:::note Pre-respin EVK quirk On the pre-respin EVK batch the ICM-42670 and BMI323 both strap to 0x69 and collide, so both IMU rows fail until the respin. The source documents this inline. :::

What it shows

  • alp_i2c_open() on BOARD_I2C_SENSORS at 100 kHz.
  • Seven chip-driver bring-up patterns on one shared bus: icm42670_*, bmi323_*, bmp581_*, ina236_*, tas2563_*, tcal9538_* (which drives either PCA9538-class expander), and eeprom_24c128_*.
  • Graceful per-device degradation — absent parts print alp_last_error() or the failing alp_status_t and the run continues.
  • alp_i2c_write_read() used directly for the small raw readbacks (amp MODE_CTRL, expander config/input).

board.yaml

Note this one runs on the M55-HE (high-efficiency) core.

som:
sku: E1M-AEN801
preset: e1m-evk

cores:
m55_he:
app: ./src
peripherals:
- i2c

chips:
- icm42670
- bmi323
- bmp581
- ina236
- tas2563
- tcal9538
- eeprom_24c128

diagnostics:
log_level: info

Every chip driver src/main.c includes directly is declared here — an undeclared <alp/chips/*.h> include skips the portability checker's family-compatibility check and misreports the ring.

Expected output

Real hardware (post-respin EVK, everything populated) prints one line per device with live values, ending in:

[devhub] RESULT PASS: 13/13 devices answered
[devhub] done

native_sim routes alp-i2c0 to a zephyr,i2c-emul-controller with no emul targets attached, so every device reports absent. This is a silicon example — the native_sim value is just "the plumbing compiles, links, and exits cleanly":

[devhub] open BOARD_I2C_SENSORS @ 100 kHz
[devhub] ICM42670 @0x69 init fail (rc=-5; pre-respin collides w/ BMI323 @0x69)
[devhub] BMI323 @0x68 init fail (rc=-5; pre-respin it's at 0x69)
[devhub] BMP581 @0x47 absent (err=0)
...
[devhub] RESULT PARTIAL: 0/13 devices answered
[devhub] done

Status

One twister row on native_sim/native/64 with ALP_BOARD_E1M_EVK set; the harness latches on [devhub] done. The RESULT line is a bench signal only — CI proves compile/link/exit, not device presence.

Troubleshooting

SymptomCause / fix
One device row fails on real hardwareRun i2c-scanner and compare against the address table. The DNP options (TCA6408A vs TCAL9538) and the pre-respin IMU collision are the usual suspects.
bus open failedThe alp-i2c alias for BOARD_I2C_SENSORS isn't routed on your board target. On native_sim, check the shipped overlay + CONFIG_EMUL=y / CONFIG_I2C_EMUL=y.

See also

Questions about this page? Discuss in Community Forum