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.

LMK05028: LMK05028 dynamic clock correction

Part Number: LMK05028

Hi,

Which LMK05028 register I can use for dynamic clock correction.

Could you please tell us the calculation steps to be used for dynamic clock correction.

Regards

Anji

Anji

  • Hello Anji,

    Can you please clarify what you mean by dynamic clock correction? Are you asking about our DCO mode?

    Regards,

    Kia Rahbar

  • Yes.
    1. How to calculate step size from ppb? 
    2. Is these below two registers used for adjusting the clock?
    DPLLy_FDEV, DPLLy_FDEV_REG_UPDATE
    3. Is there any GPIO registers to enable before clock adjustment.
    4. Please share us a psudo code for clock adjustment.

    Regards

    Anji

  • Hello Anji,

    1. Section 9.4.4.1 in the data sheet shows the equation for calculating the step size from ppb.

    2. Yes for adjusting the clock, the DPLLy_FDEV sets the step size and the DPLLy_FDEV_REG_UPDATE increments or decrements that step size from the numerator. Also please note that the DPLLy_FDEV_EN must be high for the DCO mode to be enabled and the DPLLy_DCO_SEL_REF_TCXOB must be set to select between TCXO DCO mode and REF DCO mode.

    3. The DCO mode can be operated using GPIO pins, but I would recommend using the register method. The register method only requires the setting of the 4 controls described in number 2 above.

    4. The TICS Pro GUI has a user friendly interface that can be used to better understand how the DCO functions.

    Basically to perform a frequency adjustment, the sequence is as follows:

    1. Enable DPLLy's DCO feature by setting the DPLLy_FDEV_EN high.

    2. Select whether the DCO adjustment needs to be TCXO mode or REF mode by setting DPLLy_DCO_SEL_REF_TCXOB.

    3. Write the step size required to the DPLLy_FDEV registers.

    4. Set the DPLLy_FDEV_REG_UPDATE low for an increment and high for a decrement.

    Regards,

    Kia Rahbar

  • Hi ,

    Based on above procedure, I implemented C function. Tried to test, its not working. Could you please check below code snippet. Let me know if i am missing anything.

    int lmk_clock_control(int64_t ppb) /*ppb value will come from ptp4l */

    {
    int64_t step_val = 0;
    uint64_t DENref = 1099511627776;
    uint64_t fIN = 390625000;
    uint64_t fVCO = 5156250000;
    int Rin = 1, P1_PLL = 4, PR_ref = 4;
    uint8_t data1,data2,data3,data4,data5;

    /*calculate step size */
    step_val = (ppb/1000000000) * DENref / (fIN/Rin) * fVCO / (P1_PLL*PR_ref);

    //byte extraction
    data1=((uint8_t)(step_val & 0x0000000000ff));
    data2=((uint8_t)((step_val & 0x00000000ff00)>>8));
    data3=((uint8_t)((step_val & 0x000000ff0000)>>16));
    data4=((uint8_t)((step_val & 0x0000ff000000)>>24));
    data5=((uint8_t)((step_val & 0x00ff00000000)>>32));

    /* Enable DCO feature for DPLL1 and DPPL2 */
    /* Select DCO adjustment mode TCXO-DPLL->0h, REF-DPLL->1h */
    if(i2c_write(&lmk, 0x0244, 0x5, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x0244);
    return -1;
    }
    if(i2c_write(&lmk, 0x0245, 0x5, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x0245);
    return -1;
    }

    /* Write step_val into DPLL1_FDEV registers */
    if(i2c_write(&lmk, 0x024A, data1, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x024A);
    return -1;
    }
    if(i2c_write(&lmk, 0x0249, data2, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x0249);
    return -1;
    }
    if(i2c_write(&lmk, 0x0248, data3, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x0248);
    return -1;
    }
    if(i2c_write(&lmk, 0x0247, data4, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x0247);
    return -1;
    }
    if(i2c_write(&lmk, 0x0246, data5, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x0246);
    return -1;
    }

    /* Write DPLL1 Update register */
    if(i2c_write(&lmk, 0x024B, 0x0, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x024B);
    return -1;
    }

    /* Write step_val into DPLL2_FDEV registers */
    if(i2c_write(&lmk, 0x0250, data1, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x0250);
    return -1;
    }
    if(i2c_write(&lmk, 0x024F, data2, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x024F);
    return -1;
    }
    if(i2c_write(&lmk, 0x024E, data3, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x024E);
    return -1;
    }
    if(i2c_write(&lmk, 0x024D, data4, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x024D);
    return -1;
    }
    if(i2c_write(&lmk, 0x024C, data5, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x024C);
    return -1;
    }


    /* Write DPLL2 Update register */
    if(i2c_write(&lmk, 0x0251, 0x0, 0) < 0) {
    printf("I2C Write error: address %x\n", 0x024B);
    return -1;
    }

    }

    /*Example calling for testing purpose */

    lmk_clock_control(5678227331);
    lmk_clock_control(10000000000);
    lmk_clock_control(5678228331);
    lmk_clock_control(10000090000);

    Regards

    Anji

  • Hello Anji,

    You need to write the FDEV registers in the opposite order. The FDEV will take effect when the LSB is written. So for DPLL1, FDEV should be written to 0x0246 first and to 0x024A last. Same sequence applies to DPLL2.

    Regards,

    Kia Rahbar

  • Hi Kia Rahbar,

    How can i select FINC/FDEC?? Lets assume I calculated step value, based on that value how to select FINC/FDEC?
    could you please help me out?

    Regards

    Anji

  • Hello Anji,

    After you have written to the DPLLy_FDEV register, set the DPLLy_FDEV_REG_UPDATE low for an increment and high for a decrement. For DPLL1, DPLL1_FDEV_REG_UPDATE is bit 0 of register 0x24B. For DPLL2, DPLL2_FDEV_REG_UPDATE is bit 0 of register 0x251.

    Regards,

    Kia Rahbar

  • Hi Kia Rahbar,

    I have following doubts regarding TICS Pro and clock adjustments.

    1. Is Target ppb from TICS pro software is same as ptp4l ppb??

    2. I am receiving ppb value from ptp4l as 2149, using this value, calculated DPLLy_FDEV value is 152,291,034. If I write this value PTP getting disconnected due to high offset correction. whats wrong I am doing here?

    3. Actually we will receive positive and negative ppb values from ptp4l, but TICS Pro software wont accept ppb (target ppb box) value as negative. why??

    Could you please help me on understanding on this ppb.

    Regards

    Anji

  • Hello Anji,

    1. The target ppb is the ppb adjustment you want to make to your output clock signal. For example, writing a 10 ppb target and then pressing the increment button will result in a 10 ppb addition to the APLL numerator and therefore the output clock will be increased 10 ppb as well.

    2. When the ptp4l returns a ppb offset, you will be that many ppb off of your target frequency. Therefore using that ppb offset, calculate the DPLLy_FDEV and then either preform a increment or decrement based off of the direction in ppb offset you are. Please ensure you are making the adjustment in the correct direction.

    3. To make a negative adjustment you must press the decrement button. The ppb value will always be entered as a positive number and then the increment and decrement buttons determine whether the ppb will be subtracted or added to the APLL numerator to preform the adjustment.

    Also please remember that the DPLLy_FDEV_REG_UPDATE control determines whether an increment or decrement will be occurring.

    Regards,

    Kia Rahbar

  • Hi Kia Rahbar,

    I implemented correction as per procedure mentioned in document and your suggestions, tried to test but its not correcting because of high FDEV value. Could you please review the attached code once. Let me know your comments.

    Regards

    Anji

    s32 lmk05028_freq_control(s64 ppb) /*ppb value receiving from ptp4l as 2149 as initially*/
    {
            s64 step_val = 0;
            u64 DENref = 1099511627776;
            u64 fIN = 10000000;//390625000;
            u64 fVCO = 5156250000;
            u32 Rin = 1, P1_PLL = 4, PR_ref = 2;
            u8 data1,data2,data3,data4,data5;
            struct i2c_adapter *i2c_adap;
            struct i2c_board_info i2c_info;
            static struct i2c_client *i2c_cli;
            int adapter_nr = 1; /* I2C device number */
            int addr = 0x60; /* I2C address */
            u64 value_1, value_2, value_3;
            s64 value_4;
            s32 s32_remainder;
            u32 u32_remainder;
    
            value_1 = div_u64_rem(fVCO, (P1_PLL*PR_ref), &u32_remainder);
            value_2 = 10000000;//div_u64_rem(fIN, Rin, &u32_remainder);
            value_3 = div64_u64(DENref,value_2);
            value_4 = div_s64_rem(ppb,1000000000,&s32_remainder);
    
            step_val = value_4 * value_3 * value_1;     
           /*calculate step size */
            /*step_val = (ppb/1000000000) * DENref / (fIN/Rin) * fVCO / (P1_PLL*PR_ref);*/
    
            //byte extraction
            data1=((uint8_t)(step_val    &   0x0000000000ff));
            data2=((uint8_t)((step_val   &   0x00000000ff00)>>8));
            data3=((uint8_t)((step_val   &   0x000000ff0000)>>16));
            data4=((uint8_t)((step_val   &   0x0000ff000000)>>24));
            data5=((uint8_t)((step_val   &   0x00ff00000000)>>32));
    
            i2c_adap = i2c_get_adapter(adapter_nr);
            memset(&i2c_info, 0, sizeof(struct i2c_board_info));
            strlcpy(i2c_info.type, "lmk05028", I2C_NAME_SIZE);
            i2c_info.addr = addr;
             if(i2c_cli == NULL)
                    i2c_cli = i2c_new_device(i2c_adap,&i2c_info);
    
            /* Enable DCO feature for DPLL1 and DPPL2 */
            /* Select DCO adjustment mode TCXO-DPLL->0h, REF-DPLL->1h */
            if(lmk05028_write(i2c_cli, 0x0244, 0x5) < 0) {
                    printk("LMK:I2C Write error: address %x\n", 0x0244);
                    return -1;
            }
            
            /* Write step_val into DPLL1_FDEV registers */
            if(lmk05028_write(i2c_cli, 0x0246, data5) < 0) {
                    printk("LMK:I2C Write error: address %x\n", 0x0246);
                    return -1;
            }
            if(lmk05028_write(i2c_cli, 0x0247, data4) < 0) {
                    printk("LMK:I2C Write error: address %x\n", 0x0247);
                    return -1;
            }
            if(lmk05028_write(i2c_cli, 0x0248, data3) < 0) {
                    printk("LMK:I2C Write error: address %x\n", 0x0248);
                    return -1;
            }
            if(lmk05028_write(i2c_cli, 0x0249, data2) < 0) {
                    printk("LMK:I2C Write error: address %x\n", 0x0249);
                    return -1;
            }
            if(lmk05028_write(i2c_cli, 0x024A, data1) < 0) {
                    printk("LMK:I2C Write error: address %x\n", 0x024A);
                    return -1;
            }
    
            if(ppb > 0)
            {
                    /* Write DPLL1 Update register for increment*/
                    if(lmk05028_write(i2c_cli, 0x024B, 0x0) < 0) {
                            printk("LMK:I2C Write error: address %x\n", 0x024B);
                            return -1;
                    }
                    printk("RSYS:AFter update register write for positive ppb\n");
            }
            else
            {
                    /* Write DPLL1 Update register decrement */
                    if(lmk05028_write(i2c_cli, 0x024B, 0x1) < 0) {
                            printk("LMK:I2C Write error: address %x\n", 0x024B);
                            return -1;
                    }
                    printk("RSYS:AFter update register write for negitive ppb\n");
            }
            return 0;
    }
    

  • Hello Anji,

    Unfortunately, I will not be able to support technical questions on software that is not our TICS Pro software. My recommendation is to either contact SMARTModular (a 3rd party programming house) to assist with your device programming or program the device using the TICS Pro software:   https://www.ti.com/tool/TICSPRO-SW.

    Regards,

    Kia Rahbar