1 | /********************************************************************************* |
---|
2 | * File : clk_cfg_eeprom_writer.c |
---|
3 | * Authors: Patrick Murphy (murphpo [at] mangocomm.com) |
---|
4 | * License: Copyright 2015, Mango Communications. All rights reserved. |
---|
5 | * Distributed under the WARP license (http://warpproject.org/license) |
---|
6 | * |
---|
7 | * This is an example application for writing clock configuration values to the |
---|
8 | * EEPROM on the WARP v3 board. The w3_clock_controller_axi core checks the EEPROM |
---|
9 | * for clock configurations immediately after the FPGA is configured. If the EEPROM |
---|
10 | * has valid clock configuration values the core uses them in place of its internal |
---|
11 | * defaults. |
---|
12 | * |
---|
13 | * See the clock controller documentation for more information |
---|
14 | * http://warpproject.org/trac/wiki/cores/w3_clock_controller |
---|
15 | * |
---|
16 | * This application will compile in any SDK workspace whose hardware project |
---|
17 | * includes the w3_iic_eeprom_axi core, including the 802.11 and WARPLab |
---|
18 | * Reference Designs. |
---|
19 | * |
---|
20 | *********************************************************************************/ |
---|
21 | |
---|
22 | #include <w3_iic_eeprom.h> |
---|
23 | #include <xparameters.h> |
---|
24 | #include <Xio.h> |
---|
25 | |
---|
26 | #define EEPROM_BASEADDR XPAR_W3_IIC_EEPROM_ONBOARD_BASEADDR |
---|
27 | #define STAT_SUCCESS 0 |
---|
28 | |
---|
29 | #define CLKCFG_DELIM_B0 0xA5 |
---|
30 | #define CLKCFG_DELIM_B1 0xCD |
---|
31 | |
---|
32 | #define CLKCFG_ADDR_BASE 15000 //address of first byte of clk config region in EEPROM |
---|
33 | #define CLKCFG_ADDR_MAX 15999 //address of last byte of clk config region in EEPROM |
---|
34 | |
---|
35 | #define CLKCFG_NUMBYTES_RFREF (8*2) // 8 data/addr pairs per config |
---|
36 | #define CLKCFG_NUMBYTES_SAMP (8*2) // 8 data/addr pairs per config |
---|
37 | #define CLKCFG_NUMBYTES_PLL (40*2) // 40 data/addr pairs per config |
---|
38 | |
---|
39 | #define CLKCFG_ADDR_RFREF_BASE (CLKCFG_ADDR_BASE + 2) //15002 |
---|
40 | |
---|
41 | #define CLKCFG_ADDR_RFREF_NOCM (CLKCFG_ADDR_RFREF_BASE + 0*CLKCFG_NUMBYTES_RFREF) |
---|
42 | #define CLKCFG_ADDR_RFREF_CMMMCX_A (CLKCFG_ADDR_RFREF_BASE + 1*CLKCFG_NUMBYTES_RFREF) |
---|
43 | #define CLKCFG_ADDR_RFREF_CMMMCX_B (CLKCFG_ADDR_RFREF_BASE + 2*CLKCFG_NUMBYTES_RFREF) |
---|
44 | #define CLKCFG_ADDR_RFREF_CMMMCX_C (CLKCFG_ADDR_RFREF_BASE + 3*CLKCFG_NUMBYTES_RFREF) |
---|
45 | #define CLKCFG_ADDR_RFREF_CMPLL_A (CLKCFG_ADDR_RFREF_BASE + 4*CLKCFG_NUMBYTES_RFREF) |
---|
46 | #define CLKCFG_ADDR_RFREF_CMPLL_B (CLKCFG_ADDR_RFREF_BASE + 5*CLKCFG_NUMBYTES_RFREF) |
---|
47 | #define CLKCFG_ADDR_RFREF_CMPLL_C (CLKCFG_ADDR_RFREF_BASE + 6*CLKCFG_NUMBYTES_RFREF) |
---|
48 | |
---|
49 | #define CLKCFG_ADDR_SAMP_BASE (CLKCFG_ADDR_RFREF_BASE + 128) //15130 |
---|
50 | |
---|
51 | #define CLKCFG_ADDR_SAMP_NOCM (CLKCFG_ADDR_SAMP_BASE + 0*CLKCFG_NUMBYTES_SAMP) |
---|
52 | #define CLKCFG_ADDR_SAMP_CMMMCX_A (CLKCFG_ADDR_SAMP_BASE + 1*CLKCFG_NUMBYTES_SAMP) |
---|
53 | #define CLKCFG_ADDR_SAMP_CMMMCX_B (CLKCFG_ADDR_SAMP_BASE + 2*CLKCFG_NUMBYTES_SAMP) |
---|
54 | #define CLKCFG_ADDR_SAMP_CMMMCX_C (CLKCFG_ADDR_SAMP_BASE + 3*CLKCFG_NUMBYTES_SAMP) |
---|
55 | #define CLKCFG_ADDR_SAMP_CMPLL_A (CLKCFG_ADDR_SAMP_BASE + 4*CLKCFG_NUMBYTES_SAMP) |
---|
56 | #define CLKCFG_ADDR_SAMP_CMPLL_B (CLKCFG_ADDR_SAMP_BASE + 5*CLKCFG_NUMBYTES_SAMP) |
---|
57 | #define CLKCFG_ADDR_SAMP_CMPLL_C (CLKCFG_ADDR_SAMP_BASE + 6*CLKCFG_NUMBYTES_SAMP) |
---|
58 | |
---|
59 | #define CLKCFG_ADDR_PLL_BASE (CLKCFG_ADDR_SAMP_BASE + 128) //15258 |
---|
60 | |
---|
61 | #define CLKCFG_ADDR_PLL_NOCM (CLKCFG_ADDR_PLL_BASE + 0*CLKCFG_NUMBYTES_PLL) |
---|
62 | #define CLKCFG_ADDR_PLL_CMPLL_A (CLKCFG_ADDR_PLL_BASE + 1*CLKCFG_NUMBYTES_PLL) |
---|
63 | #define CLKCFG_ADDR_PLL_CMPLL_B (CLKCFG_ADDR_PLL_BASE + 2*CLKCFG_NUMBYTES_PLL) |
---|
64 | #define CLKCFG_ADDR_PLL_CMPLL_C (CLKCFG_ADDR_PLL_BASE + 3*CLKCFG_NUMBYTES_PLL) |
---|
65 | |
---|
66 | /*************************************************************************************** |
---|
67 | RF ref clk buffer (AD9512): |
---|
68 | CLK1: Input from on-board 80MHz oscillator |
---|
69 | CLK2: Input from clock module |
---|
70 | OUT0: LVPECL output to clock module |
---|
71 | OUT1: Unused LVPECL output (not terminated) |
---|
72 | OUT2: Unused LVPECL output (not terminated) |
---|
73 | OUT3: LVCMOS outputs to RFA/RFB MAX2829 (p: RFB, n: RFA) |
---|
74 | OUT4: LVDS output to FMC slot |
---|
75 | |
---|
76 | All configs not listed below are handled post-boot by MicroBlaze application |
---|
77 | |
---|
78 | No Clock Module: |
---|
79 | Do nothing - all config handled post-boot by MicroBlaze application |
---|
80 | |
---|
81 | CM-MMCX Configs: |
---|
82 | A/B/C: Do nothing |
---|
83 | |
---|
84 | CM-PLL Configs: |
---|
85 | A: Select CLK1 input (on-board osc), enable OUT0 (output to clock module) as 10MHz full-scale LVPECL |
---|
86 | B/C: Do nothing |
---|
87 | |
---|
88 | Relevant registers: |
---|
89 | 0x45: Selects clock input: 0x00 for off-board, 0x01 for on-board |
---|
90 | 0x4A: 0x33 sets divider on OUT0 (output to clk mod) to 8, 50% duty cycle |
---|
91 | 0x4B: 0x00 enables divider on OUT0 (output to clk mod) |
---|
92 | 0x3D: 0x08 configures LVPECL output OUT0 (output to clk mod) for max drive |
---|
93 | 0x5A: Trigger device update from SPI registers (self-clearing) |
---|
94 | ***************************************************************************************/ |
---|
95 | u8 cfg_nocm_rfref_addr[] = {0xFF}; |
---|
96 | u8 cfg_nocm_rfref_data[] = {0xFF}; |
---|
97 | |
---|
98 | u8 cfg_cmmmcx_A_rfref_addr[] = {0xFF}; |
---|
99 | u8 cfg_cmmmcx_A_rfref_data[] = {0xFF}; |
---|
100 | |
---|
101 | u8 cfg_cmmmcx_B_rfref_addr[] = {0xFF}; |
---|
102 | u8 cfg_cmmmcx_B_rfref_data[] = {0xFF}; |
---|
103 | |
---|
104 | u8 cfg_cmmmcx_C_rfref_addr[] = {0xFF}; |
---|
105 | u8 cfg_cmmmcx_C_rfref_data[] = {0xFF}; |
---|
106 | |
---|
107 | u8 cfg_cmpll_A_rfref_addr[] = {0x45, 0x4A, 0x4B, 0x3D, 0x5A, 0xFF}; |
---|
108 | u8 cfg_cmpll_A_rfref_data[] = {0x01, 0x33, 0x00, 0x08, 0x01, 0xFF}; |
---|
109 | |
---|
110 | u8 cfg_cmpll_B_rfref_addr[] = {0xFF}; |
---|
111 | u8 cfg_cmpll_B_rfref_data[] = {0xFF}; |
---|
112 | |
---|
113 | u8 cfg_cmpll_C_rfref_addr[] = {0xFF}; |
---|
114 | u8 cfg_cmpll_C_rfref_data[] = {0xFF}; |
---|
115 | |
---|
116 | /*************************************************************************************** |
---|
117 | Samp clk buffer (AD9512): |
---|
118 | CLK1: Input from on-board 80MHz oscillator |
---|
119 | CLK2: Input from clock module |
---|
120 | OUT0: LVPECL output to RFB AD9963 |
---|
121 | OUT1: LVPECL output to clock module |
---|
122 | OUT2: LVPECL output to RFA AD9963 |
---|
123 | OUT3: LVDS output to FPGA |
---|
124 | OUT4: LVDS output to FMC slot |
---|
125 | |
---|
126 | All configs not listed below are handled post-boot by MicroBlaze application |
---|
127 | |
---|
128 | No Clock Module: |
---|
129 | -Select CLK1 |
---|
130 | -Enable OUT3 as 80MHz LVDS |
---|
131 | |
---|
132 | CM-MMCX Configs: |
---|
133 | A: Same as No Clock Module |
---|
134 | |
---|
135 | B/C: -Select CLK2 |
---|
136 | -Enable OUT3 as 80MHz LVDS |
---|
137 | |
---|
138 | CM-PLL Configs: |
---|
139 | A/B/C: -Select CLK2 (input from clock module) |
---|
140 | -Enable OUT3 (output to FPGA) as 80MHz LVDS |
---|
141 | |
---|
142 | Relevant registers: |
---|
143 | 0x45: Selects clock input: 0x00 for off-board, 0x01 for on-board |
---|
144 | 0x51: 0x80 bypasses OUT3 divider (output to FPGA) |
---|
145 | 0x5A: Trigger device update from SPI registers (self-clearing) |
---|
146 | ***************************************************************************************/ |
---|
147 | u8 cfg_nocm_samp_addr[] = {0x45, 0x51, 0x5A, 0xFF}; |
---|
148 | u8 cfg_nocm_samp_data[] = {0x01, 0x80, 0x01, 0xFF}; |
---|
149 | |
---|
150 | u8 cfg_cmmmcx_A_samp_addr[] = {0x45, 0x51, 0x5A, 0xFF}; |
---|
151 | u8 cfg_cmmmcx_A_samp_data[] = {0x01, 0x80, 0x01, 0xFF}; |
---|
152 | |
---|
153 | u8 cfg_cmmmcx_B_samp_addr[] = {0x45, 0x51, 0x5A, 0xFF}; |
---|
154 | u8 cfg_cmmmcx_B_samp_data[] = {0x00, 0x80, 0x01, 0xFF}; |
---|
155 | |
---|
156 | u8 cfg_cmmmcx_C_samp_addr[] = {0x45, 0x51, 0x5A, 0xFF}; |
---|
157 | u8 cfg_cmmmcx_C_samp_data[] = {0x00, 0x80, 0x01, 0xFF}; |
---|
158 | |
---|
159 | u8 cfg_cmpll_A_samp_addr[] = {0x45, 0x51, 0x5A, 0xFF}; |
---|
160 | u8 cfg_cmpll_A_samp_data[] = {0x00, 0x80, 0x01, 0xFF}; |
---|
161 | |
---|
162 | u8 cfg_cmpll_B_samp_addr[] = {0x45, 0x51, 0x5A, 0xFF}; |
---|
163 | u8 cfg_cmpll_B_samp_data[] = {0x00, 0x80, 0x01, 0xFF}; |
---|
164 | |
---|
165 | u8 cfg_cmpll_C_samp_addr[] = {0x45, 0x51, 0x5A, 0xFF}; |
---|
166 | u8 cfg_cmpll_C_samp_data[] = {0x00, 0x80, 0x01, 0xFF}; |
---|
167 | |
---|
168 | /*************************************************************************************** |
---|
169 | CM-PLL Buffer/PLL (AD9511): |
---|
170 | CLK1: Input from off-board reference, bypasses PLL |
---|
171 | CLK2: Input from on-board 80MHz VCXO |
---|
172 | OUT0/1/2: Unused LVPECL outputs (unterminated) |
---|
173 | OUT3: LVDS output to clock module header RFCLKBUF pins (rf ref clk buf CLK2 input) |
---|
174 | OUT4: LVDS output to clock module header SAMPCLKBUF pins (samp clk buf CLK2 input) |
---|
175 | |
---|
176 | All configs not listed below are handled post-boot by MicroBlaze application |
---|
177 | |
---|
178 | No Clock Module: |
---|
179 | Toggle reset, power down PLL core and all outputs |
---|
180 | This handles the case of the CM-PLL being mounted but its switches being set to 00 |
---|
181 | It's better to do SPI writes to open pins (i.e. no CM) than let the PLL run free |
---|
182 | |
---|
183 | CM-MMCX Configs: |
---|
184 | Do nothing - no PLL |
---|
185 | |
---|
186 | CM-PLL Configs: |
---|
187 | Common: |
---|
188 | -Toggle reset |
---|
189 | -Disable OUT0/1/2 (unused) |
---|
190 | -Enable OUT4 as 80MHz max-drive LVDS |
---|
191 | |
---|
192 | A: -Configure PLL for 10MHz reference (see below) |
---|
193 | -Disable OUT3 (output to RF ref clk buf) |
---|
194 | |
---|
195 | B: -Configure PLL for 10MHz reference (see below) |
---|
196 | -Enable OUT3 (output to RF ref clk buf) |
---|
197 | |
---|
198 | C: -Configure PLL for 80MHz reference (see below) |
---|
199 | -Enable OUT3 (output to RF ref clk buf) |
---|
200 | |
---|
201 | Relevant registers: |
---|
202 | 0x00: 30 resets, 10 un-resets |
---|
203 | 0x04: A counter b[5:0] |
---|
204 | 0x05: B counter b[12:8] |
---|
205 | 0x06: B counter b[7:0] |
---|
206 | 0x0B: R counter b[13:8] |
---|
207 | 0x0C: R counter b[7:0] |
---|
208 | 0x07: 0x00 disables loss-of-reference state machine |
---|
209 | 0x08: 0x47 enables charge pump, sets STATUS=lock_det, sets positive PFD polarity |
---|
210 | 0x09: 0x70 sets max charge pump current |
---|
211 | 0x0A: 0x08 for normal operation, 10MHz ref; 0x040 for normal operation, 80MHz ref) |
---|
212 | b[1:0]: PLL powerdown (00 or 10=normal operation, 01 or 11=powe down) |
---|
213 | b[4:2]: Prescaler mode (see datasheet for full list) |
---|
214 | 000: FD, div by 1 |
---|
215 | 010: DM, (P/P+1)=2/3 |
---|
216 | 0x3D/3E/3F: 03 powers down LVPECL outputs OUT0/1/2 |
---|
217 | 0x40/41: 01 disables OUT3/4, 02 enables LVDS output OUT3/4 |
---|
218 | 0x51/53: 80 disables divider (W3 board wants 80MHz inputs from clk module) |
---|
219 | 0x45: 02 selects CLK2 (VCXO clk src), powers down CLK1 input, powers up all other I/O |
---|
220 | 0x5A: Trigger device update from SPI registers (self-clearing) |
---|
221 | |
---|
222 | Common reference frequency configs: |
---|
223 | 10MHz: |
---|
224 | PFD freq: 10MHz |
---|
225 | R divider: 1 |
---|
226 | N divider: 8 (implies DM mode, prescaler mode (2/3), A=2, B=3) |
---|
227 | |
---|
228 | 80MHz: |
---|
229 | PFD freq: 80MHz |
---|
230 | R divider: 1 |
---|
231 | N divider: 1 (implies FD mode, prescaler mode div 1, B=1 (bypassed)) |
---|
232 | |
---|
233 | See AD9511 datasheet Table 16 for PLL settings for other valid divider settings |
---|
234 | |
---|
235 | ***************************************************************************************/ |
---|
236 | |
---|
237 | u8 cfg_nocm_pll_addr[] = {0x00, 0x00, 0x0A, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0xFF}; |
---|
238 | u8 cfg_nocm_pll_data[] = {0x30, 0x10, 0x11, 0x03, 0x03, 0x03, 0x01, 0x01, 0xFF}; |
---|
239 | |
---|
240 | u8 cfg_cmpll_A_pll_addr[] = {0x00, 0x00, 0x04, 0x05, 0x06, 0x0B, 0x0C, 0x07, 0x08, 0x09, 0x0A, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x51, 0x53, 0x45, 0x5A, 0xFF}; |
---|
241 | u8 cfg_cmpll_A_pll_data[] = {0x30, 0x10, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x47, 0x70, 0x08, 0x03, 0x03, 0x03, 0x01, 0x02, 0x80, 0x80, 0x02, 0x01, 0xFF}; |
---|
242 | |
---|
243 | u8 cfg_cmpll_B_pll_addr[] = {0x00, 0x00, 0x04, 0x05, 0x06, 0x0B, 0x0C, 0x07, 0x08, 0x09, 0x0A, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x51, 0x53, 0x45, 0x5A, 0xFF}; |
---|
244 | u8 cfg_cmpll_B_pll_data[] = {0x30, 0x10, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x47, 0x70, 0x08, 0x03, 0x03, 0x03, 0x02, 0x02, 0x80, 0x80, 0x02, 0x01, 0xFF}; |
---|
245 | |
---|
246 | u8 cfg_cmpll_C_pll_addr[] = {0x00, 0x00, 0x04, 0x05, 0x06, 0x0B, 0x0C, 0x07, 0x08, 0x09, 0x0A, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x51, 0x53, 0x45, 0x5A, 0xFF}; |
---|
247 | u8 cfg_cmpll_C_pll_data[] = {0x30, 0x10, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x47, 0x70, 0x40, 0x03, 0x03, 0x03, 0x02, 0x02, 0x80, 0x80, 0x02, 0x01, 0xFF}; |
---|
248 | |
---|
249 | int main() { |
---|
250 | |
---|
251 | int addr, i; |
---|
252 | int status = 0; |
---|
253 | |
---|
254 | //Confirm every array is short enough and that every data/addr array pair have matching lengths |
---|
255 | if( (sizeof(cfg_nocm_rfref_addr) > CLKCFG_NUMBYTES_RFREF/2) || (sizeof(cfg_nocm_rfref_addr) != sizeof(cfg_nocm_rfref_addr)) || |
---|
256 | (sizeof(cfg_cmmmcx_A_rfref_addr) > CLKCFG_NUMBYTES_RFREF/2) || (sizeof(cfg_cmmmcx_A_rfref_addr) != sizeof(cfg_cmmmcx_A_rfref_data)) || |
---|
257 | (sizeof(cfg_cmmmcx_B_rfref_addr) > CLKCFG_NUMBYTES_RFREF/2) || (sizeof(cfg_cmmmcx_B_rfref_addr) != sizeof(cfg_cmmmcx_B_rfref_data)) || |
---|
258 | (sizeof(cfg_cmmmcx_C_rfref_addr) > CLKCFG_NUMBYTES_RFREF/2) || (sizeof(cfg_cmmmcx_C_rfref_addr) != sizeof(cfg_cmmmcx_C_rfref_data)) || |
---|
259 | (sizeof(cfg_cmpll_A_rfref_addr) > CLKCFG_NUMBYTES_RFREF/2) || (sizeof(cfg_cmpll_A_rfref_addr) != sizeof(cfg_cmpll_A_rfref_data)) || |
---|
260 | (sizeof(cfg_cmpll_B_rfref_addr) > CLKCFG_NUMBYTES_RFREF/2) || (sizeof(cfg_cmpll_B_rfref_addr) != sizeof(cfg_cmpll_B_rfref_data)) || |
---|
261 | (sizeof(cfg_cmpll_C_rfref_addr) > CLKCFG_NUMBYTES_RFREF/2) || (sizeof(cfg_cmpll_C_rfref_addr) != sizeof(cfg_cmpll_C_rfref_data)) ) { |
---|
262 | status = -1; |
---|
263 | xil_printf("ERROR: Invalid lengths for some RF ref clk buffer config data/addr arrays. Check max lengths and matching data/addr lengths.\n"); |
---|
264 | } |
---|
265 | if( (sizeof(cfg_nocm_samp_addr) > CLKCFG_NUMBYTES_SAMP/2) || (sizeof(cfg_nocm_samp_addr) != sizeof(cfg_nocm_samp_addr)) || |
---|
266 | (sizeof(cfg_cmmmcx_A_samp_addr) > CLKCFG_NUMBYTES_SAMP/2) || (sizeof(cfg_cmmmcx_A_samp_addr) != sizeof(cfg_cmmmcx_A_samp_data)) || |
---|
267 | (sizeof(cfg_cmmmcx_B_samp_addr) > CLKCFG_NUMBYTES_SAMP/2) || (sizeof(cfg_cmmmcx_B_samp_addr) != sizeof(cfg_cmmmcx_B_samp_data)) || |
---|
268 | (sizeof(cfg_cmmmcx_C_samp_addr) > CLKCFG_NUMBYTES_SAMP/2) || (sizeof(cfg_cmmmcx_C_samp_addr) != sizeof(cfg_cmmmcx_C_samp_data)) || |
---|
269 | (sizeof(cfg_cmpll_A_samp_addr) > CLKCFG_NUMBYTES_SAMP/2) || (sizeof(cfg_cmpll_A_samp_addr) != sizeof(cfg_cmpll_A_samp_data)) || |
---|
270 | (sizeof(cfg_cmpll_B_samp_addr) > CLKCFG_NUMBYTES_SAMP/2) || (sizeof(cfg_cmpll_B_samp_addr) != sizeof(cfg_cmpll_B_samp_data)) || |
---|
271 | (sizeof(cfg_cmpll_C_samp_addr) > CLKCFG_NUMBYTES_SAMP/2) || (sizeof(cfg_cmpll_C_samp_addr) != sizeof(cfg_cmpll_C_samp_data)) ) { |
---|
272 | status = -1; |
---|
273 | xil_printf("ERROR: Invalid lengths for some samp clk buffer config data/addr arrays. Check max lengths and matching data/addr lengths.\n"); |
---|
274 | } |
---|
275 | if( (sizeof(cfg_nocm_pll_addr) > CLKCFG_NUMBYTES_PLL/2) || (sizeof(cfg_nocm_pll_addr) != sizeof(cfg_nocm_pll_addr)) || |
---|
276 | (sizeof(cfg_cmpll_A_pll_addr) > CLKCFG_NUMBYTES_PLL/2) || (sizeof(cfg_cmpll_A_pll_addr) != sizeof(cfg_cmpll_A_pll_data)) || |
---|
277 | (sizeof(cfg_cmpll_B_pll_addr) > CLKCFG_NUMBYTES_PLL/2) || (sizeof(cfg_cmpll_B_pll_addr) != sizeof(cfg_cmpll_B_pll_data)) || |
---|
278 | (sizeof(cfg_cmpll_C_pll_addr) > CLKCFG_NUMBYTES_PLL/2) || (sizeof(cfg_cmpll_C_pll_addr) != sizeof(cfg_cmpll_C_pll_data)) ) { |
---|
279 | status = -1; |
---|
280 | xil_printf("ERROR: Invalid lengths for some PLL config data/addr arrays. Check max lengths and matching data/addr lengths.\n"); |
---|
281 | } |
---|
282 | |
---|
283 | if(status != STAT_SUCCESS) {return -1;} |
---|
284 | |
---|
285 | xil_printf("\n\n******************************************\n"); |
---|
286 | xil_printf("Starting Clock Config Data EEPROM Write...\n\n"); |
---|
287 | |
---|
288 | //Initialize the EEPROM driver |
---|
289 | iic_eeprom_init(EEPROM_BASEADDR, 0x64); |
---|
290 | |
---|
291 | #if 0 |
---|
292 | //Initialize the full clk config region to 0xFF |
---|
293 | // This ensures all address/data values not supplied by the user are left with a safe "don't care" value |
---|
294 | xil_printf("\tInitializing config data region in EEPROM\n"); |
---|
295 | |
---|
296 | for(addr = CLKCFG_ADDR_BASE; addr <= CLKCFG_ADDR_MAX; addr++) { |
---|
297 | status = iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr, 0xFF); |
---|
298 | if(status != STAT_SUCCESS) {xil_printf("ERROR: Failed to init byte addr %d; exiting\n", addr); return -1;} |
---|
299 | } |
---|
300 | #endif |
---|
301 | |
---|
302 | //Write the magic delimeter value to the base of the clk config region |
---|
303 | addr = CLKCFG_ADDR_BASE; |
---|
304 | status = iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)CLKCFG_DELIM_B0); |
---|
305 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)CLKCFG_DELIM_B1); |
---|
306 | if(status != STAT_SUCCESS) {xil_printf("ERROR: Failed to write delim; exiting\n"); return -1;} |
---|
307 | |
---|
308 | //Write the RF ref clk buffer addr/data bytes |
---|
309 | xil_printf("\tWriting RF reference clock buffer config data at addr %d\n", (u16)CLKCFG_ADDR_RFREF_NOCM); |
---|
310 | |
---|
311 | status = STAT_SUCCESS; |
---|
312 | |
---|
313 | addr = (u16)CLKCFG_ADDR_RFREF_NOCM; |
---|
314 | for(i=0; i<sizeof(cfg_nocm_rfref_addr); i++) { |
---|
315 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_nocm_rfref_addr[i]); |
---|
316 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_nocm_rfref_data[i]); |
---|
317 | } |
---|
318 | addr = (u16)CLKCFG_ADDR_RFREF_CMMMCX_A; |
---|
319 | for(i=0; i<sizeof(cfg_cmmmcx_A_rfref_addr); i++) { |
---|
320 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_A_rfref_addr[i]); |
---|
321 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_A_rfref_data[i]); |
---|
322 | } |
---|
323 | addr = (u16)CLKCFG_ADDR_RFREF_CMMMCX_B; |
---|
324 | for(i=0; i<sizeof(cfg_cmmmcx_B_rfref_addr); i++) { |
---|
325 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_B_rfref_addr[i]); |
---|
326 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_B_rfref_data[i]); |
---|
327 | } |
---|
328 | addr = (u16)CLKCFG_ADDR_RFREF_CMMMCX_C; |
---|
329 | for(i=0; i<sizeof(cfg_cmmmcx_C_rfref_addr); i++) { |
---|
330 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_C_rfref_addr[i]); |
---|
331 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_C_rfref_data[i]); |
---|
332 | } |
---|
333 | addr = (u16)CLKCFG_ADDR_RFREF_CMPLL_A; |
---|
334 | for(i=0; i<sizeof(cfg_cmpll_A_rfref_addr); i++) { |
---|
335 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_A_rfref_addr[i]); |
---|
336 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_A_rfref_data[i]); |
---|
337 | } |
---|
338 | addr = (u16)CLKCFG_ADDR_RFREF_CMPLL_B; |
---|
339 | for(i=0; i<sizeof(cfg_cmpll_B_rfref_addr); i++) { |
---|
340 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_B_rfref_addr[i]); |
---|
341 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_B_rfref_data[i]); |
---|
342 | } |
---|
343 | addr = (u16)CLKCFG_ADDR_RFREF_CMPLL_C; |
---|
344 | for(i=0; i<sizeof(cfg_cmpll_C_rfref_addr); i++) { |
---|
345 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_C_rfref_addr[i]); |
---|
346 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_C_rfref_data[i]); |
---|
347 | } |
---|
348 | if(status != STAT_SUCCESS) {xil_printf("ERROR: Failed to write RF ref clk config data; exiting\n"); return -1;} |
---|
349 | |
---|
350 | //Write the samp clk buffer addr/data bytes |
---|
351 | xil_printf("\tWriting sampling clock buffer config data at addr %d\n", (u16)CLKCFG_ADDR_SAMP_NOCM); |
---|
352 | |
---|
353 | status = STAT_SUCCESS; |
---|
354 | |
---|
355 | addr = (u16)CLKCFG_ADDR_SAMP_NOCM; |
---|
356 | for(i=0; i<sizeof(cfg_nocm_samp_addr); i++) { |
---|
357 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_nocm_samp_addr[i]); |
---|
358 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_nocm_samp_data[i]); |
---|
359 | } |
---|
360 | addr = (u16)CLKCFG_ADDR_SAMP_CMMMCX_A; |
---|
361 | for(i=0; i<sizeof(cfg_cmmmcx_A_samp_addr); i++) { |
---|
362 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_A_samp_addr[i]); |
---|
363 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_A_samp_data[i]); |
---|
364 | } |
---|
365 | addr = (u16)CLKCFG_ADDR_SAMP_CMMMCX_B; |
---|
366 | for(i=0; i<sizeof(cfg_cmmmcx_B_samp_addr); i++) { |
---|
367 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_B_samp_addr[i]); |
---|
368 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_B_samp_data[i]); |
---|
369 | } |
---|
370 | addr = (u16)CLKCFG_ADDR_SAMP_CMMMCX_C; |
---|
371 | for(i=0; i<sizeof(cfg_cmmmcx_C_samp_addr); i++) { |
---|
372 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_C_samp_addr[i]); |
---|
373 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmmmcx_C_samp_data[i]); |
---|
374 | } |
---|
375 | addr = (u16)CLKCFG_ADDR_SAMP_CMPLL_A; |
---|
376 | for(i=0; i<sizeof(cfg_cmpll_A_samp_addr); i++) { |
---|
377 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_A_samp_addr[i]); |
---|
378 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_A_samp_data[i]); |
---|
379 | } |
---|
380 | addr = (u16)CLKCFG_ADDR_SAMP_CMPLL_B; |
---|
381 | for(i=0; i<sizeof(cfg_cmpll_B_samp_addr); i++) { |
---|
382 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_B_samp_addr[i]); |
---|
383 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_B_samp_data[i]); |
---|
384 | } |
---|
385 | addr = (u16)CLKCFG_ADDR_SAMP_CMPLL_C; |
---|
386 | for(i=0; i<sizeof(cfg_cmpll_C_samp_addr); i++) { |
---|
387 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_C_samp_addr[i]); |
---|
388 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_C_samp_data[i]); |
---|
389 | } |
---|
390 | if(status != STAT_SUCCESS) {xil_printf("ERROR: Failed to write samp clk config data; exiting\n"); return -1;} |
---|
391 | |
---|
392 | //Write the PLL addr/data bytes |
---|
393 | xil_printf("\tWriting PLL config data at addr %d\n", (u16)CLKCFG_ADDR_PLL_NOCM); |
---|
394 | |
---|
395 | status = STAT_SUCCESS; |
---|
396 | |
---|
397 | addr = (u16)CLKCFG_ADDR_PLL_NOCM; |
---|
398 | for(i=0; i<sizeof(cfg_nocm_pll_addr); i++) { |
---|
399 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_nocm_pll_addr[i]); |
---|
400 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_nocm_pll_data[i]); |
---|
401 | } |
---|
402 | addr = (u16)CLKCFG_ADDR_PLL_CMPLL_A; |
---|
403 | for(i=0; i<sizeof(cfg_cmpll_A_pll_addr); i++) { |
---|
404 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_A_pll_addr[i]); |
---|
405 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_A_pll_data[i]); |
---|
406 | } |
---|
407 | addr = (u16)CLKCFG_ADDR_PLL_CMPLL_B; |
---|
408 | for(i=0; i<sizeof(cfg_cmpll_B_pll_addr); i++) { |
---|
409 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_B_pll_addr[i]); |
---|
410 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_B_pll_data[i]); |
---|
411 | } |
---|
412 | addr = (u16)CLKCFG_ADDR_PLL_CMPLL_C; |
---|
413 | for(i=0; i<sizeof(cfg_cmpll_C_pll_addr); i++) { |
---|
414 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_C_pll_addr[i]); |
---|
415 | status |= iic_eeprom_writeByte(EEPROM_BASEADDR, (u16)addr++, (u8)cfg_cmpll_C_pll_data[i]); |
---|
416 | } |
---|
417 | if(status != STAT_SUCCESS) {xil_printf("ERROR: Failed to write PLL config data; exiting\n"); return -1;} |
---|
418 | |
---|
419 | xil_printf("\nDone! Clock configuration data now ready for use by w3_clock_config_axi core.\n\n"); |
---|
420 | |
---|
421 | return 0; |
---|
422 | } |
---|