Topics

Si5351 Programming Flowchart

 

Hi Guys
A weeks ago Josué Marin-CO7RR- sent me this information to share with my group.
I am only try to be a good 'USER" testing some interesting project I can get on the web and afterward share it with my group.
Now Pavel-CO7WT- sent me this link and I think is a good idea to share with all of you.
 
https://nt7s.com/2018/02/si5351-programming-flowchart/

It is a Josué Marin email address
marinjosue75atgmaildotcom 
Qrv's
73's Jc

Jerry Gaffke
 

That flowchart describes how to code low level si5351 routines,
not how to use those routines.  So probably not of much intereset
to most of the readers of this forum.

Allard's Bitx40 firmware and in Farhan's uBitx firmware currently use the si5351bx routines,
to use them just embed the two functions si5351bx_init() and si5351bx_setfreq() into your sketch.
Call si5351bx_init() once at startup, all three clk's get initialized to the off state.
Call si5351bx_setfreq(clknum, fout) each time you wish to change the frequency of a clock
with clknum a value of 0, 1, or 2, and fout in hz between 500khz and 109mhz.
Use a frequency of 0 hz if you wish to turn one of the clocks back off.
To calibrate, adjust the value of si5351bx_vcoa and then call si5351bx_setfreq() for each of the active clocks.

Resolution is to one hz, since fout in hz is an integer.  (Though we could go to a fractional fixed point representation if necessary.)
The accuracy of the calculations is down around 1ppm, considerably better than the stability of the 25mhz reference oscillator.

There has been one minor bug found since the si5351bx code was made available last summer, this line:
    i2cWrite(183, SI5351BX_XTALPF << 6);
should be changed to this:
    i2cWrite(183, (SI5351BX_XTALPF << 6) | 0x12);
to agree with the recommendations in the SiLabs apnote AN619
This may improve phase noise, though I have not heard any reports of it making any perceivable difference.

The code from Pavel (and the code from Etherkit or G0UPL) will allow you to exceed the 109mhz max frequency
if that is of interest.  There may be differences in phase noise, though again I am not aware of this being perceptible by
anyone in this forum. 

Jerry, KE7ER



On Mon, Feb 12, 2018 at 09:07 am, JuanCarlos Berberena Gonzalez wrote:
Hi Guys
A weeks ago Josué Marin-CO7RR- sent me this information to share with my group.
I am only try to be a good 'USER" testing some interesting project I can get on the web and afterward share it with my group.
Now Pavel-CO7WT- sent me this link and I think is a good idea to share with all of you.
 
https://nt7s.com/2018/02/si5351-programming-flowchart/

JuanCarlos
 

Thx, good to know.
73's Jc

“If you have a penny and I have a penny and we exchange pennies, you still have one cent and I still have one cent.  But if you have an idea and I have an idea and we exchange ideas, you now have two ideas and I now have two ideas.” 

Mr. Juan Carlos Berberena Gonzalez, BSc.
WJ6C exCO6BG 


2018-02-12 12:48 GMT-05:00 Jerry Gaffke via Groups.Io <jgaffke@...>:

That flowchart describes how to code low level si5351 routines,
not how to use those routines.  So probably not of much intereset
to most of the readers of this forum.

Allard's Bitx40 firmware and in Farhan's uBitx firmware currently use the si5351bx routines,
to use them just embed the two functions si5351bx_init() and si5351bx_setfreq() into your sketch.
Call si5351bx_init() once at startup, all three clk's get initialized to the off state.
Call si5351bx_setfreq(clknum, fout) each time you wish to change the frequency of a clock
with clknum a value of 0, 1, or 2, and fout in hz between 500khz and 109mhz.
Use a frequency of 0 hz if you wish to turn one of the clocks back off.
To calibrate, adjust the value of si5351bx_vcoa and then call si5351bx_setfreq() for each of the active clocks.

Resolution is to one hz, since fout in hz is an integer.  (Though we could go to a fractional fixed point representation if necessary.)
The accuracy of the calculations is down around 1ppm, considerably better than the stability of the 25mhz reference oscillator.

There has been one minor bug found since the si5351bx code was made available last summer, this line:
    i2cWrite(183, SI5351BX_XTALPF << 6);
should be changed to this:
    i2cWrite(183, (SI5351BX_XTALPF << 6) | 0x12);
to agree with the recommendations in the SiLabs apnote AN619
This may improve phase noise, though I have not heard any reports of it making any perceivable difference.

