From 08f6b21ce7cc4aa4069b4461785fc7173bed2998 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 26 Mar 2010 11:45:56 -0700 Subject: added interface address discovery --- host/lib/CMakeLists.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'host/lib/CMakeLists.txt') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 22fbde265..4dd638336 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -28,6 +28,7 @@ SET(libuhd_sources time_spec.cpp types.cpp wax.cpp + transport/if_addrs.cpp transport/udp_simple.cpp transport/vrt.cpp usrp/dboard/basic.cpp @@ -60,7 +61,6 @@ LIST(APPEND libuhd_sources # Setup defines for module loading ######################################################################## INCLUDE(CheckIncludeFileCXX) - CHECK_INCLUDE_FILE_CXX(dlfcn.h HAVE_DLFCN_H) CHECK_INCLUDE_FILE_CXX(Winbase.h HAVE_WINBASE_H) @@ -74,6 +74,19 @@ ELSE(HAVE_DLFCN_H) MESSAGE(STATUS "Module loading not supported...") ENDIF(HAVE_DLFCN_H) +######################################################################## +# Setup defines for interface address discovery +######################################################################## +INCLUDE(CheckIncludeFileCXX) +CHECK_INCLUDE_FILE_CXX(ifaddrs.h HAVE_IFADDRS_H) + +IF(HAVE_IFADDRS_H) + MESSAGE(STATUS "Interface address discovery supported through getifaddrs...") + ADD_DEFINITIONS(-DHAVE_IFADDRS_H) +ELSE(HAVE_IFADDRS_H) + MESSAGE(STATUS "Interface address discovery not supported...") +ENDIF(HAVE_IFADDRS_H) + ######################################################################## # Setup libuhd library ######################################################################## -- cgit v1.2.3 From 72927d983f1f84127e83bf2d80db6b8ee882bad7 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 26 Mar 2010 15:56:04 -0800 Subject: library loading on windows, status message tweaks, warning tweaks --- host/CMakeLists.txt | 2 +- host/include/uhd/config.hpp | 9 ++++++++- host/lib/CMakeLists.txt | 20 ++++++++++++-------- host/lib/load_modules.cpp | 4 ++-- 4 files changed, 23 insertions(+), 12 deletions(-) (limited to 'host/lib/CMakeLists.txt') diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 148ba2d00..05d782abe 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -64,10 +64,10 @@ IF(UNIX) ENDIF(UNIX) IF(WIN32) - ADD_DEFINITIONS(-Dnot=! -Dand=&& -Dor=||) #logical operators ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501) #minimum version required is windows xp ADD_DEFINITIONS(-DNOMINMAX) #disables stupidity and enables std::min and std::max ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS) #avoid warnings from boost::split + ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) #avoid warnings from std::getenv ADD_DEFINITIONS(-DBOOST_ALL_DYN_LINK) #setup boost auto-linking in msvc ENDIF(WIN32) diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp index 10f9c093f..8e30a8333 100644 --- a/host/include/uhd/config.hpp +++ b/host/include/uhd/config.hpp @@ -35,8 +35,15 @@ # pragma warning(disable: 4275) // non dll-interface class ... used as base for dll-interface class ... //# pragma warning(disable: 4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data //# pragma warning(disable: 4511) // 'class' : copy constructor could not be generated -#endif +#endif +//define logical operators +#ifdef BOOST_MSVC + #define not ! + #define and && + #define or || +#endif + // http://gcc.gnu.org/wiki/Visibility // Generic helper definitions for shared library support #if defined _WIN32 || defined __CYGWIN__ diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 4dd638336..a0bfd6d0a 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -60,31 +60,35 @@ LIST(APPEND libuhd_sources ######################################################################## # Setup defines for module loading ######################################################################## +MESSAGE(STATUS "Configuring module loading...") + INCLUDE(CheckIncludeFileCXX) CHECK_INCLUDE_FILE_CXX(dlfcn.h HAVE_DLFCN_H) -CHECK_INCLUDE_FILE_CXX(Winbase.h HAVE_WINBASE_H) +CHECK_INCLUDE_FILE_CXX(Windows.h HAVE_WINDOWS_H) IF(HAVE_DLFCN_H) - MESSAGE(STATUS "Module loading supported through dlopen...") + MESSAGE(STATUS " Module loading supported through dlopen.") ADD_DEFINITIONS(-DHAVE_DLFCN_H) -ELSEIF(HAVE_WINBASE_H) - MESSAGE(STATUS "Module loading supported through LoadLibrary...") - ADD_DEFINITIONS(-DHAVE_WINBASE_H) +ELSEIF(HAVE_WINDOWS_H) + MESSAGE(STATUS " Module loading supported through LoadLibrary.") + ADD_DEFINITIONS(-DHAVE_WINDOWS_H) ELSE(HAVE_DLFCN_H) - MESSAGE(STATUS "Module loading not supported...") + MESSAGE(STATUS " Module loading not supported.") ENDIF(HAVE_DLFCN_H) ######################################################################## # Setup defines for interface address discovery ######################################################################## +MESSAGE(STATUS "Configuring interface address discovery...") + INCLUDE(CheckIncludeFileCXX) CHECK_INCLUDE_FILE_CXX(ifaddrs.h HAVE_IFADDRS_H) IF(HAVE_IFADDRS_H) - MESSAGE(STATUS "Interface address discovery supported through getifaddrs...") + MESSAGE(STATUS " Interface address discovery supported through getifaddrs.") ADD_DEFINITIONS(-DHAVE_IFADDRS_H) ELSE(HAVE_IFADDRS_H) - MESSAGE(STATUS "Interface address discovery not supported...") + MESSAGE(STATUS " Interface address discovery not supported.") ENDIF(HAVE_IFADDRS_H) ######################################################################## diff --git a/host/lib/load_modules.cpp b/host/lib/load_modules.cpp index 700afcd3f..bcdff98a6 100644 --- a/host/lib/load_modules.cpp +++ b/host/lib/load_modules.cpp @@ -40,8 +40,8 @@ static void load_module(const std::string &file_name){ } } -#elif HAVE_WINBASE_H -#include +#elif HAVE_WINDOWS_H +#include static void load_module(const std::string &file_name){ if (LoadLibrary(file_name.c_str()) == NULL){ -- cgit v1.2.3 From ae02148f12615ab4f8e326dac5cf388ab976ec7f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 26 Mar 2010 17:52:57 -0800 Subject: get interface addresses on windows --- host/lib/CMakeLists.txt | 6 +- host/lib/load_modules.cpp | 2 +- host/lib/transport/if_addrs.cpp | 311 +++++-------------------------------- host/lib/usrp/usrp2/usrp2_impl.cpp | 3 + 4 files changed, 48 insertions(+), 274 deletions(-) (limited to 'host/lib/CMakeLists.txt') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index a0bfd6d0a..170d1d3bf 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -64,7 +64,7 @@ MESSAGE(STATUS "Configuring module loading...") INCLUDE(CheckIncludeFileCXX) CHECK_INCLUDE_FILE_CXX(dlfcn.h HAVE_DLFCN_H) -CHECK_INCLUDE_FILE_CXX(Windows.h HAVE_WINDOWS_H) +CHECK_INCLUDE_FILE_CXX(windows.h HAVE_WINDOWS_H) IF(HAVE_DLFCN_H) MESSAGE(STATUS " Module loading supported through dlopen.") @@ -83,10 +83,14 @@ MESSAGE(STATUS "Configuring interface address discovery...") INCLUDE(CheckIncludeFileCXX) CHECK_INCLUDE_FILE_CXX(ifaddrs.h HAVE_IFADDRS_H) +CHECK_INCLUDE_FILE_CXX(winsock2.h HAVE_WINSOCK2_H) IF(HAVE_IFADDRS_H) MESSAGE(STATUS " Interface address discovery supported through getifaddrs.") ADD_DEFINITIONS(-DHAVE_IFADDRS_H) +ELSEIF(HAVE_WINSOCK2_H) + MESSAGE(STATUS " Interface address discovery supported through SIO_GET_INTERFACE_LIST.") + ADD_DEFINITIONS(-DHAVE_WINSOCK2_H) ELSE(HAVE_IFADDRS_H) MESSAGE(STATUS " Interface address discovery not supported.") ENDIF(HAVE_IFADDRS_H) diff --git a/host/lib/load_modules.cpp b/host/lib/load_modules.cpp index bcdff98a6..77426b898 100644 --- a/host/lib/load_modules.cpp +++ b/host/lib/load_modules.cpp @@ -41,7 +41,7 @@ static void load_module(const std::string &file_name){ } #elif HAVE_WINDOWS_H -#include +#include static void load_module(const std::string &file_name){ if (LoadLibrary(file_name.c_str()) == NULL){ diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp index d3ea448fd..eb0e56b3a 100644 --- a/host/lib/transport/if_addrs.cpp +++ b/host/lib/transport/if_addrs.cpp @@ -36,10 +36,7 @@ static boost::asio::ip::address_v4 sockaddr_to_ip_addr(sockaddr *addr){ } static bool ifaddrs_valid(const struct ifaddrs *ifaddrs){ - return ( - ifaddrs->ifa_addr->sa_family == AF_INET and - sockaddr_to_ip_addr(ifaddrs->ifa_addr) != boost::asio::ip::address_v4::loopback() - ); + return ifaddrs->ifa_addr->sa_family == AF_INET; } std::vector uhd::transport::get_if_addrs(void){ @@ -62,7 +59,44 @@ std::vector uhd::transport::get_if_addrs(void){ /*********************************************************************** * Interface address discovery through windows api (TODO) **********************************************************************/ -//#elif HAVE_XXX_H +#elif HAVE_WINSOCK2_H +#include +#include +#include +#include + +std::vector uhd::transport::get_if_addrs(void){ + std::vector if_addrs; + SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0); + if (sd == SOCKET_ERROR) { + std::cerr << "Failed to get a socket. Error " << WSAGetLastError() << + std::endl; return if_addrs; + } + + INTERFACE_INFO InterfaceList[20]; + unsigned long nBytesReturned; + if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList, + sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) { + std::cerr << "Failed calling WSAIoctl: error " << WSAGetLastError() << + std::endl; + return if_addrs; + } + + int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO); + for (int i = 0; i < nNumInterfaces; ++i) { + boost::uint32_t iiAddress = ntohl(reinterpret_cast(InterfaceList[i].iiAddress).sin_addr.s_addr); + boost::uint32_t iiNetmask = ntohl(reinterpret_cast(InterfaceList[i].iiNetmask).sin_addr.s_addr); + boost::uint32_t iiBroadcastAddress = (iiAddress & iiNetmask) | ~iiNetmask; + + if_addrs_t if_addr; + if_addr.inet = boost::asio::ip::address_v4(iiAddress).to_string(); + if_addr.mask = boost::asio::ip::address_v4(iiNetmask).to_string(); + if_addr.bcast = boost::asio::ip::address_v4(iiBroadcastAddress).to_string(); + if_addrs.push_back(if_addr); + } + + return if_addrs; +} /*********************************************************************** * Interface address discovery not included @@ -74,270 +108,3 @@ std::vector uhd::transport::get_if_addrs(void){ } #endif /* HAVE_IFADDRS_H */ - -//////////////////////////////////////////////////////////////////////// -// How to extract the ip address: unix/windows -// http://www.developerweb.net/forum/showthread.php?t=5085 -//////////////////////////////////////////////////////////////////////// - -/* -#include - -#ifdef WIN32 -# include -# include -# include -#else -# include -# include -# include -# include -# include -# include -# include -#endif - -#include -#include - -typedef unsigned long uint32; - -#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__) -# define USE_GETIFADDRS 1 -# include -static uint32 SockAddrToUint32(struct sockaddr * a) -{ - return ((a)&&(a->sa_family == AF_INET)) ? ntohl(((struct sockaddr_in *)a)->sin_addr.s_addr) : 0; -} -#endif - -// convert a numeric IP address into its string representation -static void Inet_NtoA(uint32 addr, char * ipbuf) -{ - sprintf(ipbuf, "%li.%li.%li.%li", (addr>>24)&0xFF, (addr>>16)&0xFF, (addr>>8)&0xFF, (addr>>0)&0xFF); -} - -// convert a string represenation of an IP address into its numeric equivalent -static uint32 Inet_AtoN(const char * buf) -{ - // net_server inexplicably doesn't have this function; so I'll just fake it - uint32 ret = 0; - int shift = 24; // fill out the MSB first - bool startQuad = true; - while((shift >= 0)&&(*buf)) - { - if (startQuad) - { - unsigned char quad = (unsigned char) atoi(buf); - ret |= (((uint32)quad) << shift); - shift -= 8; - } - startQuad = (*buf == '.'); - buf++; - } - return ret; -} - -static void PrintNetworkInterfaceInfos() -{ -#if defined(USE_GETIFADDRS) - // BSD-style implementation - struct ifaddrs * ifap; - if (getifaddrs(&ifap) == 0) - { - struct ifaddrs * p = ifap; - while(p) - { - uint32 ifaAddr = SockAddrToUint32(p->ifa_addr); - uint32 maskAddr = SockAddrToUint32(p->ifa_netmask); - uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr); - if (ifaAddr > 0) - { - char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr); - char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr); - char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr); - printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); - } - p = p->ifa_next; - } - freeifaddrs(ifap); - } -#elif defined(WIN32) - // Windows XP style implementation - - // Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx - // Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable() - // multiple times in order to deal with potential race conditions properly. - MIB_IPADDRTABLE * ipTable = NULL; - { - ULONG bufLen = 0; - for (int i=0; i<5; i++) - { - DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false); - if (ipRet == ERROR_INSUFFICIENT_BUFFER) - { - free(ipTable); // in case we had previously allocated it - ipTable = (MIB_IPADDRTABLE *) malloc(bufLen); - } - else if (ipRet == NO_ERROR) break; - else - { - free(ipTable); - ipTable = NULL; - break; - } - } - } - - if (ipTable) - { - // Try to get the Adapters-info table, so we can given useful names to the IP - // addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle - // the potential race condition between the size-query call and the get-data call. - // I love a well-designed API :^P - IP_ADAPTER_INFO * pAdapterInfo = NULL; - { - ULONG bufLen = 0; - for (int i=0; i<5; i++) - { - DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen); - if (apRet == ERROR_BUFFER_OVERFLOW) - { - free(pAdapterInfo); // in case we had previously allocated it - pAdapterInfo = (IP_ADAPTER_INFO *) malloc(bufLen); - } - else if (apRet == ERROR_SUCCESS) break; - else - { - free(pAdapterInfo); - pAdapterInfo = NULL; - break; - } - } - } - - for (DWORD i=0; idwNumEntries; i++) - { - const MIB_IPADDRROW & row = ipTable->table[i]; - - // Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it - const char * name = NULL; - const char * desc = NULL; - if (pAdapterInfo) - { - IP_ADAPTER_INFO * next = pAdapterInfo; - while((next)&&(name==NULL)) - { - IP_ADDR_STRING * ipAddr = &next->IpAddressList; - while(ipAddr) - { - if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr)) - { - name = next->AdapterName; - desc = next->Description; - break; - } - ipAddr = ipAddr->Next; - } - next = next->Next; - } - } - char buf[128]; - if (name == NULL) - { - sprintf(buf, "unnamed-%i", i); - name = buf; - } - - uint32 ipAddr = ntohl(row.dwAddr); - uint32 netmask = ntohl(row.dwMask); - uint32 baddr = ipAddr & netmask; - if (row.dwBCastAddr) baddr |= ~netmask; - - char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr); - char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr); - char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr); - printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); - } - - free(pAdapterInfo); - free(ipTable); - } -#else - // Dunno what we're running on here! -# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!" -#endif -} - -int main(int, char **) -{ - PrintNetworkInterfaceInfos(); - return 0; -} -*/ - -//////////////////////////////////////////////////////////////////////// -// How to extract the mac address: linux/windows -// http://old.nabble.com/MAC-Address-td19111197.html -//////////////////////////////////////////////////////////////////////// - -/* -Linux: - -#include -#include -#include -#include -#include -#include -#include - -ifaddrs * ifap = 0; -if(getifaddrs(&ifap) == 0) -{ - ifaddrs * iter = ifap; - while(iter) - { - sockaddr_ll * sal = - reinterpret_cast(iter->ifa_addr); - if(sal->sll_family == AF_PACKET) - { - // get the mac bytes - // copy(sal->sll_addr, - // sal->sll_addr+sal->sll_hallen, - // buffer); - } - iter = iter->ifa_next; - } - freeifaddrs(ifap); -} - -Windows: -#include -#include - -std::vector buf; -DWORD bufLen = 0; -GetAdaptersAddresses(0, 0, 0, 0, &bufLen); -if(bufLen) -{ - buf.resize(bufLen, 0); - IP_ADAPTER_ADDRESSES * ptr = - reinterpret_cast(&buf[0]); - DWORD err = GetAdaptersAddresses(0, 0, 0, ptr, &bufLen); - if(err == NO_ERROR) - { - while(ptr) - { - if(ptr->PhysicalAddressLength) - { - // get the mac bytes - // copy(ptr->PhysicalAddress, - // ptr->PhysicalAddress+ptr->PhysicalAddressLength, - // buffer); - } - ptr = ptr->Next; - } - } -} -*/ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index f04ae8d2c..35a4aeb20 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -41,6 +41,9 @@ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ //if no address was specified, send a broadcast on each interface if (not hint.has_key("addr")){ BOOST_FOREACH(const if_addrs_t &if_addrs, get_if_addrs()){ + //avoid the loopback device + if (if_addrs.inet == asio::ip::address_v4::loopback().to_string()) continue; + //create a new hint with this broadcast address device_addr_t new_hint = hint; new_hint["addr"] = if_addrs.bcast; -- cgit v1.2.3 From b71d0cbea9e1e107eeb1da51ef14fe6b9e983ee6 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 27 Mar 2010 14:27:55 -0700 Subject: refactored types.hpp into types directory --- host/include/uhd/CMakeLists.txt | 6 +- host/include/uhd/device.hpp | 4 +- host/include/uhd/device_addr.hpp | 69 -------------- host/include/uhd/dict.hpp | 154 -------------------------------- host/include/uhd/metadata.hpp | 61 ------------- host/include/uhd/simple_device.hpp | 4 +- host/include/uhd/time_spec.hpp | 55 ------------ host/include/uhd/transport/vrt.hpp | 2 +- host/include/uhd/types.hpp | 119 ------------------------ host/include/uhd/types/CMakeLists.txt | 30 +++++++ host/include/uhd/types/clock_config.hpp | 50 +++++++++++ host/include/uhd/types/device_addr.hpp | 45 ++++++++++ host/include/uhd/types/dict.hpp | 154 ++++++++++++++++++++++++++++++++ host/include/uhd/types/mac_addr.hpp | 39 ++++++++ host/include/uhd/types/metadata.hpp | 61 +++++++++++++ host/include/uhd/types/ranges.hpp | 46 ++++++++++ host/include/uhd/types/stream_cmd.hpp | 56 ++++++++++++ host/include/uhd/types/time_spec.hpp | 55 ++++++++++++ host/include/uhd/types/tune_result.hpp | 44 +++++++++ host/lib/CMakeLists.txt | 3 - host/lib/device.cpp | 6 +- host/lib/device_addr.cpp | 86 ------------------ host/lib/gain_handler.cpp | 24 ++--- host/lib/metadata.cpp | 37 -------- host/lib/simple_device.cpp | 5 +- host/lib/time_spec.cpp | 35 -------- host/lib/types.cpp | 113 +++++++++++++++++++++-- host/lib/usrp/dboard/basic.cpp | 26 +++--- host/lib/usrp/dboard_manager.cpp | 2 +- host/lib/usrp/usrp2/dboard_impl.cpp | 1 + host/lib/usrp/usrp2/dsp_impl.cpp | 6 +- host/lib/usrp/usrp2/mboard_impl.cpp | 3 +- host/lib/usrp/usrp2/usrp2_impl.hpp | 10 +-- host/test/addr_test.cpp | 5 +- host/test/gain_handler_test.cpp | 22 ++--- host/utils/discover_usrps.cpp | 2 +- 36 files changed, 752 insertions(+), 688 deletions(-) delete mode 100644 host/include/uhd/device_addr.hpp delete mode 100644 host/include/uhd/dict.hpp delete mode 100644 host/include/uhd/metadata.hpp delete mode 100644 host/include/uhd/time_spec.hpp delete mode 100644 host/include/uhd/types.hpp create mode 100644 host/include/uhd/types/CMakeLists.txt create mode 100644 host/include/uhd/types/clock_config.hpp create mode 100644 host/include/uhd/types/device_addr.hpp create mode 100644 host/include/uhd/types/dict.hpp create mode 100644 host/include/uhd/types/mac_addr.hpp create mode 100644 host/include/uhd/types/metadata.hpp create mode 100644 host/include/uhd/types/ranges.hpp create mode 100644 host/include/uhd/types/stream_cmd.hpp create mode 100644 host/include/uhd/types/time_spec.hpp create mode 100644 host/include/uhd/types/tune_result.hpp delete mode 100644 host/lib/device_addr.cpp delete mode 100644 host/lib/metadata.cpp delete mode 100644 host/lib/time_spec.cpp (limited to 'host/lib/CMakeLists.txt') diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt index 2203ea83e..0cebea095 100644 --- a/host/include/uhd/CMakeLists.txt +++ b/host/include/uhd/CMakeLists.txt @@ -17,20 +17,16 @@ ADD_SUBDIRECTORY(transport) +ADD_SUBDIRECTORY(types) ADD_SUBDIRECTORY(usrp) ADD_SUBDIRECTORY(utils) INSTALL(FILES config.hpp device.hpp - device_addr.hpp - dict.hpp gain_handler.hpp - metadata.hpp props.hpp simple_device.hpp - time_spec.hpp - types.hpp wax.hpp DESTINATION ${INCLUDE_DIR}/uhd ) diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp index 13b40febe..bab8afca6 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -19,9 +19,9 @@ #define INCLUDED_UHD_DEVICE_HPP #include -#include +#include +#include #include -#include #include #include #include diff --git a/host/include/uhd/device_addr.hpp b/host/include/uhd/device_addr.hpp deleted file mode 100644 index 7673faff0..000000000 --- a/host/include/uhd/device_addr.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// 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 . -// - -#ifndef INCLUDED_UHD_DEVICE_ADDR_HPP -#define INCLUDED_UHD_DEVICE_ADDR_HPP - -#include -#include -#include -#include -#include -#include - -namespace uhd{ - - /*! - * Wrapper for an ethernet mac address. - * Provides conversion between string and binary formats. - */ - struct UHD_API mac_addr_t{ - boost::uint8_t mac_addr[6]; - mac_addr_t(const std::string &mac_addr_str = "00:00:00:00:00:00"); - std::string to_string(void) const; - }; - - /*! - * The device address args are just a mapping of key/value string pairs. - * When left empty, the discovery routine will try to find all usrps. - * The discovery can be narrowed down by specifying the transport type arguments. - * - * For example, to access a specific usrp2 one would specify the transport type - * ("type", "udp") and the transport args ("addr", ""). - */ - typedef dict device_addr_t; - typedef std::vector device_addrs_t; - - /*! - * Function to turn a device address into a string. - * Just having the operator<< below should be sufficient. - * However, boost format seems to complain with the % - * and this is just easier because it works. - * \param device_addr a device address instance - * \return the string representation - */ - namespace device_addr{ - UHD_API std::string to_string(const device_addr_t &device_addr); - } - -} //namespace uhd - -//ability to use types with stream operators -UHD_API std::ostream& operator<<(std::ostream &, const uhd::device_addr_t &); -UHD_API std::ostream& operator<<(std::ostream &, const uhd::mac_addr_t &); - -#endif /* INCLUDED_UHD_DEVICE_ADDR_HPP */ diff --git a/host/include/uhd/dict.hpp b/host/include/uhd/dict.hpp deleted file mode 100644 index f08493952..000000000 --- a/host/include/uhd/dict.hpp +++ /dev/null @@ -1,154 +0,0 @@ -// -// 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 . -// - -#ifndef INCLUDED_UHD_DICT_HPP -#define INCLUDED_UHD_DICT_HPP - -#include -#include -#include -#include - -namespace uhd{ - - /*! - * A templated dictionary class with a python-like interface. - */ - template class dict{ - public: - typedef std::pair pair_t; - - /*! - * Create a new empty dictionary. - */ - dict(void){ - /* NOP */ - } - - /*! - * Input iterator constructor: - * Makes boost::assign::map_list_of work. - * \param first the begin iterator - * \param last the end iterator - */ - template - dict(InputIterator first, InputIterator last){ - for(InputIterator it = first; it != last; it++){ - _map.push_back(*it); - } - } - - /*! - * Destroy this dict. - */ - ~dict(void){ - /* NOP */ - } - - /*! - * Get the number of elements in this dict. - * \param the number of elements - */ - std::size_t size(void) const{ - return _map.size(); - } - - /*! - * Get a list of the keys in this dict. - * Key order depends on insertion precedence. - * \return vector of keys - */ - std::vector get_keys(void) const{ - std::vector keys; - BOOST_FOREACH(const pair_t &p, _map){ - keys.push_back(p.first); - } - return keys; - } - - /*! - * Get a list of the values in this dict. - * Value order depends on insertion precedence. - * \return vector of values - */ - std::vector get_vals(void) const{ - std::vector vals; - BOOST_FOREACH(const pair_t &p, _map){ - vals.push_back(p.second); - } - return vals; - } - - /*! - * Does the dictionary contain this key? - * \param key the key to look for - * \return true if found - */ - bool has_key(const Key &key) const{ - BOOST_FOREACH(const pair_t &p, _map){ - if (p.first == key) return true; - } - return false; - } - - /*! - * Get a value for the given key if it exists. - * If the key is not found throw an error. - * \param key the key to look for - * \return the value at the key - * \throw an exception when not found - */ - const Val &operator[](const Key &key) const{ - BOOST_FOREACH(const pair_t &p, _map){ - if (p.first == key) return p.second; - } - throw std::invalid_argument("key not found in dict"); - } - - /*! - * Set a value for the given key, however, in reality - * it really returns a reference which can be assigned to. - * \param key the key to set to - * \return a reference to the value - */ - Val &operator[](const Key &key){ - BOOST_FOREACH(pair_t &p, _map){ - if (p.first == key) return p.second; - } - _map.push_back(pair_t(key, Val())); - return _map.back().second; - } - - /*! - * Pop an item out of the dictionary. - * \param key the item key - * \return the value of the item - * \throw an exception when not found - */ - Val pop(const Key &key){ - Val val = (*this)[key]; - _map.remove(pair_t(key, val)); - return val; - } - - private: - std::list _map; //private container - }; - -} //namespace uhd - -#endif /* INCLUDED_UHD_DICT_HPP */ diff --git a/host/include/uhd/metadata.hpp b/host/include/uhd/metadata.hpp deleted file mode 100644 index 6d80f070d..000000000 --- a/host/include/uhd/metadata.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// -// 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 . -// - -#ifndef INCLUDED_UHD_METADATA_HPP -#define INCLUDED_UHD_METADATA_HPP - -#include -#include - -namespace uhd{ - -/*! - * RX metadata structure for describing sent IF data. - * Includes stream ID, time specification, and fragmentation flags. - * The receive routines will convert IF data headers into metadata. - */ -struct UHD_API rx_metadata_t{ - boost::uint32_t stream_id; - time_spec_t time_spec; - bool has_stream_id; - bool has_time_spec; - bool is_fragment; - - //default constructor - rx_metadata_t(void); -}; - -/*! - * TX metadata structure for describing received IF data. - * Includes stream ID, time specification, and burst flags. - * The send routines will convert the metadata to IF data headers. - */ -struct UHD_API tx_metadata_t{ - boost::uint32_t stream_id; - time_spec_t time_spec; - bool has_stream_id; - bool has_time_spec; - bool start_of_burst; - bool end_of_burst; - - //default constructor - tx_metadata_t(void); -}; - -} //namespace uhd - -#endif /* INCLUDED_UHD_METADATA_HPP */ diff --git a/host/include/uhd/simple_device.hpp b/host/include/uhd/simple_device.hpp index bbe0258c7..52928367a 100644 --- a/host/include/uhd/simple_device.hpp +++ b/host/include/uhd/simple_device.hpp @@ -20,7 +20,9 @@ #include #include -#include +#include +#include +#include #include #include #include diff --git a/host/include/uhd/time_spec.hpp b/host/include/uhd/time_spec.hpp deleted file mode 100644 index e863746ba..000000000 --- a/host/include/uhd/time_spec.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// 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 . -// - -#ifndef INCLUDED_UHD_TIME_SPEC_HPP -#define INCLUDED_UHD_TIME_SPEC_HPP - -#include -#include -#include - -namespace uhd{ - - /*! - * A time_spec_t holds a seconds and ticks time value. - * The temporal width of a tick depends on the device's clock rate. - * The time_spec_t can be used when setting the time on devices - * and for controlling the start of streaming for applicable dsps. - */ - struct UHD_API time_spec_t{ - boost::uint32_t secs; - boost::uint32_t ticks; - - /*! - * Create a time_spec_t from seconds and ticks. - * \param new_secs the new seconds (default = 0) - * \param new_ticks the new ticks (default = 0) - */ - time_spec_t(boost::uint32_t new_secs = 0, boost::uint32_t new_ticks = 0); - - /*! - * Create a time_spec_t from boost posix time. - * \param time fine-grained boost posix time - * \param tick_rate the rate of ticks per second - */ - time_spec_t(boost::posix_time::ptime time, double tick_rate); - - }; - -} //namespace uhd - -#endif /* INCLUDED_UHD_TIME_SPEC_HPP */ diff --git a/host/include/uhd/transport/vrt.hpp b/host/include/uhd/transport/vrt.hpp index db2c57eba..04945b347 100644 --- a/host/include/uhd/transport/vrt.hpp +++ b/host/include/uhd/transport/vrt.hpp @@ -19,7 +19,7 @@ #define INCLUDED_UHD_TRANSPORT_VRT_HPP #include -#include +#include #include namespace uhd{ namespace transport{ diff --git a/host/include/uhd/types.hpp b/host/include/uhd/types.hpp deleted file mode 100644 index 3ad3dae82..000000000 --- a/host/include/uhd/types.hpp +++ /dev/null @@ -1,119 +0,0 @@ -// -// 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 . -// - -#ifndef INCLUDED_UHD_TYPES_HPP -#define INCLUDED_UHD_TYPES_HPP - -#include -#include -#include - -namespace uhd{ - - typedef float gain_t; //TODO REMOVE - typedef double freq_t; //TODO REMOVE - - /*! - * The gain range struct describes possible gain settings. - * The mimumum gain, maximum gain, and step size are in dB. - */ - struct UHD_API gain_range_t{ - float min, max, step; - gain_range_t(float min = 0.0, float max = 0.0, float step = 0.0); - }; - - /*! - * The frequency range struct describes possible frequency settings. - * Because tuning is very granular (sub-Hz), step size is not listed. - * The mimumum frequency and maximum frequency are in Hz. - */ - struct UHD_API freq_range_t{ - double min, max; - freq_range_t(double min = 0.0, double max = 0.0); - }; - - /*! - * The tune result struct holds result of a 2-phase tuning: - * The struct hold the result of tuning the dboard as - * the target and actual intermediate frequency. - * The struct hold the result of tuning the DDC/DUC as - * the target and actual digital converter frequency. - * It also tell us weather or not the spectrum is inverted. - */ - struct UHD_API tune_result_t{ - double target_inter_freq; - double actual_inter_freq; - double target_dxc_freq; - double actual_dxc_freq; - bool spectrum_inverted; - tune_result_t(void); - }; - - /*! - * Clock configuration settings: - * The source for the 10MHz reference clock. - * The source and polarity for the PPS clock. - */ - struct UHD_API clock_config_t{ - enum ref_source_t { - REF_INT, //internal reference - REF_SMA, //external sma port - REF_MIMO //mimo cable (usrp2 only) - } ref_source; - enum pps_source_t { - PPS_INT, //there is no internal - PPS_SMA, //external sma port - PPS_MIMO //mimo cable (usrp2 only) - } pps_source; - enum pps_polarity_t { - PPS_NEG, //negative edge - PPS_POS //positive edge - } pps_polarity; - clock_config_t(void); - }; - - /*! - * Command struct for configuration and control of streaming: - * - * A stream command defines how the device sends samples to the host. - * Streaming is controlled by submitting a stream command to the rx dsp. - * Granular control over what the device streams to the host can be - * achieved through submission of multiple (carefully-crafted) commands. - * - * The stream_now parameter controls when the stream begins. - * When true, the device will begin streaming ASAP. When false, - * the device will begin streaming at a time specified by time_spec. - * - * The continuous parameter controls the number of samples received. - * When true, the device continues streaming indefinitely. When false, - * the device will stream the number of samples specified by num_samps. - * - * Standard usage case: - * To start continuous streaming, set stream_now to true and continuous to true. - * To end continuous streaming, set stream_now to true and continuous to false. - */ - struct UHD_API stream_cmd_t{ - bool stream_now; - time_spec_t time_spec; - bool continuous; - size_t num_samps; - stream_cmd_t(void); - }; - -} //namespace uhd - -#endif /* INCLUDED_UHD_TYPES_HPP */ diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt new file mode 100644 index 000000000..10262dd65 --- /dev/null +++ b/host/include/uhd/types/CMakeLists.txt @@ -0,0 +1,30 @@ +# +# 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 . +# + + +INSTALL(FILES + clock_config.hpp + device_addr.hpp + dict.hpp + mac_addr.hpp + metadata.hpp + ranges.hpp + stream_cmd.hpp + time_spec.hpp + tune_result.hpp + DESTINATION ${INCLUDE_DIR}/uhd/types +) diff --git a/host/include/uhd/types/clock_config.hpp b/host/include/uhd/types/clock_config.hpp new file mode 100644 index 000000000..8b2fea016 --- /dev/null +++ b/host/include/uhd/types/clock_config.hpp @@ -0,0 +1,50 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_CLOCK_CONFIG_HPP +#define INCLUDED_UHD_TYPES_CLOCK_CONFIG_HPP + +#include + +namespace uhd{ + + /*! + * Clock configuration settings: + * The source for the 10MHz reference clock. + * The source and polarity for the PPS clock. + */ + struct UHD_API clock_config_t{ + enum ref_source_t { + REF_INT, //internal reference + REF_SMA, //external sma port + REF_MIMO //mimo cable (usrp2 only) + } ref_source; + enum pps_source_t { + PPS_INT, //there is no internal + PPS_SMA, //external sma port + PPS_MIMO //mimo cable (usrp2 only) + } pps_source; + enum pps_polarity_t { + PPS_NEG, //negative edge + PPS_POS //positive edge + } pps_polarity; + clock_config_t(void); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_CLOCK_CONFIG_HPP */ diff --git a/host/include/uhd/types/device_addr.hpp b/host/include/uhd/types/device_addr.hpp new file mode 100644 index 000000000..d32dfa77e --- /dev/null +++ b/host/include/uhd/types/device_addr.hpp @@ -0,0 +1,45 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP +#define INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP + +#include +#include +#include +#include + +namespace uhd{ + + /*! + * The device address args are just a mapping of key/value string pairs. + * When left empty, the discovery routine will try to find all usrps. + * The discovery can be narrowed down by specifying the transport type arguments. + * + * For example, to access a specific usrp2 one would specify the transport type + * ("type", "udp") and the transport args ("addr", ""). + */ + class UHD_API device_addr_t : public dict{ + public: std::string to_string(void) const; + }; + + //handy typedef for a vector of device addresses + typedef std::vector device_addrs_t; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP */ diff --git a/host/include/uhd/types/dict.hpp b/host/include/uhd/types/dict.hpp new file mode 100644 index 000000000..5b9883704 --- /dev/null +++ b/host/include/uhd/types/dict.hpp @@ -0,0 +1,154 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_DICT_HPP +#define INCLUDED_UHD_TYPES_DICT_HPP + +#include +#include +#include +#include + +namespace uhd{ + + /*! + * A templated dictionary class with a python-like interface. + */ + template class dict{ + public: + typedef std::pair pair_t; + + /*! + * Create a new empty dictionary. + */ + dict(void){ + /* NOP */ + } + + /*! + * Input iterator constructor: + * Makes boost::assign::map_list_of work. + * \param first the begin iterator + * \param last the end iterator + */ + template + dict(InputIterator first, InputIterator last){ + for(InputIterator it = first; it != last; it++){ + _map.push_back(*it); + } + } + + /*! + * Destroy this dict. + */ + ~dict(void){ + /* NOP */ + } + + /*! + * Get the number of elements in this dict. + * \param the number of elements + */ + std::size_t size(void) const{ + return _map.size(); + } + + /*! + * Get a list of the keys in this dict. + * Key order depends on insertion precedence. + * \return vector of keys + */ + std::vector get_keys(void) const{ + std::vector keys; + BOOST_FOREACH(const pair_t &p, _map){ + keys.push_back(p.first); + } + return keys; + } + + /*! + * Get a list of the values in this dict. + * Value order depends on insertion precedence. + * \return vector of values + */ + std::vector get_vals(void) const{ + std::vector vals; + BOOST_FOREACH(const pair_t &p, _map){ + vals.push_back(p.second); + } + return vals; + } + + /*! + * Does the dictionary contain this key? + * \param key the key to look for + * \return true if found + */ + bool has_key(const Key &key) const{ + BOOST_FOREACH(const pair_t &p, _map){ + if (p.first == key) return true; + } + return false; + } + + /*! + * Get a value for the given key if it exists. + * If the key is not found throw an error. + * \param key the key to look for + * \return the value at the key + * \throw an exception when not found + */ + const Val &operator[](const Key &key) const{ + BOOST_FOREACH(const pair_t &p, _map){ + if (p.first == key) return p.second; + } + throw std::invalid_argument("key not found in dict"); + } + + /*! + * Set a value for the given key, however, in reality + * it really returns a reference which can be assigned to. + * \param key the key to set to + * \return a reference to the value + */ + Val &operator[](const Key &key){ + BOOST_FOREACH(pair_t &p, _map){ + if (p.first == key) return p.second; + } + _map.push_back(pair_t(key, Val())); + return _map.back().second; + } + + /*! + * Pop an item out of the dictionary. + * \param key the item key + * \return the value of the item + * \throw an exception when not found + */ + Val pop(const Key &key){ + Val val = (*this)[key]; + _map.remove(pair_t(key, val)); + return val; + } + + private: + std::list _map; //private container + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_DICT_HPP */ diff --git a/host/include/uhd/types/mac_addr.hpp b/host/include/uhd/types/mac_addr.hpp new file mode 100644 index 000000000..2cac7d343 --- /dev/null +++ b/host/include/uhd/types/mac_addr.hpp @@ -0,0 +1,39 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_MAC_ADDR_HPP +#define INCLUDED_UHD_TYPES_MAC_ADDR_HPP + +#include +#include +#include + +namespace uhd{ + + /*! + * Wrapper for an ethernet mac address. + * Provides conversion between string and binary formats. + */ + struct UHD_API mac_addr_t{ + boost::uint8_t mac_addr[6]; + mac_addr_t(const std::string &mac_addr_str = "00:00:00:00:00:00"); + std::string to_string(void) const; + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_MAC_ADDR_HPP */ diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp new file mode 100644 index 000000000..6e93040d9 --- /dev/null +++ b/host/include/uhd/types/metadata.hpp @@ -0,0 +1,61 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_METADATA_HPP +#define INCLUDED_UHD_TYPES_METADATA_HPP + +#include +#include + +namespace uhd{ + + /*! + * RX metadata structure for describing sent IF data. + * Includes stream ID, time specification, and fragmentation flags. + * The receive routines will convert IF data headers into metadata. + */ + struct UHD_API rx_metadata_t{ + boost::uint32_t stream_id; + time_spec_t time_spec; + bool has_stream_id; + bool has_time_spec; + bool is_fragment; + + //default constructor + rx_metadata_t(void); + }; + + /*! + * TX metadata structure for describing received IF data. + * Includes stream ID, time specification, and burst flags. + * The send routines will convert the metadata to IF data headers. + */ + struct UHD_API tx_metadata_t{ + boost::uint32_t stream_id; + time_spec_t time_spec; + bool has_stream_id; + bool has_time_spec; + bool start_of_burst; + bool end_of_burst; + + //default constructor + tx_metadata_t(void); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_METADATA_HPP */ diff --git a/host/include/uhd/types/ranges.hpp b/host/include/uhd/types/ranges.hpp new file mode 100644 index 000000000..a2057d1c8 --- /dev/null +++ b/host/include/uhd/types/ranges.hpp @@ -0,0 +1,46 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_RANGES_HPP +#define INCLUDED_UHD_TYPES_RANGES_HPP + +#include + +namespace uhd{ + + /*! + * The gain range struct describes possible gain settings. + * The mimumum gain, maximum gain, and step size are in dB. + */ + struct UHD_API gain_range_t{ + float min, max, step; + gain_range_t(float min = 0.0, float max = 0.0, float step = 0.0); + }; + + /*! + * The frequency range struct describes possible frequency settings. + * Because tuning is very granular (sub-Hz), step size is not listed. + * The mimumum frequency and maximum frequency are in Hz. + */ + struct UHD_API freq_range_t{ + double min, max; + freq_range_t(double min = 0.0, double max = 0.0); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_RANGES_HPP */ diff --git a/host/include/uhd/types/stream_cmd.hpp b/host/include/uhd/types/stream_cmd.hpp new file mode 100644 index 000000000..97a6b73ce --- /dev/null +++ b/host/include/uhd/types/stream_cmd.hpp @@ -0,0 +1,56 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_STREAM_CMD_HPP +#define INCLUDED_UHD_TYPES_STREAM_CMD_HPP + +#include +#include + +namespace uhd{ + + /*! + * Command struct for configuration and control of streaming: + * + * A stream command defines how the device sends samples to the host. + * Streaming is controlled by submitting a stream command to the rx dsp. + * Granular control over what the device streams to the host can be + * achieved through submission of multiple (carefully-crafted) commands. + * + * The stream_now parameter controls when the stream begins. + * When true, the device will begin streaming ASAP. When false, + * the device will begin streaming at a time specified by time_spec. + * + * The continuous parameter controls the number of samples received. + * When true, the device continues streaming indefinitely. When false, + * the device will stream the number of samples specified by num_samps. + * + * Standard usage case: + * To start continuous streaming, set stream_now to true and continuous to true. + * To end continuous streaming, set stream_now to true and continuous to false. + */ + struct UHD_API stream_cmd_t{ + bool stream_now; + time_spec_t time_spec; + bool continuous; + size_t num_samps; + stream_cmd_t(void); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_STREAM_CMD_HPP */ diff --git a/host/include/uhd/types/time_spec.hpp b/host/include/uhd/types/time_spec.hpp new file mode 100644 index 000000000..8c8f2bc25 --- /dev/null +++ b/host/include/uhd/types/time_spec.hpp @@ -0,0 +1,55 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_TIME_SPEC_HPP +#define INCLUDED_UHD_TYPES_TIME_SPEC_HPP + +#include +#include +#include + +namespace uhd{ + + /*! + * A time_spec_t holds a seconds and ticks time value. + * The temporal width of a tick depends on the device's clock rate. + * The time_spec_t can be used when setting the time on devices + * and for controlling the start of streaming for applicable dsps. + */ + struct UHD_API time_spec_t{ + boost::uint32_t secs; + boost::uint32_t ticks; + + /*! + * Create a time_spec_t from seconds and ticks. + * \param new_secs the new seconds (default = 0) + * \param new_ticks the new ticks (default = 0) + */ + time_spec_t(boost::uint32_t new_secs = 0, boost::uint32_t new_ticks = 0); + + /*! + * Create a time_spec_t from boost posix time. + * \param time fine-grained boost posix time + * \param tick_rate the rate of ticks per second + */ + time_spec_t(boost::posix_time::ptime time, double tick_rate); + + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_TIME_SPEC_HPP */ diff --git a/host/include/uhd/types/tune_result.hpp b/host/include/uhd/types/tune_result.hpp new file mode 100644 index 000000000..31742e1af --- /dev/null +++ b/host/include/uhd/types/tune_result.hpp @@ -0,0 +1,44 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_TUNE_RESULT_HPP +#define INCLUDED_UHD_TYPES_TUNE_RESULT_HPP + +#include + +namespace uhd{ + + /*! + * The tune result struct holds result of a 2-phase tuning: + * The struct hold the result of tuning the dboard as + * the target and actual intermediate frequency. + * The struct hold the result of tuning the DDC/DUC as + * the target and actual digital converter frequency. + * It also tell us weather or not the spectrum is inverted. + */ + struct UHD_API tune_result_t{ + double target_inter_freq; + double actual_inter_freq; + double target_dxc_freq; + double actual_dxc_freq; + bool spectrum_inverted; + tune_result_t(void); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_TUNE_RESULT_HPP */ diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 170d1d3bf..1eceb53ea 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -20,12 +20,9 @@ ######################################################################## SET(libuhd_sources device.cpp - device_addr.cpp gain_handler.cpp load_modules.cpp - metadata.cpp simple_device.cpp - time_spec.cpp types.cpp wax.cpp transport/if_addrs.cpp diff --git a/host/lib/device.cpp b/host/lib/device.cpp index 0bdbf5f23..833e7a0da 100644 --- a/host/lib/device.cpp +++ b/host/lib/device.cpp @@ -16,7 +16,7 @@ // #include -#include +#include #include #include #include @@ -110,14 +110,14 @@ device::sptr device::make(const device_addr_t &hint, size_t which){ //check that we found any devices if (dev_addr_makers.size() == 0){ throw std::runtime_error(str( - boost::format("No devices found for ----->\n%s") % device_addr::to_string(hint) + boost::format("No devices found for ----->\n%s") % hint.to_string() )); } //check that the which index is valid if (dev_addr_makers.size() <= which){ throw std::runtime_error(str( - boost::format("No device at index %d for ----->\n%s") % which % device_addr::to_string(hint) + boost::format("No device at index %d for ----->\n%s") % which % hint.to_string() )); } diff --git a/host/lib/device_addr.cpp b/host/lib/device_addr.cpp deleted file mode 100644 index d26bb4b9d..000000000 --- a/host/lib/device_addr.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// -// 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 . -// - -#include -#include -#include -#include -#include -#include -#include - -//----------------------- u2 mac addr wrapper ------------------------// -uhd::mac_addr_t::mac_addr_t(const std::string &mac_addr_str_){ - std::string mac_addr_str = (mac_addr_str_ == "")? "ff:ff:ff:ff:ff:ff" : mac_addr_str_; - - //ether_aton_r(str.c_str(), &mac_addr); - boost::uint8_t p[6] = {0x00, 0x50, 0xC2, 0x85, 0x30, 0x00}; // Matt's IAB - - try{ - //only allow patterns of xx:xx or xx:xx:xx:xx:xx:xx - //the IAB above will fill in for the shorter pattern - if (mac_addr_str.size() != 5 and mac_addr_str.size() != 17) - throw std::runtime_error("expected exactly 5 or 17 characters"); - - //split the mac addr hex string at the colons - std::vector hex_strs; - boost::split(hex_strs, mac_addr_str, boost::is_any_of(":")); - for (size_t i = 0; i < hex_strs.size(); i++){ - int hex_num; - std::istringstream iss(hex_strs[i]); - iss >> std::hex >> hex_num; - p[i] = boost::uint8_t(hex_num); - } - - } - catch(std::exception const& e){ - throw std::runtime_error(str( - boost::format("Invalid mac address: %s\n\t%s") % mac_addr_str % e.what() - )); - } - - memcpy(&mac_addr, p, sizeof(mac_addr)); -} - -std::string uhd::mac_addr_t::to_string(void) const{ - //ether_ntoa_r(&mac_addr, addr_buf); - const boost::uint8_t *p = reinterpret_cast(&mac_addr); - return str( - boost::format("%02x:%02x:%02x:%02x:%02x:%02x") - % int(p[0]) % int(p[1]) % int(p[2]) - % int(p[3]) % int(p[4]) % int(p[5]) - ); -} - -std::ostream& operator<<(std::ostream &os, const uhd::mac_addr_t &x){ - os << x.to_string(); - return os; -} - -//----------------------- usrp device_addr_t wrapper -------------------------// -std::string uhd::device_addr::to_string(const uhd::device_addr_t &device_addr){ - std::stringstream ss; - BOOST_FOREACH(std::string key, device_addr.get_keys()){ - ss << boost::format("%s: %s") % key % device_addr[key] << std::endl; - } - return ss.str(); -} - -std::ostream& operator<<(std::ostream &os, const uhd::device_addr_t &device_addr){ - os << uhd::device_addr::to_string(device_addr); - return os; -} diff --git a/host/lib/gain_handler.cpp b/host/lib/gain_handler.cpp index 7b3dd266c..a6ae06c50 100644 --- a/host/lib/gain_handler.cpp +++ b/host/lib/gain_handler.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include @@ -47,7 +47,7 @@ private: is_equal_t _is_equal; prop_names_t get_gain_names(void); - gain_t get_overall_gain_val(void); + float get_overall_gain_val(void); gain_range_t get_overall_gain_range(void); template T get_named_prop(const wax::obj &prop, const std::string &name){ return _link[named_prop_t(prop, name)].as(); @@ -90,21 +90,21 @@ prop_names_t gain_handler_impl::get_gain_names(void){ return _link[_props.names].as(); } -gain_t gain_handler_impl::get_overall_gain_val(void){ - gain_t gain_val = 0; +float gain_handler_impl::get_overall_gain_val(void){ + float gain_val = 0; BOOST_FOREACH(std::string name, get_gain_names()){ - gain_val += get_named_prop(_props.value, name); + gain_val += get_named_prop(_props.value, name); } return gain_val; } gain_range_t gain_handler_impl::get_overall_gain_range(void){ - gain_t gain_min = 0, gain_max = 0, gain_step = 0; + float gain_min = 0, gain_max = 0, gain_step = 0; BOOST_FOREACH(std::string name, get_gain_names()){ - gain_range_t gain_tmp = get_named_prop(_props.range, name); - gain_min += gain_tmp.min; - gain_max += gain_tmp.max; - gain_step = std::max(gain_step, gain_tmp.step); + gain_range_t floatmp = get_named_prop(_props.range, name); + gain_min += floatmp.min; + gain_max += floatmp.max; + gain_step = std::max(gain_step, floatmp.step); } return gain_range_t(gain_min, gain_max, gain_step); } @@ -145,7 +145,7 @@ bool gain_handler_impl::intercept_set(const wax::obj &key_, const wax::obj &val) //not a gain value key... dont handle if (not _is_equal(key, _props.value)) return false; - gain_t gain_val = val.as(); + float gain_val = val.as(); //not a wildcard... dont handle (but check name and range) if (name != ""){ @@ -164,7 +164,7 @@ bool gain_handler_impl::intercept_set(const wax::obj &key_, const wax::obj &val) gain_range_t gain = get_named_prop(_props.range, name); //clip g to be within the allowed range - gain_t g = std::min(std::max(gain_val, gain.min), gain.max); + float g = std::min(std::max(gain_val, gain.min), gain.max); //set g to be a multiple of the step size g -= std::fmod(g, gain.step); //set g to be the new gain diff --git a/host/lib/metadata.cpp b/host/lib/metadata.cpp deleted file mode 100644 index 40fdb7c73..000000000 --- a/host/lib/metadata.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// 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 . -// - -#include - -using namespace uhd; - -rx_metadata_t::rx_metadata_t(void){ - stream_id = 0; - has_stream_id = false; - time_spec = time_spec_t(); - has_time_spec = false; - is_fragment = false; -} - -tx_metadata_t::tx_metadata_t(void){ - stream_id = 0; - has_stream_id = false; - time_spec = time_spec_t(); - has_time_spec = false; - start_of_burst = false; - end_of_burst = false; -} diff --git a/host/lib/simple_device.cpp b/host/lib/simple_device.cpp index 0eb69d9fa..95bc8fecc 100644 --- a/host/lib/simple_device.cpp +++ b/host/lib/simple_device.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -208,7 +207,7 @@ public: } float get_rx_gain(void){ - return _rx_subdev[SUBDEV_PROP_GAIN].as(); + return _rx_subdev[SUBDEV_PROP_GAIN].as(); } gain_range_t get_rx_gain_range(void){ @@ -264,7 +263,7 @@ public: } float get_tx_gain(void){ - return _tx_subdev[SUBDEV_PROP_GAIN].as(); + return _tx_subdev[SUBDEV_PROP_GAIN].as(); } gain_range_t get_tx_gain_range(void){ diff --git a/host/lib/time_spec.cpp b/host/lib/time_spec.cpp deleted file mode 100644 index 98bf28077..000000000 --- a/host/lib/time_spec.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// 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 . -// - -#include - -using namespace uhd; - -time_spec_t::time_spec_t(boost::uint32_t new_secs, boost::uint32_t new_ticks){ - secs = new_secs; - ticks = new_ticks; -} - -static const boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1)); -static double time_tick_rate = double(boost::posix_time::time_duration::ticks_per_second()); - -time_spec_t::time_spec_t(boost::posix_time::ptime time, double tick_rate){ - boost::posix_time::time_duration td = time - epoch; - secs = boost::uint32_t(td.total_seconds()); - double time_ticks_per_device_ticks = time_tick_rate/tick_rate; - ticks = boost::uint32_t(td.fractional_seconds()/time_ticks_per_device_ticks); -} diff --git a/host/lib/types.cpp b/host/lib/types.cpp index 273f87a2d..bd5dc8e26 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -15,12 +15,23 @@ // along with this program. If not, see . // -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace uhd; /*********************************************************************** - * gain range + * ranges **********************************************************************/ gain_range_t::gain_range_t(float min_, float max_, float step_){ min = min_; @@ -28,9 +39,6 @@ gain_range_t::gain_range_t(float min_, float max_, float step_){ step = step_; } -/*********************************************************************** - * freq range - **********************************************************************/ freq_range_t::freq_range_t(double min_, double max_){ min = min_; max = max_; @@ -64,3 +72,98 @@ stream_cmd_t::stream_cmd_t(void){ continuous = false; num_samps = 0; } + +/*********************************************************************** + * metadata + **********************************************************************/ +rx_metadata_t::rx_metadata_t(void){ + stream_id = 0; + has_stream_id = false; + time_spec = time_spec_t(); + has_time_spec = false; + is_fragment = false; +} + +tx_metadata_t::tx_metadata_t(void){ + stream_id = 0; + has_stream_id = false; + time_spec = time_spec_t(); + has_time_spec = false; + start_of_burst = false; + end_of_burst = false; +} + +/*********************************************************************** + * time spec + **********************************************************************/ +time_spec_t::time_spec_t(boost::uint32_t new_secs, boost::uint32_t new_ticks){ + secs = new_secs; + ticks = new_ticks; +} + +static const boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1)); +static double time_tick_rate = double(boost::posix_time::time_duration::ticks_per_second()); + +time_spec_t::time_spec_t(boost::posix_time::ptime time, double tick_rate){ + boost::posix_time::time_duration td = time - epoch; + secs = boost::uint32_t(td.total_seconds()); + double time_ticks_per_device_ticks = time_tick_rate/tick_rate; + ticks = boost::uint32_t(td.fractional_seconds()/time_ticks_per_device_ticks); +} + +/*********************************************************************** + * device addr + **********************************************************************/ +std::string device_addr_t::to_string(void) const{ + const device_addr_t &device_addr = *this; + std::stringstream ss; + BOOST_FOREACH(std::string key, device_addr.get_keys()){ + ss << boost::format("%s: %s") % key % device_addr[key] << std::endl; + } + return ss.str(); +} + +/*********************************************************************** + * mac addr + **********************************************************************/ +uhd::mac_addr_t::mac_addr_t(const std::string &mac_addr_str_){ + std::string mac_addr_str = (mac_addr_str_ == "")? "ff:ff:ff:ff:ff:ff" : mac_addr_str_; + + //ether_aton_r(str.c_str(), &mac_addr); + boost::uint8_t p[6] = {0x00, 0x50, 0xC2, 0x85, 0x30, 0x00}; // Matt's IAB + + try{ + //only allow patterns of xx:xx or xx:xx:xx:xx:xx:xx + //the IAB above will fill in for the shorter pattern + if (mac_addr_str.size() != 5 and mac_addr_str.size() != 17) + throw std::runtime_error("expected exactly 5 or 17 characters"); + + //split the mac addr hex string at the colons + std::vector hex_strs; + boost::split(hex_strs, mac_addr_str, boost::is_any_of(":")); + for (size_t i = 0; i < hex_strs.size(); i++){ + int hex_num; + std::istringstream iss(hex_strs[i]); + iss >> std::hex >> hex_num; + p[i] = boost::uint8_t(hex_num); + } + + } + catch(std::exception const& e){ + throw std::runtime_error(str( + boost::format("Invalid mac address: %s\n\t%s") % mac_addr_str % e.what() + )); + } + + memcpy(&mac_addr, p, sizeof(mac_addr)); +} + +std::string uhd::mac_addr_t::to_string(void) const{ + //ether_ntoa_r(&mac_addr, addr_buf); + const boost::uint8_t *p = reinterpret_cast(&mac_addr); + return str( + boost::format("%02x:%02x:%02x:%02x:%02x:%02x") + % int(p[0]) % int(p[1]) % int(p[2]) + % int(p[3]) % int(p[4]) % int(p[5]) + ); +} diff --git a/host/lib/usrp/dboard/basic.cpp b/host/lib/usrp/dboard/basic.cpp index 07cb8d11c..2f29c8e0c 100644 --- a/host/lib/usrp/dboard/basic.cpp +++ b/host/lib/usrp/dboard/basic.cpp @@ -16,7 +16,7 @@ // #include -#include +#include #include #include #include @@ -34,26 +34,26 @@ using namespace boost::assign; **********************************************************************/ class basic_rx : public rx_dboard_base{ public: - basic_rx(ctor_args_t const& args, freq_t max_freq); + basic_rx(ctor_args_t const& args, double max_freq); ~basic_rx(void); void rx_get(const wax::obj &key, wax::obj &val); void rx_set(const wax::obj &key, const wax::obj &val); private: - freq_t _max_freq; + double _max_freq; }; class basic_tx : public tx_dboard_base{ public: - basic_tx(ctor_args_t const& args, freq_t max_freq); + basic_tx(ctor_args_t const& args, double max_freq); ~basic_tx(void); void tx_get(const wax::obj &key, wax::obj &val); void tx_set(const wax::obj &key, const wax::obj &val); private: - freq_t _max_freq; + double _max_freq; }; /*********************************************************************** @@ -85,7 +85,7 @@ UHD_STATIC_BLOCK(reg_dboards){ /*********************************************************************** * Basic and LF RX dboard **********************************************************************/ -basic_rx::basic_rx(ctor_args_t const& args, freq_t max_freq) : rx_dboard_base(args){ +basic_rx::basic_rx(ctor_args_t const& args, double max_freq) : rx_dboard_base(args){ _max_freq = max_freq; // set the gpios to safe values (all inputs) get_interface()->set_gpio_ddr(dboard_interface::GPIO_RX_BANK, 0x0000, 0xffff); @@ -113,7 +113,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_GAIN: - val = gain_t(0); + val = float(0); return; case SUBDEV_PROP_GAIN_RANGE: @@ -125,7 +125,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_FREQ: - val = freq_t(0); + val = double(0); return; case SUBDEV_PROP_FREQ_RANGE: @@ -164,7 +164,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){ switch(key.as()){ case SUBDEV_PROP_GAIN: - ASSERT_THROW(val.as() == gain_t(0)); + ASSERT_THROW(val.as() == float(0)); return; case SUBDEV_PROP_ANTENNA: @@ -196,7 +196,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){ /*********************************************************************** * Basic and LF TX dboard **********************************************************************/ -basic_tx::basic_tx(ctor_args_t const& args, freq_t max_freq) : tx_dboard_base(args){ +basic_tx::basic_tx(ctor_args_t const& args, double max_freq) : tx_dboard_base(args){ _max_freq = max_freq; // set the gpios to safe values (all inputs) get_interface()->set_gpio_ddr(dboard_interface::GPIO_TX_BANK, 0x0000, 0xffff); @@ -221,7 +221,7 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_GAIN: - val = gain_t(0); + val = float(0); return; case SUBDEV_PROP_GAIN_RANGE: @@ -233,7 +233,7 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_FREQ: - val = freq_t(0); + val = double(0); return; case SUBDEV_PROP_FREQ_RANGE: @@ -272,7 +272,7 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){ switch(key.as()){ case SUBDEV_PROP_GAIN: - ASSERT_THROW(val.as() == gain_t(0)); + ASSERT_THROW(val.as() == float(0)); return; case SUBDEV_PROP_ANTENNA: diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index 0f2189cd1..bc9bfbf14 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 6b49ff29d..fd72aeaa4 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -16,6 +16,7 @@ // #include +#include #include #include "usrp2_impl.hpp" diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 654096d14..40ef06a8c 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -35,7 +35,7 @@ template T log2(T num){ /*********************************************************************** * DDC Helper Methods **********************************************************************/ -static boost::uint32_t calculate_freq_word_and_update_actual_freq(freq_t &freq, freq_t clock_freq){ +static boost::uint32_t calculate_freq_word_and_update_actual_freq(double &freq, double clock_freq){ double scale_factor = std::pow(2.0, 32); //calculate the freq register word @@ -163,7 +163,7 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){ return; } else if (key_name == "freq"){ - freq_t new_freq = val.as(); + double new_freq = val.as(); ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); _ddc_freq = new_freq; //shadow @@ -283,7 +283,7 @@ void usrp2_impl::duc_set(const wax::obj &key, const wax::obj &val){ return; } else if (key_name == "freq"){ - freq_t new_freq = val.as(); + double new_freq = val.as(); ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); _duc_freq = new_freq; //shadow diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index e4706dcf0..b6919a738 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -16,6 +16,7 @@ // #include +#include #include "usrp2_impl.hpp" using namespace uhd; @@ -168,7 +169,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ return; case MBOARD_PROP_CLOCK_RATE: - val = freq_t(get_master_clock_freq()); + val = double(get_master_clock_freq()); return; case MBOARD_PROP_RX_DSP: diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 3a2963c5a..6535e7049 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -19,9 +19,9 @@ #define INCLUDED_USRP2_IMPL_HPP #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -173,14 +173,14 @@ private: //methods and shadows for the ddc dsp std::vector _allowed_decim_and_interp_rates; size_t _ddc_decim; - uhd::freq_t _ddc_freq; + double _ddc_freq; void init_ddc_config(void); void update_ddc_config(void); void issue_ddc_stream_cmd(const uhd::stream_cmd_t &stream_cmd); //methods and shadows for the duc dsp size_t _duc_interp; - uhd::freq_t _duc_freq; + double _duc_freq; void init_duc_config(void); void update_duc_config(void); diff --git a/host/test/addr_test.cpp b/host/test/addr_test.cpp index 148aee015..0c8f63b0a 100644 --- a/host/test/addr_test.cpp +++ b/host/test/addr_test.cpp @@ -16,13 +16,14 @@ // #include -#include +#include +#include BOOST_AUTO_TEST_CASE(test_mac_addr){ std::cout << "Testing mac addr..." << std::endl; const std::string mac_addr_str("00:01:23:45:67:89"); uhd::mac_addr_t mac_addr(mac_addr_str); std::cout << "Input: " << mac_addr_str << std::endl; - std::cout << "Output: " << mac_addr << std::endl; + std::cout << "Output: " << mac_addr.to_string() << std::endl; BOOST_CHECK_EQUAL(mac_addr_str, mac_addr.to_string()); } diff --git a/host/test/gain_handler_test.cpp b/host/test/gain_handler_test.cpp index 47acb30f0..e13063e06 100644 --- a/host/test/gain_handler_test.cpp +++ b/host/test/gain_handler_test.cpp @@ -17,9 +17,9 @@ #include #include -#include +#include +#include #include -#include #include #include @@ -84,7 +84,7 @@ private: //handle the get request conditioned on the key switch(key.as()){ case PROP_GAIN_VALUE: - _gain_values[name] = val.as(); + _gain_values[name] = val.as(); return; case PROP_GAIN_RANGE: @@ -94,7 +94,7 @@ private: } gain_handler::sptr _gain_handler; - uhd::dict _gain_values; + uhd::dict _gain_values; uhd::dict _gain_ranges; }; @@ -104,18 +104,18 @@ BOOST_AUTO_TEST_CASE(test_gain_handler){ gainful_obj go0; BOOST_CHECK_THROW( - go0[named_prop_t(PROP_GAIN_VALUE, "fail")].as(), + go0[named_prop_t(PROP_GAIN_VALUE, "fail")].as(), std::exception ); std::cout << "verifying the overall min, max, step" << std::endl; gain_range_t gain = go0[PROP_GAIN_RANGE].as(); - BOOST_CHECK_EQUAL(gain.min, gain_t(-10)); - BOOST_CHECK_EQUAL(gain.max, gain_t(100)); - BOOST_CHECK_EQUAL(gain.step, gain_t(1.5)); + BOOST_CHECK_EQUAL(gain.min, float(-10)); + BOOST_CHECK_EQUAL(gain.max, float(100)); + BOOST_CHECK_EQUAL(gain.step, float(1.5)); std::cout << "verifying the overall gain" << std::endl; - go0[named_prop_t(PROP_GAIN_VALUE, "g0")] = gain_t(-5); - go0[named_prop_t(PROP_GAIN_VALUE, "g1")] = gain_t(30); - BOOST_CHECK_EQUAL(go0[PROP_GAIN_VALUE].as(), gain_t(25)); + go0[named_prop_t(PROP_GAIN_VALUE, "g0")] = float(-5); + go0[named_prop_t(PROP_GAIN_VALUE, "g1")] = float(30); + BOOST_CHECK_EQUAL(go0[PROP_GAIN_VALUE].as(), float(25)); } diff --git a/host/utils/discover_usrps.cpp b/host/utils/discover_usrps.cpp index dc2b845bc..72c5b8822 100644 --- a/host/utils/discover_usrps.cpp +++ b/host/utils/discover_usrps.cpp @@ -63,7 +63,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::cout << "--------------------------------------------------" << std::endl; std::cout << "-- USRP Device " << i << std::endl; std::cout << "--------------------------------------------------" << std::endl; - std::cout << device_addrs[i] << std::endl << std::endl; + std::cout << device_addrs[i].to_string() << std::endl << std::endl; uhd::device::make(device_addrs[i]); //test make } -- cgit v1.2.3 From 86fffe7f9ed78a682879dd56c26628256f89e6ae Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 29 Mar 2010 00:45:26 -0700 Subject: Added tune helper to utils. Takes a subdevice and dxc properties object and tunes them. Made use of tune helper in simple device. Moved gain handler into utils header dir. --- host/include/uhd/CMakeLists.txt | 1 - host/include/uhd/gain_handler.hpp | 90 ----------------------- host/include/uhd/utils/CMakeLists.txt | 2 + host/include/uhd/utils/gain_handler.hpp | 90 +++++++++++++++++++++++ host/include/uhd/utils/tune_helper.hpp | 79 ++++++++++++++++++++ host/lib/CMakeLists.txt | 1 + host/lib/gain_handler.cpp | 2 +- host/lib/simple_device.cpp | 74 +------------------ host/lib/tune_helper.cpp | 125 ++++++++++++++++++++++++++++++++ host/lib/usrp/dboard_manager.cpp | 2 +- host/test/gain_handler_test.cpp | 2 +- 11 files changed, 303 insertions(+), 165 deletions(-) delete mode 100644 host/include/uhd/gain_handler.hpp create mode 100644 host/include/uhd/utils/gain_handler.hpp create mode 100644 host/include/uhd/utils/tune_helper.hpp create mode 100644 host/lib/tune_helper.cpp (limited to 'host/lib/CMakeLists.txt') diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt index 0cebea095..b364f78cd 100644 --- a/host/include/uhd/CMakeLists.txt +++ b/host/include/uhd/CMakeLists.txt @@ -24,7 +24,6 @@ ADD_SUBDIRECTORY(utils) INSTALL(FILES config.hpp device.hpp - gain_handler.hpp props.hpp simple_device.hpp wax.hpp diff --git a/host/include/uhd/gain_handler.hpp b/host/include/uhd/gain_handler.hpp deleted file mode 100644 index 65d6cecf9..000000000 --- a/host/include/uhd/gain_handler.hpp +++ /dev/null @@ -1,90 +0,0 @@ -// -// 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 . -// - -#ifndef INCLUDED_UHD_GAIN_HANDLER_HPP -#define INCLUDED_UHD_GAIN_HANDLER_HPP - -#include -#include -#include -#include - -namespace uhd{ - -class UHD_API gain_handler{ -public: - typedef boost::shared_ptr sptr; - typedef boost::function is_equal_t; - - /*! - * A set of properties for dealing with gains. - */ - struct UHD_API props_t{ - wax::obj value, range, names; - props_t(void); //default constructor - }; - - /*! - * Make a new gain handler. - * The construction arguments are agnostic to the property type. - * It is up to the caller to provide an "is_equal" function that - * can tell weather two properties (in a wax obj) are equal. - * \param link a link to the wax obj with properties - * \param props a struct of properties keys - * \param is_equal the function that tests for equal properties - */ - static sptr make( - const wax::obj &link, - const props_t &props, - is_equal_t is_equal - ); - - /*! - * Intercept gets for overall gain, min, max, step. - * Ensures that the gain name is valid. - * \return true for handled, false to pass on - */ - virtual bool intercept_get(const wax::obj &key, wax::obj &val) = 0; - - /*! - * Intercept sets for overall gain. - * Ensures that the gain name is valid. - * Ensures that the new gain is within range. - * \return true for handled, false to pass on - */ - virtual bool intercept_set(const wax::obj &key, const wax::obj &val) = 0; - - /*! - * Function template to test if two wax types are equal: - * The constructor will bind an instance of this for a specific type. - * This bound equals functions allows the intercept methods to be non-templated. - */ - template static bool is_equal(const wax::obj &a, const wax::obj &b){ - try{ - return a.as() == b.as(); - } - catch(const wax::bad_cast &){ - return false; - } - } - -}; - -} //namespace uhd - -#endif /* INCLUDED_UHD_GAIN_HANDLER_HPP */ - diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt index f6ed87701..1b673f44a 100644 --- a/host/include/uhd/utils/CMakeLists.txt +++ b/host/include/uhd/utils/CMakeLists.txt @@ -18,7 +18,9 @@ INSTALL(FILES algorithm.hpp assert.hpp + gain_handler.hpp safe_main.hpp static.hpp + tune_helper.hpp DESTINATION ${INCLUDE_DIR}/uhd/utils ) diff --git a/host/include/uhd/utils/gain_handler.hpp b/host/include/uhd/utils/gain_handler.hpp new file mode 100644 index 000000000..f4629e6a7 --- /dev/null +++ b/host/include/uhd/utils/gain_handler.hpp @@ -0,0 +1,90 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_UTILS_GAIN_HANDLER_HPP +#define INCLUDED_UHD_UTILS_GAIN_HANDLER_HPP + +#include +#include +#include +#include + +namespace uhd{ + +class UHD_API gain_handler{ +public: + typedef boost::shared_ptr sptr; + typedef boost::function is_equal_t; + + /*! + * A set of properties for dealing with gains. + */ + struct UHD_API props_t{ + wax::obj value, range, names; + props_t(void); //default constructor + }; + + /*! + * Make a new gain handler. + * The construction arguments are agnostic to the property type. + * It is up to the caller to provide an "is_equal" function that + * can tell weather two properties (in a wax obj) are equal. + * \param link a link to the wax obj with properties + * \param props a struct of properties keys + * \param is_equal the function that tests for equal properties + */ + static sptr make( + const wax::obj &link, + const props_t &props, + is_equal_t is_equal + ); + + /*! + * Intercept gets for overall gain, min, max, step. + * Ensures that the gain name is valid. + * \return true for handled, false to pass on + */ + virtual bool intercept_get(const wax::obj &key, wax::obj &val) = 0; + + /*! + * Intercept sets for overall gain. + * Ensures that the gain name is valid. + * Ensures that the new gain is within range. + * \return true for handled, false to pass on + */ + virtual bool intercept_set(const wax::obj &key, const wax::obj &val) = 0; + + /*! + * Function template to test if two wax types are equal: + * The constructor will bind an instance of this for a specific type. + * This bound equals functions allows the intercept methods to be non-templated. + */ + template static bool is_equal(const wax::obj &a, const wax::obj &b){ + try{ + return a.as() == b.as(); + } + catch(const wax::bad_cast &){ + return false; + } + } + +}; + +} //namespace uhd + +#endif /* INCLUDED_UHD_UTILS_GAIN_HANDLER_HPP */ + diff --git a/host/include/uhd/utils/tune_helper.hpp b/host/include/uhd/utils/tune_helper.hpp new file mode 100644 index 000000000..828575c99 --- /dev/null +++ b/host/include/uhd/utils/tune_helper.hpp @@ -0,0 +1,79 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_UTILS_TUNE_HELPER_HPP +#define INCLUDED_UHD_UTILS_TUNE_HELPER_HPP + +#include +#include +#include + +namespace uhd{ + +/*! + * Tune a rx chain to the desired frequency: + * The IF of the subdevice is set as close as possible to + * the given target frequency + the LO offset (when applicable). + * The ddc cordic is setup to bring the IF down to baseband. + * \param subdev the dboard subdevice object with properties + * \param ddc the ddc properties object (with "rate", "decim", "freq") + * \param target_freq the desired center frequency + * \param lo_offset an offset for the subdevice IF from center + * \return a tune result struct + */ +UHD_API tune_result_t tune_rx_subdev_and_ddc( + wax::obj subdev, wax::obj ddc, + double target_freq, double lo_offset +); + +/*! + * Tune a rx chain to the desired frequency: + * Same as the above, except the LO offset + * is calculated based on the subdevice and BW. + */ +UHD_API tune_result_t tune_rx_subdev_and_ddc( + wax::obj subdev, wax::obj ddc, double target_freq +); + +/*! + * Tune a tx chain to the desired frequency: + * The IF of the subdevice is set as close as possible to + * the given target frequency + the LO offset (when applicable). + * The duc cordic is setup to bring the baseband up to IF. + * \param subdev the dboard subdevice object with properties + * \param duc the duc properties object (with "rate", "interp", "freq") + * \param target_freq the desired center frequency + * \param lo_offset an offset for the subdevice IF from center + * \return a tune result struct + */ +UHD_API tune_result_t tune_tx_subdev_and_duc( + wax::obj subdev, wax::obj duc, + double target_freq, double lo_offset +); + +/*! + * Tune a tx chain to the desired frequency: + * Same as the above, except the LO offset + * is calculated based on the subdevice and BW. + */ +UHD_API tune_result_t tune_tx_subdev_and_duc( + wax::obj subdev, wax::obj duc, double target_freq +); + +} //namespace uhd + +#endif /* INCLUDED_UHD_UTILS_TUNE_HELPER_HPP */ diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 1eceb53ea..55034c780 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -23,6 +23,7 @@ SET(libuhd_sources gain_handler.cpp load_modules.cpp simple_device.cpp + tune_helper.cpp types.cpp wax.cpp transport/if_addrs.cpp diff --git a/host/lib/gain_handler.cpp b/host/lib/gain_handler.cpp index a6ae06c50..daf629f0b 100644 --- a/host/lib/gain_handler.cpp +++ b/host/lib/gain_handler.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see . // -#include +#include #include #include #include diff --git a/host/lib/simple_device.cpp b/host/lib/simple_device.cpp index 95bc8fecc..d507762a9 100644 --- a/host/lib/simple_device.cpp +++ b/host/lib/simple_device.cpp @@ -16,8 +16,8 @@ // #include +#include #include -#include #include #include #include @@ -26,64 +26,6 @@ using namespace uhd; -/*********************************************************************** - * Tune Helper Function - **********************************************************************/ -static tune_result_t tune( - double target_freq, - double lo_offset, - wax::obj subdev, - wax::obj dxc, - bool is_tx -){ - wax::obj subdev_freq_proxy = subdev[SUBDEV_PROP_FREQ]; - bool subdev_quadrature = subdev[SUBDEV_PROP_QUADRATURE].as(); - bool subdev_spectrum_inverted = subdev[SUBDEV_PROP_SPECTRUM_INVERTED].as(); - wax::obj dxc_freq_proxy = dxc[std::string("freq")]; - double dxc_sample_rate = dxc[std::string("rate")].as(); - - // Ask the d'board to tune as closely as it can to target_freq+lo_offset - double target_inter_freq = target_freq + lo_offset; - subdev_freq_proxy = target_inter_freq; - double actual_inter_freq = subdev_freq_proxy.as(); - - // Calculate the DDC setting that will downconvert the baseband from the - // daughterboard to our target frequency. - double delta_freq = target_freq - actual_inter_freq; - double delta_sign = std::signum(delta_freq); - delta_freq *= delta_sign; - delta_freq = fmod(delta_freq, dxc_sample_rate); - bool inverted = delta_freq > dxc_sample_rate/2.0; - double target_dxc_freq = inverted? (delta_freq - dxc_sample_rate) : (-delta_freq); - target_dxc_freq *= delta_sign; - - // If the spectrum is inverted, and the daughterboard doesn't do - // quadrature downconversion, we can fix the inversion by flipping the - // sign of the dxc_freq... (This only happens using the basic_rx board) - if (subdev_spectrum_inverted){ - inverted = not inverted; - } - if (inverted and not subdev_quadrature){ - target_dxc_freq *= -1.0; - inverted = not inverted; - } - // down conversion versus up conversion, fight! - // your mother is ugly and your going down... - target_dxc_freq *= (is_tx)? -1.0 : +1.0; - - dxc_freq_proxy = target_dxc_freq; - double actual_dxc_freq = dxc_freq_proxy.as(); - - //return some kind of tune result tuple/struct - tune_result_t tune_result; - tune_result.target_inter_freq = target_inter_freq; - tune_result.actual_inter_freq = actual_inter_freq; - tune_result.target_dxc_freq = target_dxc_freq; - tune_result.actual_dxc_freq = actual_dxc_freq; - tune_result.spectrum_inverted = inverted; - return tune_result; -} - /*********************************************************************** * Helper Functions **********************************************************************/ @@ -190,12 +132,7 @@ public: } tune_result_t set_rx_freq(double target_freq){ - double lo_offset = 0.0; - //if the local oscillator will be in the passband, use an offset - if (_rx_subdev[SUBDEV_PROP_LO_INTERFERES].as()){ - lo_offset = get_rx_rate()*2.0; - } - return tune(target_freq, lo_offset, _rx_subdev, _rx_ddc, false/* not tx */); + return tune_rx_subdev_and_ddc(_rx_subdev, _rx_ddc, target_freq); } freq_range_t get_rx_freq_range(void){ @@ -246,12 +183,7 @@ public: } tune_result_t set_tx_freq(double target_freq){ - double lo_offset = 0.0; - //if the local oscillator will be in the passband, use an offset - if (_tx_subdev[SUBDEV_PROP_LO_INTERFERES].as()){ - lo_offset = get_tx_rate()*2.0; - } - return tune(target_freq, lo_offset, _tx_subdev, _tx_duc, true/* is tx */); + return tune_tx_subdev_and_duc(_tx_subdev, _tx_duc, target_freq); } freq_range_t get_tx_freq_range(void){ diff --git a/host/lib/tune_helper.cpp b/host/lib/tune_helper.cpp new file mode 100644 index 000000000..eeda0b6be --- /dev/null +++ b/host/lib/tune_helper.cpp @@ -0,0 +1,125 @@ +// +// 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 . +// + +#include +#include +#include +#include + +using namespace uhd; + +/*********************************************************************** + * Tune Helper Function + **********************************************************************/ +static tune_result_t tune_xx_subdev_and_dxc( + bool is_tx, + wax::obj subdev, wax::obj dxc, + double target_freq, double lo_offset +){ + wax::obj subdev_freq_proxy = subdev[SUBDEV_PROP_FREQ]; + bool subdev_quadrature = subdev[SUBDEV_PROP_QUADRATURE].as(); + bool subdev_spectrum_inverted = subdev[SUBDEV_PROP_SPECTRUM_INVERTED].as(); + wax::obj dxc_freq_proxy = dxc[std::string("freq")]; + double dxc_sample_rate = dxc[std::string("rate")].as(); + + // Ask the d'board to tune as closely as it can to target_freq+lo_offset + double target_inter_freq = target_freq + lo_offset; + subdev_freq_proxy = target_inter_freq; + double actual_inter_freq = subdev_freq_proxy.as(); + + // Calculate the DDC setting that will downconvert the baseband from the + // daughterboard to our target frequency. + double delta_freq = target_freq - actual_inter_freq; + double delta_sign = std::signum(delta_freq); + delta_freq *= delta_sign; + delta_freq = std::fmod(delta_freq, dxc_sample_rate); + bool inverted = delta_freq > dxc_sample_rate/2.0; + double target_dxc_freq = inverted? (delta_freq - dxc_sample_rate) : (-delta_freq); + target_dxc_freq *= delta_sign; + + // If the spectrum is inverted, and the daughterboard doesn't do + // quadrature downconversion, we can fix the inversion by flipping the + // sign of the dxc_freq... (This only happens using the basic_rx board) + if (subdev_spectrum_inverted){ + inverted = not inverted; + } + if (inverted and not subdev_quadrature){ + target_dxc_freq *= -1.0; + inverted = not inverted; + } + // down conversion versus up conversion, fight! + // your mother is ugly and your going down... + target_dxc_freq *= (is_tx)? -1.0 : +1.0; + + dxc_freq_proxy = target_dxc_freq; + double actual_dxc_freq = dxc_freq_proxy.as(); + + //return some kind of tune result tuple/struct + tune_result_t tune_result; + tune_result.target_inter_freq = target_inter_freq; + tune_result.actual_inter_freq = actual_inter_freq; + tune_result.target_dxc_freq = target_dxc_freq; + tune_result.actual_dxc_freq = actual_dxc_freq; + tune_result.spectrum_inverted = inverted; + return tune_result; +} + +/*********************************************************************** + * RX Tune + **********************************************************************/ +tune_result_t uhd::tune_rx_subdev_and_ddc( + wax::obj subdev, wax::obj ddc, + double target_freq, double lo_offset +){ + bool is_tx = false; + return tune_xx_subdev_and_dxc(is_tx, subdev, ddc, target_freq, lo_offset); +} + +tune_result_t uhd::tune_rx_subdev_and_ddc( + wax::obj subdev, wax::obj ddc, + double target_freq +){ + double lo_offset = 0.0; + //if the local oscillator will be in the passband, use an offset + if (subdev[SUBDEV_PROP_LO_INTERFERES].as()){ + lo_offset = 2.0*ddc[std::string("rate")].as()/ddc[std::string("decim")].as(); + } + return tune_rx_subdev_and_ddc(subdev, ddc, target_freq, lo_offset); +} + +/*********************************************************************** + * TX Tune + **********************************************************************/ +tune_result_t uhd::tune_tx_subdev_and_duc( + wax::obj subdev, wax::obj duc, + double target_freq, double lo_offset +){ + bool is_tx = true; + return tune_xx_subdev_and_dxc(is_tx, subdev, duc, target_freq, lo_offset); +} + +tune_result_t uhd::tune_tx_subdev_and_duc( + wax::obj subdev, wax::obj duc, + double target_freq +){ + double lo_offset = 0.0; + //if the local oscillator will be in the passband, use an offset + if (subdev[SUBDEV_PROP_LO_INTERFERES].as()){ + lo_offset = 2.0*duc[std::string("rate")].as()/duc[std::string("interp")].as(); + } + return tune_tx_subdev_and_duc(subdev, duc, target_freq, lo_offset); +} diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index bc9bfbf14..f86545696 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -16,7 +16,7 @@ // #include -#include +#include #include #include #include diff --git a/host/test/gain_handler_test.cpp b/host/test/gain_handler_test.cpp index a7c6e1e82..76b065ce2 100644 --- a/host/test/gain_handler_test.cpp +++ b/host/test/gain_handler_test.cpp @@ -16,7 +16,7 @@ // #include -#include +#include #include #include #include -- cgit v1.2.3