SparkFun Clock Generator 5P49V60 (Qwiic) Hookup Guide

Pages
Contributors: Elias The Sparkiest
Favorited Favorite 2

Example 3: Integer and Fractional Divider Calculation

In this example, the division of the reference clock and the division for the frequency output dividers of each clock are set manually. Click on File > Examples > SparkFun Clock 5P49V60 Arduino Library > Example3_int_and_frac_divider_calc to open the example. It's especially beneficial to do this manually when applying fractional values to the frequency dividers. These values often have remainders that must be rounded and thus become the round-off error of your clock output in parts per million (ppm). Knowing this error value could be important to your application. To determine the division values requires some simple math. First, as in the previous two examples the correct libraries are imported and the microcontroller connects to the SparkFun Clock Generator using its' default address: 0x6A.

language:c
void setup(){

  Wire.begin();
  Serial.begin(115200);

  if (clockGen.begin() == true){
    Serial.println("Clock Generator Ready.");
  }
  else {
    Serial.println("Could not communicate with the SparkFun Clock Generator.");
    while(1);
  }

As in the previous sections the voltage controlled oscillator is set to to 1600MHz (1.6GHz). However, the register value must be calculated with some simple math. Our desired input (1600MHz) divided by the frequency of the reference clock (16MHz) equals the divider value 100. Easy Peezy Lemon Squeezy...

language:c
1600/16 = 100

Now we set the register values in code.

language:c
  // Fist, Setting the internal oscillator to a known value that makes for easy
  // division: 1600MHz. 1600MHz/16MHz = 100
  Serial.println("Setting Integer Divider.");
  clockGen.setPllFeedbackIntDiv(100);
  Serial.print("Integer Divider set to: ");
  uint16_t fbVal = clockGen.readPllFeedBackIntDiv();
  Serial.println(fbVal);

The formula for this calculation is in the example sketch's comments. Next the divider values for a frequency of 22MHz is calculated with a similar equation. Divide the voltage controlled oscillator's frequency from above (1600MHz) by two, then divide that value by the desired clock output (22MHz) to get the the clock's frequency output divider's value.

language:c
(1600/2)/22 = 36.3636

This divider value has a decimal and consequently will have two separate values to write to the SparkFun Clock Generator's registers. The first value is the integer portion (36) and the second value is the fractional portion (.36). The integer value can be set as is, but the fractional value first needs additional calculations to translate it into a value the SparkFun Clock Generator expects. To do that we multiply the fractional value by 224 and round that value to the closest integer. The decimal value is the clock output's rounding error in parts per million.

language:c
2^24 * .36 = 6039796.76
.76 = rounding error 
76/ppm

Now we write these two values to their registers.

language:c
  // Clock One -----------------------------------------------------
  // To get 16MHz Output = (1600MHz/2)/22MHz = 36.3636
  // Integer portion = 36
  // Fractional portion = .36 -> Need to convert to a HEX value
  // 2^24 * .36 = 6039796.76
  // Round the value to closest integer = 6039797
  clockGen.setIntDivOutOne(36);
  clockGen.setFractDivFodOne(6039797);
  Serial.print("FOD One Integer Divider: ");
  Serial.println(clockGen.readIntDivOutOne());
  Serial.print("FOD One Fractional Divider: ");
  Serial.println(clockGen.readFractDivFodOne());
  clockGen.muxPllToFodOne();
  // There are many OUTPUT modes available for each clock - this example uses
  // LVPECL (Low voltage Positive Emitter Coupled Logic) mode and terminates 
  // the clock with a 100Ohm resistance to GND.
  clockGen.clockOneConfigMode(LVPECL_MODE);
  clockGen.clockOneControl(ENABLE);
  // --------------------------------------------------------------

}

void loop(){
  delay(1000); 
}

The integer portion is set with clockGen.setIntiDivOutOne(36) and the fractional portion is set with clockGen.setFractDivOut(6039796). These two values are then read back with their respective "read" functions: clockGen.readIntDivOutOne() and clockGen.readFractDivFodOne(). Next we pipe (multiplex) the VCO frequency to the frequency output divider we just set, set the signal type, and enable the clock. In the previous examples, all of the math was done behind the scenes but here doing the math may prove beneficial when needing to know the rounding error.