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

180 lines
15 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "README del firmware hbox_v5_bringup (inglés)"
tags: [project-drogheda, firmware, hbox_v5_bringup, readme, en]
date: 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](index.md); 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.
```bash
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:
```bash
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`).
```bash
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
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:
```bash
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.
```bash
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_assert`ed 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.