Leo generated the vendor part with easyeda2kicad (C5120257) -> Drogheda-v6.kicad_sym / .pretty / .3dshapes, now registered in sym-lib-table and fp-lib-table. CROSS-CHECK: the EasyEDA/LCSC symbol independently CONFIRMS the datasheet transcription - pads 1-54 match the u-blox pin assignment function for function, and the 21 Reserved pads are identical. Pads 55-102 are 48 extra GND pads (the ground array under the module), which our symbol was missing; T3a2 adds them stacked on the pin-1 coordinate so one GND label serves all. Symbol is now 102/102 pins, footprint = Drogheda-v6:LCC-LGA-102_L22.0-W17.0_FM660. Block N as wired (verified by rebuilding connectivity from label-on-pin geometry): GNSS_TX U16.16 + U18.43 GNSS_RX U16.17 + U18.42 DOUT_4G U18.26 (RXD2, RTCM in - modem end lands in T4) USART1_RX U16.43 + Rdfu1.1 + U18.27 (TXD2 uplink; K1.1 also on this net per the PCB) GNSS_RESET_N U16.53 (PC12) + U18.49 + R105 10k pull-up to 3V3_GNSS GNSS_TIMEPULSE U16.23 (PA7) + U18.53 GNSS_ANT_DETECT U16.9 (PC1) + U18.4 GNSS_ANT_SHORT_N U16.10 (PC2) + U18.6 GNSS_RTK_STAT U16.11 (PC3) + U18.20 <- hardware answer to are-corrections-being-used 3V3_GNSS = U21.5 + U18.33/34 + C120-C124 + R105; U21 fed from SW_5V (stays MCU-gated) V_BCKP = U18.36 on the UNGATED 3V3 so ephemeris survives a power-cycle 33 no-connects: the 21 reserved pads plus V_USB, USB_DM/DP, ANT_OFF, SDA, SCL, TX_READY, D_SEL (open = UART mode), SAFEBOOT_N, EXTINT, GEOFENCE_STAT and the LDO NC/NR pin. T3c fixes two coordinates the generators emitted as 3.552713679e-15 (i.e. zero); KiCad is not guaranteed to accept exponent notation. See the script header for the lesson: a first attempt used a bare numeric regex over the whole file and corrupted 264 UUIDs, because segments such as 895e-4153 parse as scientific notation. Reverted from backup and redone scoped to (at ...) forms only, with a UUID-integrity guard. Verified 2298 UUIDs, 0 malformed, 0 exponent coordinates. STILL OPEN: the PCB has no U18/U21/passive footprints yet - that is a KiCad Update-PCB-from-Schematic. And confirm the -04B datasheet pin assignment on paper. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJ4eAB6zjQT49RVwpgfKdt
51 lines
2.1 KiB
Python
51 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""v6 T3c - replace scientific-notation COORDINATES with exact 0.
|
|
|
|
Float accumulation in the T3a/T3b generators emitted coordinates like 3.552713679e-15
|
|
(i.e. zero). KiCad's s-expression parser is not guaranteed to accept exponent notation.
|
|
|
|
!! LESSON (2026-08-24): a first attempt used a bare numeric regex over the whole file and
|
|
corrupted 264 UUIDs - segments such as "895e-4153" parse as scientific notation.
|
|
This version ONLY touches tokens inside an (at ...) form, only when the token is a
|
|
complete float in exponent form, and only when |value| < 1e-9. It also refuses to run
|
|
if any UUID would change.
|
|
|
|
Usage: python3 2026-08-24_v6_T3c_fix_sci_notation.py [--apply]
|
|
"""
|
|
import re, sys, os, shutil
|
|
|
|
KI = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '03-Architecture-Hardware', 'kicad')
|
|
FILES = [os.path.join(KI, 'Drogheda-sym.kicad_sym'), os.path.join(KI, 'hbox-watchdog-v6.kicad_sch')]
|
|
APPLY = '--apply' in sys.argv
|
|
AT = re.compile(r'\(at ([^()]*)\)')
|
|
NUM = re.compile(r'^[+-]?(?:\d+\.?\d*|\.\d+)[eE][+-]?\d+$')
|
|
UUID = re.compile(r'\(uuid "([^"]*)"\)')
|
|
|
|
total = 0
|
|
for f in FILES:
|
|
src = open(f, encoding='utf-8').read()
|
|
changed = []
|
|
def fix(m):
|
|
toks = m.group(1).split()
|
|
out = []
|
|
for t in toks:
|
|
if NUM.fullmatch(t):
|
|
v = float(t)
|
|
if abs(v) >= 1e-9:
|
|
sys.exit('REFUSING: non-negligible exponent coordinate %s' % t)
|
|
changed.append((m.group(0), t)); out.append('0')
|
|
else:
|
|
out.append(t)
|
|
return '(at ' + ' '.join(out) + ')'
|
|
new = AT.sub(fix, src)
|
|
if UUID.findall(new) != UUID.findall(src):
|
|
sys.exit('REFUSING: a UUID would change - aborting')
|
|
print('%-30s %d coordinate(s) fixed' % (os.path.basename(f), len(changed)))
|
|
for before, tok in changed:
|
|
print(' %s (token %s -> 0)' % (before, tok))
|
|
total += len(changed)
|
|
if APPLY and changed:
|
|
shutil.copy2(f, f + '.T3cbak'); open(f, 'w', encoding='utf-8').write(new)
|
|
print('total: %d' % total)
|
|
print('APPLIED' if APPLY else '\nDRY RUN - nothing written. Re-run with --apply.')
|