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.

LMX2820: Spur-b-gone Algorithm code

Part Number: LMX2820
Other Parts Discussed in Thread: CODELOADER, LMX2571

Hi

I'm interested in using the programmable input multiplier for minimising boundary spurs as given in Dean Banerjee's application note SNAA289.

Looking at other forum posts, it appears to have been previously bundled as a python script with Codeloader and TICS PRO, but doesn't appear to be anywhere in my installation files.

Would it be possible to provide a copy code of Dean's algorithm as it may have a place in a project I'm working on, assuming it provides some benefit for this part and acknowledging that it is an estimate?

Many Thanks

Ian Southgate

  • Ian,

    I am glad that you like the Spur-b-Gone code.  The general strategy is to avoid integer boundary spurs as a first priority. But also, when you are close to, but not exactly near a fraction of 1/2, you also get higher spurs, although less severe.

    You can open the LMX2571.py file and find this code as well.

    Also realize that for any TICSPro part, you can mouse over boxes and see the name.

    For instance "Fosc_FREQ" is the OSCin box.  "Fosc_FREQ.dValue" is this value expressed as a double

    This is in python, but the copy and paste ruined the indent, but I think that you can hopefully get the idea.

    Regards,
    Dean

    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
    flexPLL_NUM.iValue=Fnum
    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_F1.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_F2.iValue=flexPLL_NUM.iValue
    PLL_DEN_F2.iValue=flexPLL_DEN.iValue
    Fvco_F2_FREQ.dValue=Fvco_FREQ.dValue

  • Thanks for replying with your algorithm Dean. The python file you mentioned doesn't appear to be bundled with TICSPro anymore. I noticed in another one of your replies related to this topic that there should be a "Configuration" folder, but there doesn't appear to be one anywhere within the directory and sub-folders (see below).

    Is there anything else that I could be missing without it?

    Many Thanks.

  • Ian,

    We separate the configurations directory into C:\ProgramData\Texas Instruments\TICS Pro.

    Regards,

    Derek Payne

  • Thanks for that Derek. Didn't think to look for it there.

  • Hi Ian,

    since your question is resolved I'm closing this thread. Please post again if you have further questions.

    regards,

    Julian