The code from Pavel (and the code from Etherkit or G0UPL) will allow you to exceed the 109mhz max frequency
if that is of interest.  There may be differences in phase noise, though again I am not aware of this being perceptible by
anyone in this forum. 

Jerry, KE7ER



On Mon, Feb 12, 2018 at 09:07 am, JuanCarlos Berberena Gonzalez wrote:
Hi Guys
A weeks ago Josué Marin-CO7RR- sent me this information to share with my group.
I am only try to be a good 'USER" testing some interesting project I can get on the web and afterward share it with my group.
Now Pavel-CO7WT- sent me this link and I think is a good idea to share with all of you.
 
https://nt7s.com/2018/02/si5351-programming-flowchart/


Jerry Gaffke
 

Calculations within the si5351bx routines are much better than than 1ppm accurate, perhaps more like 0.01ppm.
As I recall, the math was accurate within 0.2hz when doing calculations for a high side vfo on the Bitx40 of 19mhz. 


On Mon, Feb 12, 2018 at 09:48 am, Jerry Gaffke wrote:
The accuracy of the calculations is down around 1ppm, considerably better than the stability of the 25mhz reference oscillator.

Pavel Milanes Costa <pavelmc@...>
 

El 12/02/18 a las 15:35, Jerry Gaffke via Groups.Io escribió:
Calculations within the si5351bx routines are much better than than 1ppm accurate, perhaps more like 0.01ppm.
As I recall, the math was accurate within 0.2hz when doing calculations for a high side vfo on the Bitx40 of 19mhz.
If the math/hardware has a better accuracy than the Xtal itself then you have at the output just the stability of the Xtal... right?

73 Pavel CO7WT

Jerry Gaffke
 

Yup, not much point in getting too carried away in creating a VFO for the Bitx40.
Initial accuracy of the si5351bx routines can be calibrated to be quite good by adjusting si5351bx_vcoa
But a slight change in temperature and the 25mhz reference will drift a few hz,
so stability will be an issue

If an application comes up where greater stability is required,
the 25mhz (or 27mhz) reference could come from an ocxo or tcxo, or be GPS disciplined,
or perhaps you constantly adjust a knob for zero-beat with a known accurate radio station such as wwv.

Jerry, KE7ER


On Mon, Feb 12, 2018 at 12:56 pm, Pavel Milanes Costa wrote:
El 12/02/18 a las 15:35, Jerry Gaffke via Groups.Io escribió:
Calculations within the si5351bx routines are much better than than 1ppm accurate, perhaps more like 0.01ppm.
As I recall, the math was accurate within 0.2hz when doing calculations for a high side vfo on the Bitx40 of 19mhz.
If the math/hardware has a better accuracy than the Xtal itself then you have at the output just the stability of the Xtal... right?

Pavel Milanes Costa <pavelmc@...>
 

Hi to all.

The flowchat is a instructive guide for the curious of how to doit without float point math and an expression of the KISS principle.

It's just a cheat sheet to learn from.

The trick is to understand the way he (like Gerry) find a, b and c not needing floating point math. (for the PLL/VCO Msynths case is)

a = int(Fvco/xtal)

b = Fvco % xtal (module, aka: rest of the division)

c = xtal

For example Gerry do a do..while to find a value of b/c that match the allowed size of c, he need it because he is working with the output Msynth dividers not the PLL/VCO Msynth, in his case c = fout and is variable.

In the later case (moving the PLL/VCO Msynth, output Msynth dividers are fixed) c is fixed and equal to the Xtal and we know it already then we can do a simple x >> 5 to both b/c to retain maximum accuracy and make it fit on the register. If we do that just set the output Msynth divider to a integer & even value to minimize jitter or phase noise.

In Gerry routines he fixes the VCO and moves the output divider Msynth and that make some jitter or phase noise (almost negligible in real applications, I know) and makes 3 outs from just one fixed VCO and does not handles the R values or the DIV_BY4 feature limiting the full range of output frequencies (not needed on his target application, I know).

This is just another way of doing things, a way that can be better understood because it uses a simple and elegant image (flowchart), to make life (& code) easier (& smaller)...

BTW I found a possible bug that can haunt more than one in the routines of computing MSx_P2. A tip for the "math" experts... and a common fault.

As per the data:

MSx_P2 = 128 * b - c * floor (128 * b / c)

Right?

