11package si5351
22
33import (
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.
1314type 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
4546func (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.
8875func (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
10085func (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
11395func (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
142117func (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
154125func (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
193159func (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.
338301func (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
463419func (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