Skip to content

Conversation

@deadprogram
Copy link
Member

@deadprogram deadprogram commented Jan 6, 2026

This PR completely refactors the interface and implementation for the si5351 clock generator. The interface based on the Arduino implementation was both somewhat hard to work with and also missing a number of important features that are needed to use this chip for RF communication.

Instead this new implementation draws inspiration from the efforts of the Traquito community. They work entirely with the rp2040 processor.

However, the actual implementation in this PR is based on the patterns and code in the TinyGo drivers repo for other i2c devices. It also includes some basic unit tests which are not comprehensive but at least provide some coverage. Of course this implementation is not tied to any particular target platform.

@deadprogram
Copy link
Member Author

PXL_20260106_155756102 MP
My scope is pretty slow but I can get <200khz just fine

Copy link
Contributor

@soypat soypat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple things I noticed to improve API

si5351/si5351.go Outdated
d.rw.Write8(CRYSTAL_INTERNAL_LOAD_CAPACITANCE, d.crystalLoad)
// Configure initializes the SI5351 with the specified crystal load capacitance,
// reference oscillator frequency, and frequency correction.
func (d *Device) Configure(xtalLoadC uint8, xoFreq uint32, correction int32) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you captured all configuration options here- or should we have a Config struct for future additions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Config type for consistency. Not sure if needed for expansion, but we're prepared just in case.

// reference oscillator frequency, and frequency correction.
func (d *Device) Configure(xtalLoadC uint8, xoFreq uint32, correction int32) error {
// Check for device on bus
if err := d.bus.Tx(uint16(d.Address), []byte{}, []byte{0}); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use d.rw instead to ensure no allocation here, or even add a IsConnected method

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think it allocates here.

si5351/si5351.go Outdated
}

// SetMultisynthSource sets the PLL source for a multisynth.
func (d *Device) SetMultisynthSource(clk uint8, pll uint8) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pll is a an enum- maybe define enums for all these types to make API usage simpler ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a number of types for clarify and safety. Good call!

si5351/si5351.go Outdated
}

// EnableOutput enables or disables a clock output.
func (d *Device) EnableOutput(clk uint8, enable bool) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clk seems to also be an enum

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

si5351/si5351.go Outdated
case pll == PLL_B && !d.pllbConfigured:
// Clock source options
const (
ClockSourceXTAL = iota
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a ClockSource type?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

si5351/si5351.go Outdated

// Clock output identifiers
const (
Clock0 uint8 = iota
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clock type

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

si5351/si5351.go Outdated

// Reference oscillator identifiers
const (
PLLInputXO = iota
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PLL type

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@deadprogram deadprogram force-pushed the si5351-refactored branch 2 times, most recently from db6fe38 to d2eb60c Compare January 7, 2026 19:27
This completely refactors the interface and implementation
for the si5351 clock generator. The interface based on the
Arduino implementation was both somewhat hard to work with
and also missing a number of important features that are
needed to use this chip for RF communication.

Instead this new implementation draws inspiration from the
efforts of the Traquino community mostly using the rp2040
processor.

The TinyGo implementation is based on the patterns and code
in the drivers repo for other i2c devices. It also includes
some basic unit tests which are not comprehensive but at
least provide some coverage.

Signed-off-by: deadprogram <ron@hybridgroup.com>
Copy link
Contributor

@soypat soypat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome stuff! thanks for the contribution ron1

@deadprogram
Copy link
Member Author

Made one last change to the naming on the config fields for clarity.

@deadprogram
Copy link
Member Author

Thanks for all the review/feedback @soypat now merging.

@deadprogram deadprogram merged commit c21cd39 into dev Jan 7, 2026
1 check passed
@deadprogram deadprogram deleted the si5351-refactored branch January 7, 2026 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants