1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright (c) 2026 Rigless Labs.
// SPDX-License-Identifier: MIT OR Apache-2.0
//! A machine: the board, which **has** its MCUs and the parts wired to them.
//!
//! A board module declares a struct whose fields are what's on the board: `mcu`, the crystals on
//! its oscillator pins, the rail its regulator sees. It implements [`Board`] for that struct.
//! Reaching any of it is a field path: `board.mcu.clocks`, `board.crystal`. Nothing is looked up by
//! name, because the board holds the things themselves. The one thing it doesn't hold is a chip on
//! an interface's wires, which it asks the interface for as the type it hung there.
//!
//! **A board puts things together. It doesn't choose what a part has.** Which of a part's own
//! peripherals are modelled is the part's business, decided once in the part's own module. What a
//! board adds is crystals, a rail, and the integrated circuits on its buses. A board that fits no
//! crystal is a board with no crystal, not a part missing a clock tree.
//!
//! [`Board::targets`] is where the board hands itself to the runtime: one [`Target`] per MCU, each
//! borrowing that MCU as a [`Mcu`]. The session then steps its target through [`Board::mcu`], which
//! it reaches on every access. The board keeps ownership throughout, so every model on it stays a
//! field path, and a test reaches one through
//! [`Session::board_mut`](crate::session::Session::board_mut) while a session holds the board.
//!
//! The board's other edge is the world's, [`crate::edge`]. A board that drives or senses something
//! implements [`Edge`](crate::edge::Edge) with its own outputs and signals types: it reads what the
//! firmware drives off its pins and hands each chip its share of the signals, turned the way the chip is
//! mounted. Both are the board's because both are wiring: which pin is which output, and which way each
//! package sits, are lines on the schematic. [`Board::edge`] reaches that edge as bytes, for whatever
//! steps a plant between rounds or prints the outputs. A board with no edge leaves it at its default.
//!
//! A board may also have wires a host sits on: a serial line a ground station or a person talks to.
//! [`Board::hosts`] names them and the port each listens on, and [`Board::attach_host`] hangs
//! whatever the caller puts there, a socket from `rigless run` or a test's stand-in (ADR-0027).
use crateuart;
use crateCoupled;
use crate;
use crateMcu;
use crateError;
/// A board's constructor: the board assembled, or the error in its own description.
pub type Constructor = fn ;
/// Every machine this build carries, by the name `rigless run --machine` matches, with its constructor.
/// A quartz crystal on a board, as the oscillator it drives sees it: a frequency, or nothing fitted.
;
/// A wire of a board a host sits on: the name the board's description gives it, and the port `rigless
/// run` listens on for it.
/// The regulated rail a board runs its MCU from, in millivolts.
;
/// What a session drives: a board, and the MCUs on it.
///
/// A board with two MCUs is two targets, and a session runs one of them, picked by its index in
/// [`Board::targets`]. That order is the board's to choose and is the same on every run.
/// One MCU of a board as the runtime sees it: the MCU itself, how its emulator is started, and how its
/// interrupts route.
///
/// It borrows rather than owns, because the board owns. The runtime asks for the targets when a
/// session opens and when the emulator starts, and keeps none of them.