mirror of
https://github.com/fairwaves/UHD-Fairwaves.git
synced 2025-11-02 21:13:14 +00:00
Merge branch 'umtrx_gains' into umtrx_update
This commit is contained in:
@@ -164,11 +164,18 @@ void lms6002d_dev::init()
|
||||
write_reg(0x09, 0x00); // RXOUTSW (disabled), CLK_EN (all disabled)
|
||||
write_reg(0x17, 0xE0);
|
||||
write_reg(0x27, 0xE3);
|
||||
write_reg(0x64, 0x32);
|
||||
write_reg(0x70, 0x01);
|
||||
write_reg(0x79, 0x37);
|
||||
write_reg(0x59, 0x09);
|
||||
write_reg(0x47, 0x40);
|
||||
|
||||
// FAQ v1.0r12, 5.27:
|
||||
write_reg(0x47, 0x40); // Improving Tx spurious emission performance
|
||||
write_reg(0x59, 0x29); // Improving ADC’s performance
|
||||
write_reg(0x64, 0x36); // Common Mode Voltage For ADC’s
|
||||
write_reg(0x79, 0x37); // Higher LNA Gain
|
||||
|
||||
// Power down DC comparators to improve the receiver linearity
|
||||
// (see FAQ v1.0r12, 5.26)
|
||||
lms_set_bits(0x6E, (0x3 << 6));
|
||||
lms_set_bits(0x5F, (0x1 << 7));
|
||||
|
||||
// Disable AUX PA
|
||||
// PA_EN[0]:AUXPA = 0 (powered up) - for mask set v1
|
||||
@@ -241,6 +248,10 @@ int lms6002d_dev::general_dc_calibration_loop(uint8_t dc_addr, uint8_t calibrati
|
||||
|
||||
int lms6002d_dev::general_dc_calibration(uint8_t dc_addr, uint8_t calibration_reg_base)
|
||||
{
|
||||
// Power up DC comparators
|
||||
lms_clear_bits(0x6E, (0x3 << 6));
|
||||
lms_clear_bits(0x5F, (0x1 << 7));
|
||||
|
||||
// Set DC_REGVAL to 31
|
||||
write_reg(calibration_reg_base+0x00, 31);
|
||||
// Run the calibration first time
|
||||
@@ -264,6 +275,11 @@ int lms6002d_dev::general_dc_calibration(uint8_t dc_addr, uint8_t calibration_re
|
||||
}
|
||||
}
|
||||
|
||||
// Power down DC comparators to improve the receiver linearity
|
||||
// (see FAQ v1.0r12, 5.26)
|
||||
lms_set_bits(0x6E, (0x3 << 6));
|
||||
lms_set_bits(0x5F, (0x1 << 7));
|
||||
|
||||
if (verbosity > 0) printf("Successful DC Offset Calibration for register bank 0x%X, DC addr %d. Result: 0x%X\n",
|
||||
calibration_reg_base, dc_addr, DC_REGVAL);
|
||||
return DC_REGVAL;
|
||||
|
||||
@@ -121,9 +121,9 @@ public:
|
||||
gain is in [-4 .. -35] dB range
|
||||
Returns the old gain value */
|
||||
int8_t set_tx_vga1gain(int8_t gain) {
|
||||
/* Safety check */
|
||||
if (not(-35 <= gain and gain <= -4))
|
||||
gain = -35;
|
||||
//clip
|
||||
if (gain < -35) gain = -35;
|
||||
if (gain > -4) gain = -4;
|
||||
int8_t old_bits = lms_write_bits(0x41, 0x1f, 35 + gain);
|
||||
return (old_bits & 0x1f) - 35;
|
||||
}
|
||||
@@ -155,9 +155,9 @@ public:
|
||||
gain is in dB [0 .. 25]
|
||||
Returns the old gain value */
|
||||
int8_t set_tx_vga2gain(int8_t gain) {
|
||||
/* Safety check */
|
||||
if (not(0 <= gain and gain <= 25))
|
||||
gain = 0;
|
||||
//clip
|
||||
if (gain < 0) gain = 0;
|
||||
if (gain > 25) gain = 25;
|
||||
int8_t old_bits = lms_write_bits(0x45, (0x1f << 3), (gain << 3));
|
||||
return old_bits >> 3;
|
||||
}
|
||||
@@ -175,9 +175,9 @@ public:
|
||||
gain is in dB [0 .. 60]
|
||||
Returns the old gain value */
|
||||
int8_t set_rx_vga2gain(int8_t gain) {
|
||||
/* Safety check */
|
||||
if (not (0 <= gain and gain <= 60))
|
||||
gain = 0;
|
||||
//clip
|
||||
if (gain < 0) gain = 0;
|
||||
if (gain > 60) gain = 60;
|
||||
int8_t old_bits = lms_write_bits(0x65, 0x1f, gain/3);
|
||||
return (old_bits & 0x1f) * 3;
|
||||
}
|
||||
|
||||
@@ -61,10 +61,11 @@ static const std::vector<std::string> lms_tx_antennas = list_of("TX0")("TX1")("T
|
||||
static const std::vector<std::string> lms_rx_antennas = list_of("RX0")("RX1")("RX2")("RX3")("CAL");
|
||||
|
||||
static const uhd::dict<std::string, gain_range_t> lms_tx_gain_ranges = map_list_of
|
||||
// ("VGA1", gain_range_t(-35, -4, double(1.0)))
|
||||
// ("VGA2", gain_range_t(0, 25, double(1.0)))
|
||||
//listing VGA2 first means that overall gain is first distributed to VGA2
|
||||
("VGA2", gain_range_t(0, 25, double(1.0)))
|
||||
("VGA1", gain_range_t(-35, -4, double(1.0)))
|
||||
// Use a single control to manually control how VGA1/VGA2 are set
|
||||
("VGA", gain_range_t(-35+0, -4+25, double(1.0)))
|
||||
// ("VGA", gain_range_t(-35+0, -4+25, double(1.0)))
|
||||
;
|
||||
|
||||
static const uhd::dict<std::string, gain_range_t> lms_rx_gain_ranges = map_list_of
|
||||
@@ -235,8 +236,10 @@ public:
|
||||
assert_has(lms_rx_gain_ranges.keys(), name, "LMS6002D rx gain name");
|
||||
if(name == "VGA1"){
|
||||
lms.set_rx_vga1gain(gain);
|
||||
return lms.get_rx_vga1gain();
|
||||
} else if(name == "VGA2"){
|
||||
lms.set_rx_vga2gain(gain);
|
||||
return lms.get_rx_vga2gain();
|
||||
} else UHD_THROW_INVALID_CODE_PATH();
|
||||
return gain;
|
||||
}
|
||||
@@ -290,23 +293,14 @@ public:
|
||||
//validate input
|
||||
assert_has(lms_tx_gain_ranges.keys(), name, "LMS6002D tx gain name");
|
||||
|
||||
if (name == "VGA") {
|
||||
// Calculate the best combination of VGA1 and VGA2 gains.
|
||||
// For simplicity we just try to use VGA2 as much as possible
|
||||
// and only then engage VGA1.
|
||||
int desired_vga2 = int(gain) - tx_vga1gain;
|
||||
if (desired_vga2 < 0)
|
||||
tx_vga2gain = 0;
|
||||
else if (desired_vga2 > 25)
|
||||
tx_vga2gain = 25;
|
||||
else
|
||||
tx_vga2gain = desired_vga2;
|
||||
tx_vga1gain = int(gain) - tx_vga2gain;
|
||||
|
||||
// Set the gains in hardware
|
||||
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);
|
||||
if (name == "VGA1") {
|
||||
if (verbosity>1) printf("db_lms6002d::set_tx_gain() VGA1=%d\n", int(gain));
|
||||
lms.set_tx_vga1gain(int(gain));
|
||||
return lms.get_tx_vga1gain();
|
||||
} else if (name == "VGA2") {
|
||||
if (verbosity>1) printf("db_lms6002d::set_tx_gain() VGA2=%d\n", int(gain));
|
||||
lms.set_tx_vga2gain(int(gain));
|
||||
return lms.get_tx_vga2gain();
|
||||
} else {
|
||||
UHD_THROW_INVALID_CODE_PATH();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@ add_executable(umtrx_test_chains umtrx_test_chains.cpp)
|
||||
target_link_libraries(umtrx_test_chains ${UMTRX_LIBRARIES})
|
||||
install(TARGETS umtrx_test_chains DESTINATION bin)
|
||||
|
||||
add_executable(umtrx_test_gains umtrx_test_gains.cpp)
|
||||
target_link_libraries(umtrx_test_gains ${UMTRX_LIBRARIES})
|
||||
install(TARGETS umtrx_test_gains DESTINATION bin)
|
||||
|
||||
add_executable(umtrx_cal_tx_dc_offset umtrx_cal_tx_dc_offset.cpp)
|
||||
target_link_libraries(umtrx_cal_tx_dc_offset ${UMTRX_LIBRARIES})
|
||||
install(TARGETS umtrx_cal_tx_dc_offset DESTINATION bin)
|
||||
|
||||
134
host/utils/umtrx_test_gains.cpp
Normal file
134
host/utils/umtrx_test_gains.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
//
|
||||
// Copyright 2015 Fairwaves 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 <uhd/utils/thread_priority.hpp>
|
||||
#include <uhd/utils/safe_main.hpp>
|
||||
#include <uhd/utils/paths.hpp>
|
||||
#include <uhd/utils/algorithm.hpp>
|
||||
#include <uhd/usrp/multi_usrp.hpp>
|
||||
#include <uhd/types/sensors.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
#include <boost/random.hpp>
|
||||
#include <iostream>
|
||||
#include <complex>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
static size_t failCount = 0;
|
||||
|
||||
#define CHECK(expr, expected) { \
|
||||
const double actual = expr; \
|
||||
const bool ok = (actual == expected); \
|
||||
if (not ok) failCount++; \
|
||||
std::cout << "Check: " << #expr << " == " << #expected << "\t\t\t" << ((ok)?"OK":"FAIL") << std::endl; \
|
||||
if (not ok) std::cout << "\t FAIL: actual = " << actual << std::endl; }
|
||||
|
||||
/***********************************************************************
|
||||
* Main
|
||||
**********************************************************************/
|
||||
int UHD_SAFE_MAIN(int argc, char *argv[])
|
||||
{
|
||||
std::string args;
|
||||
|
||||
po::options_description desc("Allowed options");
|
||||
desc.add_options()
|
||||
("help,h", "help message")
|
||||
("args", po::value<std::string>(&args)->default_value(""), "device address args [default = \"\"]")
|
||||
;
|
||||
|
||||
po::variables_map vm;
|
||||
po::store(po::parse_command_line(argc, argv, desc), vm);
|
||||
po::notify(vm);
|
||||
|
||||
//print the help message
|
||||
if (vm.count("help")){
|
||||
std::cout << desc << std::endl;
|
||||
return ~0;
|
||||
}
|
||||
|
||||
//create a usrp device
|
||||
std::cout << std::endl;
|
||||
std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;
|
||||
uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
|
||||
uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
|
||||
const uhd::fs_path mb_path = "/mboards/0";
|
||||
|
||||
//get the spi-interface to check gain values
|
||||
uhd::spi_iface::sptr spiface = tree->access<uhd::spi_iface::sptr>(mb_path / "spi_iface").get();
|
||||
|
||||
for (size_t ch = 0; ch <= 1; ch++)
|
||||
{
|
||||
std::cout << std::endl << "==== Testing channel: " << ch << std::endl;
|
||||
|
||||
std::cout << std::endl << "Check RX gain ranges:" << std::endl;
|
||||
CHECK(usrp->get_rx_gain_range("VGA1", ch).start(), 0);
|
||||
CHECK(usrp->get_rx_gain_range("VGA1", ch).stop(), 126);
|
||||
CHECK(usrp->get_rx_gain_range("VGA2", ch).start(), 0);
|
||||
CHECK(usrp->get_rx_gain_range("VGA2", ch).stop(), 30);
|
||||
CHECK(usrp->get_rx_gain_range(ch).start(), 0);
|
||||
CHECK(usrp->get_rx_gain_range(ch).stop(), 156);
|
||||
|
||||
std::cout << std::endl << "Check TX gain ranges:" << std::endl;
|
||||
CHECK(usrp->get_tx_gain_range("VGA1", ch).start(), -35);
|
||||
CHECK(usrp->get_tx_gain_range("VGA1", ch).stop(), -4);
|
||||
CHECK(usrp->get_tx_gain_range("VGA2", ch).start(), 0);
|
||||
CHECK(usrp->get_tx_gain_range("VGA2", ch).stop(), 25);
|
||||
CHECK(usrp->get_tx_gain_range(ch).start(), -35);
|
||||
CHECK(usrp->get_tx_gain_range(ch).stop(), 21);
|
||||
|
||||
std::cout << std::endl << "Test RX gain distribution:" << std::endl;
|
||||
usrp->set_rx_gain(0, ch);
|
||||
CHECK(usrp->get_rx_gain(ch), 0);
|
||||
CHECK(usrp->get_rx_gain("VGA1", ch), 0);
|
||||
CHECK(usrp->get_rx_gain("VGA2", ch), 0);
|
||||
usrp->set_rx_gain(15, ch);
|
||||
CHECK(usrp->get_rx_gain(ch), 15);
|
||||
CHECK(usrp->get_rx_gain("VGA1", ch), 15);
|
||||
CHECK(usrp->get_rx_gain("VGA2", ch), 0);
|
||||
usrp->set_rx_gain(129, ch);
|
||||
CHECK(usrp->get_rx_gain(ch), 129);
|
||||
CHECK(usrp->get_rx_gain("VGA1", ch), 126);
|
||||
CHECK(usrp->get_rx_gain("VGA2", ch), 3);
|
||||
|
||||
std::cout << std::endl << "Test TX gain distribution:" << std::endl;
|
||||
usrp->set_tx_gain(-35, ch);
|
||||
CHECK(usrp->get_tx_gain(ch), -35);
|
||||
CHECK(usrp->get_tx_gain("VGA2", ch), 0);
|
||||
CHECK(usrp->get_tx_gain("VGA1", ch), -35);
|
||||
usrp->set_tx_gain(-10, ch);
|
||||
CHECK(usrp->get_tx_gain(ch), -10);
|
||||
CHECK(usrp->get_tx_gain("VGA2", ch), 0);
|
||||
CHECK(usrp->get_tx_gain("VGA1", ch), -10);
|
||||
usrp->set_tx_gain(10, ch);
|
||||
CHECK(usrp->get_tx_gain(ch), 10);
|
||||
CHECK(usrp->get_tx_gain("VGA2", ch), 14);
|
||||
CHECK(usrp->get_tx_gain("VGA1", ch), -4);
|
||||
}
|
||||
|
||||
//print status
|
||||
std::cout << std::endl;
|
||||
const bool fail = failCount > 0;
|
||||
if (fail) std::cerr << std::endl << failCount << " TESTS FAILED!!!" << std::endl;
|
||||
else std::cout << std::endl << "ALL TESTS PASSED" << std::endl;
|
||||
std::cout << "Done!" << std::endl;
|
||||
return fail?EXIT_FAILURE:EXIT_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user