Document full G2 command inventory from interactive submenu exploration

All 12 submenus explored via live hardware ? help. Key findings:
- A3981: 6 cmds (sm/ss/st for microstep and torque control)
- ADC: 5 cmds (bdid=STATIONARY, bdrevid=A, scan deadlock hazard)
- MOT: 25 cmds (azscanwxp radio telescope, pid tuning, vms velocity)
- DVB: 38 cmds (full DiSEqC 2.x suite, blind scan, NID streaming)
- PEAK: 6 cmds (rssits polarity-switching RSSI, H=489 V=235)
- GPIO: 4 cmds (regs dumps all 92 K60 pins across ports A-E)
- EEPROM: 3 cmds (inv=INVALIDATE not inventory, mostly unused)
- STEP: 7 cmds (raw ustep API, Kp=250 Kv=50, velocity/position)
- LATLON: satellite triangulation calculator (4-param, centidegrees)
- DIPSWITCH: raw GPIO + interpreted config (101=DISH 110+119+129)

Boot sequence enriched with SPI bus speeds and antenna ID string.
Added Known Console Hazards section (scan deadlock, q shell kill).
This commit is contained in:
Ryan Malloy 2026-02-12 23:24:42 -07:00
parent 7ff91b08ea
commit c010cee282

209
CLAUDE.md
View File

