Si5351-lib
Description
Si5351-A/B/C-B lib for STM32 Cortex M processors. Later, it may be modified for other architectures as well. If you wih to port it to another architecture, you just need to replace 2 functions which deal with I2C and one member of one struct which specifies which I2C to use.
Overview
This library can (contrary to most other libraries) completely utilize the features of Si5351-A/B/C-B (second generation of Si5351-A/B/C). Currently, it can set all of the properties of input stage, PLLs, Multisynths, CLKs and output stage. It can also set several undocumented features which (at least I think so) were not yet implemented anywhere else - for example turn off "fanout" of several internal signals or modify the capacitive load of the internal VCO.
The approach of this library is not to completely abstract from the hardware of the PLL - you have to figure out the frequency plan yourself. This library handles all of the communication and formatting of the parameters and cuts off user from having to care about some details like switching between integer and fractional modes (this happens automatically inside the library).
Reset of PLLs is not yet completely automated, because it is very badly documented, so it is still a responsibility of the user.
Features
Input Stage
All of the important features are implemented - CLKIN divider, VCXO, crystal oscillator load setting and PLL capacitive load (yep, maybe it should be moved to other section). The undocumented 4 pF crystal load is included.
TODO: Automatically detect if it is possible to turn off "fanout" of internal clocks.
PLL
The PLL can be set to any frequency - the limits were empirically found to be about 170 - 1200 MHz where the VCO can oscillate. Useable range of frequencies is however (on my tested devices) narrower - 170 to 820 MHz (yes, one is out of spec, the other is just abusement of the device, it should be 600-900). The library takes control of everything, all you need is to set the multiplier values and clock source and use the configuration functions. It is also possible to override the default VCO capacitive load, though not recommended.
TODO: Currently, only one PLL can be reset at a time. Note however that even by resetting them at the same time, they will never be synchronised! If you want synchronous clocks with defined phase offset, they have to be taken from one PLL!
Spread Spectrum
Spread spectrum supports both down- and center-spread. It has been empirically found that it can be used up to about 5% spread (datasheet allows max +-2.5%). At around 8%, glitches on output start to appear.
TODO: Add possibility to set SS_NCLK by user. This however needs to be first tested using a spectral analyzer, because SiLabs are trying not to help at all.
MultiSynth
The MultiSynth can be set to any integer or fractional divider and use any of the PLLs. The library automatically sets the mode depending on the settings you give it. The minimal divider is 4 (this allows for max output clock of 205 MHz on my devices), maximal is 1800 (111 kHz when PLL=200 MHz). Minimal divider for fractional mode is 8. Multisynths 6 and 7 which are integer-only are implemented as well.
Output stage
Output R divider, clock selection, phase offset, inversion, OEB pin masking, current drive, disable state, enabling and power down are supported.
Interrupts
Interrupts can be masked. Even the undocumented LOS_XTAL_MASK is implemented.
Status bits
Reading status bits is supported. Reading and clearing "sticky" status bits is implemented as well. The half-documented LOS_XTAL is implemented.
The source files
Look in the folders "inc" and "src" for source files. In folder "documentation", you may find all relevant info about the Si5351.
Porting
Information for anyone wishing to make a port are included in the source files. In short, all you need to modify, is the two communication functions: Si5351_WriteRegister and Si5351_ReadRegister and the I2Cx member of the struct Si5351_ConfigTypeDef.
Coming potentially soon
There should be some automatic way of reseting the PLL only when it is needed to relieve the user of this responsibility. SS_NCLK parameter could be a bit investigated and maybe abused for something useful. There are still several strange unexplained bits in register map which may be of interest. Maybe I will make it platform independent, so it could be used at least with Arduino as well.
Example
Simple example how to get 50 kHz output with 25 MHz crystal:
Si5351_ConfigTypeDef Si5351_ConfigStruct;
Si5351_StructInit(&Si5351_ConfigStruct); //initialize the structure with default "safe" values
Si5351_ConfigStruct.OSC.OSC_XTAL_Load = XTAL_Load_8_pF; //use 8 pF load for crystal
Si5351_ConfigStruct.PLL[0].PLL_Clock_Source = PLL_Clock_Source_XTAL; //select xrystal as clock input for the PLL
Si5351_ConfigStruct.PLL[0].PLL_Multiplier_Integer = 32; //multiply the clock frequency by 32, this gets us 800 MHz clock
Si5351_ConfigStruct.MS[0].MS_Clock_Source = MS_Clock_Source_PLLA; //select PLLA as clock source for MultiSynth 0
Si5351_ConfigStruct.MS[0].MS_Divider_Integer = 250; //divide the 800 MHz by 250 this gets us 3.2 MHz
Si5351_ConfigStruct.CLK[0].CLK_R_Div = CLK_R_Div64; //divide the MultiSynth output by 64, this gets us 50 kHz
Si5351_ConfigStruct.CLK[0].CLK_Enable = ON; //turn on the output
Si5351_Init(&Si5351_ConfigStruct); //apply the changes
This is all you need to get a clock out of the Si5351. There are many options you may explore, but this is the very basic mandatory setting.
Reference
Please, be aware that the documentation of SiLabs is full of errors and nonsense. My library has most of them fixed, some of my own fixes were even reflected by SiLabs in AN-619 v0.7. I am hosting the documents here, because SiLabs hides the old versions of the documents.
AN-551: Crystal selection guide for Si5350/51 devices v0.3
AN-554: Si5350/51 PCB Layout Guide v0.3
Please see this, I tried to draw into the document what is wrong:
AN-619: Manually generating a Si5351 Register Map v0.7 with my own corrections of bugs
AN-619: Manually generating a Si5351 Register Map v0.7
This is the only place where there is some mention of the VCO capacitive load:
AN-619: Manually generating a Si5351 Register Map v0.6
Here is a list of errors I found in datasheet 1.0 and AN-619 0.6:
First contact with someone from SiLabs about all of those nasty bugs
Effort to find some info about the VCO capacitive load and the LOS_XTAL and its corresponding status bit, sticky bit and int mask:
Second contact with SiLabs about the bugs, a year later
And most importantly - some info from radioamateurs who were trying out how the damned thing works: