Adafruit Si5351 Library
Adafruit_SI5351.h
1 /*
2  * @file Adafruit_SI5351.h
3  */
4 
5 #ifndef _SI5351_H_
6 #define _SI5351_H_
7 
8 #if ARDUINO >= 100
9 #include <Arduino.h>
10 #else
11 #include <WProgram.h>
12 #endif
13 //#include <Adafruit_Sensor.h>
14 #include <Adafruit_I2CDevice.h>
15 
16 #include "asserts.h"
17 #include "errors.h"
18 
19 #define SI5351_ADDRESS (0x60) // Assumes ADDR pin = low
20 #define SI5351_READBIT (0x01)
21 
22 /* Test setup from SI5351 ClockBuilder
23  * -----------------------------------
24  * XTAL: 25 MHz
25  * Channel 0: 120.00 MHz
26  * Channel 1: 12.00 MHz
27  * Channel 2: 13.56 MHz
28  */
29 static const uint8_t m_si5351_regs_15to92_149to170[100][2] = {
30  {15, 0x00}, /* Input source = crystal for PLLA and PLLB */
31  {16, 0x4F}, /* CLK0 Control: 8mA drive, Multisynth 0 as CLK0 source, Clock
32  not inverted, Source = PLLA, Multisynth 0 in integer mode,
33  clock powered up */
34  {17, 0x4F}, /* CLK1 Control: 8mA drive, Multisynth 1 as CLK1 source, Clock
35  not inverted, Source = PLLA, Multisynth 1 in integer mode,
36  clock powered up */
37  {18, 0x6F}, /* CLK2 Control: 8mA drive, Multisynth 2 as CLK2 source, Clock
38  not inverted, Source = PLLB, Multisynth 2 in integer mode,
39  clock powered up */
40  {19, 0x80}, /* CLK3 Control: Not used ... clock powered down */
41  {20, 0x80}, /* CLK4 Control: Not used ... clock powered down */
42  {21, 0x80}, /* CLK5 Control: Not used ... clock powered down */
43  {22, 0x80}, /* CLK6 Control: Not used ... clock powered down */
44  {23, 0x80}, /* CLK7 Control: Not used ... clock powered down */
45  {24, 0x00}, /* Clock disable state 0..3 (low when disabled) */
46  {25, 0x00}, /* Clock disable state 4..7 (low when disabled) */
47  /* PLL_A Setup */
48  {26, 0x00},
49  {27, 0x05},
50  {28, 0x00},
51  {29, 0x0C},
52  {30, 0x66},
53  {31, 0x00},
54  {32, 0x00},
55  {33, 0x02},
56  /* PLL_B Setup */
57  {34, 0x02},
58  {35, 0x71},
59  {36, 0x00},
60  {37, 0x0C},
61  {38, 0x1A},
62  {39, 0x00},
63  {40, 0x00},
64  {41, 0x86},
65  /* Multisynth Setup */
66  {42, 0x00},
67  {43, 0x01},
68  {44, 0x00},
69  {45, 0x01},
70  {46, 0x00},
71  {47, 0x00},
72  {48, 0x00},
73  {49, 0x00},
74  {50, 0x00},
75  {51, 0x01},
76  {52, 0x00},
77  {53, 0x1C},
78  {54, 0x00},
79  {55, 0x00},
80  {56, 0x00},
81  {57, 0x00},
82  {58, 0x00},
83  {59, 0x01},
84  {60, 0x00},
85  {61, 0x18},
86  {62, 0x00},
87  {63, 0x00},
88  {64, 0x00},
89  {65, 0x00},
90  {66, 0x00},
91  {67, 0x00},
92  {68, 0x00},
93  {69, 0x00},
94  {70, 0x00},
95  {71, 0x00},
96  {72, 0x00},
97  {73, 0x00},
98  {74, 0x00},
99  {75, 0x00},
100  {76, 0x00},
101  {77, 0x00},
102  {78, 0x00},
103  {79, 0x00},
104  {80, 0x00},
105  {81, 0x00},
106  {82, 0x00},
107  {83, 0x00},
108  {84, 0x00},
109  {85, 0x00},
110  {86, 0x00},
111  {87, 0x00},
112  {88, 0x00},
113  {89, 0x00},
114  {90, 0x00},
115  {91, 0x00},
116  {92, 0x00},
117  /* Misc Config Register */
118  {149, 0x00},
119  {150, 0x00},
120  {151, 0x00},
121  {152, 0x00},
122  {153, 0x00},
123  {154, 0x00},
124  {155, 0x00},
125  {156, 0x00},
126  {157, 0x00},
127  {158, 0x00},
128  {159, 0x00},
129  {160, 0x00},
130  {161, 0x00},
131  {162, 0x00},
132  {163, 0x00},
133  {164, 0x00},
134  {165, 0x00},
135  {166, 0x00},
136  {167, 0x00},
137  {168, 0x00},
138  {169, 0x00},
139  {170, 0x00}};
140 
141 /* See http://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf for
142  * registers 26..41 */
143 enum {
144  SI5351_REGISTER_0_DEVICE_STATUS = 0,
145  SI5351_REGISTER_1_INTERRUPT_STATUS_STICKY = 1,
146  SI5351_REGISTER_2_INTERRUPT_STATUS_MASK = 2,
147  SI5351_REGISTER_3_OUTPUT_ENABLE_CONTROL = 3,
148  SI5351_REGISTER_9_OEB_PIN_ENABLE_CONTROL = 9,
149  SI5351_REGISTER_15_PLL_INPUT_SOURCE = 15,
150  SI5351_REGISTER_16_CLK0_CONTROL = 16,
151  SI5351_REGISTER_17_CLK1_CONTROL = 17,
152  SI5351_REGISTER_18_CLK2_CONTROL = 18,
153  SI5351_REGISTER_19_CLK3_CONTROL = 19,
154  SI5351_REGISTER_20_CLK4_CONTROL = 20,
155  SI5351_REGISTER_21_CLK5_CONTROL = 21,
156  SI5351_REGISTER_22_CLK6_CONTROL = 22,
157  SI5351_REGISTER_23_CLK7_CONTROL = 23,
158  SI5351_REGISTER_24_CLK3_0_DISABLE_STATE = 24,
159  SI5351_REGISTER_25_CLK7_4_DISABLE_STATE = 25,
160  SI5351_REGISTER_42_MULTISYNTH0_PARAMETERS_1 = 42,
161  SI5351_REGISTER_43_MULTISYNTH0_PARAMETERS_2 = 43,
162  SI5351_REGISTER_44_MULTISYNTH0_PARAMETERS_3 = 44,
163  SI5351_REGISTER_45_MULTISYNTH0_PARAMETERS_4 = 45,
164  SI5351_REGISTER_46_MULTISYNTH0_PARAMETERS_5 = 46,
165  SI5351_REGISTER_47_MULTISYNTH0_PARAMETERS_6 = 47,
166  SI5351_REGISTER_48_MULTISYNTH0_PARAMETERS_7 = 48,
167  SI5351_REGISTER_49_MULTISYNTH0_PARAMETERS_8 = 49,
168  SI5351_REGISTER_50_MULTISYNTH1_PARAMETERS_1 = 50,
169  SI5351_REGISTER_51_MULTISYNTH1_PARAMETERS_2 = 51,
170  SI5351_REGISTER_52_MULTISYNTH1_PARAMETERS_3 = 52,
171  SI5351_REGISTER_53_MULTISYNTH1_PARAMETERS_4 = 53,
172  SI5351_REGISTER_54_MULTISYNTH1_PARAMETERS_5 = 54,
173  SI5351_REGISTER_55_MULTISYNTH1_PARAMETERS_6 = 55,
174  SI5351_REGISTER_56_MULTISYNTH1_PARAMETERS_7 = 56,
175  SI5351_REGISTER_57_MULTISYNTH1_PARAMETERS_8 = 57,
176  SI5351_REGISTER_58_MULTISYNTH2_PARAMETERS_1 = 58,
177  SI5351_REGISTER_59_MULTISYNTH2_PARAMETERS_2 = 59,
178  SI5351_REGISTER_60_MULTISYNTH2_PARAMETERS_3 = 60,
179  SI5351_REGISTER_61_MULTISYNTH2_PARAMETERS_4 = 61,
180  SI5351_REGISTER_62_MULTISYNTH2_PARAMETERS_5 = 62,
181  SI5351_REGISTER_63_MULTISYNTH2_PARAMETERS_6 = 63,
182  SI5351_REGISTER_64_MULTISYNTH2_PARAMETERS_7 = 64,
183  SI5351_REGISTER_65_MULTISYNTH2_PARAMETERS_8 = 65,
184  SI5351_REGISTER_66_MULTISYNTH3_PARAMETERS_1 = 66,
185  SI5351_REGISTER_67_MULTISYNTH3_PARAMETERS_2 = 67,
186  SI5351_REGISTER_68_MULTISYNTH3_PARAMETERS_3 = 68,
187  SI5351_REGISTER_69_MULTISYNTH3_PARAMETERS_4 = 69,
188  SI5351_REGISTER_70_MULTISYNTH3_PARAMETERS_5 = 70,
189  SI5351_REGISTER_71_MULTISYNTH3_PARAMETERS_6 = 71,
190  SI5351_REGISTER_72_MULTISYNTH3_PARAMETERS_7 = 72,
191  SI5351_REGISTER_73_MULTISYNTH3_PARAMETERS_8 = 73,
192  SI5351_REGISTER_74_MULTISYNTH4_PARAMETERS_1 = 74,
193  SI5351_REGISTER_75_MULTISYNTH4_PARAMETERS_2 = 75,
194  SI5351_REGISTER_76_MULTISYNTH4_PARAMETERS_3 = 76,
195  SI5351_REGISTER_77_MULTISYNTH4_PARAMETERS_4 = 77,
196  SI5351_REGISTER_78_MULTISYNTH4_PARAMETERS_5 = 78,
197  SI5351_REGISTER_79_MULTISYNTH4_PARAMETERS_6 = 79,
198  SI5351_REGISTER_80_MULTISYNTH4_PARAMETERS_7 = 80,
199  SI5351_REGISTER_81_MULTISYNTH4_PARAMETERS_8 = 81,
200  SI5351_REGISTER_82_MULTISYNTH5_PARAMETERS_1 = 82,
201  SI5351_REGISTER_83_MULTISYNTH5_PARAMETERS_2 = 83,
202  SI5351_REGISTER_84_MULTISYNTH5_PARAMETERS_3 = 84,
203  SI5351_REGISTER_85_MULTISYNTH5_PARAMETERS_4 = 85,
204  SI5351_REGISTER_86_MULTISYNTH5_PARAMETERS_5 = 86,
205  SI5351_REGISTER_87_MULTISYNTH5_PARAMETERS_6 = 87,
206  SI5351_REGISTER_88_MULTISYNTH5_PARAMETERS_7 = 88,
207  SI5351_REGISTER_89_MULTISYNTH5_PARAMETERS_8 = 89,
208  SI5351_REGISTER_90_MULTISYNTH6_PARAMETERS = 90,
209  SI5351_REGISTER_91_MULTISYNTH7_PARAMETERS = 91,
210  SI5351_REGISTER_092_CLOCK_6_7_OUTPUT_DIVIDER = 92,
211  SI5351_REGISTER_149_SPREAD_SPECTRUM_PARAMETERS = 149,
212  SI5351_REGISTER_165_CLK0_INITIAL_PHASE_OFFSET = 165,
213  SI5351_REGISTER_166_CLK1_INITIAL_PHASE_OFFSET = 166,
214  SI5351_REGISTER_167_CLK2_INITIAL_PHASE_OFFSET = 167,
215  SI5351_REGISTER_168_CLK3_INITIAL_PHASE_OFFSET = 168,
216  SI5351_REGISTER_169_CLK4_INITIAL_PHASE_OFFSET = 169,
217  SI5351_REGISTER_170_CLK5_INITIAL_PHASE_OFFSET = 170,
218  SI5351_REGISTER_177_PLL_RESET = 177,
219  SI5351_REGISTER_183_CRYSTAL_INTERNAL_LOAD_CAPACITANCE = 183
220 };
221 
222 typedef enum {
223  SI5351_PLL_A = 0,
224  SI5351_PLL_B,
225 } si5351PLL_t;
226 
227 typedef enum {
228  SI5351_CRYSTAL_LOAD_6PF = (1 << 6),
229  SI5351_CRYSTAL_LOAD_8PF = (2 << 6),
230  SI5351_CRYSTAL_LOAD_10PF = (3 << 6)
231 } si5351CrystalLoad_t;
232 
233 typedef enum {
234  SI5351_CRYSTAL_FREQ_25MHZ = (25000000),
235  SI5351_CRYSTAL_FREQ_27MHZ = (27000000)
236 } si5351CrystalFreq_t;
237 
238 typedef enum {
239  SI5351_MULTISYNTH_DIV_4 = 4,
240  SI5351_MULTISYNTH_DIV_6 = 6,
241  SI5351_MULTISYNTH_DIV_8 = 8
242 } si5351MultisynthDiv_t;
243 
244 typedef enum {
245  SI5351_R_DIV_1 = 0,
246  SI5351_R_DIV_2 = 1,
247  SI5351_R_DIV_4 = 2,
248  SI5351_R_DIV_8 = 3,
249  SI5351_R_DIV_16 = 4,
250  SI5351_R_DIV_32 = 5,
251  SI5351_R_DIV_64 = 6,
252  SI5351_R_DIV_128 = 7,
253 } si5351RDiv_t;
254 
258 typedef struct {
259  bool initialised;
260  si5351CrystalFreq_t crystalFreq;
261  si5351CrystalLoad_t crystalLoad;
262  uint32_t crystalPPM;
264  uint32_t plla_freq;
266  uint32_t pllb_freq;
268 
273 public:
274  Adafruit_SI5351(void);
275 
276  err_t begin(TwoWire *theWire = &Wire);
277  err_t setClockBuilderData(void);
278  err_t setupPLL(si5351PLL_t pll, uint8_t mult, uint32_t num,
279  uint32_t denom);
280  err_t setupPLLInt(si5351PLL_t pll, uint8_t mult);
281  err_t setupMultisynth(uint8_t output, si5351PLL_t pllSource, uint32_t div,
282  uint32_t num, uint32_t denom);
283  err_t setupMultisynthInt(uint8_t output, si5351PLL_t pllSource,
284  si5351MultisynthDiv_t div);
285 
286  err_t enableSpreadSpectrum(bool enabled);
287  err_t enableOutputs(bool enabled);
292  err_t setupRdiv(uint8_t output, si5351RDiv_t div);
293 
294 private:
295  si5351Config_t m_si5351Config;
296 
297  Adafruit_I2CDevice *i2c_dev = NULL;
298  err_t write8(uint8_t reg, uint8_t value);
299  err_t read8(uint8_t reg, uint8_t *value);
300  err_t writeN(uint8_t *data, uint8_t n);
301 
302  uint8_t lastRdivValue[3];
303 };
304 
305 #endif
bool plla_configured
Phase-locked loop A configured.
Definition: Adafruit_SI5351.h:263
SI5351 constructor.
Definition: Adafruit_SI5351.h:258
err_t enableSpreadSpectrum(bool enabled)
Enables or disables spread spectrum.
Definition: Adafruit_SI5351.cpp:533
err_t
Definition: errors.h:13
err_t setupPLL(si5351PLL_t pll, uint8_t mult, uint32_t num, uint32_t denom)
Sets the multiplier for the specified PLL.
Definition: Adafruit_SI5351.cpp:219
bool pllb_configured
Phase-locked loop B configured.
Definition: Adafruit_SI5351.h:265
err_t setupMultisynthInt(uint8_t output, si5351PLL_t pllSource, si5351MultisynthDiv_t div)
Configures the Multisynth divider using integer output.
Definition: Adafruit_SI5351.cpp:313
err_t setupMultisynth(uint8_t output, si5351PLL_t pllSource, uint32_t div, uint32_t num, uint32_t denom)
Configures the Multisynth divider, which determines the output clock frequency based on the specified...
Definition: Adafruit_SI5351.cpp:398
SI5351 class.
Definition: Adafruit_SI5351.h:272
bool initialised
Initialization status of SI5351.
Definition: Adafruit_SI5351.h:259
Adafruit_SI5351(void)
SI5351 object.
Definition: Adafruit_SI5351.cpp:67
uint32_t pllb_freq
Phase-locked loop B frequency.
Definition: Adafruit_SI5351.h:266
err_t enableOutputs(bool enabled)
Enables or disables all clock outputs.
Definition: Adafruit_SI5351.cpp:515
err_t setClockBuilderData(void)
Configures the Si5351 with config settings generated in ClockBuilder. You can use this function to ma...
Definition: Adafruit_SI5351.cpp:150
err_t begin(TwoWire *theWire=&Wire)
Initializes I2C and configures the breakout (call this function before doing anything else) ...
Definition: Adafruit_SI5351.cpp:90
uint32_t plla_freq
Phase-locked loop A frequency.
Definition: Adafruit_SI5351.h:264
uint32_t crystalPPM
Frequency synthesis.
Definition: Adafruit_SI5351.h:262
err_t setupRdiv(uint8_t output, si5351RDiv_t div)
Definition: Adafruit_SI5351.cpp:318
si5351CrystalLoad_t crystalLoad
Crystal load capacitors.
Definition: Adafruit_SI5351.h:261
err_t setupPLLInt(si5351PLL_t pll, uint8_t mult)
Sets the multiplier for the specified PLL using integer values.
Definition: Adafruit_SI5351.cpp:185
si5351CrystalFreq_t crystalFreq
Crystal frequency.
Definition: Adafruit_SI5351.h:260