My Project
Files | Functions
MrfCommon

Files

file  mrfFracSynth.c
 Support routines for the Micrel SY87739L Fractional-N Synthesizer.
 

Functions

epicsShareExtern epicsStatus mrfSetEventClockSpeed (epicsFloat64 InputClockSpeed, epicsUInt32 InputControlWord, epicsFloat64 ReferenceFreq, epicsFloat64 *OutputClockSpeed, epicsUInt32 *OutputControlWord, epicsInt32 PrintFlag)
 
epicsShareExtern epicsUInt32 FracSynthControlWord (epicsFloat64 DesiredFreq, epicsFloat64 ReferenceFreq, epicsInt32 debugFlag, epicsFloat64 *Error)
 
epicsShareExtern epicsFloat64 FracSynthAnalyze (epicsUInt32 ControlWord, epicsFloat64 ReferenceFreq, epicsInt32 PrintFlag)
 

Detailed Description

Function Documentation

◆ mrfSetEventClockSpeed()

epicsShareExtern epicsStatus mrfSetEventClockSpeed ( epicsFloat64  InputClockSpeed,
epicsUInt32  InputControlWord,
epicsFloat64  ReferenceFreq,
epicsFloat64 *  OutputClockSpeed,
epicsUInt32 *  OutputControlWord,
epicsInt32  PrintFlag 
)
Description:

This routine will determine the system's event clock speed (in Megahertz) and/or the value for the fractional synthesizer control word given at least one of these two values.

Function:

If the InputClockSpeed parameter is specified (not zero), the routine will compute the value of the fractional synthesizer control word to produce that frequency.

If the InputControlWord parameter is specified (not zero), the routine will check the control word for programming errors and return the actual frequency (in Megahertz) produced by that control word.

If neither parameter is specified, the routine will output a default event clock frequency and a default control word.

If both parameters are specified, the routine will make sure the frequency generated by the control word is within 100 ppm of the desired clock speed.

If no errors are encountered, the routine will return both the final event clock speed and the fractional synthesizer control word. If errors are encountered, both output parameters will contain zero.

Parameters
InputClockSpeed= (input) Desired event clock speed in Megahertz. 0.0 means no clock speed specified.
InputControlWord= (input) Desired value for the fractional synthesizer control word. 0 means no control word specified.
ReferenceFreq= (input) SY87739L input reference frequency in MegaHertz.
OutputClockSpeed= (output) The input or computed value for the event clock speed
OutputControlWord= (output) The input or computed value for the fractional synthesizer control word.
PrintFlag= (input) Flag to control output messages. Output levels correspond to the DEBUGPRINT output levels:
DP_NONE (0) = Only display errors that prevent us from returning the event clock speed and the control word.
DP_ERROR (2) = Display any programming errors detected in the control word.
DP_WARN (3) = Display warning messages such as the one warning that we are using the default event clock frequency.
DP_INFO (4) = Display the value of the computed control word, its actual output frequency, and the error (in ppm) between the desired and actual frequencies.
DP_DEBUG (5) = Display the actual values of the fields in the control word, along with the constituent parts of the output frequency (VCO frequency, correction term, reference freq.)
Returns
OK if we were able to return both an event clock frequency and a fractional synthesizer control word.
ERROR if we could not.

References FracSynthAnalyze(), and FracSynthControlWord().

◆ FracSynthControlWord()

epicsShareExtern epicsUInt32 FracSynthControlWord ( epicsFloat64  DesiredFreq,
epicsFloat64  ReferenceFreq,
epicsInt32  debugFlag,
epicsFloat64 *  Error 
)
Description:

This routine will take a desired output frequency (expressed in MegaHertz)and a reference frequency (also expressed in MegaHertz) and create a control word for the Micrel SY877391L Fractional-N Synthesizer chip that will produce an output frequency as close as possible to the desired frequency. The routine also returns an error value (expressed in parts-per-million) between the actual output frequency and the desired output frequency.

Function:

A complete description of how the Micrel SY87739L chip works is way beyond the scope of a function header comment. The reader who wants a complete understanding of what this routine is doing should refer to the Micrel SY87739L product description sheet available at: www.micrel.com

A brief description of the chip programming is useful, however, and is provided here:

The output frequency is described by the following formulae:

F(out) = F(vco) / PostDiv

where F(vco) is the frequency generated by a voltage-controlled oscillator, and PostDiv is a frequency divider value between 1 and 60 (not inclusive). The PostDiv value must be chosen so that the VCO frequency is within its operating range of 540 - 729 MHz. The VCO frequency is given by:

F(vco) = C * F(frac) * F(ref)

