XilinxProcessorIPLib/drivers/v_hdmitxss1/examples/xhdmi_example/si5324drv.c
int Si5324_CalcFreqSettings(u32 ClkInFreq, u32 ClkOutFreq,
                        u8  *N1_hs, u32 *NCn_ls,
                        u8  *N2_hs, u32 *N2_ls,
                        u32 *N3n,   u8  *BwSel) {
    /* TBD */
    si5324_settings_t settings;
    int result;

    settings.fin = (u64)ClkInFreq  << 28; // 32.28 fixed point
    settings.fout= (u64)ClkOutFreq << 28; // 32.28 fixed point
    settings.best_delta_fout = settings.fout; // High frequency error to start with

    // Calculate some limits for N1_HS * NCn_LS and for N3 base on the input
    // and output frequencies.
    settings.n1_min = (int)(SI5324_FOSC_MIN / ClkOutFreq);
    if (settings.n1_min < SI5324_N1_HS_MIN * SI5324_NC_LS_MIN) {
        settings.n1_min = SI5324_N1_HS_MIN * SI5324_NC_LS_MIN;
    }
    settings.n1_max = (int)(SI5324_FOSC_MAX / ClkOutFreq);
    if (settings.n1_max > SI5324_N1_HS_MAX * SI5324_NC_LS_MAX) {
        settings.n1_max = SI5324_N1_HS_MAX * SI5324_NC_LS_MAX;
    }
    settings.n3_min = ClkInFreq / SI5324_F3_MAX;
    if (settings.n3_min < SI5324_N3_MIN) {
        settings.n3_min = SI5324_N3_MIN;
    }
    settings.n3_max = ClkInFreq / SI5324_F3_MIN;
    if (settings.n3_max > SI5324_N3_MAX) {
        settings.n3_max = SI5324_N3_MAX;
    }
    // Find a valid oscillator frequency with the highest setting of N1_HS
    // possible (reduces power)
    for (settings.n1_hs = SI5324_N1_HS_MAX; settings.n1_hs >= SI5324_N1_HS_MIN; settings.n1_hs--) {
        if (SI5324_DEBUG) {
            xil_printf("Trying N1_HS = %d.\r\n", settings.n1_hs);
        }
        result = Si5324_CalcNclsLimits(&settings);
        if (result) {
            if (SI5324_DEBUG) {
                xil_printf("\tNo valid settings for NCn_LS.\r\n");
            }
            continue;
        }
        result = Si5324_FindNcls(&settings);
        if (result) {
            // Best possible result found. Skip the rest of the possibilities.
            break;
        }
    }
    if (settings.best_delta_fout /= settings.fout) {
        if (SI5324_DEBUG) {
            xil_printf("Si5324: ERROR: No valid settings found.\r\n");
        }
        return SI5324_ERR_FREQ;
    }
    if (SI5324_DEBUG) {
        xil_printf("Si5324: Found solution: fout = %dHz.\r\n",
                   (u32)(settings.best_fout >> 28));
    }

    // Post processing: convert temporary values to actual register settings
    *N1_hs  = (u8)settings.best_n1_hs - 4;
    *NCn_ls =     settings.best_nc_ls - 1;
    *N2_hs  = (u8)settings.best_n2_hs - 4;
    *N2_ls  =     settings.best_n2_ls - 1;
    *N3n    =     settings.best_n3    - 1;
    /* How must the bandwidth selection be determined? Not all settings will
     * be valid.
    refclk        2, 0xA2,  //              BWSEL_REG=1010 (?)
    free running  2, 0x42,  //              BWSEL_REG=0100 (?)
    */
    *BwSel  = 6; //4
    return SI5324_SUCCESS;
}
/*****************************************************************************/
/**
 * Calculate the frequency settings for the desired output frequency.
 *
 * @param    ClkInFreq contains the frequency of the input clock.
 * @param    ClkOutFreq contains the desired output clock frequency.
 * @param    N1_hs  will be set to the value for the N1_HS register.
 * @param    NCn_ls will be set to the value for the NCn_LS register.
 * @param    N2_hs  will be set to the value for the N2_HS register.
 * @param    N2_ls  will be set to the value for the N2_LS register.
 * @param    N3n    will be set to the value for the N3n register.
 * @param    BwSel  will be set to the value for the BW_SEL register.
 *
 * @return   SI5324_SUCCESS for success, SI5324_ERR_FREQ when the requested
 *           frequency cannot be generated.
 * @note     Private function.
 *****************************************************************************/
