PlutoSDR clock input

Warning! This modification voids the warranty and can operate the transceiver outside of it’s absolute maximum ratings!

PlutoSDR with 3rd SMA jack for clock input

The PlutoSDR has an internal XO (Rakon RXO3225M 40.000 MHz), which has excellent qualities like very low jitter.
Unfortunatly for ham radio use, the absolute accuracy (PPM) and stability isn’t great.
When generating signals in the GHz-range (like a TX-signal for QO-100 at 2.4 GHz) the error can multiply up to several kHz, much more than the signal bandwidth itself.

Oscillator mod

PlutoSDR with 3rd SMA jack PlutoSDR PCB, most parts masked off with Kapton tape, except for the crystal oscillator PlutoSDR PCB with crystal oscillator (Y3) removed PlutoSDR PCB with wire from 3rd/middle SMA jack to upper-left pin of the Y3 footprint

To fix this issue, I modified my PlutoSDR to accept an external 40 MHz reference clock signal.
This signal is provided by a LeoBodnar Mini GPS Reference Clock, which has an adjustable output frequency and is pretty much perfect for this application.

The AD9363 transceiver chip only requires a very low signal input. Ideally you would install 2 fast antiparallel diodes to clamp the voltage to a maximum of about 0.7V. My modification is a bit rough and may damage the chip in the long run, but it works fine for now.

PlutoSDRs are factory calibrated to their own XOs.
When using an external reference clock you’ll need to set xo_correction = 40000000 in the config.txt.

Frequency counter, measuring 2350.0001 MHz PlutoSDR with LeoBodnar GPS referenced clock on top, connected via SMA cable

Alternative reference frequencies

The PlutoSDR can accept a wide range of input reference frequencies between 10 MHz and 80 MHz. This can be useful if you want to use a regular 10 MHz lab reference or want to share the same GPSDO between a PlutoSDR and a satellite LNB (which commonly use ~27 MHz).

After logging into the PlutoSDR either via SSH (192.168.2.1 root/analog) or serial console, the following commands can be used to set the reference clock:

fw_setenv adi_loadvals 'fdt addr ${fit_load_address} && fdt get value fdt_choosen /configurations/${fit_config}/ fdt && fdt get addr fdtaddr /images/${fdt_choosen} data && fdt addr ${fdtaddr}; if test ! -n ${ad936x_skip_ext_refclk}; then if test -n ${ad936x_custom_refclk}; then fdt set /clocks/clock@0 clock-frequency ${ad936x_custom_refclk}; elif test -n ${ad936x_ext_refclk}; then fdt set /clocks/clock@0 clock-frequency ${ad936x_ext_refclk}; fi; fi; if test -n ${model}; then fdt set / model ${model}; fi; if test -n ${attr_name} && test -n ${attr_val}; then fdt set /amba/spi@e0006000/ad9361-phy@0 ${attr_name} ${attr_val}; fi'
fw_setenv ad936x_custom_refclk "<25000000>"

These (rather unwieldy) commands will change the behaviour of the bootloader at startup. Normally the u-boot looks for a special variable called ad936x_ext_refclk which is set in the factory and contains an individually calibrated value for each PlutoSDR. This value then gets loaded into the device tree. We modify that behaviour so that we can set our own ad936x_custom_refclk variable with a custom value.
Note: The < >-characters around the frequency are mandatory.

To check if our changes were successful, we can read the device-tree:

cat /proc/device-tree/clocks/clock@0/clock-frequency | xxd
# 00000000: 017d 7840                                .}x@

Hex 017d 7840 is 25000000 in decimal, so our custom frequency was successfully applied.