@ -68,7 +68,7 @@ Five known Winegard dish variants documented by Gabe Emerson (KL1FI) / saveitfor
- **Carryout G2 is RS-422 full-duplex:** Separate TX/RX pairs at 115200 baud via RJ-12 6P6C, vs. RS-485 half-duplex at 57600 on the Trav'ler variants. Tested with DSD TECH SH-U11 USB-to-RS422 adapter (FTDI FT232R). **Polarity matters** — A/B (or +/-) labeling is not standardized; if you get garbled data at the correct baud rate, swap the +/- wires on the RX pair. TX pair polarity swap causes the dish to not receive commands (silent failure). - **Carryout G2 is RS-422 full-duplex:** Separate TX/RX pairs at 115200 baud via RJ-12 6P6C, vs. RS-485 half-duplex at 57600 on the Trav'ler variants. Tested with DSD TECH SH-U11 USB-to-RS422 adapter (FTDI FT232R). **Polarity matters** — A/B (or +/-) labeling is not standardized; if you get garbled data at the correct baud rate, swap the +/- wires on the RX pair. TX pair polarity swap causes the dish to not receive commands (silent failure).
- **Carryout G2 position format differs from Trav'ler:** Position query `a` in `MOT>` submenu returns `Angle[0] = 180.00` / `Angle[1] = 45.00` — not the `AZ = / EL =` format used by HAL 0.0.00 and HAL 2.05. Move confirmation returns `Angle = 46.00` (no array index). `CarryoutG2Protocol.get_position()` uses `Angle\[0\]`/`Angle\[1\]` regex. Motor overshoot is direction-dependent: +0.010.05° in travel direction, -0.020.06° on return (stepper backlash). - **Carryout G2 position format differs from Trav'ler:** Position query `a` in `MOT>` submenu returns `Angle[0] = 180.00` / `Angle[1] = 45.00` — not the `AZ = / EL =` format used by HAL 0.0.00 and HAL 2.05. Move confirmation returns `Angle = 46.00` (no array index). `CarryoutG2Protocol.get_position()` uses `Angle\[0\]`/`Angle\[1\]` regex. Motor overshoot is direction-dependent: +0.010.05° in travel direction, -0.020.06° on return (stepper backlash).
- **Carryout G2 firmware version 02.02.48** confirmed (Copyright 2013 - Winegard Company). Bootloader version 1.01. MCU: Kinetis (NXP ARM Cortex-M). DVB tuner: BCM4515 (Broadcom). - **Carryout G2 firmware version 02.02.48** confirmed (Copyright 2013 - Winegard Company). Bootloader version 1.01. MCU: Kinetis (NXP ARM Cortex-M). DVB tuner: BCM4515 (Broadcom).
- **Carryout G2 boot sequence:** Bootloader → SPI init → Motor init (System=12Inch, master=40000 steps, slave=24960 steps, ratio=1.602564) → DVB tuner init (BCM4515) → NVS load → EL home (stall detect, 2s timeout) → AZ home (stall detect, 8s timeout) → `Antenna Facing Front``TRK>` prompt (if tracker disabled) or search start. - **Carryout G2 boot sequence:** Bootloader v1.01 → SPI1 init @ 4 MHz (A3981 motor drivers, mode 0x03) → Motor init (System=12Inch, master=40000 steps, slave=24960 steps, ratio=1.602564) → SPI2 init @ 6.857 MHz (BCM4515 DVB tuner, mode 0x03) → `EXTENDED_DVB_DEBUG ENABLED` → DVB init (AP RAM FW verified, BCM4515 ID 0x4515 Rev B0, FW v113.37, strap 0x25018) → auto-search config (blind scan, 18000-24000 ksps, rolloff 0.35) → `Enabled LNB STB``Ant ID - 12-IN G2`NVS load → EL home (stall detect, 2s timeout) → AZ home (stall detect, 8s timeout) → `Antenna Facing Front``TRK>` prompt (if tracker disabled) or search start. When NVS 20 = TRUE (tracker disabled), homing is skipped entirely — motors stay uncalibrated and AZ position reads as INT_MAX (2147483647).
- **Carryout G2 cable wrap:** Confirmed from homing output: `wrap_min:-42333 wrap_max:2333` (centidegrees). Total range ~446.66°. - **Carryout G2 cable wrap:** Confirmed from homing output: `wrap_min:-42333 wrap_max:2333` (centidegrees). Total range ~446.66°.
- **Carryout G2 has `h <id>` homing:** Explicit motor home-to-reference command. Not documented on other variants. - **Carryout G2 has `h <id>` homing:** Explicit motor home-to-reference command. Not documented on other variants.
- **Carryout G2 has DVB/RSSI:** BCM4515 tuner (ID 0x4515, Rev B0, firmware v113.37). DVB submenu provides `rssi <n>` (bounded, returns `Reads:<n> RSSI[avg: <v> cur: <v>]`), `agc` (streaming RF/IF AGC + SNR + NID), `snr`, `lnbdc odu` (enable LNA 13V), `lnbv` (streaming voltage monitor), `dis` (channel params), `config` (hardware ID), `table` (transponder scan), and DiSEqC 2.x commands (`di2*`, `send`). RSSI noise floor is ~500. `lnbdc odu` sets 13V (V-pol); boot default is 18V (H-pol). Streaming commands run until interrupted by `q` or another command. - **Carryout G2 has DVB/RSSI:** BCM4515 tuner (ID 0x4515, Rev B0, firmware v113.37). DVB submenu provides `rssi <n>` (bounded, returns `Reads:<n> RSSI[avg: <v> cur: <v>]`), `agc` (streaming RF/IF AGC + SNR + NID), `snr`, `lnbdc odu` (enable LNA 13V), `lnbv` (streaming voltage monitor), `dis` (channel params), `config` (hardware ID), `table` (transponder scan), and DiSEqC 2.x commands (`di2*`, `send`). RSSI noise floor is ~500. `lnbdc odu` sets 13V (V-pol); boot default is 18V (H-pol). Streaming commands run until interrupted by `q` or another command.
@ -191,14 +191,15 @@ For short cable runs (under ~3m between ESP32 and dish), the built-in 120 ohm te
### Firmware Console Commands ### Firmware Console Commands
Full command inventory from automated deep probe (firmware 02.02.48, 2026-02-12). Full command inventory from automated deep probe + interactive `?` exploration
Probed with `scripts/hidden_menu_probe.py --deep --wordlist scripts/wordlists/winegard.txt`. (firmware 02.02.48, 2026-02-12). Automated probe finds commands that respond
without arguments; interactive `?` in each submenu reveals the full set including
parameter-requiring commands the probe misses.
#### Root Menu (TRK>) #### Root Menu (TRK>)
``` ```
? — list available commands (alias: help) ? — list available commands (alias: help)
command — undocumented (accepts input, purpose unknown)
a3981 — enter motor driver submenu a3981 — enter motor driver submenu
adc — enter ADC submenu adc — enter ADC submenu
dipswitch — enter dipswitch submenu dipswitch — enter dipswitch submenu
@ -218,110 +219,177 @@ odu — tunnel to outdoor unit (Trav'ler Pro only)
ngsearch — enter search submenu (HAL 2.05 only) ngsearch — enter search submenu (HAL 2.05 only)
``` ```
Note: `command` appeared in automated probe results — this is a false positive.
The help parser extracted it from the `help [<command>]` usage text, where
`<command>` is a parameter placeholder, not an actual command.
#### A3981 Submenu (A3981>) — Allegro Stepper Driver #### A3981 Submenu (A3981>) — Allegro Stepper Driver
6 commands. Controls the two A3981 stepper motor driver ICs via SPI.
``` ```
reset — reset Az/El A3981 fault flags cm — current control mode: AZ/EL both report "AUTO" or "HiZ"/"LoZ"
diag — read AZ/EL diagnostic status (OK / fault) diag — fault pin status: "AZ DIAG: OK EL DIAG: OK" (or FAULT)
cm — Hi/Lo current control (torque) mode reset — reset AZ/EL A3981 fault flags
help / ? — list available commands sm — step size mode: AZ/EL both report "AUTO" or fixed mode
q — return to TRK> ss — step size: returns integer (FULL=16, HALF=8, QTR=4, EIGHTH=2, SIXTEENTH=1)
st — torque level: AZ/EL report "HIGH" (moving) or "LOW" (idle/holding)
? / q — help / return to TRK>
``` ```
#### ADC Submenu (ADC>) — Analog-to-Digital Converter #### ADC Submenu (ADC>) — Analog-to-Digital Converter
5 commands. Hardware-level ADC readings from the LNB signal chain and board ID.
``` ```
m — monitor RSSI (streaming, interrupt with q) bdid — board identity: returns "STATIONARY" (Carryout G2 variant)
rssi — read RSSI (single-shot, returns raw ADC value) bdrevid — board revision: returns "A"
scan — position sweep with RSSI readings (AZ/EL + lock + SNR) m — monitor RSSI (streaming, CR-overwrite line, interrupt with q)
help / ? — list available commands rssi — single-shot RSSI (raw ADC count, ~233-238 noise floor)
q — return to TRK> scan — AZ sweep with per-position RSSI/Lock/SNR readings
Output: "Motor:<id> Angle:<cdeg> RSSI:<adc> Lock:<0/1> SNR:<dB> Scan Delta:<step>"
WARNING: without arguments on uncalibrated AZ, targets INT_MAX (2147483647)
and DEADLOCKS the shell — requires power cycle to recover!
? / q — help / return to TRK>
``` ```
#### DIPSWITCH Submenu (DIPSWITCH>) #### DIPSWITCH Submenu (DIPSWITCH>)
1 command. Reads physical DIP switch GPIOs and interprets satellite config code.
``` ```
dipswitch — read interpreted dipswitch value dipswitch — read dipswitch: "val:<hex32>" (raw GPIO) + "app_dipswitch:<decimal>" (interpreted)
help / ? — list available commands val:ffffff01 = all switches OFF/up. app_dipswitch:101 = DISH 110+119+129°W
q — return to TRK> ? / q — help / return to TRK>
``` ```
#### DVB Submenu (DVB>) — BCM4515 Tuner #### DVB Submenu (DVB>) — BCM4515 Tuner
38 commands. Controls the Broadcom BCM4515 DVB-S2 tuner and DiSEqC 2.x LNB interface.
Help is paginated: `?` shows first page, `man` shows extended commands.
``` ```
agc — stream RF/IF AGC + SNR + NID (continuous, interrupt with q) agc — stream RF/IF AGC + SNR + NID (continuous, interrupt with q)
config — BCM hardware/firmware version config — BCM hardware/firmware version (ID 0x4515, Rev B0, FW v113.37)
def — restore DVB defaults
diag — multi-block per-transponder diagnostics diag — multi-block per-transponder diagnostics
dis — display channel parameters (frequency, symbol rate, LNB polarity) dis — display channel parameters (frequency, symbol rate, LNB polarity)
e <n> <v> — edit channel parameter e <n> <v> — edit channel parameter
freqs — tuner frequency list freqs — tuner frequency list
h <n> — select transponder by ID (1-13)
help / ? — list available commands (first page)
lnbdc odu — enable LNA in ODU mode (13V = V-pol; boot default 18V = H-pol) lnbdc odu — enable LNA in ODU mode (13V = V-pol; boot default 18V = H-pol)
lnbv — stream LNB voltage readings (continuous, interrupt with q) lnbv — stream LNB voltage readings (continuous, interrupt with q)
ls — lock status ls — lock status (total reads, no-signal count, glitch count, NID table)
man — extended help (srch_mode, stats, t, etc.) man — extended help page (shows srch_mode, stats, DiSEqC commands, etc.)
msw — multi-switch control
nid — streaming NID reads (Network ID, FFFF = no signal)
pwr — power control
qls — quick lock status qls — quick lock status
range — signal range test
rssi <n> — RSSI averaged over n samples (bounded, returns avg + cur) rssi <n> — RSSI averaged over n samples (bounded, returns avg + cur)
shuf — shuffle/reorder transponders
snr — SNR level (streaming) snr — SNR level (streaming)
srch_mode — auto search mode (from man page) srch — start satellite search
stats — satellite read stats (from man page) srch_mode — auto search mode setting
stats — accumulated satellite read statistics
t <n> — select transponder t <n> — select transponder
table — generate transponder table table — generate transponder table
tablex — extended transponder table
tabto — table timeout setting
to — timeout setting
di2conf — DiSEqC LNB config register (raw: "3 21180544 238 <4.5")
di2cs — DiSEqC committed switch command
di2id — DiSEqC read LNB hardware ID di2id — DiSEqC read LNB hardware ID
di2rcs — DiSEqC read committed switch status
di2sc — DiSEqC switch control
di2stat — DiSEqC read LNB status flags di2stat — DiSEqC read LNB status flags
ovraddr — DiSEqC override address
pretx — DiSEqC pre-transmit delay
rrto — DiSEqC receive reply timeout
send <hex> — raw DiSEqC packet (max 6 bytes, space-delimited hex) send <hex> — raw DiSEqC packet (max 6 bytes, space-delimited hex)
q — return to TRK> tdthresh — DiSEqC tone detect threshold
? / q — help / return to TRK>
``` ```
#### EEPROM Submenu (EEPROM>) #### EEPROM Submenu (EE>) — K60 FlexNVM/EEPROM
3 commands. Low-level EEPROM access (separate from NVS). Prompt is `EE>`, not `EEPROM>`.
Most indices read as 0 (unwritten) or fail with val:65793 (0x10101 marker = uninitialized).
The firmware primarily uses NVS, not EEPROM, for persistent settings.
``` ```
ee <idx> [<v>] — read/write EEPROM value at index ee <idx> [<v>] — read/write EEPROM value at index
inv [<idx>] — EEPROM inventory (from help) Read: "Index:<n> Read value = <v>" or "Failed to read eeprom index:<n> val:65793"
def — restore defaults (from help) inv <idx> — INVALIDATE EEPROM index (DESTRUCTIVE — marks entry invalid, not "inventory"!)
help / ? — list available commands def — restore EEPROM defaults
q — return to TRK> ? / q — help / return to TRK>
``` ```
#### GPIO Submenu (GPIO>) #### GPIO Submenu (GPIO>)
4 commands. Direct access to K60 GPIO ports A-E. Pin naming: `<port><pin>` (e.g., B0, E12).
``` ```
dir — set GPIO pin direction dir <pin> — query pin direction: returns "INPUT" or "OUTPUT"
r — read GPIO pin (returns e.g. "B0 = 1") r <pin> — read single GPIO pin value (0 or 1)
w — write GPIO pin (requires parameters) regs — dump ALL GPIO pin states across ports A-E (26+16+20+16+14 = 92 pins)
help / ? — list available commands Note: A20-A23, B12-B15 absent (not bonded). E29 shows "Unknown bit E29"
q — return to TRK> w <pin> <val> — write GPIO pin (requires pin name and value)
? / q — help / return to TRK>
``` ```
#### LATLON Submenu (LATLON>) #### LATLON Submenu (LATLON>)
1 command. Satellite triangulation calculator — computes ground station lat/lon from
look angles to two known geostationary satellites. Used for auto-location when GPS
is unavailable. Values stored internally as centidegrees.
``` ```
l — calculate lat/lon position (requires 4 parameters) l <p1> <p2> <p3> <p4>
help / ? — list available commands — calculate lat/lon from 4 parameters (likely AZ/EL pairs for 2 satellites)
q — return to TRK> Output: "anglesentered = <cdeg1> <cdeg2> <cdeg3> <cdeg4>"
"Lat = <cdeg> Lon = <cdeg>" (centidegrees)
? / q — help / return to TRK>
``` ```
#### MOT Submenu (MOT>) — Motor Control #### MOT Submenu (MOT>) — Motor Control
25 commands. High-level motor control with angle-based positioning.
``` ```
a — show position: Angle[0] (AZ), Angle[1] (EL) a — show position: Angle[0] (AZ), Angle[1] (EL)
a <id> <deg> — move motor to absolute angle (0=AZ, 1=EL) a <id> <deg> — move motor to absolute angle (0=AZ, 1=EL)
a <id> +/-deg — relative move (G2 only, undocumented) a <id> +/-deg — relative move (G2 only, undocumented)
azscan — scan AZ from EL min to max (from help, untested) azscan [az_rel] [el_rel] [delay]
— AZ sweep: scan relative AZ range at EL steps with delay
azscanwxp [motor] [span_deg] [res_cdeg] [num_xponders]
— AZ sweep + transponder cycling (radio telescope mode)
e — engage motors (energize steppers) e — engage motors (energize steppers)
ela2s <deg> — elevation angle to steps converter (centidegrees internally)
elminmaxhome — show EL limits: "Min: <v> Max: <v> Home: <v>" (NVS values)
els2a <steps> — elevation steps to angle converter (reports overflow if out of range)
g <az> <el> — go to AZ/EL (aborts on new input) g <az> <el> — go to AZ/EL (aborts on new input)
h <id> — home motor to reference position h <id> — home motor to reference position (stall-detect based)
l — list motors and state (0=AZIMUTH, 1=ELEVATION) l — list motors and state (0=AZIMUTH, 1=ELEVATION)
life — motor lifetime/usage stats
ma — read max acceleration per motor ma — read max acceleration per motor
motorboth — simultaneous dual-motor move test
motorlife — detailed motor life statistics
mv — max velocity per motor: "Max Vel [0] = <v> / Max Vel [1] = <v>"
p — read raw step positions p — read raw step positions
pid [motor] [Kp] [Kv] [Ki]
— read or set PID gains for motor control loop
r — release motors (de-energize steppers) r — release motors (de-energize steppers)
sd — stall detection test (motor, direction, timeout) sd — stall detection test (motor, direction, timeout)
sw — undocumented (requires parameters) sp [motor] [pos]
— set position (override current position register)
sw [motor] [pos]
— set wrap position (cable wrap reference point)
v — read motor velocities v — read motor velocities
w — undocumented (requires parameters) vms [motor] [deg_per_rev] [ms]
help / ? — list available commands — velocity move for duration: spin motor at velocity for N milliseconds
q — return to TRK> w [motor] [ON/OFF]
— wrap manager: enable/disable cable wrap protection per motor
? / q — help / return to TRK>
``` ```
#### NVS Submenu (NVS>) — Non-Volatile Storage #### NVS Submenu (NVS>) — Non-Volatile Storage
@ -336,8 +404,7 @@ d <idx> — dump single value with details
e <idx> — read NVS value at index e <idx> — read NVS value at index
e <idx> <v> — write NVS value at index (NOT saved until `s`) e <idx> <v> — write NVS value at index (NOT saved until `s`)
s — save pending changes to flash s — save pending changes to flash
help / ? — list available commands ? / q — help / return to TRK>
q — return to TRK>
``` ```
#### OS Submenu (OS>) #### OS Submenu (OS>)
@ -347,29 +414,45 @@ id — full MCU/firmware identification (NVS version, System ID, chi
reboot — reboot microcontroller reboot — reboot microcontroller
tasks — list running tasks (HAL 0.0.00 only, not on G2) tasks — list running tasks (HAL 0.0.00 only, not on G2)
kill <name> — kill a named task (HAL 0.0.00 only, not on G2) kill <name> — kill a named task (HAL 0.0.00 only, not on G2)
help / ? — list available commands ? / q — help / return to TRK>
q — return to TRK>
``` ```
#### PEAK Submenu (PEAK>) — Signal Peak / DiSEqC Switch #### PEAK Submenu (PEAK>) — Signal Peak / DiSEqC Switch
6 commands. EchoStar/DiSEqC switch control and LNB polarity-switched RSSI.
``` ```
ts — EchoStar switch toggle status pw — peak signal search (likely requires sat lock)
pw — peak signal (from help, details truncated) psnr — peak SNR measurement
help / ? — list available commands pxy1 — peak XY single-axis (likely az or el sweep)
q — return to TRK> rssits — RSSI with LNB toggle switch: alternates H-pol (18V, even transponders)
and V-pol (13V, odd transponders). Reports "Even_sig = <v>, Odd_sig = <v>".
Noise floor: even ~489, odd ~235 (V-pol quieter).
stb — STB (set-top box) control / DiSEqC switch test
ts — EchoStar switch toggle status: "SW Status: 0b<binary> <decimal>"
(reads 4-bit status, all zeros = no switch connected)
? / q — help / return to TRK>
``` ```
#### STEP Submenu (STEP>) — Low-Level Stepper Control #### STEP Submenu (STEP>) — Low-Level Stepper Control
7 commands. Raw stepper API in microstep units (ustep/sec, ustep/sec/msec).
MOT wraps STEP with angle-to-step conversion.
``` ```
e — engage motor (same as MOT `e`) e — engage motor (same as MOT `e`)
ma — set/read max acceleration ma — max acceleration: "Accel[0] = 44 / Accel[1] = 28" (ustep/sec/ms)
p — read step positions (raw counts, not degrees) Set: `ma [motor] [ustep/sec/ms]`
r — release motor (same as MOT `r`) mv — max velocity: "Max Vel [0] = 7222 / Max Vel [1] = 3120" (ustep/sec)
v — read velocity (raw, not degrees/sec) Set: `mv [motor] [ustep/sec]`
help / ? — list available commands (7222 ustep/s ÷ 40000 steps/rev × 360° = 65.0°/s AZ)
q — return to TRK> (3120 ustep/s ÷ 24960 steps/rev × 360° = 45.0°/s EL)
p — goto position in raw step counts: `p [motor] [steps]`
pid — PID values: "Kp=250 Kv=50" (no Ki at STEP level)
Set: `pid [motor] [Kp] [Kv]`
r — release motors (same as MOT `r`)
v — go to velocity (continuous spin): `v [motor] [ustep/sec]`
? / q — help / return to TRK>
``` ```
### Known NVS Indices ### Known NVS Indices
@ -400,6 +483,16 @@ Full dump in `docs/g2-nvs-dump.md` (firmware 02.02.48, captured 2026-02-12).
| `AZ MOTOR STALLED` | Obstruction preventing rotation | | `AZ MOTOR STALLED` | Obstruction preventing rotation |
| `EL MOTOR STALLED` | Obstruction preventing elevation change | | `EL MOTOR STALLED` | Obstruction preventing elevation change |
| `EL Motor Home Failure` | Requires EL recalibration via IDU menu | | `EL Motor Home Failure` | Requires EL recalibration via IDU menu |
| `Step to Position EL angle error: 2147483647` | INT_MAX sentinel — motor axis uncalibrated/unhomed |
### Known Console Hazards
- **ADC `scan` without arguments on uncalibrated AZ:** Targets position 2147483647 (INT_MAX),
motor task blocks forever, shell deadlocks. No serial input (CR, Ctrl+C, ESC, `q`, `reboot`)
can recover — requires hardware power cycle. The firmware shell is single-threaded: UART
input is only parsed between command completions, so a blocking motor move prevents all input.
- **Root `q` command:** Terminates the shell task entirely. Console becomes unresponsive until
power cycle (same as deadlock, but intentional).
### IDU/ODU Cable Wiring (if cut) ### IDU/ODU Cable Wiring (if cut)