twiddling gpio successfully

This commit is contained in:
Jason Abele 2009-08-21 15:16:18 -07:00 committed by Johnathan Corgan
parent 3e0eb64bf7
commit 1d5822c0dc
6 changed files with 164 additions and 159 deletions

View File

@ -50,8 +50,7 @@ protected:
void _write_it(int v);
bool _lock_detect();
virtual bool _compute_regs(double freq, int &retR, int &retcontrol,
int &retN, double &retfreq);
//virtual bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq);
int _compute_control_reg();
int _refclk_divisor();
double _refclk_freq();
@ -117,8 +116,7 @@ class db_wbxng_tx : public wbxng_base_tx
~db_wbxng_tx();
// Wrapper calls to d_common functions
bool _compute_regs(double freq, int &retR, int &retcontrol,
int &retN, double &retfreq);
//bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq);
};
class db_wbxng_rx : public wbxng_base_rx
@ -132,8 +130,7 @@ public:
float gain_db_per_step();
bool i_and_q_swapped();
bool _compute_regs(double freq, int &retR, int &retcontrol,
int &retN, double &retfreq);
//bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq);
};

View File

@ -9,7 +9,7 @@
#include <usrp/db_base.h>
#include <stdint.h>
typedef uint32_t freq_t;
typedef uint64_t freq_t;
class adf4350_regs;
class adf4350

View File

@ -23,43 +23,43 @@ public:
void _load_register(uint8_t addr);
/* reg 0 */
uint16_t _int;
uint16_t _frac;
uint16_t d_int;
uint16_t d_frac;
/* reg 1 */
static uint8_t _prescaler;
static uint16_t _phase;
uint16_t _mod;
static const uint8_t s_prescaler;
static const uint16_t s_phase;
uint16_t d_mod;
/* reg 2 */
static uint8_t _low_noise_and_low_spur_modes;
static uint8_t _muxout;
static uint8_t _reference_doubler;
static uint8_t _rdiv2;
uint16_t _10_bit_r_counter;
static uint8_t _double_buff;
static uint8_t _charge_pump_setting;
static uint8_t _ldf;
static uint8_t _ldp;
static uint8_t _pd_polarity;
static uint8_t _power_down;
static uint8_t _cp_three_state;
static uint8_t _counter_reset;
static const uint8_t s_low_noise_and_low_spur_modes;
static const uint8_t s_muxout;
static const uint8_t s_reference_doubler;
static const uint8_t s_rdiv2;
uint16_t d_10_bit_r_counter;
static const uint8_t s_double_buff;
static const uint8_t s_charge_pump_setting;
static const uint8_t s_ldf;
static const uint8_t s_ldp;
static const uint8_t s_pd_polarity;
static const uint8_t s_power_down;
static const uint8_t s_cp_three_state;
static const uint8_t s_counter_reset;
/* reg 3 */
static uint8_t _csr;
static uint8_t _clk_div_mode;
static uint16_t _12_bit_clock_divider_value;
static const uint8_t s_csr;
static const uint8_t s_clk_div_mode;
static const uint16_t s_12_bit_clock_divider_value;
/* reg 4 */
static uint8_t _feedback_select;
uint8_t _divider_select;
uint8_t _8_bit_band_select_clock_divider_value;
static uint8_t _vco_power_down;
static uint8_t _mtld;
static uint8_t _aux_output_select;
static uint8_t _aux_output_enable;
static uint8_t _aux_output_power;
static uint8_t _rf_output_enable;
static uint8_t _output_power;
static const uint8_t s_feedback_select;
uint8_t d_divider_select;
uint8_t d_8_bit_band_select_clock_divider_value;
static const uint8_t s_vco_power_down;
static const uint8_t s_mtld;
static const uint8_t s_aux_output_select;
static const uint8_t s_aux_output_enable;
static const uint8_t s_aux_output_power;
static const uint8_t s_rf_output_enable;
static const uint8_t s_output_power;
/* reg 5 */
static uint8_t _ld_pin_mode;
static const uint8_t s_ld_pin_mode;
};
#endif /* ADF4350_REGS_H */

View File

