mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2026-11-13 10:27:37 +00:00
* SubGHz: survive an external module unplugged mid-session The external CC1101 was probed once, in subghz_txrx_alloc(), and the result latched for the life of the app. Unplug it and enter Read, and the app drove a chip that was not there: subghz_txrx_rx_start() -> subghz_txrx_begin() -> ... -> subghz_device_cc1101_ext_rx() waiting for CC1101StateRX, which never arrives, and the furi_check around it took the firmware down. App side, the probe now happens where the radio is about to be used instead of once at startup. subghz_txrx_radio_device_set() tears the module down first and honours subghz_devices_begin()'s return value - the self-test that actually distinguishes a present module from a floating header, and previously discarded - so it returns what came up rather than what was asked for. subghz_txrx_radio_device_poll() re-checks before every RX and TX start, on every hop (hopping skips begin()) and on the Sub-GHz menu, falling back to the internal radio and picking the external one back up once it is plugged in again. A missing module reads back as a steady -74 dBm rather than as nothing, so Read would otherwise show a receiver that looks healthier than an idle one; poll_active() catches that from the receiver tick and restarts RX on whatever answered. Driver side, the three furi_check(cc1101_wait_status_state(...)) calls now log and carry on. A hot-pluggable peripheral being absent is an I/O condition, not an invariant violation - the internal radio keeps its furi_check, since that chip is soldered on and there is nothing to fall back to. This is also the only part of the fix that reaches the other consumers of the driver (CLI, JS, subghz_remote, subghz_tx_rx_worker), none of which re-probe. Alongside it: - set_frequency() waited for CC1101StateIDLE in an unbounded while(true) while holding the SPI bus; the hopper reaches it every hop, so a module that stopped answering was a watchdog reset waiting to happen - is_connect() tested PARTNUM, which a genuine CC1101 reports as 0x00 - the same as an empty bus. It reads VERSION now, which is what makes the cheap liveness check on the receiver tick possible - the E07 amp is no longer keyed without confirmation that the chip reached TX, and is still dropped on the IDLE path when the transition times out Known gaps, deliberately left: SubGhz Remote keeps its own copy of the txrx helper and gets only the driver half of this; TX failing because the module is gone still reports "Transmission is blocked / Frequency is outside of default range", which needs its own error state. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * CHANGELOG: external SubGHz module hot-unplug Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * apply review fixes --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: MX <10697207+xMasterX@users.noreply.github.com>