DEV Community

Hedy
Hedy

Posted on

How to effectively deal with crystal oscillator failure in TM4C129X MCU

Here’s a proven playbook for handling a crystal (MOSC) failure on TI’s TM4C129x MCUs:

1) Turn on the hardware monitor (and set it up correctly)

  • Enable MOSC verification: set MOSCCTL.CVAL = 1.
  • Pick the proper range: for 10–25 MHz crystals, set MOSCCTL.OSCRNG = 1 (High-frequency range).
  • Tell the chip a crystal is actually connected: clear MOSCCTL.NOXTAL when you have a crystal or single-ended clock attached.
  • Don’t power it down accidentally: clear MOSCCTL.PWRDN for crystal mode; and consider locking MOSC on across sleep/“accidental power-down” by setting DSCLKCFG.MOSCDPD = 1 if peripherals (e.g., Ethernet PHY) depend on MOSC.

2) Decide the failure action: reset+NMI or interrupt

The monitor runs continuously; if the main oscillator goes out of bounds, hardware auto-switches the system clock to the 16 MHz PIOSC. Then one of two things happens, based on MOSCCTL.MOSCIM:

  • MOSCIM = 0: internal reset occurs, RESC.MOSCFAIL is set, and execution is vectored to the NMI handler on reboot.
  • MOSCIM = 1: a maskable interrupt is raised (RIS.MOFRIS / MISC.MOFMIS flow). Choose the path that best fits your product’s safety story (reset-for-safety vs. stay up and degrade service).

Tip: On older silicon, the NMIC register may not reliably indicate the NMI source. Use RIS.MOFRIS to confirm a MOSC failure (errata SYSCTL#13).

3) What your handler should actually do

Whether you land in NMI (after a reset) or a normal ISR:

1. Acknowledge & log

  • Read and then clear RESC.MOSCFAIL (write 0 to clear that sticky bit).
  • If using interrupts, clear the MISC.MOFMIS bit by writing 1 to it.

2. Run in a safe clock

You’re already on PIOSC (hardware switched you), but explicitly ensure the system stays on a stable source (PIOSC or PLL sourced from PIOSC) until recovery.

3. Attempt recovery with a timeout

Re-enable MOSC (clear PWRDN, keep NOXTAL=0), wait for MOSC power-up (RIS.MOSCPUPRIS), then re-lock PLL (watch RIS.PLLLRIS). If any wait times out, abort and stay in “safe mode.”

4. Gradual restore

Only after MOSC and PLL are stable, switch system clock back to MOSC/PLL and resume services that require precise timing (Ethernet/USB/etc.).

4) Add a belt-and-suspenders watchdog

Run Watchdog 1 from an alternate clock (PIOSC/LFIOSC via ALTCLK) so it still barks even if MOSC disappears. If your recovery logic stalls, the watchdog(What is a Watchdog?) guarantees a reset.

5) What MOSC failure can (and can’t) detect

The verification circuit does run at runtime (not just at start) and detects when MOSC frequency wanders outside a broad valid band. It’s not a precision drift detector (e.g., 25 MHz → 24 MHz may not trip it). If you need tighter assurance, implement a software cross-check that measures a MOSC-derived clock against PIOSC.

6) Common pitfalls & errata to mind

  • EEPROM/flash operations: resets (including MOSC-failure resets) during EEPROM writes can corrupt data; avoid non-volatile writes in your failure path.
  • Deep-sleep power: some revisions had higher deep-sleep current if MOSC wasn’t explicitly turned off; follow the recommended MOSC power sequencing (and use MOSCDPD when you must keep MOSC alive).
  • ROM driver quirk: early ROM SysCtlClockFreqSet had MOSC issues; use the flash version from TivaWare if you’re on affected silicon.

Minimal checklist (copy into your bring-up notes)

  • Set MOSCCTL: CVAL=1, OSCRNG=1 (≥10 MHz), NOXTAL=0, PWRDN=0.
  • Choose action: MOSCIM=0 (reset+NMI) or MOSCIM=1 (interrupt) and enable IMC.MOFIM.
  • In handler: clear MISC.MOFMIS or RESC.MOSCFAIL, stay on PIOSC, try timed MOSC/PLL re-bring-up.
  • Enable WDT1 on ALTCLK (PIOSC/LFIOSC) as a last resort.
  • If Ethernet/PHY depends on MOSC, set DSCLKCFG.MOSCDPD=1 so MOSC can’t be auto-powered down.

Top comments (0)