Adafruit Si5351 Library
Public Member Functions | List of all members
Adafruit_SI5351 Class Reference

SI5351 class. More...

#include <Adafruit_SI5351.h>

Public Member Functions

 Adafruit_SI5351 (void)
 SI5351 object. More...
 
err_t begin (TwoWire *theWire=&Wire)
 Initializes I2C and configures the breakout (call this function before doing anything else) More...
 
err_t setClockBuilderData (void)
 Configures the Si5351 with config settings generated in ClockBuilder. You can use this function to make sure that your HW is properly configure and that there are no problems with the board itself. More...
 
err_t setupPLL (si5351PLL_t pll, uint8_t mult, uint32_t num, uint32_t denom)
 Sets the multiplier for the specified PLL. More...
 
err_t setupPLLInt (si5351PLL_t pll, uint8_t mult)
 Sets the multiplier for the specified PLL using integer values. More...
 
err_t setupPLLSource (si5351PLL_t pll, si5351PLLSource_t source, si5351ClkinDiv_t clkinDiv=SI5351_CLKIN_DIV_1)
 Selects the reference source (XTAL or CLKIN) for the specified PLL, and optionally sets the CLKIN pre-divider. More...
 
err_t setupMultisynth (uint8_t output, si5351PLL_t pllSource, uint32_t div, uint32_t num, uint32_t denom)
 Configures the Multisynth divider, which determines the output clock frequency based on the specified PLL input. More...
 
err_t setupMultisynthInt (uint8_t output, si5351PLL_t pllSource, uint8_t div)
 Configures a Multisynth divider in integer mode. More...
 
err_t enableSpreadSpectrum (bool enabled)
 Enables or disables spread spectrum. More...
 
err_t enableOutputs (bool enabled)
 Enables or disables all clock outputs. More...
 
err_t readDeviceStatus (uint8_t *device_status)
 Read register 0 status byte. More...
 
err_t readStickyStatus (uint8_t *sticky)
 Read register 1 sticky byte. More...
 
err_t clearStickyStatus (void)
 Clear register 1 sticky flags. More...
 
err_t setInterruptMask (uint8_t mask)
 Write register 2 interrupt mask byte. More...
 
err_t setupRdiv (uint8_t output, si5351RDiv_t div)
 Configures the R divider for a given output channel. More...
 
err_t setFrequency (uint8_t output, si5351PLL_t pll, uint32_t freq)
 Automatically computes and applies the PLL multiplier, Multisynth divider and R divider needed to generate a desired output frequency on a given channel, then configures the hardware. This is a convenience wrapper over setupPLL(), setupMultisynth() and setupRdiv(). More...
 

Detailed Description

SI5351 class.

Constructor & Destructor Documentation

◆ Adafruit_SI5351()

Adafruit_SI5351::Adafruit_SI5351 ( void  )

SI5351 object.

Constructor

Member Function Documentation

◆ begin()

err_t Adafruit_SI5351::begin ( TwoWire *  theWire = &Wire)

Initializes I2C and configures the breakout (call this function before doing anything else)

Returns
ERROR_NONE
Parameters
theWireThe I2C (Wire) bus to use.

◆ setClockBuilderData()

err_t Adafruit_SI5351::setClockBuilderData ( void  )

Configures the Si5351 with config settings generated in ClockBuilder. You can use this function to make sure that your HW is properly configure and that there are no problems with the board itself.

Returns
ERROR_NONE

Running this function should provide the following output: Channel 0: 120.00 MHz Channel 1: 12.00 MHz Channel 2: 13.56 MHz

Note
This will overwrite all of the config registers!

◆ setupPLL()

err_t Adafruit_SI5351::setupPLL ( si5351PLL_t  pll,
uint8_t  mult,
uint32_t  num,
uint32_t  denom 
)

Sets the multiplier for the specified PLL.

Returns
ERROR_NONE
Parameters
pllThe PLL to configure, which must be one of the following:
  • SI5351_PLL_A
  • SI5351_PLL_B
multThe PLL integer multiplier (must be between 15 and 90)
numThe 20-bit numerator for fractional output (0..1,048,575). Set this to '0' for integer output.
denomThe 20-bit denominator for fractional output (1..1,048,575). Set this to '1' or higher to avoid divider by zero errors.

Configuration

fVCO is the PLL output, and must be between 600..900MHz, where:

fVCO = fXTAL * (a+(b/c))

fXTAL = the crystal input frequency a = an integer between 15 and 90 b = the fractional numerator (0..1,048,575) c = the fractional denominator (1..1,048,575)

NOTE: Try to use integers whenever possible to avoid clock jitter (only use the a part, setting b to '0' and c to '1').

See: http://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf

◆ setupPLLInt()

err_t Adafruit_SI5351::setupPLLInt ( si5351PLL_t  pll,
uint8_t  mult 
)

Sets the multiplier for the specified PLL using integer values.

