← Commit history

hover: per-component descriptions under section headers; per-rail PS1/PS2/PS3 zones; per-contact MC-to-IO mapping

Caleb ·c499c1fcc0 ·2mo ago ·parent e02bbc5
1 file changed +79−34
README.html+79−34
@@ -165,7 +165,7 @@ else {         const tip = document.createElement('div');         tip.style.cssText = 'position:absolute;display:none;z-index:20;pointer-events:none;' +           'background:rgba(22,27,34,.96);border:1px solid rgba(240,246,252,.15);border-radius:8px;' +-          'padding:8px 11px;max-width:290px;color:#e6edf3;font-size:12.5px;line-height:1.45;' ++          'padding:8px 11px;max-width:300px;color:#e6edf3;font-size:12.5px;line-height:1.45;' +           "font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif";         const tipT = document.createElement('div'); tipT.style.fontWeight = '600';         const tipB = document.createElement('div'); tipB.style.color = '#9aa4b2'; tipB.style.marginTop = '2px';@@ -177,38 +177,78 @@ else {         ctl.appendChild(dBtn);         dBtn.onclick = () => { tipsOn = !tipsOn; dBtn.classList.toggle('on', tipsOn); if (!tipsOn) tip.style.display = 'none'; }; +        const HDR = {+          mini: 'RP2350A Mini (user MCU)',+          usbc: 'USB-C (J1)',+          usb: 'USB VBUS power path',+          bulk: 'VBUS bulk capacitance',+          pwr: 'Power contact field (MC1\u2013MC30)',+          io: 'USER_IO contact field (MC31\u2013MC56)',+          led: 'Power LED',+          jmp: 'Rail ground bonds',+          dock: 'ET60T blade dock',+          board: 'Control Panel: Scaffold',+        };         const T = {-          mini: ['RP2350A Mini (user MCU)', 'RP2350A: dual Cortex-M33 / RISC-V @ 150 MHz, 520 KB SRAM, PIO; W25Q16JV 2 MB flash. 26 USER_IO (PWM, PIO, 4\u00d7 ADC), USB 2.0 FS dual-role. Red D1 = power, blue D2 = status.'],-          usbc: ['USB-C (J1)', 'G-Switch GT-USB-7090C (LCSC C3019716). USB 2.0 dual-role, power delivery 3.0 A; VBUS sourced from PS2 \u2014 PD unavailable while PS2 floats.'],-          usbpath: ['USB VBUS power path', 'TPS25940 smart eFuse (2.7\u201318 V, 5 A limit), TUSB321 CC controller, TPD2EUSB30 USB ESD, AO3401A P-FET back-feed block.'],-          bulk: ['VBUS bulk capacitance', 'C5 150 \u00b5F electrolytic + C4 47 \u00b5F ceramic on the switched 5 V rail.'],-          pwrfield: ['Power contact field (MC1\u2013MC30)', 'PS1 0\u201360 V / 12 A, PS2 5 V / 10 A, PS3 user rail + returns. Medium machine contacts, ~6.4 A each (80% derated), 24 AWG solid-core mating wire.'],-          iofield: ['USER_IO contact field (MC31\u2013MC56)', '26 RP2350 USER_IO lines. Medium machine contacts ~6.4 A, 2 mm pitch; interleaved MC57\u2013MC65 are ground returns.'],-          gndmc: ['Ground contacts (MC57\u2013MC65)', 'Return-path contacts interleaved with the USER_IO rows.'],-          jp1: ['PS1 ground bond (JP1)', 'Large machine-pin jumper bonds the PS1 return to ground. Remove to float PS1.'],-          jp2: ['PS2 ground bond (JP2)', 'Bonds the PS2 isolated return to ground; floated, it may ride up to \u00b12.5 V from common.'],-          jp3: ['PS3 ground bond (JP3)', 'Large machine-pin jumper bonds the PS3 return to ground. Remove to float PS3.'],-          jp4: ['USB return bond (JP4)', 'Ground bond for the USB return path beside the USB-C port.'],-          ccj: ['CC jumper (CCJ)', 'Place when VBUS is broken out through machine pins without CC termination satisfied.'],-          led: ['Power LED (D1)', 'Red 0402 (LCSC C130719) \u2014 scaffold power indicator.'],-          dock: ['ET60T blade dock', 'Samtec ET60T blade set: PS1/PS2/PS3 + returns, USB 2.0, SWD/UART debug, MCU boot/reset \u2014 mates to the workcell each dock.'],+          mini: [HDR.mini, 'RP2350A: dual Cortex-M33 / RISC-V @ 150 MHz, 520 KB SRAM, PIO; W25Q16JV 2 MB flash. 26 USER_IO (PWM, PIO, 4\u00d7 ADC), USB 2.0 FS dual-role.'],+          miniSW: [HDR.mini, 'SW1 \u2014 SKRPACE010 boot select button.'],+          miniD1: [HDR.mini, 'D1 \u2014 red 0402 power LED (LCSC C130719).'],+          miniD2: [HDR.mini, 'D2 \u2014 blue 0402 status LED on GPIO25 (LCSC C130724).'],+          usbc: [HDR.usbc, 'G-Switch GT-USB-7090C (LCSC C3019716). USB 2.0 dual-role, power delivery 3.0 A; VBUS sourced from PS2 \u2014 PD unavailable while PS2 floats.'],+          u1: [HDR.usb, 'U1 \u2014 TPS25940ARVCR smart eFuse: 2.7\u201318 V, 5 A current limit, reverse-current block on VBUS.'],+          u3: [HDR.usb, 'U3 \u2014 TUSB321RWBR Type-C CC controller (attach + role detect).'],+          u4: [HDR.usb, 'U4 \u2014 TPD2EUSB30DRTR 2-channel USB ESD clamp.'],+          q1: [HDR.usb, 'Q1 \u2014 AO3401A P-FET: blocks VBUS back-feed in device role.'],+          rEfuse: [HDR.usb, 'eFuse set resistor \u2014 UVLO / OVP / ILIM divider for the TPS25940.'],+          rCc: [HDR.usb, 'CC / configuration resistor for the Type-C controller.'],+          rCd: [HDR.usb, 'R11 \u2014 5.1 k\u03a9 Rd pull-down (UFP role).'],+          cDec: [HDR.usb, '100 nF decoupling.'],+          bulk: [HDR.bulk, 'C5 150 \u00b5F electrolytic + C4 47 \u00b5F ceramic on the switched 5 V rail.'],+          ps1: [HDR.pwr, 'PS1 \u2014 variable rail, 0\u201360 V / 12 A from dock blade P1. + and \u2212 land on medium contacts (~6.4 A each, 80% derated).'],+          ps2: [HDR.pwr, 'PS2 \u2014 switched 5 V / 10 A rail from blade P2. Isolated return may float up to \u00b12.5 V unless bonded at JP2.'],+          ps3: [HDR.pwr, 'PS3 \u2014 user rail from blade P3. Medium contacts, ~6.4 A each.'],+          gndmc: [HDR.io, 'MC57\u2013MC65 \u2014 ground return contacts interleaved with the USER_IO rows.'],+          jp1: [HDR.jmp, 'JP1 \u2014 large machine-pin jumper: bonds the PS1 return to ground. Remove to float PS1.'],+          jp2: [HDR.jmp, 'JP2 \u2014 bonds the PS2 isolated return to ground; floated it may ride to \u00b12.5 V.'],+          jp3: [HDR.jmp, 'JP3 \u2014 bonds the PS3 return to ground. Remove to float PS3.'],+          jp4: [HDR.jmp, 'JP4 \u2014 ground bond for the USB return path.'],+          posts: [HDR.jmp, '12\u00d76 machine-pin jumper stock for the rail ground bonds.'],+          ccj: [HDR.dock, 'CCJ \u2014 place when VBUS is broken out through machine pins without CC termination satisfied.'],+          led: [HDR.led, 'D1 \u2014 red 0402 (LCSC C130719), scaffold power indicator.'],+          rLed: [HDR.led, 'R5 \u2014 10 k\u03a9 series resistor for D1.'],+          dock: [HDR.dock, 'Samtec ET60T blade set: PS1/PS2/PS3 + returns, USB 2.0, SWD/UART debug, MCU boot/reset \u2014 mates to the workcell each dock.'],           ghost: ['Control Panel: Workcell (ghost)', 'The workcell half shown mated above: CM5 carrier and power-distribution hub.'],-          posts: ['Ground jumper posts', '12\u00d76 machine-pin jumper stock for the rail ground bonds.'],-          board: ['Control Panel: Scaffold', 'User power and I/O dock board for the base scaffold.'],+          board: [HDR.board, 'User power and I/O dock board for the base scaffold.'],         };+        function ioOf(mc) {+          let io = null, adc = false;+          if (mc >= 31 && mc <= 34) { io = 29 - (mc - 31); adc = true; }+          else if (mc >= 35 && mc <= 38) io = 25 - (mc - 35);+          else if (mc >= 39 && mc <= 46) io = 19 - (mc - 39);+          else if (mc >= 47 && mc <= 56) io = 9 - (mc - 47);+          if (io === null) return T.gndmc;+          return [HDR.io, 'MC' + mc + ' \u2192 USER_IO' + io + ' \u2014 digital I/O, PWM, PIO' + (adc ? ', ADC-capable' : '') + '. Medium contact ~6.4 A.'];+        }         const NAME_RULES = [-          [/^(U2$|Molecule_RP2350A_Mini|mini-D|MINI_)/, 'mini'],+          [/^SW1$/, 'miniSW'],+          [/^(MINI_D1|mini-D1)/, 'miniD1'],+          [/^(MINI_D2|mini-D2)/, 'miniD2'],+          [/^(U2$|Molecule_RP2350A_Mini)/, 'mini'],           [/^J1$/, 'usbc'],-          [/^(U1$|U3$|U4$|Q1$)/, 'usbpath'],-          [/^(C4$|C5$)/, 'bulk'],+          [/^U1$/, 'u1'], [/^U3$/, 'u3'], [/^U4$/, 'u4'], [/^Q1$/, 'q1'],+          [/^(R1|R2|R3|R4|R10)$/, 'rEfuse'],+          [/^(R6|R7|R8|R9)$/, 'rCc'],+          [/^R11$/, 'rCd'],+          [/^R5$/, 'rLed'],+          [/^(C4|C5)$/, 'bulk'],+          [/^(C1|C2|C3|C6)$/, 'cDec'],           [/^JP1/, 'jp1'], [/^JP2/, 'jp2'], [/^JP3/, 'jp3'], [/^JP4/, 'jp4'],-          [/^(JMP|Adom_Jumper)/, 'posts'],+          [/^(JMP|Adom_Jumper|GNDSPACER)/, 'posts'],           [/^CCJ/, 'ccj'],           [/^(D1$|D1_glow|D1_cone)/, 'led'],-          [/^(WIRE_MC|MC)(\d+)/, (m) => { const k = +m[2]; return k >= 57 ? 'gndmc' : (k >= 31 ? 'iofield' : 'pwrfield'); }],+          [/^(WIRE_MC|MC)(\d+)$/, (m) => { const k = +m[2]; return k >= 57 ? T.gndmc : (k >= 31 ? ioOf(k) : null); }],           [/^(ETT|ETS)/, 'dock'],           [/^GHOST/, 'ghost'],-          [/^GNDSPACER/, 'posts'],         ];         const REGIONS = [           [0.1135, 0.1260, -0.0880, -0.0760, 'usbc'],@@ -217,24 +257,29 @@ else {           [0.0700, 0.0840, -0.0840, -0.0760, 'jp2'],           [0.0880, 0.1020, -0.0840, -0.0760, 'jp3'],           [0.0850, 0.0970, -0.1360, -0.1240, 'ccj'],-          [0.1220, 0.1280, -0.0710, -0.0650, 'led'],-          [0.1230, 0.1370, -0.0770, -0.0610, 'usbpath'],+          [0.1220, 0.1280, -0.0710, -0.0640, 'led'],+          [0.1230, 0.1370, -0.0770, -0.0610, 'u1'],           [0.1030, 0.1110, -0.0870, -0.0770, 'bulk'],           [0.1600, 0.1800, -0.0860, -0.0500, 'mini'],-          [0.0430, 0.1020, -0.0950, -0.0830, 'pwrfield'],-          [0.1020, 0.1960, -0.0950, -0.0830, 'iofield'],+          [0.0430, 0.0680, -0.0950, -0.0760, 'ps1'],+          [0.0680, 0.0860, -0.0950, -0.0760, 'ps2'],+          [0.0860, 0.1020, -0.0950, -0.0760, 'ps3'],+          [0.1020, 0.1960, -0.0950, -0.0830, 'io'],         ];+        T.io = [HDR.io, '26 RP2350 USER_IO lines on MC31\u2013MC56; interleaved MC57\u2013MC65 are ground returns.'];         const inv = new window.BABYLON.Matrix();         const root = scene.transformNodes.concat(scene.meshes).find(n => (n.name||'').indexOf('control-panel_scaffold') === 0);         function describe(pick) {-          let n = pick.pickedMesh;-          while (n) {-            const nm = n.name || '';-            for (const [re, key] of NAME_RULES) {+          let n = pick.pickedMesh; const names = [];+          while (n) { names.push(n.name || ''); n = n.parent; }+          for (const [re, val] of NAME_RULES) {+            for (const nm of names) {               const m = re.exec(nm);-              if (m) return T[typeof key === 'function' ? key(m) : key];+              if (m) {+                const r = typeof val === 'function' ? val(m) : T[val];+                if (r) return r;+              }             }-            n = n.parent;           }           if (root && pick.pickedPoint) {             root.getWorldMatrix().invertToRef(inv);@@ -259,7 +304,7 @@ else {               tipT.textContent = d[0]; tipB.textContent = d[1];               tip.style.display = 'block';               const r = wrap.getBoundingClientRect();-              tip.style.left = Math.min(ev.clientX - r.left + 14, r.width - 300) + 'px';+              tip.style.left = Math.min(ev.clientX - r.left + 14, r.width - 310) + 'px';               tip.style.top = Math.max(ev.clientY - r.top - 10, 46) + 'px';             } else tip.style.display = 'none';           });