where C is a "Correction Factor" (also referred to as the "wrapper correction" in the documentation0 expressed as (N/M) where N and M are from the set {14, 15, 16, 17, 18, 31, 32}. Not all combinations, however, are legal. F(frac) is the fractional frequency produced by a fractional-N P/P-1 divider circuit. F(ref) is the input reference frequency to the Micrel chip. Typically it is 27 MHz, although in the MRF timing boards it is 24 MHz. The fractional frequency is basically a multiplier for the reference frequency. It is expressed as a rational number with a divisor less than 32 and is given by:

F(frac) = P - (Q(p-1) / (Q(p) + Q(p-1)))

where P is the integer part of the fractional frequency, Q(p) is the number of clock periods where the reference clock is divided by P and Q(p-1) is the number of clock periods where the reference clock is divided by P-1. A hardware implementation of Bresenham's algorithm is used to evenly space out the P and P-1 divisions. Beyond this, you'll have to read the manual for further details.

The routine works by doing an exhaustive search (with some optimizations) of the parameter space {C, Q(p), Q(p-1), PostDiv}. P is predetermined by F(out) and PostDiv, so it does not need to be searched. The Q(p), Q(p-1) search is accomplished by searching all the numerators for the denominator (Q(p) + Q(p-1)) that produce a fraction less than 1. Although an exhaustive search is not the most efficient way to optimize a 4-parameter space, it turns out that the dimensions of each parameter are not that big. PostDiv only has 31 unique values, and we only search the values that produce a valid F(vco). When you rule out duplications and illegal combinations it turns out that C only has 22 valid values, and if you arrange them in ascending order, you only have to search until the error value stops decreasing. For Q(p) and Q(p-1), we only have to search 31 denominators and for each denominator we only have to search n-1 numerators. This gives us n(n+1)/2, or 465 (for n=30) possible numerator/denominator pairs to search, although we stop immediately if we find a denominator that exactly divides the desired fractional frequency.

If we search 22 correction factors for each numerator/denominator pair, and we repeat the process for each of 31 possible PostDiv values, we get a worst case number of 317,130 possible combinations. In practice, the VCO frequency limitations (between 540 and 729 Megahertz) will usually eliminate most of the 31 possible PostDiv values. Given the other optimizations mentioned above, the worst case number is a pretty pathological example. In most cases the number of combinations actually searched will be far less than that.

Parameters
DesiredFreq= (input) Desired output frequency in MegaHertz.
ReferenceFreq= (input) SY87739L input reference frequency in MegaHertz.
debugFlag= (input) Flag for debug output. If the value is 4 (DP_INFO) or higher, the routine will print the value of the control word and the frequency actually produced.
Error= (output) Error between the actual output frequency and the desired output frequency. Expressed in parts-per-million.
Implicit Inputs:
CorrectionList = (CorrectionStruct) List of all valid correction factors and their control-word encodings.
PostDivideList = (PostDivideStruct) List of valid post-divide values and their control-word encodings.
Returns
Returns the SY87739L Control Word for the desired frequency.

Referenced by EVRMRM::clockSet(), and mrfSetEventClockSpeed().

◆ FracSynthAnalyze()

epicsShareExtern epicsFloat64 FracSynthAnalyze ( epicsUInt32  ControlWord,
epicsFloat64  ReferenceFreq,
epicsInt32  PrintFlag 
)
Description:
This routine will take a bit pattern representing an SY87739L fractional synthesizer control word, break it down into its constituent parts, and return the effective output frequency (in MegaHertz) that the control word will generate. Depending on the value of the "PrintFlag" parameter, it will also display the constituent parts of the the control word and the resulting values that make up the output frequency, and analyze the control word for programming errors.
Parameters
ControlWord= (input) The control word bit pattern to analyze.
ReferenceFreq= (input) SY87739L input reference frequency in MegaHertz.
PrintFlag= (input) Flag to control output messages. Output levels correspond to the DEBUGPRINT output levels:
DP_NONE (0) = No printed output, just return the effective output frequency.
DP_ERROR (2) = Display any programming errors detected in the control word
DP_DEBUG (5) = Display the actual values of the fields in the control word, along with the constituent parts of the output frequency (VCO frequency, correction term, reference freq.)
Implicit Inputs:
CorrectionValList = (CorrectionValStruct) Array to translate correction term components from their coded values to actual values and classes. PostDivideValList = (epicsInt32) Array to translate the post-divider field from its coded value to its actual value.
Returns
Returns the output frequency generated by the control word.
Returns 0.0 if the analysis discovered programming errors in the control word.

Referenced by EVRMRM::clockSet(), and mrfSetEventClockSpeed().