DEV Community

Hedy
Hedy

Posted on

How to troubleshoot STM32 hardware errors?

troubleshooting STM32 hardware errors is a practical skill that saves hours. Below is a compact, actionable checklist and deeper diagnostics guide you can run through start→finish. It covers quick hardware checks, debug connections, software-side fault analysis, common peripheral problems, measurement tips, and recovery actions. Use what fits your board and MCU family — I avoid absolute register names where families differ, and point out where to check the reference manual.

Quick checklist (first 10 things to try)

  1. Power rails: confirm VDD, VDDA, VSS, VCAP (if present) voltages with a multimeter.
  2. Reset/BOOT pins: ensure NRST pulled-up and BOOT0 is set for expected boot mode.
  3. Decoupling caps: verify decoupling caps close to VDD pins; no cold solder joints.
  4. Clock source: check that crystal/oscillator is populated and correct caps; try internal RC clock if unsure.
  5. SWD connection: connect ST-Link / J-Link; ensure SWDIO / SWCLK signals intact.
  6. Read reset reason: use debugger or reading RCC reset flags (see reference manual) to know what reset occurred (POR, BOR, IWDG, or software).
  7. Simple blink test: flash a trivial blink program to confirm basic MCU functionality.
  8. Check option bytes: verify watchdog/boot configuration and read-protect aren’t blocking debug.
  9. Observe LEDs / serial output: add early UART prints or blink patterns to show boot progress.
  10. Search for shorts: visually inspect and measure shorts between power rails and ground.

Hardware checks — what to measure and why

  • VDD / VDDA / VREF+: measure absolute voltages and ripple. Undervoltage or noisy rails cause weird faults.
  • VCAP pins (H7, F7 etc): ensure required cap(s) to ground are present and correct value — missing VCAP often prevents startup.
  • Reset line (NRST): confirm not stuck low (use scope to see pulses).
  • Crystal/oscillator: check oscillator waveform on oscillator pins with scope or try switching to internal HSI clock in software to isolate.
  • Grounding & copper pours: ensure ground return for power loops is short; measure voltage drop across ground plane under load.
  • Solder joints / component orientation: reflow suspicious parts (USB connector, MOSFETs, decoupling).
  • ESD / damage signs: burnt parts, smell, or discoloration.

Debug connection and flashing

  • Use a hardware debugger: ST-Link / J-Link / Black Magic Probe. Confirm the debugger detects MCU (shows core ID).
  • If debugger doesn’t connect: check BOOT0, nRESET, and that the device is not in low-power shutdown or option bytes set to disable debug.
  • Force system memory boot: set BOOT0=1 to invoke system bootloader (if you need to recover from bad firmware).
  • Mass erase / unlock: STM32CubeProgrammer or OpenOCD can perform mass erase if flash content is corrupt.
  • Check debug protection: if read-out protection is enabled, the debugger may be blocked — consult STM tools to unprotect (may erase flash).

Software/firmware fault analysis

  • HardFault / BusFault / MemManage / UsageFault: enable all fault exceptions in SCB->SHCSR and implement fault handlers that dump registers (R0–R12, LR, PC, xPSR). Example handler snippet below.
  • Stack overflow: ensure stack size in linker script is sufficient; check for corrupted stack pointer on faults.
  • Vector table: confirm the vector table address and that it points to valid stack top and reset handler (especially if bootloader present).
  • Clock config: misconfigured PLL or clock source can hang system. Temporarily use HSI and minimal clock to test.
  • Peripherals:

    • ADC: check VDDA, reference pins and sample capacitor, ensure ADC clock enabled.
    • I2C: check pull-ups, bus voltage, stuck SDA/SCL lines (use pull-ups to correct voltage), bus recovery (clock pulses).
    • SPI: check CPOL/CPHA and chip-select wiring.
    • UART: check common ground and correct baud and line levels (3.3V vs 5V).
    • USB: proper pull-up or PHY connections; power to VBUS if required.
  • Interrupt storms: enable debug view of NVIC; high-frequency interrupts can starve CPU. Use a scope to see IRQ pin activity where applicable.