It's very tempting to reduce it but the floor functions is in there... let see... floor is the lower integer for that float number, hum...

Floor is on the C of Gcc the compiler used by the arduino project but it implies the use of floating point math hence bigger code, just eliminate it and do the math, let try to reduce it...

MSx_P2 = (128 * b) - (c * 128 * b / c)
MSx_P2 = (128 * b) - (128 * b) ---> (c is eliminated as it's * and /  in the expression)
MSx_P2 = 128 * (b - b) ---> ( hum....)
MSx_P2 = 128 * 0 ---> (HUMMMM!!!)
MSx_P2 = 0 ---> (WTF !!!!)

Doing some math and wall head-hiting you can conclude that the floor function is instructing you to IGNORE the use of fractions and then you get a value in MSx_P2 that it related to the amount of error or rest of division of doing things (math) with integers... hence the floor function... forcing you to use just integers... nice.

For example Gerry users in his code this:

msxp2 = 128 * msb - 128 * msb / msc * msc;

If you play that same function with human and integer rules it play well and result is different from zero, but if you use floating point math it always equals to ZERO!

Let's play it with me in full integer math

let's say msb = 900 and msc = 1000

msxp2 = 128 * 900 - 128 * 900 / 1000 * 1000;
msxp2 = 115200 - 115200 / 1000 * 1000;
msxp2 = 115200 - 115 * 1000;   // <<<<=== here is the floor in action (result in float is 115.200 we get it down to 115, all with the magic of integer math)
msxp2 = 115200 - 115000;
msxp2 = 200;

In this case 200 is a relation of the error of using integer math... interesting, mind you how the chip use it internally

For correctness and just to be sure to maintain the best accuracy you must get sure the compiler do the 128*b/c * c in the correct order, that is as per Gerry code fragment:

msxp2 = 128 * msb - 128 * msb / msc * msc;

Must be forced to execute in the correct order by placing some parenthesis to maintain more accuracy.

msxp2 = 128 * msb - ((128 * msb) / msc) * msc;

Firmware size impact is unchanged, compiled code is the same (sha256sum) with and without the parenthesis so GCC compiler is doing he job right, beware of others...

I mentioned this because I have a ham fellow in university (freshman) that hit his head against this wall a few times, "that's impossible, that has no sense.... MSx_P2 is always zero..." he said...

Just my two cents for other that may be in troubles like this understanding the chip.

Cheers, Pavel.

El 12/02/18 a las 12:07, JuanCarlos Berberena Gonzalez escribió:
Hi Guys
A weeks ago Josué Marin-CO7RR- sent me this information to share with my group.
I am only try to be a good 'USER" testing some interesting project I can get on the web and afterward share it with my group.
Now Pavel-CO7WT- sent me this link and I think is a good idea to share with all of you.
 
https://nt7s.com/2018/02/si5351-programming-flowchart/

It is a Josué Marin email address
marinjosue75atgmaildotcom 
Qrv's
73's Jc

K9WIS
 

there is a windows program on the adafruit website that will give you the parameters after you enter the frequency..I am using a nano($3) and one of the adafruit si5351break out boards($8) with a low pass filter9$5) for a QRSS 20mW xmtr I plan to release with a balloon..total cost under $20
Brian K9WIS

---- Pavel Milanes Costa <pavelmc@...> wrote:

Hi to all.

The flowchat is a instructive guide for the curious of how to doit
without float point math and an expression of the KISS principle.

It's just a cheat sheet to learn from.

The trick is to understand the way he (like Gerry) find a, b and c not
needing floating point math. (for the PLL/VCO Msynths case is)

a = int(Fvco/xtal)

b = Fvco % xtal (module, aka: rest of the division)

c = xtal

For example Gerry do a do..while to find a value of b/c that match the
allowed size of c, he need it because he is working with the output
Msynth dividers not the PLL/VCO Msynth, in his case c = fout and is
variable.

In the later case (moving the PLL/VCO Msynth, output Msynth dividers are
fixed) c is fixed and equal to the Xtal and we know it already then we
can do a simple x >> 5 to both b/c to retain maximum accuracy and make
it fit on the register. If we do that just set the output Msynth divider
to a integer & even value to minimize jitter or phase noise.

In Gerry routines he fixes the VCO and moves the output divider Msynth
and that make some jitter or phase noise (almost negligible in real
applications, I know) and makes 3 outs from just one fixed VCO and does
not handles the R values or the DIV_BY4 feature limiting the full range
of output frequencies (not needed on his target application, I know).