@ -46,7 +46,7 @@ wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on)
d_first = true;
d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
usrp()->_write_oe(d_which, 0, 0xffff); // turn off all outputs
usrp()->_write_oe(d_which, 1, 0xffff); // turn off all outputs
_enable_refclk(false); // disable refclk
set_auto_tr(false);
@ -125,11 +125,13 @@ wbxng_base::_lock_detect()
@returns: the value of the VCO/PLL lock detect bit.
@rtype: 0 or 1
*/
/*
if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
if(d_common->_get_locked()){
return true;
}
else { // Give it a second chance
return false;
/*
// FIXME: make portable sleep
timespec t;
t.tv_sec = 0;
@ -142,8 +144,9 @@ wbxng_base::_lock_detect()
else {
return false;
}
*/
}
*/
throw std::runtime_error("_lock_detect called from wbxng_base\n");
}
@ -199,14 +202,17 @@ wbxng_base::set_freq(double freq)
actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
*/
struct freq_result_t args = {false, 0};
freq_t int_freq = (freq_t) freq;
bool ok = d_common->_set_freq(int_freq);
double freq_result = (double) d_common->_get_freq();
struct freq_result_t args = {ok, freq_result};
// Offsetting the LO helps get the Tx carrier leakage out of the way.
// This also ensures that on Rx, we're not getting hosed by the
// FPGA's DC removal loop's time constant. We were seeing a
// problem when running with discontinuous transmission.
// Offsetting the LO made the problem go away.
freq += d_lo_offset;
//freq += d_lo_offset;
//int R, control, N;
//double actual_freq;
@ -252,15 +258,13 @@ wbxng_base::is_quadrature()
double
wbxng_base::freq_min()
{
throw std::runtime_error("freq_min called from wbxng_base\n");
//return d_common->freq_min();
return (double) d_common->_get_min_freq();
}
double
wbxng_base::freq_max()
{
throw std::runtime_error("freq_max called from wbxng_base\n");
//return d_common->freq_max();
return (double) d_common->_get_max_freq();
}
// ----------------------------------------------------------------
@ -283,13 +287,11 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
d_common = new adf4350(_usrp, d_which, d_spi_enable);
// power up the transmit side, but don't enable the mixer
/*
usrp()->_write_oe(d_which,(POWER_UP|RX_TXN|ENABLE), 0xffff);
usrp()->write_io(d_which, (power_on()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
set_lo_offset(4e6);
usrp()->_write_oe(d_which,(RX_TXN|ENABLE_33|ENABLE_5), 0xffff);
usrp()->write_io(d_which, (power_on()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5));
//set_lo_offset(4e6);
set_gain((gain_min() + gain_max()) / 2.0); // initialize gain
*/
//set_gain((gain_min() + gain_max()) / 2.0); // initialize gain
}
wbxng_base_tx::~wbxng_base_tx()
@ -308,12 +310,14 @@ wbxng_base_tx::shutdown()
// do whatever there is to do to shutdown
// Power down and leave the T/R switch in the R position
//usrp()->write_io(d_which, (power_off()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
usrp()->write_io(d_which, (power_off()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5));
/*
// Power down VCO/PLL
d_PD = 3;
_write_control(_compute_control_reg());
*/
_enable_refclk(false); // turn off refclk
set_auto_tr(false);
}
@ -325,8 +329,8 @@ wbxng_base_tx::set_auto_tr(bool on)
bool ok = true;
/*
if(on) {
ok &= set_atr_mask (RX_TXN | ENABLE);
ok &= set_atr_txval(0 | ENABLE);
ok &= set_atr_mask (RX_TXN | ENABLE_33 | ENABLE_5);
ok &= set_atr_txval(0 | ENABLE_33 | ENABLE_5);
ok &= set_atr_rxval(RX_TXN | 0);
}
else {
@ -346,15 +350,14 @@ wbxng_base_tx::set_enable(bool on)
*/
int v;
//int mask = RX_TXN | ENABLE_5 | ENABLE_33;
int mask = RX_TXN | ENABLE_5 | ENABLE_33;
if(on) {
v = ENABLE_5 | ENABLE_33;
}
else {
v = RX_TXN;
}
throw std::runtime_error("set_enable called from wbxng_base_tx\n");
//return usrp()->write_io(d_which, v, mask);
return usrp()->write_io(d_which, v, mask);
}
float
@ -408,16 +411,16 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
d_common = new adf4350(_usrp, d_which, d_spi_enable);
/*
usrp()->_write_oe(d_which, (POWER_UP|RX2_RX1N|ENABLE), 0xffff);
usrp()->write_io(d_which, (power_on()|RX2_RX1N|ENABLE),
(POWER_UP|RX2_RX1N|ENABLE));
usrp()->_write_oe(d_which, (RX2_RX1N|ENABLE_33|ENABLE_5), 0xffff);
usrp()->write_io(d_which, (power_on()|RX2_RX1N|ENABLE_33|ENABLE_5),
(RX2_RX1N|ENABLE_33|ENABLE_5));
// set up for RX on TX/RX port
select_rx_antenna("TX/RX");
bypass_adc_buffers(true);
/*
set_lo_offset(-4e6);
*/
}
@ -437,7 +440,7 @@ wbxng_base_rx::shutdown()
// do whatever there is to do to shutdown
// Power down
//usrp()->common_write_io(C_RX, d_which, power_off(), (POWER_UP|ENABLE));
usrp()->common_write_io(C_RX, d_which, power_off(), (ENABLE_33|ENABLE_5));
// Power down VCO/PLL
d_PD = 3;
@ -447,10 +450,10 @@ wbxng_base_rx::shutdown()
//_write_control(_compute_control_reg());
// fprintf(stderr, "wbxng_base_rx::shutdown before _enable_refclk\n");
//_enable_refclk(false); // turn off refclk
_enable_refclk(false); // turn off refclk
// fprintf(stderr, "wbxng_base_rx::shutdown before set_auto_tr\n");
//set_auto_tr(false);
set_auto_tr(false);
// fprintf(stderr, "wbxng_base_rx::shutdown after set_auto_tr\n");
}
@ -462,9 +465,9 @@ wbxng_base_rx::set_auto_tr(bool on)
//bool ok = true;
/*
if(on) {
ok &= set_atr_mask (ENABLE);
ok &= set_atr_mask (ENABLE_33|ENABLE_5);
ok &= set_atr_txval( 0);
ok &= set_atr_rxval(ENABLE);
ok &= set_atr_rxval(ENABLE_33|ENABLE_5);
}
else {
ok &= set_atr_mask (0);
@ -475,14 +478,13 @@ wbxng_base_rx::set_auto_tr(bool on)
return true;
}
/* *** TODO *** Defined select_rx_antenna twice?
bool
wbxng_base_rx::select_rx_antenna(int which_antenna)
{
**COMMENT**
/*
Specify which antenna port to use for reception.
@param which_antenna: either 'TX/RX' or 'RX2'
**COMMENT**
*/
if(which_antenna == 0) {
usrp()->write_io(d_which, 0,RX2_RX1N);
@ -496,7 +498,6 @@ wbxng_base_rx::select_rx_antenna(int which_antenna)
}
return true;
}
*/
bool
wbxng_base_rx::select_rx_antenna(const std::string &which_antenna)
@ -506,7 +507,7 @@ wbxng_base_rx::select_rx_antenna(const std::string &which_antenna)
@param which_antenna: either 'TX/RX' or 'RX2'
*/
/*
if(which_antenna == "TX/RX") {
usrp()->write_io(d_which, 0, RX2_RX1N);
}
@ -517,7 +518,7 @@ wbxng_base_rx::select_rx_antenna(const std::string &which_antenna)
// throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
return false;
}
*/
return true;
}

