HMC703 no Charge Pump Current

Hey community,

I set up the HMC703 and connected a  reference Source with a frequency of 200 kHz. I don't have a VCO connected, so I am using a source with 10 MHz. In Integer Mode N=50 is set. Now I am trying to  measure the outcoming current that is set to max 2.5 mA. When I activate the Test Mode in PD Reg (PFDForceUp=1) I can measure some current over a resistor to GND. But there is Zero current during normal Operation. Any hints?

In the Attachement you find my configuration code. This code describes my Setup. The hmc703.h includes the bitfields for Setting up the Registers. the hmc703.c Shows my init Parameters.

// hmc703.c

/*
Enumerations to make code easier to understand
*/
enum {Register_no_match, Register_match}; // Register_no_match=0 , Register_match=1
enum {disable=0, enable=1};
enum {SD_Clk_from_MCounter=0, VDIV_PFD_CLK=1, RDIV_PFD_CLK=2, FREF_CLK=3}; // Delta Sigma Modulator (DSM) Clock Reference
enum {not_initialized=0, initialized_on_events=1};
enum {Type_B=0, Type_A=1};
/*
Prototypes
*/

unsigned int read_back_reg (SPI spi, unsigned int reg_adress, unsigned int pData );

/*
Name:			hmc703_init
Function:		Initializes the Parameters and Writes Via SPI. Later function HMC_par_update can be used to reassign values
Description:	Sets some default parameter to setup the board for first run. Parameters can be changed later
*/
void hmc703_init(SPI spi, struct_Reg *Reg){
	unsigned int R=0;
	//1 Init SD CFG Register
		Reg->Obj_SD_CFG.R						=0; // Force unused Values =0;
		Reg->Obj_SD_CFG.B.SD_MODE				=Integer;
		Reg->Obj_SD_CFG.B.modulator_type		=Type_A; 
		Reg->Obj_SD_CFG.B.BIST_en				=0;		// Must be 0
		Reg->Obj_SD_CFG.B.dis_reset_acc_rmp		=0;		//
		Reg->Obj_SD_CFG.B.DSM_clock_src			=SD_Clk_from_MCounter;		//
		Reg->Obj_SD_CFG.B.EXTTRIG_EN			=disable;		// 1--> Enables Trigger at external Pin 6
		Reg->Obj_SD_CFG.B.force_DSM_clk			=disable;
		Reg->Obj_SD_CFG.B.force_RFIV_byp		=disable;
		Reg->Obj_SD_CFG.B.inv_DSM_clock			=disable;
		Reg->Obj_SD_CFG.B.numb_bist_cyc			=0;
		Reg->Obj_SD_CFG.B.phase_mode			=not_initialized;		
		Reg->Obj_SD_CFG.B.ssrm					=0;
		Reg->Obj_SD_CFG.B.Res1					=15;
		Reg->Obj_SD_CFG.B.Res2					=7;
		Reg->Obj_SD_CFG.B.Res3					=0;
	//read_back_reg(spi,REG_SD_CFG, Reg->Obj_SD_CFG.R);

	
	//2 Fractional Mode --> Init N_Channels in ALTFRAC Register
		Reg->Obj_ALTFRAC.R						=0; // Force unused Values =0;
		Reg->Obj_ALTFRAC.B.ALTFRAC				=0;	// to be done for high precision frequency setup // N_channels need to be calculated by formular EQ9, page 23/58
	
	
	//3 Init of Analog Enable Register Fields
		Reg->Obj_AN_EN_REG.R					=0;	// Force unused Values =0;
		Reg->Obj_AN_EN_REG.B.EnBias				=enable;
		Reg->Obj_AN_EN_REG.B.EnCP				=enable;
		Reg->Obj_AN_EN_REG.B.EnGP				=enable;
		Reg->Obj_AN_EN_REG.B.EnMcnt				=enable;
		Reg->Obj_AN_EN_REG.B.EnOPAmp			=enable;
		Reg->Obj_AN_EN_REG.B.EnPFD				=enable;
		Reg->Obj_AN_EN_REG.B.EnPS				=enable;
		Reg->Obj_AN_EN_REG.B.EnVCO				=enable;
		Reg->Obj_AN_EN_REG.B.EnVCOBias			=enable;
		Reg->Obj_AN_EN_REG.B.EnXTAL				=enable;
		Reg->Obj_AN_EN_REG.B.RFDIV2Sel			=disable;   // /k Pre-Divider k=2
		Reg->Obj_AN_EN_REG.B.VCO_Out_BiasA		=3;
		Reg->Obj_AN_EN_REG.B.VCO_Out_BiasB		=3;
		Reg->Obj_AN_EN_REG.B.VCOOBWSel			=1;
		Reg->Obj_AN_EN_REG.B.XtalDisSat			=0;
		Reg->Obj_AN_EN_REG.B.XtalLowGain		=0; // recommended 1 (f_in>200 MHz) , 0 (fin<200 MHz)
	
	//4 Init of PD Register
		Reg->Obj_PD_Reg.R						=0;	// Force unused Values =0;
		Reg->Obj_PD_Reg.B.LKDProcTesttoCP		=0;
		Reg->Obj_PD_Reg.B.McntClkGateSel		=3;
		Reg->Obj_PD_Reg.B.OpAmpBiasSel			=3;
		Reg->Obj_PD_Reg.B.PFDDly				=3;  // Dead-Zone Avoidance Delay = 3: t=3 ns
		Reg->Obj_PD_Reg.B.PFDUpEn				=enable;  // 1: Enable PFD Up Pulses to CP 
		Reg->Obj_PD_Reg.B.PFDDnEn				=enable;  // 1: Enable PFD Down Pulses to CP 
		Reg->Obj_PD_Reg.B.PFDForceDn			=disable;  // 1: forces min current to test min output [test]
		Reg->Obj_PD_Reg.B.PFDForceMid			=disable;  // 1: Forces a voltage source for the loop filter [test]
		Reg->Obj_PD_Reg.B.PFDForceUp			=disable;  // 1: force max Current to test max output [test]
		Reg->Obj_PD_Reg.B.PFDInv				=disable;  // 0- Use with a positive tuning slope VCO and passive loop filter
		Reg->Obj_PD_Reg.B.PFDShort				=disable; 
		Reg->Obj_PD_Reg.B.PSBiasSel				=disable;  // Power Supply Bias Current? What is this?
		Reg->Obj_PD_Reg.B.VDIVExt				=disable;
	//5 Init of Charge Pump Register Fields
		Reg->Obj_CP_Reg.R						=0;	// Force unused Values =0;
		Reg->Obj_CP_Reg.B.CPHik					=0;
		Reg->Obj_CP_Reg.B.CPIdn					=125;	// 2.5mA = value * 20 uA
		Reg->Obj_CP_Reg.B.CPIup					=125;	// 2.5mA = value * 20 uA
		Reg->Obj_CP_Reg.B.CPOffset				=disable;		  // disable in INTEGER mode
		//Reg->Obj_CP_Reg.B.CPSnkEn				=~Reg->Obj_PD_Reg.B.PFDInv;	// same as NOT-PFDInv bit in FRAC Mode
		Reg->Obj_CP_Reg.B.CPSnkEn				=disable;;	// same as NOT-PFDInv bit in int Mode
		//Reg->Obj_CP_Reg.B.CPSrcEn				=Reg->Obj_PD_Reg.B.PFDInv;		//  same as PFDInv bit in FRAC Mode
		Reg->Obj_CP_Reg.B.CPSrcEn				=disable;;		//  disable in INT Mode
	//6 Init R Divider
		Reg->Obj_R_DIV.R						=0;	// Force unused Values =0;
		//Reg->Obj_R_DIV.B.rdiv					=R_DIV;	// to be done
		Reg->Obj_R_DIV.B.rdiv					=1; // R Pre-Divider of FREF of PFD Reference
	//7 Init N Int Part
		Reg->Obj_FREQ_Int_Part.R					=0;	// Force unused Values =0;
		//Reg->Obj_FREQ_Int_Part.B.intg_part		=N_Int; // to be done
		//Reg->Obj_FREQ_Int_Part.B.intg_part			=16; // testvalue
		Reg->Obj_FREQ_Int_Part.B.intg_part			=50; // testvalue
	//8 Init N Frac Part
		Reg->Obj_FREQ_FRAC_Part.R					=0;	// Force unused Values =0;
		//Reg->Obj_FREQ_FRAC_Part.B.frac_part			=N_Frac; // to be done
		Reg->Obj_FREQ_FRAC_Part.B.frac_part			=0; // dummy value
	//9 Init Lock Detect Register
		Reg->Obj_Lock_DETECT.R						=0;	// Force unused Values =0;
		Reg->Obj_Lock_DETECT.B.Cyc_Slp_prev_en		=0;		// Maybe set 1 to higher CP Gain for phase errors ... see table 20
		Reg->Obj_Lock_DETECT.B.LKDCounts			=7;		// 65535 --> Change to good value! 
		Reg->Obj_Lock_DETECT.B.Lock_Det_Cnt_En		=1;
		Reg->Obj_Lock_DETECT.B.Lock_Det_Tmr_En		=1;
		Reg->Obj_Lock_DETECT.B.Res					=12;
		Reg->Obj_Lock_DETECT.B.Res2					=0;
		//Reg->Obj_Lock_DETECT.B.Res3					=0;
		Reg->Obj_Lock_DETECT.B.Res4					=1;
		Reg->Obj_Lock_DETECT.B.Train_Lock_Det_Tmr	=1;
	//10 Init GPO Register
		Reg->Obj_GPO_Reg.R						=0;	// Force unused Values =0;
		Reg->Obj_GPO_Reg.B.GPOAlways			=0;			//1--> Lock Detect // Other Configurations see table 28
		Reg->Obj_GPO_Reg.B.GPOOn				=1;		// Permanenter SDO Mode
		Reg->Obj_GPO_Reg.B.GPOPullDnDis			=0;
		Reg->Obj_GPO_Reg.B.GPOPullUpDis			=0;
		Reg->Obj_GPO_Reg.B.GPOSel				=4;		// 0: Static Test Voltage //8, xref // 9. rdiv out
		Reg->Obj_GPO_Reg.B.GPOTest				=0;
	//11 Init Reg_SEED Register
		Reg->Obj_SEED.R							=0;	// Force unused Values =0;
		Reg->Obj_SEED.B.seed					=0;	// Phase of Output
	//12 Init Trigger Register
		Reg->Obj_SPITRIG.R						=0;	// Force unused bits to 0
		Reg->Obj_SPITRIG.B.SPITRIG				=disable;	// 0: No External Trigger
}

