From b1ee1febec32868915e4272bebf95a12b259ebdb Mon Sep 17 00:00:00 2001 From: SoundMatt <47545907+SoundMatt@users.noreply.github.com> Date: Thu, 20 Aug 2026 12:00:59 -0700 Subject: [PATCH] docs: fix TC18.txt citation drift in gpio.rs/i2c.rs/lifecycle.rs/lin.rs/pwm.rs/timestamp.rs doc comments (issue #164 batch 2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Batch 2 of issue #164: re-verifies every TC18.txt line-number and table/figure-number citation in these six files' doc comments (///, //!, and adjacent // test comments) against the current canonical TC18.txt, individually — not a uniform line-shift. - src/gpio.rs: 6 line citations updated (~408-409-line drift, confirmed). Two genuine renumbers found and fixed: Figure 24 (now SPI's own request-format figure) -> Figure 25 for GPIO's request figure; Table 30 (now GPIO's own AND/pin-reset row lives at a different location) -> Table 33 for the per-endpoint evt-field table, fixed everywhere it's mentioned in this file (doc comments and adjacent test-body comments), including two more Figure 24 mentions the initial pass missed. - src/i2c.rs: 3 line citations updated (~411-line drift, confirmed). Table 46 -> Table 49 (i2c functional configuration table renumbered, not just shifted — Table 46 is now pwmo functional configuration). Also fixed a mislabeled worked-example figure reference: "(Figure 29)" for I2C's own 10-bit-address/5-byte worked example -> Figure 30 (Figure 29 is PWM_IN's own request figure, not I2C's). - src/lifecycle.rs: 5 citation instances (3 duplicate quotes of 2 distinct line anchors, plus one list-range) updated, ~375-line drift confirmed for all. None were genuinely missing content — the issue's "3 not-found" flags were the audit script failing to match spliced/elided quotes ("After a power cycle ... configured in", "... may incorporate default settings ... advanced state"), not real content loss; hand-verified against current TC18.txt §12.3/§12.3.1.1 line by line. - src/lin.rs: line citations updated (~416-line drift, confirmed). Table 52 -> Table 55 (LIN's functional-config table renumbered; Table 52 is now uart trigger signals). Figure 38 -> Figure 39 in two more places (Figure 38 is now ADC's response-frame figure, not LIN's request-format figure — LIN's own figure, already correctly cited elsewhere in this same file with no line number, is Figure 39). The correct, already-existing LIN-specific Table 33 Row-2 material from a prior PR is untouched. - src/pwm.rs: line citations updated (~408-411-line drift, confirmed). Table 45 -> Table 48 (Table 45 is now pwmo trigger outputs, not the PWM_IN functional-config table pwmi_err_on_max_period/ pwmi_max_period live in). - src/timestamp.rs: all 3 citations updated (~376-377-line drift, confirmed) for the avtp_timestamp/message_timestamp rollover-period formulas in TC18 §11.4.1. Not resolved / nothing left unresolved: every citation in these six files was individually re-locatable in current TC18.txt with the quoted text matching verbatim (module apostrophe-encoding aside); no genuine content removal or rewording was found in this batch's scope (unlike e2e.rs's RC4->RC5 rewording, out of scope here). Doc-comment-only change: cargo build/cargo test --lib unaffected (1168 tests pass, unchanged count from batch 1), cargo fmt --check clean, no public API surface change. Signed-off-by: SoundMatt <47545907+SoundMatt@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 Signed-off-by: SoundMatt <47545907+SoundMatt@users.noreply.github.com> --- src/gpio.rs | 32 ++++++++++++++++---------------- src/i2c.rs | 20 ++++++++++---------- src/lifecycle.rs | 10 +++++----- src/lin.rs | 22 +++++++++++----------- src/pwm.rs | 14 +++++++------- src/timestamp.rs | 6 +++--- 6 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/gpio.rs b/src/gpio.rs index ba16ade..dab9b71 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -195,7 +195,7 @@ impl GpioBitmask { /// /// Big-endian places IO0 in the last byte's least-significant bit and /// IO31 in the first byte's most-significant bit, so IO `n` is bit `n` - /// of the `byte_msg_payload` exactly as TC18 §13.7.4.1's Figure 24 lays + /// of the `byte_msg_payload` exactly as TC18 §13.7.4.1's Figure 25 lays /// the payload out (msb on the left, IO23..IO0 in the low positions for /// that figure's own 24-pin example endpoint). //fusa:req REQ-GPIO-001 @@ -245,12 +245,12 @@ pub enum GpioWriteSemantics { /// Bitwise AND the operand into the current value. /// /// TC18 §13.7.4.1's prose words the value-changing operations as - /// "(NAND, OR, XOR)", but TC18 §13.5's Table 30 — the normative + /// "(NAND, OR, XOR)", but TC18 §13.5's Table 33 — the normative /// per-endpoint `evt[2:0]` table — defines code `010b` as the /// *byte_msg_payload bitwise AND current interface status*, with the /// worked example "with a byte_msg_payload of 0xFFFF FFFE the first IO /// pin will be reset, while other IO pins remain unchanged". This crate - /// follows Table 30's AND; §13.7.4.1's "NAND" wording contradicts it and + /// follows Table 33's AND; §13.7.4.1's "NAND" wording contradicts it and /// is recorded as a TC18-internal inconsistency, not implemented as /// written. //fusa:req REQ-GPIO-021 @@ -852,7 +852,7 @@ mod tests { // ── TC18 §13.7.4 spec-literal conformance checks ──────────────────────── - /// TC18 §13.7.4.1 (TC18.txt line 4381): "Each GPIO endpoint can handle + /// TC18 §13.7.4.1 (TC18.txt line 4789): "Each GPIO endpoint can handle /// up to 32 IOs." The 4-byte bitmask is exactly 32 bit positions wide, /// so IO0..IO31 are all representable and there is no IO32. #[test] @@ -876,7 +876,7 @@ mod tests { ); } - /// TC18 §13.7.4.1 / Figure 24 (TC18.txt lines 4389-4398): "Each GPIO pin + /// TC18 §13.7.4.1 / Figure 25 (TC18.txt lines 4797-4808): "Each GPIO pin /// can be assigned to a bit position of the byte_msg_payload", laid out /// msb-first with IO23..IO0 in the low bit positions for that figure's /// own 24-pin example endpoint. IO `n` is therefore bit `n`, and the @@ -890,16 +890,16 @@ mod tests { assert_eq!(GpioBitmask(1u32 << 7).encode(), [0x00, 0x00, 0x00, 0x80]); // IO8 opens the next byte up. assert_eq!(GpioBitmask(1u32 << 8).encode(), [0x00, 0x00, 0x01, 0x00]); - // IO23 — the highest IO drawn in Figure 24's 24-pin example. + // IO23 — the highest IO drawn in Figure 25's 24-pin example. assert_eq!(GpioBitmask(1u32 << 23).encode(), [0x00, 0x80, 0x00, 0x00]); - // Figure 24's whole 24-pin example EP: IO0..IO23 asserted, the + // Figure 25's whole 24-pin example EP: IO0..IO23 asserted, the // "don't care" positions above IO23 clear. assert_eq!(GpioBitmask(0x00FF_FFFF).encode(), [0x00, 0xFF, 0xFF, 0xFF]); // IO31 tops out the 32-IO range. assert_eq!(GpioBitmask(1u32 << 31).encode(), [0x80, 0x00, 0x00, 0x00]); } - /// TC18 §13.7.4.3 (TC18.txt line 4480): "A request with data + /// TC18 §13.7.4.3 (TC18.txt line 4889): "A request with data /// '0x0000 0000' and evt[2:0] = 0x001 (OR) results in 'no change'." #[test] //fusa:test REQ-GPIO-019 @@ -923,16 +923,16 @@ mod tests { } } - /// TC18 §13.7.4.1 (TC18.txt lines 4403-4404): "Generating a pulse for a + /// TC18 §13.7.4.1 (TC18.txt lines 4811-4812): "Generating a pulse for a /// defined time is NOT a function of the GPIO endpoint. This either /// needs to be managed by the Client ... by a compound or a trigger /// operation." The endpoint's whole write surface is therefore exactly - /// TC18 §13.5 Table 30's eight `evt[2:0]` value-level codes, with no + /// TC18 §13.5 Table 33's eight `evt[2:0]` value-level codes, with no /// ninth, duration-carrying operation. #[test] //fusa:test REQ-GPIO-020 fn gpio_write_surface_is_tc18_eight_codes_with_no_pulse_operation() { - // TC18 §13.5 Table 30's GPIO/PWM_OUT rows, code by code. + // TC18 §13.5 Table 33's GPIO/PWM_OUT rows, code by code. let table_30: [(u8, GpioWriteSemantics); 8] = [ (0b000, GpioWriteSemantics::Replace), (0b001, GpioWriteSemantics::Or), @@ -957,13 +957,13 @@ mod tests { } } - /// TC18 §13.7.4.1 (TC18.txt line 4402) words the value-changing - /// operations as "(NAND, OR, XOR)", but TC18 §13.5 Table 30 (TC18.txt - /// lines 3699-3702) defines `evt[2:0] = 010b` as the byte_msg_payload + /// TC18 §13.7.4.1 (TC18.txt line 4810) words the value-changing + /// operations as "(NAND, OR, XOR)", but TC18 §13.5 Table 33 (TC18.txt + /// lines 4098-4101) defines `evt[2:0] = 010b` as the byte_msg_payload /// *bitwise AND* the current interface status, with the worked example /// "with a byte_msg_payload of 0xFFFF FFFE the first IO pin will be /// reset, while other IO pins remain unchanged". This crate follows - /// Table 30's AND. + /// Table 33's AND. #[test] //fusa:test REQ-GPIO-021 fn gpio_evt_010b_is_bitwise_and_per_tc18_table_30_worked_example() { @@ -971,7 +971,7 @@ mod tests { GpioWriteSemantics::from_sub_opcode(0b010), Ok(GpioWriteSemantics::And) ); - // Table 30's own worked example: every IO currently set, payload + // Table 33's own worked example: every IO currently set, payload // 0xFFFF_FFFE -> IO0 reset, IO1..IO31 unchanged. let current = GpioBitmask(0xFFFF_FFFF); let payload = GpioBitmask(0xFFFF_FFFE); diff --git a/src/i2c.rs b/src/i2c.rs index e0f40d6..680c644 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -446,12 +446,12 @@ mod tests { assert!(!mode.is_ambiguous_high_speed_row()); } - // ── TC18 Table 46: i2c_mode preset wire values ────────────────────────── + // ── TC18 Table 49: i2c_mode preset wire values ────────────────────────── #[test] //fusa:test REQ-I2C-009 fn i2c_mode_wire_values_match_tc18_table_46_unambiguous_rows() { - // TC18 §13.7.7.2 Table 46 (TC18.txt lines 4815-4817), i2c_mode + // TC18 §13.7.7.2 Table 49 (TC18.txt lines 5226-5228), i2c_mode // (relative address 0x0007, 8 bit R/W): // 0: Standard Mode 100kbit/s // 1: Fast Mode 400kbit/s @@ -462,7 +462,7 @@ mod tests { assert_eq!(I2cSpeedMode::Standard.to_u8(), 0); assert_eq!(I2cSpeedMode::Fast.to_u8(), 1); assert_eq!(I2cSpeedMode::FastPlus.to_u8(), 2); - // None of these three rows is one of Table 46's duplicated + // None of these three rows is one of Table 49's duplicated // high-speed rows, so none may be reported as unresolved. for mode in [ I2cSpeedMode::Standard, @@ -476,14 +476,14 @@ mod tests { #[test] //fusa:test REQ-I2C-010 fn i2c_mode_value_three_is_not_resolved_to_a_single_high_speed_rate() { - // TC18 §13.7.7.2 Table 46 (TC18.txt lines 4818-4819) lists two + // TC18 §13.7.7.2 Table 49 (TC18.txt lines 5229-5230) lists two // adjacent High-speed rows that both carry the same i2c_mode wire // value 3: // 3: High-speed mode 1.7Mbit/s // 3: High-speed mode 3.4Mbit/s // Decoding value 3 must therefore be flagged as unresolved rather // than silently picking either bit rate. - let decoded = I2cSpeedMode::from_u8(3).expect("3 is an enumerated Table 46 i2c_mode value"); + let decoded = I2cSpeedMode::from_u8(3).expect("3 is an enumerated Table 49 i2c_mode value"); assert!(decoded.is_ambiguous_high_speed_row()); assert_eq!(decoded.to_u8(), 3); } @@ -493,11 +493,11 @@ mod tests { #[test] //fusa:test REQ-I2C-011 fn i2c_byte_transfer_is_transparent_to_seven_and_ten_bit_addressing() { - // TC18 §13.7.7.3 (TC18.txt line 4830): "The byte msg payload is the - // I2C payload including the address. The I2C endpoint does not know - // whether there is a 7- or 10-bit address, since the endpoint is just - // transparent." The worked example there (Figure 29) is an I²C - // transfer with a 10-bit address and 5 bytes of data — 2 address + // TC18 §13.7.7.3 (TC18.txt lines 5241-5242): "The byte msg payload is + // the I2C payload including the address. The I2C endpoint does not + // know whether there is a 7- or 10-bit address, since the endpoint + // is just transparent." The worked example there (Figure 30) is an + // I²C transfer with a 10-bit address and 5 bytes of data — 2 address // bytes + 5 data bytes = a 7-byte byte_msg_payload. let ten_bit_addressed = vec![0xF2, 0x34, 0x11, 0x22, 0x33, 0x44, 0x55]; assert_eq!(ten_bit_addressed.len(), 7); diff --git a/src/lifecycle.rs b/src/lifecycle.rs index b865722..2c24f57 100644 --- a/src/lifecycle.rs +++ b/src/lifecycle.rs @@ -292,7 +292,7 @@ impl RcServerState { /// spec fact) given `HW_UNCONFIGURED`'s name and `0x00` encoding both /// suggest a power-on/reset default. /// - /// TC18 §12.3 (TC18.txt line 2059) settles the surrounding rule this + /// TC18 §12.3 (TC18.txt line 2434) settles the surrounding rule this /// default serves: "After a power cycle or restart ... the RC Server /// shall start in the life-cycle state it is actually configured in", /// where a device with no NVM "may incorporate default settings which @@ -529,7 +529,7 @@ pub fn check_register_writable( /// /// One of the excluded pairs is excluded by TC18 itself, not merely by /// this crate's reading of `ROADMAP.md`: TC18 §12.3.1.1 (TC18.txt line -/// 2168) states that, from `HW_UNCONFIGURED`, "a request to advance the +/// 2544) states that, from `HW_UNCONFIGURED`, "a request to advance the /// state directly to RCP_CONFIGURED will be rejected with an error /// response" — the two-hop route through `HW_CONFIGURED` is the only way /// up. @@ -665,7 +665,7 @@ mod tests { // ── TC18 §12.3: start state after a power cycle or restart ─────────── - /// TC18 §12.3 (TC18.txt line 2059): "After a power cycle or restart, + /// TC18 §12.3 (TC18.txt line 2434): "After a power cycle or restart, /// depending on the RC Server's implementation, the RC Server shall /// start in the life-cycle state it is actually configured in. /// Depending on the devices physical implementation it may have either @@ -676,7 +676,7 @@ mod tests { /// /// Both halves are asserted against literal values: the no-stored- /// configuration default is `HW_UNCONFIGURED`/`0x00`, and each of the - /// three state names TC18 §12.3 lists (TC18.txt lines 2065-2067) can be + /// three state names TC18 §12.3 lists (TC18.txt lines 2440-2442) can be /// restored by name as a configured start state. #[test] //fusa:test REQ-LIFE-015 @@ -702,7 +702,7 @@ mod tests { // ── TC18 §12.3.1.1: no direct advance to RCP_CONFIGURED ────────────── - /// TC18 §12.3.1.1 (TC18.txt line 2168): from `HW_UNCONFIGURED`, "per + /// TC18 §12.3.1.1 (TC18.txt lines 2543-2544): from `HW_UNCONFIGURED`, "per /// write request to the server functional configuration entry /// svr_lifecycle_state the life-cycle state can be advanced to /// HW_CONFIGURED. A request to advance the state directly to diff --git a/src/lin.rs b/src/lin.rs index c7b7907..ec4ee76 100644 --- a/src/lin.rs +++ b/src/lin.rs @@ -179,8 +179,8 @@ //! //! ## TC18 reconciliation note (§13.7.10) //! -//! TC18 §13.7.10.3 (TC18.txt line 5304) states only that "the Byte Msg -//! Payload is the payload to be used on the Lin bus", and Figure 38 shows +//! TC18 §13.7.10.3 (TC18.txt line 5720) states only that "the Byte Msg +//! Payload is the payload to be used on the Lin bus", and Figure 39 shows //! that payload as one undifferentiated "Lin payload" field followed by //! padding — it defines no PID sub-field, no checksum sub-field, and no //! per-frame length ceiling of its own. This module's split of the leading @@ -194,13 +194,13 @@ //! recorded as explicit not-implemented requirement entries rather than //! silently omitted: matching each received LIN message against the pending //! read request's `byte_msg_payload` under the conditions given by -//! `evt[2:0]` and replying when `op = 0` (TC18.txt lines 5276-5277); issuing +//! `evt[2:0]` and replying when `op = 0` (TC18.txt lines 5692-5693); issuing //! a trigger once a transmission has been finalized and the configured -//! trailing time has expired (line 5278); and the cyclic-transmission +//! trailing time has expired (line 5694); and the cyclic-transmission //! pattern built from a repeated trigger request on the endpoint's own -//! trigger (line 5279). All three are RC-Server run-time endpoint behaviors, -//! outside this module's codec-only scope. TC18 Table 52's own -//! functional-config register layout (§13.7.10.2, lines 5287-5298) is +//! trigger (line 5695). All three are RC-Server run-time endpoint behaviors, +//! outside this module's codec-only scope. TC18 Table 55's own +//! functional-config register layout (§13.7.10.2, lines 5697-5714) is //! likewise unimplemented — see [`LinFunctionalConfig`]. //! //! ## Relationship to [`crate::regmap`] @@ -288,7 +288,7 @@ impl LinFrameTransfer { /// Encode this transfer to its raw wire representation: the PID byte /// followed by `data`, unmodified and unframed. /// - /// This is the `byte_msg_payload` TC18 §13.7.10.3 (TC18.txt line 5304) + /// This is the `byte_msg_payload` TC18 §13.7.10.3 (TC18.txt line 5720) /// calls "the payload to be used on the Lin bus": the bytes are emitted /// verbatim, in supplied order, with nothing inserted, removed, or /// reordered — see this module's doc comment "TC18 reconciliation note". @@ -479,9 +479,9 @@ mod tests { #[test] //fusa:test REQ-LIN-007 fn lin_byte_msg_payload_is_carried_verbatim_onto_the_bus() { - // TC18 §13.7.10.3 (TC18.txt line 5304): "The Byte Msg Payload is the - // payload to be used on the Lin bus." Figure 38's own on-wire example - // (line 5305) carries three payload bytes with no PID/checksum + // TC18 §13.7.10.3 (TC18.txt line 5720): "The Byte Msg Payload is the + // payload to be used on the Lin bus." Figure 39's own on-wire example + // (line 5721) carries three payload bytes with no PID/checksum // sub-structure and no length/format byte of its own, so the encoded // form must be byte-for-byte identical to the supplied payload. // diff --git a/src/pwm.rs b/src/pwm.rs index 5141359..0027252 100644 --- a/src/pwm.rs +++ b/src/pwm.rs @@ -634,16 +634,16 @@ mod tests { #[test] //fusa:test REQ-PWMI-003 fn resolve_pwm_in_read_invalidates_measurement_once_max_period_is_exceeded() { - // TC18 §13.7.6.2 Table 45, pwmi_err_on_max_period = 0b (TC18.txt - // line 4721): "if MAX PERIOD is exceeded, invalidate measurement and - // wait for new active phase of signal". pwmi_max_period (Table 45, - // relative address 0x000A, TC18.txt line 4735) is a 16-bit register, - // so 0xFFFF is the largest MAX PERIOD a conforming RC Server can be - // configured with. + // TC18 §13.7.6.2 Table 48, pwmi_err_on_max_period = 0b (TC18.txt + // lines 5129-5131): "if MAX PERIOD is exceeded, invalidate + // measurement and wait for new active phase of signal". + // pwmi_max_period (Table 48, relative address 0x000A, TC18.txt line + // 5146) is a 16-bit register, so 0xFFFF is the largest MAX PERIOD a + // conforming RC Server can be configured with. let config = PwmInFunctionalConfig { no_signal_timeout: 0xFFFF, }; - // TC18 §13.7.6.3 (TC18.txt line 4758): both measured values are + // TC18 §13.7.6.3 (TC18.txt line 5169): both measured values are // 16-bit, so a valid measurement fits 0x0000..=0xFFFF. let measured = PwmDurationPair { period: 0x8000, diff --git a/src/timestamp.rs b/src/timestamp.rs index b0a1319..d4d67ec 100644 --- a/src/timestamp.rs +++ b/src/timestamp.rs @@ -126,7 +126,7 @@ impl AvtpTimestamp { /// This type's rollover period, in raw ticks: the field's full 32-bit /// width. /// - /// TC18 §11.4.1 (TC18.txt lines 1952-1953) confirms both the tick unit + /// TC18 §11.4.1 (TC18.txt lines 2328-2329) confirms both the tick unit /// and the period: "avtp_timestamp = (AS_sec × 10^9 + AS_ns) mod 2^32 /// where AS_sec is the gPTP seconds field and AS_ns is the gPTP /// nanoseconds field (thus rolls over every 4 seconds)" — i.e. the @@ -221,7 +221,7 @@ impl MessageTimestamp { /// This type's rollover period, in raw ticks: the field's full 64-bit /// width — 2^32 times longer than [`AvtpTimestamp::ROLLOVER_PERIOD`]. /// - /// TC18 §11.4.1 (TC18.txt lines 1954-1955) confirms both the tick unit + /// TC18 §11.4.1 (TC18.txt lines 2331-2332) confirms both the tick unit /// and the period: "message_timestamp = (AS_sec × 10^9 + AS_ns) mod /// 2^64 where AS_sec is the gPTP seconds field and AS_ns is the gPTP /// nanoseconds field (thus rolls over every 584,9 years)" — i.e. the @@ -609,7 +609,7 @@ mod tests { #[test] //fusa:test REQ-TS-007 fn rollover_periods_match_tc18_11_4_1_nanosecond_derivation() { - // TC18 §11.4.1 (TC18.txt lines 1952-1955) states both moduli and + // TC18 §11.4.1 (TC18.txt lines 2328-2332) states both moduli and // both resulting real-world periods, with the tick unit fixed at // nanoseconds by the `AS_sec × 10^9 + AS_ns` construction: //