source: PlatformSupport/CustomPeripherals/pcores/w3_clock_controller_v3_00_b/src/w3_clock_controller.c

Last change on this file was 1872, checked in by murphpo, 11 years ago

Fixed error in clock controller driver

File size: 17.8 KB
Line 
1/*****************************************************************
2* File: w3_clock_controller.c
3* Copyright (c) 2012 Mango Communications, all rights reseved
4* Released under the WARP License
5* See http://warp.rice.edu/license for details
6*****************************************************************/
7
8/** \file w3_clock_controller.c
9
10\mainpage
11This is the driver for the w3_clock_controller core, which implements an SPI master for controlling
12the AD9512 clock buffers on the WARP v3 board. Refer to the WARP v3 user guide for more details
13on the clock options and connections.
14
15@version 3.00.b
16@author Patrick Murphy
17@copyright (c) 2012 Mango Communications, Inc. All rights reserved.<br>
18Released under the WARP open source license (see http://warp.rice.edu/license)
19
20*/
21
22#include "w3_clock_controller.h"
23
24/**
25\defgroup user_functions Functions
26\brief Functions to call from user code
27\addtogroup user_functions
28
29Example:
30\code{.c}
31//Assumes user code sets CLK_BASEADDR to base address of w3_clock_controller core, as set in xparameters.h
32
33//Initialize the AD9512 clock buffers
34ad_init(CLK_BASEADDR, 3);
35
36//Enable clock outputs to FMC slot
37clk_config_outputs(CLK_BASEADDR, CLK_OUTPUT_ON, (CLK_SAMP_OUTSEL_FMC | CLK_RFREF_OUTSEL_FMC));
38
39//Disable clock outputs to clock module header
40clk_config_outputs(CLK_BASEADDR, CLK_OUTPUT_OFF, (CLK_SAMP_OUTSEL_CLKMODHDR | CLK_RFREF_OUTSEL_CLKMODHDR));
41
42//Set clock to AD chips to 40MHz (80MHz source divided by 2)
43clk_config_dividers(CLK_BASEADDR, 2, (CLK_SAMP_OUTSEL_AD_RFA | CLK_SAMP_OUTSEL_AD_RFB));
44
45\endcode
46
47@{
48*/
49
50/**
51\brief Initializes the clock controller. This function must be called once at boot before any AD or
52RF operations will work. Default config is:
53- On board 80MHz TCXO used as source for sampling and RF ref clock buffers
54- 80MHz clock driven to FPGA, RF A and RF B ADC/DACs
55- 40MHz clock driven to RF A and B transceivers
56- FMC and clock module header clocks disabled
57\param baseaddr Base memory address of w3_clock_controller pcore
58\param clkDiv Clock divider for SPI serial clock (set to 3 for 160MHz bus)
59*/
60int clk_init(u32 baseaddr, u8 clkDiv) {
61    u32 x;
62   
63    Xil_Out32(baseaddr + CLKCTRL_REG_CONFIG, (clkDiv & CLKCTRL_REG_CONFIG_MASK_CLKDIV));
64
65    //Toggle AD9512 resets (active low)
66    //Currently bypased-buffers auto-reset on power up, and resetting here can stop clock to FPGA (damn causality)
67    //Xil_Out32(CLKCTRL_REG_CONFIG, 0); //Also sets clk_div = 0
68    //Xil_Out32(CLKCTRL_REG_CONFIG, CLKCTRL_REG_CONFIG_MASK_SAMP_FUNC | CLKCTRL_REG_CONFIG_MASK_RFREF_FUNC);
69
70    //Confirm the SPI interfaces are working
71    x = clk_spi_read(baseaddr, (CLK_SAMP_CS|CLK_RFREF_CS), 0x0);
72    if(x != 0x1010) {
73        xil_printf("First CLK SPI readback was wrong: addr[0]=0x%04x (should be 0x1010)\n", x);
74        return -1;
75    }
76
77    /* Samping Clock Buffer Config
78    Samp clock AD9512 outputs on WARP v3 board:
79     OUT0: AD2 (LVPECL)
80     OUT1: Clock module header (LVPECL)
81     OUT2: AD1 (LVPECL)
82     OUT3: FPGA col2 SRCC (LVDS)
83     OUT4: FMC  (LVDS)
84
85    Default config:
86     -Select CLK1 as input
87     -Disable:
88       -Outputs OUT1, OUT4
89       -All output dividers
90       -CLK2 input
91    */
92   
93    /*
94    reg 0x45: CLK1/CLK2 config:
95     0: 1=Use CLK1 input
96     1: 0=Enable CLK1 circuits
97     2: 1=Disable CLK2 circuits
98    */
99    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x45, 0x05);
100
101    //Enable OUT0, OUT2, OUT3; disable OUT1, OUT4; all outputs are on after powerup/reset
102    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x3E, 0x02); //OUT1 = off (PD2 mode, because OUT1 has load resistors)
103    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x41, 0x01); //OUT4 = off
104
105    //Power down divider logic- all active outputs at 80MHz
106    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4B, 0x80); //OUT0 divider off
107    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4D, 0x80); //OUT1 divider off
108    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4F, 0x80); //OUT2 divider off
109    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x51, 0x80); //OUT3 divider off
110    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x53, 0x80); //OUT4 divider off
111
112
113    //Alternate config: 40MHz clock for AD1, AD2
114//  clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4B, 0x00); //OUT0 divider on
115//  clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4A, 0x00); //OUT0 divide by 2
116//  clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4F, 0x00); //OUT2 divider on
117//  clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4E, 0x00); //OUT2 divide by 2
118
119    //Trigger register update
120    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x5A, 0x01); //Self-clearing register update flag
121
122
123    /* RF Reference Clock Buffer Config
124    RF ref clock AD9512 outputs on WARP v3 board:
125        OUT0: Clock module header (LVPECL)
126        OUT1: NC
127        OUT2: NC
128        OUT3: Both MAX2829 ref (RFA=CMOSp, RFB=CMOSn; must be 20 or 40 MHz)
129        OUT4: FMC (LVDS)
130
131        Default config:
132         -Select CLK1 as input
133         -Enable + and - CMOS outputs on OUT3
134         -Set OUT3 divider to 2 (produces 40MHz clock at OUT3)
135         -Disable:
136           -Outputs OUT0, OUT1, OUT2, OUT4
137           -Dividers for OUT0, OUT1, OUT2, OUT4
138           -CLK2 input
139    */
140    //Enable OUT3; Disable OUT0, OUT1, OUT2, OUT4; all outputs are on after reset
141    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x3D, 0x02); //OUT0 = off, has load resistors
142    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x3E, 0x03); //OUT1 = off, has no load resistors
143    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x3F, 0x03); //OUT2 = off, has no load resistors
144    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x41, 0x01); //OUT4 = off
145
146    //Enable inverted CMOS output on OUT3
147    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x40, 0x18); //OUT3 = CMOS, +/- both on
148
149    //Power down CLK2 input
150    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x45, 0x05); //CLK1 on, CLK2 off, CLK1 drives distribution
151
152    //Power down divider logic on disabled ports
153    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x4B, 0x80); //OUT0 divider off
154    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x4D, 0x80); //OUT1 divider off
155    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x4F, 0x80); //OUT2 divider off
156    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x53, 0x80); //OUT4 divider off
157
158    //Set divider to 2 on OUT3
159    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x50, 0x00); //OUT3 40MHz (1 cycle down)
160
161    //Alternate config: 20MHz RF reference clock, OUT3 divider=4
162//  clk_spi_write(baseaddr, CLK_RFREF_CS, 0x50, 0x11); //OUT3 20MHz (2 cycle down)
163
164    //Trigger register update
165    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x5A, 0x01); //Self-clearing register update flag
166   
167    return 0;
168}
169
170/**
171\brief Configures which outputs are en/disabled in both AD9512 clock buffers
172\param baseaddr Base memory address of w3_clock_controller pcore
173\param clkOutMode New mode for selected clock outputs; must be CLK_OUTPUT_ON or CLK_OUTPUT_OFF
174\param clkOutSel Masks to select which clock outputs to affect; must be OR'd combination of:
175 Mask | Selected Output
176 ---- | ----
177 CLK_SAMP_OUTSEL_FMC | Sampling clock buffer to FMC slot
178 CLK_SAMP_OUTSEL_CLKMODHDR | Sampling clock buffer to clock module header
179 CLK_SAMP_OUTSEL_FPGA | Sampling clock buffer to FPGA
180 CLK_SAMP_OUTSEL_AD_RFA | Sampling clock buffer to RF A AD9963 (ADC/DAC ref clock)
181 CLK_SAMP_OUTSEL_AD_RFB | Sampling clock buffer to RF B AD9963 (ADC/DAC ref clock)
182 CLK_RFREF_OUTSEL_FMC | RF ref clock buffer to FMC
183 CLK_RFREF_OUTSEL_CLKMODHDR | RF ref clock buffer to clock module header
184 CLK_RFREF_OUTSEL_RFAB | RF ref clock buffer to RF A and B transceivers
185\return Returns 0 on success, -1 for invalid parameters
186*/
187int clk_config_outputs(u32 baseaddr, u8 clkOutMode, u32 clkOutSel) {
188    if((clkOutMode != CLK_OUTPUT_ON) && (clkOutMode != CLK_OUTPUT_OFF))
189        return -1;
190/*
191    Samp clock AD9512 outputs on WARP v3 board:
192        OUT0: AD2 (LVPECL)
193        OUT1: Clock module header (LVPECL)
194        OUT2: AD1 (LVPECL)
195        OUT3: FPGA col2 SRCC (LVDS)
196        OUT4: FMC  (LVDS)
197
198    RF ref clock AD9512 outputs on WARP v3 board:
199        OUT0: Clock module header (LVPECL)
200        OUT1: NC
201        OUT2: NC
202        OUT3: Both MAX2829 ref (RFA=CMOSp, RFB=CMOSn; must be 20 or 40 MHz)
203        OUT4: FMC (LVDS)
204*/
205   
206    u8 lvpecl_cfg, lvds_cfg, cmos_cfg;
207
208    //Set the register values to write, based on output type and user ON/OFF param
209    if(clkOutMode == CLK_OUTPUT_ON) lvpecl_cfg = 0x8; //LVPECL output on, 805mV drive
210    else lvpecl_cfg = 0x2; //output off (for outputs w/ load resistors)
211
212    if(clkOutMode == CLK_OUTPUT_ON) lvds_cfg = 0x2; //output on, LVDS logic, 3.5mA drive
213    else lvds_cfg = 0x1; //output off
214
215    if(clkOutMode == CLK_OUTPUT_ON) cmos_cfg = 0x18; //+/- outputs on, CMOS logic
216    else cmos_cfg = 0x1; //output off
217   
218    /***** Sampling Clock Buffer Config ******/
219    //reg 0x3D, 0x3E, 0x3F: CLKOUT[0,1,2] config
220    // [1:0] LVPECL power down
221    //   (0x0=on, 0x2=PD2 (power down outputs w/ load resistors), 0x3=PD3 (power down outputs w/out load resistors)
222    // [3:2] LVPECL output drive (set to 0x2 for default 805mv)
223    if(clkOutSel & CLK_SAMP_OUTSEL_AD_RFB)      clk_spi_write(baseaddr, CLK_SAMP_CS, 0x3D, lvpecl_cfg); //CLKOUT0
224    if(clkOutSel & CLK_SAMP_OUTSEL_CLKMODHDR)   clk_spi_write(baseaddr, CLK_SAMP_CS, 0x3E, lvpecl_cfg); //CLKOUT1
225    if(clkOutSel & CLK_SAMP_OUTSEL_AD_RFA)      clk_spi_write(baseaddr, CLK_SAMP_CS, 0x3F, lvpecl_cfg); //CLKOUT2
226
227    //reg 0x40, 0x41: CLKOUT[3,4] config
228    // [0] 0=output on, 1=output off
229    // [2:1] LVDS output current (set to 0x1 for 3.5mA default)
230    // [3] Logic (0=LVDS, 1=CMOS)
231    // [4] CMOS- (0=Disable CMOS inverted output; 1=enable)
232    if(clkOutSel & CLK_SAMP_OUTSEL_FPGA)        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x40, lvds_cfg); //CLKOUT3 (LVDS)
233    if(clkOutSel & CLK_SAMP_OUTSEL_FMC)         clk_spi_write(baseaddr, CLK_SAMP_CS, 0x41, lvds_cfg); //CLKOUT4 (LVDS)
234
235    //Trigger register update
236    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x5A, 0x01); //Self-clearing register update flag
237
238    /***** RF Ref Clock Buffer Config ******/
239    //reg 0x3D: CLKOUT0 config
240    // [1:0] LVPECL power down
241    //   (0x0=on, 0x2=PD2 (power down outputs w/ load resistors), 0x3=PD3 (power down outputs w/out load resistors)
242    // [3:2] LVPECL output drive (set to 0x2 for default 805mv)
243    //CLKOUT1, CLKOUT2 are unused and are disabled in clk_init
244    if(clkOutSel & CLK_RFREF_OUTSEL_CLKMODHDR)  clk_spi_write(baseaddr, CLK_RFREF_CS, 0x3D, lvpecl_cfg); //CLKOUT0
245
246    //reg 0x40, 0x41: CLKOUT[3,4] config
247    // [0] 0=output on, 1=output off
248    // [2:1] LVDS output current (set to 0x1 for 3.5mA default)
249    // [3] Logic (0=LVDS, 1=CMOS)
250    // [4] CMOS- (0=Disable CMOS inverted output; 1=enable)
251    if(clkOutSel & CLK_RFREF_OUTSEL_RFAB)       clk_spi_write(baseaddr, CLK_RFREF_CS, 0x40, cmos_cfg); //CLKOUT3 (CMOS +/-)
252    if(clkOutSel & CLK_RFREF_OUTSEL_FMC)        clk_spi_write(baseaddr, CLK_RFREF_CS, 0x41, lvds_cfg); //CLKOUT4 (LVDS)
253
254    //Trigger register update
255    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x5A, 0x01); //Self-clearing register update flag
256
257    return 0;
258}
259
260/**
261\brief Configures whether the RF Reference Buffer uses the on-board or off-board clock source
262\param baseaddr Base memory address of w3_clock_controller pcore
263\param clkInSel Clock source mask, must be either CLK_INSEL_ONBOARD (for on-board oscillator) or CLK_INSEL_CLKMOD (for off-board clock via clock module header)
264 Mask | Selected Input
265 ---- | ----
266 CLK_INSEL_ONBOARD | Selects on-board TCXO as RF Reference clock source (AD9512 CLK1/CLK1B port)
267 CLK_INSEL_CLKMOD | Selects off-board clock from clock module header as RF Reference clock source (AD9512 CLK2/CLK2B port)
268\return Returns 0 on success, -1 for invalid parameters
269*/
270int clk_config_input_rf_ref(u32 baseaddr, u8 clkInSel) {
271    if((clkInSel != CLK_INSEL_ONBOARD) && (clkInSel != CLK_INSEL_CLKMOD))
272        return -1;
273/*
274    Samp clock AD9512 inputs on WARP v3 board:
275        CLK1: On-board TCXO
276        CLK2: Clock module header
277*/
278   
279    /***** Sampling Clock Buffer Config ******/
280    //reg 0x45
281    // [0] Input sel (0=CLK2, 1=CLK1)
282    // [1] 1=Power down CLK1 input circuit
283    // [2] 1=Power down CLK2 input circuit
284    // [3:4] Reserved
285    // [5] Power down both input circuits
286    // [6:7] Reserved
287    if(clkInSel == CLK_INSEL_ONBOARD)   clk_spi_write(baseaddr, CLK_RFREF_CS, 0x45, 0x05); //Select CLK1, power down CLK2
288    if(clkInSel == CLK_INSEL_CLKMOD)    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x45, 0x02); //Select CLK2, power down CLK1
289
290    //Trigger register update
291    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x5A, 0x01); //Self-clearing register update flag
292
293    return 0;
294}
295
296/**
297\brief Configures output dividers in both AD9512 clock buffers
298\param baseaddr Base memory address of w3_clock_controller pcore
299\param clkDiv Divider value to set; must be 1 or even integer in [2,32]
300\param clkOutSel Masks to select which clock outputs to affect; must be OR'd combination of:
301 Mask | Selected Output
302 ---- | ----
303 CLK_SAMP_OUTSEL_FMC | Sampling clock buffer to FMC slot
304 CLK_SAMP_OUTSEL_CLKMODHDR | Sampling clock buffer to clock module header
305 CLK_SAMP_OUTSEL_FPGA | Sampling clock buffer to FPGA
306 CLK_SAMP_OUTSEL_AD_RFA | Sampling clock buffer to RF A AD9963 (ADC/DAC ref clock)
307 CLK_SAMP_OUTSEL_AD_RFB | Sampling clock buffer to RF B AD9963 (ADC/DAC ref clock)
308 CLK_RFREF_OUTSEL_FMC | RF ref clock buffer to FMC
309 CLK_RFREF_OUTSEL_CLKMODHDR | RF ref clock buffer to clock module header
310 CLK_RFREF_OUTSEL_RFAB | RF ref clock buffer to RF A and B transceivers
311\return Returns 0 on success, -1 for invalid parameters
312*/
313int clk_config_dividers(u32 baseaddr, u8 clkDiv, u32 clkOutSel) {
314/*
315    AD9512 reg 0x[4A,4C,4E,50,52]: Divider config high/low for CLKOUT[0,1,2,3,4]
316     [3:0] Divider high cycles
317     [7:4] Divider low cycles
318     Clock freq divided by ((high+1)+(low+1))
319     50% duty cycle requkired; only possible with 1 or even division ratios (high==low)
320
321    AD9512 reg 0x[4B,4D,4F,51,53]: Divider power down & sync for CLKOUT[0,1,2,3,4]
322     [7] 1=disable and bypass divider logic, 0=use divider
323     [6:0] Divider sync setup (not currently used)
324    */
325   
326    u8 div_pd, div_cfg;
327
328    //Check for invalid clkDiv value (any odd value besides 1, greater than 32, or 0)
329    if( ((clkDiv != 1) && (clkDiv & 0x1)) || clkDiv > 32 || clkDiv == 0)
330        return -1;
331   
332    if(clkDiv == 1) {
333        div_pd = 0x80; //divide-by-1 requires bypassing divider entirely
334        div_cfg = 0x00;
335    } else {
336        div_pd = 0x00; //enable divider
337
338        //Calculate number of high/low cycles
339        div_cfg = (clkDiv>>1)-1;
340       
341        //Set high=low
342        div_cfg = (div_cfg<<4) | div_cfg;
343    }
344   
345   
346    //Sampling clock buffer
347    if(clkOutSel & CLK_SAMP_OUTSEL_AD_RFB) { //CLKOUT0
348        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4A, div_cfg);
349        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4B, div_pd);
350    }
351    if(clkOutSel & CLK_SAMP_OUTSEL_CLKMODHDR) { //CLKOUT1
352        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4C, div_cfg);
353        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4D, div_pd);
354    }
355    if(clkOutSel & CLK_SAMP_OUTSEL_AD_RFA) { //CLKOUT2
356        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4E, div_cfg);
357        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x4F, div_pd);
358    }
359    if(clkOutSel & CLK_SAMP_OUTSEL_FPGA) { //CLKOUT3
360        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x50, div_cfg);
361        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x51, div_pd);
362    }
363    if(clkOutSel & CLK_SAMP_OUTSEL_FMC) { //CLKOUT4
364        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x52, div_cfg);
365        clk_spi_write(baseaddr, CLK_SAMP_CS, 0x53, div_pd);
366    }
367   
368    //Trigger register update
369    clk_spi_write(baseaddr, CLK_SAMP_CS, 0x5A, 0x01); //Self-clearing register update flag
370
371    //RF reference clock buffer
372    if(clkOutSel & CLK_RFREF_OUTSEL_CLKMODHDR) { //CLKOUT0
373        clk_spi_write(baseaddr, CLK_RFREF_CS, 0x4A, div_cfg);
374        clk_spi_write(baseaddr, CLK_RFREF_CS, 0x4B, div_pd);
375    }
376    //CLKOUT1, CLKOUT2 are unused; dividers are disabled in clk_init
377    if(clkOutSel & CLK_RFREF_OUTSEL_RFAB) { //CLKOUT3
378        clk_spi_write(baseaddr, CLK_RFREF_CS, 0x50, div_cfg);
379        clk_spi_write(baseaddr, CLK_RFREF_CS, 0x51, div_pd);
380    }
381    if(clkOutSel & CLK_RFREF_OUTSEL_FMC) { //CLKOUT4
382        clk_spi_write(baseaddr, CLK_RFREF_CS, 0x52, div_cfg);
383        clk_spi_write(baseaddr, CLK_RFREF_CS, 0x53, div_pd);
384    }
385   
386    //Trigger register update
387    clk_spi_write(baseaddr, CLK_RFREF_CS, 0x5A, 0x01); //Self-clearing register update flag
388
389    return 0;
390}
391
392/**
393\brief Reads the specified register from both AD9963s
394\param baseaddr Base memory address of w3_clock_controller pcore
395\param csMask OR'd combination of CLK_SAMP_CS and CLK_RFREF_CS
396\param regAddr Address of register to read, in [0x00, 0x5A]
397\return Returns concatenation of current values of the specified register for both AD9512s (if selected); samp clock buffer is LSB
398*/
399u32 clk_spi_read(u32 baseaddr,  u32 csMask, u8 regAddr) {
400    u32 txWord, rxWord;
401
402    //SPI Tx register is 4 bytes:
403    // [3]: chip selects (bitwise OR'd ADCTRL_REG_SPITX_ADx_CS)
404    // [2]: {rnw n1 n0 5'b0}, rnw=1 for SPI write, n1=n0=0 for 1 byte write
405    // [1]: reg addr[7:0]
406    // [0]: ignored for read (read value captured in Rx register)
407    txWord = (csMask & (CLK_SAMP_CS | CLK_RFREF_CS)) | //chip selects
408             (CLKCTRL_REG_SPITX_RNW) | //spi_tx_byte[2] = {rnw n1 n0 5'b0}
409             ((regAddr & 0x7F)<<8) | //spi_tx_byte[1] = addr[7:0]
410             (0x00); //spi_tx_byte[0] = ignored for read (AD drives data pin during this byte)
411
412    Xil_Out32(baseaddr + CLKCTRL_REG_SPITX, txWord);
413
414    rxWord = Xil_In32(baseaddr + CLKCTRL_REG_SPIRX);
415
416    return(rxWord);
417}
418
419/**
420\brief Writes the specified register value to the selected AD9512 clock buffers
421\param baseaddr Base memory address of w3_clock_controller pcore
422\param csMask OR'd combination of CLK_SAMP_CS and CLK_RFREF_CS
423\param regAddr Address of register to write, in [0x00, 0x5A]
424\param txByte 8-bit value to write
425*/
426void clk_spi_write(u32 baseaddr, u32 csMask, u8 regAddr, u8 txByte) {
427    u32 txWord;
428
429    //SPI read process:
430    // -Write full SPI word with RNW=1 and address of desired register
431    // -Capture register value in last byte of SPI write process (handled automatically in logic)
432   
433    //SPI Tx register is 4 bytes:
434    // [3]: chip selects (bitwise OR'd ADCTRL_REG_SPITX_ADx_CS)
435    // [2]: {rnw n1 n0 5'b0}, rnw=0 for SPI write, n1=n0=0 for 1 byte write
436    // [1]: reg addr[7:0]
437    // [0]: reg data[7:0]
438    txWord = (csMask & (CLK_SAMP_CS | CLK_RFREF_CS)) | //chip selects
439             (0x00) | //spi_tx_byte[2] = {rnw n1 n0 5'b0}
440             ((regAddr & 0xFF)<<8) | //spi_tx_byte[1] = addr[7:0]
441             (txByte & 0xFF); //spi_tx_byte[0] = data byte to write
442
443    Xil_Out32(baseaddr + CLKCTRL_REG_SPITX, txWord);
444   
445    return;
446}
447
448/** @}*/ //END group user_functions
Note: See TracBrowser for help on using the repository browser.