diff options
author | jblum | 2009-02-04 03:06:20 +0000 |
---|---|---|
committer | jblum | 2009-02-04 03:06:20 +0000 |
commit | 620c5db0cc448c8b275943069e39cb0eec2f08a0 (patch) | |
tree | bca0abd1a39a6e82b9ebc9703f0915a5cefd8160 /usrp2/firmware/lib/db_xcvr2450.c | |
parent | 27b85cba78bb01b5e70929ce110fc6f2ce14fdcf (diff) | |
download | gnuradio-620c5db0cc448c8b275943069e39cb0eec2f08a0.tar.gz gnuradio-620c5db0cc448c8b275943069e39cb0eec2f08a0.tar.bz2 gnuradio-620c5db0cc448c8b275943069e39cb0eec2f08a0.zip |
usrp2: xcvr working
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10382 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'usrp2/firmware/lib/db_xcvr2450.c')
-rw-r--r-- | usrp2/firmware/lib/db_xcvr2450.c | 207 |
1 files changed, 91 insertions, 116 deletions
diff --git a/usrp2/firmware/lib/db_xcvr2450.c b/usrp2/firmware/lib/db_xcvr2450.c index d1d6bb4ea..d2e96a3e6 100644 --- a/usrp2/firmware/lib/db_xcvr2450.c +++ b/usrp2/firmware/lib/db_xcvr2450.c @@ -21,6 +21,7 @@ #include <spi.h> #include <hal_io.h> #include <clocks.h> +#include <mdelay.h> void set_atr_regs(int bank, struct db_base *db); //FIXME I need to be in a header @@ -51,8 +52,9 @@ void set_atr_regs(int bank, struct db_base *db); //FIXME I need to be in a heade #define TX_SAFE_IO HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|AD9515DIV #define TX_ATR_MASK HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN|AD9515DIV -#define TUN_FREQ_MIN U2_DOUBLE_TO_FXPT_FREQ(2.4e9) -#define TUN_FREQ_MAX U2_DOUBLE_TO_FXPT_FREQ(6.0e9) +#define TUN_FREQ_MIN U2_DOUBLE_TO_FXPT_FREQ(2.3e9) +#define TUN_FREQ_MAX U2_DOUBLE_TO_FXPT_FREQ(6.1e9) +#define REF_CLK_DIV 1 bool xcvr2450_init(struct db_base *db); bool xcvr2450_set_freq(struct db_base *db, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc); @@ -105,17 +107,12 @@ struct db_xcvr2450_rx db_xcvr2450_rx = { .base.is_quadrature = true, .base.i_and_q_swapped = false, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4.25e6), .base.init = xcvr2450_init, .base.set_freq = xcvr2450_set_freq, .base.set_gain = xcvr2450_set_gain_rx, - //.base.set_tx_enable = 0, .base.atr_mask = RX_ATR_MASK, .base.atr_txval = 0x0, .base.atr_rxval = 0x0, - // .base.atr_tx_delay = - // .base.atr_rx_delay = - .common.spi_mask = SPI_SS_RX_DB, }; struct db_xcvr2450_tx db_xcvr2450_tx = { @@ -131,30 +128,25 @@ struct db_xcvr2450_tx db_xcvr2450_tx = { .base.is_quadrature = true, .base.i_and_q_swapped = true, .base.spectrum_inverted = false, - //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4.25e6), .base.init = xcvr2450_init, .base.set_freq = xcvr2450_set_freq, .base.set_gain = xcvr2450_set_gain_tx, - //.base.set_tx_enable = xcvr2450_set_tx_enable, .base.atr_mask = TX_ATR_MASK, .base.atr_txval = 0x0, .base.atr_rxval = 0x0, - // .base.atr_tx_delay = - // .base.atr_rx_delay = - .common.spi_mask = SPI_SS_TX_DB, }; /************************************************** * Set Registers **************************************************/ -void +static void send_reg(struct db_xcvr2450_dummy *db, int v){ // Send 24 bits, it keeps last 18 clocked in spi_transact(SPI_TXONLY,db->common.spi_mask,v,24,SPIF_PUSH_FALL); - printf("xcvr2450: Setting reg %d to %x\n", (v&15), v); + //printf("xcvr2450: Setting reg %d to %x\n", (v&15), v); } -void +static void set_reg_standby(struct db_xcvr2450_dummy *db){ int reg_standby = ( (db->common.d_mimo<<17) | @@ -165,7 +157,7 @@ set_reg_standby(struct db_xcvr2450_dummy *db){ send_reg(db, reg_standby); } -void +static void set_reg_int_divider(struct db_xcvr2450_dummy *db){ int reg_int_divider = (( (db->common.d_frac_div & 0x03)<<16) | @@ -173,18 +165,18 @@ set_reg_int_divider(struct db_xcvr2450_dummy *db){ send_reg(db, reg_int_divider); } -void +static void set_reg_frac_divider(struct db_xcvr2450_dummy *db){ int reg_frac_divider = ((db->common.d_frac_div & 0xfffc)<<2) | 4; send_reg(db, reg_frac_divider); } -void +static void set_reg_bandselpll(struct db_xcvr2450_dummy *db){ int reg_bandselpll = ((db->common.d_mimo<<17) | (1<<16) | (1<<15) | - (0<<11) | + (0<<11) | //this bit gets toggled (db->common.d_highband<<10) | (db->common.d_cp_current<<9) | (db->common.d_ref_div<<5) | @@ -201,7 +193,7 @@ set_reg_bandselpll(struct db_xcvr2450_dummy *db){ send_reg(db, reg_bandselpll); } -void +static void set_reg_cal(struct db_xcvr2450_dummy *db){ // FIXME do calibration int reg_cal = ( @@ -209,7 +201,7 @@ set_reg_cal(struct db_xcvr2450_dummy *db){ send_reg(db, reg_cal); } -void +static void set_reg_lpf(struct db_xcvr2450_dummy *db){ int reg_lpf = ( (db->common.d_rssi_hbw<<15) | @@ -219,7 +211,7 @@ set_reg_lpf(struct db_xcvr2450_dummy *db){ send_reg(db, reg_lpf); } -void +static void set_reg_rxrssi_ctrl(struct db_xcvr2450_dummy *db){ int reg_rxrssi_ctrl = ( (db->common.d_rxvga_ser<<16) | @@ -232,7 +224,7 @@ set_reg_rxrssi_ctrl(struct db_xcvr2450_dummy *db){ send_reg(db, reg_rxrssi_ctrl); } -void +static void set_reg_txlin_gain(struct db_xcvr2450_dummy *db){ int reg_txlin_gain = ( (db->common.d_txvga_ser<<14) | @@ -243,7 +235,7 @@ set_reg_txlin_gain(struct db_xcvr2450_dummy *db){ send_reg(db, reg_txlin_gain); } -void +static void set_reg_pabias(struct db_xcvr2450_dummy *db){ int reg_pabias = ( (db->common.d_pabias_delay<<10) | @@ -251,7 +243,7 @@ set_reg_pabias(struct db_xcvr2450_dummy *db){ send_reg(db, reg_pabias); } -void +static void set_reg_rxgain(struct db_xcvr2450_dummy *db){ int reg_rxgain = ( (db->common.d_rx_rf_gain<<9) | @@ -259,7 +251,7 @@ set_reg_rxgain(struct db_xcvr2450_dummy *db){ send_reg(db, reg_rxgain); } -void +static void set_reg_txgain(struct db_xcvr2450_dummy *db){ int reg_txgain = ( (db->common.d_txgain<<4) | 12); @@ -269,18 +261,17 @@ set_reg_txgain(struct db_xcvr2450_dummy *db){ /************************************************** * GPIO **************************************************/ -void +static void set_gpio(struct db_xcvr2450_dummy *db){ - // We calculate four values: - // - // io_rx_while_rx: what to drive onto io_rx_* when receiving - // io_rx_while_tx: what to drive onto io_rx_* when transmitting - // io_tx_while_rx: what to drive onto io_tx_* when receiving - // io_tx_while_tx: what to drive onto io_tx_* when transmitting - // - // B1-B7 is ignored as gain is set serially for now. - - int rx_hp, tx_antsel, rx_antsel, tx_pa_sel; + //set tx/rx gpio pins for auto tr + + int rx_hp, tx_antsel, rx_antsel, tx_pa_sel, ad9515_sel=0; + + if(db->common.d_ad9515_div == 3) + ad9515_sel = AD9515DIV; + else if(db->common.d_ad9515_div == 2) + ad9515_sel = 0; + if(db->common.d_rx_hp_pin) rx_hp = RX_HP; else @@ -307,8 +298,8 @@ set_gpio(struct db_xcvr2450_dummy *db){ db->base.atr_txval = EN|rx_hp; set_atr_regs(GPIO_RX_BANK, (struct db_base *)db); /* set tx bank */ - db->base.atr_rxval = HB_PA_OFF|LB_PA_OFF|rx_antsel|AD9515DIV; - db->base.atr_txval = tx_pa_sel|tx_antsel|TX_EN|AD9515DIV; + db->base.atr_rxval = HB_PA_OFF|LB_PA_OFF|rx_antsel|ad9515_sel; + db->base.atr_txval = tx_pa_sel|tx_antsel|TX_EN|ad9515_sel; set_atr_regs(GPIO_TX_BANK, (struct db_base *)db); } @@ -318,7 +309,7 @@ set_gpio(struct db_xcvr2450_dummy *db){ bool xcvr2450_init(struct db_base *dbb){ struct db_xcvr2450_dummy *db = (struct db_xcvr2450_dummy *) dbb; - // Sane defaults + /* set sane defaults */ db->common.d_mimo = 1; // 0 = OFF, 1 = ON db->common.d_int_div = 192; // 128 = min, 255 = max db->common.d_frac_div = 0; // 0 = min, 65535 = max @@ -348,29 +339,10 @@ xcvr2450_init(struct db_base *dbb){ db->common.d_rx_rf_gain = 0; // 0 = 0dB, 1 = 0dB, 2 = 15dB, 3 = 30dB db->common.d_rx_bb_gain = 16; // 0 = min, 31 = max (0 - 62 dB) db->common.d_txgain = 63; // 0 = min, 63 = max - - clocks_enable_tx_dboard(true, 1); - - /*--------------------------------> !!! taken care of by db base operations - // Initialize GPIO and ATR - tx_write_io(TX_SAFE_IO, TX_OE_MASK); - tx_write_oe(TX_OE_MASK, ~0); - tx_set_atr_txval(TX_SAFE_IO); - tx_set_atr_rxval(TX_SAFE_IO); - tx_set_atr_mask(TX_OE_MASK); - - rx_write_io(RX_SAFE_IO, RX_OE_MASK); - rx_write_oe(RX_OE_MASK, ~0); - rx_set_atr_rxval(RX_SAFE_IO); - rx_set_atr_txval(RX_SAFE_IO); - rx_set_atr_mask(RX_OE_MASK); - ---------------------------------------> replaced with set_gpio - * */ - + db->common.spi_mask = SPI_SS_RX_DB; + /* Initialize chipset */ + clocks_enable_tx_dboard(true, REF_CLK_DIV); set_gpio(db); - - // Initialize chipset - // TODO: perform reset sequence to ensure power up defaults set_reg_standby(db); set_reg_bandselpll(db); set_reg_cal(db); @@ -380,27 +352,22 @@ xcvr2450_init(struct db_base *dbb){ set_reg_pabias(db); set_reg_rxgain(db); set_reg_txgain(db); - //FIXME: set_freq(2.45e9); - u2_fxpt_freq_t dc; - db->base.set_freq(dbb, U2_DOUBLE_TO_FXPT_FREQ(4.55e9), &dc); - - db->base.set_gain(dbb, (db->base.gain_max - db->base.gain_min)/2); //set mid-range gain + //u2_fxpt_freq_t dc; + //db->base.set_freq(dbb, U2_DOUBLE_TO_FXPT_FREQ(2.434e9), &dc); return true; } /************************************************** * Lock detect **************************************************/ -bool +static bool lock_detect(){ - /* - @returns: the value of the VCO/PLL lock detect bit. - @rtype: 0 or 1 - */ + //true when the VCO/PLL lock detect bit is set. if(hal_gpio_read(GPIO_RX_BANK) & LOCKDET) { return true; } else { // Give it a second chance + mdelay(1); if(hal_gpio_read(GPIO_RX_BANK) & LOCKDET) return true; else @@ -413,57 +380,64 @@ lock_detect(){ **************************************************/ bool xcvr2450_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc){ + unsigned int scaler, div_factor, actual_div_q16; struct db_xcvr2450_dummy *db = (struct db_xcvr2450_dummy *) dbb; - //ensure gain in within range - if(!(freq >= db->base.freq_min && freq <= db->base.freq_max)) { + /* ensure freq is within low range or high range */ + if(!( + (freq >= db->base.freq_min && freq <= U2_DOUBLE_TO_FXPT_FREQ(2.6e9)) || + (freq >= U2_DOUBLE_TO_FXPT_FREQ(4.8e9) && freq <= db->base.freq_max))) { return false; } - - int scaler; - if(freq > U2_DOUBLE_TO_FXPT_FREQ(3e9)) { + /* set the highband bit */ + if(freq > U2_DOUBLE_TO_FXPT_FREQ(5.408e9)) { + db->common.d_highband = 1; + //printf("5-HB\n"); + } + else { + db->common.d_highband = 0; + //printf("5-LB\n"); + } + /* set the 5 gig bit, determine scaler */ + if(freq > U2_DOUBLE_TO_FXPT_FREQ(4e9)) { db->common.d_five_gig = 1; - db->common.d_ad9515_div = 3; - //scaler = (4.0/5.0); - //vco_freq = (4*freq)/5; scaler = 5; - printf("5-GHZ\n"); + //printf("5-GHZ\n"); } else { db->common.d_five_gig = 0; - db->common.d_ad9515_div = 3; - //scaler = (4.0/3.0); - //vco_freq = (4*freq)/3; scaler = 3; - printf("2.4-GHZ\n"); + //printf("2.4-GHZ\n"); } - - if(freq > U2_DOUBLE_TO_FXPT_FREQ(5.408e9)) { - db->common.d_highband = 1; - printf("5-HB\n"); + /* set the dividers so that div_int >= 131, practical minimum */ + db->common.d_int_div = 0; + unsigned int loop_iter = 0; + while (db->common.d_int_div < 131){ + switch(loop_iter){ + case 0: + db->common.d_ad9515_div = 3; + db->common.d_ref_div = 1; + break; + case 1: + db->common.d_ad9515_div = 2; + db->common.d_ref_div = 2; + break; + default: + db->common.d_ad9515_div = 3; + db->common.d_ref_div = loop_iter; + } + loop_iter++; + div_factor = db->common.d_ref_div*db->common.d_ad9515_div*4*REF_CLK_DIV; + /* calculate the fractional divisor */ + actual_div_q16 = ((freq*div_factor)/(scaler*MASTER_CLK_RATE)) >> (U2_FPF_RP-16); + db->common.d_int_div = actual_div_q16 >> 16; } - else { - db->common.d_highband = 0; - printf("5-LB\n"); - } - - int div_factor = db->common.d_ref_div*db->common.d_ad9515_div*4; - - u2_fxpt_freq_t div_q20 = freq*div_factor/(scaler*MASTER_CLK_RATE); - - db->common.d_int_div = div_q20>>U2_FPF_RP; - db->common.d_frac_div = (div_q20>>4)&0xffff; - - unsigned int actual_div_q16 = (db->common.d_int_div<<16)+db->common.d_frac_div; - - printf("scaler %d, div_factor %d, %u\n", scaler, div_factor, db->common.d_int_div); - - u2_fxpt_freq_t actual_freq = ((((u2_fxpt_freq_t)MASTER_CLK_RATE)*actual_div_q16*scaler) / div_factor) << 4; - *dc = actual_freq; - + db->common.d_frac_div = actual_div_q16 & 0xffff; //isolate lower 16 bits + /* calculate the dc freq */ + *dc = ((((u2_fxpt_freq_t)MASTER_CLK_RATE)*actual_div_q16*scaler) / div_factor) << (U2_FPF_RP-16); + /*printf("scaler %d, div(int) %u, div_factor %d, ad9515_div %u, ref_div %u\n", + scaler, db->common.d_int_div, div_factor, db->common.d_ad9515_div, db->common.d_ref_div); printf("actual div %u, Target Freq %uKHz, Actual Freq %uKHz\n", - actual_div_q16, - u2_fxpt_freq_round_to_int(freq/1000), - u2_fxpt_freq_round_to_int(actual_freq/1000)); - + actual_div_q16, u2_fxpt_freq_round_to_int(freq/1000), u2_fxpt_freq_round_to_int(*dc/1000)); + */ set_gpio(db); set_reg_int_divider(db); set_reg_frac_divider(db); @@ -471,10 +445,9 @@ xcvr2450_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc){ bool ok = lock_detect(); if(!ok){ - printf("Fail %uKHz\n", u2_fxpt_freq_round_to_int(freq/1000)); + printf("Fail lock detect %uKHz\n", u2_fxpt_freq_round_to_int(freq/1000)); } - // return ok; - return true; + return ok; } /************************************************** @@ -483,7 +456,7 @@ xcvr2450_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc){ bool xcvr2450_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain){ struct db_xcvr2450_dummy *db = (struct db_xcvr2450_dummy *) dbb; - //ensure gain in within range + //ensure gain is within range if(!(gain >= db->base.gain_min && gain <= db->base.gain_max)) { return false; } @@ -501,6 +474,7 @@ xcvr2450_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain){ db->common.d_rx_rf_gain = 3; // 30.5 dB RF gain db->common.d_rx_bb_gain = u2_fxpt_gain_round_to_int((gain-U2_DOUBLE_TO_FXPT_GAIN(30.5))/2); } + //printf("RX RF Gain %u, RX BB Gain %u\n", db->common.d_rx_rf_gain, db->common.d_rx_bb_gain); set_reg_rxgain(db); return true; } @@ -517,6 +491,7 @@ xcvr2450_set_gain_tx(struct db_base *dbb, u2_fxpt_gain_t gain){ } //scale for register and set db->common.d_txgain = gain/db->base.gain_step_size; + //printf("TX Gain %u\n", db->common.d_txgain); set_reg_txgain(db); return true; } |