aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/usrp2
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/usrp2')
-rw-r--r--host/lib/usrp/usrp2/CMakeLists.txt29
-rw-r--r--host/lib/usrp/usrp2/dboard_iface.cpp57
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp24
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp3
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp32
5 files changed, 85 insertions, 60 deletions
diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt
new file mode 100644
index 000000000..f9907e21e
--- /dev/null
+++ b/host/lib/usrp/usrp2/CMakeLists.txt
@@ -0,0 +1,29 @@
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+#This file will be included by cmake, use absolute paths!
+
+LIBUHD_APPEND_SOURCES(
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/clock_control.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_impl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_iface.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dsp_impl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_iface.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.cpp
+)
diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp
index 74d80163c..372a5af07 100644
--- a/host/lib/usrp/usrp2/dboard_iface.cpp
+++ b/host/lib/usrp/usrp2/dboard_iface.cpp
@@ -29,6 +29,7 @@
using namespace uhd;
using namespace uhd::usrp;
+using namespace boost::assign;
class usrp2_dboard_iface : public dboard_iface{
public:
@@ -122,49 +123,42 @@ double usrp2_dboard_iface::get_clock_rate(unit_t){
void usrp2_dboard_iface::set_clock_enabled(unit_t unit, bool enb){
switch(unit){
- case UNIT_RX:
- _clk_ctrl->enable_rx_dboard_clock(enb);
- return;
- case UNIT_TX:
- _clk_ctrl->enable_tx_dboard_clock(enb);
- return;
+ case UNIT_RX: _clk_ctrl->enable_rx_dboard_clock(enb); return;
+ case UNIT_TX: _clk_ctrl->enable_tx_dboard_clock(enb); return;
}
}
/***********************************************************************
* GPIO
**********************************************************************/
-static int unit_to_shift(dboard_iface::unit_t unit){
- switch(unit){
- case dboard_iface::UNIT_RX: return 0;
- case dboard_iface::UNIT_TX: return 16;
- }
- throw std::runtime_error("unknown unit type");
-}
+static const uhd::dict<dboard_iface::unit_t, int> unit_to_shift = map_list_of
+ (dboard_iface::UNIT_RX, 0)
+ (dboard_iface::UNIT_TX, 16)
+;
void usrp2_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){
_ddr_shadow = \
- (_ddr_shadow & ~(0xffff << unit_to_shift(unit))) |
- (boost::uint32_t(value) << unit_to_shift(unit));
+ (_ddr_shadow & ~(0xffff << unit_to_shift[unit])) |
+ (boost::uint32_t(value) << unit_to_shift[unit]);
_iface->poke32(FR_GPIO_DDR, _ddr_shadow);
}
boost::uint16_t usrp2_dboard_iface::read_gpio(unit_t unit){
- return boost::uint16_t(_iface->peek32(FR_GPIO_IO) >> unit_to_shift(unit));
+ return boost::uint16_t(_iface->peek32(FR_GPIO_IO) >> unit_to_shift[unit]);
}
void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){
//define mapping of unit to atr regs to register address
static const uhd::dict<
unit_t, uhd::dict<atr_reg_t, boost::uint32_t>
- > unit_to_atr_to_addr = boost::assign::map_list_of
- (UNIT_RX, boost::assign::map_list_of
+ > unit_to_atr_to_addr = map_list_of
+ (UNIT_RX, map_list_of
(ATR_REG_IDLE, FR_ATR_IDLE_RXSIDE)
(ATR_REG_TX_ONLY, FR_ATR_INTX_RXSIDE)
(ATR_REG_RX_ONLY, FR_ATR_INRX_RXSIDE)
(ATR_REG_FULL_DUPLEX, FR_ATR_FULL_RXSIDE)
)
- (UNIT_TX, boost::assign::map_list_of
+ (UNIT_TX, map_list_of
(ATR_REG_IDLE, FR_ATR_IDLE_TXSIDE)
(ATR_REG_TX_ONLY, FR_ATR_INTX_TXSIDE)
(ATR_REG_RX_ONLY, FR_ATR_INRX_TXSIDE)
@@ -177,19 +171,10 @@ void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t
/***********************************************************************
* SPI
**********************************************************************/
-/*!
- * Static function to convert a unit type enum
- * to an over-the-wire value for the spi device.
- * \param unit the dboard interface unit type enum
- * \return an over the wire representation
- */
-static boost::uint8_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){
- switch(unit){
- case dboard_iface::UNIT_TX: return SPI_SS_TX_DB;
- case dboard_iface::UNIT_RX: return SPI_SS_RX_DB;
- }
- throw std::invalid_argument("unknown unit type");
-}
+static const uhd::dict<dboard_iface::unit_t, int> unit_to_spi_dev = map_list_of
+ (dboard_iface::UNIT_TX, SPI_SS_TX_DB)
+ (dboard_iface::UNIT_RX, SPI_SS_RX_DB)
+;
void usrp2_dboard_iface::write_spi(
unit_t unit,
@@ -197,7 +182,7 @@ void usrp2_dboard_iface::write_spi(
boost::uint32_t data,
size_t num_bits
){
- _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/);
+ _iface->transact_spi(unit_to_spi_dev[unit], config, data, num_bits, false /*no rb*/);
}
boost::uint32_t usrp2_dboard_iface::read_write_spi(
@@ -206,7 +191,7 @@ boost::uint32_t usrp2_dboard_iface::read_write_spi(
boost::uint32_t data,
size_t num_bits
){
- return _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/);
+ return _iface->transact_spi(unit_to_spi_dev[unit], config, data, num_bits, true /*rb*/);
}
/***********************************************************************
@@ -224,7 +209,7 @@ byte_vector_t usrp2_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes
* Aux DAX/ADC
**********************************************************************/
void usrp2_dboard_iface::_write_aux_dac(unit_t unit){
- static const uhd::dict<unit_t, int> unit_to_spi_dac = boost::assign::map_list_of
+ static const uhd::dict<unit_t, int> unit_to_spi_dac = map_list_of
(UNIT_RX, SPI_SS_RX_DAC)
(UNIT_TX, SPI_SS_TX_DAC)
;
@@ -248,7 +233,7 @@ void usrp2_dboard_iface::write_aux_dac(unit_t unit, int which, float value){
}
float usrp2_dboard_iface::read_aux_adc(unit_t unit, int which){
- static const uhd::dict<unit_t, int> unit_to_spi_adc = boost::assign::map_list_of
+ static const uhd::dict<unit_t, int> unit_to_spi_adc = map_list_of
(UNIT_RX, SPI_SS_RX_ADC)
(UNIT_TX, SPI_SS_TX_ADC)
;
diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp
index bd61ac376..195a9bc53 100644
--- a/host/lib/usrp/usrp2/dsp_impl.cpp
+++ b/host/lib/usrp/usrp2/dsp_impl.cpp
@@ -52,6 +52,23 @@ static boost::uint32_t calculate_freq_word_and_update_actual_freq(double &freq,
return freq_word;
}
+// Check if requested decim/interp rate is:
+// multiple of 4, enable two halfband filters
+// multiple of 2, enable one halfband filter
+// handle remainder in CIC
+static boost::uint32_t calculate_cic_word(size_t rate){
+ int hb0 = 0, hb1 = 0;
+ if (not (rate & 0x1)){
+ hb0 = 1;
+ rate /= 2;
+ }
+ if (not (rate & 0x1)){
+ hb1 = 1;
+ rate /= 2;
+ }
+ return (hb1 << 9) | (hb0 << 8) | (rate & 0xff);
+}
+
static boost::uint32_t calculate_iq_scale_word(boost::int16_t i, boost::int16_t q){
return (boost::uint16_t(i) << 16) | (boost::uint16_t(q) << 0);
}
@@ -81,7 +98,7 @@ void usrp2_impl::init_ddc_config(void){
void usrp2_impl::update_ddc_config(void){
//set the decimation
- _iface->poke32(FR_DSP_RX_DECIM_RATE, _ddc_decim);
+ _iface->poke32(FR_DSP_RX_DECIM_RATE, calculate_cic_word(_ddc_decim));
//set the scaling
static const boost::int16_t default_rx_scale_iq = 1024;
@@ -160,15 +177,14 @@ void usrp2_impl::init_duc_config(void){
void usrp2_impl::update_duc_config(void){
// Calculate CIC interpolation (i.e., without halfband interpolators)
- size_t tmp_interp = _duc_interp;
- while(tmp_interp > 128) tmp_interp /= 2;
+ size_t tmp_interp = calculate_cic_word(_duc_interp) & 0xff;
// Calculate closest multiplier constant to reverse gain absent scale multipliers
double interp_cubed = std::pow(double(tmp_interp), 3);
boost::int16_t scale = rint((4096*std::pow(2, ceil(log2(interp_cubed))))/(1.65*interp_cubed));
//set the interpolation
- _iface->poke32(FR_DSP_TX_INTERP_RATE, _ddc_decim);
+ _iface->poke32(FR_DSP_TX_INTERP_RATE, calculate_cic_word(_duc_interp));
//set the scaling
_iface->poke32(FR_DSP_TX_SCALE_IQ, calculate_iq_scale_word(scale, scale));
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index a2e99c824..7c9d003ce 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -39,6 +39,9 @@ void usrp2_impl::io_init(void){
//initially empty copy buffer
_rx_copy_buff = asio::buffer("", 0);
+ //init the expected rx seq number
+ _rx_stream_id_to_packet_seq[0] = 0;
+
//send a small data packet so the usrp2 knows the udp source port
managed_send_buffer::sptr send_buff = _data_transport->get_send_buff();
boost::uint32_t data = htonl(USRP2_INVALID_VRT_HEADER);
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 2b974fb9b..1dde8c054 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -113,31 +113,23 @@ device::sptr usrp2::make(const device_addr_t &device_addr){
device_addr["addr"], num2str(USRP2_UDP_CTRL_PORT)
);
- //create a data transport
- udp_zero_copy::sptr data_transport = udp_zero_copy::make(
- device_addr["addr"], num2str(USRP2_UDP_DATA_PORT)
- );
-
- //resize the recv data transport buffers
+ //extract the receive and send buffer sizes
+ size_t recv_buff_size = 0, send_buff_size= 0 ;
if (device_addr.has_key("recv_buff_size")){
- size_t num_byes = size_t(boost::lexical_cast<double>(device_addr["recv_buff_size"]));
- size_t actual_bytes = data_transport->resize_recv_buff_size(num_byes);
- if (num_byes != actual_bytes) std::cout << boost::format(
- "Target recv buffer size: %d\n"
- "Actual recv byffer size: %d"
- ) % num_byes % actual_bytes << std::endl;
+ recv_buff_size = size_t(boost::lexical_cast<double>(device_addr["recv_buff_size"]));
}
-
- //resize the send data transport buffers
if (device_addr.has_key("send_buff_size")){
- size_t num_byes = size_t(boost::lexical_cast<double>(device_addr["send_buff_size"]));
- size_t actual_bytes = data_transport->resize_send_buff_size(num_byes);
- if (num_byes != actual_bytes) std::cout << boost::format(
- "Target send buffer size: %d\n"
- "Actual send byffer size: %d"
- ) % num_byes % actual_bytes << std::endl;
+ send_buff_size = size_t(boost::lexical_cast<double>(device_addr["send_buff_size"]));
}
+ //create a data transport
+ udp_zero_copy::sptr data_transport = udp_zero_copy::make(
+ device_addr["addr"],
+ num2str(USRP2_UDP_DATA_PORT),
+ recv_buff_size,
+ send_buff_size
+ );
+
//create the usrp2 implementation guts
return device::sptr(
new usrp2_impl(ctrl_transport, data_transport)