Main Content

Quadrupling the sample rate of an RP2040 oscilloscope

With a few lines of code we were able to quadruple the sample rate and bandwidth of our RP2040 based oscilloscope. We show you how.

Any oscilloscope that uses the RP2040 ADC will be limited by its modest maximum sample rate of 500kS/s - and so when I saw on the Raspberry Pi forums a thread titled RP2040 ADC Overclock - 4Msps! - I decided to investigate to see if higher sample rates could be achieved without an unacceptable effect on oscilloscope performance.

My oscilloscope uses the Scoppy firmware and Android app but the information here applies to any oscilloscope that acquires its samples using the internal ADC of the RP2040.

RP2040 ADC
The RP2040 datasheet states that the clock source for the built-in ADC must be 48MHz and that each ADC conversion takes 96 clock cycles. This gives a maximum sample rate of 500kS/s (ie. 48000000 / 96 = 500000). This in turn limits the maximum bandwidth achievable by an oscilloscope that uses the RP2040’s internal ADC.

However, if we ignore the datasheet and clock the ADC at a higher rate then we can achieve sample rates of 2.0MS/s or higher.

How to increase the maximum sample rate (i.e. reduce the sampling time)
The maximum sample rate can be increased by reducing the time required to acquire each sample. Each sample acquisition takes a fixed number of ADC clock cycles and so the obvious thing to do is reduce the ADC clock period….so how can we do that?

The Pico C-SDK configures the ADC to use the fixed frequency USB PLL as its clock source. This runs at 48MHz and in turn limits our sampling rate to 500kS/s. We can however configure the ADC to use the variable frequency system PLL as its clock source. The default frequency of the system PLL is 125MHz and so this alone will increase our maximum sample rate to approximately 1.3MS/s (125M / 96 = 1.3M)

In the forum post mentioned above, the author configures the ADC clock source by directly accessing the CLK_ADC_CTRL register. I prefer to use the clock_configure SDK function as it not only updates the CLK_ADC_CTRL register but also allows the ADC clock frequency to be accurately queried with the clock_get_hz function.”

Link to article