Files
wiredsensor/bridge/build.rs
T
Oliver Walter ddfda14085 Add USB-RS485 bridge and PC-side test suite
Makes end-to-end verification of the bus possible with a spare RP2040 and
no dedicated RS485 dongle.

bridge/ turns a second Pico into a transparent USB-to-RS485 bridge. It is
deliberately protocol-agnostic: bytes from USB go out on the pair, bytes
from the pair go back up USB, and it knows nothing about frames,
addresses or CRCs. A protocol-aware bridge could have a bug that happens
to agree with the node's own, which would defeat the point of using it as
a test instrument. It also needs no register-level code — it never has to
delimit a frame, and the one thing it does need, knowing that the final
stop bit has cleared the shifter before releasing DE, rp2040-hal exposes
as uart_is_busy().

tools/wiredsensor.py is an independent implementation of the wire format,
written from the specification in README.md rather than sharing code with
wiredsensor-core. Shared code would let a framing or CRC bug cancel out
and every test pass regardless. Cross-checked: it reproduces the
CRC-16/MODBUS catalogue vector and builds byte-identical frames to the
Rust side for all five documented examples.

Its `test` subcommand covers what host tests structurally cannot, all of
it timing-dependent: that malformed and mis-addressed frames leave the
node silent rather than colliding with whoever was actually addressed,
that the driver-enable turnaround leaves replies intact, and that no
state leaks between back-to-back frames.

Uses one wiring diagram for both boards, since the bridge mirrors the
node's GPIO0/1/2 assignment. Frames must fit one 64-byte USB packet, as
each host write becomes exactly one DE-bracketed transmission; every real
command is at most 21 bytes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 20:31:30 +02:00

19 lines
853 B
Rust

use std::{env, fs, path::PathBuf};
fn main() {
// Copy memory.x somewhere the linker will find it. Relying on the linker's
// working directory does not work in a workspace, where cargo runs rustc
// from the workspace root rather than this package's directory.
let out = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR"));
fs::copy("memory.x", out.join("memory.x")).expect("copy memory.x into OUT_DIR");
println!("cargo:rustc-link-search={}", out.display());
// --nmagic disables page alignment of sections; without it the vector table
// is pushed away from the start of flash and the boot ROM cannot find it.
println!("cargo:rustc-link-arg-bins=--nmagic");
println!("cargo:rustc-link-arg-bins=-Tlink.x");
println!("cargo:rerun-if-changed=memory.x");
println!("cargo:rerun-if-changed=build.rs");
}