Skip to content

Commit 99907b5

Browse files
committed
refactor: use regmap instead of legacy package to avoid heap allocations
Signed-off-by: deadprogram <ron@hybridgroup.com>
1 parent 4d9a363 commit 99907b5

File tree

1 file changed

+33
-81
lines changed

1 file changed

+33
-81
lines changed

si5351/si5351.go

Lines changed: 33 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
package si5351
22

33
import (
4+
"encoding/binary"
45
"errors"
56
"fmt"
67
"math"
78

89
"tinygo.org/x/drivers"
9-
"tinygo.org/x/drivers/internal/legacy"
10+
"tinygo.org/x/drivers/internal/regmap"
1011
)
1112

1213
// Device wraps an I2C connection to a SI5351 device.
1314
type Device struct {
1415
bus drivers.I2C
1516
Address uint8
1617

17-
buf [8]byte
18+
rw regmap.Device8
1819
initialised bool
1920
crystalFreq uint32
2021
crystalLoad uint8
@@ -43,29 +44,14 @@ func New(bus drivers.I2C) Device {
4344
// Configure sets up the device for communication
4445
// TODO error handling
4546
func (d *Device) Configure() error {
46-
data := d.buf[:1]
47-
48-
// Disable all outputs setting CLKx_DIS high
49-
data[0] = 0xFF
50-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), OUTPUT_ENABLE_CONTROL, data); err != nil {
51-
return err
52-
}
47+
// // Disable all outputs setting CLKx_DIS high
48+
d.rw.Write8I2C(d.bus, uint16(d.Address), OUTPUT_ENABLE_CONTROL, 0xFF)
5349

5450
// Set the load capacitance for the XTAL
55-
data[0] = d.crystalLoad
56-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), CRYSTAL_INTERNAL_LOAD_CAPACITANCE, data); err != nil {
57-
return err
58-
}
59-
60-
data = d.buf[:8]
51+
d.rw.Write8I2C(d.bus, uint16(d.Address), CRYSTAL_INTERNAL_LOAD_CAPACITANCE, d.crystalLoad)
6152

6253
// Power down all output drivers
63-
for i := range data {
64-
data[i] = 0x80
65-
}
66-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), CLK0_CONTROL, data); err != nil {
67-
return err
68-
}
54+
d.rw.Write32I2C(d.bus, uint16(d.Address), CLK0_CONTROL, 0x80808080, binary.LittleEndian)
6955

7056
// Disable spread spectrum output.
7157
if err := d.DisableSpreadSpectrum(); err != nil {
@@ -85,29 +71,25 @@ func (d *Device) Connected() (bool, error) {
8571
return true, nil
8672
}
8773

74+
// EnableSpreadSpectrum enables spread spectrum modulation to reduce EMI.
8875
func (d *Device) EnableSpreadSpectrum() error {
89-
data := d.buf[:1]
90-
if err := legacy.ReadRegister(d.bus, uint8(d.Address), SPREAD_SPECTRUM_PARAMETERS, data); err != nil {
76+
data, err := d.rw.Read8I2C(d.bus, uint16(d.Address), SPREAD_SPECTRUM_PARAMETERS)
77+
if err != nil {
9178
return err
9279
}
93-
data[0] |= 0x80
94-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), SPREAD_SPECTRUM_PARAMETERS, data); err != nil {
95-
return err
96-
}
97-
return nil
80+
81+
data |= 0x80
82+
return d.rw.Write8I2C(d.bus, uint16(d.Address), SPREAD_SPECTRUM_PARAMETERS, data)
9883
}
9984

10085
func (d *Device) DisableSpreadSpectrum() error {
101-
data := d.buf[:1]
102-
if err := legacy.ReadRegister(d.bus, uint8(d.Address), SPREAD_SPECTRUM_PARAMETERS, data); err != nil {
103-
return err
104-
}
105-
data[0] &^= 0x80
106-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), SPREAD_SPECTRUM_PARAMETERS, data); err != nil {
86+
data, err := d.rw.Read8I2C(d.bus, uint16(d.Address), SPREAD_SPECTRUM_PARAMETERS)
87+
if err != nil {
10788
return err
10889
}
10990

110-
return nil
91+
data &^= 0x80
92+
return d.rw.Write8I2C(d.bus, uint16(d.Address), SPREAD_SPECTRUM_PARAMETERS, data)
11193
}
11294

11395
func (d *Device) OutputEnable(output uint8, enable bool) error {
@@ -116,13 +98,11 @@ func (d *Device) OutputEnable(output uint8, enable bool) error {
11698
}
11799

118100
// Read the current value of the OUTPUT_ENABLE_CONTROL register
119-
data := make([]byte, 1)
120-
if err := legacy.ReadRegister(d.bus, uint8(d.Address), OUTPUT_ENABLE_CONTROL, data); err != nil {
101+
regVal, err := d.rw.Read8I2C(d.bus, uint16(d.Address), OUTPUT_ENABLE_CONTROL)
102+
if err != nil {
121103
return err
122104
}
123105

124-
regVal := data[0]
125-
126106
// Modify regVal based on clk and enable
127107
if enable {
128108
regVal &= ^(1 << output)
@@ -131,36 +111,22 @@ func (d *Device) OutputEnable(output uint8, enable bool) error {
131111
}
132112

133113
// Write the modified value back to the OUTPUT_ENABLE_CONTROL register
134-
data[0] = regVal
135-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), OUTPUT_ENABLE_CONTROL, data); err != nil {
136-
return err
137-
}
138-
139-
return nil
114+
return d.rw.Write8I2C(d.bus, uint16(d.Address), OUTPUT_ENABLE_CONTROL, regVal)
140115
}
141116

