hbox-docs/docs/descargas/hbox-v5-bringup-README.md

15 KiB
Raw Permalink Blame History

title tags date
README del firmware hbox_v5_bringup (inglés)
project-drogheda
firmware
hbox_v5_bringup
readme
en
2026-09-27

hbox_v5_bringup — EinarBoard v5 first-flash bring-up firmware

Nota (sitio de documentación): este es el README del código fuente del firmware hbox_v5_bringup, en inglés, para quien compila. La tabla de binarios vigentes y sus SHA-256 es la de Descargas; la tabla «Release» de abajo se quedó en 0.5.1 y solo documenta cómo se nombran los archivos.

Bench-proves a newly assembled v5 board over USB-C J11 only. Never powers the RTK stack. 0.5.0: Modo B in-band $PHLG (server Salud column) on top of the 0.4.0 field-minimum: AUTO by default (stack self-powers with 5 V on P2, kept on through 5 V loss), watchdog, fan, link recovery, LEDs; charge OFF. Bench mode: P+Y stack ON/OFF, n NMEA monitor (fix 4 = RTK FIX). Console (0.2.1): CR+LF lines, EVT on every state change, named STAT every 5 s, $PHLG every 10 s in the fleet v3.x layout (server-parseable). Checks: HSE 25 MHz + USB CDC · LSE Y4 · I2C: PCF8574 0x20 / SHT40 0x44 / TMP102 0x48 / SC16IS752 0x4D · gauge + RGB LED walk · ADC · digital inputs. Prints PASS/FAIL, then a STAT line every 2 s. Console commands: r rerun · g gauge walk · i I2C scan · h help.

Procedure for technicians (ES): 06-Testing-Validation/2026-09-15_Drogheda_EinarBoard-v5_Procedimiento-Prueba-y-Flasheo_ES_v1.0.md

Build

STM32duino core 3.x (STMicroelectronics:stm32). Target is the generic F411RE, not the Blackpill.

arduino-cli compile \
  --fqbn "STMicroelectronics:stm32:GenF4:pnum=GENERIC_F411RETX,usb=CDCgen,xserial=generic,rtlib=nanofp" \
  --build-property "build.extra_flags=-DHSE_VALUE=25000000UL" \
  --output-dir out hbox_v5_bringup

rtlib=nanofp is required — the default newlib-nano build prints nothing for %f, so every voltage and temperature line would be blank. SystemClock_Config() is overridden in the sketch (HSE 25 MHz → 96 MHz, USB 48 MHz) because the generic variant defaults to HSI, which is not accurate enough for USB.

EinarBoard v4 (socketed Blackpill) — same sketch, board_v4.h

The v4 board is this design on a Blackpill (verified pad-by-pad against hbox-watchdog-v4.kicad_pcb); only ETH_INT moves to PB2. Build with the Blackpill variant and the board switch:

arduino-cli compile \
  --fqbn "STMicroelectronics:stm32:GenF4:pnum=BLACKPILL_F411CE,usb=CDCgen,xserial=generic,rtlib=nanofp" \
  --build-property "build.extra_flags=-DHBOX_BOARD_V4" \
  --output-dir out-v4 hbox_v5_bringup
mv out-v4/hbox_v5_bringup.ino.bin release/hbox-tarjetaV4_0.5.1.bin

PB2 is BOOT1 on the F411: enter DFU with USB only (W5500 unpowered) so INTn cannot hold BOOT1 high. The first console line must read board=EinarBoard v4 (HBOX v4).

Ethernet de banco (0.6.0-eth) — -DENABLE_ETH=1

Build separado; el binario de campo 0.5.8 no lo incluye. Necesita la librería Ethernet (arduino-cli lib install Ethernet).

arduino-cli lib install Ethernet
arduino-cli compile --fqbn "$FQBN_V5" \
  --build-property "build.extra_flags=-DHSE_VALUE=25000000UL -DENABLE_ETH=1" \
  --output-dir out-v5-eth hbox_v5_bringup
# V4:  --fqbn "$FQBN_V4" --build-property "build.extra_flags=-DHBOX_BOARD_V4 -DENABLE_ETH=1" --output-dir out-v4-eth

Sin PoE (J10 solo datos). Con 5 V presente el W5500 sale del reset, pide DHCP o cae a 192.168.7.2/24 y abre un TCP a 192.168.7.1:5010 (portátil con nc -lk 5010), por donde salen en espejo NMEA + $PHLG + $PHCG (0.6.2) + $PHEV + $PHID. Cable directo al portátil (Auto-MDIX) o cualquier switch. Overrides: -DETH_IP=a,b,c,d -DETH_SERVER_IP=a,b,c,d -DETH_SERVER_PORT=n -DETH_DHCP=0. Tecla E = on/off. Ver CHANGELOG 0.6.0-eth.

