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. 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.
3435func 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
4550func (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.
8880func (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
10090func (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
113100func (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
142122func (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
154130func (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
193164func (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.
338306func (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
463424func (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