Returns
ERROR_NONE
Parameters
pllThe PLL to configure, which must be one of the following:
  • SI5351_PLL_A
  • SI5351_PLL_B
multThe PLL integer multiplier (must be between 15 and 90)

◆ setupPLLSource()

err_t Adafruit_SI5351::setupPLLSource ( si5351PLL_t  pll,
si5351PLLSource_t  source,
si5351ClkinDiv_t  clkinDiv = SI5351_CLKIN_DIV_1 
)

Selects the reference source (XTAL or CLKIN) for the specified PLL, and optionally sets the CLKIN pre-divider.

Returns
ERROR_NONE
Parameters
pllThe PLL whose reference source is being configured:
  • SI5351_PLL_A
  • SI5351_PLL_B
sourceReference source for this PLL:
  • SI5351_PLL_SOURCE_XTAL (use the on-board crystal)
  • SI5351_PLL_SOURCE_CLKIN (use the external CLKIN pin)
clkinDivCLKIN pre-divider (reg 15, bits [7:6]). The CLKIN input to the PLLs must be in the 10..40 MHz range; pick a divider that brings your CLKIN signal into that window. Only written when source == SI5351_PLL_SOURCE_CLKIN, so that switching one PLL back to XTAL does not clobber the divider used by the other PLL.
  • SI5351_CLKIN_DIV_1 (default)
  • SI5351_CLKIN_DIV_2
  • SI5351_CLKIN_DIV_4
  • SI5351_CLKIN_DIV_8

Map (AN619)

Register 15 – PLL Input Source

Bit | Field ---—+--------------------------------— 7:6 | CLKIN_DIV[1:0] 5:4 | (reserved) 3 | PLLB_SRC (0 = XTAL, 1 = CLKIN) 2 | PLLA_SRC (0 = XTAL, 1 = CLKIN) 1:0 | (reserved)

Both PLLA_SRC and PLLB_SRC are single-bit fields, so we use Adafruit_BusIO_RegisterBits to read-modify-write only the affected bit and leave the other PLL's source (and the reserved bits) intact.

Returns
ERROR_NONE on success, or ERROR_I2C_TRANSACTION on a bus failure.

◆ setupMultisynth()

err_t Adafruit_SI5351::setupMultisynth ( uint8_t  output,
si5351PLL_t  pllSource,
uint32_t  div,
uint32_t  num,
uint32_t  denom 
)

Configures the Multisynth divider, which determines the output clock frequency based on the specified PLL input.

Returns
ERROR_NONE
Parameters
outputThe output channel to use (0..2)
pllSourceThe PLL input source to use, which must be one of:
  • SI5351_PLL_A
  • SI5351_PLL_B
divThe integer divider for the Multisynth output. If pure integer values are used, this value must be one of:
  • SI5351_MULTISYNTH_DIV_4
  • SI5351_MULTISYNTH_DIV_6
  • SI5351_MULTISYNTH_DIV_8 If fractional output is used, this value must be between 8 and 900.
numThe 20-bit numerator for fractional output (0..1,048,575). Set this to '0' for integer output.
denomThe 20-bit denominator for fractional output (1..1,048,575). Set this to '1' or higher to avoid divide by zero errors.

Clock Configuration

The multisynth dividers are applied to the specified PLL output, and are used to reduce the PLL output to a valid range (500kHz to 160MHz). The relationship can be seen in this formula, where fVCO is the PLL output frequency and MSx is the multisynth divider:

fOUT = fVCO / MSx

Valid multisynth dividers are 4, 6, or 8 when using integers, or any fractional values between 8 + 1/1,048,575 and 900 + 0/1

The following formula is used for the fractional mode divider:

a + b / c

a = The integer value, which must be 4, 6 or 8 in integer mode (MSx_INT=1) or 8..900 in fractional mode (MSx_INT=0). b = The fractional numerator (0..1,048,575) c = The fractional denominator (1..1,048,575)

Note
Try to use integers whenever possible to avoid clock jitter
For output frequencies > 150MHz, you must set the divider to 4 and adjust to PLL to generate the frequency (for example a PLL of 640 to generate a 160MHz output clock). This is not yet supported in the driver, which limits frequencies to 500kHz .. 150MHz.
For frequencies below 500kHz (down to 8kHz) Rx_DIV must be used, but this isn't currently implemented in the driver.

◆ setupMultisynthInt()

err_t Adafruit_SI5351::setupMultisynthInt ( uint8_t  output,
si5351PLL_t  pllSource,
uint8_t  div 
)

Configures a Multisynth divider in integer mode.

Returns
ERROR_NONE

Outputs 0..5 use the full fractional MultiSynths driven in integer mode (num=0, denom=1). Outputs 6 and 7 are hardware integer-only MultiSynths controlled by a single divider register each (regs 90/91), and are handled separately here.

Parameters
outputThe output channel to configure (0..7).
pllSourceThe PLL input source to use, which must be one of:
  • SI5351_PLL_A
  • SI5351_PLL_B
