Define the line rate once, in wiredsensor-core
BAUD_RATE was declared separately in firmware/src/board.rs and bridge/src/main.rs with a comment asking that they be kept in agreement by hand. A baud mismatch between two ends of an RS485 segment is silent and presents as random CRC failures, which is a poor thing to debug and a poor thing to leave to a comment. It now lives in wiredsensor_core::timing alongside the arithmetic that derives from it, because the line rate is a property of the segment rather than of any one board. board.rs re-exports it, and the bridge takes a dependency on core purely to read it — it still knows nothing about the protocol itself. INTER_FRAME_GAP_US and CHAR_TIME_US move with it and are now derived at the definition site, with a test asserting they cannot go stale if the rate changes. Also fills two documentation gaps: the bridge and PC test suite were committed without any README coverage, and the account of the RTIM pitfall still described the incomplete understanding held before the hardware test found the real mechanism. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+30
-4
@@ -1,12 +1,29 @@
|
||||
//! Wire timing derived from the line rate.
|
||||
//! The line rate, and the wire timing derived from it.
|
||||
//!
|
||||
//! Kept here rather than in the firmware so the arithmetic — which decides
|
||||
//! whether frames are delimited correctly and whether the transceiver is
|
||||
//! released at the right moment — is covered by host tests.
|
||||
//! Kept here rather than in the firmware for two reasons. The arithmetic —
|
||||
//! which decides whether frames are delimited correctly and whether the
|
||||
//! transceiver is released at the right moment — is covered by host tests. And
|
||||
//! [`BAUD_RATE`] is a property of the *segment*, not of any one board: the node
|
||||
//! and every master on the bus must agree on it, so it is defined once here
|
||||
//! rather than copied into each firmware and kept in sync by hand.
|
||||
|
||||
/// Line rate for the whole segment.
|
||||
///
|
||||
/// 19200 8N1 is the Modbus default and a safe starting point for long runs.
|
||||
/// Changing it here changes it for every device built from this workspace,
|
||||
/// which is the point — a mismatch between two ends is silent and looks like
|
||||
/// random CRC failures.
|
||||
pub const BAUD_RATE: u32 = 19_200;
|
||||
|
||||
/// Bits on the wire per character: 1 start + 8 data + 1 stop, i.e. 8N1.
|
||||
pub const BITS_PER_CHAR: u32 = 10;
|
||||
|
||||
/// Inter-frame idle gap at [`BAUD_RATE`], in microseconds.
|
||||
pub const INTER_FRAME_GAP_US: u32 = inter_frame_gap_us(BAUD_RATE);
|
||||
|
||||
/// Time to clock out one character at [`BAUD_RATE`], in microseconds.
|
||||
pub const CHAR_TIME_US: u32 = char_time_us(BAUD_RATE);
|
||||
|
||||
/// Idle time that delimits one frame from the next, in microseconds.
|
||||
///
|
||||
/// Modbus specifies 3.5 character times, but pins the value at a fixed 1750 µs
|
||||
@@ -79,4 +96,13 @@ mod tests {
|
||||
assert_eq!(tx_time_us(1, 19_200), char_time_us(19_200));
|
||||
assert_eq!(tx_time_us(21, 19_200), 21 * 520);
|
||||
}
|
||||
|
||||
/// The derived constants must track whatever [`BAUD_RATE`] is set to, so
|
||||
/// changing the line rate cannot leave a stale gap or character time behind.
|
||||
#[test]
|
||||
fn derived_constants_follow_the_configured_rate() {
|
||||
assert_eq!(INTER_FRAME_GAP_US, inter_frame_gap_us(BAUD_RATE));
|
||||
assert_eq!(CHAR_TIME_US, char_time_us(BAUD_RATE));
|
||||
assert!(INTER_FRAME_GAP_US > CHAR_TIME_US);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user