1. Today’s topic

Today we examine power as part of firmware architecture:

text
power source
→ DC/DC or LDO
→ local capacitors
→ power-good / voltage monitor
→ ESP32, STM32, EC25, and peripherals
→ brownout detection
→ controlled degraded mode
→ safely stop Flash writes
→ reset or shutdown

The central idea: a brownout detector does not fix a poor power supply. It stops the processor before it begins executing code at an unsafe voltage.

2. Why this matters in your projects

EC25 produces current bursts during registration, data transmission, network search, and TLS/MQTT/HTTP traffic. The supply must handle peak loads, and voltage must be measured directly at the module pins, not only at the board input. The ESP32 brownout detector is enabled by default. Disabling it when it trips masks the problem rather than solving it. STM32 often has POR/PDR, BOR, and PVD, and may use an external supervisor for early warning.

3. Theory

10.3.1 3.1. Brownout reset and early warning

Brownout reset occurs when voltage is already too low. It is then too late to start MQTT publish, NVS save, or normal modem shutdown. Early warning must occur sooner:

text
VIN starts falling
→ supervisor/PVD generates a signal
→ power_task forbids Flash writes
→ safe outputs
→ minimal diagnostics

The warning threshold must be above the reset threshold:

text
V_WARN > V_BOR

10.3.2 3.2. Hold-up capacitor

Simplified:

text
C ≥ I × Δt / ΔV

For ESP32 at 100 mA, 10 ms, and a 0.3 V drop:

text
C ≥ 0.1 × 0.010 / 0.3 ≈ 3300 uF

For EC25 at 2 A, 10 ms, and a 0.4 V drop:

text
C ≥ 2 × 0.010 / 0.4 = 50 000 uF

Conclusion: a capacitor helps with fast pulses but cannot replace a suitable DC/DC converter and board layout.

10.3.3 3.3. Bulk and ceramic capacitors

text
Ceramic 100 nF - several uF:
  fast edges, local current at the pin.
Bulk 100-1000 uF:
  RF burst, startup, DC/DC response, long supply line.

10.3.4 3.4. ESR

text
ΔV_ESR = I_STEP × ESR

2 A and 100 mOhm ESR produce an immediate 0.2 V drop.

10.3.5 3.5. Power domains

text
primary source
├── DC/DC EC25 3.8 V
├── DC/DC/LDO 3.3 V ESP32
├── sensor/optocoupler supply
└── switchable secondary loads

This reduces the impact of an EC25 pulse on ESP32 and allows the modem to be switched off separately.

10.3.6 3.6. Load shedding

c
typedef enum {
    POWER_STATE_NORMAL = 0,
    POWER_STATE_WARN,
    POWER_STATE_SHEDDING,
    POWER_STATE_CRITICAL,
    POWER_STATE_RECOVERING,
} power_state_t;

At WARN, prohibit new Flash writes, reduce telemetry, and disconnect noncritical loads. At CRITICAL, apply safe outputs and await reset. 10.3.7 3.7. EC25 should not simply lose power

For a normal shutdown, use PWRKEY or an AT command if time permits. When power disappears quickly, the hardware must be resilient on its own.

10.3.8 3.8. Flash/NVS and power fail

Do not start a new write after warning:

c
if (!power_service_flash_write_allowed()) {
    return ESP_ERR_INVALID_STATE;
}

Configuration requires A/B, CRC, and generation. OTA requires two slots and rollback.

10.3.9 3.9. Staged startup

To avoid a boot-loop:

text
reset
→ start only MCU
→ measure power
→ stable interval
→ input path
→ I2C/CAN
→ EC25
→ high-current outputs

If many power-related resets occur in a short period, do not start EC25 automatically; enter degraded startup.

10.3.10 3.10. ESP32 power management

DFS/Light-sleep may affect latency. Critical sections need a PM lock:

c
esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "timing", &lock);
esp_pm_lock_acquire(lock);
/* critical timing */
esp_pm_lock_release(lock);

4. Common mistakes

text
1. Disabling the brownout detector.
2. Measuring supply voltage away from EC25 pins.
3. Trusting the supply’s average current rating.
4. Placing one electrolytic capacitor far from the module.
5. Performing NVS-save inside PVD ISR.
6. Starting EC25 shutdown too late.
7. Enabling every load immediately after reset.
8. Not counting reset reason.
9. Using vTaskDelay() instead of checking power-good.
10. Relying on ADC during a fast collapse.
11. Trying to hold EC25 with a supercap without calculation.
12. Not testing repeated brief drops.

5. Practical assignment for 30-60 minutes

Create POWER_POLICY.md:

markdown
# Power policy
1. Brownout detector is never disabled in production.
2. Critical Flash writes require power_good.
3. High-current loads start sequentially.
4. EC25 power is controlled independently where possible.
5. Power warning and reset thresholds are different.
6. Power-fail ISR only notifies power_task.
7. Safe outputs are defined in hardware and firmware.
8. Power-related reset loops enter degraded startup.
9. Every power transition is counted and timestamped.
10. Power-fail behavior is tested in HIL.

Add power_status_t:

c
typedef enum {
    POWER_QUALITY_UNKNOWN = 0,
    POWER_QUALITY_GOOD,
    POWER_QUALITY_WARN,
    POWER_QUALITY_CRITICAL,
    POWER_QUALITY_RECOVERING,
} power_quality_t;
typedef struct {
    power_quality_t quality;
    uint32_t warning_count;
    uint32_t critical_count;
    uint32_t recovery_count;
    uint32_t brownout_boot_count;
    uint32_t unstable_boot_count;
    uint32_t vin_mv;
    uint32_t rail_3v3_mv;
    uint32_t modem_vbat_mv;
    int64_t last_transition_us;
    int64_t stable_since_us;
    bool flash_write_allowed;
    bool modem_start_allowed;
    bool high_load_allowed;
} power_status_t;

power CLI:

text
power:
quality=GOOD
vin=12180mV
rail_3v3=3294mV
modem_vbat=3790mV
flash_write_allowed=yes
modem_start_allowed=yes
high_load_allowed=yes
warnings=3
critical=1
brownout_boots=1
stable_for=42800ms

HIL: test power dips during NVS, OTA, the first boot of a new OTA image, EC25 startup, and bouncing power.

6. Further reading

  • ESP-IDF Fatal Errors, Brownout Detector, and Power Management.
  • STM32 PWR/BOR/PVD documentation for the selected series.
  • Quectel EC25 Hardware Design for the actual revision.

Brief recap

text
power source
→ regulator with transient margin
→ local low-ESR decoupling
→ power-good / early warning
→ power_service
→ load shedding
→ safe outputs
→ transactional storage
→ BOR/brownout reset as last protection

Exercise

A reboot loop starts when EC25 transmits. Define the measurement point and startup policy that avoids hiding the fault.

Self-check criteria: Use peak-voltage evidence rather than average current alone; do not replace power-good validation with an arbitrary delay.

Show the supplied answer

Measure voltage at EC25 module pins under peak activity and inspect regulator/layout/transients. Keep brownout protection enabled; start MCU and essential inputs first, require a stable supply interval, and use degraded startup after repeated power-related resets.

Exercise

Design a low-voltage HIL power-loss test during configuration save. State the warning action and evidence of valid restart selection.

Self-check criteria: Check interrupted storage and restart selection on isolated test hardware; distinguish warning response from final brownout reset.

Show the supplied answer

Inject a controlled interruption, observe that early warning blocks new Flash writes and reaches safe outputs, then verify A/B CRC/generation selection after reboot. Retain reset reason and storage status; avoid a large last-moment save in the warning ISR.