Calculate the frequency settings for the desired output frequency.
@param    ClkInFreq contains the frequency of the input clock.
@param    ClkOutFreq contains the desired output clock frequency.
@param    N1_hs  will be set to the value for the N1_HS register.
@param    NCn_ls will be set to the value for the NCn_LS register.
@param    N2_hs  will be set to the value for the N2_HS register.
@param    N2_ls  will be set to the value for the N2_LS register.
@param    N3n    will be set to the value for the N3n register.
@param    BwSel  will be set to the value for the BW_SEL register.

@return   SI5324_SUCCESS for success, SI5324_ERR_FREQ when the requested
frequency cannot be generated.
@note     Private function.
Calculate the frequency settings for the desired output frequency . @param ClkInFreq contains the frequency of the input clock . @param ClkOutFreq contains the desired output clock frequency . @param N1_hs will be set to the value for the N1_HS register . @param NCn_ls will be set to the value for the NCn_LS register . @param N2_hs will be set to the value for the N2_HS register . @param N2_ls will be set to the value for the N2_LS register . @param N3n will be set to the value for the N3n register . @param BwSel will be set to the value for the BW_SEL register . @return SI5324_SUCCESS for success SI5324_ERR_FREQ when the requested frequency cannot be generated . @note Private function .
int Si5324_CalcFreqSettings(u32 ClkInFreq, u32 ClkOutFreq,
                        u8  *N1_hs, u32 *NCn_ls,
                        u8  *N2_hs, u32 *N2_ls,
                        u32 *N3n,   u8  *BwSel) {
    si5324_settings_t settings;
    int result;
    settings.fin = (u64)ClkInFreq  << 28; 
    settings.fout= (u64)ClkOutFreq << 28; 
    settings.best_delta_fout = settings.fout; 
    settings.n1_min = (int)(SI5324_FOSC_MIN / ClkOutFreq);
    if (settings.n1_min < SI5324_N1_HS_MIN * SI5324_NC_LS_MIN) {
        settings.n1_min = SI5324_N1_HS_MIN * SI5324_NC_LS_MIN;
    }
    settings.n1_max = (int)(SI5324_FOSC_MAX / ClkOutFreq);
    if (settings.n1_max > SI5324_N1_HS_MAX * SI5324_NC_LS_MAX) {
        settings.n1_max = SI5324_N1_HS_MAX * SI5324_NC_LS_MAX;
    }
    settings.n3_min = ClkInFreq / SI5324_F3_MAX;
    if (settings.n3_min < SI5324_N3_MIN) {
        settings.n3_min = SI5324_N3_MIN;
    }
    settings.n3_max = ClkInFreq / SI5324_F3_MIN;
    if (settings.n3_max > SI5324_N3_MAX) {
        settings.n3_max = SI5324_N3_MAX;
    }
    for (settings.n1_hs = SI5324_N1_HS_MAX; settings.n1_hs >= SI5324_N1_HS_MIN; settings.n1_hs--) {
        if (SI5324_DEBUG) {
            xil_printf("Trying N1_HS = %d.\r\n", settings.n1_hs);
        }
        result = Si5324_CalcNclsLimits(&settings);
        if (result) {
            if (SI5324_DEBUG) {
                xil_printf("\tNo valid settings for NCn_LS.\r\n");
            }
            continue;
        }
        result = Si5324_FindNcls(&settings);
        if (result) {
            break;
        }
    }
    if (settings.best_delta_fout /= settings.fout) {
        if (SI5324_DEBUG) {
            xil_printf("Si5324: ERROR: No valid settings found.\r\n");
        }
        return SI5324_ERR_FREQ;
    }
    if (SI5324_DEBUG) {
        xil_printf("Si5324: Found solution: fout = %dHz.\r\n",
                   (u32)(settings.best_fout >> 28));
    }
    *N1_hs  = (u8)settings.best_n1_hs - 4;
    *NCn_ls =     settings.best_nc_ls - 1;
    *N2_hs  = (u8)settings.best_n2_hs - 4;
    *N2_ls  =     settings.best_n2_ls - 1;
    *N3n    =     settings.best_n3    - 1;
    *BwSel  = 6; 
    return SI5324_SUCCESS;
}
int Si5324_CalcFreqSettings ( u32 ClkInFreq , u32 ClkOutFreq , u8 * N1_hs , u32 * NCn_ls , u8 * N2_hs , u32 * N2_ls , u32 * N3n , u8 * BwSel ) { si5324_settings_t settings ; int result ; settings . fin = ( u64 ) ClkInFreq << 28 ; settings . fout = ( u64 ) ClkOutFreq << 28 ; settings . best_delta_fout = settings . fout ; settings . n1_min = ( int ) ( SI5324_FOSC_MIN / ClkOutFreq ) ; if ( settings . n1_min < SI5324_N1_HS_MIN * SI5324_NC_LS_MIN ) { settings . n1_min = SI5324_N1_HS_MIN * SI5324_NC_LS_MIN ; } settings . n1_max = ( int ) ( SI5324_FOSC_MAX / ClkOutFreq ) ; if ( settings . n1_max > SI5324_N1_HS_MAX * SI5324_NC_LS_MAX ) { settings . n1_max = SI5324_N1_HS_MAX * SI5324_NC_LS_MAX ; } settings . n3_min = ClkInFreq / SI5324_F3_MAX ; if ( settings . n3_min < SI5324_N3_MIN ) { settings . n3_min = SI5324_N3_MIN ; } settings . n3_max = ClkInFreq / SI5324_F3_MIN ; if ( settings . n3_max > SI5324_N3_MAX ) { settings . n3_max = SI5324_N3_MAX ; } for ( settings . n1_hs = SI5324_N1_HS_MAX ; settings . n1_hs >= SI5324_N1_HS_MIN ; settings . n1_hs -- ) { if ( SI5324_DEBUG ) { xil_printf ( " \r \n " , settings . n1_hs ) ; } result = Si5324_CalcNclsLimits ( & settings ) ; if ( result ) { if ( SI5324_DEBUG ) { xil_printf ( " \t \r \n " ) ; } continue ; } result = Si5324_FindNcls ( & settings ) ; if ( result ) { break ; } } if ( settings . best_delta_fout /= settings . fout ) { if ( SI5324_DEBUG ) { xil_printf ( " \r \n " ) ; } return SI5324_ERR_FREQ ; } if ( SI5324_DEBUG ) { xil_printf ( " \r \n " , ( u32 ) ( settings . best_fout >> 28 ) ) ; } * N1_hs = ( u8 ) settings . best_n1_hs - 4 ; * NCn_ls = settings . best_nc_ls - 1 ; * N2_hs = ( u8 ) settings . best_n2_hs - 4 ; * N2_ls = settings . best_n2_ls - 1 ; * N3n = settings . best_n3 - 1 ; * BwSel = 6 ; return SI5324_SUCCESS ; }
Calculate the frequency settings for the desired output frequency.
Calculate the frequency settings for the desired output frequency .
/* TBD */ // 32.28 fixed point // 32.28 fixed point // High frequency error to start with // Calculate some limits for N1_HS * NCn_LS and for N3 base on the input // and output frequencies. // Find a valid oscillator frequency with the highest setting of N1_HS // possible (reduces power) // Best possible result found. Skip the rest of the possibilities. // Post processing: convert temporary values to actual register settings /* How must the bandwidth selection be determined? Not all settings will
     * be valid.
    refclk        2, 0xA2,  //              BWSEL_REG=1010 (?)
    free running  2, 0x42,  //              BWSEL_REG=0100 (?)
    */ //4