Skip to content

Conversation

@deadprogram
Copy link
Member

Adds support for the si5351 I2C programmable clock generator using code from @chiefMarlin which used code from @conotto which somehow never got merged.

Thank you everyone!

si5351/si5351.go Outdated
"math"

"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy"
Copy link
Contributor

Choose a reason for hiding this comment

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

This is known to cause heap allocations, shall we try and avoid this from start?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point @ysoldak I just added another commit to use the regmap package instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated again with the latest code from #801

Adds support for the si5351 I2C programmable clock generator using code
from @chiefMarlin which used code from @conotto which somehow never got merged.

Thank you everyone!

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.

Very nice! Love to see regmap in use! FYI got a couple suggestions on how to avoid most if not all allocations

si5351/si5351.go Outdated

// Power down all output drivers
buf := []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}
d.bus.Tx(uint16(d.Address), append([]byte{CLK0_CONTROL}, buf...), nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Potentially avoid an allocation by doing(not guaranteed):

buf := []byte{CLK0_CONTROL, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}
	d.bus.Tx(uint16(d.Address), buf nil)

Copy link
Contributor

Choose a reason for hiding this comment

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

If you decide to add auxbuf and guaranteed allocation avoidance here make auxbuf length 9 and do:

copy(d.auxbuf[:9], []byte{CLK0_CONTROL, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80})
d.bus.Tx(uint16(d.Address), d.auxbuf[:9], nil)

Copy link
Member Author

Choose a reason for hiding this comment

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

Before any change:

$ tinygo build -size short -print-allocs=Configure -o ./build/test.hex -target=pico ./examples/si5351/main.go
/home/ron/Development/tinygo/drivers/si5351/si5351.go:59:43: object allocated on the heap: escapes at line 59
   code    data     bss |   flash     ram
  23964     200    5232 |   24164    5432

After making the first proposed change (getting rid of the append):

$ tinygo build -size short -print-allocs=Configure -o ./build/test.hex -target=pico ./examples/si5351/main.go
   code    data     bss |   flash     ram
  23936     200    5232 |   24136    5432


// Connected returns whether a device at SI5351 address has been found.
func (d *Device) Connected() (bool, error) {
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.

Maybe you can avoid an allocation here by calling d.rw.Read8. I understand you are just checking for an error from the I2C implementation for connected or not

}

// Set the MSx config registers
data := [8]byte{}
Copy link
Contributor

Choose a reason for hiding this comment

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

You can avoid an allocation here by adding this buffer to Device.

type Device struct {
    // fields...
    auxbuf [8]byte
}

And then use it here:

data := d.auxbuf[:8]
data[0] = uint8((p3 & 0xFF00) >> 8)
// ...
err := d.bus.Tx(uint16(baseaddr), data, nil)

Copy link
Member Author

@deadprogram deadprogram Nov 9, 2025

Choose a reason for hiding this comment

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

This already does not escape with this PR, so no further change needed:

$ tinygo build -size short -print-allocs=ConfigureMultisynth -o ./build/test.hex -target=pico ./examples/si5351/main.go
   code    data     bss |   flash     ram
  23936     200    5232 |   24136    5432

data[5] = uint8(((p3 & 0x000F0000) >> 12) | ((p2 & 0x000F0000) >> 16))
data[6] = uint8((p2 & 0x0000FF00) >> 8)
data[7] = uint8(p2 & 0x000000FF)
if err := d.bus.Tx(uint16(baseaddr), data[:], nil); 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.

suggestion on how to avoid allocation here below.

Copy link
Member Author

Choose a reason for hiding this comment

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

See my previous response.

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

Appears that there are no further heap allocations now. Should be ready to go.

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.

4 participants