#define Reg_RST						0x01		// Reset Trigger Register
#define REFDIV						0x02
#define REG_N_INTEGER_Part			0x03
#define REG_N_FRACTIONAL_Part		0x04
#define Reg_SEED					0x05
#define REG_SD_CFG					0x06
#define Lock_DETECT_Reg				0x07
#define AN_EN						0x08		// Analog Enable Register
#define REG_CP_OFFSET				0x09		// Charge Pump Register				// Table 22
#define REG_AUX_Register			0x0A
#define PD_Reg						0x0B		// Phase Detector Register			// Table 24
#define REG_ALTERNATE_INTEGER		0x0C
#define REG_ALTERNATE_FRACTIONAL	0x0D
#define SPI_TRIG_Reg				0x0E		//									// Table 27
#define GPO_Reg						0x0F

enum {Fractional=0, Integer=1, Exact_Freq_Fractional=2, FM=3, PM=4, Sweep_1=5, Sweep_2=6, Sweep_3=7}; // SD Modes
/*
Description:	Global Parameters
*/
//tbd





/*
Register:	Struct for Reg Frequency Register 03h - Integer Part // See Table 16
Description:	tbd
*/

typedef union {
	struct {
			unsigned int Fill					:16;		// Filling bits to 32 bit
			unsigned int intg_part				:16;		// Configure the integer of the Divider see table 16
		} B;
		unsigned int R;	
}struct_FREQ_Int_Part;

