summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/transport/CMakeLists.txt4
-rw-r--r--host/lib/transport/buffer_pool.cpp80
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp10
-rw-r--r--host/lib/transport/udp_zero_copy_asio.cpp12
-rw-r--r--host/lib/types.cpp2
-rw-r--r--host/lib/usrp/dboard/db_xcvr2450.cpp3
-rw-r--r--host/lib/usrp/usrp1/dboard_iface.cpp46
7 files changed, 129 insertions, 28 deletions
diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt
index 5602e47a7..4bfe03b10 100644
--- a/host/lib/transport/CMakeLists.txt
+++ b/host/lib/transport/CMakeLists.txt
@@ -22,7 +22,8 @@
########################################################################
# Setup libusb
########################################################################
-FIND_PACKAGE(USB1)
+MESSAGE(STATUS "")
+FIND_PACKAGE(USB1 REQUIRED)
LIBUHD_REGISTER_COMPONENT("USB" ENABLE_USB ON "ENABLE_LIBUHD;LIBUSB_FOUND" OFF)
@@ -108,6 +109,7 @@ SET_SOURCE_FILES_PROPERTIES(
)
LIBUHD_APPEND_SOURCES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/buffer_pool.cpp
${CMAKE_CURRENT_SOURCE_DIR}/if_addrs.cpp
${CMAKE_CURRENT_SOURCE_DIR}/udp_simple.cpp
${CMAKE_CURRENT_SOURCE_DIR}/udp_zero_copy_asio.cpp
diff --git a/host/lib/transport/buffer_pool.cpp b/host/lib/transport/buffer_pool.cpp
new file mode 100644
index 000000000..88ecedd2f
--- /dev/null
+++ b/host/lib/transport/buffer_pool.cpp
@@ -0,0 +1,80 @@
+//
+// 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/>.
+//
+
+#include <uhd/transport/buffer_pool.hpp>
+#include <boost/shared_array.hpp>
+#include <vector>
+
+using namespace uhd::transport;
+
+//! pad the byte count to a multiple of alignment
+static size_t pad_to_boundary(const size_t bytes, const size_t alignment){
+ return bytes + (alignment - bytes)%alignment;
+}
+
+/***********************************************************************
+ * Buffer pool implementation
+ **********************************************************************/
+class buffer_pool_impl : public buffer_pool{
+public:
+ buffer_pool_impl(
+ const std::vector<ptr_type> &ptrs,
+ boost::shared_array<char> mem
+ ): _ptrs(ptrs), _mem(mem){
+ /* NOP */
+ }
+
+ ptr_type at(const size_t index) const{
+ return _ptrs.at(index);
+ }
+
+ size_t size(void) const{
+ return _ptrs.size();
+ }
+
+private:
+ std::vector<ptr_type> _ptrs;
+ boost::shared_array<char> _mem;
+};
+
+/***********************************************************************
+ * Buffer pool factor function
+ **********************************************************************/
+buffer_pool::sptr buffer_pool::make(
+ const size_t num_buffs,
+ const size_t buff_size,
+ const size_t alignment
+){
+ //1) pad the buffer size to be a multiple of alignment
+ //2) pad the overall memory size for room after alignment
+ //3) allocate the memory in one block of sufficient size
+ const size_t padded_buff_size = pad_to_boundary(buff_size, alignment);
+ boost::shared_array<char> mem(new char[padded_buff_size*num_buffs + alignment-1]);
+
+ //Fill a vector with boundary-aligned points in the memory
+ const size_t mem_start = pad_to_boundary(size_t(mem.get()), alignment);
+ std::vector<ptr_type> ptrs(num_buffs);
+ for (size_t i = 0; i < num_buffs; i++){
+ ptrs[i] = ptr_type(mem_start + padded_buff_size*i);
+ }
+
+ //Create a new buffer pool implementation with:
+ // - the pre-computed pointers, and
+ // - the reference to allocated memory.
+ return sptr(new buffer_pool_impl(ptrs, mem));
+}
+
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index f589d7c77..5dc230527 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -18,9 +18,9 @@
#include "libusb1_base.hpp"
#include <uhd/transport/usb_zero_copy.hpp>
#include <uhd/transport/bounded_buffer.hpp>
+#include <uhd/transport/buffer_pool.hpp>
#include <uhd/utils/thread_priority.hpp>
#include <uhd/utils/assert.hpp>
-#include <boost/shared_array.hpp>
#include <boost/foreach.hpp>
#include <boost/thread.hpp>
#include <boost/enable_shared_from_this.hpp>
@@ -105,8 +105,8 @@ private:
//! a list of all transfer structs we allocated
std::vector<libusb_transfer *> _all_luts;
- //! a block of memory for the transfer buffers
- boost::shared_array<char> _buffer;
+ //! memory allocated for the transfer buffers
+ buffer_pool::sptr _buffer_pool;
// Calls for processing asynchronous I/O
libusb_transfer *allocate_transfer(void *mem, size_t len);
@@ -157,9 +157,9 @@ usb_endpoint::usb_endpoint(
_input(input)
{
_completed_list = lut_buff_type::make(num_transfers);
- _buffer = boost::shared_array<char>(new char[num_transfers*transfer_size]);
+ _buffer_pool = buffer_pool::make(num_transfers, transfer_size);
for (size_t i = 0; i < num_transfers; i++){
- _all_luts.push_back(allocate_transfer(_buffer.get() + i*transfer_size, transfer_size));
+ _all_luts.push_back(allocate_transfer(_buffer_pool->at(i), transfer_size));
//input luts are immediately submitted to be filled
//output luts go into the completed list as free buffers
diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp
index 12695893e..4f5fbebc2 100644
--- a/host/lib/transport/udp_zero_copy_asio.cpp
+++ b/host/lib/transport/udp_zero_copy_asio.cpp
@@ -18,10 +18,10 @@
#include <uhd/transport/udp_zero_copy.hpp>
#include <uhd/transport/udp_simple.hpp> //mtu
#include <uhd/transport/bounded_buffer.hpp>
+#include <uhd/transport/buffer_pool.hpp>
#include <uhd/utils/thread_priority.hpp>
#include <uhd/utils/assert.hpp>
#include <uhd/utils/warning.hpp>
-#include <boost/shared_array.hpp>
#include <boost/asio.hpp>
#include <boost/format.hpp>
#include <boost/thread.hpp>
@@ -124,16 +124,16 @@ public:
void init(void){
//allocate all recv frames and release them to begin xfers
_pending_recv_buffs = pending_buffs_type::make(_num_recv_frames);
- _recv_buffer = boost::shared_array<char>(new char[_num_recv_frames*_recv_frame_size]);
+ _recv_buffer_pool = buffer_pool::make(_num_recv_frames, _recv_frame_size);
for (size_t i = 0; i < _num_recv_frames; i++){
- release(_recv_buffer.get() + i*_recv_frame_size);
+ release(_recv_buffer_pool->at(i));
}
//allocate all send frames and push them into the fifo
_pending_send_buffs = pending_buffs_type::make(_num_send_frames);
- _send_buffer = boost::shared_array<char>(new char[_num_send_frames*_send_frame_size]);
+ _send_buffer_pool = buffer_pool::make(_num_send_frames, _send_frame_size);
for (size_t i = 0; i < _num_send_frames; i++){
- handle_send(_send_buffer.get() + i*_send_frame_size);
+ handle_send(_send_buffer_pool->at(i));
}
//spawn the service threads that will run the io service
@@ -303,7 +303,7 @@ public:
private:
//memory management -> buffers and fifos
boost::thread_group _thread_group;
- boost::shared_array<char> _send_buffer, _recv_buffer;
+ buffer_pool::sptr _send_buffer_pool, _recv_buffer_pool;
typedef bounded_buffer<asio::mutable_buffer> pending_buffs_type;
pending_buffs_type::sptr _pending_recv_buffs, _pending_send_buffs;
const size_t _recv_frame_size, _num_recv_frames;
diff --git a/host/lib/types.cpp b/host/lib/types.cpp
index bea20a4aa..9e4a26c23 100644
--- a/host/lib/types.cpp
+++ b/host/lib/types.cpp
@@ -43,8 +43,10 @@ using namespace uhd;
/***********************************************************************
* ranges template instantiation
**********************************************************************/
+#ifdef UHD_USE_EXIM_TMPL
template struct uhd::meta_range_t<float>;
template struct uhd::meta_range_t<double>;
+#endif
/***********************************************************************
* tune request
diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp
index a3a1e6242..e76727bec 100644
--- a/host/lib/usrp/dboard/db_xcvr2450.cpp
+++ b/host/lib/usrp/dboard/db_xcvr2450.cpp
@@ -245,7 +245,8 @@ void xcvr2450::update_atr(void){
int band_sel = (xcvr2450::is_highband(_lo_freq))? HB_PA_TXIO : LB_PA_TXIO;
int tx_ant_sel = (_tx_ant == "J1")? ANTSEL_TX1_RX2_TXIO : ANTSEL_TX2_RX1_TXIO;
int rx_ant_sel = (_rx_ant == "J2")? ANTSEL_TX1_RX2_TXIO : ANTSEL_TX2_RX1_TXIO;
- int xx_ant_sel = tx_ant_sel; //prefer the tx antenna selection for full duplex (rx will get the other antenna)
+ int xx_ant_sel = tx_ant_sel; //Prefer the tx antenna selection for full duplex,
+ //due to the issue that USRP1 will take the value of full duplex for its TXATR.
int ad9515div = (_ad9515div == 3)? AD9515DIV_3_TXIO : AD9515DIV_2_TXIO;
//set the tx registers
diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp
index 70ce3da76..4e47d6bf6 100644
--- a/host/lib/usrp/usrp1/dboard_iface.cpp
+++ b/host/lib/usrp/usrp1/dboard_iface.cpp
@@ -267,22 +267,38 @@ void usrp1_dboard_iface::_set_atr_reg(unit_t unit,
atr_reg_t atr, boost::uint16_t value)
{
// Ignore unsupported states
- if ((atr == ATR_REG_IDLE) || (atr == ATR_REG_FULL_DUPLEX))
+ if ((atr == ATR_REG_IDLE) || (atr == ATR_REG_TX_ONLY))
return;
-
- switch(unit) {
- case UNIT_RX:
- if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A)
- _iface->poke32(FR_ATR_RXVAL_1, value);
- else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B)
- _iface->poke32(FR_ATR_RXVAL_3, value);
- break;
- case UNIT_TX:
- if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A)
- _iface->poke32(FR_ATR_TXVAL_0, value);
- else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B)
- _iface->poke32(FR_ATR_TXVAL_2, value);
- break;
+ if(atr == ATR_REG_RX_ONLY) {
+ switch(unit) {
+ case UNIT_RX:
+ if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A)
+ _iface->poke32(FR_ATR_RXVAL_1, value);
+ else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B)
+ _iface->poke32(FR_ATR_RXVAL_3, value);
+ break;
+ case UNIT_TX:
+ if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A)
+ _iface->poke32(FR_ATR_RXVAL_0, value);
+ else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B)
+ _iface->poke32(FR_ATR_RXVAL_2, value);
+ break;
+ }
+ } else if (atr == ATR_REG_FULL_DUPLEX) {
+ switch(unit) {
+ case UNIT_RX:
+ if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A)
+ _iface->poke32(FR_ATR_TXVAL_1, value);
+ else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B)
+ _iface->poke32(FR_ATR_TXVAL_3, value);
+ break;
+ case UNIT_TX:
+ if (_dboard_slot == usrp1_impl::DBOARD_SLOT_A)
+ _iface->poke32(FR_ATR_TXVAL_0, value);
+ else if (_dboard_slot == usrp1_impl::DBOARD_SLOT_B)
+ _iface->poke32(FR_ATR_TXVAL_2, value);
+ break;
+ }
}
}
/***********************************************************************