Exemple #1
0
/**
 * This method sets the frequency as close the value specified as possible
 * Argument : Requested frequency in Hertz
 * Return   : Actual frequency in Hertz
 */
int64_t Adf4351::SetFrequency( int64_t freqHz )
{
    double Fin;
    double Fpsd;
    double frac;
    double Fvco;
    int    mul,divCode;
    unsigned int prevR4;

    if( mLog & ADF_LOG_FREQ_CALC ){
        printf("Adf4351::SetFrequency d=%d f=%f\n",mDevNum,(double)freqHz );
    }

    if( freqHz/1e6 < 34 ){
        fprintf(stderr,"f=%f too low\n",(double)freqHz);
        return(1);
    }
    if( freqHz/1e6 > 4500 ){
        fprintf(stderr,"f=%f too high\n",(double)freqHz);
        return(1);
    }

    // Reference frequency specified by oscillator on board
    Fin  = 25000000;
    Fpsd = Fin/mR;

    // Fvco must be within 2200Mhz - 4400Mhz
    Fvco = freqHz;
    mul  = 1;
    while( Fvco < 2200e6 ){
       mul  = mul  * 2;
       Fvco = Fvco * 2;
    }
    if( mLog & ADF_LOG_FREQ_CALC ){
        printf("Div=%3d, Fvco=%f Fin=%f Fpsd=%f\n",mul,Fvco,Fin,Fpsd);
    }

    mInt = Fvco / Fpsd;
    frac = ( Fvco - (mInt*Fpsd) )/Fpsd;
    mFrac= frac * mMod;

    if( mLog & ADF_LOG_FREQ_CALC ){
        printf("INT=%8d, FRAC=%8d\n",mInt,mFrac);
    }

    freqHz = (mInt*Fpsd + Fpsd*mFrac/mMod )/mul;
    if( mLog & ADF_LOG_FREQ_CALC ){
        printf("Factual=%f\n",(double)freqHz);
    }

    switch( mul ){
        case  1: divCode = 0;break;
        case  2: divCode = 1;break;
        case  4: divCode = 2;break;
        case  8: divCode = 3;break;
        case 16: divCode = 4;break;
        case 32: divCode = 5;break;
        case 64: divCode = 6;break;
        default: divCode = 6;break;
    }

    // Update R4 for divider and only program if different
    prevR4               =  mRegs[ADF4351_REG4];
    mRegs[ADF4351_REG4] &= ~ADF4351_REG4_RF_DIV_SEL( 0x7 );
    mRegs[ADF4351_REG4] |=  ADF4351_REG4_RF_DIV_SEL( divCode );
    if( mRegs[ADF4351_REG4] !=  prevR4 ){
        (mSpiWriteFunc)(mDevNum,mLog&ADF_LOG_WRITES,mRegs[ADF4351_REG4]);
    }

    // Program R0 for int/frac
    mRegs[ADF4351_REG0]  =  ADF4351_REG0_FRACT( mFrac )                |
                            ADF4351_REG0_INT( mInt  )                  |
                            0x0;
    (mSpiWriteFunc)(mDevNum,mLog&ADF_LOG_WRITES,mRegs[ADF4351_REG0]);

    mFactHz = freqHz;
    return( freqHz );
}
Exemple #2
0
/***************************************************************************//**
 * @brief Sets the ADF4351 frequency on the specified channel.
 *
 * @param st - The selected structure.
 * @param freq - The desired frequency value.
 * @param channel - 0 = RX channel, 1 = TX channel 
 *
 * @return calculatedFrequency - The actual frequency value that was set.
*******************************************************************************/
int64_t adf4351_set_freq(struct adf4351_state *st, uint64_t freq,
							char channel)
{
	struct adf4351_platform_data *pdata = st->pdata;
	uint64_t tmp;
	uint32_t div_gcd, prescaler, chspc;
	uint16_t mdiv, r_cnt = 0;
	uint8_t band_sel_div;
	int32_t ret;

	if ((freq > ADF4351_MAX_OUT_FREQ) || (freq < ADF4351_MIN_OUT_FREQ))
		return -1;

	st->r4_rf_div_sel = 0;

	while (freq < ADF4351_MIN_VCO_FREQ) {
		freq <<= 1;
		st->r4_rf_div_sel++;
	}

	if (freq > ADF4351_MAX_FREQ_45_PRESC) {
		prescaler = ADF4351_REG1_PRESCALER;
		mdiv = 75;
	} else {
		prescaler = 0;
		mdiv = 23;
	}

	/*
	 * Allow a predefined reference division factor
	 * if not set, compute our own
	 */
	if (pdata->ref_div_factor)
		r_cnt = pdata->ref_div_factor - 1;

	chspc = st->chspc;

	do  {
		do {
	do  {
		r_cnt = adf4351_tune_r_cnt(st, r_cnt);
				st->r1_mod = st->fpfd / chspc;
				if (r_cnt > ADF4351_MAX_R_CNT) {
					/* try higher spacing values */
					chspc++;
					r_cnt = 0;
		}
			} while ((st->r1_mod > ADF4351_MAX_MODULUS) && r_cnt);
		} while (r_cnt == 0);


		tmp = freq * (uint64_t)st->r1_mod + (st->fpfd > 1);
		
		tmp = (tmp / st->fpfd);	/* Div round closest (n + d/2)/d */
		
		st->r0_fract = tmp % st->r1_mod;
		tmp = tmp / st->r1_mod;
		
		st->r0_int = (uint32_t)tmp;
	} while (mdiv > st->r0_int);

	band_sel_div = (((st->fpfd) + (ADF4351_MAX_BANDSEL_CLK) - 1) / (ADF4351_MAX_BANDSEL_CLK));	// DIV_ROUND_UP

	if (st->fpfd == ADF4351_MAX_FREQ_PFD)
		band_sel_div = 255;

	if (st->r0_fract && st->r1_mod) {
		div_gcd = gcd(st->r1_mod, st->r0_fract);
		st->r1_mod /= div_gcd;
		st->r0_fract /= div_gcd;
	} else {
		st->r0_fract = 0;
		st->r1_mod = 1;
	}

	st->regs[ADF4351_REG0] = ADF4351_REG0_INT(st->r0_int) |
				 ADF4351_REG0_FRACT(st->r0_fract);

	st->regs[ADF4351_REG1] = ADF4351_REG1_PHASE(1) |
				 ADF4351_REG1_MOD(st->r1_mod) |
				 prescaler;

	st->regs[ADF4351_REG2] =
		ADF4351_REG2_10BIT_R_CNT(r_cnt) |
		ADF4351_REG2_DOUBLE_BUFF_EN |
		(pdata->ref_doubler_en ? ADF4351_REG2_RMULT2_EN : 0) |
		(pdata->ref_div2_en ? ADF4351_REG2_RDIV2_EN : 0) |
		(pdata->r2_user_settings & (ADF4351_REG2_PD_POLARITY_POS |
		ADF4351_REG2_LDP_6ns | ADF4351_REG2_LDF_INT_N |
		ADF4351_REG2_CHARGE_PUMP_CURR_uA(5000) |
		ADF4351_REG2_MUXOUT(0x7) | ADF4351_REG2_NOISE_MODE(0x3)));

	st->regs[ADF4351_REG3] = pdata->r3_user_settings &
				 (ADF4351_REG3_12BIT_CLKDIV(0xFFF) |
				 ADF4351_REG3_12BIT_CLKDIV_MODE(0x3) |
				 ADF4351_REG3_12BIT_CSR_EN |
				 ADF4351_REG3_CHARGE_CANCELLATION_EN |
				 ADF4351_REG3_ANTI_BACKLASH_3ns_EN |
				 ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH);

	st->regs[ADF4351_REG4] =
		ADF4351_REG4_FEEDBACK_FUND |
		ADF4351_REG4_RF_DIV_SEL(st->r4_rf_div_sel) |
		ADF4351_REG4_8BIT_BAND_SEL_CLKDIV(band_sel_div) |
		ADF4351_REG4_RF_OUT_EN |
		(pdata->r4_user_settings &
		(ADF4351_REG4_OUTPUT_PWR(0x3) |
		ADF4351_REG4_AUX_OUTPUT_PWR(0x3) |
		ADF4351_REG4_AUX_OUTPUT_EN |
		ADF4351_REG4_AUX_OUTPUT_FUND |
		ADF4351_REG4_MUTE_TILL_LOCK_EN));

	st->regs[ADF4351_REG5] = ADF4351_REG5_LD_PIN_MODE_DIGITAL + 0x00180000;

	ret = adf4351_sync_config(st, channel);
	if(ret < 0)
		return ret;

    tmp = (uint64_t)((st->r0_int * st->r1_mod) + st->r0_fract) * (uint64_t)st->fpfd;
    tmp = tmp / ((uint64_t)st->r1_mod * ((uint64_t)1 << st->r4_rf_div_sel));

	return tmp;
}
Exemple #3
0
/**
 * This method tests the spi interface to the device and configures
 * the registers.
 */
int Adf4351::Open( 
    Adf4351SpiWriteFuncPtr spiWriteFunc,
    Adf4351GetLdFuncPtr    getLockFunc )
{
    int err;

    // Save the io interface we are provided
    mSpiWriteFunc = spiWriteFunc;
    mGetLockFunc  = getLockFunc;

    // Test the spi interface and lock detect signal 
    if( mLog & ADF_LOG_SPI_TESTS ){
       printf("Adf4351::Open() SPI Test (LD toggle) #######################\n");
    }
    err = this->SpiTest();
    if( err ){
        fprintf(stderr,"Adf4351::Open SpiTest()  failed dev=%d\n",mDevNum);
    }

    //  Setup the basic configuration
    mRegs[ADF4351_REG5] =  ADF4351_REG5_LD_PIN_MODE_DIGITAL           | 
  	                   0x00180000                                 |
                           0x5;

    mRegs[ADF4351_REG4] =  ADF4351_REG4_FEEDBACK_FUND                 |
	                   ADF4351_REG4_RF_DIV_SEL( 6 )               |
                           ADF4351_REG4_8BIT_BAND_SEL_CLKDIV( 255 )   |
                           ADF4351_REG4_AUX_OUTPUT_DIV                |
                           ADF4351_REG4_AUX_OUTPUT_EN                 |
                           ADF4351_REG4_AUX_OUTPUT_PWR(1)             |
                           ADF4351_REG4_RF_OUT_EN                     |     
                           ADF4351_REG4_OUTPUT_PWR(1)                 |
                           0x4;

    mRegs[ADF4351_REG3] =  ADF4351_REG3_12BIT_CLKDIV(1)               |
                           0x3;

    mRegs[ADF4351_REG2] =  ADF4351_REG2_10BIT_R_CNT( mR   )           |
                           ADF4351_REG2_CHARGE_PUMP_CURR_uA( 512 )    |
                           ADF4351_REG2_PD_POLARITY_POS               |
                           0x2;

    mRegs[ADF4351_REG1] =  ADF4351_REG1_PRESCALER                     |
                           ADF4351_REG1_MOD( mMod )                   | 
                           0x1;

    mRegs[ADF4351_REG0] =  ADF4351_REG0_FRACT( mFrac )                |
                           ADF4351_REG0_INT( mInt  )                  |
                           0x0;

    if( mLog & ADF_LOG_SPI_TESTS ){
       printf("Adf4351::Open Begin Configure ##############################\n");
    }
    (mSpiWriteFunc)(mDevNum,mLog&ADF_LOG_WRITES,mRegs[ADF4351_REG5]);
    (mSpiWriteFunc)(mDevNum,mLog&ADF_LOG_WRITES,mRegs[ADF4351_REG4]);
    (mSpiWriteFunc)(mDevNum,mLog&ADF_LOG_WRITES,mRegs[ADF4351_REG3]);
    (mSpiWriteFunc)(mDevNum,mLog&ADF_LOG_WRITES,mRegs[ADF4351_REG2]);
    (mSpiWriteFunc)(mDevNum,mLog&ADF_LOG_WRITES,mRegs[ADF4351_REG1]);
    (mSpiWriteFunc)(mDevNum,mLog&ADF_LOG_WRITES,mRegs[ADF4351_REG0]);

    if( mLog & ADF_LOG_SPI_TESTS ){
       printf("Adf4351::Open End   Configure ##############################\n");
    }

    mIsOpen = 1;

    return( 0 );
}