/*
Register:	Struct for Reg Frequency Register 04h - Fractional Part // See Table 17
Description:	tbd
*/

typedef union {
	struct {
		unsigned int Fill					:8;			// Filling bits to 32 bit
		unsigned int frac_part				:24;		//Configure the fractional of the Divider see table 17
	} B;
	unsigned int R;
}struct_FREQ_FRAC_Part;

/*
Register:	Struct for Reg Seed Reg 05h - Phase4 of Output // See Table 18
Description:	tbd
*/


typedef union {
	struct {
		unsigned int Fill				:8;		// Filling bits to 32 bit
		unsigned int seed				:24;		//
	} B;
	unsigned int R;
}struct_SEED;

/*
Register:		Struct for Reg Lock Detect Register 07h // See Table 20
Description:	tbd

*/

typedef union {
	struct {
		unsigned int Fill					:10;	// Filling bits to 32 bit
		unsigned int Res4					:1;		// Reserved, must be 1
		unsigned int Train_Lock_Det_Tmr		:1;		// Must be programmed from 0 to 1 after change of PD reference clock
		unsigned int Res3					:4;		// Reserved
		unsigned int Cyc_Slp_prev_en		:1;		// Increases Charpe Pump Gain for phase errors larger than lock detect timer
		unsigned int Lock_Det_Tmr_En		:1;		// Enable Lock Detect Timer (should be 1)
		unsigned int Res2					:2;		// Reserved, must be 0
		unsigned int Lock_Det_Cnt_En		:1;		// Enable Lock Detect Counter (should be 1)
		unsigned int Res					:8;		// Must be value=12, reserved bits
		unsigned int LKDCounts				:3;		// Configure the Size of Lock Detect Windows //See Table 20
	} B;
	unsigned int R;
}struct_Lock_DETECT; 


