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.
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.
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.
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.
NOTE: Resetting both PLLs at the same time has been implemented. 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 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.
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 R divider, clock selection, phase offset, inversion, OEB pin masking, current drive, disable state, enabling and power down are supported.
Interrupts can be masked. Even the undocumented LOS_XTAL_MASK is implemented.
Reading status bits is supported. Reading and clearing "sticky" status bits is implemented as well. The half-documented LOS_XTAL is implemented.
Look in the folders "inc" and "src" for source files. In folder "documentation", you may find all relevant info about the Si5351.
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.
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.
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.
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. PLEASE BE AWARE OF THE FACT THAT THE LIBRARY HAS BEEN WRITTEN IN 2018-2020. Therefore, it should be updated to match datasheet 1.2 and 1.3 and AN-619 0.8. Also, older versions should be checked fro explaining undocumented registers.
Datasheets:
Datasheet for the Si5351 v1.3 NOT USED DURING LIBRARY CREATION
Datasheet for the Si5351 v1.2 NOT USED DURING LIBRARY CREATION
Datasheet for the Si5351 v0.75 NOT USED DURING LIBRARY CREATION
Datasheet for the Si5351 v0.95 (it is older than 0.75) NOT USED DURING LIBRARY CREATION
Datasheet for the Si5351 v0.9 (it is older than 0.75) NOT USED DURING LIBRARY CREATION
Datasheet for the Si5351 v0.1 NOT USED DURING LIBRARY CREATION
Application note explaining setup of the chip:
AN-619: Manually generating a Si5351 Register Map v0.8 NOT USED DURING LIBRARY CREATION
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
AN-619: Manually generating a Si5351 Register Map v0.3 NOT USED DURING LIBRARY CREATION
AN-619: Manually generating a Si5351 Register Map v0.2 NOT USED DURING LIBRARY CREATION
Application note explaining setup of the chip for the 4-channel version of Si5351:
AN-1234: Manually Generating an Si5351 Register Map for 16QFN Devices v0.1
Auxiliary application notes:
AN-551: Crystal selection guide for Si5350/51 devices v0.3
AN-551: Crystal selection guide for Si5350/51 devices v0.1 NOT USED DURING LIBRARY CREATION
AN-554: Si5350/51 PCB Layout Guide v0.3
AN-554: Si5350/51 PCB Layout Guide v0.2 NOT USED DURING LIBRARY CREATION
AN-554: Si5350/51 PCB Layout Guide v0.1 NOT USED DURING LIBRARY CREATION
FAQ (list of versions not available)
Si5351 FAQ v0.5 NOT USED DURING LIBRARY CREATION
Here is a list of errors I found in datasheet 1.0 and AN-619 0.6:
Effort to find some info about the VCO capacitive load and the LOS_XTAL and its corresponding status bit, sticky bit and int mask:
And most importantly - some info from radioamateurs who were trying out how the damned thing works: