Skip to content

Commit 8d599d2

Browse files
committed
Working - using the emulator example
1 parent 12b4e00 commit 8d599d2

File tree

6 files changed

+282
-30
lines changed

6 files changed

+282
-30
lines changed

examples/Example02_setFrequencyHz/Example02_setFrequencyHz.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ void setup()
3737
myTCXO.setBaseFrequencyHz(10000000.0); // Pass the oscillator base frequency into the driver
3838

3939
Serial.print("Base frequency set to ");
40-
Serial.println(myTCXO.getBaseFrequencyHz());
40+
Serial.print(myTCXO.getBaseFrequencyHz());
4141
Serial.println(" Hz");
4242

4343
myTCXO.setPullRangeControl(SiT5358_PULL_RANGE_200ppm); // Set the pull range control to 200ppm
@@ -51,7 +51,7 @@ void setup()
5151
Serial.print(myTCXO.getFrequencyHz());
5252
Serial.println(" Hz");
5353

54-
Serial.print("Frequency control word should be 16777216. It is ");
54+
Serial.print("Frequency control word should be 16777215. It is ");
5555
Serial.println(myTCXO.getFrequencyControlWord());
5656
}
5757

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
Set the frequency of the SiT5358 DCTCXO.
3+
4+
This example demonstrates what happens when an illegal (out of bounds) frequency is selected.
5+
6+
By: Paul Clark
7+
SparkFun Electronics
8+
Date: 2024/8/1
9+
SparkFun code, firmware, and software is released under the MIT License.
10+
Please see LICENSE.md for further details.
11+
12+
*/
13+
14+
// You will need the SparkFun Toolkit. Click here to get it: http://librarymanager/All#SparkFun_Toolkit
15+
16+
#include <SparkFun_SiT5358.h> // Click here to get the library: http://librarymanager/All#SparkFun_SiT5358
17+
18+
SfeSiT5358ArdI2C myTCXO;
19+
20+
void setup()
21+
{
22+
delay(1000); // Allow time for the microcontroller to start up
23+
24+
Serial.begin(115200); // Begin the Serial console
25+
while (!Serial)
26+
{
27+
delay(100); // Wait for the user to open the Serial Monitor
28+
}
29+
Serial.println("SparkFun SiT5358 Example");
30+
31+
Wire.begin(); // Begin the I2C bus
32+
33+
if (!myTCXO.begin())
34+
{
35+
Serial.println("SiT5358 not detected! Please check the address and try again...");
36+
while (1); // Do nothing more
37+
}
38+
39+
myTCXO.setBaseFrequencyHz(10000000.0); // Pass the oscillator base frequency into the driver
40+
41+
Serial.print("Base frequency set to ");
42+
Serial.print(myTCXO.getBaseFrequencyHz());
43+
Serial.println(" Hz");
44+
45+
myTCXO.setPullRangeControl(SiT5358_PULL_RANGE_200ppm); // Set the pull range control to 200ppm
46+
47+
Serial.print("Pull range control set to ");
48+
Serial.println(myTCXO.getPullRangeControlText(myTCXO.getPullRangeControl()));
49+
50+
myTCXO.setFrequencyHz(9900000.0); // Try to set the frequency to 9.9MHz (-10000ppm)
51+
52+
Serial.print("Frequency set to ");
53+
Serial.print(myTCXO.getFrequencyHz());
54+
Serial.println(" Hz");
55+
56+
Serial.print("Frequency control word should be -33554432. It is ");
57+
Serial.println(myTCXO.getFrequencyControlWord());
58+
}
59+
60+
void loop()
61+
{
62+
// Nothing to do here
63+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
Set the frequency of the SiT5358 DCTCXO from RX clock delay.
3+
4+
This example demonstrates how to set the frequency of the SiT5358 DCTCXO from a GNSS
5+
RX Clock Bias (in milliseconds).
6+
7+
By: Paul Clark
8+
SparkFun Electronics
9+
Date: 2024/8/1
10+
SparkFun code, firmware, and software is released under the MIT License.
11+
Please see LICENSE.md for further details.
12+
13+
Consider the SiT5358AI-FS033IT-10.000000 used on the SparkFun RTK mosaic-T:
14+
The operating temperature range is Industrial, -40 to 85°C (option "I").
15+
LVCMOS output (option "-").
16+
Frequency stability +/-50ppb (option "S").
17+
It is DCTCXO with an I2C address of 0x60 (option "0").
18+
Supply voltage 3.3V (option "33").
19+
Pin 1 is Output Enable (option "I"). (No software OE control).
20+
The default pull range is 6.25ppm (option "T").
21+
Base frequency is 10.000000MHz.
22+
23+
Consider this example:
24+
* The TCXO frequency has not yet been changed. It is running at the default 10.000000 MHz.
25+
* 10.000000 MHZ is the library default base frequency. But we could set it with setBaseFrequencyHz(10000000.0)
26+
* The pull range is read during begin. But we could set it with setPullRangeControl(SiT5358_PULL_RANGE_6ppm25)
27+
* The mosaic-T manual states that the oscillator frequency should be changed by no more than 3ppb per second.
28+
* We tell the library this using setMaxFrequencyChangePPB(3.0)
29+
* The GNSS RxClkBias reports that receiver time is ahead of system time by 200 nanoseconds (+200ns).
30+
* We instruct the library to change the frequency using setFrequencyByBiasMillis(200.0e-6)
31+
* The TCXO clock period is 100ns.
32+
* The 200ns bias corresponds to 2 clock cycles.
33+
* To remove that bias in one second, the oscillator frequency would need to be reduced to 9.999998 MHz.
34+
* That is a change of 2 parts in 10000000, or 0.2ppm, or 200ppb.
35+
* The frequency change will be limited to 3ppb.
36+
* Since the SiT5358 Pull Range is set to 6.25ppm, and the Pull Register is 26-bit signed, 3ppb corresponds to 16106 LSB.
37+
* The firmware writes the value -16106 to the Frequency Control Register, reducing the frequency to 9.99999997 MHz.
38+
* getFrequencyHz will return 9999999.97
39+
40+
*/
41+
42+
// You will need the SparkFun Toolkit. Click here to get it: http://librarymanager/All#SparkFun_Toolkit
43+
44+
#include <SparkFun_SiT5358.h> // Click here to get the library: http://librarymanager/All#SparkFun_SiT5358
45+
46+
SfeSiT5358ArdI2C myTCXO;
47+
48+
void setup()
49+
{
50+
delay(1000); // Allow time for the microcontroller to start up
51+
52+
Serial.begin(115200); // Begin the Serial console
53+
while (!Serial)
54+
{
55+
delay(100); // Wait for the user to open the Serial Monitor
56+
}
57+
Serial.println("SparkFun SiT5358 Example");
58+
59+
Wire.begin(); // Begin the I2C bus
60+
61+
if (!myTCXO.begin())
62+
{
63+
Serial.println("SiT5358 not detected! Please check the address and try again...");
64+
while (1); // Do nothing more
65+
}
66+
67+
myTCXO.setBaseFrequencyHz(10000000.0); // Pass the oscillator base frequency into the driver
68+
69+
Serial.print("Base frequency set to ");
70+
Serial.print(myTCXO.getBaseFrequencyHz());
71+
Serial.println(" Hz");
72+
73+
myTCXO.setPullRangeControl(SiT5358_PULL_RANGE_6ppm25); // Set the pull range control to 6.25ppm
74+
75+
Serial.print("Pull range control set to ");
76+
Serial.println(myTCXO.getPullRangeControlText(myTCXO.getPullRangeControl()));
77+
78+
myTCXO.setMaxFrequencyChangePPB(3.0); // Set the maximum frequency change in PPB
79+
80+
Serial.print("Maximum frequency change set to ");
81+
Serial.print(myTCXO.getMaxFrequencyChangePPB());
82+
Serial.println(" PPB");
83+
84+
myTCXO.setFrequencyByBiasMillis(200.0e-6); // Set the frequency by clock bias (+200ns, +200e-6ms)
85+
86+
Serial.print("Frequency should be 9999999.97 Hz. It is ");
87+
Serial.print(myTCXO.getFrequencyHz());
88+
Serial.println(" Hz");
89+
90+
Serial.print("Frequency control word should be -16106. It is ");
91+
Serial.println(myTCXO.getFrequencyControlWord());
92+
}
93+
94+
void loop()
95+
{
96+
// Nothing to do here
97+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
Emulate the SiT5358 DCTCXO.
3+
4+
By: Paul Clark
5+
SparkFun Electronics
6+
Date: 2024/8/1
7+
SparkFun code, firmware, and software is released under the MIT License.
8+
Please see LICENSE.md for further details.
9+
10+
*/
11+
12+
#include <Wire.h>
13+
14+
#define I2C_DEV_ADDR 0x60
15+
16+
uint8_t registerBytes[6] = { 0, 0, 0, 0, 0, 0 };
17+
uint8_t registerAddress = 0;
18+
19+
// On Request:
20+
// Write bytes from registerBytes, starting at registerAddress * 2
21+
void onRequest()
22+
{
23+
int i = registerAddress * 2;
24+
for (; i < 6; i++)
25+
Wire.write(registerBytes[i]);
26+
}
27+
28+
// On Receive:
29+
// Copy the first incoming byte into registerAddress
30+
// Copy the remaining bytes into registerBytes, starting at registerAddress * 2
31+
void onReceive(int len)
32+
{
33+
int count = -1;
34+
while (Wire.available())
35+
{
36+
uint8_t b = Wire.read();
37+
switch (count)
38+
{
39+
case -1:
40+
registerAddress = b;
41+
break;
42+
default:
43+
if (((registerAddress * 2) + count) < 6)
44+
registerBytes[((registerAddress * 2) + count)] = b;
45+
break;
46+
}
47+
count++;
48+
}
49+
}
50+
51+
void setup()
52+
{
53+
delay(1000); // Allow time for the microcontroller to start up
54+
55+
Serial.begin(115200); // Begin the Serial console
56+
while (!Serial)
57+
{
58+
delay(100); // Wait for the user to open the Serial Monitor
59+
}
60+
Serial.println("SparkFun SiT5358 Emulator");
61+
62+
Wire.onReceive(onReceive);
63+
Wire.onRequest(onRequest);
64+
Wire.begin((uint8_t)I2C_DEV_ADDR);
65+
}
66+
67+
void loop()
68+
{
69+
static unsigned long lastPrint = 0;
70+
71+
if (millis() > (lastPrint + 1000))
72+
{
73+
lastPrint = millis();
74+
75+
// Extract the 26-bit Frequency Control Word
76+
uint32_t freqControl = ((uint32_t)registerBytes[0]) << 8;
77+
freqControl |= (uint32_t)registerBytes[1];
78+
freqControl |= (((uint32_t)registerBytes[2]) & 0x03) << 24;
79+
freqControl |= ((uint32_t)registerBytes[3]) << 16;
80+
if (freqControl & 0x02000000) // Correct two's complement
81+
freqControl |= 0xFC000000;
82+
83+
union // Avoid any ambiguity when converting uint32_t to int32_t
84+
{
85+
uint32_t unsigned32;
86+
int32_t signed32;
87+
} unsignedSigned32;
88+
unsignedSigned32.unsigned32 = freqControl;
89+
90+
Serial.print("Frequency control is ");
91+
Serial.print(unsignedSigned32.signed32);
92+
93+
// Extract the 4-bit Pull Range Control
94+
Serial.print(". Pull range control is ");
95+
Serial.println(registerBytes[5]);
96+
}
97+
}

src/SparkFun_SiT5358.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,29 @@ void SfeSiT5358Driver::setMaxFrequencyChangePPB(double ppb)
261261
/// and the setMaxFrequencyChangePPB. Call getFrequencyHz to read the frequency set.
262262
bool SfeSiT5358Driver::setFrequencyByBiasMillis(double bias)
263263
{
264-
return false;
264+
double freq = getFrequencyHz();
265+
266+
double clockInterval_s = 1.0 / freq; // Convert freq to interval in seconds
267+
268+
double biasInClocks = bias / 1000.0; // Convert bias from millis to seconds
269+
biasInClocks /= clockInterval_s; // Convert bias to clock cycles
270+
271+
double maxChangeInClocks = freq * _maxFrequencyChangePPB / 1.0e9;
272+
273+
if (biasInClocks >= 0.0)
274+
{
275+
if (biasInClocks > maxChangeInClocks)
276+
biasInClocks = maxChangeInClocks;
277+
}
278+
else
279+
{
280+
if (biasInClocks < (0.0 - maxChangeInClocks))
281+
biasInClocks = 0.0 - maxChangeInClocks;
282+
}
283+
284+
double newFreq = freq - biasInClocks;
285+
286+
return setFrequencyHz(newFreq);
265287
}
266288

267289
/// @brief Convert the 4-bit pull range into text

src/SparkFun_SiT5358.h

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,33 +25,6 @@
2525
To set the oscillator to a specific frequency, it is necessary to know the base frequency
2626
and pull range limit (in ppm). The frequency control word defines the pull as fractional ppm.
2727
28-
Consider the SiT5358AI-FS033IT-10.000000 used on the SparkFun RTK mosaic-T:
29-
The operating temperature range is Industrial, -40 to 85°C (option "I").
30-
LVCMOS output (option "-").
31-
Frequency stability +/-50ppb (option "S").
32-
It is DCTCXO with an I2C address of 0x60 (option "0").
33-
Supply voltage 3.3V (option "33").
34-
Pin 1 is Output Enable (option "I"). (No software OE control).
35-
The default pull range is 6.25ppm (option "T").
36-
Base frequency is 10.000000MHz.
37-
38-
Consider this example:
39-
* The TCXO frequency has not yet been changed. It is running at the default 10.000000 MHz.
40-
* 10.000000 MHZ is the library default base frequency. But we could set it with setBaseFrequencyHz(10000000.0)
41-
* The pull range is read during begin. But we could set it with setPullRangeControl(SiT5358_PULL_RANGE_6ppm25)
42-
* The mosaic-T manual states that the oscillator frequency should be changed by no more than 3ppb per second.
43-
* We tell the library this using setMaxFrequencyChangePPB(3.0)
44-
* The GNSS RxClkBias reports that receiver time is ahead of system time by 200 nanoseconds (+200ns).
45-
* We instruct the library to change the frequency using setFrequencyByBiasMillis(200.0e-6)
46-
* The TCXO clock period is 100ns.
47-
* The 200ns bias corresponds to 2 clock cycles.
48-
* To remove that bias in one second, the oscillator frequency would need to be reduced to 9.999998 MHz.
49-
* That is a change of 2 parts in 10000000, or 0.2ppm, or 200ppb.
50-
* The frequency change will be limited to 3ppb.
51-
* Since the SiT5358 Pull Range is set to 6.25ppm, and the Pull Register is 26-bit signed, 3ppb corresponds to 16106 LSB.
52-
* The firmware writes the value -16106 to the Frequency Control Register, reducing the frequency to 9.99999997 MHz.
53-
* getFrequencyHz will return 9999999.97
54-
5528
*/
5629

5730
#pragma once

0 commit comments

Comments
 (0)