From: Johnathan Corgan Date: Sun, 21 Feb 2010 18:32:22 +0000 (-0800) Subject: Merge branches 'wbx_usrp2' and 'wbx_usrp1' of git://gnuradio.org/jabele X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=48850cce5609941289c00fea9cd3493624bf7376;p=debian%2Fgnuradio Merge branches 'wbx_usrp2' and 'wbx_usrp1' of git://gnuradio.org/jabele --- 48850cce5609941289c00fea9cd3493624bf7376 diff --cc usrp2/firmware/lib/adf4350.c index 00000000,b2e8db8e,00000000..0725c933 mode 000000,100644,000000..100644 --- a/usrp2/firmware/lib/adf4350.c +++ b/usrp2/firmware/lib/adf4350.c @@@@ -1,0 -1,211 -1,0 +1,209 @@@@ + +/* + + * Copyright 2010 Free Software Foundation, Inc. + + * - * Copyright 2010 Ettus Research LLC - * + + * This program is free software: you can redistribute it and/or modify + + * it under the terms of the GNU General Public License as published by + + * the Free Software Foundation, either version 3 of the License, or + + * (at your option) any later version. + + * + + * This program is distributed in the hope that it will be useful, + + * but WITHOUT ANY WARRANTY; without even the implied warranty of + + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + * GNU General Public License for more details. + + * + + * You should have received a copy of the GNU General Public License + + * along with this program. If not, see . + + * + + */ + + + +#include "adf4350.h" + +#include "adf4350_regs.h" + +#include "db_wbxng.h" + +#include + +#include + +#include + +#include + + + +#define INPUT_REF_FREQ U2_DOUBLE_TO_FXPT_FREQ(50e6) + +#define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ) /* input ref freq with doubler turned on */ + +#define MAX_RF_DIV UINT8_C(16) /* max rf divider, divides rf output */ + +#define MIN_VCO_FREQ U2_DOUBLE_TO_FXPT_FREQ(2.2e9) /* minimum vco freq */ + +#define MAX_VCO_FREQ U2_DOUBLE_TO_FXPT_FREQ(4.4e9) /* minimum vco freq */ + +#define MAX_FREQ MAX_VCO_FREQ /* upper bound freq (rf div = 1) */ + +#define MIN_FREQ DIV_ROUND(MIN_VCO_FREQ, MAX_RF_DIV) /* calculated lower bound freq */ + + + +u2_fxpt_freq_t adf4350_get_max_freq(void){ + + return MAX_FREQ; + +} + + + +u2_fxpt_freq_t adf4350_get_min_freq(void){ + + return MIN_FREQ; + +} + + + +void adf4350_init(struct db_base *dbb){ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + + + /* Initialize the pin levels. */ + + hal_gpio_write( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK, PLL_CE, PLL_CE ); + + adf4350_enable(true, dbb); + + /* Initialize the registers. */ + + adf4350_load_register(5, dbb); + + adf4350_load_register(4, dbb); + + adf4350_load_register(3, dbb); + + adf4350_load_register(2, dbb); + + adf4350_load_register(1, dbb); + + adf4350_load_register(0, dbb); + +} + + + +/* + +void adf4350_update(void){ + + // mirror the lock detect pin to the led debug + + if (adf4350_get_locked()){ + + io_set_pin(led_pin); + + }else{ + + io_clear_pin(led_pin); + + } + +} + +*/ + + + +bool adf4350_get_locked(struct db_base *dbb){ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + + + int pins; + + pins = hal_gpio_read( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK ); + + if(pins & PLL_LOCK_DETECT) + + return true; + + return false; + +} + + + +void adf4350_enable(bool enable, struct db_base *dbb){ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + + + if (enable){ /* chip enable */ + + hal_gpio_write( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK, PLL_PDBRF, PLL_PDBRF ); + + }else{ + + hal_gpio_write( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK, 0, PLL_PDBRF ); + + } + +} + + + +void adf4350_write(uint8_t addr, uint32_t data, struct db_base *dbb){ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + + + //printf("SPI write ADDR 0x%x, WORD 0x%x\n", (int) (addr), (int) (data)); + + data |= addr; + + spi_transact(SPI_TXONLY,db->common.spi_mask,data,32,SPIF_PUSH_FALL); + + //spi_read_write(clk_pin, data_pin, ld_pin, &data, 32); + + /* pulse latch */ + + //io_set_pin(le_pin); + + //io_clear_pin(le_pin); + +} + + + +bool adf4350_set_freq(u2_fxpt_freq_t freq, struct db_base *dbb){ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + + + /* Set the frequency by setting int, frac, mod, r, div */ + + if (freq > MAX_FREQ || freq < MIN_FREQ) return false; + + + + /* Set the prescaler and the min N based on the freq. */ + + uint16_t min_int_div; + + if (freq > U2_DOUBLE_TO_FXPT_FREQ(3e9) ){ + + db->common.adf4350_regs_prescaler = (uint8_t) 1; + + min_int_div = UINT16_C(75); + + }else{ + + db->common.adf4350_regs_prescaler = (uint8_t) 0; + + min_int_div = UINT16_C(23); + + } + + + + /* Ramp up the RF divider until the VCO is within range. */ + + db->common.adf4350_regs_divider_select = (uint8_t) 0; + + while (freq < MIN_VCO_FREQ){ + + freq <<= 1; //double the freq + + db->common.adf4350_regs_divider_select++; //double the divider + + } + + + + /* Ramp up the R divider until the N divider is at least the minimum. */ + + db->common.adf4350_regs_10_bit_r_counter = (uint16_t) (DIV_ROUND((INPUT_REF_FREQ*min_int_div), freq)); + + //printf("Initial R setting: %u, MIN_INT: %u\n", db->common.adf4350_regs_10_bit_r_counter, min_int_div); + + if (db->common.adf4350_regs_10_bit_r_counter * U2_DOUBLE_TO_FXPT_FREQ(32e6) < INPUT_REF_FREQ){ + + db->common.adf4350_regs_10_bit_r_counter = (uint16_t) (DIV_ROUND(INPUT_REF_FREQ, U2_DOUBLE_TO_FXPT_FREQ(32e6))); + + //printf("Updating R setting: %u, MIN_INT: %u\n", db->common.adf4350_regs_10_bit_r_counter, min_int_div); + + } + + + + db->common.adf4350_regs_10_bit_r_counter--; + + //db->common.adf4350_regs_10_bit_r_counter=1; + + + + do{ + + db->common.adf4350_regs_10_bit_r_counter++; + + /* throw out some fractional bits in freq to avoid overflow */ + + u2_fxpt_freq_t some_frac_freq = (U2_DOUBLE_TO_FXPT_FREQ(1.0)/db->common.adf4350_regs_mod); + + uint64_t n_mod = DIV_ROUND(freq, some_frac_freq); + + n_mod *= db->common.adf4350_regs_10_bit_r_counter; + + n_mod *= db->common.adf4350_regs_mod; + + n_mod = DIV_ROUND(n_mod, DIV_ROUND(INPUT_REF_FREQ, some_frac_freq)); + + /* calculate int and frac: regs_mod is a power of 2, this will optimize to a bitwise operation */ + + db->common.adf4350_regs_int = (uint16_t) (n_mod/db->common.adf4350_regs_mod); + + db->common.adf4350_regs_frac = (uint16_t) (n_mod%db->common.adf4350_regs_mod); + + //printf("Int %u < Min %u\n", db->common.adf4350_regs_int, min_int_div); + + }while(db->common.adf4350_regs_int < min_int_div); + + + + /* calculate the band select so PFD is under 125 KHz */ + + db->common.adf4350_regs_8_bit_band_select_clock_divider_value = \ + + (uint8_t) (INPUT_REF_FREQ/(U2_DOUBLE_TO_FXPT_FREQ(30e3)*db->common.adf4350_regs_10_bit_r_counter)) + 1; + + + + /* + + printf( + + "VCO %u KHz, Int %u, Frac %u, Mod %u, R %u, Div %u, BandSelect %u\n", + + (uint32_t) ((freq >> U2_FPF_RP)/1000), + + (uint32_t) db->common.adf4350_regs_int, + + (uint32_t) db->common.adf4350_regs_frac, + + (uint32_t) db->common.adf4350_regs_mod, + + (uint32_t) db->common.adf4350_regs_10_bit_r_counter, + + (uint32_t) (1 << db->common.adf4350_regs_divider_select), + + (uint32_t) db->common.adf4350_regs_8_bit_band_select_clock_divider_value + + ); + + */ + + + + /* load involved registers */ + + adf4350_load_register(5, dbb); + + adf4350_load_register(3, dbb); + + adf4350_load_register(1, dbb); + + adf4350_load_register(2, dbb); + + adf4350_load_register(4, dbb); + + adf4350_load_register(0, dbb); /* register 0 must be last */ + + return true; + +} + + + +u2_fxpt_freq_t adf4350_get_freq(struct db_base *dbb){ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + + + /* Calculate the freq from int, frac, mod, ref, r, div: + + * freq = (int + frac/mod) * (ref/r) + + * Keep precision by doing multiplies first: + + * freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div) + + */ + + uint64_t temp; + + temp = (uint64_t) db->common.adf4350_regs_int; + + temp *= (uint64_t) db->common.adf4350_regs_mod; + + temp += (uint64_t) db->common.adf4350_regs_frac; + + temp *= (uint64_t) (INPUT_REF_FREQ >> U2_FPF_RP); + + temp /= (uint64_t) db->common.adf4350_regs_mod; + + temp /= (uint64_t) db->common.adf4350_regs_10_bit_r_counter; + + temp /= (uint64_t) (1 << db->common.adf4350_regs_divider_select); + + + + /* Shift 1Hz Radix Point for u2_fxpt_freq_t */ + + temp = temp << U2_FPF_RP; + + + + /* + + printf( + + "Got Freq %u KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n", + + (uint32_t) ((temp >> U2_FPF_RP)/1000), + + (uint32_t) db->common.adf4350_regs_int, + + (uint32_t) db->common.adf4350_regs_frac, + + (uint32_t) db->common.adf4350_regs_mod, + + (uint32_t) db->common.adf4350_regs_10_bit_r_counter, + + (uint32_t) (1 << db->common.adf4350_regs_divider_select) + + ); + + */ + + + + return (u2_fxpt_freq_t) (temp); + +} diff --cc usrp2/firmware/lib/adf4350.h index 00000000,5ee13ddb,00000000..3c66ec34 mode 000000,100644,000000..100644 --- a/usrp2/firmware/lib/adf4350.h +++ b/usrp2/firmware/lib/adf4350.h @@@@ -1,0 -1,42 -1,0 +1,40 @@@@ + +/* + + * Copyright 2010 Free Software Foundation, Inc. + + * - * Copyright 2010 Ettus Research LLC - * + + * This program is free software: you can redistribute it and/or modify + + * it under the terms of the GNU General Public License as published by + + * the Free Software Foundation, either version 3 of the License, or + + * (at your option) any later version. + + * + + * This program is distributed in the hope that it will be useful, + + * but WITHOUT ANY WARRANTY; without even the implied warranty of + + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + * GNU General Public License for more details. + + * + + * You should have received a copy of the GNU General Public License + + * along with this program. If not, see . + + * + + */ + + + +#ifndef ADF4350_H + +#define ADF4350_H + + + +#include + +#include + +#include + + + +#define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom)) + +#define UINT8_C(num) ((uint8_t) (num)) + +#define UINT16_C(num) ((uint16_t) (num)) + + + +void adf4350_init(struct db_base *dbb); + +//void adf4350_update(void); + +bool adf4350_get_locked(struct db_base *dbb); + +void adf4350_enable(bool enable, struct db_base *dbb); + +void adf4350_write(uint8_t addr, uint32_t data, struct db_base *dbb); + +bool adf4350_set_freq(u2_fxpt_freq_t freq, struct db_base *dbb); + +u2_fxpt_freq_t adf4350_get_freq(struct db_base *dbb); + +u2_fxpt_freq_t adf4350_get_max_freq(void); + +u2_fxpt_freq_t adf4350_get_min_freq(void); + + + +#endif /* ADF4350_H */ diff --cc usrp2/firmware/lib/adf4350_regs.c index 00000000,196a97c5,00000000..e2740d3a mode 000000,100644,000000..100644 --- a/usrp2/firmware/lib/adf4350_regs.c +++ b/usrp2/firmware/lib/adf4350_regs.c @@@@ -1,0 -1,105 -1,0 +1,103 @@@@ + +/* + + * Copyright 2010 Free Software Foundation, Inc. + + * - * Copyright 2010 Ettus Research LLC - * + + * This program is free software: you can redistribute it and/or modify + + * it under the terms of the GNU General Public License as published by + + * the Free Software Foundation, either version 3 of the License, or + + * (at your option) any later version. + + * + + * This program is distributed in the hope that it will be useful, + + * but WITHOUT ANY WARRANTY; without even the implied warranty of + + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + * GNU General Public License for more details. + + * + + * You should have received a copy of the GNU General Public License + + * along with this program. If not, see . + + * + + */ + + + +#include "adf4350_regs.h" + +#include "adf4350.h" + +#include "db_wbxng.h" + + + +#define _REG_SHIFT(reg, shift) (((uint32_t)(reg)) << (shift)) + + + +/* reg 0 */ + +/* reg 1 */ + +static const uint16_t adf4350_regs_phase = 0; /* 0 */ + +/* reg 2 */ + +static const uint8_t adf4350_regs_low_noise_and_low_spur_modes = 3; /* low noise mode */ + +static const uint8_t adf4350_regs_muxout = 3; /* digital lock detect */ + +static const uint8_t adf4350_regs_reference_doubler = 0; /* disabled */ + +static const uint8_t adf4350_regs_rdiv2 = 1; /* disabled */ + +static const uint8_t adf4350_regs_double_buff = 0; /* disabled */ + +static const uint8_t adf4350_regs_charge_pump_setting = 5; /* 2.50 mA */ + +static const uint8_t adf4350_regs_ldf = 0; /* frac-n */ + +static const uint8_t adf4350_regs_ldp = 0; /* 10 ns */ + +static const uint8_t adf4350_regs_pd_polarity = 1; /* positive */ + +static const uint8_t adf4350_regs_power_down = 0; /* disabled */ + +static const uint8_t adf4350_regs_cp_three_state = 0; /* disabled */ + +static const uint8_t adf4350_regs_counter_reset = 0; /* disabled */ + +/* reg 3 */ + +static const uint8_t adf4350_regs_csr = 0; /* disabled */ + +static const uint8_t adf4350_regs_clk_div_mode = 0; /* clock divider off */ + +static const uint16_t adf4350_regs_12_bit_clock_divider_value = 0; /* 0 */ + +/* reg 4 */ + +static const uint8_t adf4350_regs_feedback_select = 1; /* fundamental */ + +static const uint8_t adf4350_regs_vco_power_down = 0; /* vco powered up */ + +static const uint8_t adf4350_regs_mtld = 0; /* mute disabled */ + +static const uint8_t adf4350_regs_aux_output_select = 1; /* divided output */ + +static const uint8_t adf4350_regs_aux_output_enable = 1; /* disabled */ + +static const uint8_t adf4350_regs_aux_output_power = 0; /* -4 */ + +static const uint8_t adf4350_regs_rf_output_enable = 1; /* enabled */ + +static const uint8_t adf4350_regs_output_power = 3; /* -1 */ + +/* reg 5 */ + +static const uint8_t adf4350_regs_ld_pin_mode = 1; /* digital lock detect */ + + + +void adf4350_load_register(uint8_t addr, struct db_base *dbb){ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + uint32_t data; + + switch (addr){ + + case 0: data = ( + + _REG_SHIFT(db->common.adf4350_regs_int, 15) | + + _REG_SHIFT(db->common.adf4350_regs_frac, 3)); break; + + case 1: data = ( + + _REG_SHIFT(db->common.adf4350_regs_prescaler, 27) | + + _REG_SHIFT(adf4350_regs_phase, 15) | + + _REG_SHIFT(db->common.adf4350_regs_mod, 3)); break; + + case 2: data = ( + + _REG_SHIFT(adf4350_regs_low_noise_and_low_spur_modes, 29) | + + _REG_SHIFT(adf4350_regs_muxout, 26) | + + _REG_SHIFT(adf4350_regs_reference_doubler, 25) | + + _REG_SHIFT(adf4350_regs_rdiv2, 24) | + + _REG_SHIFT(db->common.adf4350_regs_10_bit_r_counter, 14) | + + _REG_SHIFT(adf4350_regs_double_buff, 13) | + + _REG_SHIFT(adf4350_regs_charge_pump_setting, 9) | + + _REG_SHIFT(adf4350_regs_ldf, 8) | + + _REG_SHIFT(adf4350_regs_ldp, 7) | + + _REG_SHIFT(adf4350_regs_pd_polarity, 6) | + + _REG_SHIFT(adf4350_regs_power_down, 5) | + + _REG_SHIFT(adf4350_regs_cp_three_state, 4) | + + _REG_SHIFT(adf4350_regs_counter_reset, 3)); break; + + case 3: data = ( + + _REG_SHIFT(adf4350_regs_csr, 18) | + + _REG_SHIFT(adf4350_regs_clk_div_mode, 15) | + + _REG_SHIFT(adf4350_regs_12_bit_clock_divider_value, 3)); break; + + case 4: data = ( + + _REG_SHIFT(adf4350_regs_feedback_select, 23) | + + _REG_SHIFT(db->common.adf4350_regs_divider_select, 20) | + + _REG_SHIFT(db->common.adf4350_regs_8_bit_band_select_clock_divider_value, 12) | + + _REG_SHIFT(adf4350_regs_vco_power_down, 11) | + + _REG_SHIFT(adf4350_regs_mtld, 10) | + + _REG_SHIFT(adf4350_regs_aux_output_select, 9) | + + _REG_SHIFT(adf4350_regs_aux_output_enable, 8) | + + _REG_SHIFT(adf4350_regs_aux_output_power, 6) | + + _REG_SHIFT(adf4350_regs_rf_output_enable, 5) | + + _REG_SHIFT(adf4350_regs_output_power, 3)); break; + + case 5: data = ( + + _REG_SHIFT(adf4350_regs_ld_pin_mode, 22)); break; + + default: return; + + } + + /* write the data out to spi */ + + adf4350_write(addr, data, dbb); + +} diff --cc usrp2/firmware/lib/db_wbxng.c index 00000000,1620c662,00000000..c02a5bda mode 000000,100644,000000..100644 --- a/usrp2/firmware/lib/db_wbxng.c +++ b/usrp2/firmware/lib/db_wbxng.c @@@@ -1,0 -1,216 -1,0 +1,214 @@@@ + +/* + + * Copyright 2010 Free Software Foundation, Inc. + + * - * Copyright 2010 Ettus Research LLC - * + + * This program is free software: you can redistribute it and/or modify + + * it under the terms of the GNU General Public License as published by + + * the Free Software Foundation, either version 3 of the License, or + + * (at your option) any later version. + + * + + * This program is distributed in the hope that it will be useful, + + * but WITHOUT ANY WARRANTY; without even the implied warranty of + + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + * GNU General Public License for more details. + + * + + * You should have received a copy of the GNU General Public License + + * along with this program. If not, see . + + * + + */ + + + + + +#include "db_wbxng.h" + +#include "adf4350.h" + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + +#include + + + +bool wbxng_init_rx(struct db_base *dbb); + +bool wbxng_init_tx(struct db_base *dbb); + +bool wbxng_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc); + +bool wbxng_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain); + +bool wbxng_set_gain_tx(struct db_base *dbb, u2_fxpt_gain_t gain); + +bool wbxng_set_tx_enable(struct db_base *dbb, bool on); + + + + + +/* + + * The class instances + + */ + +struct db_wbxng_rx db_wbxng_rx = { + + .base.dbid = 0x0053, + + .base.is_tx = false, + + .base.output_enables = RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5|PLL_CE|PLL_PDBRF|ATTN_MASK, + + .base.used_pins = 0xFFFF, + + .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(67.5e6), + + .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2200e6), + + .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0), + + .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(31.5), + + .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.5), + + .base.is_quadrature = true, + + .base.i_and_q_swapped = false, + + .base.spectrum_inverted = false, + + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), + + .base.init = wbxng_init_rx, + + .base.set_freq = wbxng_set_freq, + + .base.set_gain = wbxng_set_gain_rx, + + .base.set_tx_enable = 0, + + .base.atr_mask = RXBB_EN | RX2_RX1N, + + .base.atr_txval = RX2_RX1N, + + .base.atr_rxval = RXBB_EN, + + // .base.atr_tx_delay = + + // .base.atr_rx_delay = + + .common.adf4350_regs_int = UINT16_C(100), + + .common.adf4350_regs_frac = 0, + + .common.adf4350_regs_prescaler = 1, + + .common.adf4350_regs_mod = UINT16_C(0xfff), + + .common.adf4350_regs_10_bit_r_counter = UINT16_C(1), + + .common.adf4350_regs_divider_select = 0, + + .common.adf4350_regs_8_bit_band_select_clock_divider_value = 0, + + .common.spi_mask = SPI_SS_RX_DB, + + .common.freq_mult = 2 + +}; + + + + + +struct db_wbxng_tx db_wbxng_tx = { + + .base.dbid = 0x0052, + + .base.is_tx = true, + + .base.output_enables = RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5|PLL_CE|PLL_PDBRF, + + .base.used_pins = 0xFFFF, + + .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(67.5e6), + + .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2200e6), + + .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0), + + .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(25), + + .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.1), + + .base.is_quadrature = true, + + .base.i_and_q_swapped = false, + + .base.spectrum_inverted = false, + + .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), + + .base.init = wbxng_init_tx, + + .base.set_freq = wbxng_set_freq, + + .base.set_gain = wbxng_set_gain_tx, + + .base.set_tx_enable = wbxng_set_tx_enable, + + .base.atr_mask = RX_TXN | TXMOD_EN, + + .base.atr_txval = TXMOD_EN, + + .base.atr_rxval = RX_TXN, + + // .base.atr_tx_delay = + + // .base.atr_rx_delay = + + .common.adf4350_regs_int = UINT16_C(100), + + .common.adf4350_regs_frac = 0, + + .common.adf4350_regs_prescaler = 1, + + .common.adf4350_regs_mod = UINT16_C(0xfff), + + .common.adf4350_regs_10_bit_r_counter = UINT16_C(1), + + .common.adf4350_regs_divider_select = 0, + + .common.adf4350_regs_8_bit_band_select_clock_divider_value = 0, + + .common.spi_mask = SPI_SS_TX_DB, + + .common.freq_mult = 2 + +}; + + + + + +bool + +wbxng_init_tx(struct db_base *dbb) + +{ + + //struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + clocks_enable_tx_dboard(true, 0); + + hal_gpio_write( GPIO_TX_BANK, ENABLE_5|ENABLE_33, ENABLE_5|ENABLE_33 ); + + + + adf4350_init(dbb); + + + + // Set the freq now to get the one time 10ms delay out of the way. + + u2_fxpt_freq_t dc; + + dbb->set_freq(dbb, dbb->freq_min, &dc); + + return true; + +} + + + +bool + +wbxng_init_rx(struct db_base *dbb) + +{ + + //struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + clocks_enable_rx_dboard(true, 0); + + hal_gpio_write( GPIO_RX_BANK, ENABLE_5|ENABLE_33, ENABLE_5|ENABLE_33 ); + + + + adf4350_init(dbb); + + + + // test gain + + dbb->set_gain(dbb,U2_DOUBLE_TO_FXPT_GAIN(20.0)); + + + + // Set the freq now to get the one time 10ms delay out of the way. + + u2_fxpt_freq_t dc; + + dbb->set_freq(dbb, dbb->freq_min, &dc); + + + + return true; + +} + + + +bool + +wbxng_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc) + +{ + + bool ok = adf4350_set_freq(2*freq,dbb); + + *dc = adf4350_get_freq(dbb)/2; + + + + return ok; + +} + + + +bool + +wbxng_set_gain_tx(struct db_base *dbb, u2_fxpt_gain_t gain) + +{ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + + + // clamp gain + + //gain = max(db->gain_min, min(gain, db->gain_max)); + + + + int offset_q8 = (int)(1.4/3.3*4096*(1<<15)); + + int range_q15 = (int)(-0.9*4096/3.3*256*128); + + int slope_q8 = range_q15/db->base.gain_max; + + + + int dacword = ((slope_q8 * gain) + offset_q8)>>15; + + //printf("DACWORD 0x%x\n",dacword); + + lsdac_write_tx(0,dacword); + + return true; + +} + + + +bool + +wbxng_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain) + +{ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + + + // clamp gain + + //gain = max(db->gain_min, min(gain, db->gain_max)); + + + + int iobits = (int) ((~((db->base.gain_max - gain) << 2)) & ATTN_MASK); + + //printf("gain %d, gainmax %d, RX_ATTN_MASK = 0x%x, RX_ATTN_WORD = 0x%x\n", gain, db->base.gain_max, (int) (ATTN_MASK), (int) (iobits)); + + + + hal_gpio_write( GPIO_RX_BANK, (int) (iobits), ATTN_MASK ); + + return true; + +} + + + + + +bool + +wbxng_set_tx_enable(struct db_base *dbb, bool on) + +{ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + + + // FIXME + + + + return false; + +} + + + +bool + +wbxng_lock_detect(struct db_base *dbb) + +{ + + struct db_wbxng_dummy *db = (struct db_wbxng_dummy *) dbb; + + + + int pins; + + pins = hal_gpio_read( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK ); + + if(pins & PLL_LOCK_DETECT) + + //printf("Got Locked Status from Synth"); + + return true; + + + + //printf("Got Unlocked Status from Synth"); + + return false; + +} + + diff --cc usrp2/firmware/lib/db_wbxng.h index 00000000,b2437cbc,00000000..3756e6c2 mode 000000,100644,000000..100644 --- a/usrp2/firmware/lib/db_wbxng.h +++ b/usrp2/firmware/lib/db_wbxng.h @@@@ -1,0 -1,76 -1,0 +1,74 @@@@ + +/* + + * Copyright 2010 Free Software Foundation, Inc. + + * - * Copyright 2010 Ettus Research LLC - * + + * This program is free software: you can redistribute it and/or modify + + * it under the terms of the GNU General Public License as published by + + * the Free Software Foundation, either version 3 of the License, or + + * (at your option) any later version. + + * + + * This program is distributed in the hope that it will be useful, + + * but WITHOUT ANY WARRANTY; without even the implied warranty of + + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + * GNU General Public License for more details. + + * + + * You should have received a copy of the GNU General Public License + + * along with this program. If not, see . + + * + + */ + + + +#ifndef DB_WBXNG_H + +#define DB_WBXNG_H + + + +#include + + + +// IO Pin functions + +// Tx and Rx have shared defs, but different i/o regs + +#define ENABLE_5 (1 << 7) // enables 5.0V power supply + +#define ENABLE_33 (1 << 6) // enables 3.3V supply + +//#define RX_TXN (1 << 15) // Tx only: T/R antenna switch for TX/RX port + +//#define RX2_RX1N (1 << 15) // Rx only: antenna switch between RX2 and TX/RX port + +#define RX_TXN ((1 << 5)|(1 << 15)) // Tx only: T/R antenna switch for TX/RX port + +#define RX2_RX1N ((1 << 5)|(1 << 15)) // Rx only: antenna switch between RX2 and TX/RX port + +#define RXBB_EN (1 << 4) + +#define TXMOD_EN (1 << 4) + +#define PLL_CE (1 << 3) + +#define PLL_PDBRF (1 << 2) + +#define PLL_MUXOUT (1 << 1) + +#define PLL_LOCK_DETECT (1 << 0) + + + +// RX Attenuator constants + +#define ATTN_SHIFT 8 + +#define ATTN_MASK (63 << ATTN_SHIFT) + + + +struct db_wbxng_common { + + // RFX common stuff + + uint16_t adf4350_regs_int; + + uint16_t adf4350_regs_frac; + + uint8_t adf4350_regs_prescaler; + + uint16_t adf4350_regs_mod; + + uint16_t adf4350_regs_10_bit_r_counter; + + uint8_t adf4350_regs_divider_select; + + uint8_t adf4350_regs_8_bit_band_select_clock_divider_value; + + + + int freq_mult; + + int spi_mask; + +}; + + + +struct db_wbxng_dummy { + + struct db_base base; + + struct db_wbxng_common common; + +}; + + + + + +struct db_wbxng_rx { + + struct db_base base; + + struct db_wbxng_common common; + +}; + + + +struct db_wbxng_tx { + + struct db_base base; + + struct db_wbxng_common common; + +}; + + + + + +#endif /* DB_WBXNG_H */