diff options
-rwxr-xr-x | usrp2/firmware/lib/db_dbsrx.c | 206 |
1 files changed, 110 insertions, 96 deletions
diff --git a/usrp2/firmware/lib/db_dbsrx.c b/usrp2/firmware/lib/db_dbsrx.c index 877e40337..3e818face 100755 --- a/usrp2/firmware/lib/db_dbsrx.c +++ b/usrp2/firmware/lib/db_dbsrx.c @@ -25,12 +25,12 @@ #define min(X,Y) ((X) < (Y) ? (X) : (Y)) #define max(X,Y) ((X) > (Y) ? (X) : (Y)) - -//#include <math.h> //round, log10 +#define abs(X) ((X) < (0) ? ((-1)*(X)) : (X)) #define I2C_ADDR 0x67 #define REFCLK_DIVISOR 25 // Gives a 4 MHz clock -#define REFCLK_FREQ MASTER_CLK_RATE/REFCLK_DIVISOR +#define REFCLK_FREQ U2_DOUBLE_TO_FXPT_FREQ(MASTER_CLK_RATE/REFCLK_DIVISOR) +#define REFCLK_FREQ_INT u2_fxpt_freq_round_to_int(REFCLK_FREQ) #define VMAXGAIN .75 #define VMINGAIN 2.6 @@ -47,14 +47,12 @@ struct db_dbsrx_common { int d_div2; int d_osc; int d_cp; - int d_r; - int d_r_int; + int d_r_reg; int d_fdac; int d_m; int d_dl; int d_ade; int d_adl; - int d_gc1; int d_gc2; int d_diag; }; @@ -96,14 +94,12 @@ struct db_dbsrx db_dbsrx = { .common.d_div2 = 0, .common.d_osc = 5, .common.d_cp = 3, - .common.d_r = 4, - .common.d_r_int = 1, + .common.d_r_reg = 1, .common.d_fdac = 127, .common.d_m = 2, .common.d_dl = 1, .common.d_ade = 0, .common.d_adl = 0, - .common.d_gc1 = 0, .common.d_gc2 = 31, .common.d_diag = 0, }; @@ -124,6 +120,7 @@ _read_adc (void){ unsigned char readback[2]; i2c_read(I2C_ADDR, readback, 2*sizeof(unsigned char)); int adc_val = (readback[0] >> 2)&7; + printf("READBACK[0] %d, [1] %d\n",readback[0],readback[1]); printf("ADC: %d\n",adc_val); return adc_val; } @@ -131,29 +128,35 @@ _read_adc (void){ void _write_reg (int regno, int v){ //regno is in [0,5], v is value to write to register""" - //assert (0 <= regno && regno <= 5); - int args[2]; - args[0] = regno; - args[1] = v; - //TODO usrp()->write_i2c (d_i2c_addr, int_seq_to_str (args)); - i2c_write(I2C_ADDR, (unsigned char*)args, 2*sizeof(char)); + unsigned char args[2]; + args[0] = (unsigned char)regno; + args[1] = (unsigned char)v; + i2c_write(I2C_ADDR, args, 2*sizeof(unsigned char)); + printf("Reg %d, Val %x\n",regno,v); } -void -_send_reg(struct db_dbsrx_dummy *db, int regno){ - //assert(0 <= regno && regno <= 5); - if(regno == 0) - _write_reg(0,(db->common.d_div2<<7) + (db->common.d_n>>8)); - if(regno == 1) - _write_reg(1,db->common.d_n & 255); - if(regno == 2) - _write_reg(2,db->common.d_osc + (db->common.d_cp<<3) + (db->common.d_r_int<<5)); - if(regno == 3) - _write_reg(3,db->common.d_fdac); - if(regno == 4) - _write_reg(4,db->common.d_m + (db->common.d_dl<<5) + (db->common.d_ade<<6) + (db->common.d_adl<<7)); - if(regno == 5) - _write_reg(5,db->common.d_gc2 + (db->common.d_diag<<5)); +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){ + _write_reg(1,db->common.d_n & 255); +} + +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){ + _write_reg(3,db->common.d_fdac); +} + +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){ + _write_reg(5,db->common.d_gc2 + (db->common.d_diag<<5)); } /************************************************** @@ -161,52 +164,47 @@ _send_reg(struct db_dbsrx_dummy *db, int regno){ **************************************************/ void _set_div2(struct db_dbsrx_dummy *db, int div2){ - // assert(div2 == 0 || div2 == 1); db->common.d_div2 = div2; - _send_reg(db, 0); + _send_reg_0(db); } // FIXME How do we handle ADE and ADL properly? void _set_ade(struct db_dbsrx_dummy *db, int ade){ - // assert(ade == 0 || ade == 1); db->common.d_ade = ade; - _send_reg(db, 4); + _send_reg_4(db); } void _set_r(struct db_dbsrx_dummy *db, int r){ - // assert(r>=0 && r<128); - db->common.d_r = r; - // db->common.d_r_int = round(log10(r)/log10(2)) - 1; - _send_reg(db, 2); + db->common.d_r_reg = r; + _send_reg_2(db); } void _set_n(struct db_dbsrx_dummy *db, int n){ - // assert(n>256 && n<32768); db->common.d_n = n; - _send_reg(db, 0); - _send_reg(db, 1); + _send_reg_0(db); + _send_reg_1(db); } void _set_osc(struct db_dbsrx_dummy *db, int osc){ - // assert(osc>=0 && osc<8); db->common.d_osc = osc; - _send_reg(db, 2); + _send_reg_2(db); } void _set_cp(struct db_dbsrx_dummy *db, int cp){ - // assert(cp>=0 && cp<4); db->common.d_cp = cp; - _send_reg(db, 2); + _send_reg_2(db); } /************************************************** * Set the freq **************************************************/ + + bool db_dbsrx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc){ struct db_dbsrx_dummy *db = (struct db_dbsrx_dummy *) dbb; @@ -214,9 +212,9 @@ db_dbsrx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc){ if(!(freq>=db->base.freq_min && freq<=db->base.freq_max)) { return false; } - /* - double vcofreq; - if(freq<1150e6) { + + u2_fxpt_freq_t vcofreq; + if(freq < U2_DOUBLE_TO_FXPT_FREQ(1150e6)) { _set_div2(db, 0); vcofreq = 4 * freq; } @@ -226,68 +224,73 @@ db_dbsrx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc){ } _set_ade(db, 1); - int rmin = max(2, (int)(REFCLK_FREQ/2e6)); - int rmax = min(128, (int)(REFCLK_FREQ/500e3)); - int r = 2; + int rmin = max(2, u2_fxpt_freq_round_to_int(REFCLK_FREQ/2e6)); //TODO? remove max() + //int rmax = min(128, u2_fxpt_freq_round_to_int(REFCLK_FREQ/500e3)); //TODO? remove min() int n = 0; - int best_r = 2; + u2_fxpt_freq_t best_delta = U2_DOUBLE_TO_FXPT_FREQ(10e6); + u2_fxpt_freq_t delta; + + int r_reg = 0; + while ((r_reg<7) && ((2<<r_reg) < rmin)) { + r_reg++; + } + printf ("r_reg = %d, r = %d\n",r_reg,2<<r_reg); + int best_r = r_reg; int best_n = 0; - int best_delta = 10e6; - int delta; - - while(r <= rmax) { - n = round(freq/(REFCLK_FREQ/r)); - if(r<rmin || n<256) { - r = r * 2; + + while(r_reg <= 7) { + n = u2_fxpt_freq_round_to_int(freq/REFCLK_FREQ_INT*(2<<r_reg)); + //printf("LOOP: r_reg %d, best_r %d, best_n %d, best_delta %d\n", + //r_reg,best_r,best_n,u2_fxpt_freq_round_to_int(best_delta)); + + //printf("N: %d\n",n); + if(n<256) { + r_reg++; continue; } - delta = (int)fabs(n*REFCLK_FREQ/r - freq); - if(delta < 75e3) { - best_r = r; - best_n = n; - break; - } - if(delta < best_delta*0.9) { - best_r = r; + delta = abs(n*REFCLK_FREQ/(2<<r_reg) - freq); + if(delta < best_delta) { + best_r = r_reg; best_n = n; best_delta = delta; } - r = r * 2; + if(best_delta < U2_DOUBLE_TO_FXPT_FREQ(75e3)) { + break; + } + r_reg++; } - _set_r(db, best_r); - _set_n(db, round(best_n)); + printf("BEST R: %d Best Delta %d Best N %d\n", + best_r,u2_fxpt_freq_round_to_int(best_delta),best_n); + _set_r(db, best_r); + _set_n(db, best_n); int vco; - if(vcofreq < 2433e6) + if(vcofreq < U2_DOUBLE_TO_FXPT_FREQ(2433e6)) vco = 0; - else if(vcofreq < 2711e6) + else if(vcofreq < U2_DOUBLE_TO_FXPT_FREQ(2711e6)) vco=1; - else if(vcofreq < 3025e6) + else if(vcofreq < U2_DOUBLE_TO_FXPT_FREQ(3025e6)) vco=2; - else if(vcofreq < 3341e6) + else if(vcofreq < U2_DOUBLE_TO_FXPT_FREQ(3341e6)) vco=3; - else if(vcofreq < 3727e6) + else if(vcofreq < U2_DOUBLE_TO_FXPT_FREQ(3727e6)) vco=4; - else if(vcofreq < 4143e6) + else if(vcofreq < U2_DOUBLE_TO_FXPT_FREQ(4143e6)) vco=5; - else if(vcofreq < 4493e6) + else if(vcofreq < U2_DOUBLE_TO_FXPT_FREQ(4493e6)) vco=6; else vco=7; - + printf("Chose VCO %d\n",vco); _set_osc(db, vco); - // Set CP current + int adc_val = 0; - int bytes[2]; - bytes[0] = 0; - bytes[1] = 0; while(adc_val == 0 || adc_val == 7) { + adc_val = _read_adc(); + printf("adc %d\n",adc_val); - i2c_read(I2C_ADDR, (unsigned char*)bytes, 2*sizeof(char)); - _read_status(bytes); - adc_val = bytes[0] >> 2; if(adc_val == 0) { if(vco <= 0) { return false; @@ -317,10 +320,9 @@ db_dbsrx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc){ _set_cp(db, 3); } - *dc = db->common.d_n * REFCLK_FREQ / db->common.d_r; + *dc = db->common.d_n * REFCLK_FREQ / (2<<db->common.d_r_reg); return true; - - */ + } /************************************************** @@ -329,9 +331,8 @@ db_dbsrx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc){ void _set_gc2(struct db_dbsrx_dummy *db, int gc2){ - // assert(gc2<32 && gc2>=0); db->common.d_gc2 = gc2; - _send_reg(db, 5); + _send_reg_5(db); } /************************************************** @@ -361,18 +362,31 @@ db_dbsrx_set_gain(struct db_base *dbb, u2_fxpt_gain_t gain){ int rfdac = (rfgain*rf_gain_slope_q8 + rf_gain_offset_q8)>>15; - printf("Set RF Gain %d, %d\n",rfgain,rfdac); - lsdac_write_rx(0,rfdac); + //printf("Set RF Gain %d, %d\n",rfgain,rfdac); + lsdac_write_rx(1,rfdac); // Set GC2 - int bb_gain_slope_q8 = 256*(0-31)/(BBGAINMAX-0); // -198 - int bb_gain_offset_q8 = 256 * 31; // 7936 + int bb_gain_slope_q8 = 256*(0-31)/(BBGAINMAX-0); int gc2 = u2_fxpt_gain_round_to_int((bb_gain_slope_q8 * bbgain)>>8) + 31; - printf("Set BB Gain: %d, gc2 %d\n",bbgain,gc2); + //printf("Set BB Gain: %d, gc2 %d\n",bbgain,gc2); - _set_gc2(db, gc2); return true; } + +/************************************************** + * Helpers for setting the bw + **************************************************/ +void +_set_m(struct db_dbsrx_dummy *db, int m){ + db->common.d_m = m; + _send_reg_4(db); +} + +void +_set_fdac(struct db_dbsrx_dummy *db, int fdac){ + db->common.d_fdac = fdac; + _send_reg_3(db); +} |