Fault handler example (register dump)

// place in fault handlers to capture register state (simple example)
void HardFault_Handler(void)
{
    __asm volatile
    (
      "tst lr, #4\n"
      "ite eq\n"
      "mrseq r0, msp\n"
      "mrsne r0, psp\n"
      "b hard_fault_handler_c\n"
    );
}

void hard_fault_handler_c(uint32_t *stack_frame)
{
    uint32_t r0  = stack_frame[0];
    uint32_t r1  = stack_frame[1];
    uint32_t r2  = stack_frame[2];
    uint32_t r3  = stack_frame[3];
    uint32_t r12 = stack_frame[4];
    uint32_t lr  = stack_frame[5];
    uint32_t pc  = stack_frame[6];
    uint32_t psr = stack_frame[7];

    // transmit these values over UART or store to RAM for debugger inspection
    for(;;);
}

Enter fullscreen mode Exit fullscreen mode

Dumping these values makes it much easier to find the instruction that caused the fault.

Reading reset reasons

Many STM32 series expose reset flags in an RCC status register (e.g., RCC->CSR or similar). Read it after reset to see BOR/POR/IWDG/WWDG/SW reset flags then clear them. Check your MCU reference manual for the exact register name and bits.

Tools and commands (recommended)

  • STM32CubeProgrammer — flash, mass erase, read option bytes.
  • ST-Link Utility / STLink — connect, read device info.
  • OpenOCD + GDB — low-level debugging and scripting.
  • Segger J-Link — high-performance debug probe.
  • Logic analyzer / Bus Pirate — sniff I2C/SPI/UART lines.
  • Oscilloscope — observe clocks, NRST, power rail ripple, switching spikes.

Peripheral-specific common problems & fixes

  • I²C stuck SDA: slave pulled low — try toggling SCL 9× to release, ensure correct pull-up resistors and voltage.
  • UART garbage: wrong baud, wrong voltage levels (5V vs 3.3V), or missing common ground.
  • SPI fails occasionally: too long traces, lack of ground reference near CS, or improper CS timing.
  • ADC noisy or unstable: missing VDDA decoupling, long sense traces, sampling at wrong point in PWM cycle — use synchronous sampling.
  • PWM/timer issues: confirm timer clock enabled, pins configured to alternate function, check dead-time and complementary outputs on advanced timers.

EMI / stability / layout issues that look like "hardware errors"

  • Long sense lines picking up switching noise — use Kelvin sense wiring and route away from switching nodes.
  • Insufficient decoupling or missing bulk capacitor causes resets at load transients.
  • Ground loops and high-current traces near analog circuits produce measurement errors.

Recovery & safe-boot strategies to add next time

  • Implement a safe bootloader with a simple LED or UART heartbeat early in reset.
  • Use BOOT0 pin accessible on board to jump to system bootloader for recovery.
  • Implement watchdog-friendly boot (i.e., restart in safe mode on repeated watchdog(What is a Watchdog?) resets).
  • Provide SWD pads accessible for field servicing.

When to suspect silicon/factory defect

  • If device fails to respond to debugger across multiple boards with correct wiring and known-good debugger — suspect damaged MCU.
  • If same code/hardware works on one board and another identical board fails, compare soldering, orientation, and component tolerances.

Final troubleshooting flow (concise)

  1. Visual inspection → 2. Power pins & reset check → 3. SWD connect and read device → 4. Mass erase / reflash simple blink → 5. Read reset flags → 6. Add fault handler to dump regs → 7. Probe clocks & NRST with scope → 8. Inspect peripherals one by one (I2C/UART/SPI/ADC) → 9. Reflow/swap MCU if all else fails.

Top comments (0)