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.
| Device | Role | Address | What's read |
|---|---|---|---|
| ICM-42670 | IMU | 0x69 | WHO_AM_I + a live accel sample |
| BMI323 | IMU | 0x68 | CHIP_ID + a live accel sample |
| BMP581 | Barometer | 0x47 | CHIP_ID + a raw pressure/temperature sample |
| INA236 ×6 | Rail monitors | per rail | Bus voltage (mV) + current (µA) per rail |
| TAS2563 ×2 | I²S smart-amps | 0x4d / 0x4e | Revision + ACTIVE-mode config readback |
| TCA6408A | I/O expander | 0x20 (TCAL9538 0x72 alt) | Config + input port |
| 24C128 | EEPROM | 0x50 | First 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/attempted — PASS 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()onBOARD_I2C_SENSORSat 100 kHz.- Seven chip-driver bring-up patterns on one shared bus:
icm42670_*,bmi323_*,bmp581_*,ina236_*,tas2563_*,tcal9538_*(which drives either PCA9538-class expander), andeeprom_24c128_*. - Graceful per-device degradation — absent parts print
alp_last_error()or the failingalp_status_tand the run continues. alp_i2c_write_read()used directly for the small raw readbacks (ampMODE_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
| Symptom | Cause / fix |
|---|---|
| One device row fails on real hardware | Run 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 failed | The 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
<alp/peripheral.h>reference — I²Ci2c-scanner— discovery companioni2c-master— single-device companion- Chip catalogue — the chip-driver APIs used here
- Examples overview