This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LMX2571: LMX2571 SPUR-B-GONE ALGORITHM

Part Number: LMX2571
Other Parts Discussed in Thread: CODELOADER

Hello,

We'have been using LMX2571 in our civil projects and now we're struggling with some spur issues.
We added spur-b-gone algorithm to our own codes. In the app note below, it says, "The Spur-b-Gone button on CodeLoader works by iterating through all valid PLL_R_PRE, PLL_R and MULT values and calculates an index for each one. Then it chooses the highest (best) index.". However, the highest index doesn't give the best solution for some output frequencies.

www.ti.com/.../snaa289.pdf

As you can see in the table below, the highest index is 17,5 for our case and Pre_R, Mult and Post_R are 1,5 and 9 respectively. But, TICs Pro chooses the first one; 1,5 and 4. So, how does TICs Pro decide that is the best index?

  • Fref = 24 MHz
  • Fout = 384.2 MHz
  • Fvco = 4610.4 MHz

Kind regards,

Gul Yesa YILDIRIM

  • Hello,

    Thanks for posting on E2E. I have assigned your post to the responsible engineer.

    Kind regards,
    Lane Boyd
  • Gul,

    The Spur-b-Gone algorithm was intended as a general guideline on how to avoid spurs. The way that the index is calculated is more of a rule of thumb, sort of an arbitrary choice. It's probably a difference in the way the index is calculated.

    Perhaps the easiest way to resolve this is just show you the code for the Spur-b-Gone from TICSPro.

    Regards,
    Dean


    Below is the routine that is run when the SpurBGone button is pressed on TICSPro ...

    def btn_SpurBGone_Update():
    Fosc=Fosc_FREQ.dValue
    Fpd = Fpd_FREQ.dValue
    Fvco=Fvco_FREQ.dValue
    Fnum=flexPLL_NUM.iValue
    OldFden = flexPLL_DEN.iValue
    OldMult = flexMULT.iValue


    OldTotalR = int(Fosc * OldMult / Fpd)

    MultInMin = 10
    MultInMax = 30
    MultOutMin = 60
    MultOutMax = 130

    FpdMin = Fpd * 0.7
    FpdMax = Fpd * 1.4
    if (FpdMax > 140):
    FpdMax = 140

    BestIBSMetric = 0.00000000001

    FpdMin = Fpd * 0.7
    FpdMax = Fpd * 1.4
    if (FpdMax > 140):
    FpdMax = 140

    BestIBSMetric = 0.00000000001
    FoundBest = False

    for Mult in range(1,16):
    if (FoundBest==True):
    break;
    if (Mult==1):
    PLL_R_PRE_min = 1
    PLL_R_PRE_max = 1
    else:
    PLL_R_PRE_min = int(math.ceil(Fosc / MultInMax))
    if (Fosc > MultInMax*PLL_R_PRE_min):
    PLL_R_PRE_min = PLL_R_PRE_min + 1

    PLL_R_PRE_max = int(Fosc / MultInMin)
    if (Fosc / PLL_R_PRE_max < MultInMin):
    PLL_R_PRE_max = PLL_R_PRE_max - 1


    for PLL_R_PRE in range(PLL_R_PRE_min,PLL_R_PRE_max+1):
    MultOut = Fosc / PLL_R_PRE * Mult
    if (Mult==1) or ((MultOut > MultOutMin - 0.0001) and (MultOut < MultOutMax - 0.0001) ):
    for PLL_R in range(1,10):
    Fpd = Mult * Fosc / (PLL_R_PRE * PLL_R)

    if (Fpd<FpdMin):
    break;

    if (Fpd<FpdMax):
    PLL_N = 2 * int(0.5+ 1.0*math.floor(Fvco / Fpd / 2) )

    IBS = math.fabs(Fvco - PLL_N * Fpd)
    if (IBS > math.fabs(Fpd - IBS) ):
    IBS = math.fabs(Fpd - IBS)

    IBS2 = math.fabs(Fpd / 2 - IBS)


    if (IBS < IBS2):
    IBSMetric = IBS
    else:
    IBSMetric = IBS * (40 * IBS2) / (IBS + 40 * IBS2 + 0.000000000001)


    if (IBS < 0.000001):
    # Best Case Scenario, integer Channel
    BestIBS = 0
    BestMult = Mult
    BestPreR = PLL_R_PRE
    BestPLL_R = PLL_R
    BestFpd = Fpd
    BestIBS2 = IBS2
    BestIBSMetric = IBS2
    FoundBest = True
    elif (IBS2 > 0.000001) and (IBSMetric > BestIBSMetric):
    # Decide based on weighted metric
    BestIBS = IBS
    BestMult = Mult
    BestPreR = PLL_R_PRE
    BestPLL_R = PLL_R
    BestFpd = Fpd
    BestIBS2 = IBS2
    BestIBSMetric = IBSMetric


    # Decide if it is necessary to update the fractional Denominator
    Fden = OldFden

    if (OldMult % BestMult > 0):

    # Find the Denominator of the original fraction in reduced form
    i=2
    while (i<math.sqrt(Fden*1.0) ):
    if (Fnum%i==0) and (Fden%i==0):
    Fden = Fden/i
    Fnum = Fnum/i
    else:
    i=i+1

    # X and Y are Mult* x TotalR
    X = BestMult * OldTotalR
    Y = OldMult * BestPreR * BestPLL_R


    while (i<math.sqrt(X*1.0) ):
    if (X%i==0) and (X%i==0):
    X = X/i
    Y = Y/i
    else:
    i=i+1

    # Now find the smallest possible simplified denominator
    if (X*Fden > 16777215):
    Fden = OldFden
    else:
    Fden = Fden*X

    # Now try to Scale Fden back to something close to the original value
    GCD = int(0.5+OldFden*1.0 / Fden)
    if (GCD<1):
    GCD=1
    Fden=Fden*GCD

    flexPLL_R_PRE.iValue = BestPreR
    flexMULT.iValue=BestMult
    flexPLL_R.iValue=BestPLL_R
    Fpd_FREQ.dValue=BestFpd
    flexPLL_DEN.iValue=Fden
    Fvco_FREQ_Update()
    if (GetActivePLL()==1):
    PLL_R_PRE_F1.iValue=flexPLL_R_PRE.iValue
    MULT_F1.iValue=flexMULT.iValue
    PLL_R_F1.iValue=flexPLL_R.iValue
    Fpd_F1_FREQ.dValue=Fpd_FREQ.dValue
    PLL_N_F1.iValue=flexPLL_N.iValue
    PLL_NUM.iValue=flexPLL_NUM.iValue
    PLL_DEN_F1.iValue=flexPLL_DEN.iValue
    Fvco_F1_FREQ.dValue=Fvco_FREQ.dValue
    else:
    PLL_R_PRE_F2.iValue=flexPLL_R_PRE.iValue
    MULT_F2.iValue=flexMULT.iValue
    PLL_R_F2.iValue=flexPLL_R.iValue
    Fpd_F2_FREQ.dValue=Fpd_FREQ.dValue
    PLL_N_F2.iValue=flexPLL_N.iValue
    PLL_NUM.iValue=flexPLL_NUM.iValue
    PLL_DEN_F2.iValue=flexPLL_DEN.iValue
    Fvco_F2_FREQ.dValue=Fvco_FREQ.dValue
  • Hi Dean,

    Thanks a lot for your quick reply. This is really helpful for us.
    Regards,

    Yesa