aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--electrical-specifications.typ87
-rw-r--r--introduction.typ27
-rw-r--r--mechanical-specifications.typ622
-rw-r--r--pictures/cassette-external-dimensions.svg628
-rw-r--r--pictures/db-25-backplane-connector.svg1053
-rw-r--r--pictures/db-25-connector-cutout.svg611
-rw-r--r--pictures/front-panel-geometry.svg648
-rw-r--r--pictures/grid.svg1177
-rw-r--r--pictures/l-channel.svg980
-rw-r--r--pictures/u-channel.svg401
-rw-r--r--pictures/ventilation.svg1255
-rw-r--r--preamble.typ (renamed from main.typ)42
12 files changed, 7465 insertions, 66 deletions
diff --git a/electrical-specifications.typ b/electrical-specifications.typ
index 6d73b5e..8384518 100644
--- a/electrical-specifications.typ
+++ b/electrical-specifications.typ
@@ -62,7 +62,7 @@ must include an out-of-domain handling strategy, and document it:
#figure(
table(
columns: (auto, auto, auto),
- table.header([*Strategy*], [*Description*], [*Example use cases*]),
+ table.header([Strategy], [Description], [Example use cases]),
[Clamp], [Output held at boundary], [Logarithm],
[Hold], [Freeze last valid output], [Integrator],
[Fold], [Reflect at boundary], [Chaotic attractor],
@@ -98,7 +98,7 @@ jacks, the parallel input impedance must be considered:
#figure(
table(
columns: (auto, auto, auto),
- table.header([*Inputs stacked*], [*Parallel $Z_"in"$*], [*Loading error*]),
+ table.header([Inputs stacked], [Parallel $Z_"in"$], [Loading error]),
[1], [$qty(1, "mega ohm")$], [$qty(10, "ppm")$],
[4], [$qty(250, "kilo ohm")$], [$qty(40, "ppm")$],
[10], [$qty(100, "kilo ohm")$], [$qty(100, "ppm")$],
@@ -109,7 +109,9 @@ jacks, the parallel input impedance must be considered:
Module designers should document expected fan-out in module specifications. For
typical patches ($lt.eq 10$ connections per output), loading error remains a
-small fraction of the Industrial tier budget.
+small fraction of the Industrial tier budget. For Metrologic patches with a
+fan-out $gt 10$, the use of a dedicated buffer module should solve the loading
+error issue.
===== Error gates <error-gates>
@@ -126,7 +128,7 @@ internal errors must never be aggregated.
#figure(
table(
columns: (auto, auto),
- table.header([*Source*], [*Category*]),
+ table.header([Source], [Category]),
[Clipping], [Internal],
[PWAM Soft Saturation], [Internal],
[Domain Violation], [Out-of-Domain],
@@ -186,8 +188,8 @@ achievable with a standard HVAC.
===== Humidity <humidity>
Measurements are made within a relative humidity range of
-$qtyrange(30, 70, "percent", delimiter: "\"to\"") "RH"$, with an hourly variation of
-maximum $plus.minus qty(5, "percent") "RH"$.
+$qtyrange(30, 70, "percent", delimiter: "\"to\"") "RH"$, with an hourly
+variation of maximum $plus.minus qty(5, "percent") "RH"$.
High humidity can cause parasitic leakage paths (nanoamps matter at high-Z
nodes), dielectric changes affecting precision capacitors, and long-term
@@ -294,7 +296,7 @@ are met.
#figure(
table(
columns: (auto, auto, auto),
- table.header([*Parameter*], [*Range*], [*Variation*]),
+ table.header([Parameter], [Range], [Variation]),
[Temperature], [$plus qty(15, "dC") "to" plus qty(30, "dC")$], [$plus.minus qty(2, "celsius per hour")$],
[Relative humidity],
@@ -306,11 +308,17 @@ are met.
[RF immunity], [$qty(3, "volt per meter"), qtyrange(80, 1000, "MHz")$], [N/A],
[Magnetic field (DC)], [$lt qty(1, "ampere per meter")$], [N/A],
+
[Magnetic field (AC)], [$lt qty(0.3, "ampere per meter")$], [N/A],
+
[Vibration], [$lt qty(0.5, "g"), qtyrange(5, 500, "Hz")$], [N/A],
+
[Shock], [$lt qty(5, "g"), qty(11, "ms")$], [N/A],
+
[Air quality], [Indoor, filtered], [N/A],
+
[Lighting], [No direct sunlight], [N/A],
+
[Background radiation], [$lt qty(1, "micro sievert per hour")$], [N/A],
),
caption: [Summary of the precision measurements conditions],
@@ -321,10 +329,10 @@ Note that electrical supply requirements will be discussed in
=== Educational tier <educational-tier>
-This tier aims for a precision of $qty(0.1, "percent")$ ($qty(1000, "ppm")$), and a SNR of
-$qty(70, "dB")$. This tier is intended for lowering the barrier of entry by
-reducing the components costs and soldering difficulty. It is suitable for
-teaching on circuit topologies and general analog computer patching. At this
+This tier aims for a precision of $qty(0.1, "percent")$ ($qty(1000, "ppm")$),
+and a SNR of $qty(70, "dB")$. This tier is intended for lowering the barrier of
+entry by reducing the components costs and soldering difficulty. It is suitable
+for teaching on circuit topologies and general analog computer patching. At this
level of precision, results are valid within $plus.minus qty(10, "mV")$.
The maximum drift rate should be inferior or equal to $qty(60, "ppm per hour")$.
@@ -332,22 +340,24 @@ We recommend calibration verification before each session.
=== Industrial tier <industrial-tier>
-This tier aims for a precision of $qty(0.01, "percent")$ ($qty(100, "ppm")$), and a SNR of
-$qty(80, "dB")$. This tier is intended for research, serious experimentation,
-and applications requiring repeatable results. It is suitable for control
-systems modeling, audio-rate computation, and scientific data acquisition. At
-this level of precision, results are valid within $plus.minus qty(1, "mV")$.
+This tier aims for a precision of $qty(0.01, "percent")$ ($qty(100, "ppm")$),
+and a SNR of $qty(80, "dB")$. This tier is intended for research, serious
+experimentation, and applications requiring repeatable results. It is suitable
+for control systems modeling, audio-rate computation, and scientific data
+acquisition. At this level of precision, results are valid within
+$plus.minus qty(1, "mV")$.
The maximum drift rate should be inferior or equal to
$qty(0.6, "ppm per hour")$. We recommend daily calibration verification.
=== Metrologic tier <metrologic-tier>
-This tier aims for a precision of $qty(0.001, "percent")$ ($qty(10, "ppm")$), and a SNR of
-$qty(90, "dB")$. This tier is intended for precision measurement, long-duration
-computation, and applications requiring traceable accuracy. It is suitable for
-metrology, reference instrumentation, and extended continuous operation. At this
-level of precision, results are valid within $plus.minus qty(0.1, "mV")$.
+This tier aims for a precision of $qty(0.001, "percent")$ ($qty(10, "ppm")$),
+and a SNR of $qty(90, "dB")$. This tier is intended for precision measurement,
+long-duration computation, and applications requiring traceable accuracy. It is
+suitable for metrology, reference instrumentation, and extended continuous
+operation. At this level of precision, results are valid within
+$plus.minus qty(0.1, "mV")$.
The maximum drift rate should be inferior or equal to
$qty(0.014, "ppm per hour")$. We recommend daily calibration verification.
@@ -357,20 +367,21 @@ $qty(0.014, "ppm per hour")$. We recommend daily calibration verification.
#figure(
table(
columns: (auto, auto, auto, auto),
- table.header([*Parameter*], [*Educational*], [*Industrial*], [*Metrologic*]),
- [*Precision*],
+ table.header([Parameter], [Educational], [Industrial], [Metrologic]),
+ [Precision],
[$qty(0.1, "percent") (qty(1000, "ppm"))$],
[$qty(0.01, "percent") (qty(100, "ppm"))$],
[$qty(0.00, "percent")% (qty(10, "ppm"))$],
- [*SNR*], [$qty(70, "dB")$], [$qty(80, "dB")$], [$qty(90, "dB")$],
- [*Result validity*], [$plus.minus qty(0.1, "V")$], [$plus.minus qty(10, "mV")$], [$plus.minus qty(1, "mV")$],
+ [SNR], [$qty(70, "dB")$], [$qty(80, "dB")$], [$qty(90, "dB")$],
+
+ [Result validity], [$plus.minus qty(0.1, "V")$], [$plus.minus qty(10, "mV")$], [$plus.minus qty(1, "mV")$],
- [*Maximum drift rate*], [$qty(60, "ppm per hour")$], [$qty(0.6, "ppm per hour")$], [$qty(0.014, "ppm per hour")$],
+ [Maximum drift rate], [$qty(60, "ppm per hour")$], [$qty(0.6, "ppm per hour")$], [$qty(0.014, "ppm per hour")$],
- [*Drift-free computation*], [$approx qty(16, "h")$], [$approx qty(7, "day")$], [$approx qty(30, "day")$],
+ [Drift-free computation], [$approx qty(16, "h")$], [$approx qty(7, "day")$], [$approx qty(30, "day")$],
- [*Calibration verification*], [Before each session], [Daily], [Daily],
+ [Calibration verification], [Before each session], [Daily], [Daily],
),
caption: [Precision tiers summary],
) <table-precision-tiers-summary>
@@ -378,13 +389,13 @@ $qty(0.014, "ppm per hour")$. We recommend daily calibration verification.
==== Drift rate derivation <drift-rate-derivation>
The drift rates are calculated such that total accumulated drift over the
-drift-free computation period consumes approximately $qty(100, "percent")$ of the precision
-budget.
+drift-free computation period consumes approximately $qty(100, "percent")$ of
+the precision budget.
#figure(
table(
columns: (auto, auto, auto, auto),
- table.header([*Tier*], [*Precision*], [*Drift rate*], [*Time to drift $qty(100, "percent")$ of budget*]),
+ table.header([Tier], [Precision], [Drift rate], [Time to drift $qty(100, "percent")$ of budget]),
[*Educational*], [$qty(1000, "ppm")$], [$qty(60, "ppm per hour")$], [$approx qty(16, "h")$],
[*Industrial*], [$qty(100, "ppm")$], [$qty(0.6, "ppm per hour")$], [$approx qty(7, "day")$],
@@ -464,9 +475,10 @@ the system utilizes a global timebase.
<analog-supply-requirements>
At the module connector, the $plus.minus qty(15.00, "V")$ rails shall maintain
-an initial accuracy within $plus.minus qty(7.5, "mV")$ ($plus.minus qty(0.05, "percent")$) at
-$qty(25, "dC")$. Line regulation shall be better than $plus.minus qty(1.5, "mV")$
-($qty(0.01, "percent")$) for a $plus.minus qty(10, "percent")$ input voltage variation. Load regulation shall
+an initial accuracy within $plus.minus qty(7.5, "mV")$
+($plus.minus qty(0.05, "percent")$) at $qty(25, "dC")$. Line regulation shall be
+better than $plus.minus qty(1.5, "mV")$ ($qty(0.01, "percent")$) for a
+$plus.minus qty(10, "percent")$ input voltage variation. Load regulation shall
be better than $plus.minus qty(3.0, "mV")$ ($qty(0.02, "percent")$) over the
full load range ($qtyrange(10, 100, "percent", delimiter: "\"to\"")$). Output
voltage ripple and noise shall not exceed $qty(500, "uVpp")$ over a
@@ -563,9 +575,14 @@ the cassette to the power distribution board. D-sub connectors are ubiquitous,
sturdy and shielded.
#figure(
+ image("pictures/db-25-backplane-connector.svg"),
+ caption: [DB-25 backplane connector],
+) <figure-backplane-connector>
+
+#figure(
table(
columns: (auto, auto, auto, auto),
- table.header([*Pin*], [*Signal*], [*Pin*], [*Signal*]),
+ table.header([Pin], [Signal], [Pin], [Signal]),
[1], [$plus qty(15.00, "V")$], [14], [AGND],
[2], [$plus qty(15.00, "V")$], [15], [AGND],
[3], [$qty(-15.00, "V")$], [16], [AGND],
diff --git a/introduction.typ b/introduction.typ
index 8631e46..6948ee9 100644
--- a/introduction.typ
+++ b/introduction.typ
@@ -1,15 +1,4 @@
-#import "@preview/unify:0.8.1": add-unit, qty
-
-// All units for the specification should be specified here
-#add-unit("ppm", "ppm", "upright(\"ppm\")")
-#add-unit("ppb", "ppb", "upright(\"ppb\")")
-#add-unit("inch", "\"", "upright(\"\\\"\")", space: false)
-#add-unit("digital voltage", "VD", "upright(\"VD\")")
-#add-unit("volt peak-to-peak", "Vpp", "upright(V_\"pp\")")
-#add-unit("milli volt peak-to-peak", "mVpp", "upright(\"mV\"_\"pp\")")
-#add-unit("micro volt peak-to-peak", "uVpp", "upright(mu V_\"pp\")")
-#add-unit("dBc", "dBc", "upright(\"dBc\")") // decibels relative to the carrier
-#add-unit("rack unit", "U", "upright(U)", space: false)
+#import "@preview/unify:0.8.1": qty
= Introduction <introduction>
@@ -235,12 +224,14 @@ Metrologic aiming at $qty(10, "ppm")$.
=== Reader's guide <readers-guide>
We recommend a reader not familiar with the field to first read this
-specification sequentially. Sections 2 and 3 will develop the core
-specifications of the SAME ecosystem. Section 4 will specify the module design
-principles that allows it to achieve its precision goals. Section 5 will explain
-how to verify conformity of a SAME product with this specification. Section 6
-will present a reference implementation of the system. Finally, sections 7 and 8
-will show how and when to use a SAME Analog Computer.
+specification sequentially. #ref(<electrical-specifications>) and
+#ref(<mechanical-specifications>) will develop the core specifications of the
+SAME ecosystem. #ref(<module-design>) will specify the module design principles
+that allows it to achieve its precision goals. #ref(<compliance-verification>)
+will explain how to verify conformity of a SAME product with this specification.
+#ref(<reference-implementation>) will present a reference implementation of the
+system. Finally, #ref(<theory-of-operation>) and #ref(<applications>) will show
+how and when to use a SAME Analog Computer.
== Document conventions <document-conventions>
diff --git a/mechanical-specifications.typ b/mechanical-specifications.typ
index a96de33..40cc933 100644
--- a/mechanical-specifications.typ
+++ b/mechanical-specifications.typ
@@ -1,4 +1,4 @@
-#import "@preview/unify:0.8.1": qty, qtyrange
+#import "@preview/unify:0.8.1": numrange, qty, qtyrange
= Mechanical specifications <mechanical-specifications>
@@ -25,7 +25,7 @@ especially in terms of magnetic shielding.
#figure(
table(
columns: (auto, auto),
- table.header([*Parameter*], [*Value*]),
+ table.header([Parameter], [Value]),
[Material], [DC01 cold-rolled steel (EN 10130)],
[Thickness], [$qty(1.2, "mm")$],
[Finish], [Matte black powder coard (RAL 9005), all surfaces.],
@@ -36,9 +36,14 @@ especially in terms of magnetic shielding.
==== External dimensions <cassette-external-dimensions>
#figure(
+ image("pictures/cassette-external-dimensions.svg"),
+ caption: "Cassette external dimensions",
+) <figure-cassette-external-dimensions>
+
+#figure(
table(
columns: (auto, auto, auto, auto),
- table.header([*Dimension*], [*Value*], [*Tolerance*], [*Note*]),
+ table.header([Dimension], [Value], [Tolerance], [Note]),
[Panel height],
[$qty(177.8, "mm")$ ($qty(4, "U"), qty(7, "inch")$)],
[$plus.minus qty(0.1, "mm")$],
@@ -47,7 +52,8 @@ especially in terms of magnetic shielding.
[Grid pitch],
[$qty(38.1, "mm")$ ($qty(1.5, "inch")$)],
[N/A],
- [Theoretical center to center spacing. Two columns of banana jacks ($qty(0.75, "inch")$ grid).],
+ [Theoretical center to center spacing. Two columns of banana jacks
+ ($qty(0.75, "inch")$ grid).],
[Panel Width],
[$qty(38.0, "mm")$ ($qty(1.5, "inch")$)],
@@ -75,6 +81,11 @@ interlocking U-shaped steel channel:
===== L-channel (chassis) <l-channel-chassis>
+#figure(
+ image("pictures/l-channel.svg"),
+ caption: [L-channel (chassis) construction],
+) <figure-l-channel-chassis>
+
/ Role: Structural spine. Holds the PCB and Front Panel.
/ Geometry:
/ Left wall ($qty(165.1, "mm") times qty(152.4, "mm")$): PCB mounts here.
@@ -102,6 +113,11 @@ interlocking U-shaped steel channel:
===== U-channel (cover) <u-channel-cover>
+#figure(
+ image("pictures/u-channel.svg"),
+ caption: [U-channel (cover) construction],
+) <figure-u-channel-construction>
+
/ Role: EMI Shielding and Protection.
/ Geometry:
/ Top ($qty(35.7, "mm") times qty(152.4, "mm")$): vented
@@ -113,6 +129,11 @@ interlocking U-shaped steel channel:
===== Front panel <front-panel>
+#figure(
+ image("pictures/front-panel-geometry.svg"),
+ caption: [Front channel construction],
+) <figure-front-channel-construction>
+
/ Geometry: $qty(177.8, "mm") times qty(38.0, "mm")$, body section
$qty(165.1, "mm")$
/ Holes: Features Countersunk Through-Holes corresponding to the L-Channel's
@@ -156,7 +177,7 @@ will fail, degrading the SNR below the $qty(90, "dB")$ target.
#figure(
table(
columns: (auto, auto),
- table.header([*Dimension*], [*Value*]),
+ table.header([Dimension], [Value]),
[Height], [$qty(162.7, "mm")$],
[Width], [$qty(35.6, "mm")$],
[Depth], [$qty(150, "mm")$],
@@ -170,9 +191,14 @@ Top and bottom faces include ventilation slots for convective cooling while
maintaining EMI shielding.
#figure(
+ image("pictures/ventilation.svg"),
+ caption: [Cassette ventilation],
+) <figure-cassette-ventilation>
+
+#figure(
table(
columns: (auto, auto),
- table.header([*Parameter*], [*Value*]),
+ table.header([Parameter], [Value]),
[Slot size], [$qty(2.5, "mm") times qty(10, "mm")$],
[Slot orientation], [Length parallel to cassette depth],
[Rows], [$5$],
@@ -186,21 +212,33 @@ maintaining EMI shielding.
caption: [Cassette ventilation specifications],
) <table-cassette-ventilation>
-==== DB-25 connector cutout
+==== DB-25 connector cutout <db-25-connector-cutout>
+
+#figure(
+ image("pictures/db-25-connector-cutout.svg"),
+ caption: [DB-25 connector cutout],
+) <figure-db-25-connector-cutout>
#figure(
table(
columns: (auto, auto),
- table.header([*Parameter*], [*Value*]),
+ table.header([Parameter], [Value]),
[Shape], [D-shaped (standard DB-25 profile)],
+
[D-opening width], [$qty(33.3, "mm")$],
+
[D-opening height], [$qty(12.5, "mm")$],
+
[Mounting hole spacing], [$qty(24.99, "mm")$],
+
[Mounting hole size], [$diameter qty(3.2, "mm")$],
+
[Center X], [$qty(17.85, "mm")$ from either edge],
+
[Center Y], [$qty(82.5, "mm")$ from top/bottom (centered on $qty(165.1, "mm")$)],
[Connector assembly], [Panel mount with solder cups],
+
[Position], [Centered on rear closure],
),
caption: [Cassette DB-25 connector cutout specifications],
@@ -280,3 +318,571 @@ PCB must be electrically isolated from the steel cassette.
$25$) creates the bond between the cable shield and the cassette body.
/ Verification: Resistance between the DB-25 Shell and any point on the
cassette powder-coat-free zones must be $lt qty(0.1, "ohm")$.
+
+=== PCB <pcb>
+
+==== Overview <pcb-overview>
+
+Module PCBs mount vertically within the L-channel, attached to the left side
+wall via standoffs. The PCB connects to the front panel (banana jacks, controls)
+via wire harnesses and to the power distribution board via the rear DB-25
+connector.
+
+==== Standard dimensions <pcb-standard-dimensions>
+
+#figure(
+ table(
+ columns: (auto, auto, auto, auto),
+ table.header([Parameter], [Value], [Tolerances], [Notes]),
+ [Height], [$qty(155.0, "mm")$], [$plus.minus qty(0.2, "mm")$], [Vertical dimension when mounted],
+
+ [Depth], [$qty(125.0, "mm")$], [$plus.minus qty(0.2, "mm")$], [Front-to-rear dimension],
+
+ [Thickness], [$qty(1.6, "mm")$], [$plus.minus qty(0.15, "mm")$], [Standard 4-layer stackup],
+
+ [Corner radius], [$qty(3.0, "mm")$], [$plus.minus qty(0.5, "mm")$], [All four corners, for insertion clearance],
+ ),
+ caption: [PCB standard dimensions],
+) <table-pcb-standard-dimensions>
+
+==== Board stackup <pcb-board-stackup>
+
+All SAME module PCBs shall use a 4-layer stackup: This allows proper ground
+management, while remaining easy to solder with standard equipment.
+
+#figure(
+ table(
+ columns: (auto, auto, auto, auto),
+ table.header([Layer], [Function], [Copper weight], [Notes]),
+ [L1 (top)],
+ [Signal + components],
+ [$qty(1, "oz")$ ($qty(35, "um")$)],
+ [Component side faces right (toward U-channel)],
+
+ [L2 (inner 1)],
+ [Ground plane],
+ [$qty(1, "oz")$ ($qty(35, "um")$)],
+ [Continuous AGND plane, split for DGND if needed],
+
+ [L3 (inner 2)],
+ [Power plane],
+ [$qty(1, "oz")$ ($qty(35, "um")$)],
+ [Split for $plus.minus qty(15, "V")$, $plus.minus qty(5, "V")$ rails],
+
+ [L4 (bottom)],
+ [Signal + earth ring],
+ [$qty(1, "oz")$ ($qty(35, "um")$)],
+ [Faces left wall (mounting side), digital traces if needed],
+ ),
+ caption: [PCB board stackup],
+) <table-pcb-board-stackup>
+
+/ Dielectric: FR-4, $"Tg" gt.eq qty(135, "dC")$
+
+==== Surface finish <pcb-surface-finish>
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Parameter], [Specification]),
+ [Finish], [ENIG (Electroless Nickel Immersion Gold)],
+
+ [Nickel thickness], [$qtyrange(3, 5, "um")$],
+
+ [Gold thickness], [$qtyrange(0.05, 0.1, "um")$ ($qtyrange(1, 2, "micro inch")$)],
+
+ [Solder mask], [Matte black (both sides)],
+
+ [Silkscreen], [White (both sides)],
+ ),
+ caption: [PCB surface finish],
+) <table-pcb-surface-finish>
+
+===== Rationale <pcb-surface-finish-rationale>
+
+ENIG provides excellent corrosion resistance for the 50-year service life
+target. A flat surface ensures reliable soldering of precision components. Gold
+does not oxidize, maintaining consistent contact resistance at test points.
+
+Black solder mask reduces light reflectivity (some precision semiconductors are
+photosensitive).
+
+==== Earth ring <pcb-earth-ring>
+
+The PCB shall include a Chassis Earth ring around the perimeter of the bottom
+layer (L4). This ring provides a defined path for any capacitively-coupled noise
+to drain to chassis earth rather than coupling into signal traces.
+
+===== Geometry <pcb-earth-ring-geometry>
+
+#figure(
+ table(
+ columns: (auto, auto, auto),
+ table.header([Parameter], [Value], [Notes]),
+ [Width], [$qty(3.0, "mm")$], [Continuous copper pour],
+ [Clearance from edge], [$qty(0.5, "mm")$], [Manufacturing tolerance],
+ [Clearance to inner circuitry], [$qty(2.0, "mm")$], [Isolation gap],
+ [Layer], [L4 (bottom) only], [Faces mounting wall],
+ ),
+ caption: [PCB earth ring geometry],
+) <table-pcb-earth-ring-geometry>
+
+===== Connection <pcb-earth-ring-connection>
+
+The earth ring shall not connect to AGND or DGND on the PCB. It connects to
+Chassis Earth exclusively through the pin 25 of the DB-25 power distributor via
+a trace on L4.
+
+===== Mounting holes details <pcb-earth-ring-mounting-holes-details>
+
+The four mounting holes shall be:
+
+- Unplated, isolated through-holes, $diameter qty(3.2, "mm")$ (M3 clearance).
+- Not connected to any layer (no vias to L1, L2, L3, L4).
+
+==== Ground planes <pcb-ground-planes>
+
+===== AGND plane <pcb-ground-planes-agnd-plane>
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Parameter], [Value]),
+ [Layer], [L2 (inner 1)],
+ [Coverage], [Minimum $qty(85, "percent")$ of signal area],
+ [Splits], [Only if DGND zone required],
+ [Connection], [Via stitching to AGND traces & pads on L1 and L4],
+ ),
+ caption: [PCB AGND plane],
+) <table-pcb-ground-planes-agnd-plane>
+
+The AGND plane provides:
+- Low-impedance return path for analog signals,
+- Shielding between signal layers,
+- Thermal spreading.
+
+===== DGND zone (if needed) <pcb-ground-planes-dgnd-zone>
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Parameter], [Value]),
+ [Location], [Defined zone on L2],
+ [Separation], [$qty(2, "mm")$ gap from AGND plane],
+ [Connection], [To the DGND pins of the power distributor],
+ [Via stitching], [Only within DGND zone],
+ ),
+ caption: [PCB DGND zone],
+) <table-pcb-ground-planes-dgnd-zone>
+
+==== Power planes <pcb-power-planes>
+
+Layer 3 is divided into power distribution zones:
+
+#figure(
+ table(
+ columns: (auto, auto, auto),
+ table.header([Zone], [Rail], [Typical area]),
+ [Zone 1], [$plus qty(15, "V")$], [$qtyrange(30, 40, "percent")$],
+ [Zone 2], [$qty(-15, "V")$], [$qtyrange(30, 40, "percent")$],
+ [Zone 3], [$plus qty(5, "V")$ (if needed)], [$qtyrange(10, 15, "percent")$],
+ [Zone 4], [$qty(-5, "V")$ (if needed)], [$qtyrange(10, 15, "percent")$],
+ ),
+ caption: [PCB power planes],
+) <table-pcb-power-planes>
+
+Design rules:
+- Miminum $qty(2, "mm")$ clearance between power zones,
+- Star distribution from power enty point,
+- Bulk decoupling capacitors from power enty point,
+- Local decoupling at each IC.
+
+==== Mounting strategy <pcb-mounting-strategy>
+
+The PCB mounts to the L-channel left wall via four standoffs.
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Parameter], [Value]),
+ [Standoff thread], [$M 3$],
+ [Standoff height], [$qty(6, "mm")$],
+ [Standoff type], [Female threaded, swaged or welded to L-channel],
+ [Mounting screw], [$M 3 times qty(8, "mm")$ pan head],
+ ),
+ caption: [PCB mounting strategy: standoffs],
+) <table-pcb-mounting-strategy-standoffs>
+
+===== Mounting holes pattern <pcb-mounting-strategy-mounting-holes-pattern>
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Parameter], [Value]),
+ [Pattern], [Rectangular, $4$ holes],
+ [Horizontal spacing (X)], [$qty(105.0, "mm")$],
+ [Vertical spacing (Y)], [$qty(155.0, "mm")$],
+ [Hole diameter], [$diameter qty(3.2, "mm")$ ($M 3$ clearance)],
+ [Hole plating], [Unplated, isolated],
+ ),
+ caption: [PCB mounting strategy: mounting holes],
+) <table-pcb-mounting-strategy-mounting-holes-pattern>
+
+====== Positions <pcb-mounting-strategy-mounting-holes-positions>
+
+#figure(
+ table(
+ columns: (auto, auto, auto),
+ table.header([Hole], [X], [Y]),
+ [1 (bottom-left)], [$qty(10.00, "mm")$], [$qty(10.00, "mm")$],
+ [2 (bottom-right)], [$qty(115.00, "mm")$], [$qty(10.00, "mm")$],
+ [3 (top-left)], [$qty(10.00, "mm")$], [$qty(145.00, "mm")$],
+ [4 (top-right)], [$qty(115.00, "mm")$], [$qty(145.00, "mm")$],
+ ),
+ caption: [PCB mounting strategy: mounting holes positions],
+)
+
+==== Keep-out zones <pcb-keep-out-zones>
+
+===== Perimeter keep-out <pcb-keep-out-zones-perimeter-keep-out>
+
+#figure(
+ table(
+ columns: (auto, auto, auto),
+ table.header([Parameter], [Value], [Notes]),
+ [Width], [$qty(5.0, "mm")$], [All four edges],
+ [Applies to], [Components and tall traces], [Solder mask and silkscreen allowed],
+
+ [Reason], [Clearance for cassette walls and earth ring], [],
+ ),
+ caption: [PCB keep-out zones: perimeter keep-out],
+) <table-pcb-keep-out-zones-perimeter-keep-out>
+
+===== Mounting holes keep-out <pcb-keep-out-zones-mounting-holes-keep-out>
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Parameter], [Value]),
+ [Radius], [$qty(0.5, "mm")$ from hole center],
+ [Applies to], [Components, traces, planes (except earth ring)],
+ ),
+ caption: [PCB keep-out zones: mounting holes keep-out],
+) <table-pcb-keep-out-zones-mounting-holes-keep-out>
+
+==== Interconnect zones <pcb-interconnect-zones>
+
+===== Zone A: power and master oscillator entry (rear) <pcb-interconnect-zones-zone-a>
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Parameter], [Value]),
+ [Location], [Rear $qty(20, "mm")$ of PCB ($Y = qtyrange(0, 20, "mm", delimiter: "\"to\"")$)],
+
+ [Function], [Connection to DB-25 backplane connector and rear BNC],
+ [Connector],
+ [
+ / Power: pluggable terminal block (e.g. Phoenix Contact MSTB $qty(3.5, "mm")$ or latching header (e.g Molex KK $qty(3.96, "mm")$).
+ / Master oscillator (optional): The rear BNC connects to the PCB via a short ($lt qty(50, "mm")$) $qty(50, "ohm")$ coaxial pigtail (RG-174 or RG-316) soldered to dedicated RF pads or a u.FL/SMA connector on the PCB edge.
+ ],
+
+ [Wire gauge], [$qtyrange(22, 24, "AWG")$ for power, $qty(26, "AWG")$ for signals],
+ ),
+ caption: [PCB interconnect zones: zone A],
+) <table-pcb-interconnect-zones-zone-a>
+
+====== Pin assignment <pcb-interconnect-zones-zone-a-pin-assignment>
+
+The PCB connector shall provide access to all power rails in a logical grouping:
+
+#figure(
+ table(
+ columns: (auto, auto, auto),
+ table.header([Position], [Signal], [Recommended wire color]),
+ [1], [$plus qty(15, "V")$], [Red],
+ [2], [$qty(-15, "V")$], [Orange],
+ [3], [AGND], [Black],
+ [4], [$plus qty(10, "V")$ force], [White],
+ [5], [$plus qty(10, "V")$ sense], [White / red stripe],
+ [6], [$qty(-10, "V")$ force], [Grey],
+ [7], [$qty(-10, "V")$ sense], [Gred / red stripe],
+ [8], [$plus qty(5, "VD")$], [Yellow],
+ [9], [$qty(-5, "VD")$], [Blue],
+ [10], [DGND], [Brown],
+ [11], [Stagger], [Purple],
+ [12], [Chassis Earth], [Green / yellow stripe],
+ ),
+ caption: [PCB interconnect zones: zone A pin assignment],
+) <table-pcb-interconnect-zones-zone-a-pin-assignment>
+
+Not all modules require all signals. Unused positions may be omitted from the
+harness.
+
+===== Zone B: front panel I/O <pcb-interconnect-zones-zone-b>
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Parameter], [Value]),
+ [Location], [Front $qty(20, "mm")$ of PCB ($Y = qtyrange(135, 155, "mm", delimiter: "\"to\"")$)],
+
+ [Function], [Connection to banana jacks and controls],
+ [Connector], [Pin headers, terminal blocks, or direct solder pads],
+ [Wire gauge], [$qtyrange(24, 25, "AWG")$],
+ ),
+ caption: [PCB interconnect zones: zone B],
+) <table-pcb-interconnect-zones-zone-b>
+
+Design guidelines:
+- Group outputs on one side, inputs on the other,
+- Maintain signal flow from right to left (input #sym.arrow.r processing
+ #sym.arrow.r output),
+- Include test points for each signal node.
+
+===== Service loop requirements <pcb-interconnect-zones-zone-b-service-loop-requirements>
+
+All internal wiring shall include a service loop of minimum $qty(20, "mm")$
+additional length. This allows the PCB to be:
+- Unscrewed from standoffs,
+- Tilted or lifted for inspection,
+- Accessed for rework.
+
+Without disconnecting the wire harnesses.
+
+==== Silkscreen requirements <pcb-silkscreen-requirements>
+
+===== Component side (L1 - top) <pcb-silkscreen-requirements-l1>
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Element], [Requirement]),
+ [Reference designators], [All components labeled($R_"bias"$, $C_"bulk"$, $U_"buf"$, etc.)],
+
+ [Polarity marks], [All polarized components (diodes, electrolytics, ICs, etc.)],
+
+ [Pin 1 indicators], [All ICs and connectors],
+ [Assembly notes], [Tier-specific component values (if applicable)],
+ [Test points], [Labeled with signal name],
+ ),
+ caption: [PCB silkscreen requirements: component side (L1 - top)],
+) <table-pcb-silkscreen-requirements-l1>
+
+Labels should be functional if possible, defaults to $R_1$, $C_1$, $U_1$, etc.
+if there are space constraints.
+
+===== Solder side (L4 - bottom) <pcb-silkscreen-requirements-l4>
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Element], [Requirement]),
+ [Board identification], [Module name, version, date],
+ [SAME logo], [Mandatory],
+ [Precision tier], ["$"EDU"$", "$"IND"$", or "$"MET"$" marking area],
+ [Designer attribution], [Name, handle or logo],
+ [License], ["$"CERN-OHL-S-2.0+"$"],
+ ),
+ caption: [PCB silkscreen requirements: solder side (L4 - bottom)],
+) <table-pcb-silkscreen-requirements-l4>
+
+==== Electrical testing <pcb-electrical-testing>
+
+All PCBs shall pass the following tests before assembly:
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Test], [Requirement]),
+ [Isolation], [$gt qty(100, "mega ohm")$ between unconnected nets],
+ [Continuity], [All nets per netlist],
+ [Earth ring isolation], [$gt qty(100, "mega ohm")$ between earth ring and AGND/DGND],
+
+ [Earth ring continuity],
+ [$lt qty(1, "ohm")$ along entire earth ring perimeter (measure between opposite corners of the ring trace)],
+ ),
+ caption: [PCB electrical testing requirements],
+) <table-pcb-electrical-testing-requirements>
+
+=== Panels <panels>
+
+==== Geometry <panels-geometry>
+
+The front panel is a separate piece that attaches to the L-channel via countersunk screws.
+
+#figure(
+ table(
+ columns: (auto, auto, auto),
+ table.header([Parameter], [Value], [Tolerance]),
+ [Height], [$qty(177.8, "mm")$ ($qty(4, "U"), qty(7, "inch")$)], [$plus.minus qty(0.1, "mm")$],
+
+ [Width], [$qty(38, "mm")$], [$plus 0.0 "/" qty(-0.1, "mm")$],
+ [Thickness], [$qty(1.2, "mm")$], [$plus.minus qty(0.1, "mm")$],
+ [Material], [DC01 cold-rolled steel], [N/A],
+ [Finish], [Matte black powder coat (RAL 9005)], [N/A],
+ ),
+ caption: [Panels geometry],
+) <table-panels-geometry>
+
+===== Panels zones <panels-zones>
+
+#figure(
+ table(
+ columns: (auto, auto, auto),
+ table.header([Zone], [Height range], [Function]),
+ [Top lip], [$qtyrange(0, 6.35, "mm")$], [Extends above cassette body],
+ [Body], [$qtyrange(6.35, 171.45, "mm")$], [Jack and control area],
+ [Bottom lip], [$qtyrange(171.45, 177.8, "mm")$], [Extends below cassette body],
+ ),
+ caption: [Panels zones],
+) <table-panels-zones>
+
+==== Grid <panels-grid>
+
+All panel-mounted components follow a $qty(0.75, "inch")$ ($qty(19.05, "mm")$)
+grid for compatibility with standard banana jack spacing and shorting bars.
+
+#figure(
+ image("pictures/grid.svg"),
+ caption: [Grid],
+) <figure-grid>
+
+===== Origin <panels-grid-origin>
+
+#figure(
+ table(
+ columns: (auto, auto),
+ table.header([Parameter], [Value]),
+ [Origin X], [$qty(9.525, "mm")$ from left edge (first column center)],
+ [Origin Y], [$qty(22.225, "mm")$ from top edge (first row center)],
+ [Column pitch], [$qty(19.95, "mm")$ ($qty(0.75, "inch")$)],
+ [Row pitch], [$qty(19.95, "mm")$ ($qty(0.75, "inch")$)],
+ [Columns], [$2$],
+ [Rows], [$8$],
+ ),
+ caption: [Panels grid orign],
+) <table-panels-grid-origin>
+
+===== Positions <panels-grid-positions>
+
+#figure(
+ table(
+ columns: (auto, auto, auto, auto, auto),
+ table.header([Position], [Column], [Row], [X (from left)], [Y (from top)]),
+ [A1], [$1$], [$1$], [$qty(9.525, "mm")$], [$qty(22.225, "mm")$],
+ [B1], [$2$], [$1$], [$qty(28.575, "mm")$], [$qty(22.225, "mm")$],
+ [A2], [$1$], [$2$], [$qty(9.525, "mm")$], [$qty(41.275, "mm")$],
+ [B2], [$2$], [$2$], [$qty(28.575, "mm")$], [$qty(41.275, "mm")$],
+ [A3], [$1$], [$3$], [$qty(9.525, "mm")$], [$qty(60.325, "mm")$],
+ [B3], [$2$], [$3$], [$qty(28.575, "mm")$], [$qty(60.325, "mm")$],
+ [A4], [$1$], [$4$], [$qty(9.525, "mm")$], [$qty(79.375, "mm")$],
+ [B4], [$2$], [$4$], [$qty(28.575, "mm")$], [$qty(79.375, "mm")$],
+ [A5], [$1$], [$5$], [$qty(9.525, "mm")$], [$qty(98.425, "mm")$],
+ [B5], [$2$], [$5$], [$qty(28.575, "mm")$], [$qty(98.425, "mm")$],
+ [A6], [$1$], [$6$], [$qty(9.525, "mm")$], [$qty(117.475, "mm")$],
+ [B6], [$2$], [$6$], [$qty(28.575, "mm")$], [$qty(117.475, "mm")$],
+ [A7], [$1$], [$7$], [$qty(9.525, "mm")$], [$qty(136.525, "mm")$],
+ [B7], [$2$], [$7$], [$qty(28.575, "mm")$], [$qty(136.525, "mm")$],
+ [A8], [$1$], [$8$], [$qty(9.525, "mm")$], [$qty(155.575, "mm")$],
+ [B8], [$2$], [$8$], [$qty(28.575, "mm")$], [$qty(155.575, "mm")$],
+ ),
+ caption: [Panels grid positions],
+) <table-panels-grid-positions>
+
+===== Component placement rules <panels-grid-component-placement-rules>
+
+#figure(
+ table(
+ columns: (auto, auto, auto),
+ table.header([Component], [Grid positions], [Hole size]),
+ [$qty(4, "mm")$ banana jack], [Any], [$diameter qty(8.0, "mm")$],
+ [$qty(6, "mm")$ potentiometer shaft], [Any], [$diameter qty(7.0, "mm")$],
+ [$qty(3, "mm")$ LED], [Between grid positions], [$diameter qty(3.2, "mm")$],
+ [Toggle switch], [Any], [Per switch specification],
+ [Other components], [Centered on grid if possible], [Per component specification],
+ ),
+ caption: [Panels grid: component placement rules],
+) <table-panels-grid-component-placement-rules>
+
+====== Off-grid placements
+
++ Small indicators (LEDs) and labels may be placed between grid positions.
++ Non-specified components (controls, interface ports, etc.) should be centered
+ on grid positions if possible, or centered on the panel.
++ Mounting screws for the panel (into L-channel flanges) are outside the grid
+ area.
+
+==== Labelling <panels-labelling>
+
+All panels shall include clear, permanent labelling for user operation.
+
+#figure(
+ table(
+ columns: (auto, auto, auto),
+ table.header([Element], [Requirement], [Location]),
+ [Module name], [Mandatory], [Top lip],