Skip to content

Commit 2c55886

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

File tree

1 file changed

+38
-81
lines changed

1 file changed

+38
-81
lines changed

si5351/si5351.go

Lines changed: 38 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.Device8I2C
1819
initialised bool
1920
crystalFreq uint32
2021
crystalLoad uint8
@@ -32,8 +33,12 @@ var ErrInvalidParameter = errors.New("Si5351 invalid parameter")
3233
//
3334
// This function only creates the Device object, it does not touch the device.
3435
func New(bus drivers.I2C) Device {
36+
rw := regmap.Device8I2C{}
37+
rw.SetBus(bus, AddressDefault, binary.BigEndian)
38+
3539
return Device{
3640
bus: bus,
41+
rw: rw,
3742
Address: AddressDefault,
3843
crystalFreq: CRYSTAL_FREQ_25MHZ,
3944
crystalLoad: CRYSTAL_LOAD_10PF,
@@ -43,29 +48,15 @@ func New(bus drivers.I2C) Device {
4348
// Configure sets up the device for communication
4449
// TODO error handling
4550
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-
}
51+
// // Disable all outputs setting CLKx_DIS high
52+
d.rw.Write8(OUTPUT_ENABLE_CONTROL, 0xFF)
5353

5454
// 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]
55+
d.rw.Write8(CRYSTAL_INTERNAL_LOAD_CAPACITANCE, d.crystalLoad)
6156

6257
// 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-
}
58+
buf := []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}
59+
d.bus.Tx(uint16(d.Address), append([]byte{CLK0_CONTROL}, buf...), nil)
6960

