Skip to content

Commit 8bbd75a

Browse files
committed
Add check for device on I2C bus to init()
1 parent c76142a commit 8bbd75a

File tree

5 files changed

+67
-30
lines changed

5 files changed

+67
-30
lines changed

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ Before you do anything with the Si5351, you will need to include the "si5351.h"
5151

5252
Now in the _Setup()_ function, let's initialize communications with the Si5351, specify the load capacitance of the reference crystal, that we want to use the default reference oscillator frequency of 25 MHz (the second argument of "0" indicates that we want to use the default), and that we will apply no frequency correction at this point (the third argument of "0"):
5353

54-
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
54+
i2c_found = si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
55+
56+
The _init()_ method returns a _bool_ which indicates whether the Arduino can communicate with a device on the I2C bus at the specified address (it does not verify that the device is an actual Si5351, but this is useful for ensuring that I2C communication is working).
5557

5658
Next, let's set the CLK0 output to 14 MHz:
5759

@@ -277,12 +279,15 @@ Public Methods
277279
*
278280
* xtal_load_c - Crystal load capacitance. Use the SI5351_CRYSTAL_LOAD_*PF
279281
* defines in the header file
280-
* ref_osc_freq - Crystal/reference oscillator frequency in 1 Hz increments.
282+
* xo_freq - Crystal/reference oscillator frequency in 1 Hz increments.
281283
* Defaults to 25000000 if a 0 is used here.
282284
* corr - Frequency correction constant in parts-per-billion
283285
*
286+
* Returns a boolean that indicates whether a device was found on the desired
287+
* I2C address.
288+
*
284289
*/
285-
void Si5351::init(uint8_t xtal_load_c, uint32_t ref_osc_freq, uint32_t ref_osc_freq)
290+
bool Si5351::init(uint8_t xtal_load_c, uint32_t ref_osc_freq, uint32_t ref_osc_freq)
286291
```
287292
### reset()
288293
```

examples/si5351_example/si5351_example.ino

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,15 @@ Si5351 si5351;
2424

