Safety review identified infinite-hang paths in do_tune(), GPIF streaming,
EP0/EP2 FIFO waits, and the 0xB4 I2C bus scan. The firmware controls an LNB
power supply (750mA at 18V) on a Cypress FX2LP with no hardware watchdog.
Key changes:
- Software watchdog via Timer0 ISR (~2s timeout, cuts LNB power on stall)
- Replace fx2lib i2c_write() in do_tune() with timeout-protected helper
- ep0_wait_data() helper replaces 7 bare EP0 BUSY spin loops
- GPIF idle wait and EP2 FIFO full wait now have timeouts
- 0xB4 I2C bus scan uses i2c_wait_done()/i2c_wait_stop() instead of bare spins
- Return-value checks on all I2C writes in sweep/scan functions
- EP0 payload length validation on all vendor commands with data phase
- Zero-fill EP0BUF before indirect reads (0x87, 0xB7) for deterministic output
- i2c_wait_stop() now sets last_error on timeout
- New error codes: ERR_TUNE_FAIL through ERR_DISEQC_LEN
- BCM_LOCK_BIT constant replaces hardcoded 0x20 in lock checks
- DiSEqC Tone Burst B rejected with ERR_NOT_SUPPORTED
- DiSEqC message length error sets ERR_DISEQC_LEN
- hp_changes counter saturates instead of wrapping
- stream_diag_poll() only updates status on successful I2C reads
- do_tune() forward declaration eliminates implicit-function warning
- do_tune() sets ERR_BCM_NOT_READY when demod not booted
- wdt_kick() in all long-running sweep/scan loops
Code: 13,057 / 15,360 bytes (85%). XRAM: 218 / 512 bytes (43%).
Stack: 132 bytes free. Zero new SDCC warnings.