142117
func (d *Device) EnableOutputs() error {
143118
if !d.initialised {
144119
return ErrNotInitialised
145120
}
146-
data := d.buf[:1]
147-
data[0] = 0x00
148-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), OUTPUT_ENABLE_CONTROL, data); err != nil {
149-
return err
150-
}
151-
return nil
121+
122+
return d.rw.Write8I2C(d.bus, uint16(d.Address), OUTPUT_ENABLE_CONTROL, 0x00)
152123
}
153124

154125
func (d *Device) DisableOutputs() error {
155126
if !d.initialised {
156127
return ErrNotInitialised
157128
}
158-
data := d.buf[:1]
159-
data[0] = 0xFF
160-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), OUTPUT_ENABLE_CONTROL, data); err != nil {
161-
return err
162-
}
163-
return nil
129+
return d.rw.Write8I2C(d.bus, uint16(d.Address), OUTPUT_ENABLE_CONTROL, 0xFF)
164130
}
165131

166132
// ConfigurePLL sets the multiplier for the specified PLL
@@ -191,7 +157,6 @@ func (d *Device) DisableOutputs() error {
191157
//
192158
// See: http://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf
193159
func (d *Device) ConfigurePLL(pll uint8, mult uint8, num uint32, denom uint32) error {
194-
195160
// Basic validation
196161
if !d.initialised {
197162
return ErrNotInitialised
@@ -249,7 +214,7 @@ func (d *Device) ConfigurePLL(pll uint8, mult uint8, num uint32, denom uint32) e
249214
}
250215

251216
// The datasheet is a nightmare of typos and inconsistencies here!
252-
data := d.buf[:8]
217+
data := [8]byte{}
253218
data[0] = uint8((p3 & 0x0000FF00) >> 8)
254219
data[1] = uint8(p3 & 0x000000FF)
255220
data[2] = uint8((p1 & 0x00030000) >> 16)
@@ -258,14 +223,12 @@ func (d *Device) ConfigurePLL(pll uint8, mult uint8, num uint32, denom uint32) e
258223
data[5] = uint8(((p3 & 0x000F0000) >> 12) | ((p2 & 0x000F0000) >> 16))
259224
data[6] = uint8((p2 & 0x0000FF00) >> 8)
260225
data[7] = uint8(p2 & 0x000000FF)
261-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), baseaddr, data); err != nil {
226+
if err := d.bus.Tx(uint16(baseaddr), data[:], nil); err != nil {
262227
return err
263228
}
264229

265230
// Reset both PLLs
266-
data = d.buf[:1]
267-
data[0] = (1 << 7) | (1 << 5)
268-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), PLL_RESET, data); err != nil {
231+
if err := d.rw.Write8I2C(d.bus, uint16(d.Address), PLL_RESET, (1<<7)|(1<<5)); err != nil {
269232
return err
270233
}
271234

@@ -336,7 +299,6 @@ func (d *Device) ConfigurePLL(pll uint8, mult uint8, num uint32, denom uint32) e
336299
//
337300
// used, but this isn't currently implemented in the driver.
338301
func (d *Device) ConfigureMultisynth(output uint8, pll uint8, div uint32, num uint32, denom uint32) error {
339-
340302
// Basic validation
341303
if !d.initialised {
342304
return ErrNotInitialised
@@ -418,7 +380,7 @@ func (d *Device) ConfigureMultisynth(output uint8, pll uint8, div uint32, num ui
418380
}
419381

420382
// Set the MSx config registers
421-
data := d.buf[:8]
383+
data := [8]byte{}
422384
data[0] = uint8((p3 & 0xFF00) >> 8)
423385
data[1] = uint8(p3 & 0xFF)
424386
data[2] = uint8(((p1 & 0x30000) >> 16)) | d.lastRdivValue[output]
@@ -427,7 +389,7 @@ func (d *Device) ConfigureMultisynth(output uint8, pll uint8, div uint32, num ui
427389
data[5] = uint8(((p3 & 0xF0000) >> 12) | ((p2 & 0xF0000) >> 16))
428390
data[6] = uint8((p2 & 0xFF00) >> 8)
429391
data[7] = uint8(p2 & 0xFF)
430-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), baseaddr, data); err != nil {
392+
if err := d.bus.Tx(uint16(baseaddr), data[:], nil); err != nil {
431393
return err
432394
}
433395

@@ -451,13 +413,7 @@ func (d *Device) ConfigureMultisynth(output uint8, pll uint8, div uint32, num ui
451413
register = CLK2_CONTROL
452414
}
453415

454-
data = d.buf[:1]
455-
data[0] = clkControlReg
456-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), register, data); err != nil {
457-
return err
458-
}
459-
460-
return nil
416+
return d.rw.Write8I2C(d.bus, uint16(d.Address), register, clkControlReg)
461417
}
462418

463419
func (d *Device) ConfigureRdiv(output uint8, div uint8) error {
@@ -476,16 +432,12 @@ func (d *Device) ConfigureRdiv(output uint8, div uint8) error {
476432
register = MULTISYNTH2_PARAMETERS_3
477433
}
478434

479-
data := d.buf[:1]
480-
if err := legacy.ReadRegister(d.bus, uint8(d.Address), register, data); err != nil {
435+
data, err := d.rw.Read8I2C(d.bus, uint16(d.Address), register)
436+
if err != nil {
481437
return err
482438
}
483439

484440
d.lastRdivValue[output] = (div & 0x07) << 4
485-
data[0] = (data[0] & 0x0F) | d.lastRdivValue[output]
486-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), register, data); err != nil {
487-
return err
488-
}
489-
490-
return nil
441+
data = (data & 0x0F) | d.lastRdivValue[output]
442+
return d.rw.Write8I2C(d.bus, uint16(d.Address), register, data)
491443
}

0 commit comments

Comments
 (0)