[4322] | 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 | |
---|
[4319] | 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: |
---|
[4322] | 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 |
---|
[4319] | 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 | |
---|
[4322] | 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}; |
---|
[4319] | 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 | |
---|
[4322] | 419 | xil_printf("\nDone! Clock configuration data now ready for use by w3_clock_config_axi core.\n\n"); |
---|
[4319] | 420 | |
---|
| 421 | return 0; |
---|
| 422 | } |
---|