I bought a GPS Disciplined Oscillator (GPSDO), because I thought it’d be fun for various projects. Specifically I bought this one.

I started by calibrating my ICOM IC-9700. I made sure it got a GPS lock, and connected it to the 9700 10MHz reference port, with a 20dB attenuator inline, just in case. Ok, the receive frequency moved a bit, but how do I know it was improved? My D75 was still about 200Hz off frequency.

IC9700 screenshot showing D75

Segal’s law paraphrased: “Someone with one radio knows what frequency they’re on. Someone with two radios is never sure”.

Unless, of course, that person has two radios with disciplined oscillators. Which I do. I also have a USRP B200 with an added GPSDO accessory.

Sidenote: wow, that’s gotten expensive. Today I’d probably use the same GPSDO from DXPatrol instead (it has four outputs). Note that if you do have the GPSDO installed in the B200, then you cannot use an external 10MHz reference. It’s a known issue. Then again if you paid this much, why would you not use it?

Configuring GNU Radio to use the GPSDO

First I thought that surely the best reference would be the default, so I should be able to just send a tone, having configured only frequency and output gain:

Flowgraph showing signal->sink

But that doesn’t seem right. It was off by almost a kHz, compared to the 9700! That’s worse than the D75.

Let me try with the morse_beacon example in RustRadio, where I know I set the clock source.

cargo run -F soapysdr --example morse_beacon -- \
  --sample-rate 320k \
  --freq 436.6m \
  -d 'soapy=0,remote=tcp://my-soapysdr-server,remote:prot=tcp,driver=remote,remote:driver=uhd' \
  --ogain 0.8 \
  --clock-source gpsdo \
  'M0THC'

Perfect match with rustradio

Yeah that’s perfect. So GNU Radio is not setting the clock source, but instead defaulting to the internal undisciplined clock source.

I looked all over the GNU Radio Companion, testing both Soapy Custom Sink and Soapy Sink (deprecated). I added various versions of clock=gpsdo to driver strings and parameters. No change.

Then I went to check the source. The block does have a clock_source parameter, but it’s hidden.

Looking further, it’s not only hidden, but also unused. I guess they kept it only to prevent old flowgraphs from having syntax errors.

But there is a way to set the clock source. By sending a message.

So I created this flowgraph, with the Message PMT being pmt.dict_add(pmt.make_dict(), pmt.intern("clock_src"), pmt.intern("gpsdo")):

Flowgraph with a message strobe

It worked. You can clearly see where the strobe message told the Source block to stop being a silly goose. The internal clock can be seen being almost a kHz off, and the GPSDO is so perfect you can’t see any error, even with the waterfall zoomed in as much as it can be.

Screenshot showing strobe changing the clock

The ICOM IC-9700 can frequency lock now?

I expected the 9700 to only support a one-off calibration, but looks like it locks on to the external reference, and keeps tuning forever. And it has a button saying “Cancel Sync”. It even keeps it enabled across reboots. Nice.

Does this mean that this injection board is obsolete?

My understanding didn’t come out of nothing. Here’s a blog post that corroborates my memory.

I guess it was solved in a firmware update? My firmware version is 1.44. Oh I see, a comment from 2022 says that this has now been fixed. Which… corroborates what I’m seeing now.

So yeah. No need for an injection board. Just plug in a 10MHz reference to the reference port.