Assignment #6: High-Speed ADC - ISR vs. DMA

📚 CMPE2250 - ICA #06: High-Speed ADC - ISR vs. DMA

📋 Overview

In this ICA, you will move beyond manual software triggering. You will use TIM6 (or any other timer) as a hardware trigger (TRGO) to automate sampling and compare two methods of data handling: Interrupt Service Routines (ISR) and Direct Memory Access (DMA).

1️⃣ Performance Profiling with PA5

To visualize the “cost” of your code and the conversion timing, you will use PA5 as a logic probe:

  • SET HIGH: Inside the Timer ISR (the moment the conversion is triggered).

  • SET LOW: Inside the ADC EOS (End of Sequence) interrupt (the moment the hardware finishes sampling all channels).

  • Objective: Use an oscilloscope to measure the pulse width. This represents the hardware “active time” for each trigger.

2️⃣ Part A: The ISR Method (CPU Intensive)

In this version, the CPU must intervene after every single conversion to move data from the ADC to memory.

  • Timer Setup: Configure TIM6 to update every 1ms and set its Master Mode (MMS) to generate a TRGO signal on every Update Event.

  • ADC Setup: Configure the ADC to be triggered by TIM6_TRGO.

  • Interrupts: Enable EOCIE (End of Conversion) and EOSIE (End of Sequence).

  • Averaging: Accumulate the sum of AN0 and AN1 inside the ADC1_COMP_IRQHandler.

  • Display: Once 1,000 sequences are complete, calculate the average and send the results to Tera Term using TERM_TxStringXY, so it displays always on the same position.

3️⃣ Part B: The DMA Method (Hardware Automated)

Refactor the code to use DMA1 Channel 1 (could use a preprocessor directive #define). This allows the hardware to move 2,000 samples (1,000 for each channel) into an array in the background.

3.1 The DMA Hardware Pipeline

  • DMAMUX: Map ADC1 (ID 5) to DMA1 Channel 1.

  • Data Width: Set MSIZE and PSIZE to 16-bit in the DMA configuration.

  • Interleaving: Because two channels are enabled, your buffer will be interleaved: [AN0, AN1, AN0, AN1…]. Your averaging function must use a stride of 2 to process the array.

3.2 The One-Shot Rearming Logic

Because we are not using circular mode, the DMA stops after 2,000 transfers. To start the next 1-second capture, your logic must:

  • Disable DMA Channel 1.

  • Reload the CNDTR to 2000.

  • Enable DMA Channel 1.

  • Re-Arm ADC: Set ADC1->CR |= ADC_CR_ADSTART. (This allows the ADC to listen for the next TIM6_TRGO pulse).

3.3 Technical Requirement: Terminal Output

  • To keep the terminal clean, do not use standard printf for the continuous data stream. Use the provided TERM_TxStringXY function to display the averages for AN0 and AN1 at a fixed coordinate on the screen.
// Example usage for your main loop
sprintf(TxBuffer, "AN0 Average: %.2f [V] | AN1 Average: %.2f [V]", avg0, avg1);
TERM_TxStringXY(USART2, 10, 10, TxBuffer); // Always displays at Row 10, Col 10

4️⃣ Submission Requirements

4.1 Analysis & Observation

  • Feed 2 signals into AN0 and AN1 using a funtion generator or AD2 and try different voltages and periodic signals at different frequecnies (remember to keep the range from 0[V] to 3.3[V])

  • Particularly try a ramp UP and ramp DOWN (synchronized ) at 1[KHz]

  • PA5 Pulse Width: Measure the pulse width on PA5. How long does it take for the ADC to finish the 2-channel sequence?

  • Frequency Estimation: Based on that pulse width, what is the theoretical maximum frequency you could set TIM6 to before the sequences begin to overlap?

4.2 Comments and Validation

  • Add all your findings into the readme.md file

💡 Technical Tips for Success

The Interleaving Pattern

When sampling two channels (AN0 and AN1), your DMA buffer will be organized as follows:

Index 0 1 2 3 4 5
Data AN0 AN1 AN0 AN1 AN0 AN1

To average only AN0, your loop must start at index 0 and increment by 2. To average AN1, start at index 1 and increment by 2.

Sync and Nyquist

When feeding a 1kHz signal into a system sampling at 1kHz, what do you expect to see on the terminal? If the result looks like a steady DC voltage that doesn’t match your signal generator’s average, try slightly increasing or decreasing your TIM6 frequency (e.g., to 1.1kHz) and observe the difference.