This is just another way of doing things, a way that can be better
understood because it uses a simple and elegant image (flowchart), to
make life (& code) easier (& smaller)...

BTW I found a possible bug that can haunt more than one in the routines
of computing MSx_P2. A tip for the "math" experts... and a common fault.

As per the data:

MSx_P2 = 128 * b - c * floor (128 * b / c)

Right?

It's very tempting to reduce it but the floor functions is in there...
let see... floor is the lower integer for that float number, hum...

Floor is on the C of Gcc the compiler used by the arduino project but it
implies the use of floating point math hence bigger code, just eliminate
it and do the math, let try to reduce it...

MSx_P2 = (128 * b) - (c * 128 * b / c)
MSx_P2 = (128 * b) - (128 * b) ---> (c is eliminated as it's * and /  in
the expression)
MSx_P2 = 128 * (b - b) ---> ( hum....)
MSx_P2 = 128 * 0 ---> (HUMMMM!!!)
MSx_P2 = 0 ---> (WTF !!!!)

Doing some math and wall head-hiting you can conclude that the floor
function is instructing you to IGNORE the use of fractions and then you
get a value in MSx_P2 that it related to the amount of error or rest of
division of doing things (math) with integers... hence the floor
function... forcing you to use just integers... nice.

For example Gerry users in his code this:

msxp2 = 128 * msb - 128 * msb / msc * msc;

If you play that same function with human and integer rules it play well
and result is different from zero, but if you use floating point math it
always equals to ZERO!

Let's play it with me in full integer math

let's say msb = 900 and msc = 1000

msxp2 = 128 * 900 - 128 * 900 / 1000 * 1000;
msxp2 = 115200 - 115200 / 1000 * 1000;
msxp2 = 115200 - 115 * 1000;   // <<<<=== here is the floor in action
(result in float is 115.200 we get it down to 115, all with the magic of
integer math)
msxp2 = 115200 - 115000;
msxp2 = 200;

In this case 200 is a relation of the error of using integer math...
interesting, mind you how the chip use it internally

For correctness and just to be sure to maintain the best accuracy you
must get sure the compiler do the 128*b/c * c in the correct order, that
is as per Gerry code fragment:

msxp2 = 128 * msb - 128 * msb / msc * msc;

Must be forced to execute in the correct order by placing some
parenthesis to maintain more accuracy.

msxp2 = 128 * msb - ((128 * msb) / msc) * msc;

Firmware size impact is unchanged, compiled code is the same (sha256sum)
with and without the parenthesis so GCC compiler is doing he job right,
beware of others...

I mentioned this because I have a ham fellow in university (freshman)
that hit his head against this wall a few times, "that's impossible,
that has no sense.... MSx_P2 is always zero..." he said...

Just my two cents for other that may be in troubles like this
understanding the chip.

Cheers, Pavel.

El 12/02/18 a las 12:07, JuanCarlos Berberena Gonzalez escribió:
Hi Guys
A weeks ago Josué Marin-CO7RR- sent me this information to share with
my group.
I am only try to be a good 'USER" testing some interesting project I
can get on the web and afterward share it with my group.
Now Pavel-CO7WT- sent me this link and I think is a good idea to share
with all of you.
https://nt7s.com/2018/02/si5351-programming-flowchart/

It is a Josué Marin email address
marinjosue75atgmaildotcom
Qrv's
73's Jc

KC9SGV <kc9sgv@...>
 

Hi Brian,
I am very interested in your HAB project.
I want to do the same.
Please forward me some details, links, etc.

I have been following Andy in Australia with his solar panel Mylar party balloon clusters.
Even set up a listening node on 30m for him here in Chicago.

$20 to track a 70,000 ft floater...
I can do that !

Bernie DeKok
KC9SGV

On Feb 12, 2018, at 7:16 PM, B C <k9wis@...> wrote:

there is a windows program on the adafruit website that will give you the parameters after you enter the frequency..I am using a nano($3) and one of the adafruit si5351break out boards($8) with a low pass filter9$5) for a QRSS 20mW xmtr I plan to release with a balloon..total cost under $20
Brian K9WIS

---- Pavel Milanes Costa <pavelmc@...> wrote:
Hi to all.

The flowchat is a instructive guide for the curious of how to doit
without float point math and an expression of the KISS principle.

It's just a cheat sheet to learn from.

