From 4dd77d04fd6cd0b293c284fec8ea4b3b14dfc7ec Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Sun, 18 Dec 2016 12:41:33 -0800 Subject: [PATCH 01/20] Change set_freq() max freq to 225 MHz --- README.md | 8 +++++--- library.properties | 2 +- src/si5351.cpp | 6 ++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3eadc99..0d8bd1c 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ Setting the Output Frequency ---------------------------- As indicated above, the library accepts and indicates clock and PLL frequencies in units of 0.01 Hz, as an _unsigned long long_ variable type (or _uint64_t_). When entering literal values, append ```ULL``` to make an explicit unsigned long long number to ensure proper tuning. Since many applications won't require sub-Hertz tuning, you may wish to use an _unsigned long_ (or _uint32_t_) variable to hold your tune frequency, then scale it up by multiplying by 100ULL before passing it to the _set_freq()_ method. -Using the _set_freq()_ method is the easiest way to use the library and gives you a wide range of tuning options, but has some constraints in its usage. Outputs CLK0 through CLK5 by default are all locked to PLLA while CLK6 and CLK7 are locked to PLLB. Due to the nature of the Si5351 architecture, there may only be one CLK output among those sharing a PLL which may be set greater than 112.5 MHz. Therefore, once one CLK output has been set above 112.5 MHz, no more CLKs on the same PLL will be allowed to be set greater than 112.5 MHz (unless the one which is already set is changed to a frequency below this threshold). Also, due to the special PLL requirements for output frequencies above 150 MHz, the _set_freq()_ method will not tune above 150 MHz. Refer to the next section for instructions on how to generate these output frequencies. +Using the _set_freq()_ method is the easiest way to use the library and gives you a wide range of tuning options, but has some constraints in its usage. Outputs CLK0 through CLK5 by default are all locked to PLLA while CLK6 and CLK7 are locked to PLLB. Due to the nature of the Si5351 architecture, there may only be one CLK output among those sharing a PLL which may be set greater than 112.5 MHz. Therefore, once one CLK output has been set above 112.5 MHz, no more CLKs on the same PLL will be allowed to be set greater than 112.5 MHz (unless the one which is already set is changed to a frequency below this threshold). If the above constraints are not suitable, you need glitch-free tuning, or you are counting on multiple clocks being locked to the same reference, you may set the PLL frequency manually then make clock reference assignments to either of the PLLs. @@ -115,8 +115,6 @@ of the VCO frequencies. To put this in other words, if you want to manually set the PLL and wish to have an output frequency greater than 112.5 MHz, then the choice of PLL frequency is dictated by the choice of output frequency, and will need to be an even multiple of 4, 6, or 8. -Furthermore, you must use the _set_freq_manual()_ method to set an output frequency greater than 150 MHz because of the requirement of the reference PLL to be a mutiple of 4 of the output frequency in this case. You can see this in the code example earlier in this section. This will most likely prevent you from using other CLK outputs locked to the same PLL (unless you can use another output on the exact same frequency). - Further Details --------------- If we like we can adjust the output drive power: @@ -660,6 +658,10 @@ This library does not currently support the spread spectrum function of the Si53 Changelog --------- +* v2.0.1 + + * Increase maximum frequency in set_freq() to 225 MHz + * v2.0.1 * Fix logic error in set_freq() which causes errors in setting multiple clocks >100 MHz diff --git a/library.properties b/library.properties index 7da146d..18ea5af 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Etherkit Si5351 -version=2.0.1 +version=2.0.2 author=Jason Milldrum maintainer=Jason Milldrum sentence=A full-featured library for the Si5351 series of clock generator ICs from Silicon Labs diff --git a/src/si5351.cpp b/src/si5351.cpp index d88b92f..ca71e78 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -207,9 +207,11 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) // Upper bounds check // We will only allow a maximum output frequency of 150 MHz using this // method. For >=150 MHz, you'll have to manually set the paramters - if(freq >= SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT) + //if(freq >= SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT) + if(freq >= SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT) { - freq = SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT - 1; + //freq = SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT - 1; + freq = SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT - 1; } // If requested freq >112.5 MHz and no other outputs are already >112.5 MHz, From e2e3771090a0562126481bd1e7ee6e8b9d790ceb Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Mon, 19 Dec 2016 10:44:30 -0800 Subject: [PATCH 02/20] Tweak max freq to be exactly 225 MHz, not 225 MHz - 1 --- README.md | 4 ++-- src/si5351.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0d8bd1c..731f11d 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ The public interface to the v2 library is similar to the v1 library, but a few o The _init()_ method now has three parameters: the crystal load capacitance, the reference frequency, and the frequency correction value (with this last parameter being a new addition). You'll need to add that third parameter to your old _init()_ calls, but then you can delete any _set_correction()_ calls after that (unless you explicitly are changing the frequency correction after the initialization). -The _set_freq()_ method is now more streamlined and only requires two parameters: the desired output frequency (from 4 kHz to 150 MHz) and clock output. In your old code, you can delete the 2nd parameter in _set_freq()_, which was the PLL frequency. In case you want to do things manually, there is now a new method called _set_freq_manual()_ (see below for details). +The _set_freq()_ method is now more streamlined and only requires two parameters: the desired output frequency (from 4 kHz to 225 MHz) and clock output. In your old code, you can delete the 2nd parameter in _set_freq()_, which was the PLL frequency. In case you want to do things manually, there is now a new method called _set_freq_manual()_ (see below for details). Those two changes should cover nearly all upgrade scenarios, unless you were doing some lower-level use of the Si5351. @@ -658,7 +658,7 @@ This library does not currently support the spread spectrum function of the Si53 Changelog --------- -* v2.0.1 +* v2.0.2 * Increase maximum frequency in set_freq() to 225 MHz diff --git a/src/si5351.cpp b/src/si5351.cpp index ca71e78..62453ca 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -208,10 +208,10 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) // We will only allow a maximum output frequency of 150 MHz using this // method. For >=150 MHz, you'll have to manually set the paramters //if(freq >= SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT) - if(freq >= SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT) + if(freq > SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT) { //freq = SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT - 1; - freq = SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT - 1; + freq = SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT; } // If requested freq >112.5 MHz and no other outputs are already >112.5 MHz, From 61681a859b34bfc8bac8c2aef76459a057cf0820 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Wed, 28 Dec 2016 12:22:05 -0800 Subject: [PATCH 03/20] Change SI5351_MULTISYNTH_SHARE_MAX to 110 MHz to deal with instability near 112 MHz --- src/si5351.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/si5351.h b/src/si5351.h index 07c610d..872e575 100644 --- a/src/si5351.h +++ b/src/si5351.h @@ -46,7 +46,8 @@ #define SI5351_MULTISYNTH_MIN_FREQ 500000 #define SI5351_MULTISYNTH_DIVBY4_FREQ 150000000 #define SI5351_MULTISYNTH_MAX_FREQ 225000000 -#define SI5351_MULTISYNTH_SHARE_MAX 112500000 +#define SI5351_MULTISYNTH_SHARE_MAX 110000000 +//#define SI5351_MULTISYNTH_SHARE_MAX 112500000 #define SI5351_MULTISYNTH_SHARE_MIN 1024000 #define SI5351_MULTISYNTH67_MAX_FREQ SI5351_MULTISYNTH_DIVBY4_FREQ #define SI5351_CLKOUT_MIN_FREQ 4000 From b7b61073fccbed43ce77185cb679ae86a140449f Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Wed, 28 Dec 2016 12:40:06 -0800 Subject: [PATCH 04/20] Update README for v2.0.2 --- README.md | 7 ++++--- src/si5351.h | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 731f11d..91001b8 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ Setting the Output Frequency ---------------------------- As indicated above, the library accepts and indicates clock and PLL frequencies in units of 0.01 Hz, as an _unsigned long long_ variable type (or _uint64_t_). When entering literal values, append ```ULL``` to make an explicit unsigned long long number to ensure proper tuning. Since many applications won't require sub-Hertz tuning, you may wish to use an _unsigned long_ (or _uint32_t_) variable to hold your tune frequency, then scale it up by multiplying by 100ULL before passing it to the _set_freq()_ method. -Using the _set_freq()_ method is the easiest way to use the library and gives you a wide range of tuning options, but has some constraints in its usage. Outputs CLK0 through CLK5 by default are all locked to PLLA while CLK6 and CLK7 are locked to PLLB. Due to the nature of the Si5351 architecture, there may only be one CLK output among those sharing a PLL which may be set greater than 112.5 MHz. Therefore, once one CLK output has been set above 112.5 MHz, no more CLKs on the same PLL will be allowed to be set greater than 112.5 MHz (unless the one which is already set is changed to a frequency below this threshold). +Using the _set_freq()_ method is the easiest way to use the library and gives you a wide range of tuning options, but has some constraints in its usage. Outputs CLK0 through CLK5 by default are all locked to PLLA while CLK6 and CLK7 are locked to PLLB. Due to the nature of the Si5351 architecture, there may only be one CLK output among those sharing a PLL which may be set greater than 110 MHz. Therefore, once one CLK output has been set above 110 MHz, no more CLKs on the same PLL will be allowed to be set greater than 110 MHz (unless the one which is already set is changed to a frequency below this threshold). If the above constraints are not suitable, you need glitch-free tuning, or you are counting on multiple clocks being locked to the same reference, you may set the PLL frequency manually then make clock reference assignments to either of the PLLs. @@ -113,7 +113,7 @@ When you are setting the PLL manually you need to be mindful of the limits of th This means that if any output is greater than 112.5 MHz (900 MHz/8), then this output frequency sets one of the VCO frequencies. -To put this in other words, if you want to manually set the PLL and wish to have an output frequency greater than 112.5 MHz, then the choice of PLL frequency is dictated by the choice of output frequency, and will need to be an even multiple of 4, 6, or 8. +To put this in other words, if you want to manually set the PLL and wish to have an output frequency greater than 110 MHz (changed in this library from the stated 112.5 MHz due to stability issues which were noticed), then the choice of PLL frequency is dictated by the choice of output frequency, and will need to be an even multiple of 4, 6, or 8. Further Details --------------- @@ -246,7 +246,7 @@ All CLK outputs are set to 0 Hz and disabled. Constraints ----------- -* Two multisynths cannot share a PLL with when both outputs are >= 112.5 MHz. The library will refuse to set another multisynth to a frequency in that range if another multisynth sharing the same PLL is already within that frequency range. +* Two multisynths cannot share a PLL with when both outputs are >= 110 MHz. The library will refuse to set another multisynth to a frequency in that range if another multisynth sharing the same PLL is already within that frequency range. * Setting phase will be limited in the extreme edges of the output tuning ranges. Because the phase register is 7-bits in size and is denominated in units representing 1/4 the PLL period, not all phases can be set for all output frequencies. For example, if you need a 90° phase shift, the lowest frequency you can set it at is 4.6875 MHz (600 MHz PLL/128). * The frequency range of Multisynth 6 and 7 is ~18.45 kHz to 150 MHz. The library assigns PLLB to these two multisynths, so if you choose to use both, then both frequencies must be an even divisor of the PLL frequency (between 6 and 254), so plan accordingly. You can see the current PLLB frequency by accessing the _pllb_freq_ public member. * VCXO pull range can be ±30 to ±240 ppm @@ -661,6 +661,7 @@ Changelog * v2.0.2 * Increase maximum frequency in set_freq() to 225 MHz + * Change SI5351_MULTISYNTH_SHARE_MAX from 112.5 MHz to 110 MHz due to stability issues * v2.0.1 diff --git a/src/si5351.h b/src/si5351.h index 872e575..3770f87 100644 --- a/src/si5351.h +++ b/src/si5351.h @@ -47,7 +47,6 @@ #define SI5351_MULTISYNTH_DIVBY4_FREQ 150000000 #define SI5351_MULTISYNTH_MAX_FREQ 225000000 #define SI5351_MULTISYNTH_SHARE_MAX 110000000 -//#define SI5351_MULTISYNTH_SHARE_MAX 112500000 #define SI5351_MULTISYNTH_SHARE_MIN 1024000 #define SI5351_MULTISYNTH67_MAX_FREQ SI5351_MULTISYNTH_DIVBY4_FREQ #define SI5351_CLKOUT_MIN_FREQ 4000 From 7e98df325c819e6e96b6dd57a651b12fe9f70a67 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Wed, 28 Dec 2016 12:44:22 -0800 Subject: [PATCH 05/20] Clean up README --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 91001b8..4328d7e 100644 --- a/README.md +++ b/README.md @@ -38,11 +38,9 @@ Those two changes should cover nearly all upgrade scenarios, unless you were doi Example ------- -Include the Si5351Arduino library into your instance of the Arduino IDE. Download a ZIP file of the library from the GitHub repository by using the "Download ZIP" button at the right of the main repository page. Extract the ZIP file, then rename the unzipped folder as "Si5351". Finally, open the Arduino IDE, select menu Sketch > Import Library... > Add Library..., and select the renamed folder that you just downloaded. Restart the IDE and you should have access to the new library. +First, install the Si5351Arduino library into your instance of the Arduino IDE as described above. -(Yes, the Arduino IDE can import a ZIP file, but it doesn't like filenames with characters such as dashes, as GitHub does when it appends the branch name with a dash. Perhaps there's an elegant way around this, we'll see.) - -There is a simple example that is placed in your examples menu under Si5351Arduino. Open this to see how to initialize the Si5351 and set a couple of the outputs to different frequencies. The commentary below will analyze the sample sketch. +There is a simple example named **si5351_example.ino** that is placed in your examples menu under the Si5351Arduino folder. Open this to see how to initialize the Si5351 and set a couple of the outputs to different frequencies. The commentary below will analyze the sample sketch. Before you do anything with the Si5351, you will need to include the "si5351.h" and "Wire.h" header files and instantiate the Si5351 class. From f873733ca6feb2b3ce8ae9a3df825607053ee5a7 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Wed, 28 Dec 2016 12:54:20 -0800 Subject: [PATCH 06/20] Clean up README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4328d7e..3efe5bf 100644 --- a/README.md +++ b/README.md @@ -131,13 +131,13 @@ You may invert a clock output signal by using this command: Calibration ----------- -There will be some inherent error in the reference oscillator's actual frequency, so we can account for this by measuring the difference between the uncalibrated actual and nominal output frequencies, then using that difference as a correction factor in the library. The _set_correction()_ method uses a signed integer calibration constant measured in parts-per-billion. The easist way to determine this correction factor is to measure a 10 MHz signal from one of the clock outputs (in Hz, or better resolution if you can measure it), scale it to parts-per-billion, then use it in the _set_correction()_ method in future use of this particular reference oscillator. Once this correction factor is determined, it should not need to be measured again for the same reference oscillator/Si5351 pair unless you want to redo the calibration. With an accurate measurement at one frequency, this calibration should be good across the entire tuning range. +There will be some inherent error in the reference oscillator's actual frequency, so we can account for this by measuring the difference between the uncalibrated actual and nominal output frequencies, then using that difference as a correction factor in the library. The _init()_ and _set_correction()_ methods use a signed integer calibration constant measured in parts-per-billion. The easiest way to determine this correction factor is to measure a 10 MHz signal from one of the clock outputs (in Hz, or better resolution if you can measure it), scale it to parts-per-billion, then use it in the _set_correction()_ method in future use of this particular reference oscillator. Once this correction factor is determined, it should not need to be measured again for the same reference oscillator/Si5351 pair unless you want to redo the calibration. With an accurate measurement at one frequency, this calibration should be good across the entire tuning range. The calibration method is called like this: si5351.set_correction(-6190); -However, you may use the third argument in the _init()_ method to specify the frequeny correction and may not actually need to use the explict _set_correction()_ method in your code. +However, you may use the third argument in the _init()_ method to specify the frequency correction and may not actually need to use the explict _set_correction()_ method in your code. A handy calibration program is provided with the library in the example folder named _si5351_calibration_. To use it, simply hook up your Arduino to your Si5351, then connect it to a PC with the Arduino IDE. Connect the CLK0 output of the Si5351 to a frequency counter capable of measuring at 10 MHz (the more resolution, the better). Load the sketch then open the serial terminal window. Follow the prompts in the serial terminal to change the output frequency until your frequency counter reads exactly 10.000 000 00 MHz. The output from the Arduino on your serial terminal will tell you the correction factor you will need for future use of that reference oscillator/Si5351 combination. From d888f52b633bb7ea591b65e838f97d4eb50c3ca2 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Wed, 28 Dec 2016 12:55:29 -0800 Subject: [PATCH 07/20] Clean up README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3efe5bf..baa46f4 100644 --- a/README.md +++ b/README.md @@ -673,7 +673,7 @@ Changelog * Change interface of _init()_ and _set_freq()_ * Add _set_freq_manual()_ method * Add _reset()_ method - * Added many new example sketechs + * Added many new example sketches * v1.1.2 From 39e446209128daca248f6d52a698417159e20ceb Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Wed, 28 Dec 2016 12:56:49 -0800 Subject: [PATCH 08/20] Clean up README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index baa46f4..d53d1f5 100644 --- a/README.md +++ b/README.md @@ -658,12 +658,12 @@ Changelog --------- * v2.0.2 - * Increase maximum frequency in set_freq() to 225 MHz + * Increase maximum frequency in _set_freq()_ to 225 MHz * Change SI5351_MULTISYNTH_SHARE_MAX from 112.5 MHz to 110 MHz due to stability issues * v2.0.1 - * Fix logic error in set_freq() which causes errors in setting multiple clocks >100 MHz + * Fix logic error in _set_freq()_ which causes errors in setting multiple clocks >100 MHz * v2.0.0 @@ -681,11 +681,11 @@ Changelog * v1.1.1 - * Fix if statement eval error in set_clock_disable() + * Fix if statement eval error in _set_clock_disable()_ * v1.1.0 - * Added set_pll_input() method to allow toggling the PLL reference source for the Si5351C variant and added support to init() for different PLL reference frequencies from 10 to 100 MHz. + * Added _set_pll_input()_ method to allow toggling the PLL reference source for the Si5351C variant and added support to _init()_ for different PLL reference frequencies from 10 to 100 MHz. * v1.0.0 From c7033b5134433aea3d2877f0281efe4b4983596e Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Wed, 28 Dec 2016 12:59:31 -0800 Subject: [PATCH 09/20] Clean up README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d53d1f5..89dbd8e 100644 --- a/README.md +++ b/README.md @@ -658,8 +658,8 @@ Changelog --------- * v2.0.2 - * Increase maximum frequency in _set_freq()_ to 225 MHz - * Change SI5351_MULTISYNTH_SHARE_MAX from 112.5 MHz to 110 MHz due to stability issues + * Increase maximum frequency in _set_freq()_ to 225 MHz + * Change SI5351_MULTISYNTH_SHARE_MAX from 112.5 MHz to 110 MHz due to stability issues * v2.0.1 From 3e143e6f53e146e86351361bf19274427f894293 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Tue, 17 Jan 2017 12:46:48 -0800 Subject: [PATCH 10/20] Change share freq to 100 MHz due to more stability issues noticed --- src/si5351.cpp | 7 +++---- src/si5351.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/si5351.cpp b/src/si5351.cpp index 62453ca..4b843ed 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -219,14 +219,13 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) // on same PLL if(freq > (SI5351_MULTISYNTH_SHARE_MAX * SI5351_FREQ_MULT)) { - // Check other clocks - // TODO: only check clocks on same PLL + // Check other clocks on same PLL uint8_t i; - for(i = 0; i < 8; i++) + for(i = 0; i < 6; i++) { if(clk_freq[i] > (SI5351_MULTISYNTH_SHARE_MAX * SI5351_FREQ_MULT)) { - if(i != (uint8_t)clk) + if(i != (uint8_t)clk && pll_assignment[i] == pll_assignment[clk]) { return 1; // won't set if any other clks already >112.5 MHz } diff --git a/src/si5351.h b/src/si5351.h index 3770f87..1807727 100644 --- a/src/si5351.h +++ b/src/si5351.h @@ -46,7 +46,7 @@ #define SI5351_MULTISYNTH_MIN_FREQ 500000 #define SI5351_MULTISYNTH_DIVBY4_FREQ 150000000 #define SI5351_MULTISYNTH_MAX_FREQ 225000000 -#define SI5351_MULTISYNTH_SHARE_MAX 110000000 +#define SI5351_MULTISYNTH_SHARE_MAX 100000000 #define SI5351_MULTISYNTH_SHARE_MIN 1024000 #define SI5351_MULTISYNTH67_MAX_FREQ SI5351_MULTISYNTH_DIVBY4_FREQ #define SI5351_CLKOUT_MIN_FREQ 4000 From 837bfacc0d085a27896aee4ebcd7a3b65dce2e3b Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Sat, 25 Feb 2017 13:23:19 -0800 Subject: [PATCH 11/20] Fix regression where pll_reset() is not called in set_freq() --- README.md | 23 +++++++---- src/si5351.cpp | 103 +++++++++++++++++++++++++++++++------------------ src/si5351.h | 5 ++- 3 files changed, 85 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 89dbd8e..4032a4b 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ Setting the Output Frequency ---------------------------- As indicated above, the library accepts and indicates clock and PLL frequencies in units of 0.01 Hz, as an _unsigned long long_ variable type (or _uint64_t_). When entering literal values, append ```ULL``` to make an explicit unsigned long long number to ensure proper tuning. Since many applications won't require sub-Hertz tuning, you may wish to use an _unsigned long_ (or _uint32_t_) variable to hold your tune frequency, then scale it up by multiplying by 100ULL before passing it to the _set_freq()_ method. -Using the _set_freq()_ method is the easiest way to use the library and gives you a wide range of tuning options, but has some constraints in its usage. Outputs CLK0 through CLK5 by default are all locked to PLLA while CLK6 and CLK7 are locked to PLLB. Due to the nature of the Si5351 architecture, there may only be one CLK output among those sharing a PLL which may be set greater than 110 MHz. Therefore, once one CLK output has been set above 110 MHz, no more CLKs on the same PLL will be allowed to be set greater than 110 MHz (unless the one which is already set is changed to a frequency below this threshold). +Using the _set_freq()_ method is the easiest way to use the library and gives you a wide range of tuning options, but has some constraints in its usage. Outputs CLK0 through CLK5 by default are all locked to PLLA while CLK6 and CLK7 are locked to PLLB. Due to the nature of the Si5351 architecture, there may only be one CLK output among those sharing a PLL which may be set greater than 110 MHz. Therefore, once one CLK output has been set above 100 MHz, no more CLKs on the same PLL will be allowed to be set greater than 100 MHz (unless the one which is already set is changed to a frequency below this threshold). If the above constraints are not suitable, you need glitch-free tuning, or you are counting on multiple clocks being locked to the same reference, you may set the PLL frequency manually then make clock reference assignments to either of the PLLs. @@ -111,7 +111,7 @@ When you are setting the PLL manually you need to be mindful of the limits of th This means that if any output is greater than 112.5 MHz (900 MHz/8), then this output frequency sets one of the VCO frequencies. -To put this in other words, if you want to manually set the PLL and wish to have an output frequency greater than 110 MHz (changed in this library from the stated 112.5 MHz due to stability issues which were noticed), then the choice of PLL frequency is dictated by the choice of output frequency, and will need to be an even multiple of 4, 6, or 8. +To put this in other words, if you want to manually set the PLL and wish to have an output frequency greater than 100 MHz (changed in this library from the stated 112.5 MHz due to stability issues which were noticed), then the choice of PLL frequency is dictated by the choice of output frequency, and will need to be an even multiple of 4, 6, or 8. Further Details --------------- @@ -232,6 +232,13 @@ The _set_pll_input()_ method is used to set the desired PLLs to reference to the Once that is set, the library can be used as you normally would, with all of the frequency calculations done based on the reference frequency set in _init()_. + +Alternate I2C Addresses +----------------------- +The standard I2C bus address for the Si5351 is 0x60, however there are other ICs in the wild that use alternate bus addresses. In order to accommodate these ICs, the class constructor can be called with the I2C bus address as a parameter, as shown in this example: + + Si5351 si5351(0x61); + Startup Conditions ------------------ This library initializes the Si5351 parameters to the following values upon startup and on reset: @@ -577,13 +584,13 @@ uint8_t Si5351::si5351_read(uint8_t addr) Public Variables ---------------- - struct Si5351Status dev_status; + struct Si5351Status dev_status; struct Si5351IntStatus dev_int_status; - enum si5351_pll pll_assignment[8]; - uint64_t clk_freq[8]; + enum si5351_pll pll_assignment[8]; + uint64_t clk_freq[8]; uint64_t plla_freq; uint64_t pllb_freq; - uint32_t xtal_freq; + uint32_t xtal_freq; Tokens ------ @@ -659,7 +666,9 @@ Changelog * v2.0.2 * Increase maximum frequency in _set_freq()_ to 225 MHz - * Change SI5351_MULTISYNTH_SHARE_MAX from 112.5 MHz to 110 MHz due to stability issues + * Change SI5351_MULTISYNTH_SHARE_MAX from 112.5 MHz to 100 MHz due to stability issues + * Add explict reset of VCXO param in reset() + * Add I2C bus address parameter and default to class constructor * v2.0.1 diff --git a/src/si5351.cpp b/src/si5351.cpp index 4b843ed..9b9d211 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -33,7 +33,8 @@ /* Public functions */ /********************/ -Si5351::Si5351(void) +Si5351::Si5351(uint8_t i2c_addr): + i2c_bus_addr(i2c_addr) { dev_status.SYS_INIT = 0; dev_status.LOL_B = 0; @@ -161,6 +162,15 @@ void Si5351::reset(void) set_ms_source(SI5351_CLK6, SI5351_PLLB); set_ms_source(SI5351_CLK7, SI5351_PLLB); + // Reset the VCXO param + si5351_write(SI5351_VXCO_PARAMETERS_LOW, 0); + si5351_write(SI5351_VXCO_PARAMETERS_MID, 0); + si5351_write(SI5351_VXCO_PARAMETERS_HIGH, 0); + + // Then reset the PLLs + pll_reset(SI5351_PLLA); + pll_reset(SI5351_PLLB); + // Set initial frequencies uint8_t i; for(i = 0; i < 8; i++) @@ -168,10 +178,6 @@ void Si5351::reset(void) clk_freq[i] = 0; output_enable((enum si5351_clock)i, 0); } - - // Then reset the PLLs - pll_reset(SI5351_PLLA); - pll_reset(SI5351_PLLB); } /* @@ -184,13 +190,14 @@ void Si5351::reset(void) * clk - Clock output * (use the si5351_clock enum) */ -uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) +uint64_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) { struct Si5351RegSet ms_reg; uint64_t pll_freq; uint8_t int_mode = 0; uint8_t div_by_4 = 0; uint8_t r_div = 0; + uint64_t temp = 1; // Check which Multisynth is being set if((uint8_t)clk <= (uint8_t)SI5351_CLK5) @@ -205,8 +212,6 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) } // Upper bounds check - // We will only allow a maximum output frequency of 150 MHz using this - // method. For >=150 MHz, you'll have to manually set the paramters //if(freq >= SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT) if(freq > SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT) { @@ -214,7 +219,7 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) freq = SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT; } - // If requested freq >112.5 MHz and no other outputs are already >112.5 MHz, + // If requested freq >100 MHz and no other outputs are already >100 MHz, // we need to recalculate PLLA and then recalculate all other CLK outputs // on same PLL if(freq > (SI5351_MULTISYNTH_SHARE_MAX * SI5351_FREQ_MULT)) @@ -227,7 +232,7 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) { if(i != (uint8_t)clk && pll_assignment[i] == pll_assignment[clk]) { - return 1; // won't set if any other clks already >112.5 MHz + return 1; // won't set if any other clks already >100 MHz } } } @@ -271,7 +276,19 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) multisynth_calc(temp_freq, pll_freq, &temp_reg); - if(i == (uint8_t)clk) + // if(i == (uint8_t)clk) + // { + // div_by_4 = 1; + // int_mode = 1; + // } + // else + // { + // div_by_4 = 0; + // int_mode = 0; + // } + + // If freq > 150 MHz, we need to use DIVBY4 and integer mode + if(temp_freq >= SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT) { div_by_4 = 1; int_mode = 1; @@ -296,17 +313,23 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) clk_freq[(uint8_t)clk] = freq; // Enable the output - output_enable(clk, 1); + //uint8_t reg_val; + //reg_val = si5351_read(SI5351_OUTPUT_ENABLE_CTRL); + + //if((reg_val >> clk) & 1 == 1) + //{ + output_enable(clk, 1); + //} // Set PLL - if(pll_assignment[clk] == SI5351_PLLA) - { - set_pll(plla_freq, pll_assignment[clk]); - } - else - { - set_pll(pllb_freq, pll_assignment[clk]); - } + // if(pll_assignment[clk] == SI5351_PLLA) + // { + // set_pll(plla_freq, pll_assignment[clk]); + // } + // else + // { + // set_pll(pllb_freq, pll_assignment[clk]); + // } // Select the proper R div value r_div = select_r_div(&freq); @@ -314,20 +337,24 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) // Calculate the synth parameters if(pll_assignment[clk] == SI5351_PLLA) { - multisynth_calc(freq, plla_freq, &ms_reg); + temp = multisynth_calc(freq, plla_freq, &ms_reg); } else { multisynth_calc(freq, pllb_freq, &ms_reg); } - div_by_4 = 0; - int_mode = 0; + // div_by_4 = 0; + // int_mode = 0; // Set multisynth registers set_ms(clk, ms_reg, int_mode, r_div, div_by_4); + ms_div(clk, 0, 0); + + // Reset the PLL + pll_reset(pll_assignment[clk]); } - return 0; + return temp; } else { @@ -1231,7 +1258,7 @@ void Si5351::set_vcxo(uint64_t pll_freq, uint8_t ppm) uint8_t Si5351::si5351_write_bulk(uint8_t addr, uint8_t bytes, uint8_t *data) { - Wire.beginTransmission(SI5351_BUS_BASE_ADDR); + Wire.beginTransmission(i2c_bus_addr); Wire.write(addr); for(int i = 0; i < bytes; i++) { @@ -1242,7 +1269,7 @@ uint8_t Si5351::si5351_write_bulk(uint8_t addr, uint8_t bytes, uint8_t *data) uint8_t Si5351::si5351_write(uint8_t addr, uint8_t data) { - Wire.beginTransmission(SI5351_BUS_BASE_ADDR); + Wire.beginTransmission(i2c_bus_addr); Wire.write(addr); Wire.write(data); Wire.endTransmission(); @@ -1252,11 +1279,11 @@ uint8_t Si5351::si5351_read(uint8_t addr) { uint8_t reg_val; - Wire.beginTransmission(SI5351_BUS_BASE_ADDR); + Wire.beginTransmission(i2c_bus_addr); Wire.write(addr); Wire.endTransmission(); - Wire.requestFrom(SI5351_BUS_BASE_ADDR, 1, false); + Wire.requestFrom(i2c_bus_addr, 1, false); while(Wire.available()) { @@ -1275,11 +1302,12 @@ uint64_t Si5351::pll_calc(uint64_t freq, struct Si5351RegSet *reg, int32_t corre uint64_t ref_freq = xtal_freq * SI5351_FREQ_MULT; uint32_t a, b, c, p1, p2, p3; uint64_t lltmp, denom; - int64_t ref_temp; + //int64_t ref_temp; // Factor calibration value into nominal crystal frequency // Measured in parts-per-billion + // ref_freq = ref_freq + (int32_t)((((((int64_t)correction) << 31) / 1000000000LL) * ref_freq) >> 31); ref_freq = ref_freq + (int32_t)((((((int64_t)correction) << 31) / 1000000000LL) * ref_freq) >> 31); // PLL bounds checking @@ -1305,18 +1333,20 @@ uint64_t Si5351::pll_calc(uint64_t freq, struct Si5351RegSet *reg, int32_t corre } // Find best approximation for b/c = fVCO mod fIN - denom = 1000ULL * 1000ULL; - lltmp = freq % ref_freq; - lltmp *= denom; - do_div(lltmp, ref_freq); + // denom = 1000ULL * 1000ULL; + // lltmp = freq % ref_freq; + // lltmp *= denom; + // do_div(lltmp, ref_freq); - b = (((uint64_t)(freq % ref_freq)) * RFRAC_DENOM) / ref_freq; + //b = (((uint64_t)(freq % ref_freq)) * RFRAC_DENOM) / ref_freq; if(vcxo) { - c = RFRAC_DENOM; + b = (((uint64_t)(freq % ref_freq)) * 1000000ULL) / ref_freq; + c = 1000000ULL; } else { + b = (((uint64_t)(freq % ref_freq)) * RFRAC_DENOM) / ref_freq; c = b ? RFRAC_DENOM : 1; } @@ -1350,7 +1380,7 @@ uint64_t Si5351::multisynth_calc(uint64_t freq, uint64_t pll_freq, struct Si5351 { uint64_t lltmp; uint32_t a, b, c, p1, p2, p3; - uint8_t divby4; + uint8_t divby4 = 0; uint8_t ret_val = 0; // Multisynth bounds checking @@ -1363,7 +1393,6 @@ uint64_t Si5351::multisynth_calc(uint64_t freq, uint64_t pll_freq, struct Si5351 freq = SI5351_MULTISYNTH_MIN_FREQ * SI5351_FREQ_MULT; } - divby4 = 0; if (freq >= SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT) { divby4 = 1; diff --git a/src/si5351.h b/src/si5351.h index 1807727..58f84d2 100644 --- a/src/si5351.h +++ b/src/si5351.h @@ -279,10 +279,10 @@ struct Si5351IntStatus class Si5351 { public: -Si5351(void); + Si5351(uint8_t i2c_addr = SI5351_BUS_BASE_ADDR); void init(uint8_t, uint32_t, int32_t); void reset(void); - uint8_t set_freq(uint64_t, enum si5351_clock); + uint64_t set_freq(uint64_t, enum si5351_clock); uint8_t set_freq_manual(uint64_t, uint64_t, enum si5351_clock); void set_pll(uint64_t, enum si5351_pll); void set_ms(enum si5351_clock, struct Si5351RegSet, uint8_t, uint8_t, uint8_t); @@ -322,6 +322,7 @@ Si5351(void); uint8_t select_r_div(uint64_t *); uint8_t select_r_div_ms67(uint64_t *); int32_t ref_correction; + uint8_t i2c_bus_addr; }; #endif /* SI5351_H_ */ From 882709776340325d2c1bc3d0079c249f28cc2c01 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Sat, 25 Feb 2017 13:38:07 -0800 Subject: [PATCH 12/20] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4032a4b..bfd6355 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ Setting the Output Frequency ---------------------------- As indicated above, the library accepts and indicates clock and PLL frequencies in units of 0.01 Hz, as an _unsigned long long_ variable type (or _uint64_t_). When entering literal values, append ```ULL``` to make an explicit unsigned long long number to ensure proper tuning. Since many applications won't require sub-Hertz tuning, you may wish to use an _unsigned long_ (or _uint32_t_) variable to hold your tune frequency, then scale it up by multiplying by 100ULL before passing it to the _set_freq()_ method. -Using the _set_freq()_ method is the easiest way to use the library and gives you a wide range of tuning options, but has some constraints in its usage. Outputs CLK0 through CLK5 by default are all locked to PLLA while CLK6 and CLK7 are locked to PLLB. Due to the nature of the Si5351 architecture, there may only be one CLK output among those sharing a PLL which may be set greater than 110 MHz. Therefore, once one CLK output has been set above 100 MHz, no more CLKs on the same PLL will be allowed to be set greater than 100 MHz (unless the one which is already set is changed to a frequency below this threshold). +Using the _set_freq()_ method is the easiest way to use the library and gives you a wide range of tuning options, but has some constraints in its usage. Outputs CLK0 through CLK5 by default are all locked to PLLA while CLK6 and CLK7 are locked to PLLB. Due to the nature of the Si5351 architecture, there may only be one CLK output among those sharing a PLL which may be set greater than 100 MHz (actually specified at 112.5 MHz by SiLabs, but stability issues have been found at the upper end). Therefore, once one CLK output has been set above 100 MHz, no more CLKs on the same PLL will be allowed to be set greater than 100 MHz (unless the one which is already set is changed to a frequency below this threshold). If the above constraints are not suitable, you need glitch-free tuning, or you are counting on multiple clocks being locked to the same reference, you may set the PLL frequency manually then make clock reference assignments to either of the PLLs. From ea668d90006c05fe90e67de0b199b01839ac83da Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Sat, 25 Feb 2017 13:41:39 -0800 Subject: [PATCH 13/20] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bfd6355..bc67c68 100644 --- a/README.md +++ b/README.md @@ -667,7 +667,7 @@ Changelog * Increase maximum frequency in _set_freq()_ to 225 MHz * Change SI5351_MULTISYNTH_SHARE_MAX from 112.5 MHz to 100 MHz due to stability issues - * Add explict reset of VCXO param in reset() + * Add explicit reset of VCXO param in reset() * Add I2C bus address parameter and default to class constructor * v2.0.1 From 1fcbe231a64be45464df59d6a74c38c9480703c3 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Sat, 25 Feb 2017 13:43:17 -0800 Subject: [PATCH 14/20] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bc67c68..b8f37f8 100644 --- a/README.md +++ b/README.md @@ -667,7 +667,7 @@ Changelog * Increase maximum frequency in _set_freq()_ to 225 MHz * Change SI5351_MULTISYNTH_SHARE_MAX from 112.5 MHz to 100 MHz due to stability issues - * Add explicit reset of VCXO param in reset() + * Add explicit reset of VCXO param in _reset()_ * Add I2C bus address parameter and default to class constructor * v2.0.1 From fc4fbebff949bac3bb3fbe5d10a9cce867a48a69 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Sat, 25 Feb 2017 13:46:35 -0800 Subject: [PATCH 15/20] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b8f37f8..d363eaf 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ All CLK outputs are set to 0 Hz and disabled. Constraints ----------- -* Two multisynths cannot share a PLL with when both outputs are >= 110 MHz. The library will refuse to set another multisynth to a frequency in that range if another multisynth sharing the same PLL is already within that frequency range. +* Two multisynths cannot share a PLL with when both outputs are >= 100 MHz. The library will refuse to set another multisynth to a frequency in that range if another multisynth sharing the same PLL is already within that frequency range. * Setting phase will be limited in the extreme edges of the output tuning ranges. Because the phase register is 7-bits in size and is denominated in units representing 1/4 the PLL period, not all phases can be set for all output frequencies. For example, if you need a 90° phase shift, the lowest frequency you can set it at is 4.6875 MHz (600 MHz PLL/128). * The frequency range of Multisynth 6 and 7 is ~18.45 kHz to 150 MHz. The library assigns PLLB to these two multisynths, so if you choose to use both, then both frequencies must be an even divisor of the PLL frequency (between 6 and 254), so plan accordingly. You can see the current PLLB frequency by accessing the _pllb_freq_ public member. * VCXO pull range can be ±30 to ±240 ppm From c37713247437da816e30fabcdf79668ceb38d6d2 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Sat, 25 Feb 2017 16:48:32 -0800 Subject: [PATCH 16/20] Update si5351_calibration.ino --- README.md | 1 + .../si5351_calibration/si5351_calibration.ino | 29 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d363eaf..a053c62 100644 --- a/README.md +++ b/README.md @@ -669,6 +669,7 @@ Changelog * Change SI5351_MULTISYNTH_SHARE_MAX from 112.5 MHz to 100 MHz due to stability issues * Add explicit reset of VCXO param in _reset()_ * Add I2C bus address parameter and default to class constructor + * Update si5351_calibration example sketch * v2.0.1 diff --git a/examples/si5351_calibration/si5351_calibration.ino b/examples/si5351_calibration/si5351_calibration.ino index f173b6b..802e430 100644 --- a/examples/si5351_calibration/si5351_calibration.ino +++ b/examples/si5351_calibration/si5351_calibration.ino @@ -2,7 +2,7 @@ * si5351_calibration.ino - Simple calibration routine for the Si5351 * breakout board. * - * Copyright 2015 - 2016 Paul Warren + * Copyright 2015 - 2017 Paul Warren * Jason Milldrum * * Uses code from https://github.com/darksidelemm/open_radio_miniconf_2015 @@ -26,7 +26,7 @@ Si5351 si5351; int32_t cal_factor = 0; -int32_t old_cal; +int32_t old_cal = 0; uint64_t rx_freq; uint64_t target_freq = 1000000000ULL; // 10 MHz, in hundredths of hertz @@ -40,6 +40,8 @@ void setup() si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); // Start on target frequency + si5351.set_correction(cal_factor); + si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA); si5351.set_freq(target_freq, SI5351_CLK0); } @@ -57,15 +59,6 @@ void loop() Serial.println(F("Adjust until your frequency counter reads as close to 10 MHz as possible.")); Serial.println(F("Press 'q' when complete.")); vfo_interface(); - - Serial.println(); - Serial.print(F("Calibration factor is ")); - Serial.println(cal_factor); - Serial.println(F("Setting calibration factor")); - si5351.set_correction(cal_factor); - Serial.println(F("Resetting target frequency")); - si5351.set_freq(target_freq, SI5351_CLK0); - si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA); } } @@ -78,6 +71,7 @@ static void flush_input(void) static void vfo_interface(void) { rx_freq = target_freq; + cal_factor = old_cal; Serial.println(F(" Up: r t y u i o p")); Serial.println(F(" Down: f g h j k l ;")); Serial.println(F(" Hz: 0.01 0.1 1 10 100 1K 10k")); @@ -90,6 +84,15 @@ static void vfo_interface(void) { case 'q': flush_input(); + Serial.println(); + Serial.print(F("Calibration factor is ")); + Serial.println(cal_factor); + Serial.println(F("Setting calibration factor")); + si5351.set_correction(cal_factor); + si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA); + Serial.println(F("Resetting target frequency")); + si5351.set_freq(target_freq, SI5351_CLK0); + old_cal = cal_factor; return; case 'r': rx_freq += 1; break; case 'f': rx_freq -= 1; break; @@ -110,8 +113,10 @@ static void vfo_interface(void) continue; } - cal_factor = (int32_t)(target_freq - rx_freq); + cal_factor = (int32_t)(target_freq - rx_freq) + old_cal; si5351.set_correction(cal_factor); + si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA); + si5351.pll_reset(SI5351_PLLA); si5351.set_freq(target_freq, SI5351_CLK0); Serial.print(F("Current difference:")); Serial.println(cal_factor); From f3b164d1ed4f5f1f4d581728db1bdecb40fad628 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Mon, 27 Feb 2017 16:34:57 -0800 Subject: [PATCH 17/20] Fix error in set_freq() return value --- src/si5351.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/si5351.cpp b/src/si5351.cpp index 9b9d211..12e6ec6 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -212,10 +212,8 @@ uint64_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) } // Upper bounds check - //if(freq >= SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT) if(freq > SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT) { - //freq = SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT - 1; freq = SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT; } @@ -354,7 +352,7 @@ uint64_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) pll_reset(pll_assignment[clk]); } - return temp; + return 0; } else { @@ -1283,7 +1281,7 @@ uint8_t Si5351::si5351_read(uint8_t addr) Wire.write(addr); Wire.endTransmission(); - Wire.requestFrom(i2c_bus_addr, 1, false); + Wire.requestFrom(i2c_bus_addr, 1, (uint8_t)false); while(Wire.available()) { From fcd7bd9c98ef9ad5974c88e5f1691fd86968a83a Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Mon, 27 Feb 2017 17:59:31 -0800 Subject: [PATCH 18/20] Correct set_freq() back to correct return value --- src/si5351.cpp | 2 +- src/si5351.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/si5351.cpp b/src/si5351.cpp index 12e6ec6..cef9065 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -190,7 +190,7 @@ void Si5351::reset(void) * clk - Clock output * (use the si5351_clock enum) */ -uint64_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) +uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) { struct Si5351RegSet ms_reg; uint64_t pll_freq; diff --git a/src/si5351.h b/src/si5351.h index 58f84d2..24abc3b 100644 --- a/src/si5351.h +++ b/src/si5351.h @@ -282,7 +282,7 @@ class Si5351 Si5351(uint8_t i2c_addr = SI5351_BUS_BASE_ADDR); void init(uint8_t, uint32_t, int32_t); void reset(void); - uint64_t set_freq(uint64_t, enum si5351_clock); + uint8_t set_freq(uint64_t, enum si5351_clock); uint8_t set_freq_manual(uint64_t, uint64_t, enum si5351_clock); void set_pll(uint64_t, enum si5351_pll); void set_ms(enum si5351_clock, struct Si5351RegSet, uint8_t, uint8_t, uint8_t); From 6d8ee4280c7213dee6fc28dde009421031a49c53 Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Tue, 28 Feb 2017 08:40:15 -0800 Subject: [PATCH 19/20] Code cleanup --- src/si5351.cpp | 47 +---------------------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/src/si5351.cpp b/src/si5351.cpp index cef9065..bb2152f 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -140,9 +140,6 @@ void Si5351::reset(void) set_pll(SI5351_PLL_FIXED, SI5351_PLLA); set_pll(SI5351_PLL_FIXED, SI5351_PLLB); - //plla_freq = SI5351_PLL_FIXED; - //pllb_freq = SI5351_PLL_FIXED; - // Make PLL to CLK assignments for automatic tuning pll_assignment[0] = SI5351_PLLA; pll_assignment[1] = SI5351_PLLA; @@ -244,17 +241,6 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) // Calculate the proper PLL frequency pll_freq = multisynth_calc(freq, 0, &ms_reg); - /* - if(pll_assignment[clk] == SI5351_PLLA) - { - plla_freq = pll_freq; - } - else - { - pllb_freq = pll_freq; - } - */ - // Set PLL set_pll(pll_freq, pll_assignment[clk]); @@ -274,17 +260,6 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) multisynth_calc(temp_freq, pll_freq, &temp_reg); - // if(i == (uint8_t)clk) - // { - // div_by_4 = 1; - // int_mode = 1; - // } - // else - // { - // div_by_4 = 0; - // int_mode = 0; - // } - // If freq > 150 MHz, we need to use DIVBY4 and integer mode if(temp_freq >= SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT) { @@ -311,23 +286,7 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) clk_freq[(uint8_t)clk] = freq; // Enable the output - //uint8_t reg_val; - //reg_val = si5351_read(SI5351_OUTPUT_ENABLE_CTRL); - - //if((reg_val >> clk) & 1 == 1) - //{ - output_enable(clk, 1); - //} - - // Set PLL - // if(pll_assignment[clk] == SI5351_PLLA) - // { - // set_pll(plla_freq, pll_assignment[clk]); - // } - // else - // { - // set_pll(pllb_freq, pll_assignment[clk]); - // } + output_enable(clk, 1); // Select the proper R div value r_div = select_r_div(&freq); @@ -341,8 +300,6 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) { multisynth_calc(freq, pllb_freq, &ms_reg); } - // div_by_4 = 0; - // int_mode = 0; // Set multisynth registers set_ms(clk, ms_reg, int_mode, r_div, div_by_4); @@ -1300,12 +1257,10 @@ uint64_t Si5351::pll_calc(uint64_t freq, struct Si5351RegSet *reg, int32_t corre uint64_t ref_freq = xtal_freq * SI5351_FREQ_MULT; uint32_t a, b, c, p1, p2, p3; uint64_t lltmp, denom; - //int64_t ref_temp; // Factor calibration value into nominal crystal frequency // Measured in parts-per-billion - // ref_freq = ref_freq + (int32_t)((((((int64_t)correction) << 31) / 1000000000LL) * ref_freq) >> 31); ref_freq = ref_freq + (int32_t)((((((int64_t)correction) << 31) / 1000000000LL) * ref_freq) >> 31); // PLL bounds checking From 2c7704f574b48b74b2f9a6d3a781c84a3b36c3db Mon Sep 17 00:00:00 2001 From: Jason Milldrum Date: Fri, 17 Mar 2017 08:47:56 -0700 Subject: [PATCH 20/20] More code cleanup --- src/si5351.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/si5351.cpp b/src/si5351.cpp index bb2152f..51c5c91 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -194,7 +194,6 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) uint8_t int_mode = 0; uint8_t div_by_4 = 0; uint8_t r_div = 0; - uint64_t temp = 1; // Check which Multisynth is being set if((uint8_t)clk <= (uint8_t)SI5351_CLK5) @@ -294,7 +293,7 @@ uint8_t Si5351::set_freq(uint64_t freq, enum si5351_clock clk) // Calculate the synth parameters if(pll_assignment[clk] == SI5351_PLLA) { - temp = multisynth_calc(freq, plla_freq, &ms_reg); + multisynth_calc(freq, plla_freq, &ms_reg); } else { @@ -1238,7 +1237,7 @@ uint8_t Si5351::si5351_read(uint8_t addr) Wire.write(addr); Wire.endTransmission(); - Wire.requestFrom(i2c_bus_addr, 1, (uint8_t)false); + Wire.requestFrom(i2c_bus_addr, (uint8_t)1, (uint8_t)false); while(Wire.available()) {