View File

@ -104,32 +104,32 @@ adf4350::_set_freq(freq_t freq){
/* Set the frequency by setting int, frac, mod, r, div */
if (freq > MAX_FREQ || freq < MIN_FREQ) return false;
/* Ramp up the RF divider until the VCO is within range. */
d_regs->_divider_select = 0;
d_regs->d_divider_select = 0;
while (freq < MIN_VCO_FREQ){
freq <<= 1; //double the freq
d_regs->_divider_select++; //double the divider
d_regs->d_divider_select++; //double the divider
}
/* Ramp up the R divider until the N divider is at least the minimum. */
d_regs->_10_bit_r_counter = INPUT_REF_FREQ_2X*MIN_INT_DIV/freq;
d_regs->d_10_bit_r_counter = INPUT_REF_FREQ_2X*MIN_INT_DIV/freq;
uint64_t n_mod;
do{
d_regs->_10_bit_r_counter++;
d_regs->d_10_bit_r_counter++;
n_mod = freq;
n_mod *= d_regs->_10_bit_r_counter;
n_mod *= d_regs->_mod;
n_mod *= d_regs->d_10_bit_r_counter;
n_mod *= d_regs->d_mod;
n_mod /= INPUT_REF_FREQ_2X;
/* calculate int and frac */
d_regs->_int = n_mod/d_regs->_mod;
d_regs->_frac = (n_mod - (freq_t)d_regs->_int*d_regs->_mod) & uint16_t(0xfff);
d_regs->d_int = n_mod/d_regs->d_mod;
d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff);
/*printf(
"VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n",
freq, d_regs->_int, d_regs->_frac,
d_regs->_mod, d_regs->_10_bit_r_counter, (1 << d_regs->_divider_select)
freq, d_regs->d_int, d_regs->d_frac,
d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select)
);*/
}while(d_regs->_int < MIN_INT_DIV);
}while(d_regs->d_int < MIN_INT_DIV);
/* calculate the band select so PFD is under 125 KHz */
d_regs->_8_bit_band_select_clock_divider_value = \
INPUT_REF_FREQ_2X/(FREQ_C(125e3)*d_regs->_10_bit_r_counter) + 1;
d_regs->d_8_bit_band_select_clock_divider_value = \
INPUT_REF_FREQ_2X/(FREQ_C(125e3)*d_regs->d_10_bit_r_counter) + 1;
/* load involved registers */
d_regs->_load_register(2);
d_regs->_load_register(4);
@ -145,12 +145,12 @@ adf4350::_get_freq(void){
* freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div)
*/
uint64_t temp;
temp = d_regs->_int;
temp *= d_regs->_mod;
temp += d_regs->_frac;
temp = d_regs->d_int;
temp *= d_regs->d_mod;
temp += d_regs->d_frac;
temp *= INPUT_REF_FREQ_2X;
temp /= d_regs->_mod;
temp /= d_regs->_10_bit_r_counter;
temp /= (1 << d_regs->_divider_select);
temp /= d_regs->d_mod;
temp /= d_regs->d_10_bit_r_counter;
temp /= (1 << d_regs->d_divider_select);
return temp;
}