Simulador en PC (0.6.1, ampliado en 0.6.2 y 0.6.3) — ../tools/hostsim_v5

Antes de flashear un cambio del gobernador de carga, del riel o del $PHLG, correr el simulador: compila este sketch sin cambios contra stubs y un modelo eléctrico de la entrada de 5 V (calibrado con H0027) y revisa 54 escenarios (ráfagas del módem, cable débil, desconexión del 24 V, hiccup, batería mala, pausa NTC, autoprueba r, vuelta del millis(), VDDA, formato del $PHLG/$PHCG y largo de las líneas que van al módem, tecla X; desde 0.6.3 también respaldo corto con el paquete bajo, motivo del reset en el RTC y espera de carga creciente, CHG_NOCHG, SLEEP con la media y la vigilancia del módem con histéresis) más un invariante de seguridad del cargador en cada vuelta del lazo.

bash ../tools/hostsim_v5/run.sh                          # todo PASS = exit 0
bash ../tools/hostsim_v5/run.sh /ruta/a/otra/copia old   # mismos escenarios contra otra versión (p. ej. 0.6.0)

Necesita g++ con -m32 (Linux: g++-multilib); en un Mac con Apple silicon, dentro de Docker linux/amd64 — ver tools/hostsim_v5/README.md. No reemplaza la prueba de banco.

Prueba de largo de línea (0.6.2) — tecla X + ../tools/phtst_report.py

El módem (NTRIP Master) descarta las líneas largas que el MCU mete en banda (0.6.1: ninguna $PHLG de 125–131 caracteres llegó al servidor). Con Modo B activo, X manda 105 líneas $PHTST de largo exacto (100…140, controles de 60 y 6 pares pegados), ~50 s; X otra vez la cancela. Unos 15 s después de PRUEBA DE LARGO fin bajar el historial crudo de la unidad (monitor → ⬇ Historial crudo) y:

python3 ../tools/phtst_report.py H0027.txt

Da el límite por línea, si el módem corta por línea o por ráfaga, y si recorta las líneas en vez de descartarlas.

Diagnóstico de campo (0.6.3)

  • Reset al volver el 5 V: tras ≥ 10 s de respaldo (0.5.9) y también tras ≥ 1 s si la media de 200 ms del paquete bajó de 3.70 V (BACKUP_WEAK_VBAT): con el paquete bajo el módem se apaga en el boost. Antes del reset sale en banda $PHEV PWR_RETURN_RESET,<razón>.
  • Motivo del reset anterior: queda en los registros de respaldo del RTC (BKP16R–BKP18R; BKP19R lo usa la autoprueba RTC_BKP) y sale en consola (EVT RESET anterior: …) y en $PHEV BOOT … prev=<razón>[+carga] n=N. Con +carga (el 5 V se cayó < 10 s después de arrancar la carga) la espera de carga del arranque siguiente es 120 s × 2^n, hasta 30 min.
  • CHG_NOCHG / STAT ltc=C8_BAJO: carga permitida, pulso de rearranque ya probado y el LTC4040 en «C/8» con el paquete bajo 3.80 V: revisar JP2/JP3/JP4 (flotación) y el paquete.
  • STAT phlg_aire= phcg_aire= aire_max= y tecla t (aire> …, las dos líneas exactas que van al módem, con su largo): para separar «la unidad no manda» de «el servidor no muestra».
  • Vigilancia del módem (STAT sag5= sagb= flat= modem=, $PHEV MODEM_DARK/MODEM_BACK, solo diagnóstico): 4 ventanas seguidas < 30 mV = oscuro, ≥ 50 mV = vivo (sag5 en 24 V, sagb en batería); las ventanas con un cambio de alimentación o de la corriente de carga no cuentan.

Puente 0.5.6 — MODEM_RST desde el MCU (V4 y V5)

El módem 4G (socket J7/J8) solo tiene su reset (MODEM_RST, J7.5) en el botón SW4G1. Desde 0.5.6 el firmware lo pulsa por el pin libre P7 del PCF8574 U13 (SOIC-16W, pin 12):