/*
Register:	Struct for Reg Analog EN Register 08h // See table 21
Description:	tbd
*/

typedef union {
	struct {
		unsigned int Fill				:12;	// Filling bits to 32 bit
		unsigned int XtalDisSat			:1;
		unsigned int XtalLowGain		:1;		
		unsigned int RFDIV2Sel			:1;
		unsigned int VCOOBWSel			:1;
		unsigned int VCO_Out_BiasB		:3;
		unsigned int VCO_Out_BiasA		:3;
		unsigned int EnOPAmp			:1;
		unsigned int EnVCOBias			:1;
		unsigned int EnPS				:1;
		unsigned int EnMcnt				:1;
		unsigned int EnGP				:1;
		unsigned int EnVCO				:1;
		unsigned int EnXTAL				:1;
		unsigned int EnPFD				:1;
		unsigned int EnCP				:1;	
		unsigned int EnBias				:1;		//
	} B;
	unsigned int R;
}struct_AN_EN_Reg;


/*
Register:	Struct for Reg Charge Pump Reg 09h // See Table 22
Description:	tbd
*/

typedef union {
	struct {
		unsigned int Fill				:8;		// Filling bits to 32 bit
		unsigned int CPHik				:1;		//
		unsigned int CPSnkEn			:1;		//
		unsigned int CPSrcEn			:1;		//
		unsigned int CPOffset			:7;		//
		unsigned int CPIup				:7;		//
		unsigned int CPIdn				:7;		//
	} B;
	unsigned int R;
}struct_CP_Reg;


/*
Attention:	Maybe its more useful to remove struct and union to normal integer Value
Register:	Struct for Reg Modulation Step Register 0Ah // See table 23
Description:	tbd
*/

typedef union {
	struct {
		unsigned int Fill		 :8;		// Filling bits to 32 bit
		int MODSTEP				:24;		// Zweierkomplement // See Table 23
	} B;
	unsigned int R;
}struct_MODSTEP;


/*
Register:	Struct for Reg 0x01 RST. Table 14 @ Datasheet
Description:	tbd
*/

typedef union {
	struct{
			unsigned int Fill			:21;	// Filling bits to 32 bit
			unsigned int EnSyncChpDis	:1;		// Configure to trigger power-off of charge-pump with  falling edge of Reference-Frequency
			unsigned int EnKeepOns		:8;		// Wiring will enable Parts even Chip is disabled
			unsigned int EnFromSPI		:1;		// Master Enable (Chip Select) from SPI Master
			unsigned int EnPinSel		:1;		// Configure to Trigger Enable to Pin instead of SPI Master
		}B;
		unsigned int R;
}struct_Reg_RST;


/*
Register:		Struct for Reg 02h REFDIV. Table 15
Description:	tbd
*/

typedef union {
	struct {
			unsigned int Fill			:18;	// Filling bits to 32 bit
			unsigned int rdiv			:14;	// Reference Divider R value. [R=1 .. 16383 --> 2^14=16384] 
		}B;
	unsigned int R;
}struct_rdiv;