View File

@ -6,47 +6,54 @@
#include <usrp/db_wbxng_adf4350.h>
//#include "cal_div.h"
/* reg 0 */
/* reg 1 */
const uint8_t adf4350_regs::s_prescaler = 1;
const uint16_t adf4350_regs::s_phase = 0;
/* reg 2 */
const uint8_t adf4350_regs::s_low_noise_and_low_spur_modes = 0;
const uint8_t adf4350_regs::s_muxout = 6;
const uint8_t adf4350_regs::s_reference_doubler = 1;
const uint8_t adf4350_regs::s_rdiv2 = 0;
const uint8_t adf4350_regs::s_double_buff = 0;
const uint8_t adf4350_regs::s_charge_pump_setting = 7;
const uint8_t adf4350_regs::s_ldf = 0;
const uint8_t adf4350_regs::s_ldp = 0;
const uint8_t adf4350_regs::s_pd_polarity = 1;
const uint8_t adf4350_regs::s_power_down = 0;
const uint8_t adf4350_regs::s_cp_three_state = 0;
const uint8_t adf4350_regs::s_counter_reset = 0;
/* reg 3 */
const uint8_t adf4350_regs::s_csr = 0;
const uint8_t adf4350_regs::s_clk_div_mode = 0;
const uint16_t adf4350_regs::s_12_bit_clock_divider_value = 0;
/* reg 4 */
const uint8_t adf4350_regs::s_feedback_select = 1;
const uint8_t adf4350_regs::s_vco_power_down = 0;
const uint8_t adf4350_regs::s_mtld = 0;
const uint8_t adf4350_regs::s_aux_output_select = 0;
const uint8_t adf4350_regs::s_aux_output_enable = 0;
const uint8_t adf4350_regs::s_aux_output_power = 0;
const uint8_t adf4350_regs::s_rf_output_enable = 1;
const uint8_t adf4350_regs::s_output_power = 1;
/* reg 5 */
const uint8_t adf4350_regs::s_ld_pin_mode = 1;
adf4350_regs::adf4350_regs(adf4350* _adf4350){
d_adf4350 = _adf4350;
/* reg 0 */
_int = uint16_t(100);
_frac = 0;
d_int = uint16_t(100);
d_frac = 0;
/* reg 1 */
_prescaler = 1; /* 8/9 */
_phase = 0; /* 0 */
_mod = uint16_t(0xfff); /* max fractional accuracy */
d_mod = uint16_t(0xfff); /* max fractional accuracy */
/* reg 2 */
_low_noise_and_low_spur_modes = 0; /* low noise mode */
_muxout = 6; /* digital lock detect */
_reference_doubler = 1; /* enabled */
_rdiv2 = 0; /* disabled */
_10_bit_r_counter = uint16_t(1);
_double_buff = 0; /* disabled */
_charge_pump_setting = 7; /* 2.50 mA */
_ldf = 0; /* frac-n */
_ldp = 0; /* 10 ns */
_pd_polarity = 1; /* positive */
_power_down = 0; /* disabled */
_cp_three_state = 0; /* disabled */
_counter_reset = 0; /* disabled */
d_10_bit_r_counter = uint16_t(1);
/* reg 3 */
_csr = 0; /* disabled */
_clk_div_mode = 0; /* clock divider off */
_12_bit_clock_divider_value = 0; /* 0 */
/* reg 4 */
_feedback_select = 1; /* fundamental */
_divider_select = 0;
_8_bit_band_select_clock_divider_value = 0;
_vco_power_down = 0; /* vco powered up */
_mtld = 0; /* mute disabled */
_aux_output_select = 0; /* divided output */
_aux_output_enable = 0; /* disabled */
_aux_output_power = 0; /* -4 */
_rf_output_enable = 1; /* enabled */
_output_power = 1; /* -1 */
d_divider_select = 0;
d_8_bit_band_select_clock_divider_value = 0;
/* reg 5 */
_ld_pin_mode = 1; /* digital lock detect */
}
adf4350_regs::~adf4350_regs(void){
@ -62,43 +69,43 @@ adf4350_regs::_load_register(uint8_t addr){
uint32_t data;
switch (addr){
case 0: data = (
_reg_shift(_int, 15) |
_reg_shift(_frac, 3)); break;
_reg_shift(d_int, 15) |
_reg_shift(d_frac, 3)); break;
case 1: data = (
_reg_shift(_prescaler, 27) |
_reg_shift(_phase, 15) |
_reg_shift(_mod, 3)); break;
_reg_shift(s_prescaler, 27) |
_reg_shift(s_phase, 15) |
_reg_shift(d_mod, 3)); break;
case 2: data = (
_reg_shift(_low_noise_and_low_spur_modes, 29) |
_reg_shift(_muxout, 26) |
_reg_shift(_reference_doubler, 25) |
_reg_shift(_rdiv2, 24) |
_reg_shift(_10_bit_r_counter, 14) |
_reg_shift(_double_buff, 13) |
_reg_shift(_charge_pump_setting, 9) |
_reg_shift(_ldf, 8) |
_reg_shift(_ldp, 7) |
_reg_shift(_pd_polarity, 6) |
_reg_shift(_power_down, 5) |
_reg_shift(_cp_three_state, 4) |
_reg_shift(_counter_reset, 3)); break;
_reg_shift(s_low_noise_and_low_spur_modes, 29) |
_reg_shift(s_muxout, 26) |
_reg_shift(s_reference_doubler, 25) |
_reg_shift(s_rdiv2, 24) |
_reg_shift(d_10_bit_r_counter, 14) |
_reg_shift(s_double_buff, 13) |
_reg_shift(s_charge_pump_setting, 9) |
_reg_shift(s_ldf, 8) |
_reg_shift(s_ldp, 7) |
_reg_shift(s_pd_polarity, 6) |
_reg_shift(s_power_down, 5) |
_reg_shift(s_cp_three_state, 4) |
_reg_shift(s_counter_reset, 3)); break;
case 3: data = (
_reg_shift(_csr, 18) |
_reg_shift(_clk_div_mode, 15) |
_reg_shift(_12_bit_clock_divider_value, 3)); break;
_reg_shift(s_csr, 18) |
_reg_shift(s_clk_div_mode, 15) |
_reg_shift(s_12_bit_clock_divider_value, 3)); break;
case 4: data = (
_reg_shift(_feedback_select, 23) |
_reg_shift(_divider_select, 20) |
_reg_shift(_8_bit_band_select_clock_divider_value, 12) |
_reg_shift(_vco_power_down, 11) |
_reg_shift(_mtld, 10) |
_reg_shift(_aux_output_select, 9) |
_reg_shift(_aux_output_enable, 8) |
_reg_shift(_aux_output_power, 6) |
_reg_shift(_rf_output_enable, 5) |
_reg_shift(_output_power, 3)); break;
_reg_shift(s_feedback_select, 23) |
_reg_shift(d_divider_select, 20) |
_reg_shift(d_8_bit_band_select_clock_divider_value, 12) |
_reg_shift(s_vco_power_down, 11) |
_reg_shift(s_mtld, 10) |
_reg_shift(s_aux_output_select, 9) |
_reg_shift(s_aux_output_enable, 8) |
_reg_shift(s_aux_output_power, 6) |
_reg_shift(s_rf_output_enable, 5) |
_reg_shift(s_output_power, 3)); break;
case 5: data = (
_reg_shift(_ld_pin_mode, 22)); break;
_reg_shift(s_ld_pin_mode, 22)); break;
default: return;
}
/* write the data out to spi */