diff options
Diffstat (limited to 'firmware/microblaze/lib/clocks.c')
-rw-r--r-- | firmware/microblaze/lib/clocks.c | 81 |
1 files changed, 54 insertions, 27 deletions
diff --git a/firmware/microblaze/lib/clocks.c b/firmware/microblaze/lib/clocks.c index ccc4a7cc7..2b352a385 100644 --- a/firmware/microblaze/lib/clocks.c +++ b/firmware/microblaze/lib/clocks.c @@ -25,40 +25,60 @@ #include "ad9510.h" #include "spi.h" #include "u2_init.h" -#include "nonstdio.h" + +//USRP2PLUS clocks: +//Clock 0: testclk +//Clock 1: FPGA clk +//Clock 2: ADC clk +//Clock 3: DAC clk +//Clock 4: SER clk +//Clock 5: TX dboard clk +//Clock 6: EXP clk +//Clock 7: RX dboard clk + +//TODO: should have enough brains to init the FPGA clock for USRP2+. all others are suspect. +//note that without EEPROM support u2_hw_rev_major is going to be incorrect. void clocks_init(void) { // Set up basic clocking functions in AD9510 - ad9510_write_reg(0x45, 0x00); // CLK2 drives distribution + ad9510_write_reg(0x45, 0x01); // CLK2 drives distribution + //enable the 100MHz clock output to the FPGA for 50MHz CPU clock clocks_enable_fpga_clk(true, 1); spi_wait(); // Set up PLL for 10 MHz reference // Reg 4, A counter, Don't Care - ad9510_write_reg(0x05, 0x00); // Reg 5, B counter MSBs, 0 - ad9510_write_reg(0x06, 0x05); // Reg 6, B counter LSBs, 5 +// ad9510_write_reg(0x05, 0x00); // Reg 5, B counter MSBs, 0 +// ad9510_write_reg(0x06, 0x05); // Reg 6, B counter LSBs, 5 // Reg 7, Loss of reference detect, doesn't work yet, 0 - ad9510_write_reg(0x5A, 0x01); // Update Regs +// ad9510_write_reg(0x5A, 0x01); // Update Regs // Primary clock configuration - clocks_mimo_config(MC_WE_DONT_LOCK); +// clocks_mimo_config(MC_WE_DONT_LOCK); + + + //wait for the clock to stabilize + while(!clocks_lock_detect()); + + //issue a reset to the DCM so it locks up to the new freq + output_regs->clk_ctrl |= CLK_RESET; // Set up other clocks //clocks_enable_test_clk(false, 0); //clocks_enable_tx_dboard(false, 0); //clocks_enable_rx_dboard(false, 0); - clocks_enable_eth_phyclk(false, 0); +// clocks_enable_eth_phyclk(false, 0); //PHY clk is separate now (u2r4, u2p) // Enable clock to ADCs and DACs //clocks_enable_dac_clk(true, 1); //clocks_enable_adc_clk(true, 1); } - +/* void clocks_mimo_config(int flags) { @@ -86,7 +106,7 @@ clocks_mimo_config(int flags) spi_wait(); // Allow for clock switchover - + // The below masks include 0x10, which issues a reset to the DCM. if (flags & _MC_WE_LOCK){ // WE LOCK if (flags & _MC_MIMO_CLK_INPUT) { // Turn on ref output and choose the MIMO connector @@ -103,18 +123,17 @@ clocks_mimo_config(int flags) } // Do we drive a clock onto the MIMO connector? - if (flags & MC_PROVIDE_CLK_TO_MIMO) - clocks_enable_clkexp_out(true,10); - else - clocks_enable_clkexp_out(false,0); +// if (flags & MC_PROVIDE_CLK_TO_MIMO) +// clocks_enable_clkexp_out(true,10); +// else +// clocks_enable_clkexp_out(false,0); } +*/ bool clocks_lock_detect() { - if(pic_regs->pending & PIC_CLKSTATUS) - return true; - return false; + return (pic_regs->pending & PIC_CLKSTATUS); } int inline @@ -136,21 +155,23 @@ clocks_gen_div(int divisor) #define CLOCK_MODE_LVDS 2 #define CLOCK_MODE_CMOS 3 +//CHANGED: set to PECL for default behavior void clocks_enable_XXX_clk(bool enable, int divisor, int reg_en, int reg_div, int mode) { int enable_word, div_word, div_en_word; switch(mode) { - case CLOCK_MODE_PECL : - enable_word = enable ? 0x08 : 0x0A; - break; case CLOCK_MODE_LVDS : enable_word = enable ? 0x02 : 0x03; break; case CLOCK_MODE_CMOS : enable_word = enable ? 0x08 : 0x09; break; + case CLOCK_MODE_PECL : + default: + enable_word = enable ? 0x08 : 0x0A; + break; } if(enable && (divisor>1)) { div_word = clocks_gen_div(divisor); @@ -180,8 +201,8 @@ clocks_enable_fpga_clk(bool enable, int divisor) { clocks_enable_XXX_clk(enable,divisor,0x3D,0x4A,CLOCK_MODE_PECL); } - -// Clock 2 on Rev 3, Clock 5 on Rev 4 +/* +// Clock 2 on Rev 3, Clock 5 on Rev 4, Clock 6 on USRP2+ void clocks_enable_clkexp_out(bool enable, int divisor) { @@ -192,13 +213,19 @@ clocks_enable_clkexp_out(bool enable, int divisor) ad9510_write_reg(0x35,0x00); // Set Full Scale to nearly 10ns ad9510_write_reg(0x36,0x1c); // Set fine delay. 0x20 is midscale clocks_enable_XXX_clk(enable,divisor,0x41,0x52,CLOCK_MODE_LVDS); - } + else if(u2_hw_rev_major == 10) { + ad9510_write_reg(0x34, 0x00); + ad9510_write_reg(0x35, 0x00); + ad9510_write_reg(0x36, 0x1C); + clocks_enable_XXX_clk(enable, divisor, 0x42, 0x52, CLOCK_MODE_LVDS); + } else - putstr("ERR: Invalid Rev\n"); + putstr("ERR (clocks_enable_clkexp_out): Invalid hw rev, don't know what to do!\n"); } - -// Clock 5 on Rev 3, none (was 2) on Rev 4 +*/ +/* +// Clock 5 on Rev 3, none (was 2) on Rev 4, none on USRP2+ void clocks_enable_eth_phyclk(bool enable, int divisor) { @@ -207,9 +234,9 @@ clocks_enable_eth_phyclk(bool enable, int divisor) else if(u2_hw_rev_major == 4) clocks_enable_XXX_clk(enable,divisor,0x3E,0x4C,CLOCK_MODE_PECL); else - putstr("ERR: Invalid Rev\n"); + putstr("(clocks_enable_eth_phyclk): no eth PHY clock or invalid hw rev\n"); //not really an error } - +*/ // Clock 3 /*void clocks_enable_dac_clk(bool enable, int divisor) |