From 620c5db0cc448c8b275943069e39cb0eec2f08a0 Mon Sep 17 00:00:00 2001 From: jblum Date: Wed, 4 Feb 2009 03:06:20 +0000 Subject: usrp2: xcvr working git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10382 221aa14e-8319-0410-a670-987f0aec2ac5 --- usrp2/firmware/lib/db_dbsrx.c | 36 +++---- usrp2/firmware/lib/db_xcvr2450.c | 207 +++++++++++++++++---------------------- 2 files changed, 109 insertions(+), 134 deletions(-) (limited to 'usrp2/firmware/lib') diff --git a/usrp2/firmware/lib/db_dbsrx.c b/usrp2/firmware/lib/db_dbsrx.c index a0ba764af..31b02722b 100755 --- a/usrp2/firmware/lib/db_dbsrx.c +++ b/usrp2/firmware/lib/db_dbsrx.c @@ -107,7 +107,7 @@ struct db_dbsrx db_dbsrx = { bool db_dbsrx_init(struct db_base *dbb){ struct db_dbsrx_dummy *db = (struct db_dbsrx_dummy *) dbb; - db->base.set_gain(dbb, (db->base.gain_max - db->base.gain_min)/2); + db->base.set_gain(dbb, (db->base.gain_max + db->base.gain_min)/2); clocks_enable_rx_dboard(true, REFCLK_DIVISOR); // Gives 4 MHz clock return true; } @@ -115,7 +115,7 @@ db_dbsrx_init(struct db_base *dbb){ /************************************************** * Registers **************************************************/ -int +static int _read_adc (void){ unsigned char readback[2]; i2c_read(I2C_ADDR, readback, 2*sizeof(unsigned char)); @@ -125,7 +125,7 @@ _read_adc (void){ return adc_val; } -void +static void _write_reg (int regno, int v){ //regno is in [0,5], v is value to write to register""" unsigned char args[2]; @@ -135,66 +135,66 @@ _write_reg (int regno, int v){ printf("Reg %d, Val %x\n",regno,v); } -void _send_reg_0(struct db_dbsrx_dummy *db){ +static void _send_reg_0(struct db_dbsrx_dummy *db){ _write_reg(0,(db->common.d_div2<<7) + (db->common.d_n>>8)); } -void _send_reg_1(struct db_dbsrx_dummy *db){ +static void _send_reg_1(struct db_dbsrx_dummy *db){ _write_reg(1,db->common.d_n & 255); } -void _send_reg_2(struct db_dbsrx_dummy *db){ +static void _send_reg_2(struct db_dbsrx_dummy *db){ _write_reg(2,db->common.d_osc + (db->common.d_cp<<3) + (db->common.d_r_reg<<5)); } -void _send_reg_3(struct db_dbsrx_dummy *db){ +static void _send_reg_3(struct db_dbsrx_dummy *db){ _write_reg(3,db->common.d_fdac); } -void _send_reg_4(struct db_dbsrx_dummy *db){ +static void _send_reg_4(struct db_dbsrx_dummy *db){ _write_reg(4,db->common.d_m + (db->common.d_dl<<5) + (db->common.d_ade<<6) + (db->common.d_adl<<7)); } -void _send_reg_5(struct db_dbsrx_dummy *db){ +static void _send_reg_5(struct db_dbsrx_dummy *db){ _write_reg(5,db->common.d_gc2 + (db->common.d_diag<<5)); } /************************************************** * Helpers for setting the freq **************************************************/ -void +static void _set_div2(struct db_dbsrx_dummy *db, int div2){ db->common.d_div2 = div2; _send_reg_0(db); } // FIXME How do we handle ADE and ADL properly? -void +static void _set_ade(struct db_dbsrx_dummy *db, int ade){ db->common.d_ade = ade; _send_reg_4(db); } -void +static void _set_r(struct db_dbsrx_dummy *db, int r){ db->common.d_r_reg = r; _send_reg_2(db); } -void +static void _set_n(struct db_dbsrx_dummy *db, int n){ db->common.d_n = n; _send_reg_0(db); _send_reg_1(db); } -void +static void _set_osc(struct db_dbsrx_dummy *db, int osc){ db->common.d_osc = osc; _send_reg_2(db); } -void +static void _set_cp(struct db_dbsrx_dummy *db, int cp){ db->common.d_cp = cp; _send_reg_2(db); @@ -330,7 +330,7 @@ db_dbsrx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc){ * Helpers for setting the gain **************************************************/ -void +static void _set_gc2(struct db_dbsrx_dummy *db, int gc2){ db->common.d_gc2 = gc2; _send_reg_5(db); @@ -380,13 +380,13 @@ db_dbsrx_set_gain(struct db_base *dbb, u2_fxpt_gain_t gain){ /************************************************** * Helpers for setting the bw **************************************************/ -void +static void _set_m(struct db_dbsrx_dummy *db, int m){ db->common.d_m = m; _send_reg_4(db); } -void +static void _set_fdac(struct db_dbsrx_dummy *db, int fdac){ db->common.d_fdac = fdac; _send_reg_3(db); 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 #include #include +#include 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; } -- cgit