/*
Register:	Struct for Reg 06h SD CFG. Table 19 
Description:	tbd
*/
typedef union {
	struct{
		unsigned int Fill				:8;		// Filling bits to 32 bit
		unsigned int ssrm				:1;		// single step ramp module. // see Table 19
		unsigned int dis_reset_acc_rmp	:1;		// Sets autoreset of accumulator for next ramps
		unsigned int force_RFIV_byp		:1;		// Uses or bypasses the /R divider
		unsigned int Res3				:1;		// Reserved, must be value=0
		unsigned int inv_DSM_clock		:1;		// Test / BIST only
		unsigned int DSM_clock_src		:2;		// Configures which source clock has to be used
		unsigned int numb_bist_cyc		:2;		// Reserved, internal use
		unsigned int BIST_en			:1;		// Reserved, must be value=0;
		unsigned int force_DSM_clk		:1;		// Forces the modulator clock on
		unsigned int Res2				:3;		// Reserved bits, must be value=7 (default)
		unsigned int EXTTRIG_EN			:1;		// Sets if an external trigger should be used
		unsigned int phase_mode			:1;		// Phase Mode
		unsigned int SD_MODE			:3;		// Configure the operational mode // see Table 19
		unsigned int Res1				:4;		// Reserved bits, Default value= 15
		unsigned int modulator_type		:1;		// Modulator Type A (1) or Type B(0)
	} B;
	unsigned int R;
}struct_SD_CFG;


/*
Register:	Struct for Reg  PD Register 0Bh   // See Table 24
Description:	tbd
*/

typedef union {
	struct {
		unsigned int Fill				:13;	// Filling bits to 32 bit
		unsigned int LKDProcTesttoCP	:1;	//
		unsigned int VDIVExt			:1;	//
		unsigned int McntClkGateSel		:2;	//
		unsigned int OpAmpBiasSel		:2;	//
		unsigned int PSBiasSel			:3;	//
		unsigned int PFDForceMid		:1;	//
		unsigned int PFDForceDn			:1;	//
		unsigned int PFDForceUp			:1;	//
		unsigned int PFDDnEn			:1;	//
		unsigned int PFDUpEn			:1;	//
		unsigned int PFDInv				:1;	//
		unsigned int PFDShort			:1;	//		
		unsigned int PFDDly				:3;	// 
	}B;
	unsigned int R;
}struct_PD_REG;

/*
Register:	Struct for Reg  ALTINT 0Ch  // See Table 25
Description:	tbd
*/

typedef union {
	struct {
		unsigned int	Fill		:16;	// Filling bits to 32 bit
		unsigned int 	ALTINT		:16;	//
	}B;
	unsigned int R;
}struct_ALTINT;

/*
Register:	Struct for Reg  ALTFRAC 0Dh  // See Table 26
Description:	tbd
*/

typedef union {
	struct {
		unsigned int Fill			:8;	// Filling bits to 32 bit
		unsigned int ALTFRAC		:24;	//
	}B;
	unsigned int R;
}struct_ALTFRAC;

/*
Register:	Struct for Reg SPI TRIG 0Eh    // See Table 27
Description:	tbd
*/

typedef union {
	struct {
		unsigned int Fill				:31;	// Filling bits to 32 bit
		unsigned int SPITRIG			:1;		//
	}B;
	unsigned int R;
}struct_SPITRIG;

/*
Register:	Struct for Reg GPO Register 0Fh    // See Table 28
Description:	tbd
*/

typedef union {
	struct {
		unsigned int Fill				:22;	// Filling bits to 32 bit
		unsigned int GPOPullDnDis		:1;	//
		unsigned int GPOPullUpDis		:1;	//
		unsigned int GPOOn				:1;	//
		unsigned int GPOAlways			:1;	//
		unsigned int GPOTest			:1;	//
		unsigned int GPOSel				:5;	//
	}B;
	unsigned int R;
}struct_GPO_Reg; 

/*
Register:	Struct for Reg  Reserved 10h   // See Table 29
Description:	tbd
*/

typedef union {
	struct {
		unsigned int	Fill		:23;	// Filling bits to 32 bit
		unsigned int 	Res			:9;		//
	}B;
	unsigned int R;
}struct_Res1;

/*
Register:	Struct for Reg  Reserved 11h   // See Table 30
Description:	tbd
*/

