Compare commits
10 Commits
c3af7afd9c
...
33b62d7052
| Author | SHA1 | Date | |
|---|---|---|---|
| 33b62d7052 | |||
| 564c3e450d | |||
| b877f0458c | |||
| 768f49a860 | |||
| 7f7a3d5d39 | |||
| 61e10d8145 | |||
| cb93840518 | |||
| 5e2dc775d7 | |||
| 538b62b72c | |||
| 94da1ad0eb |
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -9,5 +9,5 @@
|
||||
url = ssh://git.helgen.dev:6611/hbox-log-tools
|
||||
[submodule "kicad"]
|
||||
path = 03-Architecture-Hardware/kicad
|
||||
url = git@github.com:lrodriguez15/hbox-kicad.git
|
||||
url = ssh://git@git.helgen.online:222/Helgen-Services/HBox_PCB.git
|
||||
branch = main
|
||||
|
||||
@ -57,13 +57,18 @@ ul{padding-left:20px}
|
||||
li{margin:4px 0}
|
||||
.tag{font-family:"Archivo",sans-serif;font-size:10.5px;text-transform:uppercase;letter-spacing:.08em;padding:2px 7px;border-radius:99px;border:1px solid var(--copper);color:var(--copper);white-space:nowrap}
|
||||
.tag.q{border-color:var(--plane);color:var(--plane)}
|
||||
.d{font-family:"Archivo",sans-serif;font-size:10px;font-weight:600;letter-spacing:.05em;padding:1px 6px;border-radius:99px;white-space:nowrap}
|
||||
.d1{background:var(--crit-soft);color:var(--crit)}
|
||||
.d2{background:var(--copper-soft);color:var(--copper)}
|
||||
.d3{background:var(--plane-soft);color:var(--plane)}
|
||||
tr.own td{font-family:"Archivo",sans-serif;font-size:12.5px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--copper);border-bottom:2px solid var(--copper);padding-top:18px;white-space:normal}
|
||||
a{color:var(--plane)}
|
||||
</style>
|
||||
<div class="wrap">
|
||||
<h1>EinarBoard v6 Copper Plan</h1>
|
||||
<p class="sub">Placement companion for the 140 × 100 re-layout — every capacitor's owner, what clusters together, and the EMC order of work. Cap ownership below is computed from the board netlist, not from memory.</p>
|
||||
|
||||
<div class="warn"><b>Before placing anything:</b> run <i>Update PCB from Schematic</i> once more. The NTC2 label was sitting on PA7 (TIMEPULSE) and merged the nets — it is fixed in the schematic (commit <code>ba70f62</code>), and the sync re-nets <code>P18</code>/<code>R126</code>/<code>C157</code> to a clean <code>/NTC2</code>. Tick <i>“delete footprints with no symbol”</i> in that dialog.</div>
|
||||
<div class="note"><b>Connector renumber (03-Sep, commit <code>b007c7c</code>):</b> P-refs now follow function order — <code>P1</code> 24V · <code>P2</code> 5V bench · <code>P3</code> battery (was P4) · <code>P4</code> fan (was P6) · <code>P5</code> cutoff (was P11) · <code>P6</code> reset (was P10) · <code>P7</code> NTC probe 1 (was P12) · <code>P8</code> NTC probe 2 (was P18) · <code>P9</code> panel LED (was P8) · <code>P10</code> RGB (was P14) · <code>P11</code> RS485 (was P15) · <code>P12</code> RS232 (was P16). ⚠ v5 field docs say "P12 = NTC" — in v6 that name is the RS232 port; update harness docs. The NTC2 net fix is applied and synced.</div>
|
||||
<div class="note"><b>Known leftovers from the auto-clustering:</b> ~54 small courtyard overlaps, nearly all against the legacy V5 regulator families that kept their old spots — <code>L2</code>/<code>D2</code> (under U19's new outline), <code>L6</code>/<code>DB2</code>/<code>DB3</code>/<code>Q2</code>/<code>Dbk1</code> near U25, <code>C40</code>, <code>R40</code>/<code>R41</code> at Y3. Drag those few aside first and the board is clean.</div>
|
||||
|
||||
<h2><span class="no">§0</span>Three laws that decide EMC at placement time</h2>
|
||||
@ -122,11 +127,11 @@ a{color:var(--plane)}
|
||||
<div class="tblwrap"><table>
|
||||
<tr><th>Ref</th><th>Value</th><th>Belongs to</th><th>Placement</th></tr>
|
||||
<tr><td>C149 C150</td><td>2.2 µF/100 V</td><td>U25 VIN</td><td>2–3 mm from pins 2/7; the hot loop</td></tr>
|
||||
<tr><td>C151</td><td>100 µF/50 V</td><td>input bulk</td><td>right behind C149/C150</td></tr>
|
||||
<tr><td>C151</td><td>100 µF/50 V</td><td>U25 input bulk</td><td>right behind C149/C150</td></tr>
|
||||
<tr><td>C152</td><td>100 nF</td><td>U25 BOOT</td><td>directly across pins 1–8</td></tr>
|
||||
<tr><td>C153 C154</td><td>47 µF/16 V</td><td>5 V output</td><td>at L22 output; FB tap (R121) here, not at the inductor</td></tr>
|
||||
<tr><td>D34</td><td>B560C</td><td>catch diode</td><td>anode ground ties straight into C149/C150 ground</td></tr>
|
||||
<tr><td>D32</td><td>SMCJ33A</td><td>surge clamp</td><td>between Q23 and the input caps, short fat ties</td></tr>
|
||||
<tr><td>C153 C154</td><td>47 µF/16 V</td><td>U25 5 V output</td><td>at L22 output; FB tap (R121) here, not at the inductor</td></tr>
|
||||
<tr><td>D34</td><td>B560C</td><td>U25 catch diode</td><td>anode ground ties straight into C149/C150 ground</td></tr>
|
||||
<tr><td>D32</td><td>SMCJ33A</td><td>U25 input surge clamp</td><td>between Q23 and the input caps, short fat ties</td></tr>
|
||||
<tr><td>R120 · R123 C155 C156 · R121 R122 · R124 R125</td><td>RT · COMP · FB · UVLO (DNP)</td><td>U25 analog side</td><td>cluster at pins 3–6, opposite the SW node; keep FB thin and away from L22</td></tr>
|
||||
</table></div>
|
||||
<p>24 V rail housekeeping: <code>C10</code>/<code>C22</code> bulk near Q10, <code>C11</code> 100 nF at the load side. Keep the whole entry block in one corner so the dirty 24 V copper never crosses the board.</p>
|
||||
@ -134,9 +139,9 @@ a{color:var(--plane)}
|
||||
<h2><span class="no">§3</span>Battery backup — U6 LTC4040 <span class="tag q">kelvin</span></h2>
|
||||
<div class="tblwrap"><table>
|
||||
<tr><th>Ref</th><th>Value</th><th>Belongs to</th><th>Placement</th></tr>
|
||||
<tr><td>C30 C31 C78</td><td>10 µF · 2.2 µF · 220 µF</td><td>VEH5V input</td><td>at U6 input pins, after RS1</td></tr>
|
||||
<tr><td>C32 C33 C34</td><td>47 µF ×2 · 10 µF</td><td>MAIN5V output</td><td>at U6/Q7 output side</td></tr>
|
||||
<tr><td>C35</td><td>22 µF</td><td>BAT_PLUS</td><td>near P4; <code>/SW_BAT</code> ≥ 2 mm polygon, <code>/BAT_PLUS</code> ≥ 1.5 mm — the blackout path, a hard v6 requirement</td></tr>
|
||||
<tr><td>C30 C31 C78</td><td>10 µF · 2.2 µF · 220 µF</td><td>U6 VEH5V input</td><td>at U6 input pins, after RS1</td></tr>
|
||||
<tr><td>C32 C33 C34</td><td>47 µF ×2 · 10 µF</td><td>U6 MAIN5V output</td><td>at U6/Q7 output side</td></tr>
|
||||
<tr><td>C35</td><td>22 µF</td><td>U6 BAT pin → P3</td><td>near P3; <code>/SW_BAT</code> ≥ 2 mm polygon, <code>/BAT_PLUS</code> ≥ 1.5 mm — the blackout path, a hard v6 requirement</td></tr>
|
||||
</table></div>
|
||||
<div class="note"><b>RS1 (10 mΩ) is a Kelvin part:</b> the LTC4040 sense pins must tap the pad faces themselves, not the power trace. Place RS1 immediately at U6 with L22's output feeding it directly.</div>
|
||||
|
||||
@ -145,10 +150,10 @@ a{color:var(--plane)}
|
||||
<p>The VBAT bank is a one-direction gradient into pins 55/56/57 — largest farthest, smallest touching the module:</p>
|
||||
<div class="tblwrap"><table>
|
||||
<tr><th>Ref</th><th>Value</th><th>Order</th><th>Placement</th></tr>
|
||||
<tr><td>C130 C131</td><td>220 µF/10 V ×2</td><td>far end</td><td>the ≥300 µF droop reservoir (2.8 A bursts, ≤300 mV sag)</td></tr>
|
||||
<tr><td>C132 → C133 → C134</td><td>22 µF → 1 µF → 100 nF</td><td>middle</td><td>stepping toward the module</td></tr>
|
||||
<tr><td>C135 C136</td><td>33 pF · 10 pF</td><td>at the pins</td><td>within 2–3 mm of pins 55/56/57 — these keep TX harmonics off VBAT</td></tr>
|
||||
<tr><td>D22</td><td>SMAJ5.0A</td><td>at the bank</td><td>across VBAT near C130/C131</td></tr>
|
||||
<tr><td>C130 C131</td><td>220 µF/10 V ×2</td><td>U19 VBAT · far end</td><td>the ≥300 µF droop reservoir (2.8 A bursts, ≤300 mV sag)</td></tr>
|
||||
<tr><td>C132 → C133 → C134</td><td>22 µF → 1 µF → 100 nF</td><td>U19 VBAT · middle</td><td>stepping toward the module</td></tr>
|
||||
<tr><td>C135 C136</td><td>33 pF · 10 pF</td><td>U19 pins 55/56/57</td><td>within 2–3 mm — these keep TX harmonics off VBAT</td></tr>
|
||||
<tr><td>D22</td><td>SMAJ5.0A</td><td>U19 VBAT bank</td><td>across VBAT near C130/C131</td></tr>
|
||||
</table></div>
|
||||
<p>VBAT copper ≥ 3 mm wide the whole way. Around the module: <code>C125</code> at pin 15 (1V8 out); <code>U22</code> SIM within 5 mm of pins 30–33 with <code>C126</code> at its VCC pad and <code>D23–D25</code> PESD at the SIM pads; <code>U23</code>/<code>U24</code> level shifters between U19 and the MCU side, each with its supply pair (<code>C137</code>/<code>C139</code> on 1V8, <code>C138</code>/<code>C140</code> on 3V3) at the pins; <code>Q20–Q22</code> near the control pins they drive. <code>J13</code> U.FL at the board edge; the DNP pi network <code>C146</code>/<code>C147</code> (+ its series element) sits inline in the 50 Ω run right at the connector, <code>D28</code> ESD at the connector ground side.</p>
|
||||
|
||||
@ -156,10 +161,12 @@ a{color:var(--plane)}
|
||||
<div class="tblwrap"><table>
|
||||
<tr><th>Ref</th><th>Value</th><th>Belongs to</th><th>Placement</th></tr>
|
||||
<tr><td>C119</td><td>10 µF</td><td>U21 input (SW_5V)</td><td>at the LDO input pin</td></tr>
|
||||
<tr><td>C120 C124</td><td>10 µF ×2</td><td>3V3_GNSS</td><td>one at U21 output, one at U18's main VCC entry</td></tr>
|
||||
<tr><td>C121 C122 C123</td><td>100 nF ×3</td><td>U18 VCC pins</td><td>one per supply pin, at the pin</td></tr>
|
||||
<tr><td>C144 C145</td><td>100 nF · 100 pF</td><td>VCC_RF / bias tee</td><td>at L21's feed side — the antenna supply injection</td></tr>
|
||||
<tr><td>C143</td><td>100 nF RF</td><td>DC block</td><td>inline in the 50 Ω run between L21 tap and J12</td></tr>
|
||||
<tr><td>C120 C124</td><td>10 µF ×2</td><td>U21 out → U18 VCC</td><td>one at U21 output, one at U18's main VCC entry</td></tr>
|
||||
<tr><td>C121 C122</td><td>100 nF ×2</td><td>U18 VCC pins 33/34</td><td>one per supply pin, at the pin</td></tr>
|
||||
<tr><td>C123</td><td>100 nF</td><td>U21 VOUT, beside C120</td><td>U18 has only two VCC pins — C123 is the rail-entry third</td></tr>
|
||||
<tr><td>Cu4</td><td>100 nF</td><td>U18 pin 36 V_BCKP (/3V3!)</td><td>V_BCKP rides the always-on 3V3, not 3V3_GNSS — that is deliberate (RTC + ephemeris survive when U21 is switched off). It needs its own /3V3 cap at the pin; C120–C124 are all on /3V3_GNSS and cannot serve it. Repurpose the spare Cu4.</td></tr>
|
||||
<tr><td>C144 C145</td><td>100 nF · 100 pF</td><td>U18 VCC_RF · L21 bias tee</td><td>at L21's feed side — the antenna supply injection</td></tr>
|
||||
<tr><td>C143</td><td>100 nF RF</td><td>J12 RF line (DC block)</td><td>inline in the 50 Ω run between L21 tap and J12</td></tr>
|
||||
<tr><td>D27</td><td>ESD9L (≤0.5 pF)</td><td>J12</td><td>at the connector, stub-less tap on the RF line</td></tr>
|
||||
</table></div>
|
||||
<p>This corner is the victim: no switcher, no inductor, no fast digital within ~25 mm (U25 sits ~95 mm away in the SE, the fan buck ~130 mm NE — keep it that way); nothing but solid In1 ground under the module and the RF run. <code>TIMEPULSE</code> to the MCU is the one digital line that leaves — route it away from the RF path.</p>
|
||||
@ -167,27 +174,207 @@ a{color:var(--plane)}
|
||||
<h2><span class="no">§6</span>MCU core — U16 <span class="tag q">analog care</span></h2>
|
||||
<div class="tblwrap"><table>
|
||||
<tr><th>Ref</th><th>Value</th><th>Belongs to</th><th>Placement</th></tr>
|
||||
<tr><td>C111</td><td>4.7 µF</td><td>VCAP1</td><td>≤ 3 mm from the pin — the core regulator, non-negotiable</td></tr>
|
||||
<tr><td>C109 C112</td><td>100 nF · 1 µF</td><td>VDDA</td><td>at the VDDA pin, on the quiet side, away from the switchers</td></tr>
|
||||
<tr><td>C105–C108 + C110</td><td>100 nF ×4 + 4.7 µF</td><td>VDD pins</td><td>one 100 nF per VDD pin, bulk nearby</td></tr>
|
||||
<tr><td>C104</td><td>100 nF</td><td>NRST</td><td>at the pin, with P10 reset routed clean</td></tr>
|
||||
<tr><td>Y3 + C113 C114</td><td>HSE + 15 pF</td><td>crystal</td><td>tight triangle at the pins, local ground, ≥10 mm from any inductor</td></tr>
|
||||
<tr><td>Y4 + C115 C116</td><td>LSE 32 kHz + 12 pF</td><td>crystal</td><td>even tighter — high-impedance oscillator, guard with ground</td></tr>
|
||||
<tr><td>C5 C7 C9 C24 C157</td><td>100 nF ×5</td><td>ADC sense filters</td><td>with their dividers (R42, R126…) at the MCU pins, not at the jacks — the wire filters at the pin</td></tr>
|
||||
<tr><td>C111</td><td>4.7 µF</td><td>U16 VCAP1</td><td>≤ 3 mm from the pin — the core regulator, non-negotiable</td></tr>
|
||||
<tr><td>C109 C112</td><td>100 nF · 1 µF</td><td>U16 VDDA</td><td>at the VDDA pin, on the quiet side, away from the switchers</td></tr>
|
||||
<tr><td>C105–C108 + C110</td><td>100 nF ×4 + 4.7 µF</td><td>U16 VDD pins</td><td>one 100 nF per VDD pin, bulk nearby</td></tr>
|
||||
<tr><td>C104</td><td>100 nF</td><td>U16 NRST</td><td>at the pin, with the P6 reset jack routed clean</td></tr>
|
||||
<tr><td>Y3 + C113 C114</td><td>HSE + 15 pF</td><td>U16 OSC pins</td><td>tight triangle at the pins, local ground, ≥10 mm from any inductor</td></tr>
|
||||
<tr><td>Y4 + C115 C116</td><td>LSE 32 kHz + 12 pF</td><td>U16 OSC32 pins</td><td>even tighter — high-impedance oscillator, guard with ground</td></tr>
|
||||
<tr><td>C5 C7 C9 C24 C157</td><td>100 nF ×5</td><td>U16 ADC pins</td><td>with their dividers (R42, R126…) at the MCU pins, not at the jacks — the wire filters at the pin</td></tr>
|
||||
</table></div>
|
||||
|
||||
<h2><span class="no">§7</span>The rest of the families</h2>
|
||||
<ul>
|
||||
<li><b>Ethernet</b> (<code>U11</code>/<code>U12</code>, <code>Y1</code>, <code>C90–C103</code>): one block, U11 close to J10 (magnetics are inside the HR911105A), crystal + 18 pF at the pins, the 3V3_ETH locals (<code>C92–C94</code>, <code>C98</code>, <code>C102</code>, <code>C103</code>) around U11. Keep the RJ45 pair region free of other routes.</li>
|
||||
<li><b>RS232</b> (<code>U15</code>): <code>C85–C88</code> are charge-pump flying caps — they carry the pump current, so they sit hard against U15; <code>C84</code> 100 nF at its supply pin. P16 at the edge.</li>
|
||||
<li><b>RS232</b> (<code>U15</code>): <code>C85–C88</code> are charge-pump flying caps — they carry the pump current, so they sit hard against U15; <code>C84</code> 100 nF at its supply pin. P12 (RS232 jack) at the edge.</li>
|
||||
<li><b>UART bridge</b> (<code>U10</code>, <code>Y2</code>, <code>C82</code>/<code>C83</code>): crystal caps at the pins, block near the MCU.</li>
|
||||
<li><b>Fan buck</b> (<code>U2</code>, <code>Cbst1</code>, <code>Ccomp1</code>, <code>C23</code>): a third switcher — treat like §4's loop, and park it in the noisy quarter near the power entry, away from GNSS.</li>
|
||||
<li><b>Accelerometer</b> (<code>U26</code>, <code>C158</code>/<code>C159</code> at VDD/VDDIO, <code>C160</code> bulk): ≤ 10 mm from a mounting hole, on stiff board — it should feel the chassis, not board flex.</li>
|
||||
<li><b>Rail sprinkles</b> (<code>Cu3</code> <code>Cu4</code> <code>C80</code> <code>C81</code> <code>C89</code> <code>C105+</code>…): every 100 nF on 3V3 pairs with one IC's power pin — when you move an IC, its 100 nF moves with it. <code>C118</code> 22 µF is the 3V3 bulk at the regulator.</li>
|
||||
<li><b>NTC channels</b>: pullup + filter (<code>R42</code>+<code>C24</code>, <code>R126</code>+<code>C157</code>) at the MCU; <code>P12</code>/<code>P18</code> jacks at the harness edge.</li>
|
||||
<li><b>NTC channels</b>: pullup + filter (<code>R42</code>+<code>C24</code> → P7, <code>R126</code>+<code>C157</code> → P8) at the MCU; <code>P7</code>/<code>P8</code> jacks at the harness edge.</li>
|
||||
</ul>
|
||||
|
||||
<h2><span class="no">§8</span>Separation rules</h2>
|
||||
<h2><span class="no">§8</span>Master proximity table — every discrete, its owner designator, and how close</h2>
|
||||
<p>Computed from the current board netlist (post-rename, all 300 footprints), then hand-corrected where the netlist heuristic picked a connected-but-wrong owner (ESD parts belong at connectors, ADC filters at the MCU, comp caps at their regulator). Distance classes:</p>
|
||||
<p><span class="d d1">🔴 GLUED ≤3 mm</span> loop-critical — same pad ground, no via between <span class="d d2">🟠 CLOSE ≤5 mm</span> at the pin, short direct trace <span class="d d3">🔵 BLOCK ≤15 mm</span> same cluster, routing order free</p>
|
||||
<div class="tblwrap"><table>
|
||||
<tr><th>Ref</th><th>Value</th><th>Glue to</th><th></th><th>Why</th></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">P1 — 24 V entry (SE corner)</td></tr>
|
||||
<tr><td>D10</td><td>SMBJ33A</td><td>P1 pin 1 (24V_IN)</td><td><span class="d d1">🔴</span></td><td>surge clamp at the jack, before anything else</td></tr>
|
||||
<tr><td>Rig1</td><td>22k</td><td>P1 ignition pin</td><td><span class="d d1">🔴</span></td><td>series element right at the jack</td></tr>
|
||||
<tr><td>F2</td><td>2 A slow 1812</td><td>P1 → Q23</td><td><span class="d d3">🔵</span></td><td>first element in the chain</td></tr>
|
||||
<tr><td>Q23</td><td>IRFR5305</td><td>F2 output</td><td><span class="d d3">🔵</span></td><td>reverse-polarity FET, chain order</td></tr>
|
||||
<tr><td>R119 D33</td><td>100k · BZX84C15</td><td>Q23 G–S pads</td><td><span class="d d1">🔴</span></td><td>gate bias + 15 V clamp across the FET itself</td></tr>
|
||||
<tr><td>D32</td><td>SMCJ33A</td><td>between Q23 and C149/C150</td><td><span class="d d2">🟠</span></td><td>clamps the line before the buck sees it</td></tr>
|
||||
<tr><td>Q10</td><td>IRFR5305</td><td>P1 24 V branch</td><td><span class="d d3">🔵</span></td><td>legacy 24 V rail FET (feeds U2 + K1)</td></tr>
|
||||
<tr><td>Rrp1 DzG1</td><td>10k · BZX84C15</td><td>Q10 G–S pads</td><td><span class="d d1">🔴</span></td><td>gate network — the part behind the v5.5 jumper check</td></tr>
|
||||
<tr><td>C10 C22</td><td>47 µF/50 V · 22 µF/50 V</td><td>Q10 load side (/24V)</td><td><span class="d d3">🔵</span></td><td>24 V rail bulk</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">U25 — TPS54360B vehicle buck</td></tr>
|
||||
<tr><td>C149 C150</td><td>2.2 µF/100 V</td><td>U25 pins 2/7 (VIN–GND)</td><td><span class="d d1">🔴</span></td><td>THE hot loop of the board</td></tr>
|
||||
<tr><td>D34</td><td>B560C</td><td>U25 SW + C149 ground</td><td><span class="d d1">🔴</span></td><td>closes the hot loop</td></tr>
|
||||
<tr><td>C151</td><td>100 µF/50 V</td><td>behind C149/C150</td><td><span class="d d2">🟠</span></td><td>input bulk</td></tr>
|
||||
<tr><td>C152</td><td>100 nF</td><td>U25 BOOT (pins 1–8)</td><td><span class="d d1">🔴</span></td><td>boot flyer</td></tr>
|
||||
<tr><td>L22</td><td>10 µH SRP1265A</td><td>U25 SW pin</td><td><span class="d d2">🟠</span></td><td>minimal SW copper</td></tr>
|
||||
<tr><td>C153 C154</td><td>47 µF/16 V</td><td>L22 output pad</td><td><span class="d d2">🟠</span></td><td>VEH5V output caps; FB taps here</td></tr>
|
||||
<tr><td>R121 R122</td><td>53.6k · 10.2k</td><td>U25 FB pin, tap at C153</td><td><span class="d d2">🟠</span></td><td>thin trace, away from L22's field</td></tr>
|
||||
<tr><td>R123 C155 C156</td><td>13k · 6.8 nF · 39 pF</td><td>U25 COMP pin</td><td><span class="d d2">🟠</span></td><td>compensation — quiet side, short ground</td></tr>
|
||||
<tr><td>R120</td><td>162k</td><td>U25 RT pin</td><td><span class="d d2">🟠</span></td><td>frequency-set, short ground</td></tr>
|
||||
<tr><td>R124 R125</td><td>UVLO (DNP)</td><td>U25 EN pin</td><td><span class="d d2">🟠</span></td><td>divider lands here if fitted</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">U6 — LTC4040 battery backup (+P3)</td></tr>
|
||||
<tr><td>RS1</td><td>10 mΩ 1%</td><td>U6 sense pins</td><td><span class="d d1">🔴</span></td><td>Kelvin — sense routes from the pad faces</td></tr>
|
||||
<tr><td>L6</td><td>2.2 µH/8 A</td><td>U6 SW pins</td><td><span class="d d1">🔴</span></td><td>charger/boost loop tight</td></tr>
|
||||
<tr><td>C30 C31 C78</td><td>10 µF · 2.2 µF · 220 µF</td><td>U6 VIN, after RS1</td><td><span class="d d2">🟠</span></td><td>VEH5V bank at the input pins</td></tr>
|
||||
<tr><td>C32 C33 C34</td><td>47 µF ×2 · 10 µF</td><td>U6 MAIN5V output / Q7</td><td><span class="d d2">🟠</span></td><td>output bank</td></tr>
|
||||
<tr><td>C35</td><td>22 µF</td><td>U6 BAT pin → P3</td><td><span class="d d2">🟠</span></td><td>on the wide /BAT_PLUS copper</td></tr>
|
||||
<tr><td>Q7</td><td>AO4406A</td><td>U6 gate/PowerPath side</td><td><span class="d d2">🟠</span></td><td>the blackout switch</td></tr>
|
||||
<tr><td>R50</td><td>825R 1%</td><td>U6 PROG pin</td><td><span class="d d1">🔴</span></td><td>precision current-program R</td></tr>
|
||||
<tr><td>R51 R52</td><td>270k · 100k</td><td>U6 PFI pin</td><td><span class="d d2">🟠</span></td><td>power-fail divider</td></tr>
|
||||
<tr><td>R53 R54</td><td>499k · 100k</td><td>U6 FB pin</td><td><span class="d d2">🟠</span></td><td>boost feedback</td></tr>
|
||||
<tr><td>R55</td><td>10k 1%</td><td>U6 NTC pin</td><td><span class="d d2">🟠</span></td><td>pack-thermistor divider (probe enters at P3)</td></tr>
|
||||
<tr><td>JP2 JP3 JP4</td><td>F-straps</td><td>U6 F0/F1/F2 pins</td><td><span class="d d3">🔵</span></td><td>logic straps</td></tr>
|
||||
<tr><td>R56 R57 R58</td><td>100k ×3</td><td>U6 ↔ U16 route</td><td><span class="d d3">🔵</span></td><td>status/enable pulls, anywhere on the line</td></tr>
|
||||
<tr><td>TP1 TP2</td><td>CLPROG · PFO</td><td>U6 block edge</td><td><span class="d d3">🔵</span></td><td>probe access</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">U2 — MP1584 fan buck (+P4)</td></tr>
|
||||
<tr><td>C11</td><td>100 nF</td><td>U2 VIN pin</td><td><span class="d d1">🔴</span></td><td>non-sync input loop (C10/C22 bulk behind)</td></tr>
|
||||
<tr><td>Dbk1</td><td>SS34</td><td>U2 SW + input ground</td><td><span class="d d1">🔴</span></td><td>catch diode — same loop</td></tr>
|
||||
<tr><td>Cbst1</td><td>10 nF</td><td>U2 BOOT–SW</td><td><span class="d d1">🔴</span></td><td>boot flyer</td></tr>
|
||||
<tr><td>L2</td><td>10 µH</td><td>U2 SW</td><td><span class="d d2">🟠</span></td><td>minimal SW copper</td></tr>
|
||||
<tr><td>C23</td><td>22 µF/16 V</td><td>L2 output → P4</td><td><span class="d d2">🟠</span></td><td>5V_FAN output cap</td></tr>
|
||||
<tr><td>R20 R21</td><td>100k · 19.1k</td><td>U2 FB, tap at C23</td><td><span class="d d2">🟠</span></td><td>feedback divider</td></tr>
|
||||
<tr><td>Rcomp1 Ccomp1</td><td>40.2k · 2.2 nF</td><td>U2 COMP pin</td><td><span class="d d2">🟠</span></td><td>compensation</td></tr>
|
||||
<tr><td>Rfreq1</td><td>100k</td><td>U2 FREQ pin</td><td><span class="d d2">🟠</span></td><td>frequency-set</td></tr>
|
||||
<tr><td>Ren1 Ren2</td><td>100k · 20k</td><td>U2 EN pin</td><td><span class="d d3">🔵</span></td><td>enable divider</td></tr>
|
||||
<tr><td>D2</td><td>SS34</td><td>P4 pins</td><td><span class="d d1">🔴</span></td><td>flyback right at the fan jack</td></tr>
|
||||
<tr><td>Q2 Rgs1</td><td>AO3400A · 100k</td><td>P4 return · Rgs1 on Q2 G–S</td><td><span class="d d2">🟠</span></td><td>low-side switch at the jack, G–S resistor glued</td></tr>
|
||||
<tr><td>Q5 Rg1</td><td>MMBT3904 · 100R</td><td>Q2 gate</td><td><span class="d d3">🔵</span></td><td>gate driver stage</td></tr>
|
||||
<tr><td>JP1</td><td>0R</td><td>P4 5V_FAN link</td><td><span class="d d3">🔵</span></td><td>current-measure link</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">U20 — AP64350 modem buck</td></tr>
|
||||
<tr><td>C127 C128</td><td>10 µF · 1 µF</td><td>U20 VIN pin 2</td><td><span class="d d1">🔴</span></td><td>sync input loop — 1 µF closest of all</td></tr>
|
||||
<tr><td>C129</td><td>100 nF</td><td>U20 BOOT–SW</td><td><span class="d d1">🔴</span></td><td>boot flyer</td></tr>
|
||||
<tr><td>L20</td><td>4.7 µH/5 A</td><td>U20 SW</td><td><span class="d d2">🟠</span></td><td>minimal SW copper</td></tr>
|
||||
<tr><td>D21</td><td>PMEG3050EP</td><td>U20 VIN feed</td><td><span class="d d2">🟠</span></td><td>input ORing</td></tr>
|
||||
<tr><td>D20</td><td>SS34</td><td>24 V → U20 input branch</td><td><span class="d d3">🔵</span></td><td>feed diode</td></tr>
|
||||
<tr><td>R110 R111</td><td>75k · 20k</td><td>U20 FB pin</td><td><span class="d d2">🟠</span></td><td>feedback divider</td></tr>
|
||||
<tr><td>R116 C141 C142</td><td>14k · 3.3 nF · 47 pF</td><td>U20 COMP pin</td><td><span class="d d2">🟠</span></td><td>compensation</td></tr>
|
||||
<tr><td>R117</td><td>200k 1%</td><td>U20 RT pin</td><td><span class="d d2">🟠</span></td><td>frequency-set</td></tr>
|
||||
<tr><td>R113</td><td>100k</td><td>U20 EN pin</td><td><span class="d d3">🔵</span></td><td>enable pull</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">U19 — A7670SA modem (+U22 SIM · U23/U24 · K1 · J13)</td></tr>
|
||||
<tr><td>C135 C136</td><td>33 pF · 10 pF</td><td>U19 pins 55/56/57</td><td><span class="d d1">🔴</span></td><td>TX-harmonic filters — the closest of the bank</td></tr>
|
||||
<tr><td>C134 C133 C132</td><td>100 nF → 1 µF → 22 µF</td><td>stepping back from those pins</td><td><span class="d d2">🟠</span></td><td>the gradient</td></tr>
|
||||
<tr><td>C130 C131</td><td>220 µF/10 V ×2</td><td>far end of U19's VBAT bank</td><td><span class="d d3">🔵</span></td><td>≥300 µF burst reservoir</td></tr>
|
||||
<tr><td>D22</td><td>SMAJ5.0A</td><td>at C130/C131</td><td><span class="d d2">🟠</span></td><td>VBAT clamp</td></tr>
|
||||
<tr><td>R112</td><td>1k</td><td>U19 VBAT side</td><td><span class="d d3">🔵</span></td><td>bleed/monitor</td></tr>
|
||||
<tr><td>C125</td><td>2.2 µF</td><td>U19 pin 15 (1V8 out)</td><td><span class="d d1">🔴</span></td><td>LDO output cap</td></tr>
|
||||
<tr><td>U22</td><td>SIM (fp TBD)</td><td>U19 pins 30–33, ≤5 mm</td><td><span class="d d2">🟠</span></td><td>unshielded SIM bus</td></tr>
|
||||
<tr><td>C126</td><td>100 nF</td><td>U22 VCC pad</td><td><span class="d d1">🔴</span></td><td>SIM supply</td></tr>
|
||||
<tr><td>D23 D24 D25</td><td>PESD5V0S1BA</td><td>U22 SIM pads</td><td><span class="d d1">🔴</span></td><td>ESD at the socket, not mid-route</td></tr>
|
||||
<tr><td>U23 U24</td><td>74LVC2T45</td><td>between U19 and U16</td><td><span class="d d3">🔵</span></td><td>level shifters sit on the path</td></tr>
|
||||
<tr><td>C137 C139</td><td>100 nF</td><td>U23/U24 1V8 pins</td><td><span class="d d1">🔴</span></td><td>supply pair, one each</td></tr>
|
||||
<tr><td>C138 C140</td><td>100 nF</td><td>U23/U24 3V3 pins</td><td><span class="d d1">🔴</span></td><td>supply pair, one each</td></tr>
|
||||
<tr><td>Q20 R114</td><td>2N7002 · 100k</td><td>U19 PWRKEY side</td><td><span class="d d3">🔵</span></td><td>open-drain driver</td></tr>
|
||||
<tr><td>Q21 R115</td><td>2N7002 · 100k</td><td>U19 RESET side</td><td><span class="d d3">🔵</span></td><td>open-drain driver</td></tr>
|
||||
<tr><td>R109 Q22 Rmled1 D4G1</td><td>NETLIGHT chain</td><td>U19 netlight pin → LED at a visible spot</td><td><span class="d d3">🔵</span></td><td>status LED driver</td></tr>
|
||||
<tr><td>R106 R107 R108</td><td>100R · 0R ×2</td><td>U23/U24 line ends</td><td><span class="d d3">🔵</span></td><td>UART series elements</td></tr>
|
||||
<tr><td>TP8</td><td>USB_BOOT</td><td>U19 BOOT pin</td><td><span class="d d3">🔵</span></td><td>probe access</td></tr>
|
||||
<tr><td>R118 C146 C147</td><td>0R · DNP pi</td><td>inline in the 50 Ω run, U19 RF pad → J13</td><td><span class="d d1">🔴</span></td><td>matching seats — zero stubs</td></tr>
|
||||
<tr><td>D28</td><td>ESD9L</td><td>J13</td><td><span class="d d1">🔴</span></td><td>at the connector, stub-less</td></tr>
|
||||
<tr><td>D6</td><td>1N4148W</td><td>K1 coil pins</td><td><span class="d d1">🔴</span></td><td>flyback across the coil</td></tr>
|
||||
<tr><td>Q6 R2 C101</td><td>MMBT3904 · 10k · 22 µF</td><td>K1 coil side</td><td><span class="d d2">🟠</span></td><td>relay driver + coil supply cap</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">U18 — ZED-F9P GNSS (+U21 LDO · J12)</td></tr>
|
||||
<tr><td>C121 C122</td><td>100 nF ×2</td><td>U18 VCC pins 33/34, one each</td><td><span class="d d1">🔴</span></td><td>per-pin decouplers</td></tr>
|
||||
<tr><td>C123</td><td>100 nF</td><td>U21 VOUT beside C120</td><td><span class="d d2">🟠</span></td><td>third 100 nF — rail entry, not a third VCC pin</td></tr>
|
||||
<tr><td>Cu4</td><td>100 nF</td><td>U18 pin 36 V_BCKP — on /3V3</td><td><span class="d d1">🔴</span></td><td>only /3V3 cap in the corner; backup rail stays alive when U21 is off</td></tr>
|
||||
<tr><td>C120 C124</td><td>10 µF ×2</td><td>U21 output · U18 VCC entry</td><td><span class="d d1">🔴</span></td><td>LDO stability + local bulk</td></tr>
|
||||
<tr><td>C119</td><td>10 µF</td><td>U21 input pin</td><td><span class="d d1">🔴</span></td><td>LDO input</td></tr>
|
||||
<tr><td>C3 C40</td><td>47 µF · 22 µF</td><td>SW_5V feed near U21</td><td><span class="d d2">🟠</span></td><td>upstream bulk</td></tr>
|
||||
<tr><td>Q1</td><td>AO3401A</td><td>upstream of U21 on SW_5V</td><td><span class="d d3">🔵</span></td><td>rail switch</td></tr>
|
||||
<tr><td>R105</td><td>10k</td><td>U18 pull-up</td><td><span class="d d3">🔵</span></td><td>strap</td></tr>
|
||||
<tr><td>L21 C144 C145</td><td>68 nH · 100 nF · 100 pF</td><td>bias-tee tap on the 50 Ω run</td><td><span class="d d1">🔴</span></td><td>antenna supply injection</td></tr>
|
||||
<tr><td>C143</td><td>100 nF RF</td><td>inline, L21 tap → J12</td><td><span class="d d1">🔴</span></td><td>DC block</td></tr>
|
||||
<tr><td>D27</td><td>ESD9L ≤0.5 pF</td><td>J12</td><td><span class="d d1">🔴</span></td><td>at the connector, stub-less</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">U16 — STM32 MCU (+Y3/Y4 · J11/J9 USB · sense jacks)</td></tr>
|
||||
<tr><td>C111</td><td>4.7 µF</td><td>U16 VCAP1 pin</td><td><span class="d d1">🔴</span></td><td>core regulator — non-negotiable</td></tr>
|
||||
<tr><td>R104</td><td>10R</td><td>U16 VDDA feed</td><td><span class="d d1">🔴</span></td><td>analog supply filter element</td></tr>
|
||||
<tr><td>C109 C112</td><td>100 nF · 1 µF</td><td>U16 VDDA pin, behind R104</td><td><span class="d d1">🔴</span></td><td>analog decoupling</td></tr>
|
||||
<tr><td>C105 C106 C107 C108</td><td>100 nF ×4</td><td>one per U16 VDD pin</td><td><span class="d d1">🔴</span></td><td>the netlist pass parked C106–C108 near U3 — they are U16's, bring them back</td></tr>
|
||||
<tr><td>C110</td><td>4.7 µF</td><td>U16 VDD bulk</td><td><span class="d d2">🟠</span></td><td>local reservoir</td></tr>
|
||||
<tr><td>C104</td><td>100 nF</td><td>U16 NRST pin</td><td><span class="d d1">🔴</span></td><td>the P6 jack just routes to it</td></tr>
|
||||
<tr><td>Y3 C113 C114</td><td>25 MHz · 15 pF</td><td>U16 OSC pins</td><td><span class="d d1">🔴</span></td><td>tight triangle, local ground</td></tr>
|
||||
<tr><td>Y4 C115 C116</td><td>32.768 kHz · 12 pF</td><td>U16 OSC32 pins</td><td><span class="d d1">🔴</span></td><td>tighter still — high-impedance osc</td></tr>
|
||||
<tr><td>R5 R6 C5</td><td>10k ×2 · 100 nF</td><td>U16 BAT_SENSE ADC pin</td><td><span class="d d2">🟠</span></td><td>divider + filter at the pin</td></tr>
|
||||
<tr><td>R7 R8 C7</td><td>10k ×2 · 100 nF</td><td>U16 5V_SENSE ADC pin</td><td><span class="d d2">🟠</span></td><td>divider + filter at the pin</td></tr>
|
||||
<tr><td>Rig2 Rigb1 C9 D5</td><td>22k · 3.3k · 100 nF · BAT54</td><td>U16 IGN_SENSE ADC pin</td><td><span class="d d2">🟠</span></td><td>divider + filter + clamp at the pin</td></tr>
|
||||
<tr><td>R42 C24</td><td>10k 1% · 100 nF</td><td>U16 NTC1 ADC pin — P7 is just the jack</td><td><span class="d d2">🟠</span></td><td>the probe wire filters at the pin</td></tr>
|
||||
<tr><td>R126 C157</td><td>10k 1% · 100 nF</td><td>U16 NTC2 ADC pin (PC4) — P8 is just the jack</td><td><span class="d d2">🟠</span></td><td>same rule</td></tr>
|
||||
<tr><td>R98 R99</td><td>10k ×2</td><td>U16 BOOT straps</td><td><span class="d d3">🔵</span></td><td>anywhere in the block</td></tr>
|
||||
<tr><td>Rdfu1</td><td>22k</td><td>U16 USART1_RX</td><td><span class="d d3">🔵</span></td><td>series element</td></tr>
|
||||
<tr><td>TP3 TP4 TP5</td><td>SWDIO · SWCLK · NRST</td><td>U16 side / P6 side</td><td><span class="d d3">🔵</span></td><td>probe access</td></tr>
|
||||
<tr><td>R1 R40 R56</td><td>1k · 1k · 100k</td><td>control lines U16 → power blocks</td><td><span class="d d3">🔵</span></td><td>anywhere along the route</td></tr>
|
||||
<tr><td>D17</td><td>LED (blue)</td><td>U16 PC13 vicinity, visible</td><td><span class="d d3">🔵</span></td><td>heartbeat LED</td></tr>
|
||||
<tr><td>Q4 Rled1</td><td>AO3400A · 10k</td><td>near the P9/P10 edge</td><td><span class="d d3">🔵</span></td><td>external-LED driver</td></tr>
|
||||
<tr><td>D13</td><td>SS34</td><td>J11 VBUS</td><td><span class="d d2">🟠</span></td><td>VBUS ORing</td></tr>
|
||||
<tr><td>D14 D15 D16</td><td>PESD5V0S1BA</td><td>J11 pads (DP/DM/VBUS)</td><td><span class="d d1">🔴</span></td><td>ESD at the jack — never mid-route</td></tr>
|
||||
<tr><td>R100 R101</td><td>5.1k</td><td>J11 CC pads</td><td><span class="d d1">🔴</span></td><td>USB-C sink ID</td></tr>
|
||||
<tr><td>Rcc1 Rcc2</td><td>5.1k</td><td>J9 CC pads</td><td><span class="d d1">🔴</span></td><td>USB-C sink ID</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">U11 — W5500 Ethernet (+U12 buck · Y1 · J10)</td></tr>
|
||||
<tr><td>C90</td><td>10 µF</td><td>U11 TOCAP pin</td><td><span class="d d1">🔴</span></td><td>internal-regulator cap</td></tr>
|
||||
<tr><td>C91</td><td>4.7 µF</td><td>U11 1V2 pin</td><td><span class="d d1">🔴</span></td><td>core rail</td></tr>
|
||||
<tr><td>C92 C93 C98</td><td>100 nF ×3</td><td>U11 VCC pins, one each</td><td><span class="d d1">🔴</span></td><td>per-pin decouplers</td></tr>
|
||||
<tr><td>C94 C102</td><td>10 µF · 22 µF</td><td>U11 supply entry</td><td><span class="d d2">🟠</span></td><td>local bulk</td></tr>
|
||||
<tr><td>Y1 C95 C96</td><td>25 MHz · 18 pF</td><td>U11 XI/XO pins</td><td><span class="d d1">🔴</span></td><td>tight triangle</td></tr>
|
||||
<tr><td>R83</td><td>12.4k 1%</td><td>U11 RSET pin</td><td><span class="d d1">🔴</span></td><td>precision bias — short, clean ground</td></tr>
|
||||
<tr><td>R84</td><td>10k</td><td>U11 PMODE</td><td><span class="d d3">🔵</span></td><td>strap</td></tr>
|
||||
<tr><td>R92 R93</td><td>49.9R 1%</td><td>U11 TX pins → J10</td><td><span class="d d1">🔴</span></td><td>line terminations</td></tr>
|
||||
<tr><td>R94 R95 C97</td><td>49.9R ×2 · 6.8 nF</td><td>J10 center taps</td><td><span class="d d1">🔴</span></td><td>Bob Smith / RCT network at the magjack</td></tr>
|
||||
<tr><td>C103</td><td>100 µF/6.3 V</td><td>J10 3V3 feed</td><td><span class="d d2">🟠</span></td><td>magnetics supply bulk</td></tr>
|
||||
<tr><td>R96 R97</td><td>330R</td><td>J10 LED pins</td><td><span class="d d3">🔵</span></td><td>link/act LEDs</td></tr>
|
||||
<tr><td>D11</td><td>SS34</td><td>U12 SW + input ground</td><td><span class="d d1">🔴</span></td><td>ETH buck catch diode</td></tr>
|
||||
<tr><td>C100</td><td>10 nF</td><td>U12 BOOT</td><td><span class="d d1">🔴</span></td><td>boot flyer</td></tr>
|
||||
<tr><td>L8</td><td>10 µH/2 A</td><td>U12 SW</td><td><span class="d d2">🟠</span></td><td>minimal SW copper</td></tr>
|
||||
<tr><td>R85 R86 R87 R88</td><td>FREQ · COMP · FB</td><td>U12 pins</td><td><span class="d d2">🟠</span></td><td>housekeeping at the IC</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">U17 — AMS1117 3V3 LDO</td></tr>
|
||||
<tr><td>C117</td><td>10 µF</td><td>U17 IN pin</td><td><span class="d d1">🔴</span></td><td>LDO input</td></tr>
|
||||
<tr><td>C118</td><td>22 µF/16 V</td><td>U17 OUT pin</td><td><span class="d d1">🔴</span></td><td>LDO output / 3V3 bulk</td></tr>
|
||||
<tr><td>D12</td><td>SS34</td><td>U17 input feed</td><td><span class="d d2">🟠</span></td><td>feed ORing</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">Serial block — U15 RS232 · U10 UART · U14 RS485 · U13 expander</td></tr>
|
||||
<tr><td>C85 C86 C87 C88</td><td>100 nF ×4</td><td>U15 pump pins, hard against the IC</td><td><span class="d d1">🔴</span></td><td>flying caps carry the pump current</td></tr>
|
||||
<tr><td>C84</td><td>100 nF</td><td>U15 VCC pin</td><td><span class="d d1">🔴</span></td><td>supply</td></tr>
|
||||
<tr><td>Y2 C82 C83</td><td>1.8432 MHz · 22 pF</td><td>U10 XTAL pins</td><td><span class="d d1">🔴</span></td><td>tight triangle</td></tr>
|
||||
<tr><td>R30 R31</td><td>4.7k</td><td>U10 side of the I2C bus</td><td><span class="d d3">🔵</span></td><td>bus pull-ups</td></tr>
|
||||
<tr><td>R80 R81</td><td>10k</td><td>U10 RST/IRQ</td><td><span class="d d3">🔵</span></td><td>pulls</td></tr>
|
||||
<tr><td>C81 C89</td><td>100 nF ×2</td><td>U14 VCC (one is spare)</td><td><span class="d d1">🔴</span></td><td>supply</td></tr>
|
||||
<tr><td>R82 JP5</td><td>120R · strap</td><td>P11 RS485 jack</td><td><span class="d d2">🟠</span></td><td>termination lives at the connector</td></tr>
|
||||
<tr><td>C80</td><td>100 nF</td><td>U13 VCC pin</td><td><span class="d d1">🔴</span></td><td>supply</td></tr>
|
||||
<tr><td>RB1 RB2 RB3 RB4<br>DB1 DB2 DB3 DB4</td><td>120R + LED ×4</td><td>U13 outputs → LEDs at the visible edge</td><td><span class="d d3">🔵</span></td><td>the netlist pass parked DB1–DB4 at U25 — they belong with U13</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">U26 — SC7A20 accelerometer (at MH6)</td></tr>
|
||||
<tr><td>C158 C159</td><td>100 nF ×2</td><td>U26 VDD/VDDIO pins</td><td><span class="d d1">🔴</span></td><td>one per supply pin</td></tr>
|
||||
<tr><td>C160</td><td>10 µF</td><td>U26 bulk</td><td><span class="d d2">🟠</span></td><td>local reservoir; U26 itself ≤10 mm from MH6</td></tr>
|
||||
|
||||
<tr class="own"><td colspan="5">Panel · sensors · leftovers</td></tr>
|
||||
<tr><td>Cu3</td><td>100 nF</td><td>U3 SHT40 VDD pin</td><td><span class="d d1">🔴</span></td><td>sensor supply</td></tr>
|
||||
<tr><td>Cu4</td><td>100 nF</td><td>reassigned → U18 pin 36 V_BCKP</td><td><span class="d d1">🔴</span></td><td>see the GNSS group — it is already on /3V3–GND, so a board move is all it takes</td></tr>
|
||||
<tr><td>C99</td><td>2.2 nF</td><td>U17/U12 area rail bypass</td><td><span class="d d3">🔵</span></td><td>verify its role in the sch before final spot</td></tr>
|
||||
<tr><td>R41</td><td>10k</td><td>U3/U16 I2C area</td><td><span class="d d3">🔵</span></td><td>pull-up strap</td></tr>
|
||||
<tr><td>R3 D1</td><td>120R · LED</td><td>P9 pins</td><td><span class="d d3">🔵</span></td><td>R3 at the jack</td></tr>
|
||||
<tr><td>R89 R90 R91</td><td>120R ×3</td><td>P10 pins</td><td><span class="d d2">🟠</span></td><td>series at the jack — the wire radiates otherwise</td></tr>
|
||||
<tr><td>D18 R102 R103</td><td>LED (green) · 1k ×2</td><td>3V3 rail, visible spot</td><td><span class="d d3">🔵</span></td><td>power LED</td></tr>
|
||||
<tr><td>TP6 TP7</td><td>GND · 3V3</td><td>anywhere reachable</td><td><span class="d d3">🔵</span></td><td>probe access</td></tr>
|
||||
</table></div>
|
||||
<div class="note"><b>Rail 100 nF rule, restated:</b> every plain 100 nF above pairs with exactly one IC power pin and moves with that IC forever. If you relocate an IC during fine-tuning, its 🔴 rows move in the same drag.</div>
|
||||
|
||||
<h2><span class="no">§9</span>Separation rules</h2>
|
||||
<div class="tblwrap"><table>
|
||||
<tr><th>Keep apart</th><th>Min</th><th>Why</th></tr>
|
||||
<tr><td>GNSS island ↔ any switcher L / SW node</td><td>25 mm</td><td>−167 dBm receiver vs. dV/dt fields</td></tr>
|
||||
@ -198,7 +385,7 @@ a{color:var(--plane)}
|
||||
<tr><td>U26 accel ↔ mounting hole</td><td>≤ 10 mm (close!)</td><td>chassis coupling, not board flex</td></tr>
|
||||
</table></div>
|
||||
|
||||
<h2><span class="no">§9</span>Order of work from here</h2>
|
||||
<h2><span class="no">§10</span>Order of work from here</h2>
|
||||
<ol class="steps">
|
||||
<li><b>Update PCB from Schematic</b> (NTC2 re-net), then fine-tune inside the §1 regions. Field wiring now enters mostly along the north edge + P1 at the SE corner — keep each connector beside its block, and its TVS/filter parts right at the jack, so cable common-mode currents stay off the board core.</li>
|
||||
<li><b>Say the word and I re-add the four zones</b> — F.Cu GND pour, In1 GND (unbroken, especially under both RF runs and the crystals), In2 3V3, B.Cu GND — plus a stitching-via plan: 5 mm grid around RF, via fence along the board edge.</li>
|
||||
@ -207,5 +394,5 @@ a{color:var(--plane)}
|
||||
<li><b>Bench items carried forward:</b> measure U21's 3V3_GNSS rise (F9P ramp window), verify U25's EP against the TI DDA drawing, and the DzG1 jumper check on the fabbed v5.5 boards.</li>
|
||||
</ol>
|
||||
|
||||
<p class="sub" style="margin-top:36px">EinarBoard HBOX v6 · Helgen · updated 03-Sep-2026 to the clustered layout (commits <code>ba70f62</code> · <code>c7d2552</code>).</p>
|
||||
<p class="sub" style="margin-top:36px">EinarBoard HBOX v6 · Helgen · updated 05-Sep-2026: U18 V_BCKP (pin 36, /3V3) gets Cu4; C123 clarified as U21-output cap; §8 rows corrected.</p>
|
||||
</div>
|
||||
|
||||
@ -0,0 +1,138 @@
|
||||
---
|
||||
tags: [project-drogheda, hardware, bom, cost, power]
|
||||
project: Project Drogheda
|
||||
author: Helgen CTO
|
||||
date: 2026-09-09
|
||||
status: Draft — first-pass estimate
|
||||
---
|
||||
|
||||
# 5 V source: on-board (V6 / U25) vs external Mean Well SD-15B-05 (V5)
|
||||
|
||||
> **Bottom line:** the on-board 24→5 V block already captured in V6 costs
|
||||
> **≈ US$2.2 / MX$37 per board** in parts. The external Mean Well it replaces costs
|
||||
> **≈ MX$330 per unit** all-in as currently purchased. **Net saving ≈ MX$290/unit**
|
||||
> (≈ MX$8,700 at 30 units, ≈ MX$29,000 at 100). The money is not the interesting part —
|
||||
> the isolation loss and the 3 A → 3.5 A headroom are.
|
||||
|
||||
Prices: LCSC/JLCPCB live database (2026-09-09) · FX **USD 1 = MXN 16.91**.
|
||||
|
||||
---
|
||||
|
||||
## 1. What each version actually does
|
||||
|
||||
| | **V5 (as built)** | **V6 (as captured in the schematic)** |
|
||||
|---|---|---|
|
||||
| 24→5 V | **External** Mean Well SD-15B-05 → `P2` (JST 2-pin) → `VEH5V` | **On-board** `U25` TPS54360B: `VIN_PROT` → `VEH5V` |
|
||||
| Rating | 5 V / **3 A** isolated (1.5 kVDC) | 5 V / **3.5 A**, non-isolated, 60 V input |
|
||||
| Entry chain | `Q10` (IRFR5305) + `D10` (SMBJ33A) → fan buck only | `F2 → Q23 → D32 (SMCJ33A) → C149/C150 → U25 → D34/L22 → C153/C154` |
|
||||
| Extra parts on board | `P2` connector | 15 fitted + 2 DNP (`R124`/`R125`) |
|
||||
|
||||
V6 keeps the fan buck (`U2`) and the 3V3_ETH buck (`U12`); `U7` was deleted. Neither
|
||||
ever made the main rail — this comparison is only about the `VEH5V` source.
|
||||
|
||||
---
|
||||
|
||||
## 2. On-board block — BOM cost per board
|
||||
|
||||
`U25` TPS54360B · `L22` SRP1265A-100M · `D34` B560C · `D32` SMCJ33A · `C149`/`C150`
|
||||
2.2 µF/100 V · `C151` 100 µF/50 V · `C152` 100 nF · `C153`/`C154` 47 µF/16 V ·
|
||||
`C155`/`C156` · `R120`–`R123` — plus the entry chain `F2` · `Q23` · `D33` · `R119`.
|
||||
|
||||
| Line | 30 boards | 100 boards | 500 boards |
|
||||
|---|---:|---:|---:|
|
||||
| `U25` TPS54360BDDAR (C524806) | $0.487 | $0.428 | $0.419 |
|
||||
| `L22` SRP1265A-100M 10 µH/10 A (C840531) | $0.639 | $0.554 | $0.504 |
|
||||
| `D34` B560C 5 A/60 V (C85100) | $0.220 | $0.179 | $0.158 |
|
||||
| `D32` SMCJ33A TVS (C699039) | $0.114 | $0.091 | $0.079 |
|
||||
| `C149`/`C150` 2.2 µF/100 V 1210 ×2 † | $0.180 | $0.180 | $0.160 |
|
||||
| `C151` 100 µF/50 V elco (C134502) | $0.149 | $0.149 | $0.149 |
|
||||
| `C153`/`C154` 47 µF/16 V 1210 ×2 (C5440143) | $0.185 | $0.185 | $0.127 |
|
||||
| `C152`, `C155`, `C156`, `R120`–`R123` | $0.022 | $0.022 | $0.022 |
|
||||
| **Buck subtotal** | **$1.996** | **$1.788** | **$1.618** |
|
||||
| `Q23` IRFR5305 (C2624) | $0.262 | $0.227 | $0.193 |
|
||||
| `F2` 2 A/1812 fuse †, `D33` BZX84C15, `R119` | $0.144 | $0.144 | $0.144 |
|
||||
| **Entry subtotal** | **$0.406** | **$0.371** | **$0.337** |
|
||||
| **Parts / board** | **$2.40** | **$2.16** | **$1.96** |
|
||||
| JLC extended-part setup (7 new uniques × $3, amortised) | $0.70 | $0.21 | $0.04 |
|
||||
| SMT placement (~50 joints) | $0.10 | $0.09 | $0.09 |
|
||||
| **All-in / board** | **$3.20 · MX$54** | **$2.46 · MX$42** | **$2.09 · MX$35** |
|
||||
|
||||
† `C149`/`C150` and `F2` have no LCSC part pinned yet — estimated at $0.09 and $0.12.
|
||||
Board outline stays 140×100, so **the block costs zero PCB area money**.
|
||||
|
||||
---
|
||||
|
||||
## 3. External Mean Well — cost per unit
|
||||
|
||||
| Item | MXN | Source |
|
||||
|---|---:|---|
|
||||
| Mean Well SD-15B-05 | **300** | `BOM-master.md` §1 item 12 (as purchased locally) |
|
||||
| — same part, direct import | *189–200* | Mouser $11.15 / Arrow $11.85 @100 |
|
||||
| DC PSU bracket (ASA print) | 20 | `BOM-master.md` §1 item 3 |
|
||||
| `P2` JST-XH + housing + crimps + wire | ~12 | est. |
|
||||
| **Total** | **≈ 332** *(≈ 221 if imported direct)* | |
|
||||
|
||||
Plus ~5 min/unit of mounting and wiring labour, and one more connector in the
|
||||
vibration path — `P2` is exactly the class of joint the RCA blamed.
|
||||
|
||||
---
|
||||
|
||||
## 4. Net
|
||||
|
||||
| Volume | External (local price) | On-board | **Saving** |
|
||||
|---|---:|---:|---:|
|
||||
| per unit | MX$332 | MX$42 | **MX$290** |
|
||||
| 30 units | MX$9,960 | MX$1,260 | **MX$8,700** |
|
||||
| 100 units | MX$33,200 | MX$4,200 | **MX$29,000** |
|
||||
|
||||
Against best-case direct import (MX$221) the saving is still **≈ MX$180/unit**.
|
||||
|
||||
---
|
||||
|
||||
## 5. What actually decides this (not the money)
|
||||
|
||||
**For on-board:**
|
||||
|
||||
- **3 A → 3.5 A.** The 10-Ago boot-loop was the SD-15B's 3 A ceiling. It also makes the
|
||||
standing `RS1` errata (3.12 A input limit sitting *above* a 3 A supply) go away by itself.
|
||||
- One fewer sub-assembly, one fewer connector, no import lead time on a PSU.
|
||||
|
||||
**Against on-board:**
|
||||
|
||||
- **Isolation is lost.** SD-15B-05 is 1.5 kVDC isolated; TPS54360B is not. HBOX ground
|
||||
becomes the cabinet 24 V return. The ignition already shares that return — worth a
|
||||
deliberate look at the ground topology before this is locked.
|
||||
- The EMC burden moves onto our board. The copper plan already calls `U25`'s input loop
|
||||
the loudest on the PCB; that stops being Mean Well's problem.
|
||||
- No field-replaceable part. Today a dead PSU is a 10-minute swap; after this it is a board.
|
||||
|
||||
---
|
||||
|
||||
## 6. 🔴 Side finding — the MP1584s cost more than this whole question
|
||||
|
||||
Genuine `MP1584EN-LF-Z` (C15051) is **$2.21 @100** on LCSC. V6 carries two (`U2`, `U12`)
|
||||
= **$4.41 / MX$75 per board**, against **$0.43** for the TPS54360B or **$0.58** for the
|
||||
AP64350 already qualified as `U20`.
|
||||
|
||||
Re-speccing those two rails onto a part already in the BOM saves **≈ $3.5 / MX$59 per
|
||||
board** — more than the entire 5 V-source saving — and it also retires EMC findings 3 and 4,
|
||||
which named the MP1584s directly. Worth a separate decision.
|
||||
|
||||
---
|
||||
|
||||
## 7. Battery — LiPo vs Li-ion, first pass
|
||||
|
||||
| | Energy | Price | **MXN / Wh** |
|
||||
|---|---:|---:|---:|
|
||||
| **Li-ion** Hyvel 18650 1S4P (current pack) | ~43 Wh | MX$204 | **≈ 4.7** |
|
||||
| **LiPo** 2000 mAh 1S, SparkFun @ Sandorobotics | 7.4 Wh | MX$270 | **≈ 36** |
|
||||
| **LiPo** 2000 mAh 1S, generic (indicative) | 7.4 Wh | ~MX$90–160 | **≈ 12–22** |
|
||||
|
||||
To reach today's 43 Wh with 2000 mAh pouches you need **6 in parallel**:
|
||||
MX$540–1,620 against MX$204. Li-ion 18650 is **3–8× cheaper per Wh**, and it is also the
|
||||
better cell for a box that runs hot — pouch cells swell, and heat is this product's
|
||||
standing failure mode.
|
||||
|
||||
LiPo buys thickness and form factor, nothing else. Treat the 2000 mAh cells as bench
|
||||
hardware. ⚠ The generic LiPo row is indicative — MercadoLibre/Amazon MX would not serve
|
||||
prices to an automated fetch; get one real quote before this line is used in a decision.
|
||||
@ -0,0 +1,194 @@
|
||||
---
|
||||
tags: [project-drogheda, firmware, power, battery, thermal]
|
||||
project: Project Drogheda
|
||||
author: Helgen CTO
|
||||
date: 2026-09-09
|
||||
status: Draft — design proposal
|
||||
---
|
||||
|
||||
# Backup mode: duty-cycled low power, and what it does to the charging problem
|
||||
|
||||
> **Bottom line:** yes, do the duty-cycle. But **the wake interval barely matters — the
|
||||
> sleep floor is everything.** 10 min vs 60 min changes runtime by 2 %. Dropping the
|
||||
> sleeping draw from 150 mW to 20 mW changes it by **5.5×**. And the payoff is bigger than
|
||||
> runtime: at ~1.5 Wh/day the pack needs **~10 minutes of charging a day**, which the
|
||||
> narrow cool window we already have can supply. **The duty-cycle largely dissolves the
|
||||
> temperature problem** — that is the real reason to do it.
|
||||
|
||||
---
|
||||
|
||||
## 1. "Can't we just move the charge temperature?"
|
||||
|
||||
The **threshold** is ours (`RNTB`). The **limit** is the cell's. Charging an NMC/LCO 18650
|
||||
at 55 °C is not a tuning choice — it is accelerated SEI growth, gas generation and a safety
|
||||
liability inside a sealed IP67 box in full sun. Not something to ship on 30 units.
|
||||
|
||||
What you *can* legitimately buy, without changing the cell:
|
||||
|
||||
- **Lower the float.** Damage rate is temperature × voltage × time. You are already at
|
||||
4.00 V rather than 4.20 V, which is most of the win. `JP3`/`JP4` → F1=0/F0=0 gives
|
||||
**3.95 V** and a little more margin. That justifies nudging the hot pause to maybe
|
||||
**48–50 °C** *if the cell's datasheet supports it*. A few degrees, not fifteen.
|
||||
- Anything beyond that needs a cell rated for it — see the high-temp LFP note.
|
||||
|
||||
**But read §3 before deciding any of this.**
|
||||
|
||||
---
|
||||
|
||||
## 2. Duty-cycled backup — the numbers
|
||||
|
||||
Pack ~43 Wh, 85 % usable = **36.5 Wh**. Boost efficiency 88 %.
|
||||
|
||||
**Today, continuous:** ~2.5 W at the 5 V rail → **~13 h**; with the fan running, ~8 h.
|
||||
|
||||
**Duty-cycled**, wake = 10 s at 1.5 W (modem held in PSM, no re-attach):
|
||||
|
||||
| sleep floor | 10 min | 30 min | 60 min |
|
||||
|---|---:|---:|---:|
|
||||
| 150 mW | 7.7 d | 8.5 d | 8.7 d |
|
||||
| 100 mW | 10.7 d | 12.4 d | 12.9 d |
|
||||
| 50 mW | 17.9 d | **23.0 d** | 24.7 d |
|
||||
| 20 mW | 29.8 d | **47.3 d** | 55.5 d |
|
||||
| 10 mW | 38.3 d | 73.1 d | 94.6 d |
|
||||
|
||||
If the carrier will not give us PSM and every wake is a full LTE re-attach (~35 s):
|
||||
|
||||
| sleep floor | 10 min | 30 min | 60 min |
|
||||
|---|---:|---:|---:|
|
||||
| 150 mW | 5.6 d | 7.5 d | 8.1 d |
|
||||
| 50 mW | 9.7 d | 16.9 d | 20.8 d |
|
||||
| 20 mW | 12.5 d | 27.3 d | **38.8 d** |
|
||||
|
||||
**Read the rows, not the columns.** Your 10-minute instinct costs 20–50 % against 30 min
|
||||
and buys the operator nothing they need. Go **30 min**, and spend the effort on the floor.
|
||||
|
||||
---
|
||||
|
||||
## 3. 🔴 The part that matters most — it also fixes the charging
|
||||
|
||||
| Duty cycle | Daily energy | Charging needed at 2.42 A |
|
||||
|---|---:|---:|
|
||||
| 30 min wake, 50 mW sleep | 1.59 Wh/day | **~10 min/day** |
|
||||
| 30 min wake, 20 mW sleep | 0.77 Wh/day | **~5 min/day** |
|
||||
| 10 min wake, 100 mW sleep | 3.41 Wh/day | ~22 min/day |
|
||||
|
||||
Today the pack must replace ~30 Wh after a long outage and we give it a charge window that
|
||||
closes at 42 °C. At **1.6 Wh/day** you need *ten minutes* of cool weather. Port nights drop
|
||||
well below 40 °C — the existing window is already enough.
|
||||
|
||||
So the ordering changes: **do the firmware work first.** It is free, it ships to the
|
||||
installed fleet over the existing update path, and it may retire the cell question entirely.
|
||||
Keep the high-temp LFP option open — but stop treating it as the first move.
|
||||
|
||||
It also means the 43 Wh pack is oversized. At 1.6 Wh/day a **single 12 Wh cell gives 6+
|
||||
days** — cheaper, cooler, smaller, easier to keep topped up.
|
||||
|
||||
---
|
||||
|
||||
## 4. What actually sets the sleep floor
|
||||
|
||||
Ranked by what I expect to find on the bench. **All of these need measuring, not assuming.**
|
||||
|
||||
| Suspect | Est. | Fix |
|
||||
|---|---:|---|
|
||||
| **`U17` AMS1117-3.3** — quiescent 5 mA typ / 11 mA max, and it burns 1.7 V × I as heat | **25–55 mW** | Swap for a low-Iq LDO. `U21` (AP2112K, 55 µA) is already in the BOM; a TPS7A02-class part is ~1 µA. **This is probably the single biggest item and it is a one-part change** |
|
||||
| **`K1` coil** — ~30 mA from SYS5V while the MCU is inserted | **150 mW** | See §5 |
|
||||
| **LTC4040 boost** at very light load — light-load efficiency and its own Iq | 10–40 mW? | Measure. If bad, this caps everything and needs a rethink |
|
||||
| Battery gauge LEDs `PB12–15`, `D17`, `D18`, `DB1–4`, `D4G1` | 50–150 mW | All off in backup, or one 50 ms blink per wake |
|
||||
| `U12` MP1584 → `/3V3_ETH` + `W5500` (~130 mA) | 400+ mW | Ethernet is useless on battery — disable `U12`, hold `W5500` in reset |
|
||||
| `MAX3232` charge pump, `SP3485`, `SC16IS752` | 5–15 mW | Shutdown pins / disable |
|
||||
| `U18` `V_BCKP` | **0.15 mW** | ✅ already right — see §6 |
|
||||
| MCU in STOP + LSE RTC | 0.1–0.2 mW | Achievable; today it is ~165 mW because `loop()` never stops |
|
||||
|
||||
⚠ **Today's `SLEEP` state is not a low-power state.** It cuts `PWR_CTRL` and then keeps
|
||||
spinning `loop()` at 84 MHz with Serial, I²C polling and the gauge alive. Real STOP-mode
|
||||
+ RTC wake is the substantive firmware change here. `Y4` (32.768 kHz) is on the board, so
|
||||
LSE-driven RTC wake is available.
|
||||
|
||||
---
|
||||
|
||||
## 5. `K1` — reverse the earlier call
|
||||
|
||||
The Firmware v3.1 brief said: *"bobina ~30 mA de SYS5V … se queda insertado; 30 mA contra
|
||||
12 Ah es ruido."* That was correct for a 13-hour continuous budget. **It is wrong for a
|
||||
duty-cycled one** — 150 mW against a 20–50 mW target is 3–7× the entire rest of the floor,
|
||||
and it alone would cap you at 8 days no matter what else you fix.
|
||||
|
||||
**New rule: `BYP_CTRL` low between wakes, high only during the TX window.** 150 mW × 10 s
|
||||
per 30 min = 0.8 mW average — it disappears. The fail-safe semantics are unchanged
|
||||
(de-energised = F9P→modem direct), and between wakes there is nothing to inject anyway.
|
||||
|
||||
Longer term, a **latching relay** (G6K-class, pulse to switch, zero hold) removes the
|
||||
question permanently. Worth pricing for the v6 BOM.
|
||||
|
||||
---
|
||||
|
||||
## 6. Don't chase position — you already have the right parts
|
||||
|
||||
The machine is **parked**. Its position does not change during an outage, so re-acquiring
|
||||
a fix every wake is pure waste.
|
||||
|
||||
- `V_BCKP` is already wired (`/3V3` via 1 kΩ + Schottky, 45 µA) and keeps ephemeris, so
|
||||
when you *do* want a fix it is a hot start (~2–5 s), not a 30 s cold start. Good design,
|
||||
already done.
|
||||
- Report the **stored** position with a `pwr=BATT` flag and a staleness marker. Take a real
|
||||
fix only every **N-th** wake (e.g. every 2 h) as an anti-theft check.
|
||||
- **`U26` (SC7A20 accelerometer) is on the v6 board.** Wire its interrupt to a wake-capable
|
||||
pin and you get motion-triggered wake for free: asleep while the machine is still, awake
|
||||
within a second if someone moves it. That is strictly better than polling GNSS.
|
||||
⚠ `U26` does not appear in any of the v6 briefs — confirm what it was placed for and that
|
||||
its INT line reaches an EXTI/wake pin before counting on this.
|
||||
|
||||
---
|
||||
|
||||
## 7. Modem: PSM before power-cycling
|
||||
|
||||
Power-cycling the modem every 10 minutes means paying a full network attach every 10 minutes
|
||||
— 20–30 s at 100–300 mA with 2 A bursts. **3GPP PSM keeps the module registered while it
|
||||
sleeps at tens of µA**, with no re-attach cost; eDRX is the lighter variant.
|
||||
|
||||
- The A7670SA (Cat-1bis) supports PSM. **Whether you get it is a Telcel question**, not a
|
||||
module question — it depends on the APN/plan and the network granting the requested TAU.
|
||||
**Verify this early; the whole table in §2 hinges on which column you land in.**
|
||||
- Fall back to `MODEM_PWR_EN` power-cycling only if PSM is refused — and then stretch the
|
||||
interval to 30–60 min so the attach cost amortises.
|
||||
|
||||
⚠ **Inrush risk.** You already tripped the LTC4040 `PFI` at 4.60 V on LTE inrush with no
|
||||
pack connected. Duty-cycling means taking that 2 A / 7.6 W burst **repeatedly, at low SoC,
|
||||
on a hot or aged pack**. Hold the ≥ 470 µF modem bulk, and bench the worst case: coldest
|
||||
SoC × hottest pack × attach burst. This is the most likely way the design fails in the field.
|
||||
|
||||
---
|
||||
|
||||
## 8. Proposed state machine
|
||||
|
||||
```
|
||||
RUNNING ──(5V_SENSE PA4 falls, debounced)──► BACKUP_ENTRY
|
||||
BACKUP_ENTRY: hot-start fix (or use last) → $PHLG{pwr=BATT, evt=POWER_LOSS} → TX now
|
||||
(operators care most in the first minute — do not make them wait 30)
|
||||
→ BACKUP_SLEEP: PWR_CTRL low · MODEM→PSM · BYP_CTRL low · U12/W5500 off
|
||||
transceivers shutdown · LEDs off · fan off · MCU STOP + RTC(T)
|
||||
→ wake on RTC(T) or accelerometer INT or PA4 rising:
|
||||
read vbat/tbat → if vbat < BAT_CRITICAL: TX final "shutting down" → deep off
|
||||
else: BYP_CTRL high → modem wake → TX heartbeat → back to BACKUP_SLEEP
|
||||
→ PA4 rising: full wake, resume RUNNING
|
||||
```
|
||||
|
||||
**Adaptive cadence** (cheap, and better product behaviour): 15 min for the first hour,
|
||||
30 min to 24 h, 60 min after. Include the **drain rate** in `$PHLG` so ops can see how long
|
||||
the unit has left rather than guessing.
|
||||
|
||||
**Fan: off in backup, full stop.** A 5 V fan is 0.75–1.25 W — it would consume the entire
|
||||
budget in hours. If the box is too hot to sit idle without a fan, that is a thermal problem,
|
||||
not a power-management one.
|
||||
|
||||
---
|
||||
|
||||
## 9. Do these three first
|
||||
|
||||
1. **Measure the sleeping current** on a v5.5 board with `PWR_CTRL` low, MCU in STOP, and
|
||||
the loads in §4 disabled one at a time. That single number decides everything in §2.
|
||||
2. **Ask Telcel about PSM/eDRX** on the current APN and plan. It sets which table applies.
|
||||
3. **Pull the `tbat`/`tntc` fleet histogram** — with §3's 10 min/day figure in hand, the
|
||||
question is no longer "is it ever cool enough" but "is it cool enough for ten minutes",
|
||||
which is a much easier bar and may already be met.
|
||||
@ -0,0 +1,143 @@
|
||||
---
|
||||
tags: [project-drogheda, hardware, battery, thermal, power]
|
||||
project: Project Drogheda
|
||||
author: Helgen CTO
|
||||
date: 2026-09-09
|
||||
status: Draft — decision input
|
||||
---
|
||||
|
||||
# Backup cell at 45 °C: why Li-ion is failing, and what replaces it
|
||||
|
||||
> **Bottom line:** LiPo is not an upgrade — a LiPo pouch *is* Li-ion, in a worse package.
|
||||
> And before changing any cell: **`RNTB` = 10 k makes the LTC4040 stop charging at
|
||||
> +40…+42 °C.** At a 45 °C port the pack essentially never charges. That is a resistor,
|
||||
> not a chemistry. The chemistry that then lets you *raise* that limit is
|
||||
> **high-temperature LiFePO4**, which the LTC4040 already supports — `JP2` re-strap, no respin.
|
||||
|
||||
---
|
||||
|
||||
## 1. LiPo is the wrong direction
|
||||
|
||||
A "LiPo" pouch is lithium-ion (LCO or NMC) in a soft laminate bag. Same 0–45 °C charge
|
||||
window, same calendar aging, and **worse** in a hot sealed box: no vent, no CID, and it
|
||||
swells. The 2000 mAh cells are bench hardware. Keep them on the bench.
|
||||
|
||||
---
|
||||
|
||||
## 2. 🔴 The charger is refusing to charge — and it is our resistor
|
||||
|
||||
`RNTB` (10 k 1 %) biases the pack NTC (`RT1`, 10 k, on the cell via `P4.3`). The LTC4040
|
||||
pauses charging when the NTC falls to **53.6 % of `RBIAS`** and resumes below **325 %**.
|
||||
With `RBIAS` = 10 k that puts the charge window at:
|
||||
|
||||
| NTC β | Charge window today |
|
||||
|---|---|
|
||||
| B3380 | **−3.1 °C … +42.4 °C** |
|
||||
| B3950 | **+0.6 °C … +39.7 °C** |
|
||||
|
||||
Port operating temperature is ~45 °C. **The pack sits above the hot-pause threshold
|
||||
for most of the working day**, so it never reaches full charge and the backup is not
|
||||
there when the power drops. The MCU's own `CHRG_EN` hot-cut sits on top of this.
|
||||
|
||||
This is very likely most of the "poor performance" — and it is **not** the cell's fault.
|
||||
Note the earlier fleet finding blamed no-charge on the LTC4040 safety-timer latch; a
|
||||
pack that is repeatedly hot-paused mid-charge is exactly how you *reach* that latch.
|
||||
|
||||
### Re-scaling `RNTB`
|
||||
|
||||
You cannot simply raise this on the current cell — an NMC/LCO 18650 **must not** be
|
||||
charged at 55 °C. Raise it *together with* the chemistry change:
|
||||
|
||||
| Target hot pause | β | New `RNTB` | Resulting window |
|
||||
|---|---|---|---|
|
||||
| +55 °C | B3380 | **6.62 k** | +6.1 … +55 °C |
|
||||
| +55 °C | B3950 | 5.56 k | +12.3 … +55 °C |
|
||||
| **+60 °C** | **B3380** | **5.67 k → 5.6 k E24** | **+9.7 … +60 °C** |
|
||||
| +60 °C | B3950 | 4.64 k | +16.0 … +60 °C |
|
||||
|
||||
`RBIAS` sets both ends, so raising the hot limit raises the cold one. **Specify the
|
||||
B3380 NTC** (the delta doc already calls B3380 "ideal", B3950 "acceptable") — with B3950
|
||||
you would refuse to charge below +16 °C, which is a real winter night in Ensenada.
|
||||
|
||||
⚠ Computed from the datasheet's 53.6 % / 325 % ratios and a β model with R25 = 10 k.
|
||||
Check against the actual NTC part's R/T table before cutting the BOM.
|
||||
|
||||
---
|
||||
|
||||
## 3. The cell: high-temperature LiFePO4 26650
|
||||
|
||||
| | Today — NMC/LCO 18650 | **High-temp LFP 26650** |
|
||||
|---|---|---|
|
||||
| Charge temp | 0…45 °C | **−20…60 °C** (Topwell 3600 mAh) · **0…75 °C** (JGNE 4000 mAh) |
|
||||
| Discharge temp | −20…60 °C | −50…80 °C · −30…75 °C |
|
||||
| Nominal | 3.6 V | 3.2 V |
|
||||
| Cell energy | ~11 Wh (3 Ah) | 11.5 Wh (3.6 Ah) · **12.8 Wh (4 Ah)** |
|
||||
| Cycle life | 300–500 | **≥ 2000** to 80 % |
|
||||
| Thermal runaway onset | ~150–200 °C | ~270 °C (olivine) — does not propagate |
|
||||
| Calendar aging at 45 °C | fast | far slower |
|
||||
|
||||
**4P of the 3.6 Ah cell = 46 Wh; 4P of the 4 Ah = 51 Wh** — both at or above today's
|
||||
~43 Wh. Even 3P clears 38 Wh.
|
||||
|
||||
### The board already supports it — one jumper
|
||||
|
||||
LTC4040 `F2` selects chemistry: **high = Li-Ion, low = LiFePO4**. Float table:
|
||||
|
||||
| F1 | F0 | F2 = 1 (Li-Ion) | F2 = 0 (LiFePO4) |
|
||||
|---|---|---|---|
|
||||
| 0 | 0 | 3.95 V | 3.45 V |
|
||||
| **0** | **1** | **4.00 V ← we are here** | **3.50 V ← we land here** |
|
||||
| 1 | 0 | 4.05 V | 3.55 V |
|
||||
| 1 | 1 | 4.10 V | 3.60 V |
|
||||
|
||||
Current straps are F2=1 / F1=0 / F0=1. **Flip `JP2` (F2) only** → 3.50 V LFP float.
|
||||
The 2026-07-06 pre-fab audit already recorded this path as preserved. No schematic
|
||||
change, no respin. 3.50 V on LFP is ~90 % SoC — deliberately shy of 3.65 V, which is
|
||||
exactly what you want for calendar life at temperature. `JP3` to F1=1 gives 3.60 V if
|
||||
you later want the last few percent.
|
||||
|
||||
### What else must change
|
||||
|
||||
1. **`RNTB` → 5.6 k** (§2) — without this the swap changes nothing; the charger still
|
||||
pauses at 42 °C.
|
||||
2. **Firmware `BAT_CRITICAL` / `BAT_RECOVERY`.** LFP's discharge curve is flat at ~3.2 V
|
||||
from 90 % to 15 % SoC. Voltage-based SoC stops working. Re-derive the thresholds
|
||||
against the knee (~2.9 V), and expect the gauge to be near-useless mid-band —
|
||||
coulomb-count or accept a three-state indicator. The firmware review already flagged
|
||||
these thresholds as bench-tune items for the 4.00 V pack; this makes it mandatory.
|
||||
3. **MCU `CHRG_EN` hot-cut threshold** — raise in step with `RNTB`, or it becomes the
|
||||
new binding limit.
|
||||
4. **LTC4040 boost current.** 3.2 V nominal instead of 3.6 V ⇒ ~12 % more pack current
|
||||
for the same backup watts. Re-check against the boost limit and the `RS1` errata fix.
|
||||
5. **Mechanical.** 26650 is 26.5 mm vs 18.5 mm and ~85 g/cell. New ASA battery-case
|
||||
print, and re-check the 4P footprint inside the HBOX.
|
||||
6. **Sourcing.** The high-temp grades are Chinese-supplier parts (JGNE, Topwell class),
|
||||
not a shelf item in MX. Check MOQ, lead time and whether they will give a real R/T
|
||||
and cycle-at-temperature spec before this goes on the 30-unit BOM.
|
||||
|
||||
---
|
||||
|
||||
## 4. Alternatives, briefly
|
||||
|
||||
| Option | Verdict |
|
||||
|---|---|
|
||||
| **High-temp LFP 26650** | ✅ **Recommended.** Solves charge-at-temperature, board already supports it, cost/Wh comparable |
|
||||
| **Supercap / LIC hold-up** | −40…+65/85 °C, no charge-temperature window at all, effectively infinite cycles — but ~1/20 the energy. **The right answer if the real requirement is "report a power-loss alarm and shut down cleanly" rather than "run for hours".** Pin the requirement before dismissing it again |
|
||||
| **Smaller pack, better cell** | Nobody has pulled this lever. 43 Wh is a lot for a parked machine. Halve the requirement and the thermal problem halves with it |
|
||||
| **LTO** | Best temperature range and cycle life, but 2.4 V nominal breaks the LTC4040's 1S window entirely — new charger. Low energy density, expensive, hard to source. **Out** |
|
||||
| **High-temp-rated NMC 18650** | Keeps the form factor, but you are still fighting the same chemistry for a few °C. Marginal |
|
||||
| **NiMH** | High self-discharge at temperature, and trickle-charging hot is its own failure mode. **Out** |
|
||||
|
||||
---
|
||||
|
||||
## 5. Do this first — you already have the data
|
||||
|
||||
Do **not** buy cells on an assumption. `tbat` (TMP102 on the pack) and `tntc` are already
|
||||
in `$PHLG` and already landing in `htracker`. Pull the fleet histogram and answer:
|
||||
|
||||
1. What is the **actual** pack temperature distribution, by unit and by hour?
|
||||
2. What **fraction of the day** does it sit above the current ~40–42 °C hot pause?
|
||||
3. Does `cflt` / charge-fault correlate with those windows?
|
||||
|
||||
Question 2 is the number that decides whether this is a resistor change, a chemistry
|
||||
change, or both. It is one query against data we are already collecting.
|
||||
@ -0,0 +1,158 @@
|
||||
---
|
||||
tags: [project-drogheda, test-plan, power, battery, firmware, backend]
|
||||
project: Project Drogheda
|
||||
author: Helgen CTO
|
||||
date: 2026-09-10
|
||||
status: Draft — evaluation procedure
|
||||
---
|
||||
|
||||
# Backup-power evaluation: the procedure
|
||||
|
||||
> **It is not a lot of things to do. It is three measurements and a decision.**
|
||||
> Everything else in the last three notes is *contingent* on them — most of that list
|
||||
> deletes itself once D3, P1 and P2 come back. Do not start firmware before Gate G1.
|
||||
|
||||
**Critical path:** D3 (requirement) → P1 (sleep floor) → P2 (modem) → F1 (firmware) →
|
||||
S1 (server) → decide the cell last. ≈ **3 weeks of elapsed time, ~7 person-days of work.**
|
||||
|
||||
---
|
||||
|
||||
## Phase D — desk, no hardware. 1 day. Kills most of the list.
|
||||
|
||||
| # | Task | Owner | Output |
|
||||
|---|---|---|---|
|
||||
| **D1** | Fleet `tbat`/`tntc` histogram from `htracker`: hourly distribution per unit over 30 d; **% of day above 42 °C**; longest continuous window **below** 40 °C; correlate `cflt` and charge events with those windows | backend | one chart + two numbers |
|
||||
| **D2** | Ask Telcel: is **PSM / eDRX** available on our APN and plan? What TAU / Active Timer will the network grant? | Leo | yes/no + granted timers |
|
||||
| **D3** | 🔴 **Pin the requirement.** From ICAVE ops / the contract, not from us: **how long must a unit keep reporting on battery, and what must it report?** | Leo | a number in hours, and a message spec |
|
||||
|
||||
**Gate G0 — do not proceed without D3.** Every number downstream is sized by it. If the
|
||||
answer is "report the outage and survive until someone attends, ~24 h", the whole problem
|
||||
is already solved by the firmware and the cell question closes. If it is "7 days of live
|
||||
tracking", that is a different product and needs a different pack.
|
||||
|
||||
### D1 query sketch
|
||||
```sql
|
||||
SELECT cell_id, date_trunc('hour', ts) AS h,
|
||||
avg(tbat) AS tbat_avg, max(tbat) AS tbat_max,
|
||||
sum((tbat > 42)::int)::float / count(*) AS frac_above_42
|
||||
FROM phlg WHERE ts > now() - interval '30 days' AND tbat > -100
|
||||
GROUP BY 1,2 ORDER BY 1,2;
|
||||
```
|
||||
Then: per unit, the longest run of consecutive hours with `tbat_max < 40`.
|
||||
**Success bar is not "always cool" — it is "≥ 15 min below 40 °C per day"** (see the
|
||||
duty-cycle brief §3). That is a much easier bar and may already be met.
|
||||
|
||||
---
|
||||
|
||||
## Phase P — bench. The measurement that decides everything. 2–3 days.
|
||||
|
||||
### Rig
|
||||
One v5.5 board, bench PSU at **3.7 V into `P4`** (pack position), current measured
|
||||
**at `BAT+`** — that is what the pack actually delivers, and it captures the LTC4040
|
||||
boost's light-load efficiency, which is one of our real unknowns. Measure the 5 V rail in
|
||||
parallel so you get both numbers and can derive the boost efficiency.
|
||||
|
||||
⚠ **A bench DMM will not do this.** You need µA-to-A dynamic range on one trace: a
|
||||
**Nordic PPK2** (~US$110) or Joulescope/Otii. Buy it — it pays for itself in this test
|
||||
alone, and every low-power decision after this depends on trusting the number.
|
||||
|
||||
### P1 — the subtraction ladder 🔴
|
||||
|
||||
Measure, then remove one load, measure again. The **deltas are the deliverable** — they
|
||||
tell you which fixes are worth writing and which are noise.
|
||||
|
||||
| Step | State | Expect |
|
||||
|---|---|---|
|
||||
| a | Full `RUNNING`, stack up, fan off | ~2.5 W baseline |
|
||||
| b | `PWR_CTRL` low (RTK stack off) | |
|
||||
| c | `BYP_CTRL` low (`K1` released) | **−150 mW** — confirms the K1 reversal |
|
||||
| d | `U12` disabled + `W5500` held in reset | **−400 mW?** |
|
||||
| e | All LEDs off (incl. gauge `PB12–15`) | −50…150 mW |
|
||||
| f | `MAX3232` / `SP3485` / `SC16IS752` in shutdown | −5…15 mW |
|
||||
| g | MCU in **STOP + LSE RTC** (not `loop()`) | −150 mW |
|
||||
| h | `U17` lifted, `/3V3` fed from bench supply through the meter | **isolates the AMS1117's own Iq — the number I most expect to be ugly** |
|
||||
|
||||
**Gate G1: is the achievable floor under 50 mW?**
|
||||
Yes → proceed to firmware. No → find out what is holding it up *before* writing any.
|
||||
If step (h) is 25–55 mW as expected, the LDO swap is a one-part change worth doing first.
|
||||
|
||||
### P2 — modem energy and the burst
|
||||
1. Real Telcel SIM. If D2 said yes: `AT+CPSMS=1,,,"<TAU>","<Active>"`. Measure **modem
|
||||
sleep current in PSM**, and **energy per wake→TX→sleep cycle** in joules.
|
||||
2. If D2 said no: measure **energy per full attach cycle** the same way.
|
||||
3. 🔴 **The burst test.** With a real pack at **low SoC** and the pack at **45 °C**,
|
||||
trigger an LTE attach and watch `MAIN5V` on a scope. Does `PFI` (4.60 V) trip?
|
||||
This is the most likely way the design fails in the field and it is cheap to check now.
|
||||
|
||||
**Gate G2:** PSM or power-cycle, and the interval locked. Feed the measured joules back
|
||||
into the runtime table.
|
||||
|
||||
---
|
||||
|
||||
## Phase F — firmware. 3–4 days, once G1 and G2 pass.
|
||||
|
||||
- `BACKUP_SLEEP` as a real state behind a compile flag (`ENABLE_BACKUP_DUTYCYCLE`), per the
|
||||
state machine in the duty-cycle brief §8. Today's `SLEEP` stays as the brownout failsafe.
|
||||
- Exercise it first in the **`hostsim` harness** already in the repo — state transitions,
|
||||
adaptive cadence, `BAT_CRITICAL` final message — before it touches silicon.
|
||||
- **F1 acceptance, on the bench:** real pack, real SIM, **72 h continuous** with the meter
|
||||
logging. Deliverable = **measured Wh/day** and extrapolated runtime.
|
||||
- **Gate G3: measured Wh/day within 30 % of the model.** If it is not, the model is wrong
|
||||
and everything downstream needs re-deciding — do not paper over it.
|
||||
|
||||
---
|
||||
|
||||
## Phase S — server-side synthesis. Your idea, and it is a good one. 1–2 days.
|
||||
|
||||
Holding the position server-side decouples what the customer sees from what the radio does.
|
||||
The device sends a heartbeat every 30–60 min; `retranslator.py` keeps feeding Wialon at
|
||||
1 Hz from the last known fix. That is the right split.
|
||||
|
||||
**But three rules, and they are not optional:**
|
||||
|
||||
1. **Mark it.** Synthesized points carry an explicit source flag and render differently in
|
||||
the UI. We are generating data that did not come from a sensor; anyone reading the track
|
||||
must be able to see that. Do not let a synthesized point be indistinguishable from a real one.
|
||||
2. 🔴 **Hard stop on a missed heartbeat.** The moment a heartbeat is late by more than one
|
||||
interval, **stop synthesizing** and switch the unit to *"last seen at X, T ago —
|
||||
unknown"*. Synthesizing past the heartbeat window turns a dead unit into a healthy-looking
|
||||
one on the operator's screen. That is strictly worse than reporting nothing, and it is
|
||||
exactly the failure this feature would be blamed for.
|
||||
3. **Movement breaks the illusion instantly.** The `U26` accelerometer wake exists for this:
|
||||
if the machine moves during an outage, the unit wakes and sends a real fix, and the server
|
||||
drops out of synthesis on the spot. Without motion-wake, a towed machine keeps reporting
|
||||
from the yard — with a port customer, that is a liability, not a bug.
|
||||
|
||||
**S1 test:** on the bench, cut vehicle power → verify Wialon shows a continuous 1 Hz track
|
||||
flagged as battery-mode → cut the unit entirely → **verify the track stops and the unit goes
|
||||
"unknown" within one heartbeat interval**, not later. Also check whether ICAVE's contract or
|
||||
Wialon billing counts records — synthesized ones may not be acceptable to count.
|
||||
|
||||
---
|
||||
|
||||
## Phase C — the cell decision, *last*
|
||||
|
||||
Only now, with **measured Wh/day** (F1) and the **real temperature histogram** (D1):
|
||||
|
||||
- **Daily energy < ~2 Wh and D1 shows ≥ 15 min/day below 40 °C** → **keep the current cell.**
|
||||
No LFP, no `RNTB` change, no new case. Consider *shrinking* the pack instead.
|
||||
- **Otherwise** → high-temp LFP + `RNTB` → 5.6 k + B3380 NTC + `JP2` re-strap, per the
|
||||
battery note. Order sample cells at D1 time so they are on the shelf if needed — that is
|
||||
the only long-lead item, and sampling two cells costs nothing.
|
||||
|
||||
---
|
||||
|
||||
## Phase V — field pilot. 30 days.
|
||||
|
||||
Two units at ICAVE on the new firmware, rest of the fleet as control. Track: actual outage
|
||||
events, hours survived, `vbat` trajectory, charge-window utilisation, and any operator
|
||||
complaint about the synthesized track. **Ship to the fleet only after 30 clean days.**
|
||||
|
||||
---
|
||||
|
||||
## What this is *not*
|
||||
|
||||
Not a v6 respin. Nothing above requires new hardware except a possible one-part LDO swap
|
||||
and, if Phase C says so, a cell and one resistor. The 30-unit build is not blocked by any
|
||||
of it — but **D3 should be answered before that build ships**, because it may change what
|
||||
pack goes in the box.
|
||||
@ -0,0 +1,72 @@
|
||||
---
|
||||
tags: [project-drogheda, comms, vendor, telecom]
|
||||
project: Project Drogheda
|
||||
author: Helgen CTO
|
||||
date: 2026-09-10
|
||||
status: Draft para envío — cubre la tarea D2 del procedimiento de evaluación
|
||||
---
|
||||
|
||||
# Correo a Vectro — PSM / eDRX en las líneas Telcel
|
||||
|
||||
> Cubre **D2** de `2026-09-10_Drogheda_Backup-Power_Evaluation-Procedure_v1.0.md`.
|
||||
> Las preguntas 1–4 están redactadas para reenviarse **tal cual** a Telcel; las 5–7 sólo
|
||||
> las puede responder Vectro.
|
||||
|
||||
---
|
||||
|
||||
**Asunto:** Consulta técnica — modos de ahorro de energía PSM / eDRX en las líneas Telcel
|
||||
|
||||
Estimado [Nombre]:
|
||||
|
||||
Requerimos confirmar si las líneas Telcel que nos suministran soportan **PSM (Power Saving
|
||||
Mode)** y **eDRX (extended DRX)**, definidos en **3GPP Release 13**. La respuesta determina
|
||||
el diseño de nuestro modo de respaldo por batería, por lo que agradeceremos su apoyo para
|
||||
escalar la consulta con Telcel si no está a su alcance responderla directamente.
|
||||
|
||||
**Contexto:** operamos equipos de telemetría GPS/RTK en terminales portuarias. Ante un corte
|
||||
de energía, el equipo debe seguir reportando posición y estado durante varios días con
|
||||
batería. PSM permite que el módem duerma a ~10 µA **manteniendo el registro en la red**, en
|
||||
lugar de volver a registrarse en cada envío. En nuestros cálculos la diferencia en autonomía
|
||||
es de **días contra semanas**, con el mismo hardware.
|
||||
|
||||
## Preguntas técnicas (pueden reenviarse tal cual a Telcel)
|
||||
|
||||
1. ¿Está habilitado **PSM** en el APN y el perfil de SIM que tenemos contratado, para
|
||||
dispositivos **LTE Cat-1bis**?
|
||||
2. En caso afirmativo, ¿qué valores otorga la red para el **T3412 extendido (TAU)** y el
|
||||
**T3324 (Active Timer)**? Nuestra solicitud sería **TAU de 30 a 60 minutos** y
|
||||
**Active Timer de 0 a 60 segundos**.
|
||||
3. ¿Está habilitado **eDRX**? ¿Cuál es el **ciclo máximo** que otorga la red?
|
||||
4. Si PSM o eDRX no están disponibles en nuestro APN actual, ¿existe un **APN de IoT/M2M**
|
||||
donde sí lo estén, y cuál sería el procedimiento y el costo de migrar nuestras líneas?
|
||||
|
||||
## Preguntas comerciales y operativas (para Vectro)
|
||||
|
||||
5. ¿Existe alguna política de **suspensión o baja por inactividad**? Un equipo en PSM puede
|
||||
permanecer **varios días sin generar tráfico**, y necesitamos confirmar que la línea no se
|
||||
suspenda ni se dé de baja por ese motivo.
|
||||
6. ¿El plan factura por **sesión / attach**, o únicamente por **volumen de datos**?
|
||||
7. ¿Podemos habilitar **una línea de prueba** con PSM activo, para validarlo en banco antes
|
||||
de aplicarlo a la flota?
|
||||
|
||||
Agradeceremos su respuesta **a más tardar el viernes 19 de septiembre**, ya que esta
|
||||
definición bloquea la siguiente etapa de nuestro desarrollo.
|
||||
|
||||
Quedo atento a sus comentarios.
|
||||
|
||||
Saludos cordiales,
|
||||
|
||||
**Leo Rodríguez**
|
||||
Helgen Technologies
|
||||
|
||||
---
|
||||
|
||||
## Notas para Leo (no enviar)
|
||||
|
||||
- Ajustar **[Nombre]** y la fecha del compromiso.
|
||||
- La **pregunta 5 es la más importante para Vectro** y la que un revendedor suele pasar por
|
||||
alto: una política de inactividad que suspenda la SIM anularía todo el beneficio de PSM.
|
||||
- Si Vectro responde "no sé", el objetivo mínimo del correo es la **pregunta 7** — con una
|
||||
sola línea de prueba podemos medir en banco lo que la red realmente otorga
|
||||
(`AT+CPSMS?` y `AT+CEDRXRDP` devuelven los valores concedidos, que casi nunca son los
|
||||
solicitados) y dejar de depender de la respuesta comercial.
|
||||
@ -1 +1 @@
|
||||
Subproject commit c7d25524a7f6ec2a579be615140f45c2ac064bc3
|
||||
Subproject commit 94917b1993b6003efb653483a305794130d395b3
|
||||
227
scripts/2026-09-15_v6_T12_sim_dual_footprint.py
Normal file
227
scripts/2026-09-15_v6_T12_sim_dual_footprint.py
Normal file
@ -0,0 +1,227 @@
|
||||
#!/usr/bin/env python3
|
||||
"""v6 T12 - SIM block: MFF2 footprint repoint (part 1 of 2).
|
||||
|
||||
WHY THIS SCRIPT EXISTS
|
||||
----------------------
|
||||
U22 (MFF2 soldered eSIM, Block Q) shipped from T4 with a placeholder footprint field:
|
||||
the literal string "Drogheda:MFF2_5x6_TBD", which resolved to nothing - Drogheda.pretty
|
||||
held only the E-J1 socket. U22 was also absent from the board.
|
||||
|
||||
On 2026-09-15 the real land pattern was built as Drogheda.pretty/MFF2_6x5.kicad_mod
|
||||
(geometry derived from ETSI TS 102 671 V19.0.0 section 6, cross-checked against the
|
||||
ST ST4SIM-200M VFDFPN8 outline) and the three property fields were edited BY HAND.
|
||||
Hand edits live outside the T-script replay chain, so a future v5 schematic change
|
||||
would silently discard them. This script puts them back in the chain.
|
||||
|
||||
It is IDEMPOTENT: on an already-patched tree it reports 0 changes and exits 0.
|
||||
|
||||
NAMING: the old field said "5x6"; ETSI dimensions the package as E=6.00 x D=5.00,
|
||||
so the footprint is MFF2_6x5.
|
||||
|
||||
PART 2 (pending, will be appended to this same script)
|
||||
------------------------------------------------------
|
||||
The nano-SIM holder alternate + eight 0R selects downstream of the existing ESD
|
||||
(D23 SIM_DATA / D24 SIM_CLK / D25 SIM_RST) + DNP flags, so MFF2 and a card holder
|
||||
can share the bus with exactly one populated. Blocked on the holder's land pattern.
|
||||
|
||||
LESSONS APPLIED (see drogheda-v6-resync-protocol)
|
||||
-------------------------------------------------
|
||||
- no bare numeric regex; every substitution is a complete quoted token or is scoped
|
||||
to one paren-matched s-expression block
|
||||
- hard invariant guard: aborts if ANY pre-existing UUID would change
|
||||
- .T12bak written before any file is touched; dry-run is the default
|
||||
|
||||
Usage: python3 2026-09-15_v6_T12_sim_dual_footprint.py [--apply]
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
KI = os.path.join(HERE, '..', '03-Architecture-Hardware', 'kicad')
|
||||
SYM = os.path.join(KI, 'Drogheda-sym.kicad_sym')
|
||||
SCH = os.path.join(KI, 'hbox-watchdog-v6.kicad_sch')
|
||||
FPF = os.path.join(KI, 'Drogheda.pretty', 'MFF2_6x5.kicad_mod')
|
||||
|
||||
APPLY = '--apply' in sys.argv
|
||||
UUID_RE = re.compile(r'\(uuid "([^"]*)"\)')
|
||||
|
||||
OLD_FP = '"Drogheda:MFF2_5x6_TBD"'
|
||||
NEW_FP = '"Drogheda:MFF2_6x5"'
|
||||
|
||||
OLD_DESC = (
|
||||
'MFF2 / DFN-8 5x6 mm soldered M2M SIM (ETSI TS 102 671). Pads: 1=C1 VCC, 2=C2 RST, '
|
||||
'3=C3 CLK, 4=C4 NC, 5=C5 GND, 6=C6 VPP (NC), 7=C7 I/O, 8=C8 NC. FOOTPRINT TBD - build '
|
||||
'from the chosen carrier chip datasheet before layout. Carrier-supplied part, not on LCSC.'
|
||||
)
|
||||
NEW_DESC = (
|
||||
'MFF2 / VFDFPN-8 6.0x5.0 mm soldered M2M eSIM (ETSI TS 102 671). Pads: 1=C1 VCC, 2=C2 RST, '
|
||||
'3=C3 CLK, 4=C4 NC, 5=C5 GND, 6=C6 VPP (NC), 7=C7 I/O, 8=C8 NC - JEDEC DFN counterclockwise, '
|
||||
'pin 1 top-left, matches ST ST4SIM-200M. Footprint Drogheda:MFF2_6x5 (2026-09-15). '
|
||||
'Carrier-supplied part: NO LCSC number, exclude from the JLCPCB PCBA BOM, hand-solder or '
|
||||
'consign. Verify pinout + die-pad exposure against the sourced carrier drawing before fab.'
|
||||
)
|
||||
U22_DESC = 'MFF2 eSIM (carrier-supplied, NO LCSC - do not order from JLCPCB)'
|
||||
|
||||
# pad number -> (x, y); size is 0.9 x 0.5 for all eight
|
||||
EXPECTED_PADS = {
|
||||
'1': (-2.85, -1.905), '2': (-2.85, -0.635), '3': (-2.85, 0.635), '4': (-2.85, 1.905),
|
||||
'5': (2.85, 1.905), '6': (2.85, 0.635), '7': (2.85, -0.635), '8': (2.85, -1.905),
|
||||
}
|
||||
|
||||
|
||||
def die(msg):
|
||||
sys.exit('REFUSING: ' + msg)
|
||||
|
||||
|
||||
def balanced_end(s, j):
|
||||
"""End index (exclusive) of the s-expression opening at j. String-aware."""
|
||||
depth = 0
|
||||
k = j
|
||||
in_str = False
|
||||
while k < len(s):
|
||||
c = s[k]
|
||||
if in_str:
|
||||
if c == '\\':
|
||||
k += 2
|
||||
continue
|
||||
if c == '"':
|
||||
in_str = False
|
||||
else:
|
||||
if c == '"':
|
||||
in_str = True
|
||||
elif c == '(':
|
||||
depth += 1
|
||||
elif c == ')':
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
return k + 1
|
||||
k += 1
|
||||
die('unbalanced s-expression starting at offset %d' % j)
|
||||
|
||||
|
||||
def paren_ok(s, label):
|
||||
depth = 0
|
||||
k = 0
|
||||
in_str = False
|
||||
while k < len(s):
|
||||
c = s[k]
|
||||
if in_str:
|
||||
if c == '\\':
|
||||
k += 2
|
||||
continue
|
||||
if c == '"':
|
||||
in_str = False
|
||||
else:
|
||||
if c == '"':
|
||||
in_str = True
|
||||
elif c == '(':
|
||||
depth += 1
|
||||
elif c == ')':
|
||||
depth -= 1
|
||||
if depth < 0:
|
||||
die('%s: unbalanced ")" at offset %d' % (label, k))
|
||||
k += 1
|
||||
if depth != 0:
|
||||
die('%s: %d unclosed "(" at EOF' % (label, depth))
|
||||
if in_str:
|
||||
die('%s: unterminated string at EOF' % label)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- gate 0: footprint
|
||||
print('== gate 0: the footprint file must exist and match the documented geometry ==')
|
||||
if not os.path.isfile(FPF):
|
||||
die('%s is missing - build the land pattern before running T12' % FPF)
|
||||
fp_src = open(FPF, encoding='utf-8').read()
|
||||
paren_ok(fp_src, 'MFF2_6x5.kicad_mod')
|
||||
|
||||
pads = dict(
|
||||
(m.group(1), (float(m.group(2)), float(m.group(3))))
|
||||
for m in re.finditer(r'\(pad "(\d)" smd rect \(at (-?[\d.]+) (-?[\d.]+)\) \(size 0\.9 0\.5\)', fp_src)
|
||||
)
|
||||
if pads != EXPECTED_PADS:
|
||||
die('MFF2_6x5.kicad_mod pad geometry does not match the T12 reference.\n'
|
||||
' found: %s\n expected: %s' % (sorted(pads.items()), sorted(EXPECTED_PADS.items())))
|
||||
print(' OK 8 pads, 0.9 x 0.5, columns at X +/-2.85, rows at Y +/-1.905 / +/-0.635')
|
||||
|
||||
# ---------------------------------------------------------------- the edits
|
||||
edits = 0
|
||||
reports = []
|
||||
|
||||
for path in (SYM, SCH):
|
||||
name = os.path.basename(path)
|
||||
if not os.path.isfile(path):
|
||||
die('%s is missing' % path)
|
||||
src = open(path, encoding='utf-8').read()
|
||||
paren_ok(src, name)
|
||||
new = src
|
||||
local = []
|
||||
|
||||
# (a) footprint field - complete quoted token only
|
||||
n = new.count(OLD_FP)
|
||||
if n:
|
||||
new = new.replace(OLD_FP, NEW_FP)
|
||||
local.append('%d x footprint field -> Drogheda:MFF2_6x5' % n)
|
||||
|
||||
# (b) library description (SYM: the symbol; SCH: the lib_symbols cache copy)
|
||||
n = new.count(OLD_DESC)
|
||||
if n:
|
||||
new = new.replace(OLD_DESC, NEW_DESC)
|
||||
local.append('%d x symbol description de-TBD-ed' % n)
|
||||
|
||||
# (c) U22 instance Description - scoped to U22's own paren-matched block
|
||||
if name.endswith('.kicad_sch'):
|
||||
targets = []
|
||||
for m in re.finditer(r'\(symbol(?=[\s(])', new):
|
||||
j = m.start()
|
||||
e = balanced_end(new, j)
|
||||
blk = new[j:e]
|
||||
if '"Drogheda-sym:MFF2_SIM"' in blk and '(property "Reference" "U22"' in blk:
|
||||
targets.append((j, e))
|
||||
if len(targets) != 1:
|
||||
die('expected exactly 1 U22 MFF2_SIM instance in %s, found %d' % (name, len(targets)))
|
||||
j, e = targets[0]
|
||||
blk = new[j:e]
|
||||
if '(property "Description" ""' in blk:
|
||||
blk2 = blk.replace('(property "Description" ""',
|
||||
'(property "Description" "%s"' % U22_DESC, 1)
|
||||
new = new[:j] + blk2 + new[e:]
|
||||
local.append('1 x U22 instance Description set')
|
||||
elif U22_DESC not in blk:
|
||||
die('U22 Description is neither empty nor the T12 value - inspect by hand')
|
||||
# sanity: U22 must carry no LCSC number (carrier-supplied part)
|
||||
blk_now = new[j:balanced_end(new, j)]
|
||||
mm = re.search(r'\(property "LCSC" "([^"]*)"', blk_now)
|
||||
if mm and mm.group(1).strip():
|
||||
die('U22 carries LCSC "%s" - it is a carrier-supplied part and must have none '
|
||||
'(C730237 belongs to U23/U24, the 74LVC2T45s)' % mm.group(1))
|
||||
|
||||
if new == src:
|
||||
reports.append('%-28s already at T12 state, nothing to do' % name)
|
||||
continue
|
||||
|
||||
# invariants
|
||||
if UUID_RE.findall(new) != UUID_RE.findall(src):
|
||||
die('%s: a UUID would change' % name)
|
||||
paren_ok(new, name + ' (post-edit)')
|
||||
if OLD_FP in new or 'MFF2_5x6_TBD' in new:
|
||||
die('%s: a TBD footprint reference survived the edit' % name)
|
||||
|
||||
reports.append('%-28s %s' % (name, '; '.join(local)))
|
||||
edits += len(local)
|
||||
if APPLY:
|
||||
shutil.copy2(path, path + '.T12bak')
|
||||
open(path, 'w', encoding='utf-8').write(new)
|
||||
|
||||
print()
|
||||
print('== edits ==')
|
||||
for r in reports:
|
||||
print(' ' + r)
|
||||
|
||||
print()
|
||||
print('total change groups: %d' % edits)
|
||||
if APPLY:
|
||||
print('APPLIED (.T12bak written beside each modified file)')
|
||||
else:
|
||||
print('DRY RUN - nothing written. Re-run with --apply.')
|
||||
Loading…
Reference in New Issue
Block a user