Umbrella issue for documented facts that the test suite does not pin, plus a record of the facts the audit verified as correct so they are not "fixed" by mistake.
Part 1 — Test gaps
1. Mode encoding 11 is actively mis-pinned
Tracked in #62. src/lib.rs:2564 asserts 11 must fail. The test has to be replaced, not merely extended.
2. Limit register reset values unpinned
Tracked in #63. Assert the register-operation reset values separately from Fieldset::ZERO — asserting against ZERO is precisely what let the wrong defaults through.
3. The decode tests have no independent oracle
- The 65,536-input test checks only range membership of the result.
- The 4096-value round-trip compares the encoder against its own inverse.
Mutually-consistent wrong permutations pass both. Add a test that computes each code's value independently: for every 12-bit code n in 0..4096, expect n < 2048 ? n : n - 4096 sixteenths, and bytes [n >> 4, (n & 15) << 4]. Include ±0.0625 °C and ±0.125 °C explicitly so individual fractional-bit weights are visible.
4. Three application-note worked values have no assertions
| Bytes |
Value |
Citation |
0x2090 |
32.5625 °C |
sources/an-sbaa588.txt:274 |
0xFAE0 |
-5.125 °C |
sources/an-sbaa588.txt:383 |
0x1880 |
24.5 °C |
sources/an-sbaa588.txt:899-902 |
Example data 0x2090 = 32.5625
These exercise mixed integer/fractional data and negative fractional decoding. Cheap pure tests, no mock needed.
5. Conversion-rate delays entirely unpinned
conversion_period_us has no assertion, and the wait_for_temperature doctests use NoopDelay — deleting the delay call outright would not fail any test. This is a total function over 4 inputs (0.25 Hz, 1 Hz, 4 Hz, 16 Hz per §7.5.3.5, sources/datasheet.txt:930); enumerate it rather than sample it. Add recording-delay tests asserting config-read -> delay -> temperature-read ordering.
6. one_shot() has no unit test at all
Tracked in #60. Its only coverage is two doctests, both of which start from the wrong chip state.
7. Hysteresis snapping and float rounding are untested policy
The ±0.05 °C acceptance band and half-away-from-zero quantisation are driver policy, not datasheet tolerances — the sources specify discrete encodings only (§7.5.3.1 Table 9, sources/datasheet.txt:894). They are legal choices, but untested at exact rounding ties, at the adjacent representable floats either side of the rejection boundaries, and at all eight hysteresis band edges.
Part 2 — Verified correct. Do not "fix" these.
The audit checked each of the following against the sources and found no defect. They are recorded because each one looks wrong at a glance and is not.
Configuration byte order is correct. 0x1022 is the internal little-endian representation of wire bytes [0x22, 0x10], which match Table 8 (sources/datasheet.txt:884, :887) and the MSB-first rule (§7.3.4, sources/datasheet.txt:673). Changing the serialisation to "fix" the endianness would introduce a defect. Prefer explicit byte-array assertions over from_ne_bytes in layout tests so this stops looking suspicious.
Celsius genuinely closes the temperature domain. Private i16 constrained by its constructors to -2048..2047 sixteenths = exactly 4096 values, matching the 12-bit register. It is not a renamed float. It already deleted the range checks and InvalidInput handling from all four inherent limit setters. A second limit newtype would add machinery and delete nothing.
Table 7 lists +128 and +127.9375 against the same code 7FF (sources/datasheet.txt:848, :849). SBAA588 Table 2-3 gives the true asymmetric range (sources/an-sbaa588.txt:883-884) and the code follows it. Do not widen Celsius to admit +128 — it would break the one-value/one-canonical-code invariant.
Config has exactly 64 legal combinations (2 x 2 x 4 x 4), matching the documented fields. No hidden invalid region; do not split it per-mode or reject nonzero hysteresis in interrupt mode (the sources do not prohibit it).
THIGH >= TLOW is not enforced, and no source prohibits it. §7.5.4 Eq. 1 (sources/datasheet.txt:983) gives the release band as (TLOW + HYS) and (THIGH - HYS), so ordering alone would be insufficient anyway. Document the relationship; do not promote it into a hardware prohibition or a breaking API change.
Partial two-byte config writes leave a legal, mixed configuration. §6.6 (sources/datasheet.txt:267) explicitly permits MS-byte-only updates. New mode/TM/CR with old POL/HYS is valid, not reserved. Document partial application on write failure; do not add an "invalid configuration" error variant.
Error<E, P> is wider than some methods need — AlertTmp108 temperature reads carry a Pin(P) variant they cannot produce. Intentional shared-error union; splitting it per-method is a breaking migration for near-zero gain. Callers wanting bus-only errors should route through sensor_mut().
No over-encoding found. A0 is a 4-value enum matching Table 2, addr() -> u8 is correct at the HAL boundary, and the resource accessors express ownership rather than chip encodings. Nothing to strip.
Part 3 — One genuine doc overpromise
src/lib.rs:1508-1510 claims continuous():
unconditionally returns the chip to [Mode::Shutdown] before returning, regardless of whether the closure succeeded or failed
Drop/cancellation, a panic inside the closure, and an entry-phase error all bypass cleanup; a failing cleanup write is swallowed in favour of the closure error, so the caller cannot distinguish confirmed cleanup from a chip still converting. Change "unconditionally returns" to "attempts to return", and document the panic and cancellation behaviour. Even a successful shutdown request lets the current conversion finish (§7.4.1, sources/datasheet.txt:741).
Audit provenance
Raised by a datasheet-compliance audit of 5e7b8d2 (byte-identical to published crates.io v0.6.0).
| id |
document |
revision |
sha256 |
datasheet |
TI TMP108 Datasheet |
SBOS663A |
ec086250fc4331e7fc923be62173062bbf0fccedad6894c2741b73cd1c084556 |
an-sbaa588 |
TI Application Note |
SBAA588A |
030ca48a844df836f6268e2960b2ea1fdf073eba07ee693b404303efa7848e50 |
an-sboa431 |
TI Application Note |
SBOA431 |
97d7fcc22ab7584b80b6464608d41d5ff9d7568a25e4a4398b4a5b12fd52e198 |
ta-sszt228 |
TI Technical Article |
SSZT228 |
3a10a4f529a184041deaf9aa0721e9e1baf6fff9379122a689788c61fe8f01c9 |
Line anchors such as sources/datasheet.txt:927 refer to pdftotext -layout extractions of the documents above. Every quote in this issue was re-grepped against its cited line. TI permalinks are unversioned, so re-derive line numbers if you re-fetch; the sha256 is what pins the bytes.
Umbrella issue for documented facts that the test suite does not pin, plus a record of the facts the audit verified as correct so they are not "fixed" by mistake.
Part 1 — Test gaps
1. Mode encoding
11is actively mis-pinnedTracked in #62.
src/lib.rs:2564asserts11must fail. The test has to be replaced, not merely extended.2. Limit register reset values unpinned
Tracked in #63. Assert the register-operation reset values separately from
Fieldset::ZERO— asserting againstZEROis precisely what let the wrong defaults through.3. The decode tests have no independent oracle
Mutually-consistent wrong permutations pass both. Add a test that computes each code's value independently: for every 12-bit code
n in 0..4096, expectn < 2048 ? n : n - 4096sixteenths, and bytes[n >> 4, (n & 15) << 4]. Include ±0.0625 °C and ±0.125 °C explicitly so individual fractional-bit weights are visible.4. Three application-note worked values have no assertions
0x2090sources/an-sbaa588.txt:2740xFAE0sources/an-sbaa588.txt:3830x1880sources/an-sbaa588.txt:899-902These exercise mixed integer/fractional data and negative fractional decoding. Cheap pure tests, no mock needed.
5. Conversion-rate delays entirely unpinned
conversion_period_ushas no assertion, and thewait_for_temperaturedoctests useNoopDelay— deleting the delay call outright would not fail any test. This is a total function over 4 inputs (0.25 Hz, 1 Hz, 4 Hz, 16 Hz per §7.5.3.5,sources/datasheet.txt:930); enumerate it rather than sample it. Add recording-delay tests asserting config-read -> delay -> temperature-read ordering.6.
one_shot()has no unit test at allTracked in #60. Its only coverage is two doctests, both of which start from the wrong chip state.
7. Hysteresis snapping and float rounding are untested policy
The ±0.05 °C acceptance band and half-away-from-zero quantisation are driver policy, not datasheet tolerances — the sources specify discrete encodings only (§7.5.3.1 Table 9,
sources/datasheet.txt:894). They are legal choices, but untested at exact rounding ties, at the adjacent representable floats either side of the rejection boundaries, and at all eight hysteresis band edges.Part 2 — Verified correct. Do not "fix" these.
The audit checked each of the following against the sources and found no defect. They are recorded because each one looks wrong at a glance and is not.
Configuration byte order is correct.
0x1022is the internal little-endian representation of wire bytes[0x22, 0x10], which match Table 8 (sources/datasheet.txt:884,:887) and the MSB-first rule (§7.3.4,sources/datasheet.txt:673). Changing the serialisation to "fix" the endianness would introduce a defect. Prefer explicit byte-array assertions overfrom_ne_bytesin layout tests so this stops looking suspicious.Celsiusgenuinely closes the temperature domain. Privatei16constrained by its constructors to -2048..2047 sixteenths = exactly 4096 values, matching the 12-bit register. It is not a renamed float. It already deleted the range checks andInvalidInputhandling from all four inherent limit setters. A second limit newtype would add machinery and delete nothing.Table 7 lists +128 and +127.9375 against the same code
7FF(sources/datasheet.txt:848,:849). SBAA588 Table 2-3 gives the true asymmetric range (sources/an-sbaa588.txt:883-884) and the code follows it. Do not widenCelsiusto admit +128 — it would break the one-value/one-canonical-code invariant.Confighas exactly 64 legal combinations (2 x 2 x 4 x 4), matching the documented fields. No hidden invalid region; do not split it per-mode or reject nonzero hysteresis in interrupt mode (the sources do not prohibit it).THIGH >= TLOW is not enforced, and no source prohibits it. §7.5.4 Eq. 1 (
sources/datasheet.txt:983) gives the release band as(TLOW + HYS)and(THIGH - HYS), so ordering alone would be insufficient anyway. Document the relationship; do not promote it into a hardware prohibition or a breaking API change.Partial two-byte config writes leave a legal, mixed configuration. §6.6 (
sources/datasheet.txt:267) explicitly permits MS-byte-only updates. New mode/TM/CR with old POL/HYS is valid, not reserved. Document partial application on write failure; do not add an "invalid configuration" error variant.Error<E, P>is wider than some methods need —AlertTmp108temperature reads carry aPin(P)variant they cannot produce. Intentional shared-error union; splitting it per-method is a breaking migration for near-zero gain. Callers wanting bus-only errors should route throughsensor_mut().No over-encoding found.
A0is a 4-value enum matching Table 2,addr() -> u8is correct at the HAL boundary, and the resource accessors express ownership rather than chip encodings. Nothing to strip.Part 3 — One genuine doc overpromise
src/lib.rs:1508-1510claimscontinuous():Drop/cancellation, a panic inside the closure, and an entry-phase error all bypass cleanup; a failing cleanup write is swallowed in favour of the closure error, so the caller cannot distinguish confirmed cleanup from a chip still converting. Change "unconditionally returns" to "attempts to return", and document the panic and cancellation behaviour. Even a successful shutdown request lets the current conversion finish (§7.4.1,
sources/datasheet.txt:741).Audit provenance
Raised by a datasheet-compliance audit of
5e7b8d2(byte-identical to published crates.io v0.6.0).datasheetec086250fc4331e7fc923be62173062bbf0fccedad6894c2741b73cd1c084556an-sbaa588030ca48a844df836f6268e2960b2ea1fdf073eba07ee693b404303efa7848e50an-sboa43197d7fcc22ab7584b80b6464608d41d5ff9d7568a25e4a4398b4a5b12fd52e198ta-sszt2283a10a4f529a184041deaf9aa0721e9e1baf6fff9379122a689788c61fe8f01c9Line anchors such as
sources/datasheet.txt:927refer topdftotext -layoutextractions of the documents above. Every quote in this issue was re-grepped against its cited line. TI permalinks are unversioned, so re-derive line numbers if you re-fetch; the sha256 is what pins the bytes.