typedef union {
	struct {
		unsigned int	Fill	:13;	// Filling bits to 32 bit
		unsigned int 	Res		:19;	//
	}B;
	unsigned int R;
}struct_Res2;


/*
Register:	Struct for Reg  GPO2 12h   // See Table 31
Description:	tbd
*/

typedef union {
	struct {
		unsigned int Fill				:29;	// Filling bits to 32 bit
		unsigned int 	RampBusy		:1;	//
		unsigned int 	LockDetect		:1;	//		
		unsigned int 	GPO				:1;	//		
	}B;
	unsigned int R;
}struct_GPO2;


/*
Register:	Struct for Reg BIST Status 13h    // See Table 32
Description:	tbd
*/

typedef union {
	struct {
		unsigned int	Fill				:15;	// Filling bits to 32 bit
		unsigned int 	BISTBusy			:1;		//
		unsigned int 	BISTSignature		:16;	//		
	}B;
	unsigned int R;
}struct_BIST;


/*
Register:		Struct for Reg  Lock Detect Status 14h   // See Table 33
Description:	Read only Register
*/

typedef union {
	struct {
		unsigned int	Fill			:28;	// Filling bits to 32 bit
		unsigned int 	LkdTraining		:1;		//
		unsigned int 	LkdSpeed		:3;		//		
	}B;
	unsigned int R;
}struct_Lkd_Stat;

/*
Register:		Super-Struct for all Registers
Description:	Call this as a pointer to get all registers and values.
*/
typedef struct {
	struct_FREQ_Int_Part	Obj_FREQ_Int_Part;
	struct_FREQ_FRAC_Part	Obj_FREQ_FRAC_Part;
	struct_SEED				Obj_SEED;
	struct_Lock_DETECT		Obj_Lock_DETECT;
	struct_AN_EN_Reg		Obj_AN_EN_REG;
	struct_CP_Reg			Obj_CP_Reg;
	struct_Reg_RST			Obj_RST;
	struct_SD_CFG			Obj_SD_CFG;
	struct_rdiv				Obj_R_DIV;
	struct_MODSTEP			Obj_MODSTEP;
	struct_PD_REG			Obj_PD_Reg;
	struct_ALTINT			Obj_ALTINT;
	struct_ALTFRAC			Obj_ALTFRAC;
	struct_SPITRIG			Obj_SPITRIG;
	struct_GPO_Reg			Obj_GPO_Reg;
	struct_Res1				Obj_Res1;
	struct_Res2				Obj_Res2;
	struct_GPO2				Obj_GPO2_Reg;
	struct_BIST				Obj_BIST;
	struct_Lkd_Stat			Obj_Lkd_Stat;
} struct_Reg;



/*

Public Prototypes

*/

void hmc703_init(SPI spi, struct_Reg *Reg);													// For Init of HMC703
void HMC_par_update(SPI spi, struct_Reg *Reg);
void set_current_out_max(SPI spi, struct_Reg *Reg);	// Tests Output charge-pump current at maximum

  • Hi,

    I won't address any potential code related issues as there are more fundamental issues at play here I believe. 

    I see several potential problems:

    1) You're using very low comparison frequencies so you need to be sure that the signals are meeting the minimum requirements for slew rate as outlined in the Reference Sensitivity Table shown in the datasheet, The PD won't do anything if it can't detect an edge. 

    2) It sounds like you're trying to test just the PD (not sure why though) as you have what sounds like an RF input of 10 MHz (fixed?, not tunable since you said no VCO) and a 200 kHz reference. If this is true you will get an output for force up / force down (depends on which signal is higher in frequency at the PD). 

    3) With all due respect, I'm not sure what you mean by 'normal' since your configuration is not how this PLL would normally be used (without a VCO and a loop filter). I'm assuming by 'normal' you are referring to the normal PD setting as opposed to forcing it to one rail or the other. If that is the case since you have a fixed RF input (nothing to tune) the 10 MHz gets divided down by 50 to come as close as it can to 200 kHz however there's nothing closing the loop. The reference is likely not exactly 200 kHz nor is the RF exactly 10 MHz so without the loop closed nut the frequencies close the current pulses out of the PD will be very narrow and very little to measure. 

    I recommend configuring the PLL with a VCO and a loop filter or procure the HMC778 which uses the HMC703 inside. 

    Best Regards, 

    Marty