A custom board may need a steady stream of electrical pulses before its digital circuitry can do anything useful. If you are bringing up a new design, an adjustable clock module can help you test that requirement before committing to a fixed oscillator. But entering the right frequency in software is only the beginning: the receiving circuit must see the right signal at its own input.
On our bench we drove a GraftSense SI5351 clock module from a GraftPort-RP2040 board running MicroPython. We captured a scope trace at 2 MHz and a second trace after the output was disabled. Those are useful observations, with one important configuration problem to resolve before anyone reuses the example.
Separate the control connection from the clock output
The module has two different jobs at its connectors. I2C carries instructions from the controller, such as the frequency to generate. The SMA connectors carry the resulting clock signals to other equipment. Raising the I2C bus speed does not change the output-clock frequency.
In our setup, GP4 is SDA and GP5 is SCL on I2C0, running at 100 kHz. The board has three labeled clock outputs, but our test configured and enabled only CLK0. It does not demonstrate three simultaneous signals.
Inside the SI5351A, a crystal provides a reference. Two phase-locked loops (PLLs) multiply that reference, and output dividers then produce the requested frequencies. Think of this as a frequency plan shared by the outputs, not three unrelated clocks that can always be changed without affecting one another.
The exact package matters. The module uses the three-output part. Some family documentation covers other members, with pins and features this device does not have. A generic family diagram is not a connector map for the assembled board.
Check the frequency plan, not just the printout
Our test program created an I2C driver instance and requested a 2 MHz output. It enabled CLK0, waited 20 seconds, then disabled it. The terminal printed the requested settings:
done freq=2000000.0 mul=15 quadrature=True invert=False
That is a software message, not a measurement. And the settings contain a real problem. A 25 MHz reference multiplied by 15 gives a 375 MHz PLL frequency. Skyworks AN619, section 2 specifies a 600 to 900 MHz VCO range for the covered devices. Our settings were outside that range, even though an output was visible on the scope.
For a new implementation, calculate a valid PLL and divider combination rather than copying that multiplier. For example, 25 MHz × 24 ÷ 300 gives 2 MHz with a 600 MHz VCO. That is a frequency-plan calculation, not a tested replacement configuration: register setup, crystal loading, output mode and the selected driver's behavior still need checking.
The printout also says quadrature=True, but that variable was never passed to init_clock(), and only one output was enabled. So there is no evidence here of a 90-degree phase relationship between two outputs, whatever the variable is called.
Measure what reaches the receiving circuit
We connected the output to a scope through an SMA adapter and short flying leads. The trace was square-like, with a displayed frequency of 2.00 MHz and visible overshoot and ringing at the edges.
That is enough to show a periodic output in this setup. It is not a precision frequency calibration, a jitter measurement or proof that a connected peripheral would accept every edge. The trace alone also cannot tell how much of the overshoot comes from the module, the wiring or the measurement arrangement.
For board bring-up, measure at the receiving clock input with the intended connection in place. Compare its high and low levels, timing and edge behavior with that device's input requirements. A trace at an unloaded module connector answers a different question from a trace taken after the cable and the actual load are attached.
This is where the product decision becomes concrete. If a peripheral works only with a very short test lead, the next task is the clock connection and board layout. If it fails after a cold start but works after reconfiguration, record the startup sequence before changing anything else.
A precise ratio does not make the crystal perfect
It is tempting to describe a synthesizer like this as having zero frequency error. That needs qualification. Skyworks' August 2025 FAQ explains that the synthesis ratios can introduce little or no error for many frequencies, while the reference crystal's inaccuracy still appears at the output.
For a prototype, decide how much error the receiving circuit actually allows. A frequency used to exercise a logic input may have different requirements from a measurement reference. If calibration is necessary, record the reference instrument and conditions; a scope's rounded 2.00 MHz label is not evidence of parts-per-million accuracy.
The crystal requirements (frequency, load capacitance and ESR) bring the discussion back to a physical component. Select the actual crystal and the register load setting together, for the exact board revision, rather than treating a software constant of 25e6 as a measured value.
Check startup and shutdown as well as steady output
Our second scope capture showed the output no longer oscillating after the program's wait. Keep that as a separate test result: being able to generate a clock and being able to stop it are different behaviors.
A recent maintenance example shows why status matters as much as commands. A September 20, 2026 Linux Si5351 patch submission addresses a path that could report preparation success after a PLL-reset timeout. It concerns a different driver and is a proposed code change, not proof of the same fault in the MicroPython driver we used.
For your next test, record the required output, the reference crystal, a valid frequency plan, the receiving input and the measured waveform at that input. Repeat after a power cycle and after disabling and re-enabling the output. That produces a useful clock-integration result instead of just a successful I2C transaction. We have not yet rerun our setup with a corrected frequency plan.