Overcoming the 2 MSPS ADC Bottleneck
When sampling a 12-bit ADC at 2 MSPS on a 400 MHz MCU, relying on CPU interrupts is a recipe for system lockup. With only 500ns between samples, you have a strict budget of just 200 CPU cycles. Once you account for context saving and IRQ exit latency, your CPU is completely saturated.
To reclaim your processor, we must architect a system that operates entirely in the background.
The Autonomous Hardware Chain
The secret to zero-overhead data acquisition is daisy-chaining your MCU’s hardware peripherals. We decouple the hardware from the math using Double-Buffered (Ping-Pong) DMA.
- The Trigger: A PWM timer running at exactly 2 MHz is configured to generate a Start of Conversion (SOC) on ADC Channel 0.
- The ADC: Upon completing the 12-bit conversion, the ADC generates a hardware event mapped directly to a DMA request.
- The Transfer: You must configure a DMA channel to pull the data from the device’s internal FIFO and stream it directly into your RAM.
The 512-Sample Ping-Pong Architecture
Instead of handling data sample by sample, the DMA controller fills massive blocks of memory while the CPU sleeps.
- Define two 512-sample arrays to act as a Ping-Pong double buffer in memory.
- The DMA continuously streams the incoming ADC results into the active buffer.
-
The EDMA fires an interrupt only when a 512-sample buffer is completely full.
- Because we process blocks instead of single samples, the interrupt frequency plummets from 2,000,000 Hz to approximately 3.9kHz.
Welford RMS & CPU Cycle Budget
Inside the 3.9kHz interrupt handler, we need to calculate the Root Mean Square (RMS) of the 512-sample block. Using standard summation for squares can quickly cause numerical overflow, so we apply Welford’s method to compute variance in a single pass using a robust iterative formula:
\[M_k = M_{k-1} + \frac{x_k - M_{k-1}}{k}\] \[S_k = S_{k-1} + (x_k - M_{k-1})(x_k - M_k)\]By shifting to a 3.9kHz interrupt rate, your available CPU time between interrupts expands from 200 cycles to an enormous 102,400 cycles (256us at 400 MHz). Running Welford’s method over 512 samples requires only a few thousand cycles.
-
Your CPU load drops from total saturation to a fraction of its capacity, while maintaining mathematically perfect continuous phase tracking.
-
You can verify this exact CPU utilization by toggling a dedicated GPIO pin high at the start of your ISR and low at the end, measuring the Worst Case Execution Time (WCET) on an oscilloscope.