2525
void setup()
2626
{
27+
bool i2c_found;
28+
2729
// Start serial and initialize the Si5351
2830
Serial.begin(57600);
29-
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
31+
i2c_found = si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
32+
if(i2c_found)
33+
{
34+
Serial.println("Device not found on I2C bus!")
35+
}
3036

3137
// Set CLK0 to output 14 MHz
3238
si5351.set_freq(1400000000ULL, SI5351_CLK0);

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Etherkit Si5351
2-
version=2.1.0
2+
version=2.1.1
33
author=Jason Milldrum <[email protected]>
44
maintainer=Jason Milldrum <[email protected]>
55
sentence=A full-featured library for the Si5351 series of clock generator ICs from Silicon Labs

src/si5351.cpp

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@
3636
Si5351::Si5351(uint8_t i2c_addr):
3737
i2c_bus_addr(i2c_addr)
3838
{
39-
dev_status.SYS_INIT = 0;
40-
dev_status.LOL_B = 0;
41-
dev_status.LOL_A = 0;
42-
dev_status.LOS = 0;
43-
dev_status.REVID = 0;
44-
45-
dev_int_status.SYS_INIT_STKY = 0;
46-
dev_int_status.LOL_B_STKY = 0;
47-
dev_int_status.LOL_A_STKY = 0;
48-
dev_int_status.LOS_STKY = 0;
39+
// dev_status.SYS_INIT = 0;
40+
// dev_status.LOL_B = 0;
41+
// dev_status.LOL_A = 0;
42+
// dev_status.LOS = 0;
43+
// dev_status.REVID = 0;
44+
//
45+
// dev_int_status.SYS_INIT_STKY = 0;
46+
// dev_int_status.LOL_B_STKY = 0;
47+
// dev_int_status.LOL_A_STKY = 0;
48+
// dev_int_status.LOS_STKY = 0;
4949

5050
xtal_freq[0] = SI5351_XTAL_FREQ;
5151

@@ -67,29 +67,53 @@ Si5351::Si5351(uint8_t i2c_addr):
6767
* Defaults to 25000000 if a 0 is used here.
6868
* corr - Frequency correction constant in parts-per-billion
6969
*
70+
* Returns a boolean that indicates whether a device was found on the desired
71+
* I2C address.
72+
*
7073
*/
71-
void Si5351::init(uint8_t xtal_load_c, uint32_t xo_freq, int32_t corr)
74+
bool Si5351::init(uint8_t xtal_load_c, uint32_t xo_freq, int32_t corr)
7275
{
7376
// Start I2C comms
7477
Wire.begin();
7578

76-
// Set crystal load capacitance
77-
si5351_write(SI5351_CRYSTAL_LOAD, (xtal_load_c & SI5351_CRYSTAL_LOAD_MASK) | 0b00010010);
79+
// Check for a device on the bus, bail out if it is not there
80+
Wire.beginTransmission(i2c_bus_addr);
81+
uint8_t reg_val;
82+
reg_val = Wire.endTransmission();
7883

79-
// Set up the XO reference frequency
80-
if (xo_freq != 0)
84+
if(reg_val == 0)
8185
{
82-
set_ref_freq(xo_freq, SI5351_PLL_INPUT_XO);
86+
// Wait for SYS_INIT flag to be clear, indicating that device is ready
87+
uint8_t status_reg = 0;
88+
do
89+
{
90+
status_reg = si5351_read(SI5351_DEVICE_STATUS);
91+
} while (status_reg >> 7 == 1);
92+
93+
// Set crystal load capacitance
94+
si5351_write(SI5351_CRYSTAL_LOAD, (xtal_load_c & SI5351_CRYSTAL_LOAD_MASK) | 0b00010010);
95+
96+
// Set up the XO reference frequency
97+
if (xo_freq != 0)
98+
{
99+
set_ref_freq(xo_freq, SI5351_PLL_INPUT_XO);
100+
}
101+
else
102+
{
103+
set_ref_freq(SI5351_XTAL_FREQ, SI5351_PLL_INPUT_XO);
104+
}
105+
106+
// Set the frequency calibration for the XO
107+
set_correction(corr, SI5351_PLL_INPUT_XO);
108+
109+
reset();
110+
111+
return true;
83112
}
84113
else
85114
{
86-
set_ref_freq(SI5351_XTAL_FREQ, SI5351_PLL_INPUT_XO);
115+
return false;
87116
}
88-
89-
// Set the frequency calibration for the XO
90-
set_correction(corr, SI5351_PLL_INPUT_XO);
91-
92-
reset();
93117
}
94118

95119
/*

src/si5351.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ class Si5351
280280
{
281281
public:
282282
Si5351(uint8_t i2c_addr = SI5351_BUS_BASE_ADDR);
283-
void init(uint8_t, uint32_t, int32_t);
283+
bool init(uint8_t, uint32_t, int32_t);
284284
void reset(void);
285285
uint8_t set_freq(uint64_t, enum si5351_clock);
286286
uint8_t set_freq_manual(uint64_t, uint64_t, enum si5351_clock);
@@ -306,8 +306,10 @@ class Si5351
306306
uint8_t si5351_write_bulk(uint8_t, uint8_t, uint8_t *);
307307
uint8_t si5351_write(uint8_t, uint8_t);
308308
uint8_t si5351_read(uint8_t);
309-
struct Si5351Status dev_status;
310-
struct Si5351IntStatus dev_int_status;
309+
struct Si5351Status dev_status = {.SYS_INIT = 0, .LOL_B = 0, .LOL_A = 0,
310+
.LOS = 0, .REVID = 0};
311+
struct Si5351IntStatus dev_int_status = {.SYS_INIT_STKY = 0, .LOL_B_STKY = 0,
312+
.LOL_A_STKY = 0, .LOS_STKY = 0};
311313
enum si5351_pll pll_assignment[8];
312314
uint64_t clk_freq[8];
313315
uint64_t plla_freq;

0 commit comments

Comments
 (0)