151 lines
12 KiB
TeX
151 lines
12 KiB
TeX
% ================================================================ 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}
|