Stop miscounting SHT31 bring-up and status-read failures

Two ways the error counters lied about sensor health.

The first measurement failed on every boot, leaving a permanent
i2c_errors=1 that a master polling READ_STATUS could not tell apart from
a real fault. The sensor NACKs a command arriving while it is still busy
with the previous one, and the bring-up sequence issued a measurement
immediately after clear_status with no quiet time. Commands are now
spaced by sht3x::COMMAND_SETTLE_MS. Bring-up failures stay uncounted on
purpose: the counters describe operational health, and an unreadable
serial already surfaces as a zero in READ_INFO.

read_status() failures were discarded via `if let Ok`, which made a
persistently unreadable status register indistinguishable from a
genuinely clean one — both leave sensor_status at zero. They are now
counted, but kept out of the consecutive-failure tally so only the
measurement path drives the fault and soft-reset logic.

Confirmed on hardware: a fresh boot now holds err[i2c=0 sht_crc=0
frame=0 bus_crc=0] indefinitely, where it previously showed i2c=1 from
the first poll onwards. After a full bus test run the counters read
exactly frame=2 bus_crc=2, accounting for the four faults the suite
injects deliberately and nothing else.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Oliver Walter
2026-07-28 20:35:59 +02:00
parent aa48d8784f
commit 25dba97c06
2 changed files with 49 additions and 9 deletions
+9
View File
@@ -77,6 +77,15 @@ pub const SOFT_RESET_MAX_MS: u32 = 2;
/// Worst-case power-up time (data sheet: 1.5 ms).
pub const POWER_UP_MAX_MS: u32 = 2;
/// Quiet time to leave between two consecutive commands.
///
/// The data sheet gives durations for individual commands but no general
/// inter-command gap, and the sensor NACKs a command that arrives while it is
/// still busy with the previous one. Sending a measurement immediately after a
/// status-register write is enough to trigger it. 5 ms is far more than any
/// non-measurement command needs and only ever costs us during bring-up.
pub const COMMAND_SETTLE_MS: u32 = 5;
/// Split a 16-bit command into the wire byte order (MSB first).
pub const fn command_bytes(cmd: u16) -> [u8; 2] {
cmd.to_be_bytes()