Emergency Stop Procedure for RF Power Amplifier Protection in PLFM-RADAR
The PLFM-RADAR firmware implements a three-layer emergency stop routine that immediately disables RF power amplifier rails and enters a safe-hold loop when critical faults are detected. This protection mechanism prevents catastrophic damage to the GaN PA during over-current, over-temperature, or watchdog timeout conditions.
This guide explains how the emergency stop procedure works in the open-source PLFM-RADAR project, walking through the fault detection logic, shutdown sequence, and verification test suite. All implementations are found in the microcontroller firmware under 9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp.
Three-Layer Protection Architecture
The RF power amplifier protection system operates through coordinated hardware and software layers:
| Layer | Purpose | Key Component |
|---|---|---|
| Fault detection | Identify PA-damaging conditions | SystemError_t enum in main.cpp (lines 808-826) |
| Decision logic | Classify critical vs. recoverable faults | handleSystemError() function (lines 1088-1095) |
| Shutdown execution | Safely de-energize all PA rails | Emergency_Stop() function (lines 820-858) |
Fault Detection and Error Classification
Hardware faults that threaten the RF power amplifier are enumerated in the SystemError_t type definition. Located at 9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp lines 808-826, this enum includes:
ERROR_RF_PA_OVERCURRENT— PA drain current exceeds safe thresholdERROR_RF_PA_BIAS_FAULT— GaN gate bias regulation failureERROR_TEMPERATURE_HIGH— Thermal runaway conditionERROR_POWER_SUPPLY— Bulk rail collapse or sequencing errorERROR_WATCHDOG_TIMEOUT— Control loop deadlock detected
These values represent conditions where continued operation risks permanent PA damage or fire hazard.
Critical Error Handling Logic
The handleSystemError() function serves as the central dispatcher for all fault conditions. Implemented in main.cpp lines 1088-1095, it performs three essential operations before deciding on recovery or shutdown:
- State tracking — increments
error_countand storeslast_errorfor diagnostic logging - Error logging — outputs diagnostic message via debug console
- Severity classification — checks if error falls within critical range
For critical errors, the function sets system_emergency_state = true before invoking Emergency_Stop(). This ordering—documented as GAP-3 FIX 5 in the source—ensures external systems receive immediate notification that an emergency stop is in progress.
// Critical error range check triggers emergency stop
if (error >= ERROR_RF_PA_OVERCURRENT &&
error <= ERROR_WATCHDOG_TIMEOUT) {
system_emergency_state = true; // Notify external systems FIRST
Emergency_Stop(); // Enter infinite safe-hold loop
}
Non-critical errors route to attemptErrorRecovery() for transient fault handling.
Emergency Stop Shutdown Sequence
The Emergency_Stop() function at main.cpp lines 820-858 implements a deterministic, fast-to-slow rail shutdown protocol. This sequencing prevents dangerous operating modes in GaN PAs, which can self-bias or oscillate if control voltages persist while drain supplies collapse.
The ordered actions are:
- Clear all DAC outputs via
DAC5578_ActivateClearPin— removes bias voltages immediately - Disable TX mixers — deasserts
GPIODpin 11 to stop RF drive - Cut PA 5V auxiliary supplies — disables
EN_P_5V0_PA1,EN_P_5V0_PA2,EN_P_5V0_PA3 - Cut PA 5.5V bulk supply — disables
EN_P_5V5_PA - Disable RF-PA VDD — deasserts
EN_DIS_RFPA_VDD(main drain supply) - Enter infinite hold loop — refreshes independent watchdog (IWDG) every 100ms to prevent reset
void Emergency_Stop(void) {
// 1. Clear DAC outputs immediately
DAC5578_ActivateClearPin();
// 2. Disable TX mixers
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11, GPIO_PIN_RESET);
// 3-5. Cut PA power rails in sequence
HAL_GPIO_WritePin(GPIOA, EN_P_5V0_PA1 | EN_P_5V0_PA2 | EN_P_5V0_PA3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, EN_P_5V5_PA, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, EN_DIS_RFPA_VDD, GPIO_PIN_RESET);
// 6. Infinite safe-hold with watchdog servicing
while (1) {
HAL_IWDG_Refresh(&hiwdg);
HAL_Delay(100);
}
}
The IWDG refresh is critical: without it, the watchdog would timeout and reset the MCU, potentially re-enabling power rails during boot before fault conditions are cleared.
System State Exposure
The global system_emergency_state flag propagates emergency status to external systems. The getSystemStatusForGUI() function reports "EMERGENCY_STOP" when this flag is set, allowing the operator interface to display appropriate alarms and block further operation attempts.
// Query system state for GUI display
char status_buffer[256];
getSystemStatusForGUI(status_buffer, sizeof(status_buffer));
// Returns: "System Status: EMERGENCY_STOP" when flag is set
Unit Test Verification
The PLFM-RADAR repository includes comprehensive unit tests validating emergency stop behavior under 9_Firmware/9_1_Microcontroller/tests/:
test_gap3_overtemp_emergency_stop.c— Confirms over-temperature and watchdog errors trigger the complete shutdown pathtest_gap3_emergency_stop_rails.c— Verifies correct GPIO sequencing for PA rail cut-offtest_gap3_emergency_state_ordering.c— Validates thatsystem_emergency_stateis set beforeEmergency_Stop()is called (GAP-3 FIX 5)
These tests ensure deterministic, repeatable protection behavior across firmware builds.
Summary
- Fault detection uses the
SystemError_tenum to classify PA-threatening conditions handleSystemError()routes critical faults to emergency stop while allowing recovery attempts for transient errorsEmergency_Stop()executes a sequenced shutdown: DAC clear → mixer disable → rail cut-off → infinite IWDG-serviced hold- The state flag ordering ensures external notification precedes the non-returning stop routine
- Unit tests verify correct implementation of all protection paths
Frequently Asked Questions
What triggers the emergency stop in PLFM-RADAR?
Critical faults in the ERROR_RF_PA_OVERCURRENT through ERROR_WATCHDOG_TIMEOUT range trigger the emergency stop procedure. These include PA over-current, bias faults, over-temperature conditions, power supply failures, and watchdog timeouts detected in main.cpp lines 808-826.
Why does the emergency stop enter an infinite loop instead of resetting?
The infinite loop with IWDG refresh prevents the MCU from resetting and potentially re-enabling PA power rails before fault conditions are cleared. This safe-hold state maintains all rails de-energized until manual intervention or power cycle occurs, eliminating the risk of automatic restart into a damaged or hazardous condition.
How can I manually trigger an emergency stop for testing?
Call Emergency_Stop() directly from diagnostic code. This function never returns, placing the system into the same safe state as fault-triggered stops:
extern void Emergency_Stop(void);
void run_manual_estop_test(void) {
Emergency_Stop(); // Enters infinite loop, requires power cycle
}
Where is the emergency stop sequence verified in the codebase?
Three unit test files validate the implementation: test_gap3_overtemp_emergency_stop.c tests thermal and watchdog triggers; test_gap3_emergency_stop_rails.c verifies GPIO rail sequencing; and test_gap3_emergency_state_ordering.c confirms state flag timing.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →