mirror of
https://github.com/fairwaves/UHD-Fairwaves.git
synced 2025-11-03 13:33:15 +00:00
umtrx: created control interface for lms6002d
This commit is contained in:
@@ -30,6 +30,8 @@ list(APPEND UMTRX_SOURCES
|
||||
umtrx_find.cpp
|
||||
umtrx_iface.cpp
|
||||
umtrx_eeprom.cpp
|
||||
lms6002d.cpp
|
||||
lms6002d_ctrl.cpp
|
||||
missing/platform.cpp #not properly exported from uhd, so we had to copy it
|
||||
cores/rx_frontend_core_200.cpp
|
||||
cores/tx_frontend_core_200.cpp
|
||||
|
||||
424
umtrx/host/cores/adf4350_regs.hpp
Normal file
424
umtrx/host/cores/adf4350_regs.hpp
Normal file
@@ -0,0 +1,424 @@
|
||||
/***********************************************************************
|
||||
* This file was generated by /home/jblum/src/umtrx/uhd/host/lib/ic_reg_maps/gen_adf4350_regs.py on Mon Mar 31 20:02:28 2014
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef INCLUDED_ADF4350_REGS_HPP
|
||||
#define INCLUDED_ADF4350_REGS_HPP
|
||||
|
||||
#include <uhd/config.hpp>
|
||||
#include <uhd/exception.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <set>
|
||||
|
||||
class adf4350_regs_t{
|
||||
public:
|
||||
boost::uint16_t frac_12_bit;
|
||||
boost::uint16_t int_16_bit;
|
||||
boost::uint16_t mod_12_bit;
|
||||
boost::uint16_t phase_12_bit;
|
||||
enum prescaler_t{
|
||||
PRESCALER_4_5 = 0,
|
||||
PRESCALER_8_9 = 1
|
||||
};
|
||||
prescaler_t prescaler;
|
||||
enum counter_reset_t{
|
||||
COUNTER_RESET_DISABLED = 0,
|
||||
COUNTER_RESET_ENABLED = 1
|
||||
};
|
||||
counter_reset_t counter_reset;
|
||||
enum cp_three_state_t{
|
||||
CP_THREE_STATE_DISABLED = 0,
|
||||
CP_THREE_STATE_ENABLED = 1
|
||||
};
|
||||
cp_three_state_t cp_three_state;
|
||||
enum power_down_t{
|
||||
POWER_DOWN_DISABLED = 0,
|
||||
POWER_DOWN_ENABLED = 1
|
||||
};
|
||||
power_down_t power_down;
|
||||
enum pd_polarity_t{
|
||||
PD_POLARITY_NEGATIVE = 0,
|
||||
PD_POLARITY_POSITIVE = 1
|
||||
};
|
||||
pd_polarity_t pd_polarity;
|
||||
enum ldp_t{
|
||||
LDP_10NS = 0,
|
||||
LDP_6NS = 1
|
||||
};
|
||||
ldp_t ldp;
|
||||
enum ldf_t{
|
||||
LDF_FRAC_N = 0,
|
||||
LDF_INT_N = 1
|
||||
};
|
||||
ldf_t ldf;
|
||||
enum charge_pump_current_t{
|
||||
CHARGE_PUMP_CURRENT_0_31MA = 0,
|
||||
CHARGE_PUMP_CURRENT_0_63MA = 1,
|
||||
CHARGE_PUMP_CURRENT_0_94MA = 2,
|
||||
CHARGE_PUMP_CURRENT_1_25MA = 3,
|
||||
CHARGE_PUMP_CURRENT_1_56MA = 4,
|
||||
CHARGE_PUMP_CURRENT_1_88MA = 5,
|
||||
CHARGE_PUMP_CURRENT_2_19MA = 6,
|
||||
CHARGE_PUMP_CURRENT_2_50MA = 7,
|
||||
CHARGE_PUMP_CURRENT_2_81MA = 8,
|
||||
CHARGE_PUMP_CURRENT_3_13MA = 9,
|
||||
CHARGE_PUMP_CURRENT_3_44MA = 10,
|
||||
CHARGE_PUMP_CURRENT_3_75MA = 11,
|
||||
CHARGE_PUMP_CURRENT_4_07MA = 12,
|
||||
CHARGE_PUMP_CURRENT_4_38MA = 13,
|
||||
CHARGE_PUMP_CURRENT_4_69MA = 14,
|
||||
CHARGE_PUMP_CURRENT_5_00MA = 15
|
||||
};
|
||||
charge_pump_current_t charge_pump_current;
|
||||
enum double_buffer_t{
|
||||
DOUBLE_BUFFER_DISABLED = 0,
|
||||
DOUBLE_BUFFER_ENABLED = 1
|
||||
};
|
||||
double_buffer_t double_buffer;
|
||||
boost::uint16_t r_counter_10_bit;
|
||||
enum reference_divide_by_2_t{
|
||||
REFERENCE_DIVIDE_BY_2_DISABLED = 0,
|
||||
REFERENCE_DIVIDE_BY_2_ENABLED = 1
|
||||
};
|
||||
reference_divide_by_2_t reference_divide_by_2;
|
||||
enum reference_doubler_t{
|
||||
REFERENCE_DOUBLER_DISABLED = 0,
|
||||
REFERENCE_DOUBLER_ENABLED = 1
|
||||
};
|
||||
reference_doubler_t reference_doubler;
|
||||
enum muxout_t{
|
||||
MUXOUT_3STATE = 0,
|
||||
MUXOUT_DVDD = 1,
|
||||
MUXOUT_DGND = 2,
|
||||
MUXOUT_RDIV = 3,
|
||||
MUXOUT_NDIV = 4,
|
||||
MUXOUT_ANALOG_LD = 5,
|
||||
MUXOUT_DLD = 6,
|
||||
MUXOUT_RESERVED = 7
|
||||
};
|
||||
muxout_t muxout;
|
||||
enum low_noise_and_spur_t{
|
||||
LOW_NOISE_AND_SPUR_LOW_NOISE = 0,
|
||||
LOW_NOISE_AND_SPUR_RESERVED0 = 1,
|
||||
LOW_NOISE_AND_SPUR_RESERVED1 = 2,
|
||||
LOW_NOISE_AND_SPUR_LOW_SPUR = 3
|
||||
};
|
||||
low_noise_and_spur_t low_noise_and_spur;
|
||||
boost::uint16_t clock_divider_12_bit;
|
||||
enum clock_div_mode_t{
|
||||
CLOCK_DIV_MODE_CLOCK_DIVIDER_OFF = 0,
|
||||
CLOCK_DIV_MODE_FAST_LOCK = 1,
|
||||
CLOCK_DIV_MODE_RESYNC_ENABLE = 2,
|
||||
CLOCK_DIV_MODE_RESERVED = 3
|
||||
};
|
||||
clock_div_mode_t clock_div_mode;
|
||||
enum cycle_slip_reduction_t{
|
||||
CYCLE_SLIP_REDUCTION_DISABLED = 0,
|
||||
CYCLE_SLIP_REDUCTION_ENABLED = 1
|
||||
};
|
||||
cycle_slip_reduction_t cycle_slip_reduction;
|
||||
enum output_power_t{
|
||||
OUTPUT_POWER_M4DBM = 0,
|
||||
OUTPUT_POWER_M1DBM = 1,
|
||||
OUTPUT_POWER_2DBM = 2,
|
||||
OUTPUT_POWER_5DBM = 3
|
||||
};
|
||||
output_power_t output_power;
|
||||
enum rf_output_enable_t{
|
||||
RF_OUTPUT_ENABLE_DISABLED = 0,
|
||||
RF_OUTPUT_ENABLE_ENABLED = 1
|
||||
};
|
||||
rf_output_enable_t rf_output_enable;
|
||||
enum aux_output_power_t{
|
||||
AUX_OUTPUT_POWER_M4DBM = 0,
|
||||
AUX_OUTPUT_POWER_M1DBM = 1,
|
||||
AUX_OUTPUT_POWER_2DBM = 2,
|
||||
AUX_OUTPUT_POWER_5DBM = 3
|
||||
};
|
||||
aux_output_power_t aux_output_power;
|
||||
enum aux_output_enable_t{
|
||||
AUX_OUTPUT_ENABLE_DISABLED = 0,
|
||||
AUX_OUTPUT_ENABLE_ENABLED = 1
|
||||
};
|
||||
aux_output_enable_t aux_output_enable;
|
||||
enum aux_output_select_t{
|
||||
AUX_OUTPUT_SELECT_DIVIDED = 0,
|
||||
AUX_OUTPUT_SELECT_FUNDAMENTAL = 1
|
||||
};
|
||||
aux_output_select_t aux_output_select;
|
||||
enum mute_till_lock_detect_t{
|
||||
MUTE_TILL_LOCK_DETECT_MUTE_DISABLED = 0,
|
||||
MUTE_TILL_LOCK_DETECT_MUTE_ENABLED = 1
|
||||
};
|
||||
mute_till_lock_detect_t mute_till_lock_detect;
|
||||
enum vco_power_down_t{
|
||||
VCO_POWER_DOWN_VCO_POWERED_UP = 0,
|
||||
VCO_POWER_DOWN_VCO_POWERED_DOWN = 1
|
||||
};
|
||||
vco_power_down_t vco_power_down;
|
||||
boost::uint8_t band_select_clock_div;
|
||||
enum rf_divider_select_t{
|
||||
RF_DIVIDER_SELECT_DIV1 = 0,
|
||||
RF_DIVIDER_SELECT_DIV2 = 1,
|
||||
RF_DIVIDER_SELECT_DIV4 = 2,
|
||||
RF_DIVIDER_SELECT_DIV8 = 3,
|
||||
RF_DIVIDER_SELECT_DIV16 = 4
|
||||
};
|
||||
rf_divider_select_t rf_divider_select;
|
||||
enum feedback_select_t{
|
||||
FEEDBACK_SELECT_DIVIDED = 0,
|
||||
FEEDBACK_SELECT_FUNDAMENTAL = 1
|
||||
};
|
||||
feedback_select_t feedback_select;
|
||||
enum ld_pin_mode_t{
|
||||
LD_PIN_MODE_LOW0 = 0,
|
||||
LD_PIN_MODE_DLD = 1,
|
||||
LD_PIN_MODE_LOW = 2,
|
||||
LD_PIN_MODE_HIGH = 3
|
||||
};
|
||||
ld_pin_mode_t ld_pin_mode;
|
||||
|
||||
adf4350_regs_t(void){
|
||||
_state = NULL;
|
||||
frac_12_bit = 0;
|
||||
int_16_bit = 35;
|
||||
mod_12_bit = 4095;
|
||||
phase_12_bit = 0;
|
||||
prescaler = PRESCALER_4_5;
|
||||
counter_reset = COUNTER_RESET_DISABLED;
|
||||
cp_three_state = CP_THREE_STATE_DISABLED;
|
||||
power_down = POWER_DOWN_DISABLED;
|
||||
pd_polarity = PD_POLARITY_POSITIVE;
|
||||
ldp = LDP_10NS;
|
||||
ldf = LDF_FRAC_N;
|
||||
charge_pump_current = CHARGE_PUMP_CURRENT_1_88MA;
|
||||
double_buffer = DOUBLE_BUFFER_DISABLED;
|
||||
r_counter_10_bit = 0;
|
||||
reference_divide_by_2 = REFERENCE_DIVIDE_BY_2_ENABLED;
|
||||
reference_doubler = REFERENCE_DOUBLER_DISABLED;
|
||||
muxout = MUXOUT_DVDD;
|
||||
low_noise_and_spur = LOW_NOISE_AND_SPUR_LOW_SPUR;
|
||||
clock_divider_12_bit = 0;
|
||||
clock_div_mode = CLOCK_DIV_MODE_FAST_LOCK;
|
||||
cycle_slip_reduction = CYCLE_SLIP_REDUCTION_DISABLED;
|
||||
output_power = OUTPUT_POWER_5DBM;
|
||||
rf_output_enable = RF_OUTPUT_ENABLE_ENABLED;
|
||||
aux_output_power = AUX_OUTPUT_POWER_M4DBM;
|
||||
aux_output_enable = AUX_OUTPUT_ENABLE_DISABLED;
|
||||
aux_output_select = AUX_OUTPUT_SELECT_FUNDAMENTAL;
|
||||
mute_till_lock_detect = MUTE_TILL_LOCK_DETECT_MUTE_DISABLED;
|
||||
vco_power_down = VCO_POWER_DOWN_VCO_POWERED_UP;
|
||||
band_select_clock_div = 0;
|
||||
rf_divider_select = RF_DIVIDER_SELECT_DIV1;
|
||||
feedback_select = FEEDBACK_SELECT_FUNDAMENTAL;
|
||||
ld_pin_mode = LD_PIN_MODE_DLD;
|
||||
}
|
||||
|
||||
~adf4350_regs_t(void){
|
||||
delete _state;
|
||||
}
|
||||
|
||||
enum addr_t{
|
||||
ADDR_R0 = 0,
|
||||
ADDR_R1 = 1,
|
||||
ADDR_R2 = 2,
|
||||
ADDR_R3 = 3,
|
||||
ADDR_R4 = 4,
|
||||
ADDR_R5 = 5
|
||||
};
|
||||
|
||||
boost::uint32_t get_reg(boost::uint8_t addr){
|
||||
boost::uint32_t reg = addr & 0x7;
|
||||
switch(addr){
|
||||
case 0:
|
||||
reg |= (boost::uint32_t(frac_12_bit) & 0xfff) << 3;
|
||||
reg |= (boost::uint32_t(int_16_bit) & 0xffff) << 15;
|
||||
break;
|
||||
case 1:
|
||||
reg |= (boost::uint32_t(mod_12_bit) & 0xfff) << 3;
|
||||
reg |= (boost::uint32_t(phase_12_bit) & 0xfff) << 15;
|
||||
reg |= (boost::uint32_t(prescaler) & 0x1) << 27;
|
||||
break;
|
||||
case 2:
|
||||
reg |= (boost::uint32_t(counter_reset) & 0x1) << 3;
|
||||
reg |= (boost::uint32_t(cp_three_state) & 0x1) << 4;
|
||||
reg |= (boost::uint32_t(power_down) & 0x1) << 5;
|
||||
reg |= (boost::uint32_t(pd_polarity) & 0x1) << 6;
|
||||
reg |= (boost::uint32_t(ldp) & 0x1) << 7;
|
||||
reg |= (boost::uint32_t(ldf) & 0x1) << 8;
|
||||
reg |= (boost::uint32_t(charge_pump_current) & 0xf) << 9;
|
||||
reg |= (boost::uint32_t(double_buffer) & 0x1) << 13;
|
||||
reg |= (boost::uint32_t(r_counter_10_bit) & 0x3ff) << 14;
|
||||
reg |= (boost::uint32_t(reference_divide_by_2) & 0x1) << 24;
|
||||
reg |= (boost::uint32_t(reference_doubler) & 0x1) << 25;
|
||||
reg |= (boost::uint32_t(muxout) & 0x7) << 26;
|
||||
reg |= (boost::uint32_t(low_noise_and_spur) & 0x3) << 29;
|
||||
break;
|
||||
case 3:
|
||||
reg |= (boost::uint32_t(clock_divider_12_bit) & 0xfff) << 3;
|
||||
reg |= (boost::uint32_t(clock_div_mode) & 0x3) << 15;
|
||||
reg |= (boost::uint32_t(cycle_slip_reduction) & 0x1) << 18;
|
||||
break;
|
||||
case 4:
|
||||
reg |= (boost::uint32_t(output_power) & 0x3) << 3;
|
||||
reg |= (boost::uint32_t(rf_output_enable) & 0x1) << 5;
|
||||
reg |= (boost::uint32_t(aux_output_power) & 0x3) << 6;
|
||||
reg |= (boost::uint32_t(aux_output_enable) & 0x1) << 8;
|
||||
reg |= (boost::uint32_t(aux_output_select) & 0x1) << 9;
|
||||
reg |= (boost::uint32_t(mute_till_lock_detect) & 0x1) << 10;
|
||||
reg |= (boost::uint32_t(vco_power_down) & 0x1) << 11;
|
||||
reg |= (boost::uint32_t(band_select_clock_div) & 0xff) << 12;
|
||||
reg |= (boost::uint32_t(rf_divider_select) & 0x7) << 20;
|
||||
reg |= (boost::uint32_t(feedback_select) & 0x1) << 23;
|
||||
break;
|
||||
case 5:
|
||||
reg |= (boost::uint32_t(ld_pin_mode) & 0x3) << 22;
|
||||
break;
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
void save_state(void){
|
||||
if (_state == NULL) _state = new adf4350_regs_t();
|
||||
_state->frac_12_bit = this->frac_12_bit;
|
||||
_state->int_16_bit = this->int_16_bit;
|
||||
_state->mod_12_bit = this->mod_12_bit;
|
||||
_state->phase_12_bit = this->phase_12_bit;
|
||||
_state->prescaler = this->prescaler;
|
||||
_state->counter_reset = this->counter_reset;
|
||||
_state->cp_three_state = this->cp_three_state;
|
||||
_state->power_down = this->power_down;
|
||||
_state->pd_polarity = this->pd_polarity;
|
||||
_state->ldp = this->ldp;
|
||||
_state->ldf = this->ldf;
|
||||
_state->charge_pump_current = this->charge_pump_current;
|
||||
_state->double_buffer = this->double_buffer;
|
||||
_state->r_counter_10_bit = this->r_counter_10_bit;
|
||||
_state->reference_divide_by_2 = this->reference_divide_by_2;
|
||||
_state->reference_doubler = this->reference_doubler;
|
||||
_state->muxout = this->muxout;
|
||||
_state->low_noise_and_spur = this->low_noise_and_spur;
|
||||
_state->clock_divider_12_bit = this->clock_divider_12_bit;
|
||||
_state->clock_div_mode = this->clock_div_mode;
|
||||
_state->cycle_slip_reduction = this->cycle_slip_reduction;
|
||||
_state->output_power = this->output_power;
|
||||
_state->rf_output_enable = this->rf_output_enable;
|
||||
_state->aux_output_power = this->aux_output_power;
|
||||
_state->aux_output_enable = this->aux_output_enable;
|
||||
_state->aux_output_select = this->aux_output_select;
|
||||
_state->mute_till_lock_detect = this->mute_till_lock_detect;
|
||||
_state->vco_power_down = this->vco_power_down;
|
||||
_state->band_select_clock_div = this->band_select_clock_div;
|
||||
_state->rf_divider_select = this->rf_divider_select;
|
||||
_state->feedback_select = this->feedback_select;
|
||||
_state->ld_pin_mode = this->ld_pin_mode;
|
||||
}
|
||||
|
||||
template<typename T> std::set<T> get_changed_addrs(void){
|
||||
if (_state == NULL) throw uhd::runtime_error("no saved state");
|
||||
//check each register for changes
|
||||
std::set<T> addrs;
|
||||
if(_state->frac_12_bit != this->frac_12_bit){
|
||||
addrs.insert(0);
|
||||
}
|
||||
if(_state->int_16_bit != this->int_16_bit){
|
||||
addrs.insert(0);
|
||||
}
|
||||
if(_state->mod_12_bit != this->mod_12_bit){
|
||||
addrs.insert(1);
|
||||
}
|
||||
if(_state->phase_12_bit != this->phase_12_bit){
|
||||
addrs.insert(1);
|
||||
}
|
||||
if(_state->prescaler != this->prescaler){
|
||||
addrs.insert(1);
|
||||
}
|
||||
if(_state->counter_reset != this->counter_reset){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->cp_three_state != this->cp_three_state){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->power_down != this->power_down){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->pd_polarity != this->pd_polarity){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->ldp != this->ldp){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->ldf != this->ldf){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->charge_pump_current != this->charge_pump_current){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->double_buffer != this->double_buffer){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->r_counter_10_bit != this->r_counter_10_bit){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->reference_divide_by_2 != this->reference_divide_by_2){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->reference_doubler != this->reference_doubler){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->muxout != this->muxout){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->low_noise_and_spur != this->low_noise_and_spur){
|
||||
addrs.insert(2);
|
||||
}
|
||||
if(_state->clock_divider_12_bit != this->clock_divider_12_bit){
|
||||
addrs.insert(3);
|
||||
}
|
||||
if(_state->clock_div_mode != this->clock_div_mode){
|
||||
addrs.insert(3);
|
||||
}
|
||||
if(_state->cycle_slip_reduction != this->cycle_slip_reduction){
|
||||
addrs.insert(3);
|
||||
}
|
||||
if(_state->output_power != this->output_power){
|
||||
addrs.insert(4);
|
||||
}
|
||||
if(_state->rf_output_enable != this->rf_output_enable){
|
||||
addrs.insert(4);
|
||||
}
|
||||
if(_state->aux_output_power != this->aux_output_power){
|
||||
addrs.insert(4);
|
||||
}
|
||||
if(_state->aux_output_enable != this->aux_output_enable){
|
||||
addrs.insert(4);
|
||||
}
|
||||
if(_state->aux_output_select != this->aux_output_select){
|
||||
addrs.insert(4);
|
||||
}
|
||||
if(_state->mute_till_lock_detect != this->mute_till_lock_detect){
|
||||
addrs.insert(4);
|
||||
}
|
||||
if(_state->vco_power_down != this->vco_power_down){
|
||||
addrs.insert(4);
|
||||
}
|
||||
if(_state->band_select_clock_div != this->band_select_clock_div){
|
||||
addrs.insert(4);
|
||||
}
|
||||
if(_state->rf_divider_select != this->rf_divider_select){
|
||||
addrs.insert(4);
|
||||
}
|
||||
if(_state->feedback_select != this->feedback_select){
|
||||
addrs.insert(4);
|
||||
}
|
||||
if(_state->ld_pin_mode != this->ld_pin_mode){
|
||||
addrs.insert(5);
|
||||
}
|
||||
return addrs;
|
||||
}
|
||||
|
||||
private:
|
||||
adf4350_regs_t *_state;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_ADF4350_REGS_HPP */
|
||||
@@ -1,111 +0,0 @@
|
||||
//
|
||||
// Copyright 2012 Fairwaves
|
||||
// Copyright 2010-2011 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 <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include "gpio_core_200.hpp"
|
||||
#include "umtrx_regs.hpp" //wishbone address constants?
|
||||
#include <uhd/usrp/dboard_iface.hpp>
|
||||
#include <uhd/types/dict.hpp>
|
||||
#include <uhd/exception.hpp>
|
||||
#include <uhd/utils/algorithm.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/asio.hpp> //htonl and ntohl
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
#include "usrp2_iface.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
using namespace uhd;
|
||||
using namespace uhd::usrp;
|
||||
using namespace boost::assign;
|
||||
|
||||
class umtrx_dboard_iface : public dboard_iface {
|
||||
usrp2_iface::sptr _iface;
|
||||
const std::string _dboard;
|
||||
double _ref_clk;
|
||||
int _lms_spi_number;
|
||||
int _adf4350_spi_number;
|
||||
void _write_aux_dac(unit_t) {}
|
||||
|
||||
public:
|
||||
umtrx_dboard_iface(usrp2_iface::sptr iface, const std::string board, double ref_clk)
|
||||
: _iface(iface), _dboard(board),
|
||||
_ref_clk(ref_clk),
|
||||
_lms_spi_number(board=="A"?SPI_SS_LMS1:SPI_SS_LMS2),
|
||||
_adf4350_spi_number(board=="A"?SPI_SS_AUX1:SPI_SS_AUX2)
|
||||
{}
|
||||
~umtrx_dboard_iface(void) {}
|
||||
|
||||
special_props_t get_special_props(void) {
|
||||
special_props_t props;
|
||||
props.soft_clock_divider = false;
|
||||
props.mangle_i2c_addrs = false;
|
||||
return props;
|
||||
}
|
||||
|
||||
void write_aux_dac(unit_t, aux_dac_t, double) {}
|
||||
double read_aux_adc(unit_t, aux_adc_t) { return 0; }
|
||||
|
||||
void _set_pin_ctrl(unit_t, boost::uint16_t) {}
|
||||
void _set_gpio_ddr(unit_t, boost::uint16_t) {}
|
||||
void _set_gpio_out(unit_t, boost::uint16_t) {}
|
||||
boost::uint16_t read_gpio(unit_t) { return 0; }
|
||||
void _set_atr_reg(unit_t, atr_reg_t, boost::uint16_t) {}
|
||||
void set_gpio_debug(unit_t, int) {}
|
||||
|
||||
void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes) { return _iface->write_i2c(addr, bytes); }
|
||||
byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes) { return _iface->read_i2c(addr, num_bytes); }
|
||||
|
||||
void set_clock_rate(unit_t, double) { /* The clock rate is fixed */ }
|
||||
double get_clock_rate(unit_t) { return _ref_clk; }
|
||||
std::vector<double> get_clock_rates(unit_t) { assert(!"umtrx_dboard_iface::get_clock_rates() is not implemented"); std::vector<double> FIXME; return FIXME; }
|
||||
void set_clock_enabled(unit_t, bool) { /* It's always enabled. */ }
|
||||
double get_codec_rate(unit_t) { assert(!"umtrx_dboard_iface::get_codec_rate() is not implemented"); return 0; }
|
||||
|
||||
void write_spi(unit_t spi_device, const spi_config_t &config, boost::uint32_t data, size_t num_bits) {
|
||||
if (spi_device == uhd::usrp::dboard_iface::UNIT_LMS) {
|
||||
// Access LMS
|
||||
_iface->write_spi(_lms_spi_number, config, data, num_bits);
|
||||
} else if (spi_device == uhd::usrp::dboard_iface::UNIT_SYNT) {
|
||||
// Access ADF4350 synthetiser
|
||||
// _iface->write_spi(_adf4350_spi_number, config, data, num_bits);
|
||||
_iface->write_spi(SPI_SS_AUX1, config, data, num_bits);
|
||||
_iface->write_spi(SPI_SS_AUX2, config, data, num_bits);
|
||||
} else {
|
||||
assert(!"Wrong unit_t pased to umtrx_dboard_iface::write_spi.");
|
||||
}
|
||||
}
|
||||
|
||||
boost::uint32_t read_write_spi(unit_t spi_device, const spi_config_t &config, boost::uint32_t data, size_t num_bits) {
|
||||
if (spi_device == uhd::usrp::dboard_iface::UNIT_LMS) {
|
||||
// Access LMS
|
||||
return _iface->read_spi(_lms_spi_number, config, data, num_bits);
|
||||
} else if (spi_device == uhd::usrp::dboard_iface::UNIT_SYNT) {
|
||||
// Access ADF4350 synthetiser
|
||||
// return _iface->read_spi(_adf4350_spi_number, config, data, num_bits);
|
||||
return _iface->read_spi(SPI_SS_AUX1, config, data, num_bits);
|
||||
return _iface->read_spi(SPI_SS_AUX2, config, data, num_bits);
|
||||
}
|
||||
assert(!"Wrong unit_t pased to umtrx_dboard_iface::write_spi.");
|
||||
return 0; // FIXME: propagate error for non-assert builds
|
||||
}
|
||||
};
|
||||
|
||||
/**********************************
|
||||
* Make Function
|
||||
**********************************/
|
||||
dboard_iface::sptr make_umtrx_dboard_iface(usrp2_iface::sptr iface, const std::string dboard, double ref_clk) {
|
||||
return dboard_iface::sptr(new umtrx_dboard_iface(iface, dboard, ref_clk));
|
||||
}
|
||||
@@ -1,3 +1,11 @@
|
||||
/***********************************************************************
|
||||
* The interface to lms6002d that get registered into the property tree
|
||||
**********************************************************************/
|
||||
|
||||
#include "lms6002d_ctrl.hpp"
|
||||
#include "lms6002d.hpp"
|
||||
#include "cores/adf4350_regs.hpp"
|
||||
|
||||
#include <uhd/utils/log.hpp>
|
||||
#include <uhd/utils/static.hpp>
|
||||
#include <uhd/utils/assert_has.hpp>
|
||||
@@ -18,9 +26,6 @@
|
||||
#include <cfloat>
|
||||
#include <limits>
|
||||
|
||||
#include "../umtrx/lms6002d.hpp"
|
||||
#include "adf4350_regs.hpp"
|
||||
|
||||
using namespace uhd;
|
||||
using namespace uhd::usrp;
|
||||
using namespace boost::assign;
|
||||
@@ -75,34 +80,103 @@ static int verbosity = 0;
|
||||
// LMS6002D interface class for UmTRX
|
||||
|
||||
class umtrx_lms6002d_dev: public lms6002d_dev {
|
||||
dboard_iface::sptr _db_iface;
|
||||
uhd::spi_iface::sptr _spiface;
|
||||
const int _slaveno;
|
||||
public:
|
||||
umtrx_lms6002d_dev(dboard_iface::sptr db_iface) : _db_iface(db_iface) {};
|
||||
umtrx_lms6002d_dev(uhd::spi_iface::sptr spiface, const int slaveno) : _spiface(spiface), _slaveno(slaveno) {};
|
||||
|
||||
virtual void write_reg(uint8_t addr, uint8_t data) {
|
||||
if (verbosity>2) printf("db_lms6002d::write_reg(addr=0x%x, data=0x%x)\n", addr, data);
|
||||
if (verbosity>2) printf("lms6002d_ctrl_impl::write_reg(addr=0x%x, data=0x%x)\n", addr, data);
|
||||
uint16_t command = (((uint16_t)0x80 | (uint16_t)addr) << 8) | (uint16_t)data;
|
||||
_db_iface->write_spi(uhd::usrp::dboard_iface::UNIT_LMS,
|
||||
spi_config_t::EDGE_RISE, command, 16);
|
||||
_spiface->write_spi(_slaveno, spi_config_t::EDGE_RISE, command, 16);
|
||||
}
|
||||
virtual uint8_t read_reg(uint8_t addr) {
|
||||
if(addr > 127) return 0; // incorrect address, 7 bit long expected
|
||||
uint8_t data = _db_iface->read_write_spi(uhd::usrp::dboard_iface::UNIT_LMS,
|
||||
spi_config_t::EDGE_RISE, addr << 8, 16);
|
||||
if (verbosity>2) printf("db_lms6002d::read_reg(addr=0x%x) data=0x%x\n", addr, data);
|
||||
uint8_t data = _spiface->read_spi(_slaveno, spi_config_t::EDGE_RISE, addr << 8, 16);
|
||||
if (verbosity>2) printf("lms6002d_ctrl_impl::read_reg(addr=0x%x) data=0x%x\n", addr, data);
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
// LMS6002D virtual daughter board for UmTRX
|
||||
|
||||
class db_lms6002d : public xcvr_dboard_base {
|
||||
class lms6002d_ctrl_impl : public lms6002d_ctrl {
|
||||
public:
|
||||
db_lms6002d(ctor_args_t args);
|
||||
lms6002d_ctrl_impl(uhd::spi_iface::sptr spiface, const int lms_spi_number, const int adf4350_spi_number, const double clock_rate);
|
||||
|
||||
double set_rx_freq(const double freq)
|
||||
{
|
||||
return this->set_freq(dboard_iface::UNIT_RX, freq);
|
||||
}
|
||||
|
||||
double set_tx_freq(const double freq)
|
||||
{
|
||||
return this->set_freq(dboard_iface::UNIT_TX, freq);
|
||||
}
|
||||
|
||||
bool set_rx_enabled(const bool enb)
|
||||
{
|
||||
return this->set_enabled(dboard_iface::UNIT_RX, enb);
|
||||
}
|
||||
|
||||
bool set_tx_enabled(const bool enb)
|
||||
{
|
||||
return this->set_enabled(dboard_iface::UNIT_RX, enb);
|
||||
}
|
||||
|
||||
uhd::freq_range_t get_rx_bw_range(void)
|
||||
{
|
||||
return lms_bandwidth_range;
|
||||
}
|
||||
|
||||
uhd::freq_range_t get_tx_bw_range(void)
|
||||
{
|
||||
return lms_bandwidth_range;
|
||||
}
|
||||
|
||||
uhd::freq_range_t get_rx_freq_range(void)
|
||||
{
|
||||
return lms_freq_range;
|
||||
}
|
||||
|
||||
uhd::freq_range_t get_tx_freq_range(void)
|
||||
{
|
||||
return lms_freq_range;
|
||||
}
|
||||
|
||||
std::vector<std::string> get_tx_antennas(void)
|
||||
{
|
||||
return lms_tx_antennas;
|
||||
}
|
||||
|
||||
std::vector<std::string> get_rx_antennas(void)
|
||||
{
|
||||
return lms_rx_antennas;
|
||||
}
|
||||
|
||||
std::vector<std::string> get_tx_gains(void)
|
||||
{
|
||||
return lms_tx_gain_ranges.keys();
|
||||
}
|
||||
|
||||
std::vector<std::string> get_rx_gains(void)
|
||||
{
|
||||
return lms_rx_gain_ranges.keys();
|
||||
}
|
||||
|
||||
uhd::gain_range_t get_rx_gain_range(const std::string &name)
|
||||
{
|
||||
return lms_rx_gain_ranges[name];
|
||||
}
|
||||
|
||||
uhd::gain_range_t get_tx_gain_range(const std::string &name)
|
||||
{
|
||||
return lms_tx_gain_ranges[name];
|
||||
}
|
||||
|
||||
double set_freq(dboard_iface::unit_t unit, double f) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_freq(%f)\n", f);
|
||||
unsigned ref_freq = get_iface()->get_clock_rate(dboard_iface::UNIT_LMS);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_freq(%f)\n", f);
|
||||
unsigned ref_freq = _clock_rate;
|
||||
double actual_freq = 0;
|
||||
if (unit==dboard_iface::UNIT_TX) {
|
||||
actual_freq = lms.tx_pll_tune(ref_freq, f);
|
||||
@@ -113,24 +187,24 @@ public:
|
||||
// New beta version of the code for UmSEL support.
|
||||
const double umsel_if = 359.5e6;
|
||||
double actual_lms_freq = lms.rx_pll_tune(ref_freq, umsel_if);
|
||||
if (verbosity>0) printf("db_lms6002d::set_freq() actual_lms_freq=%f\n", actual_lms_freq);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_freq() actual_lms_freq=%f\n", actual_lms_freq);
|
||||
double adf4350_freq = f - actual_lms_freq;
|
||||
actual_freq = tune_adf4350(adf4350_freq);
|
||||
if (verbosity>0) printf("db_lms6002d::set_freq() adf4350 freq=%f\n", actual_freq);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_freq() adf4350 freq=%f\n", actual_freq);
|
||||
actual_freq += actual_lms_freq;
|
||||
if (verbosity>0) printf("db_lms6002d::set_freq() actual_freq=%f\n", actual_freq);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_freq() actual_freq=%f\n", actual_freq);
|
||||
#endif
|
||||
} else {
|
||||
assert(!"Wrong units_t value passed to db_lms6002d::set_freq()");
|
||||
assert(!"Wrong units_t value passed to lms6002d_ctrl_impl::set_freq()");
|
||||
}
|
||||
if (actual_freq<0)
|
||||
actual_freq = 0;
|
||||
if (verbosity>0) printf("db_lms6002d::set_freq() actual_freq=%f\n", actual_freq);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_freq() actual_freq=%f\n", actual_freq);
|
||||
return actual_freq;
|
||||
}
|
||||
|
||||
bool set_enabled(dboard_iface::unit_t unit, bool en) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_enabled(%d)\n", en);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_enabled(%d)\n", en);
|
||||
if (unit==dboard_iface::UNIT_RX) {
|
||||
if (en)
|
||||
lms.rx_enable();
|
||||
@@ -147,7 +221,7 @@ public:
|
||||
}
|
||||
|
||||
double set_rx_gain(double gain, const std::string &name) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_rx_gain(%f, %s)\n", gain, name.c_str());
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_rx_gain(%f, %s)\n", gain, name.c_str());
|
||||
assert_has(lms_rx_gain_ranges.keys(), name, "LMS6002D rx gain name");
|
||||
if(name == "VGA1"){
|
||||
lms.set_rx_vga1gain(gain);
|
||||
@@ -158,14 +232,14 @@ public:
|
||||
}
|
||||
|
||||
void set_rx_ant(const std::string &ant) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_rx_ant(%s)\n", ant.c_str());
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_rx_ant(%s)\n", ant.c_str());
|
||||
//validate input
|
||||
assert_has(lms_rx_antennas, ant, "LMS6002D rx antenna name");
|
||||
|
||||
if (ant == "CAL") {
|
||||
// Enable RF loopback if disabled
|
||||
if (!rf_loopback_enabled) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_rx_ant(%s) enabling RF loopback for LNA%d\n", ant.c_str(), lms.get_rx_lna());
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_rx_ant(%s) enabling RF loopback for LNA%d\n", ant.c_str(), lms.get_rx_lna());
|
||||
lms.rf_loopback_enable(lms.get_rx_lna());
|
||||
rf_loopback_enabled = true;
|
||||
}
|
||||
@@ -191,7 +265,7 @@ public:
|
||||
}
|
||||
|
||||
double set_rx_bandwidth(double bandwidth) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_rx_bandwidth(%f)\n", bandwidth);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_rx_bandwidth(%f)\n", bandwidth);
|
||||
// Get the closest available bandwidth
|
||||
bandwidth = lms_bandwidth_range.clip(bandwidth);
|
||||
|
||||
@@ -202,7 +276,7 @@ public:
|
||||
}
|
||||
|
||||
double set_tx_gain(double gain, const std::string &name) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_tx_gain(%f, %s)\n", gain, name.c_str());
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_tx_gain(%f, %s)\n", gain, name.c_str());
|
||||
//validate input
|
||||
assert_has(lms_tx_gain_ranges.keys(), name, "LMS6002D tx gain name");
|
||||
|
||||
@@ -220,7 +294,7 @@ public:
|
||||
tx_vga1gain = int(gain) - tx_vga2gain;
|
||||
|
||||
// Set the gains in hardware
|
||||
if (verbosity>1) printf("db_lms6002d::set_tx_gain() VGA1=%d VGA2=%d\n", tx_vga1gain, tx_vga2gain);
|
||||
if (verbosity>1) printf("lms6002d_ctrl_impl::set_tx_gain() VGA1=%d VGA2=%d\n", tx_vga1gain, tx_vga2gain);
|
||||
lms.set_tx_vga1gain(tx_vga1gain);
|
||||
lms.set_tx_vga2gain(tx_vga2gain);
|
||||
} else {
|
||||
@@ -232,7 +306,7 @@ public:
|
||||
}
|
||||
|
||||
void set_tx_ant(const std::string &ant) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_tx_ant(%s)\n", ant.c_str());
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_tx_ant(%s)\n", ant.c_str());
|
||||
//validate input
|
||||
assert_has(lms_tx_antennas, ant, "LMS6002D tx antenna ant");
|
||||
|
||||
@@ -251,7 +325,7 @@ public:
|
||||
}
|
||||
|
||||
double set_tx_bandwidth(double bandwidth) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_tx_bandwidth(%f)\n", bandwidth);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_tx_bandwidth(%f)\n", bandwidth);
|
||||
// Get the closest available bandwidth
|
||||
bandwidth = lms_bandwidth_range.clip(bandwidth);
|
||||
|
||||
@@ -262,13 +336,13 @@ public:
|
||||
}
|
||||
|
||||
uint8_t _set_tx_vga1dc_i_int(uint8_t offset) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_tx_vga1dc_i_int(%d)\n", offset);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_tx_vga1dc_i_int(%d)\n", offset);
|
||||
lms.set_tx_vga1dc_i_int(offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
uint8_t _set_tx_vga1dc_q_int(uint8_t offset) {
|
||||
if (verbosity>0) printf("db_lms6002d::set_tx_vga1dc_q_int(%d)\n", offset);
|
||||
if (verbosity>0) printf("lms6002d_ctrl_impl::set_tx_vga1dc_q_int(%d)\n", offset);
|
||||
lms.set_tx_vga1dc_q_int(offset);
|
||||
return offset;
|
||||
}
|
||||
@@ -280,12 +354,22 @@ private:
|
||||
|
||||
// Tune ADF4350 on an UmSEL
|
||||
double tune_adf4350(double target_freq);
|
||||
|
||||
uhd::spi_iface::sptr _spiface;
|
||||
const int _lms_spi_number;
|
||||
const int _adf4350_spi_number;
|
||||
const double _clock_rate;
|
||||
};
|
||||
|
||||
lms6002d_ctrl::sptr lms6002d_ctrl::make(uhd::spi_iface::sptr spiface, const int lms_spi_number, const int adf4350_spi_number, const double clock_rate)
|
||||
{
|
||||
return sptr(new lms6002d_ctrl_impl(spiface, lms_spi_number, adf4350_spi_number, clock_rate));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Tuning
|
||||
**********************************************************************/
|
||||
double db_lms6002d::tune_adf4350(double target_freq) {
|
||||
double lms6002d_ctrl_impl::tune_adf4350(double target_freq) {
|
||||
UHD_LOGV(often) << boost::format(
|
||||
"UmSEL tune: target frequency %f Mhz"
|
||||
) % (target_freq/1e6) << std::endl;
|
||||
@@ -311,7 +395,7 @@ double db_lms6002d::tune_adf4350(double target_freq) {
|
||||
|
||||
double actual_freq, pfd_freq;
|
||||
// TODO:: May be *2? Check
|
||||
double ref_freq = get_iface()->get_clock_rate(dboard_iface::UNIT_LMS) * 2;
|
||||
double ref_freq = _clock_rate * 2;
|
||||
int R=0, BS=0, N=0, FRAC=0, MOD=0;
|
||||
int RFdiv = 1;
|
||||
adf4350_regs_t::reference_divide_by_2_t T = adf4350_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
|
||||
@@ -436,12 +520,12 @@ double db_lms6002d::tune_adf4350(double target_freq) {
|
||||
);
|
||||
}
|
||||
#else
|
||||
this->get_iface()->write_spi(uhd::usrp::dboard_iface::UNIT_SYNT, spi_config_t::EDGE_RISE, 0x0580000|5, 32);
|
||||
this->get_iface()->write_spi(uhd::usrp::dboard_iface::UNIT_SYNT, spi_config_t::EDGE_RISE, 0x0BFF4F8|4, 32);
|
||||
this->get_iface()->write_spi(uhd::usrp::dboard_iface::UNIT_SYNT, spi_config_t::EDGE_RISE, 0x0040000|3, 32);
|
||||
this->get_iface()->write_spi(uhd::usrp::dboard_iface::UNIT_SYNT, spi_config_t::EDGE_RISE, 0x1006E40|2, 32);
|
||||
this->get_iface()->write_spi(uhd::usrp::dboard_iface::UNIT_SYNT, spi_config_t::EDGE_RISE, 0x8008208|1, 32);
|
||||
this->get_iface()->write_spi(uhd::usrp::dboard_iface::UNIT_SYNT, spi_config_t::EDGE_RISE, (325<<15)|(1<<3)|0, 32);
|
||||
_spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, 0x0580000|5, 32);
|
||||
_spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, 0x0BFF4F8|4, 32);
|
||||
_spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, 0x0040000|3, 32);
|
||||
_spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, 0x1006E40|2, 32);
|
||||
_spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, 0x8008208|1, 32);
|
||||
_spiface->write_spi(_adf4350_spi_number, spi_config_t::EDGE_RISE, (325<<15)|(1<<3)|0, 32);
|
||||
#endif
|
||||
|
||||
//return the actual frequency
|
||||
@@ -452,23 +536,17 @@ double db_lms6002d::tune_adf4350(double target_freq) {
|
||||
return actual_freq;
|
||||
}
|
||||
|
||||
// Register the LMS dboards
|
||||
|
||||
static dboard_base::sptr make_lms6002d(dboard_base::ctor_args_t args) {
|
||||
return dboard_base::sptr(new db_lms6002d(args));
|
||||
}
|
||||
|
||||
UHD_STATIC_BLOCK(reg_lms_dboards){
|
||||
dboard_manager::register_dboard(0xfa07, 0xfa09, &make_lms6002d, "LMS6002D");
|
||||
}
|
||||
|
||||
// LMS RX dboard configuration
|
||||
|
||||
db_lms6002d::db_lms6002d(ctor_args_t args) : xcvr_dboard_base(args),
|
||||
lms(get_iface()),
|
||||
lms6002d_ctrl_impl::lms6002d_ctrl_impl(uhd::spi_iface::sptr spiface, const int lms_spi_number, const int adf4350_spi_number, const double clock_rate) :
|
||||
lms(umtrx_lms6002d_dev(spiface, lms_spi_number)),
|
||||
tx_vga1gain(lms.get_tx_vga1gain()),
|
||||
tx_vga2gain(lms.get_tx_vga2gain()),
|
||||
rf_loopback_enabled(false)
|
||||
rf_loopback_enabled(false),
|
||||
_spiface(spiface),
|
||||
_lms_spi_number(lms_spi_number),
|
||||
_adf4350_spi_number(adf4350_spi_number),
|
||||
_clock_rate(clock_rate)
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// LMS6002D initialization
|
||||
@@ -484,8 +562,9 @@ db_lms6002d::db_lms6002d(ctor_args_t args) : xcvr_dboard_base(args),
|
||||
lms.set_tx_vga1gain(-10);
|
||||
|
||||
// Perform autocalibration
|
||||
lms.auto_calibration(get_iface()->get_clock_rate(dboard_iface::UNIT_LMS), 0xf);
|
||||
lms.auto_calibration(_clock_rate, 0xf);
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Register RX properties
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -494,19 +573,19 @@ db_lms6002d::db_lms6002d(ctor_args_t args) : xcvr_dboard_base(args),
|
||||
|
||||
BOOST_FOREACH(const std::string &name, lms_rx_gain_ranges.keys()){
|
||||
this->get_rx_subtree()->create<double>("gains/"+name+"/value")
|
||||
.coerce(boost::bind(&db_lms6002d::set_rx_gain, this, _1, name))
|
||||
.coerce(boost::bind(&lms6002d_ctrl_impl::set_rx_gain, this, _1, name))
|
||||
.set((lms_rx_gain_ranges[name].start()+lms_rx_gain_ranges[name].stop())/2.0);
|
||||
this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
|
||||
.set(lms_rx_gain_ranges[name]);
|
||||
}
|
||||
|
||||
this->get_rx_subtree()->create<double>("freq/value")
|
||||
.coerce(boost::bind(&db_lms6002d::set_freq, this, dboard_iface::UNIT_RX, _1));
|
||||
.coerce(boost::bind(&lms6002d_ctrl_impl::set_freq, this, dboard_iface::UNIT_RX, _1));
|
||||
this->get_rx_subtree()->create<meta_range_t>("freq/range")
|
||||
.set(lms_freq_range);
|
||||
|
||||
this->get_rx_subtree()->create<std::string>("antenna/value")
|
||||
.subscribe(boost::bind(&db_lms6002d::set_rx_ant, this, _1))
|
||||
.subscribe(boost::bind(&lms6002d_ctrl_impl::set_rx_ant, this, _1))
|
||||
.set("RX1");
|
||||
this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options")
|
||||
.set(lms_rx_antennas);
|
||||
@@ -515,11 +594,11 @@ db_lms6002d::db_lms6002d(ctor_args_t args) : xcvr_dboard_base(args),
|
||||
.set(sensor_value_t("LO", true, "locked", "unlocked"));
|
||||
this->get_rx_subtree()->create<std::string>("connection").set("IQ");
|
||||
this->get_rx_subtree()->create<bool>("enabled")
|
||||
.coerce(boost::bind(&db_lms6002d::set_enabled, this, dboard_iface::UNIT_RX, _1));
|
||||
.coerce(boost::bind(&lms6002d_ctrl_impl::set_enabled, this, dboard_iface::UNIT_RX, _1));
|
||||
|
||||
this->get_rx_subtree()->create<bool>("use_lo_offset").set(false);
|
||||
this->get_rx_subtree()->create<double>("bandwidth/value")
|
||||
.coerce(boost::bind(&db_lms6002d::set_rx_bandwidth, this, _1))
|
||||
.coerce(boost::bind(&lms6002d_ctrl_impl::set_rx_bandwidth, this, _1))
|
||||
.set(double(2*0.75e6));
|
||||
this->get_rx_subtree()->create<meta_range_t>("bandwidth/range")
|
||||
.set(lms_bandwidth_range);
|
||||
@@ -532,19 +611,19 @@ db_lms6002d::db_lms6002d(ctor_args_t args) : xcvr_dboard_base(args),
|
||||
|
||||
BOOST_FOREACH(const std::string &name, lms_tx_gain_ranges.keys()){
|
||||
this->get_tx_subtree()->create<double>("gains/"+name+"/value")
|
||||
.coerce(boost::bind(&db_lms6002d::set_tx_gain, this, _1, name))
|
||||
.coerce(boost::bind(&lms6002d_ctrl_impl::set_tx_gain, this, _1, name))
|
||||
.set((lms_tx_gain_ranges[name].start()+lms_tx_gain_ranges[name].stop())/2.0);
|
||||
this->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range")
|
||||
.set(lms_tx_gain_ranges[name]);
|
||||
}
|
||||
|
||||
this->get_tx_subtree()->create<double>("freq/value")
|
||||
.coerce(boost::bind(&db_lms6002d::set_freq, this, dboard_iface::UNIT_TX, _1));
|
||||
.coerce(boost::bind(&lms6002d_ctrl_impl::set_freq, this, dboard_iface::UNIT_TX, _1));
|
||||
this->get_tx_subtree()->create<meta_range_t>("freq/range")
|
||||
.set(lms_freq_range);
|
||||
|
||||
this->get_tx_subtree()->create<std::string>("antenna/value")
|
||||
.subscribe(boost::bind(&db_lms6002d::set_tx_ant, this, _1))
|
||||
.subscribe(boost::bind(&lms6002d_ctrl_impl::set_tx_ant, this, _1))
|
||||
.set("TX2");
|
||||
this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options")
|
||||
.set(lms_tx_antennas);
|
||||
@@ -553,21 +632,22 @@ db_lms6002d::db_lms6002d(ctor_args_t args) : xcvr_dboard_base(args),
|
||||
.set(sensor_value_t("LO", true, "locked", "unlocked"));
|
||||
this->get_tx_subtree()->create<std::string>("connection").set("IQ");
|
||||
this->get_tx_subtree()->create<bool>("enabled")
|
||||
.coerce(boost::bind(&db_lms6002d::set_enabled, this, dboard_iface::UNIT_TX, _1));
|
||||
.coerce(boost::bind(&lms6002d_ctrl_impl::set_enabled, this, dboard_iface::UNIT_TX, _1));
|
||||
|
||||
this->get_tx_subtree()->create<bool>("use_lo_offset").set(false);
|
||||
this->get_tx_subtree()->create<double>("bandwidth/value")
|
||||
.coerce(boost::bind(&db_lms6002d::set_tx_bandwidth, this, _1))
|
||||
.coerce(boost::bind(&lms6002d_ctrl_impl::set_tx_bandwidth, this, _1))
|
||||
.set(double(2*0.75e6));
|
||||
this->get_tx_subtree()->create<meta_range_t>("bandwidth/range")
|
||||
.set(lms_bandwidth_range);
|
||||
|
||||
// UmTRX specific calibration
|
||||
this->get_tx_subtree()->create<uint8_t>("lms6002d/tx_dc_i/value")
|
||||
.subscribe(boost::bind(&db_lms6002d::_set_tx_vga1dc_i_int, this, _1))
|
||||
.subscribe(boost::bind(&lms6002d_ctrl_impl::_set_tx_vga1dc_i_int, this, _1))
|
||||
.publish(boost::bind(&umtrx_lms6002d_dev::get_tx_vga1dc_i_int, &lms));
|
||||
this->get_tx_subtree()->create<uint8_t>("lms6002d/tx_dc_q/value")
|
||||
.subscribe(boost::bind(&db_lms6002d::_set_tx_vga1dc_q_int, this, _1))
|
||||
.subscribe(boost::bind(&lms6002d_ctrl_impl::_set_tx_vga1dc_q_int, this, _1))
|
||||
.publish(boost::bind(&umtrx_lms6002d_dev::get_tx_vga1dc_q_int, &lms));
|
||||
*/
|
||||
}
|
||||
|
||||
50
umtrx/host/lms6002d_ctrl.hpp
Normal file
50
umtrx/host/lms6002d_ctrl.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef INCLUDED_LMS6002D_CTRL_HPP
|
||||
#define INCLUDED_LMS6002D_CTRL_HPP
|
||||
|
||||
#include <uhd/types/ranges.hpp>
|
||||
#include <uhd/types/serial.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
/***********************************************************************
|
||||
* The interface to lms6002d that get registered into the property tree
|
||||
**********************************************************************/
|
||||
class lms6002d_ctrl
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<lms6002d_ctrl> sptr;
|
||||
static sptr make(uhd::spi_iface::sptr spiface, const int lms_spi_number, const int adf4350_spi_number, const double clock_rate);
|
||||
|
||||
virtual double set_rx_freq(const double freq) = 0;
|
||||
virtual double set_tx_freq(const double freq) = 0;
|
||||
|
||||
virtual bool set_rx_enabled(const bool enb) = 0;
|
||||
virtual bool set_tx_enabled(const bool enb) = 0;
|
||||
|
||||
virtual double set_rx_gain(const double gain, const std::string &name) = 0;
|
||||
virtual double set_tx_gain(const double gain, const std::string &name) = 0;
|
||||
|
||||
virtual void set_rx_ant(const std::string &ant) = 0;
|
||||
virtual void set_tx_ant(const std::string &ant) = 0;
|
||||
|
||||
virtual double set_rx_bandwidth(const double bandwidth) = 0;
|
||||
virtual double set_tx_bandwidth(const double bandwidth) = 0;
|
||||
|
||||
virtual uhd::freq_range_t get_rx_bw_range(void) = 0;
|
||||
virtual uhd::freq_range_t get_tx_bw_range(void) = 0;
|
||||
|
||||
virtual uhd::freq_range_t get_rx_freq_range(void) = 0;
|
||||
virtual uhd::freq_range_t get_tx_freq_range(void) = 0;
|
||||
|
||||
virtual std::vector<std::string> get_tx_antennas(void) = 0;
|
||||
virtual std::vector<std::string> get_rx_antennas(void) = 0;
|
||||
|
||||
virtual std::vector<std::string> get_tx_gains(void) = 0;
|
||||
virtual std::vector<std::string> get_rx_gains(void) = 0;
|
||||
|
||||
virtual uhd::gain_range_t get_rx_gain_range(const std::string &name) = 0;
|
||||
virtual uhd::gain_range_t get_tx_gain_range(const std::string &name) = 0;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_LMS6002D_CTRL_HPP */
|
||||
Reference in New Issue
Block a user