U13 pin 12 (P7)  ──|<──  SW4G1 pad 1 (MODEM_RST)        diodo Schottky BAT54 / 1N5819 (1N4148 sirve)
                cátodo   ánodo
  • Verificar con M en consola (etapa ON): SW4G1 pad 1 debe caer a < 0.4 V durante 0.5 s y el módem reinicia (LEDs del módulo apagan y vuelven). STAT cuenta los pulsos en mrst=.
  • Sin el puente, el firmware es idéntico salvo que el pulso no llega a nada.

Flash (DFU, J11)

Hold SW2 (BOOT0) → tap SW1 (RESET) → release SW2 → device 0483:DF11 appears.

dfu-util -a 0 -s 0x08000000:leave -D release/hbox-v5-bringup_0.5.1.bin

or STM32CubeProgrammer → USB → Connect → Download release/hbox-v5-bringup_0.5.1.bin @ 0x08000000.

Release

File Version SHA-256 (first 16) Size
release/hbox-v5-bringup_0.5.1.bin 0.5.1 (2026-09-18) — USE THIS (field-minimum + Modo B telemetry + diagnostics) e1f351084e803306 79 804 B
release/superseded/hbox-v5-bringup_0.5.0.bin 0.5.0 — superseded (24-field $PHLG, no $PHEV) 98656ddcc4e209e2 77 312 B
release/superseded/hbox-v5-bringup_0.4.0.bin 0.4.0 — superseded (no in-band telemetry) a8de74b3d7768e9d 75 524 B
release/superseded/hbox-v5-bringup_0.3.0.bin 0.3.0 — superseded (AUTO opt-in, no watchdog/fan/recovery) d4608c739cef2661 72 860 B
release/superseded/hbox-v5-bringup_0.2.1.bin 0.2.1 — superseded (no AUTO mode; stack OFF on 5 V loss) 78b34f4603550c05 70 084 B
release/superseded/hbox-v5-bringup_0.2.0.bin 0.2.0 — superseded (LF-only console, no EVT/$PHLG) 8491625d494f9ee1 64 780 B
release/hbox-v5-bringup_0.1.1.bin 0.1.1 — superseded (no bench mode) 91ca6f87a86686be 55 104 B
release/hbox-v5-bringup_0.1.0.bin 0.1.0 — SUPERSEDED (no float printf, ETH_CS driven) 1a9a77ae479c8f86 41 040 B

