Drogheda/03-Architecture-Hardware/Auditoria-Final-V56-V57/sec7-firmware.tex

151 lines
12 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters

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.

% ================================================================ FIRMWARE
\section{E $\cdot$ Firmware: dónde estamos y qué hace falta para que «todo funcione»}\label{sec:firmware}
\subsection{0.6.3 contra el hardware de V5.6 / V5.7}
El firmware de campo (\texttt{hbox\_v5\_bringup} 0.6.3, 2025 líneas) sirve a la V5.5 y a la V4. Sobre una V5.6
compila y arranca, pero \textbf{no enciende el módem} y lee mal dos entradas:
\hwtab{\begin{tabular}{@{}L{3.37cm}L{4.37cm}L{4.37cm}L{3.37cm}@{}}
\toprule
\cab{\cw{Función} & \cw{0.6.3 (V5.5)} & \cw{V5.6 / V5.7 (netlist)} & \cw{Efecto con 0.6.3}}\\
\midrule
Riel del módem & siempre encendido (MP1584 desde el riel) & \net{MODEM\_EN} = PC3, apagado por defecto & \alerta{el módem nunca enciende}\\
\rowcolor{HelgenMist} Reset del módem & PCF8574 P7 $\to$ puente a SW4G1 & PC1 directo (R107) & el pulso no hace nada\\
LED del módem & no se lee & PC2 & sin señal de vida\\
\rowcolor{HelgenMist} NTC & PB1, 3V3--10k--NTC--GND & PC5, nodo NTC del LTC4040 ×0.5455 & lectura basura\\
Flotación & 4.00 V (Li-ion) & 3.50 V (LFP, JP2 2-3) & rearranques de carga mal juzgados (0.95 × flot.)\\
\rowcolor{HelgenMist} Corte en batería & 3.40 / 3.70 V & LFP: 2.95 / 3.20 V & corta con el paquete a medio llenar\\
Ignición & \texttt{digitalRead} PA5 & ADC (12 V $\to$ 1.38 V) & aleatoria en máquinas de 12 V\\
\rowcolor{HelgenMist} Acelerómetro $\cdot$ RTCM & — & SC7A20 en 0x18 (INT1 PB9) $\cdot$ USART6 RX en PC7 & sin usar\\
Ciclo en batería & \texttt{ENABLE\_DUTY 0}; con 1: espera activa a 96 MHz, 120--180 s por ventana & STOP + RTC posible (LSE Y4) & piso de 165 mW solo por el MCU\\
\bottomrule
\end{tabular}}
\textbf{Entregado hoy:} \texttt{04-Source-Code/firmware/hbox\_v5\_bringup/board\_v56.h}, el mapa de los 64 pines
derivado del netlist (idéntico para V5.6 y V5.7), con los umbrales del hardware como constantes y las notas de
cada pin nuevo. Extracto:
\begin{lstlisting}
#define PIN_MODEM_EN PC3 // -> R105 10k -> EN del AP64350; R106 100k a GND: HIGH = 3V3_MODEM encendido
#define PIN_MODEM_RST PC1 // -> R107 1k -> J7.5 (RESET XBee, activo en BAJO; SW4G1 en paralelo). Colector abierto.
#define PIN_MODEM_LED PC2 // <- R108 1k <- J8.8 (LED del modem). Entrada.
#define PIN_RTCM_TAP PC7 // USART6_RX <- R111 1k <- DOUT_4G (RTCM3 hacia RX2 del F9P). Solo escucha.
#define PIN_ACC_INT1 PB9 // INT1 del SC7A20 (EXTI9): despertar por movimiento desde STOP
#define PIN_NTC_CELL PC5 // nodo NTC del LTC4040 x 120k/(100k+120k); solo con VEH5V presente
#define PIN_IGN_SENSE PA5 // ADC: x0.1154; umbral 0.80 V ON / 0.55 V OFF (12 V -> 1.38 V)
#define BOARD_PFI_FALL_V 4.40f // R51 270k / R52 100k
#define BOARD_VSYS_BACKUP_V 4.79f // R53 499k / R54 100k
#define BOARD_VFLOAT_V 3.50f // JP2 2-3 (LFP), F1 = 0, F0 = 1
#define BOARD_ICHG_A 1.40f // R50 1.43k
#define BOARD_IIN_LIMIT_A 2.50f // RS1 10 mR Kelvin
\end{lstlisting}
\subsection{Los algoritmos que ya existen (0.6.3) y que 0.7.0 hereda}\label{sec:algoritmos}
\paragraph{1 $\cdot$ Gobernador de carga (\texttt{chargeService}).} El cargador no se enciende «porque sí»: se
enciende cuando el riel demuestra que puede con la carga y se corta antes de que el PFI lo haga. Nació del incidente
del 10-ago (carga + ráfaga LTE $\to$ PFI $\to$ bucle de reinicios). Con RS1 Kelvin el LTC4040 ya recorta solo a 2.5 A,
pero el gobernador sigue siendo la segunda línea.
\begin{figure}[H]\centering
\begin{tikzpicture}[->, >=Stealth, node distance=17mm and 13mm, auto, font=\scriptsize,
every state/.style={draw=HelgenIndigo, fill=HelgenMist, text=HelgenIndigo, minimum size=11mm, inner sep=1pt},
every edge/.style={draw=HelgenIndigo, thick}]
\node[state] (init) {INIT};
\node[state, right=of init] (hold) {HOLDOFF};
\node[state, right=of hold] (prov) {PROVING};
\node[state, right=of prov] (on) {ON};
\node[state, below=of on] (shed) {SHED};
\node[state, left=of shed] (cool) {COOLDOWN};
\node[state, left=of cool] (wait) {WAIT};
\node[state, above=of prov, yshift=-6mm] (hot) {HOT};
\path (init) edge node {arranque} (hold)
(hold) edge node {120 s} (prov)
(prov) edge node {riel $\ge$ 5.05 V 30 s} (on)
(on) edge node[right] {$<$ 4.70 V (muestra) o media $<$ 4.90 V 1 s} (shed)
(shed) edge node[above] {5 V sigue 3 s} (cool)
(shed) edge[bend left=25] node[below, pos=0.6] {5 V se fue} (wait)
(cool) edge node[above] {60 s $\cdot$ 2$^n$ $\cdot$ 30 min} (wait)
(wait) edge[bend left=15] node[left, pos=0.3] {riel OK} (prov)
(on) edge[bend right=20] node[above left] {celda $\ge$ 45 °C} (hot)
(hot) edge[bend right=20] node[above right] {$<$ 40 °C} (prov);
\end{tikzpicture}
\caption{Gobernador de carga (0.6.1--0.6.3). HOLDOFF también tras cada STACK ON (ventana de registro LTE).
Un corte cuenta y dobla el enfriamiento solo si el 5 V sigue ahí 3 s después. Pulso de rearranque de 500 ms del
LTC4040 bajo 0.95 × flotación; nunca con FAULT activo. En 0.7.0 cambian las constantes de flotación y de paquete
(LFP), no la máquina.}
\end{figure}
\paragraph{2 $\cdot$ Recuperación de enlace.} Gracia de 90 s tras STACK ON; sin NMEA válido 60 s $\to$ ciclo de etapa
(máximo uno cada 5 min); RTK perdido 15 min después de haberlo tenido $\to$ ciclo (uno cada 30 min); tres ciclos
$\to$ \textbf{LIMP} (se queda encendida y lo reporta). Invariante 3: las correcciones viven en el módem, el ciclo
de etapa es el remedio, nunca un reset del GNSS. \textbf{0.7.0:} el ciclo de etapa incluye al módem en orden —
\net{MODEM\_EN} = 0, PA1 = 0, esperar 10 s a que los rieles lleguen a 0 V (PWR\_RETURN\_OFF\_MS), PA1 = 1, NMEA,
\net{MODEM\_EN} = 1 — para no cargar el boost con el módem registrándose mientras la etapa hace inrush (F-8).
\paragraph{3 $\cdot$ Modo B y telemetría en banda.} K1 se engancha 10 s después del primer NMEA; el MCU retransmite
TX2 del F9P hacia el módem y \emph{inyecta} sus líneas solo cuando el anillo de transmisión lleva $\ge$ 8 ms vacío
(nunca parte una sentencia): \texttt{\$PHLG} (campos 1--24, $\le$ 100 caracteres: el 4G NTRIP Master tira líneas de
más de $\sim$108) cada 30 s, \texttt{\$PHCG} (energía y gobernador) en el hueco siguiente, \texttt{\$PHEV} por evento;
antes de cortar la etapa o reiniciar, se vacía la cola y se suelta K1. El servidor (\texttt{retranslator.py},
\texttt{\_parse\_phlg} / \texttt{\_parse\_phcg}) no cambia. Fail-safe: con el MCU muerto, K1 suelto = F9P $\to$
módem directo.
\paragraph{4 $\cdot$ Vigilancia del módem.} Hoy es indirecta: la caída del riel en ventanas de 30 s (ráfagas LTE
= vivo; plano 4 ventanas = oscuro, con histéresis 30/50 mV) y la edad del RTCM en los campos 13/14 del GGA.
\textbf{0.7.0} la vuelve directa con el hardware nuevo: \net{MODEM\_LED} (PC2) y la toma de RTCM3 (PC7, bytes 0xD3
en los últimos 120 s). Pulso de \net{MODEM\_RST} (PC1, 500 ms) 5 s después de \net{MODEM\_EN} y si no hay vida en
90 s (máximo 2 por ventana).
\paragraph{5 $\cdot$ Cortes térmicos y de batería.} Etapa fuera a 60 °C (TMP102 o NTC), rearme a 55; aviso a 50.
Batería: corte y rearme por media de 200 ms (0.6.3). \textbf{0.7.0:} umbrales LFP (2.95 / 3.20 V) y la
temperatura de la celda ya no viene de un NTC propio sino de U4 (cargador) y U18 (módem); \net{NTC\_CELL} se
reporta solo con 24 V presente.
\paragraph{6 $\cdot$ Ventilador.} Política v3.0.3: con vehículo (5 V + ignición) 100 \% siempre; en batería termostato
48/45 °C — que en V5.6/V5.7 no tiene efecto porque sin 24 V no hay 5V\_FAN. Sin cambios.
\paragraph{7 $\cdot$ Medición.} ADC calibrado con VREFINT de fábrica; muestras rápidas por lazo con mínimo de ventana
(detecta la ráfaga) y media de 200 ms (decide); la media del paquete, no una muestra, para cortar.
\paragraph{8 $\cdot$ Supervisión propia.} IWDG de 16 s; razón de cada reset propio en los registros de respaldo del
RTC (sobrevive al reset) y en el \texttt{\$PHEV BOOT} siguiente; holdoff de carga ×2$^n$ tras un reset causado por
una carga; bandera MANUAL en EEPROM emulada (solo 0x5A = manual).
\paragraph{9 $\cdot$ Ciclo de respaldo (nuevo).} La figura \ref{fig:ciclo}. Despertadores: alarma RTC (10 min;
adaptativo 15 $\to$ 30 $\to$ 60 min después de 24 h es una opción que el servidor puede pedir), INT1 del SC7A20
(movimiento: la máquina se mueve, hay que reportar) y el regreso del 24 V. Posición: la última guardada con
\texttt{pwr=BATT} y bandera de antigüedad; un fix fresco solo si llega en la ventana.
\subsection{Lo que falta para 0.7.0, con tamaño}
\hwtab{\begin{tabular}{@{}L{0.78cm}L{6.27cm}L{1.96cm}L{6.47cm}@{}}
\toprule
\cab{\cw{} & \cw{Trabajo} & \cw{Tamaño} & \cw{Prueba que lo cierra}}\\
\midrule
F-1 & \texttt{board\_v56.h} + \texttt{-DHBOX\_BOARD\_V56}; MODEM\_EN/RST/LED en setStack y en el arranque; NTC\_CELL; flotación y umbrales LFP; ignición por ADC & \textbf{1 día} (0.7.0-pre) & Tarjeta del piloto en banco: el módem enciende 2 s después del NMEA, registra, RTCM en PC7; \texttt{tntc} razonable a 24 V; ignición OK a 12 y 24 V\\
\rowcolor{HelgenMist} F-2 & Ciclo de respaldo: STOP + alarma RTC (LSE con fallback LSI), apagado ordenado, W5500 PD, K1 suelto, reporte ×2, despertar por INT1 & 3--4 días & 20 ciclos con paquete al 20 \% a 45 °C; piso $<$ 100 mW; el servidor ve 2 líneas por ventana\\
F-3 & SC16IS752: driver mínimo (baudios, FIFO, IRQ en PB8); \textbf{EFCR auto-RS-485 + RTS en bajo como primera escritura}; eco/lazo para las pruebas B3/B4 & 1 día & RS-485 y RS-232 en lazo a 115200 sin errores; bus libre $<$ 100 ms después del reset\\
\rowcolor{HelgenMist} F-4 & Ethernet de campo: DHCP o IP fija configurables, servidor/puerto configurables, reconexión, PD en batería (parte del 0.6.0-eth ya existe) & 2 días & 24 h de espejo NMEA + \$PHLG a un servidor TCP sin bloquear el lazo\\
F-5 & SC7A20: WHO\_AM\_I 0x11, 10 Hz low power, umbral de movimiento, INT1 enclavada & 0.5 día & Golpe en la mesa despierta del STOP\\
\rowcolor{HelgenMist} F-6 & Vigilancia del módem por LED y RTCM; pulso de reset con límite & 0.5 día & Desconectar la antena LTE: la unidad lo reporta en $\le$ 2 min\\
F-7 & Modo B con el módem apagado/encendido por software: no insertar hasta que el módem viva; soltar antes de MODEM\_EN = 0 & 0.5 día & Sin líneas truncadas en el historial crudo del servidor\\
\rowcolor{HelgenMist} F-8 & Secuencia de recuperación con módem (arriba) & 0.5 día & 10 ciclos de recuperación forzados sin reset del MCU\\
\bottomrule
\end{tabular}}
Compilación como hasta ahora: arduino-cli + STM32duino 3.x, \path{GenF4:pnum=GENERIC_F411RETX,usb=CDCgen,xserial=generic,rtlib=nanofp} (sin \texttt{nanofp} el \texttt{\%f} sale vacío), \texttt{build\_opt.h} con anillos UART de
256, HSE 25 MHz por \texttt{SystemClock\_Config}. Binario con la tarjeta en el nombre:
\texttt{hbox-tarjetaV56\_0.7.0.bin} (sirve a V5.7). \textbf{Regla que no cambia: banco antes de campo.}
\begin{helgennotice}[Dónde puede fallar el firmware aunque el hardware esté bien (riesgos F)]
(a) \textbf{STOP mal hecho}: un periférico con reloj encendido o un pin flotando duplican el piso; se mide, no
se supone. (b) \textbf{Rearranque del módem}: si \net{3V3\_MODEM} no llega a 0 V entre ventanas (C43 de 220 $\mu$F con
$\mu$A de carga tarda; Rdfu1 lo sostiene), el módem puede quedar «encendido pero muerto»: el pulso de reset es la
defensa y hay que verificar que SW4G1-por-PC1 revive al 4G NTRIP Master en ese estado. (c) \textbf{El 4G NTRIP
Master tarda}: registro + NTRIP $\approx$ 20--40 s; la ventana no puede ser de 10 s. (d) \textbf{RTC}: LSE que no
arranca sin fallback = unidad que no despierta. (e) \textbf{Líneas largas}: cualquier campo nuevo en \texttt{\$PHLG}
rompe el límite de $\sim$100 caracteres del módem; lo nuevo va en \texttt{\$PHCG}/\texttt{\$PHEV}.
\end{helgennotice}