divThe integer divider. For CLK0..CLK5 use one of SI5351_MULTISYNTH_DIV_4/6/8. For CLK6/CLK7 use an even value in the range 6..254.
Returns
ERROR_NONE on success, otherwise an appropriate error code.

◆ enableSpreadSpectrum()

err_t Adafruit_SI5351::enableSpreadSpectrum ( bool  enabled)

Enables or disables spread spectrum.

Parameters
enabledWhether spread spectrum output is enabled
Returns
ERROR_NONE

◆ enableOutputs()

err_t Adafruit_SI5351::enableOutputs ( bool  enabled)

Enables or disables all clock outputs.

Parameters
enabledWhether output is enabled
Returns
ERROR_NONE

◆ readDeviceStatus()

err_t Adafruit_SI5351::readDeviceStatus ( uint8_t *  device_status)

Read register 0 status byte.

Reads the current device status register.

Parameters
device_statusPointer to where register 0 value will be stored.
Returns
ERROR_NONE on success, or an I2C/parameter error.

◆ readStickyStatus()

err_t Adafruit_SI5351::readStickyStatus ( uint8_t *  sticky)

Read register 1 sticky byte.

Reads the sticky interrupt status register.

Parameters
stickyPointer to where register 1 value will be stored.
Returns
ERROR_NONE on success, or an I2C/parameter error.

◆ clearStickyStatus()

err_t Adafruit_SI5351::clearStickyStatus ( void  )

Clear register 1 sticky flags.

Clears all sticky interrupt flags.

Returns
ERROR_NONE on success, or ERROR_I2C_TRANSACTION on failure.

◆ setInterruptMask()

err_t Adafruit_SI5351::setInterruptMask ( uint8_t  mask)

Write register 2 interrupt mask byte.

Sets the interrupt status mask register.

Parameters
maskRegister 2 bitmask where 1 masks (disables) an interrupt source.
Returns
ERROR_NONE on success, or ERROR_I2C_TRANSACTION on failure.

◆ setupRdiv()

err_t Adafruit_SI5351::setupRdiv ( uint8_t  output,
si5351RDiv_t  div 
)

Configures the R divider for a given output channel.

Parameters
outputEnables or disables output
divSet of output divider values (2^n, n=1..7)
Returns
ERROR_NONE

The R divider provides a final power-of-two division stage (1..128) after the Multisynth, extending the usable output range down to low frequencies. It is a 3-bit field occupying bits 4..6 of the channel's MSx_PARAMETERS_3 register. The shifted value is cached in lastRdivValue[] so setupMultisynth() can preserve it when rewriting the same parameter byte.

Parameters
outputThe output channel to configure (0..5).
divThe R divider value, one of:
  • SI5351_R_DIV_1
  • SI5351_R_DIV_2
  • SI5351_R_DIV_4
  • SI5351_R_DIV_8
  • SI5351_R_DIV_16
  • SI5351_R_DIV_32
  • SI5351_R_DIV_64
  • SI5351_R_DIV_128
Returns
ERROR_NONE on success, ERROR_INVALIDPARAMETER if the channel is out of range, or ERROR_I2C_TRANSACTION on a bus failure.

◆ setFrequency()

err_t Adafruit_SI5351::setFrequency ( uint8_t  output,
si5351PLL_t  pll,
uint32_t  freq 
)

Automatically computes and applies the PLL multiplier, Multisynth divider and R divider needed to generate a desired output frequency on a given channel, then configures the hardware. This is a convenience wrapper over setupPLL(), setupMultisynth() and setupRdiv().

Returns
ERROR_NONE
Parameters
outputThe output channel to use (0..2).
pllThe PLL to drive this output, either SI5351_PLL_A or SI5351_PLL_B. The caller selects the PLL; note that any other output already sharing this PLL will be retuned.
freqDesired output frequency in Hz (8000 .. 150000000).
Returns
ERROR_NONE on success, or ERROR_INVALIDPARAMETER if the requested frequency cannot be synthesised within the hardware limits.

Algorithm

The output is generated as:

fOUT = (fXTAL * (M)) / (D * R)

where fXTAL is the 25 MHz reference, M = a + b/c is the fractional PLL feedback multiplier, D is the (integer) Multisynth divider and R is the output R divider (1..128). To keep output jitter low the fractional part is placed entirely on the PLL while the Multisynth runs in integer mode.

The solver:

  1. Applies the R divider (doubling until the pre-R frequency is at least 600 kHz) so low frequencies stay within Multisynth range.
  2. Chooses the largest even Multisynth divider D that keeps the VCO within its 600..900 MHz lock range.
  3. Computes the fractional PLL multiplier M to hit the VCO target, using a denominator of 1048575 for maximum resolution.
Note
Frequencies above 150 MHz require the DIVBY4 path and are not yet supported; they return ERROR_INVALIDPARAMETER.
The output is left enabled/disabled exactly as it was; call enableOutputs() as needed.

The documentation for this class was generated from the following files: