diff options
Diffstat (limited to 'host/usrp_e_utils')
-rw-r--r-- | host/usrp_e_utils/CMakeLists.txt | 42 | ||||
-rw-r--r-- | host/usrp_e_utils/common.hpp | 64 | ||||
-rw-r--r-- | host/usrp_e_utils/usrp-e-loopback.cpp | 298 | ||||
-rw-r--r-- | host/usrp_e_utils/usrp-e-wb-test.cpp | 68 |
4 files changed, 0 insertions, 472 deletions
diff --git a/host/usrp_e_utils/CMakeLists.txt b/host/usrp_e_utils/CMakeLists.txt deleted file mode 100644 index 0d6763174..000000000 --- a/host/usrp_e_utils/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright 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/>. -# - -######################################################################## -# USRP embedded utilities that get installed into the share path -######################################################################## -LIBUHD_REGISTER_COMPONENT("USRP-E Utils" ENABLE_USRP_E_UTILS OFF "LINUX" OFF) - -IF(ENABLE_USRP_E_UTILS) - ENABLE_LANGUAGE(C) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/lib/usrp/e100) - INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/lib/usrp/e100/include) - - SET(usrp_e_utils_sources - usrp-e-loopback.cpp - usrp-e-wb-test.cpp - ) - - #for each source: build an executable and install - FOREACH(util_source ${usrp_e_utils_sources}) - GET_FILENAME_COMPONENT(util_name ${util_source} NAME_WE) - ADD_EXECUTABLE(${util_name} ${util_source}) - TARGET_LINK_LIBRARIES(${util_name} ${Boost_LIBRARIES}) - INSTALL(TARGETS ${util_name} RUNTIME DESTINATION ${PKG_LIB_DIR}/usrp_e_utils) - ENDFOREACH(util_source) - -ENDIF(ENABLE_USRP_E_UTILS) diff --git a/host/usrp_e_utils/common.hpp b/host/usrp_e_utils/common.hpp deleted file mode 100644 index 989aecd06..000000000 --- a/host/usrp_e_utils/common.hpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright 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 <sys/ioctl.h> //ioctl -#include <fcntl.h> //open, close - -#include <linux/usrp_e.h> -#include "e100_regs.hpp" - -static int fp; - -static inline int peek16(int reg){ - int ret; - struct usrp_e_ctl16 d; - - d.offset = reg; - d.count = 1; - ret = ioctl(fp, USRP_E_READ_CTL16, &d); - return d.buf[0]; -} - -static inline void poke16(int reg, int val){ - int ret; - struct usrp_e_ctl16 d; - - d.offset = reg; - d.count = 1; - d.buf[0] = val; - ret = ioctl(fp, USRP_E_WRITE_CTL16, &d); -} - -static inline int peek32(int reg){ - int ret; - struct usrp_e_ctl32 d; - - d.offset = reg; - d.count = 1; - ret = ioctl(fp, USRP_E_READ_CTL32, &d); - return d.buf[0]; -} - -static inline void poke32(int reg, int val){ - int ret; - struct usrp_e_ctl32 d; - - d.offset = reg; - d.count = 1; - d.buf[0] = val; - ret = ioctl(fp, USRP_E_WRITE_CTL32, &d); -} diff --git a/host/usrp_e_utils/usrp-e-loopback.cpp b/host/usrp_e_utils/usrp-e-loopback.cpp deleted file mode 100644 index d4220adc3..000000000 --- a/host/usrp_e_utils/usrp-e-loopback.cpp +++ /dev/null @@ -1,298 +0,0 @@ -// -// Copyright 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 "common.hpp" -#include <cstdlib> -#include <cstdio> -#include <cstring> -#include <ctime> -#include <iostream> -#include <boost/thread/thread.hpp> -#include <boost/format.hpp> -#include <boost/cstdint.hpp> -#include <sys/mman.h> //mmap -#include <unistd.h> //getpagesize -#include <poll.h> //poll - -static const size_t bytes_per_frame = 2048; - -static const int poll_timeout_ms = 100; - -struct loopback_pkt_hdr_type{ - boost::uint32_t words32; - boost::uint32_t checksum; - boost::uint64_t seq_num; -}; - -struct loopback_pkt_type{ - loopback_pkt_hdr_type hdr; - boost::uint32_t data[(bytes_per_frame-sizeof(loopback_pkt_hdr_type))/sizeof(boost::uint32_t)]; -}; - -static ring_buffer_info (*recv_info)[]; -static ring_buffer_info (*send_info)[]; -static loopback_pkt_type (*recv_buff)[]; -static loopback_pkt_type (*send_buff)[]; - -static struct usrp_e_ring_buffer_size_t rb_size; - -static bool running = true; - -static boost::uint64_t seq_errors = 0; -static boost::uint64_t checksum_errors = 0; -static boost::uint64_t sent_words32 = 0; -static boost::uint64_t recvd_words32 = 0; - -static inline void print_pkt(const loopback_pkt_type &pkt){ - std::cout << std::endl; - std::cout << "pkt.hdr.words32 " << pkt.hdr.words32 << std::endl; - std::cout << "pkt.hdr.checksum " << pkt.hdr.checksum << std::endl; - std::cout << "pkt.hdr.seq_num " << pkt.hdr.seq_num << std::endl; -} - -boost::uint32_t my_checksum(void *buff, size_t size32){ - boost::uint32_t x = 0; - for (size_t i = 0; i < size32; i++){ - x += reinterpret_cast<boost::uint32_t *>(buff)[i]; - x ^= reinterpret_cast<boost::uint32_t *>(buff)[i]; - } - return x; -} - -/*********************************************************************** - * Read thread - recv frames and verify checksum - **********************************************************************/ -static void read_thread(void){ - std::cout << "start read thread... " << std::endl; - - boost::uint64_t seq_num = 0; - size_t index = 0; - - while (running){ - - loopback_pkt_type &pkt = (*recv_buff)[index]; - ring_buffer_info &info = (*recv_info)[index]; - - //wait for frame available - if (not (info.flags & RB_USER)){ - pollfd pfd; - pfd.fd = fp; - pfd.events = POLLIN; - if (poll(&pfd, 1, poll_timeout_ms) <= 0){ - std::cout << "Read poll timeout, exiting read thread!" << std::endl; - running = false; - return; - } - } - info.flags = RB_USER_PROCESS; - - //print_pkt(pkt); - - //handle checksum - const boost::uint32_t expected_checksum = pkt.hdr.checksum; - pkt.hdr.checksum = 0; //set to zero for calculation - const boost::uint32_t actual_checksum = my_checksum(&pkt, pkt.hdr.words32); - if (expected_checksum != actual_checksum){ - checksum_errors++; - std::cerr << "C"; - } - else{ - recvd_words32 += pkt.hdr.words32; - } - - //handle sequence - if (seq_num != pkt.hdr.seq_num){ - seq_errors++; - std::cerr << "S"; - } - seq_num = pkt.hdr.seq_num+1; - - //release the packet - info.flags = RB_KERNEL; - - //increment index and wrap around to zero - index++; - if (index == size_t(rb_size.num_rx_frames)) index = 0; - } - -} - -/*********************************************************************** - * Write thread - send frames and calculate checksum - **********************************************************************/ -static void write_thread(const size_t num_words32){ - std::cout << "start write thread... " << std::endl; - - srandom(std::time(NULL)); - - boost::uint64_t seq_num = 0; - size_t index = 0; - - //write into tmp and memcopy into pkt to avoid cache issues - loopback_pkt_type pkt_tmp; - - while (running){ - - ring_buffer_info &info = (*send_info)[index]; - - //wait for frame available - if (not (info.flags & RB_KERNEL)){ - pollfd pfd; - pfd.fd = fp; - pfd.events = POLLOUT; - if (poll(&pfd, 1, poll_timeout_ms) <= 0){ - std::cout << "Write poll timeout, exiting write thread!" << std::endl; - running = false; - return; - } - } - - //fill packet header and body - const boost::uint32_t seed = random(); - pkt_tmp.hdr.words32 = sizeof(pkt_tmp.hdr)/sizeof(boost::uint32_t) + num_words32; - pkt_tmp.hdr.checksum = 0; //set to zero for checksum() - pkt_tmp.hdr.seq_num = seq_num++; - for (size_t i = 0; i < num_words32; i++) pkt_tmp.data[i] = seed + i; - pkt_tmp.hdr.checksum = my_checksum(&pkt_tmp, pkt_tmp.hdr.words32); - sent_words32 += pkt_tmp.hdr.words32; - - loopback_pkt_type &pkt = (*send_buff)[index]; - std::memcpy(&pkt, &pkt_tmp, pkt_tmp.hdr.words32*sizeof(boost::uint32_t)); - - //print_pkt(pkt); - - //commit the packet - info.len = pkt_tmp.hdr.words32*sizeof(boost::uint32_t); - info.flags = RB_USER; - ::write(fp, NULL, 0); - - //increment index and wrap around to zero - index++; - if (index == size_t(rb_size.num_tx_frames)) index = 0; - } -} - -/*********************************************************************** - * Setup memory mapped ring buffer - **********************************************************************/ -static void setup_ring(void){ - std::cout << "setup memory mapped ring buffer... " << std::flush; - - //calculate various sizes - const size_t page_size = getpagesize(); - ioctl(fp, USRP_E_GET_RB_INFO, &rb_size); - const size_t map_size = (rb_size.num_pages_rx_flags + rb_size.num_pages_tx_flags) * page_size + - (rb_size.num_rx_frames + rb_size.num_tx_frames) * (page_size >> 1); - - //call into memory map - void *mem = ::mmap(0, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); - if (mem == MAP_FAILED) { - std::cerr << "mmap failed" << std::endl; - std::exit(-1); - } - - //calculate the memory offsets for info and buffers - const size_t recv_info_off = 0; - const size_t recv_buff_off = recv_info_off + (rb_size.num_pages_rx_flags * page_size); - const size_t send_info_off = recv_buff_off + (rb_size.num_rx_frames * page_size/2); - const size_t send_buff_off = send_info_off + (rb_size.num_pages_tx_flags * page_size); - - //set the internal pointers for info and buffers - typedef ring_buffer_info (*rbi_pta)[]; - typedef loopback_pkt_type (*pkt_pta)[]; - char *rb_ptr = reinterpret_cast<char *>(mem); - recv_info = reinterpret_cast<rbi_pta>(rb_ptr + recv_info_off); - recv_buff = reinterpret_cast<pkt_pta>(rb_ptr + recv_buff_off); - send_info = reinterpret_cast<rbi_pta>(rb_ptr + send_info_off); - send_buff = reinterpret_cast<pkt_pta>(rb_ptr + send_buff_off); - - std::cout << "done" << std::endl; -} - -/*********************************************************************** - * Main - **********************************************************************/ -#include <boost/program_options.hpp> - -int main(int argc, char *argv[]){ - - //variables to be set by po - double duration; - size_t nwords; - - //setup the program options - namespace po = boost::program_options; - po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ("duration", po::value<double>(&duration)->default_value(10), "number of seconds to run loopback") - ("nwords", po::value<size_t>(&nwords)->default_value(400), "number of words32 to send per packet") - ; - 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 << boost::format("UHD USRP-E-Loopback %s") % desc << std::endl; - return ~0; - } - - if ((fp = ::open("/dev/usrp_e0", O_RDWR)) < 0){ - std::cerr << "Open failed" << std::endl; - return -1; - } - - //set the mode to loopback - poke16(E100_REG_MISC_XFER_RATE, (1<<8) | (1<<9)); - - //clear FIFO state in FPGA and kernel - poke32(E100_REG_CLEAR_FIFO, 0); - ::close(fp); - if ((fp = ::open("/dev/usrp_e0", O_RDWR)) < 0){ - std::cerr << "Open failed" << std::endl; - return -1; - } - - //setup the ring buffer - setup_ring(); - - //spawn threads - boost::thread_group tg; - tg.create_thread(boost::bind(&read_thread)); - tg.create_thread(boost::bind(&write_thread, nwords)); - - const boost::system_time start_time = boost::get_system_time(); - const boost::system_time finish_time = start_time + boost::posix_time::milliseconds(long(duration*1000)); - while (boost::get_system_time() < finish_time){ - boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); - std::cerr << "."; - } - running = false; - tg.join_all(); - - std::cout << std::endl; - std::cout << "seq_errors " << seq_errors << std::endl; - std::cout << "checksum_errors " << checksum_errors << std::endl; - std::cout << "sent_words32 " << sent_words32 << std::endl; - std::cout << "recvd_words32 " << recvd_words32 << std::endl; - std::cout << "approx send rate " << (sent_words32/duration)/1e6 << "Msps" << std::endl; - std::cout << "approx recv rate " << (recvd_words32/duration)/1e6 << "Msps" << std::endl; - - ::close(fp); - return seq_errors + checksum_errors; -} diff --git a/host/usrp_e_utils/usrp-e-wb-test.cpp b/host/usrp_e_utils/usrp-e-wb-test.cpp deleted file mode 100644 index 2b793dc06..000000000 --- a/host/usrp_e_utils/usrp-e-wb-test.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright 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 "common.hpp" -#include <cstdlib> -#include <cstdio> -#include <ctime> -#include <iostream> - -static const size_t num_test_iters = 10000000; - -int main(int, char *[]){ - - srandom(time(NULL)); //seed random() - - if ((fp = ::open("/dev/usrp_e0", O_RDWR)) < 0){ - std::cerr << "Open failed" << std::endl; - return -1; - } - - size_t num_pass = 0, num_fail = 0; - for (size_t i = 0; i < num_test_iters; i++){ - if(i%1000000 == 0) { - std::cout << "num pass: " << num_pass; - std::cout << "\tnum fail: " << num_fail << std::endl; - } - //make random values - int random_test32 = ::random(); - int random_test16 = ::random() & 0xffff; - //int random_secs = ::random(); - - //set a bunch of registers - poke16(E100_REG_MISC_TEST, random_test16); - poke32(E100_REG_SR_MISC_TEST32, random_test32); - //poke32(E100_REG_TIME64_TICKS, 0); - //poke32(E100_REG_TIME64_IMM, 1); //immediate - //poke32(E100_REG_TIME64_SECS, random_secs); - - //read a bunch of registers - if ( - (peek16(E100_REG_MISC_TEST) == random_test16) and - (peek32(E100_REG_RB_MISC_TEST32) == random_test32) and -// (peek32(E100_REG_RB_TIME_NOW_SECS) == random_secs) and -// (peek32(E100_REG_RB_TIME_NOW_TICKS) < 1000000) and - true) num_pass++; - else num_fail++; - } - - std::cout << "num pass: " << num_pass << std::endl; - std::cout << "num fail: " << num_fail << std::endl; - - ::close(fp); - return 0; -} |