7061
// Disable spread spectrum output.
7162
if err := d.DisableSpreadSpectrum(); err != nil {
@@ -85,29 +76,25 @@ func (d *Device) Connected() (bool, error) {
8576
return true, nil
8677
}
8778

79+
// EnableSpreadSpectrum enables spread spectrum modulation to reduce EMI.
8880
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 {
81+
data, err := d.rw.Read8(SPREAD_SPECTRUM_PARAMETERS)
82+
if err != nil {
9183
return err
9284
}
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
85+
86+
data |= 0x80
87+
return d.rw.Write8(SPREAD_SPECTRUM_PARAMETERS, data)
9888
}
9989

10090
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 {
91+
data, err := d.rw.Read8(SPREAD_SPECTRUM_PARAMETERS)
92+
if err != nil {
10793
return err
10894
}
10995

110-
return nil
96+
data &^= 0x80
97+
return d.rw.Write8(SPREAD_SPECTRUM_PARAMETERS, data)
11198
}
11299

113100
func (d *Device) OutputEnable(output uint8, enable bool) error {
@@ -116,13 +103,11 @@ func (d *Device) OutputEnable(output uint8, enable bool) error {
116103
}
117104

118105
// 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 {
106+
regVal, err := d.rw.Read8(OUTPUT_ENABLE_CONTROL)
107+
if err != nil {
121108
return err
122109
}
123110

124-
regVal := data[0]
125-
126111
// Modify regVal based on clk and enable
127112
if enable {
128113
regVal &= ^(1 << output)
@@ -131,36 +116,22 @@ func (d *Device) OutputEnable(output uint8, enable bool) error {
131116
}
132117

133118
// 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
119+
return d.rw.Write8(OUTPUT_ENABLE_CONTROL, regVal)
140120
}
141121

142122
func (d *Device) EnableOutputs() error {
143123
if !d.initialised {
144124
return ErrNotInitialised
145125
}
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
126+
127+
return d.rw.Write8(OUTPUT_ENABLE_CONTROL, 0x00)
152128
}
153129

154130
func (d *Device) DisableOutputs() error {
155131
if !d.initialised {
156132
return ErrNotInitialised
157133
}
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
134+
return d.rw.Write8(OUTPUT_ENABLE_CONTROL, 0xFF)
164135
}
165136

166137
// ConfigurePLL sets the multiplier for the specified PLL
@@ -191,7 +162,6 @@ func (d *Device) DisableOutputs() error {
191162
//
192163
// See: http://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf
193164
func (d *Device) ConfigurePLL(pll uint8, mult uint8, num uint32, denom uint32) error {
194-
195165
// Basic validation
196166
if !d.initialised {
197167
return ErrNotInitialised
@@ -249,7 +219,7 @@ func (d *Device) ConfigurePLL(pll uint8, mult uint8, num uint32, denom uint32) e
249219
}
250220

251221
// The datasheet is a nightmare of typos and inconsistencies here!
252-
data := d.buf[:8]
222+
data := [8]byte{}
253223
data[0] = uint8((p3 & 0x0000FF00) >> 8)
254224
data[1] = uint8(p3 & 0x000000FF)
255225
data[2] = uint8((p1 & 0x00030000) >> 16)
@@ -258,14 +228,12 @@ func (d *Device) ConfigurePLL(pll uint8, mult uint8, num uint32, denom uint32) e
258228
data[5] = uint8(((p3 & 0x000F0000) >> 12) | ((p2 & 0x000F0000) >> 16))
259229
data[6] = uint8((p2 & 0x0000FF00) >> 8)
260230
data[7] = uint8(p2 & 0x000000FF)
261-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), baseaddr, data); err != nil {
231+
if err := d.bus.Tx(uint16(baseaddr), data[:], nil); err != nil {
262232
return err
263233
}
264234

265235
// 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 {
236+
if err := d.rw.Write8(PLL_RESET, (1<<7)|(1<<5)); err != nil {
269237
return err
270238
}
271239

@@ -336,7 +304,6 @@ func (d *Device) ConfigurePLL(pll uint8, mult uint8, num uint32, denom uint32) e
336304
//
337305
// used, but this isn't currently implemented in the driver.
338306
func (d *Device) ConfigureMultisynth(output uint8, pll uint8, div uint32, num uint32, denom uint32) error {
339-
340307
// Basic validation
341308
if !d.initialised {
342309
return ErrNotInitialised
@@ -418,7 +385,7 @@ func (d *Device) ConfigureMultisynth(output uint8, pll uint8, div uint32, num ui
418385
}
419386

420387
// Set the MSx config registers
421-
data := d.buf[:8]
388+
data := [8]byte{}
422389
data[0] = uint8((p3 & 0xFF00) >> 8)
423390
data[1] = uint8(p3 & 0xFF)
424391
data[2] = uint8(((p1 & 0x30000) >> 16)) | d.lastRdivValue[output]
@@ -427,7 +394,7 @@ func (d *Device) ConfigureMultisynth(output uint8, pll uint8, div uint32, num ui
427394
data[5] = uint8(((p3 & 0xF0000) >> 12) | ((p2 & 0xF0000) >> 16))
428395
data[6] = uint8((p2 & 0xFF00) >> 8)
429396
data[7] = uint8(p2 & 0xFF)
430-
if err := legacy.WriteRegister(d.bus, uint8(d.Address), baseaddr, data); err != nil {
397+
if err := d.bus.Tx(uint16(baseaddr), data[:], nil); err != nil {
431398
return err
432399
}
433400

@@ -451,13 +418,7 @@ func (d *Device) ConfigureMultisynth(output uint8, pll uint8, div uint32, num ui
451418
register = CLK2_CONTROL
452419
}
453420

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
421+
return d.rw.Write8(register, clkControlReg)
461422
}
462423

463424
func (d *Device) ConfigureRdiv(output uint8, div uint8) error {
@@ -476,16 +437,12 @@ func (d *Device) ConfigureRdiv(output uint8, div uint8) error {
476437
register = MULTISYNTH2_PARAMETERS_3
477438
}
478439

479-
data := d.buf[:1]
480-
if err := legacy.ReadRegister(d.bus, uint8(d.Address), register, data); err != nil {
440+
data, err := d.rw.Read8(register)
441+
if err != nil {
481442
return err
482443
}
483444

484445
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
446+
data = (data & 0x0F) | d.lastRdivValue[output]
447+
return d.rw.Write8(register, data)
491448
}

0 commit comments

Comments
 (0)