The trick is to understand the way he (like Gerry) find a, b and c not
needing floating point math. (for the PLL/VCO Msynths case is)

a = int(Fvco/xtal)

b = Fvco % xtal (module, aka: rest of the division)

c = xtal

For example Gerry do a do..while to find a value of b/c that match the
allowed size of c, he need it because he is working with the output
Msynth dividers not the PLL/VCO Msynth, in his case c = fout and is
variable.

In the later case (moving the PLL/VCO Msynth, output Msynth dividers are
fixed) c is fixed and equal to the Xtal and we know it already then we
can do a simple x >> 5 to both b/c to retain maximum accuracy and make
it fit on the register. If we do that just set the output Msynth divider
to a integer & even value to minimize jitter or phase noise.

In Gerry routines he fixes the VCO and moves the output divider Msynth
and that make some jitter or phase noise (almost negligible in real
applications, I know) and makes 3 outs from just one fixed VCO and does
not handles the R values or the DIV_BY4 feature limiting the full range
of output frequencies (not needed on his target application, I know).

This is just another way of doing things, a way that can be better
understood because it uses a simple and elegant image (flowchart), to
make life (& code) easier (& smaller)...

BTW I found a possible bug that can haunt more than one in the routines
of computing MSx_P2. A tip for the "math" experts... and a common fault.

As per the data:

MSx_P2 = 128 * b - c * floor (128 * b / c)

Right?

It's very tempting to reduce it but the floor functions is in there...
let see... floor is the lower integer for that float number, hum...

Floor is on the C of Gcc the compiler used by the arduino project but it
implies the use of floating point math hence bigger code, just eliminate
it and do the math, let try to reduce it...

MSx_P2 = (128 * b) - (c * 128 * b / c)
MSx_P2 = (128 * b) - (128 * b) ---> (c is eliminated as it's * and / in
the expression)
MSx_P2 = 128 * (b - b) ---> ( hum....)
MSx_P2 = 128 * 0 ---> (HUMMMM!!!)
MSx_P2 = 0 ---> (WTF !!!!)

Doing some math and wall head-hiting you can conclude that the floor
function is instructing you to IGNORE the use of fractions and then you
get a value in MSx_P2 that it related to the amount of error or rest of
division of doing things (math) with integers... hence the floor
function... forcing you to use just integers... nice.

For example Gerry users in his code this:

msxp2 = 128 * msb - 128 * msb / msc * msc;

If you play that same function with human and integer rules it play well
and result is different from zero, but if you use floating point math it
always equals to ZERO!

Let's play it with me in full integer math

let's say msb = 900 and msc = 1000

msxp2 = 128 * 900 - 128 * 900 / 1000 * 1000;
msxp2 = 115200 - 115200 / 1000 * 1000;
msxp2 = 115200 - 115 * 1000; // <<<<=== here is the floor in action
(result in float is 115.200 we get it down to 115, all with the magic of
integer math)
msxp2 = 115200 - 115000;
msxp2 = 200;

In this case 200 is a relation of the error of using integer math...
interesting, mind you how the chip use it internally

For correctness and just to be sure to maintain the best accuracy you
must get sure the compiler do the 128*b/c * c in the correct order, that
is as per Gerry code fragment:

msxp2 = 128 * msb - 128 * msb / msc * msc;

Must be forced to execute in the correct order by placing some
parenthesis to maintain more accuracy.

msxp2 = 128 * msb - ((128 * msb) / msc) * msc;

Firmware size impact is unchanged, compiled code is the same (sha256sum)
with and without the parenthesis so GCC compiler is doing he job right,
beware of others...

I mentioned this because I have a ham fellow in university (freshman)
that hit his head against this wall a few times, "that's impossible,
that has no sense.... MSx_P2 is always zero..." he said...

Just my two cents for other that may be in troubles like this
understanding the chip.

Cheers, Pavel.

El 12/02/18 a las 12:07, JuanCarlos Berberena Gonzalez escribió:
Hi Guys
A weeks ago Josué Marin-CO7RR- sent me this information to share with
my group.
I am only try to be a good 'USER" testing some interesting project I
can get on the web and afterward share it with my group.
Now Pavel-CO7WT- sent me this link and I think is a good idea to share
with all of you.
https://nt7s.com/2018/02/si5351-programming-flowchart/

It is a Josué Marin email address
marinjosue75atgmaildotcom
Qrv's
73's Jc