This article was first published on my site: https://resume.tensorview.cc/blog/i2c-trise-ack-trap.html
CCR looked flawless. TRISE was the real trap.
Recently I worked on a layout where the host MCU needed more GPIOs, so we hung an I2C expander. Standard architecture — until intermittent EIO (-5) errors and missing slave ACKs showed up.
Instead of guessing at the driver, I took a structured path: scope the bus and dump physical I2C registers at the moment of failure.
The Illusion
The Clock Control Register (CCR) was calculated correctly for 100 kHz Standard Mode. On paper the baud rate looked flawless.
The Symptom
The oscilloscope showed a slight trailing edge on the SCL rise. The register snapshot at failure captured SR1.AF = 1 (Acknowledge Failure).
The Root Cause
TRISE (maximum rise time) was set too low. The I2C state machine jumped the gun — sampling before SCL had reached a valid high (Vih).
The Fix
I recomputed TRISE from PCLK and the I2C spec, updated Device Tree / driver init, and the bus stayed clean across a 10,000-cycle stress test.
Key Takeaway
High-level abstractions often mask physical reality. When a driver throws a generic error, dump the hardware registers. Registers do not lie.
Original post: https://resume.tensorview.cc/blog/i2c-trise-ack-trap.html
Top comments (0)