From 727781cb6b39867938dbcba45e1946c6570e9ecd Mon Sep 17 00:00:00 2001 From: Matthew Hiles <15929821+sparques@users.noreply.github.com> Date: Mon, 26 Jan 2026 10:57:54 -0500 Subject: [PATCH 1/2] Add per-byte timeout budget for rp2 I2C --- src/machine/machine_rp2_i2c.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/machine/machine_rp2_i2c.go b/src/machine/machine_rp2_i2c.go index 50e2e8a277..2ff92dd7f0 100644 --- a/src/machine/machine_rp2_i2c.go +++ b/src/machine/machine_rp2_i2c.go @@ -280,8 +280,6 @@ func (i2c *I2C) deinit() (resetVal uint32) { // tx performs blocking write followed by read to I2C bus. func (i2c *I2C) tx(addr uint8, tx, rx []byte) (err error) { - const timeout_us = 4_000 - deadline := ticks() + timeout_us if addr >= 0x80 || isReservedI2CAddr(addr) { return errInvalidTgtAddr } @@ -292,6 +290,14 @@ func (i2c *I2C) tx(addr uint8, tx, rx []byte) (err error) { return nil } + // Base 4ms for small register pokes. + // Add per-byte budget. 100us/byte is conservative at 400kHz and still ok at 100kHz for modest sizes. + timeout_us := uint64(4_000) + uint64(txlen+rxlen) * 100 + // Cap so it doesn't go insane: + timeout_us = min(timeout_us, 500_000) + + deadline := ticks() + timeout_us + err = i2c.disable() if err != nil { return err From f7472d5502cbde63198f9fa5281e0df5d0c3ed6d Mon Sep 17 00:00:00 2001 From: Matthew Hiles Date: Mon, 26 Jan 2026 11:31:30 -0500 Subject: [PATCH 2/2] run goimports --- src/machine/machine_rp2_i2c.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_rp2_i2c.go b/src/machine/machine_rp2_i2c.go index 2ff92dd7f0..e4de7a783b 100644 --- a/src/machine/machine_rp2_i2c.go +++ b/src/machine/machine_rp2_i2c.go @@ -292,7 +292,7 @@ func (i2c *I2C) tx(addr uint8, tx, rx []byte) (err error) { // Base 4ms for small register pokes. // Add per-byte budget. 100us/byte is conservative at 400kHz and still ok at 100kHz for modest sizes. - timeout_us := uint64(4_000) + uint64(txlen+rxlen) * 100 + timeout_us := uint64(4_000) + uint64(txlen+rxlen)*100 // Cap so it doesn't go insane: timeout_us = min(timeout_us, 500_000)