Changelog

  • 0.5.1 (2026-09-18) — diagnostics in band. $PHLG gains 5 append-only fields (25..29): up_s, pwr (VEH|BATT), v5min, vbat_min (lowest single-shot ADC reading in the 30 s window, sampled every loop iteration — catches the ms-scale LTE-burst sags that trip the LTC4040 PFI), bkp_n. New $PHEV,<up_s>,<CODE>,<detail>*CS event sentence on every state change (STACK_ON/OFF+reason, BACKUP_START/END, RECOVERY, LIMP/LIMP_END, TEMP_CUT/REARM, V5_LOW/LOST/OK, IGN_ON/OFF, SLEEP/SLEEP_END, MODOB_ON/OFF, BOOT), queued (6 deep) and sent in idle gaps ahead of $PHLG; STACK_OFF/MODOB_OFF are flushed synchronously (≤ 120 ms) before K1 releases. STAT adds v5min= vbatmin= bkp=. Server side: 02-Architecture-Software/htracker-patches/ (retranslator: 29-field parser, $PHEV store + events in status JSON, 5 diagnostic rules) — old parsers ignore the extras.
  • 0.5.0 (2026-09-18) — Modo B: $PHLG in band. Once the stack is on and the F9P has been talking for 10 s, USART1 (PA10 tap / PA9) is started before K1 (PB5) is energised; the F9P TX2 stream then flows F9P → PA10 → MCU → PA9 → K1 NO → modem DIN byte for byte, and a $PHLG (same 24 fields) is injected every 30 s only after > 8 ms of line idle (a GGA is never split). Corrections modem → F9P stay on their direct wire. Fail-safe is hardware: PB5 low (reset, IWDG, any stack-off) = K1 NC = direct path. Prerequisites shipped with it: 256-byte UART rings (build_opt.h, static_asserted at compile), non-blocking SHT40 (two-phase kick/poll), console STAT/$PHLG deferred to line-idle gaps, K1 released before EEPROM.write (flash erase stalls the core) and before the r self-tests. B toggles Modo B (default allowed). STAT adds modoB= relay= phlg_aire=. Server: no change needed — retranslator._parse_phlg already accepts the sentence; units get the Salud column.
  • 0.4.0 (2026-09-17) — field-minimum ("-fm"): what a unit needs to be left on a machine for days without the production charge governor. AUTO is now the default (only the flash byte 0x5A means MANUAL; a virgin board powers the stack by itself). IWDG 16 s watchdog · fan policy = v3.0.3 (vehicle 5 V+ign → 100 %; battery → thermostat 48/45 C on the hottest sensor) · link recovery (no valid NMEA 60 s after a 90 s grace → 5 s stack cycle, max 1/5 min; RTK lost 15 min after having it → one cycle, max 1/30 min; 3 NMEA-loss cycles → LIMP, stack stays ON) · gauge DB1-4 (3.60/3.75/3.90/3.97 V, −0.10 hyst) + RGB state via PCF8574 (green RTK · blue on/no RTK · magenta on/no NMEA · yellow battery · red off) · thermal cut tbat/tntc ≥ 60 C, re-arm < 55 C, warning 50 C · low battery cut 3.40 V, re-arm 3.70 V or 5 V return · $PHLG now carries recoveries, limp, fan_pwm, state PWRCYC/SLEEP, link LIMP (verified against retranslator._parse_phlg + web_monitor badges). CHARGE STAYS OFF — the pack is one-shot until the production port.
  • 0.3.0 (2026-09-17): AUTO mode (A toggles, persisted in flash via STM32duino EEPROM emulation — survives reset and power loss; factory default = MANUAL). In AUTO the stack powers itself 3 s after 5 V is present on P2, no console needed. Battery-backup test: in AUTO, losing the 5 V input keeps the stack ON from the pack and logs EVT BACKUP inicio / BACKUP fin dur= nmea_durante= vbat= (NMEA continuity through the dropout = LTC4040 backup proven); stack dropped at vbat < 3.40 V or tbat/tntc > 50 C (AUTO(pausa) until 5 V is re-plugged). MANUAL keeps 0.2.x behaviour (stack OFF on 5 V loss). STAT adds modo= and backup=. Charge stays OFF in every mode. RAM +8 KB (EEPROM sector buffer).
  • 0.2.1 (2026-09-17): console made monitorable — every line ends CR+LF (no more PuTTY staircase); EVT up=… line on every state change (stack ON/OFF with reason and the expected voltages, ignition edge, 5 V present/lost, charger status/fault edges, first NMEA frame / NMEA lost >5 s, GGA fix-quality change, stack refused/cancelled); STAT every 5 s with named values (ign=ON, chrg=idle, flt=none, tntc=n/c, i2cerr=, t_on=, nmea=/bad=); $PHLG every 10 s + after each stack change, same 24-field layout + XOR checksum as fleet fw v3.x (verified against htracker/retranslator.py::_parse_phlg; fw=0.2.1-bu, state=BENCH|RUN, link=SRCH|DEGR|OK); NMEA checksum verified (bad frames counted as rxbad); P arms non-blocking (10 s window), Y confirms; new commands t ($PHLG now), l (field legend), v (multimeter checkpoints for the stack gate: SYS5V/PWR_CTRL/GATE_LS/SW_5V); stack auto-OFF if 5 V is lost; v5=…(BAJO) + EVT when VEH5V drops under 4.6 V (LTC4040 PFI zone: PFI divider R51 270k/R52 100k → 4.44 V falling, backup VSYS 4.79 V via R53 499k/R54 100k) — the 24-Jul modem-hiccup mechanism, now visible in the log. Build: no-op ctags + explicit definition order (arduino/ctags unreachable from the build host).
  • 0.2.0 (2026-09-17): bench mode for the assembled unit — P+Y powers the RTK stack (only with 5 V on P2), P again turns it off; n streams $GxGGA from the simpleRTK2B UART1 (PA3, 115200) for 20 s with fix/sats/HDOP; STAT shows stack= and the last GGA. Charge stays disabled, K1 released. Uses the core's Serial2 (USART2).
  • 0.1.1 (2026-09-16, audit): build with rtlib=nanofp (floats printed blank in 0.1.0); ETH_CS now INPUT_PULLUP instead of driving HIGH into the unpowered W5500; reset cause reports PIN only when PINRSTF is set (else UNKNOWN).
  • 0.1.0 (2026-09-15): first build.

⚠ Do not flash blackpillrtkcode_v3 (v3.0.3) on v5

Its PIN_BATLED1..4 = PB12–PB15 are the W5500 SPI2 bus on this board. board_v5.h is the verified v5 pin map — the production v5 firmware should include it rather than redefine pins.