From 694dc3c7bc6f07b9660aef0c5ace9f6e11f98066 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 22 Mar 2010 17:52:08 -0700 Subject: merged usrp2 stuff from u1e branch (without merging the u1e stuff) --- host/lib/usrp/usrp2/usrp2_impl.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'host/lib/usrp/usrp2/usrp2_impl.cpp') diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index bdf8cc55b..85d73e83a 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -26,7 +26,7 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace asio = boost::asio; -STATIC_BLOCK(register_device){ +STATIC_BLOCK(register_usrp2_device){ device::register_device(&usrp2::discover, &usrp2::make); } @@ -36,6 +36,8 @@ STATIC_BLOCK(register_device){ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ device_addrs_t usrp2_addrs; + if (not hint.has_key("addr")) return usrp2_addrs; + //create a udp transport to communicate //TODO if an addr is not provided, search all interfaces? std::string ctrl_port = boost::lexical_cast(USRP2_UDP_CTRL_PORT); -- cgit v1.2.3 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/include/uhd/transport/CMakeLists.txt | 1 + host/include/uhd/transport/if_addrs.hpp | 47 ++++ host/include/uhd/transport/smart_buffer.hpp | 2 +- host/include/uhd/transport/udp_simple.hpp | 2 +- host/include/uhd/transport/udp_zero_copy.hpp | 2 +- host/lib/CMakeLists.txt | 15 +- host/lib/transport/if_addrs.cpp | 343 +++++++++++++++++++++++++++ host/lib/transport/udp_simple.cpp | 1 + host/lib/transport/udp_zero_copy_asio.cpp | 1 + host/lib/usrp/usrp2/usrp2_impl.cpp | 20 +- host/lib/usrp/usrp2/usrp2_impl.hpp | 1 + 11 files changed, 429 insertions(+), 6 deletions(-) create mode 100644 host/include/uhd/transport/if_addrs.hpp create mode 100644 host/lib/transport/if_addrs.cpp (limited to 'host/lib/usrp/usrp2/usrp2_impl.cpp') diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt index 75b07c540..14b5ccd29 100644 --- a/host/include/uhd/transport/CMakeLists.txt +++ b/host/include/uhd/transport/CMakeLists.txt @@ -17,6 +17,7 @@ INSTALL(FILES + if_addrs.hpp smart_buffer.hpp udp_simple.hpp udp_zero_copy.hpp diff --git a/host/include/uhd/transport/if_addrs.hpp b/host/include/uhd/transport/if_addrs.hpp new file mode 100644 index 000000000..fbbb35e1d --- /dev/null +++ b/host/include/uhd/transport/if_addrs.hpp @@ -0,0 +1,47 @@ +// +// 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_IFADDRS_HPP +#define INCLUDED_UHD_IFADDRS_HPP + +#include +#include +#include + +namespace uhd{ namespace transport{ + + /*! + * The address for a network interface. + */ + struct UHD_API if_addrs_t{ + std::string inet; + std::string mask; + std::string bcast; + if_addrs_t(void); + }; + + /*! + * Get a list of network interface addresses. + * The internal implementation is system-dependent. + * \return a vector of if addrs + */ + UHD_API std::vector get_if_addrs(void); + +}} //namespace + + +#endif /* INCLUDED_UHD_IFADDRS_HPP */ diff --git a/host/include/uhd/transport/smart_buffer.hpp b/host/include/uhd/transport/smart_buffer.hpp index 9e1032feb..a9bc259e9 100644 --- a/host/include/uhd/transport/smart_buffer.hpp +++ b/host/include/uhd/transport/smart_buffer.hpp @@ -18,7 +18,7 @@ #ifndef INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP #define INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP -#include +#include #include #include diff --git a/host/include/uhd/transport/udp_simple.hpp b/host/include/uhd/transport/udp_simple.hpp index 40e60d091..793ec4fd7 100644 --- a/host/include/uhd/transport/udp_simple.hpp +++ b/host/include/uhd/transport/udp_simple.hpp @@ -19,7 +19,7 @@ #define INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP #include -#include +#include #include #include diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp index 03d89b3a5..0441a8e74 100644 --- a/host/include/uhd/transport/udp_zero_copy.hpp +++ b/host/include/uhd/transport/udp_zero_copy.hpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include 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 ######################################################################## diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp new file mode 100644 index 000000000..d3ea448fd --- /dev/null +++ b/host/lib/transport/if_addrs.cpp @@ -0,0 +1,343 @@ +// +// 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 + +uhd::transport::if_addrs_t::if_addrs_t(void){ + /* NOP */ +} + +/*********************************************************************** + * Interface address discovery through ifaddrs api + **********************************************************************/ +#ifdef HAVE_IFADDRS_H +#include +#include + +static boost::asio::ip::address_v4 sockaddr_to_ip_addr(sockaddr *addr){ + if (addr->sa_family == AF_INET) return boost::asio::ip::address_v4(ntohl( + reinterpret_cast(addr)->sin_addr.s_addr + )); + return boost::asio::ip::address_v4::any(); +} + +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() + ); +} + +std::vector uhd::transport::get_if_addrs(void){ + std::vector if_addrs; + struct ifaddrs *ifap; + if (getifaddrs(&ifap) == 0){ + for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next){ + if (not ifaddrs_valid(iter)) continue; + if_addrs_t if_addr; + if_addr.inet = sockaddr_to_ip_addr(iter->ifa_addr).to_string(); + if_addr.mask = sockaddr_to_ip_addr(iter->ifa_netmask).to_string(); + if_addr.bcast = sockaddr_to_ip_addr(iter->ifa_broadaddr).to_string(); + if_addrs.push_back(if_addr); + } + freeifaddrs(ifap); + } + return if_addrs; +} + +/*********************************************************************** + * Interface address discovery through windows api (TODO) + **********************************************************************/ +//#elif HAVE_XXX_H + +/*********************************************************************** + * Interface address discovery not included + **********************************************************************/ +#else /* HAVE_IFADDRS_H */ + +std::vector uhd::transport::get_if_addrs(void){ + return std::vector(); +} + +#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/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp index 3c8ecb70d..f339127ad 100644 --- a/host/lib/transport/udp_simple.cpp +++ b/host/lib/transport/udp_simple.cpp @@ -16,6 +16,7 @@ // #include +#include #include #include #include diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index 219ae8720..63944b2bf 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 85d73e83a..f04ae8d2c 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -15,9 +15,11 @@ // along with this program. If not, see . // +#include +#include #include +#include #include -#include #include #include "usrp2_impl.hpp" @@ -36,7 +38,21 @@ STATIC_BLOCK(register_usrp2_device){ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ device_addrs_t usrp2_addrs; - if (not hint.has_key("addr")) return usrp2_addrs; + //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()){ + //create a new hint with this broadcast address + device_addr_t new_hint = hint; + new_hint["addr"] = if_addrs.bcast; + + //call discover with the new hint and append results + device_addrs_t new_usrp2_addrs = usrp2::discover(new_hint); + usrp2_addrs.insert(usrp2_addrs.begin(), + new_usrp2_addrs.begin(), new_usrp2_addrs.end() + ); + } + return usrp2_addrs; + } //create a udp transport to communicate //TODO if an addr is not provided, search all interfaces? diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 55ac0b192..a2f454c61 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include -- 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/usrp/usrp2/usrp2_impl.cpp') 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 52df9afd679fd0f42edeef29f0bbc0d7bd76559e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 27 Mar 2010 01:02:58 -0700 Subject: Split utils.hpp into subdir with multiple files. static for static block and static instance (singleton) assert for assertion and throwing related stuff algorithm for my addons to std::algorithm (has) and a new one, safe main, for having a main catch-all --- host/examples/rx_timed_samples.cpp | 3 +- host/include/uhd/CMakeLists.txt | 2 +- host/include/uhd/utils.hpp | 130 ------------------------------- host/include/uhd/utils/CMakeLists.txt | 24 ++++++ host/include/uhd/utils/algorithm.hpp | 60 ++++++++++++++ host/include/uhd/utils/assert.hpp | 76 ++++++++++++++++++ host/include/uhd/utils/safe_main.hpp | 43 ++++++++++ host/include/uhd/utils/static.hpp | 35 +++++++++ host/lib/device.cpp | 7 +- host/lib/gain_handler.cpp | 2 +- host/lib/load_modules.cpp | 4 +- host/lib/simple_device.cpp | 4 +- host/lib/usrp/dboard/basic.cpp | 5 +- host/lib/usrp/dboard_manager.cpp | 5 +- host/lib/usrp/usrp2/dboard_impl.cpp | 2 +- host/lib/usrp/usrp2/dboard_interface.cpp | 2 +- host/lib/usrp/usrp2/dsp_impl.cpp | 2 +- host/lib/usrp/usrp2/mboard_impl.cpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.cpp | 5 +- host/test/module_test.cpp | 4 +- host/utils/discover_usrps.cpp | 3 +- host/utils/usrp2_burner.cpp | 3 +- 22 files changed, 269 insertions(+), 154 deletions(-) delete mode 100644 host/include/uhd/utils.hpp create mode 100644 host/include/uhd/utils/CMakeLists.txt create mode 100644 host/include/uhd/utils/algorithm.hpp create mode 100644 host/include/uhd/utils/assert.hpp create mode 100644 host/include/uhd/utils/safe_main.hpp create mode 100644 host/include/uhd/utils/static.hpp (limited to 'host/lib/usrp/usrp2/usrp2_impl.cpp') diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 7d58187cd..5d4b5a68d 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include #include #include #include @@ -24,7 +25,7 @@ namespace po = boost::program_options; -int main(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char *argv[]){ //variables to be set by po std::string transport_args; int seconds_in_future; diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt index 84e7b441b..2203ea83e 100644 --- a/host/include/uhd/CMakeLists.txt +++ b/host/include/uhd/CMakeLists.txt @@ -18,6 +18,7 @@ ADD_SUBDIRECTORY(transport) ADD_SUBDIRECTORY(usrp) +ADD_SUBDIRECTORY(utils) INSTALL(FILES config.hpp @@ -30,7 +31,6 @@ INSTALL(FILES simple_device.hpp time_spec.hpp types.hpp - utils.hpp wax.hpp DESTINATION ${INCLUDE_DIR}/uhd ) diff --git a/host/include/uhd/utils.hpp b/host/include/uhd/utils.hpp deleted file mode 100644 index e5333539f..000000000 --- a/host/include/uhd/utils.hpp +++ /dev/null @@ -1,130 +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_UTILS_HPP -#define INCLUDED_UHD_UTILS_HPP - -#include -#include -#include -#include -#include - -/*! - * Defines a function that implements the "construct on first use" idiom - * \param _t the type definition for the instance - * \param _x the name of the defined function - * \return a reference to the lazy instance - */ -#define STATIC_INSTANCE(_t, _x) static _t &_x(){static _t _x; return _x;} - -/*! - * Defines a static code block that will be called before main() - * \param _x the name of the defined struct (must be unique in file) - */ -#define STATIC_BLOCK(_x) static struct _x{_x();}_x;_x::_x() - -/*! - * Useful templated functions and classes that I like to pretend are part of stl - */ -namespace std{ - - class assert_error : public std::logic_error{ - public: - explicit assert_error(const string& what_arg) : logic_error(what_arg){ - /* NOP */ - } - }; - - #define ASSERT_THROW(_x) if (not (_x)) { \ - throw std::assert_error(str(boost::format( \ - "Assertion Failed:\n %s:%d\n %s\n ---> %s <---" \ - ) % __FILE__ % __LINE__ % BOOST_CURRENT_FUNCTION % std::string(#_x))); \ - } - - template - T reduce(InputIterator first, InputIterator last, Function fcn, T init = 0){ - T tmp = init; - for ( ; first != last; ++first ){ - tmp = fcn(tmp, *first); - } - return tmp; - } - - template - T reduce(Iterable iterable, Function fcn, T init = 0){ - return reduce(iterable.begin(), iterable.end(), fcn, init); - } - - template - bool has(InputIterator first, InputIterator last, const T &elem){ - return last != std::find(first, last, elem); - } - - template - bool has(const Iterable &iterable, const T &elem){ - return has(iterable.begin(), iterable.end(), elem); - } - - template T signum(T n){ - if (n < 0) return -1; - if (n > 0) return 1; - return 0; - } - -}//namespace std - -#include -#include -#include - -namespace uhd{ - - /*! - * Check that an element is found in a container. - * If not, throw a meaningful assertion error. - * The "what" in the error will show what is - * being set and a list of known good values. - * - * \param iterable a list of possible settings - * \param elem an element that may be in the list - * \param what a description of what is being set - * \throw assertion_error when elem not in list - */ - template void assert_has( - const Iterable &iterable, - const T &elem, - const std::string &what = "unknown" - ){ - if (std::has(iterable, elem)) return; - std::string possible_values = ""; - BOOST_FOREACH(T e, iterable){ - if (e != iterable.begin()[0]) possible_values += ", "; - possible_values += boost::lexical_cast(e); - } - throw std::assert_error(str(boost::format( - "Error: %s is not a valid %s. " - "Possible values are: [%s]." - ) - % boost::lexical_cast(elem) - % what % possible_values - )); - } - -}//namespace uhd - -#endif /* INCLUDED_UHD_UTILS_HPP */ diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt new file mode 100644 index 000000000..f6ed87701 --- /dev/null +++ b/host/include/uhd/utils/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# 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 + algorithm.hpp + assert.hpp + safe_main.hpp + static.hpp + DESTINATION ${INCLUDE_DIR}/uhd/utils +) diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp new file mode 100644 index 000000000..6635c8a4a --- /dev/null +++ b/host/include/uhd/utils/algorithm.hpp @@ -0,0 +1,60 @@ +// +// 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_ALGORITHM_HPP +#define INCLUDED_UHD_UTILS_ALGORITHM_HPP + +#include + +/*! + * Useful templated functions and classes that I like to pretend are part of stl + */ +namespace std{ + + template + T reduce(InputIterator first, InputIterator last, Function fcn, T init = 0){ + T tmp = init; + for ( ; first != last; ++first ){ + tmp = fcn(tmp, *first); + } + return tmp; + } + + template + T reduce(Iterable iterable, Function fcn, T init = 0){ + return reduce(iterable.begin(), iterable.end(), fcn, init); + } + + template + bool has(InputIterator first, InputIterator last, const T &elem){ + return last != std::find(first, last, elem); + } + + template + bool has(const Iterable &iterable, const T &elem){ + return has(iterable.begin(), iterable.end(), elem); + } + + template T signum(T n){ + if (n < 0) return -1; + if (n > 0) return 1; + return 0; + } + +}//namespace std + +#endif /* INCLUDED_UHD_UTILS_ALGORITHM_HPP */ diff --git a/host/include/uhd/utils/assert.hpp b/host/include/uhd/utils/assert.hpp new file mode 100644 index 000000000..842ed8dfa --- /dev/null +++ b/host/include/uhd/utils/assert.hpp @@ -0,0 +1,76 @@ +// +// 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_ASSERT_HPP +#define INCLUDED_UHD_UTILS_ASSERT_HPP + +#include +#include +#include +#include +#include +#include + +namespace uhd{ + + class assert_error : public std::logic_error{ + public: + explicit assert_error(const std::string& what_arg) : logic_error(what_arg){ + /* NOP */ + } + }; + + #define ASSERT_THROW(_x) if (not (_x)) { \ + throw uhd::assert_error(str(boost::format( \ + "Assertion Failed:\n %s:%d\n %s\n ---> %s <---" \ + ) % __FILE__ % __LINE__ % BOOST_CURRENT_FUNCTION % std::string(#_x))); \ + } + + /*! + * Check that an element is found in a container. + * If not, throw a meaningful assertion error. + * The "what" in the error will show what is + * being set and a list of known good values. + * + * \param iterable a list of possible settings + * \param elem an element that may be in the list + * \param what a description of what is being set + * \throw assertion_error when elem not in list + */ + template void assert_has( + const Iterable &iterable, + const T &elem, + const std::string &what = "unknown" + ){ + if (std::has(iterable, elem)) return; + std::string possible_values = ""; + BOOST_FOREACH(T e, iterable){ + if (e != iterable.begin()[0]) possible_values += ", "; + possible_values += boost::lexical_cast(e); + } + throw uhd::assert_error(str(boost::format( + "Error: %s is not a valid %s. " + "Possible values are: [%s]." + ) + % boost::lexical_cast(elem) + % what % possible_values + )); + } + +}//namespace uhd + +#endif /* INCLUDED_UHD_UTILS_ASSERT_HPP */ diff --git a/host/include/uhd/utils/safe_main.hpp b/host/include/uhd/utils/safe_main.hpp new file mode 100644 index 000000000..dd738f2e3 --- /dev/null +++ b/host/include/uhd/utils/safe_main.hpp @@ -0,0 +1,43 @@ +// +// 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_SAFE_MAIN_HPP +#define INCLUDED_UHD_UTILS_SAFE_MAIN_HPP + +#include +#include + +/*! + * Defines a safe wrapper that places a catch-all around main. + * If an exception is thrown, it prints to stderr and returns. + * Usage: int UHD_SAFE_MAIN(int argc, char *argv[]){ main code here } + * \param _argc the declaration for argc + * \param _argv the declaration for argv + */ +#define UHD_SAFE_MAIN(_argc, _argv) _main(int, char*[]); \ +int main(int argc, char *argv[]){ \ + try { \ + return _main(argc, argv); \ + } catch(const std::exception &e) { \ + std::cerr << "Error: " << e.what() << std::endl; \ + } catch(...) { \ + std::cerr << "Error: unknown exception" << std::endl; \ + } \ + return ~0; \ +} int _main(_argc, _argv) + +#endif /* INCLUDED_UHD_UTILS_SAFE_MAIN_HPP */ diff --git a/host/include/uhd/utils/static.hpp b/host/include/uhd/utils/static.hpp new file mode 100644 index 000000000..63db5a247 --- /dev/null +++ b/host/include/uhd/utils/static.hpp @@ -0,0 +1,35 @@ +// +// 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_STATIC_HPP +#define INCLUDED_UHD_UTILS_STATIC_HPP + +/*! + * Defines a function that implements the "construct on first use" idiom + * \param _t the type definition for the instance + * \param _x the name of the defined function + * \return a reference to the lazy instance + */ +#define UHD_SINGLETON_FCN(_t, _x) static _t &_x(){static _t _x; return _x;} + +/*! + * Defines a static code block that will be called before main() + * \param _x the name of the defined struct (must be unique in file) + */ +#define UHD_STATIC_BLOCK(_x) static struct _x{_x();}_x;_x::_x() + +#endif /* INCLUDED_UHD_UTILS_STATIC_HPP */ diff --git a/host/lib/device.cpp b/host/lib/device.cpp index cd8a01ab4..0bdbf5f23 100644 --- a/host/lib/device.cpp +++ b/host/lib/device.cpp @@ -17,7 +17,8 @@ #include #include -#include +#include +#include #include #include #include @@ -59,7 +60,7 @@ static size_t hash_device_addr( typedef boost::tuple dev_fcn_reg_t; // instantiate the device function registry container -STATIC_INSTANCE(std::vector, get_dev_fcn_regs) +UHD_SINGLETON_FCN(std::vector, get_dev_fcn_regs) void device::register_device( const discover_t &discover, @@ -136,7 +137,7 @@ device::sptr device::make(const device_addr_t &hint, size_t which){ return hash_to_device[dev_hash].lock(); } //create and register a new device - catch(const std::assert_error &){ + catch(const uhd::assert_error &){ device::sptr dev = maker(dev_addr); hash_to_device[dev_hash] = dev; return dev; diff --git a/host/lib/gain_handler.cpp b/host/lib/gain_handler.cpp index 7dd1547cb..7b3dd266c 100644 --- a/host/lib/gain_handler.cpp +++ b/host/lib/gain_handler.cpp @@ -16,7 +16,7 @@ // #include -#include +#include #include #include #include diff --git a/host/lib/load_modules.cpp b/host/lib/load_modules.cpp index 77426b898..babff1ca5 100644 --- a/host/lib/load_modules.cpp +++ b/host/lib/load_modules.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see . // -#include +#include #include #include #include @@ -101,7 +101,7 @@ static void load_path(const fs::path &path){ * Load all the modules given by the module path enviroment variable. * The path variable may be several paths split by path separators. */ -STATIC_BLOCK(load_modules){ +UHD_STATIC_BLOCK(load_modules){ //get the environment variable module path char *env_module_path = std::getenv("UHD_MODULE_PATH"); if (env_module_path == NULL) return; diff --git a/host/lib/simple_device.cpp b/host/lib/simple_device.cpp index a25cb12e0..0eb69d9fa 100644 --- a/host/lib/simple_device.cpp +++ b/host/lib/simple_device.cpp @@ -16,8 +16,8 @@ // #include -#include -#include +#include +#include #include #include #include diff --git a/host/lib/usrp/dboard/basic.cpp b/host/lib/usrp/dboard/basic.cpp index 849cbd764..07cb8d11c 100644 --- a/host/lib/usrp/dboard/basic.cpp +++ b/host/lib/usrp/dboard/basic.cpp @@ -15,9 +15,10 @@ // along with this program. If not, see . // -#include #include #include +#include +#include #include #include #include @@ -74,7 +75,7 @@ static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t const& args){ return dboard_base::sptr(new basic_tx(args, 32e6)); } -STATIC_BLOCK(reg_dboards){ +UHD_STATIC_BLOCK(reg_dboards){ dboard_manager::register_dboard(0x0000, &make_basic_tx, "Basic TX"); dboard_manager::register_dboard(0x0001, &make_basic_rx, "Basic RX", list_of("ab")("a")("b")); dboard_manager::register_dboard(0x000e, &make_lf_tx, "LF TX"); diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index 6683534f1..0f2189cd1 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -17,7 +17,8 @@ #include #include -#include +#include +#include #include #include #include @@ -35,7 +36,7 @@ typedef boost::tuple a //map a dboard id to a dboard constructor typedef uhd::dict id_to_args_map_t; -STATIC_INSTANCE(id_to_args_map_t, get_id_to_args_map) +UHD_SINGLETON_FCN(id_to_args_map_t, get_id_to_args_map) void dboard_manager::register_dboard( dboard_id_t dboard_id, diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 66e02d469..6b49ff29d 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see . // -#include +#include #include #include "usrp2_impl.hpp" diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp index d20465147..8fc7864b0 100644 --- a/host/lib/usrp/usrp2/dboard_interface.cpp +++ b/host/lib/usrp/usrp2/dboard_interface.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see . // -#include +#include #include "usrp2_impl.hpp" using namespace uhd::usrp; diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 44f654863..654096d14 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see . // -#include +#include #include #include #include diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index c56782c4b..e4706dcf0 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see . // -#include +#include #include "usrp2_impl.hpp" using namespace uhd; diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 35a4aeb20..9dce351be 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -16,7 +16,8 @@ // #include -#include +#include +#include #include #include #include @@ -28,7 +29,7 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace asio = boost::asio; -STATIC_BLOCK(register_usrp2_device){ +UHD_STATIC_BLOCK(register_usrp2_device){ device::register_device(&usrp2::discover, &usrp2::make); } diff --git a/host/test/module_test.cpp b/host/test/module_test.cpp index 71721ef90..47a0e1af9 100644 --- a/host/test/module_test.cpp +++ b/host/test/module_test.cpp @@ -15,10 +15,10 @@ // along with this program. If not, see . // -#include +#include #include -STATIC_BLOCK(module_test){ +UHD_STATIC_BLOCK(module_test){ std::cout << "---------------------------------------" << std::endl; std::cout << "-- Good news, everyone!" << std::endl; std::cout << "-- The test module has been loaded." << std::endl; diff --git a/host/utils/discover_usrps.cpp b/host/utils/discover_usrps.cpp index d670d1651..dc2b845bc 100644 --- a/host/utils/discover_usrps.cpp +++ b/host/utils/discover_usrps.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include #include #include #include @@ -23,7 +24,7 @@ namespace po = boost::program_options; -int main(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char *argv[]){ po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") diff --git a/host/utils/usrp2_burner.cpp b/host/utils/usrp2_burner.cpp index 941e71d0c..ff6d4426f 100644 --- a/host/utils/usrp2_burner.cpp +++ b/host/utils/usrp2_burner.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include #include #include #include @@ -23,7 +24,7 @@ namespace po = boost::program_options; -int main(int argc, char *argv[]){ +int UHD_SAFE_MAIN(int argc, char *argv[]){ po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") -- cgit v1.2.3 From 281307833c8275031bd2469e6aef3f472490749a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 30 Mar 2010 15:11:23 -0700 Subject: use find to discover devices --- host/include/uhd/device.hpp | 14 +++---- host/include/uhd/usrp/usrp1e.hpp | 5 +-- host/include/uhd/usrp/usrp2.hpp | 5 +-- host/lib/device.cpp | 8 ++-- host/lib/usrp/usrp1e/usrp1e_none.cpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.cpp | 7 ++-- host/utils/CMakeLists.txt | 6 +-- host/utils/discover_usrps.cpp | 71 ------------------------------------ host/utils/uhd_find_devices.cpp | 71 ++++++++++++++++++++++++++++++++++++ 9 files changed, 93 insertions(+), 96 deletions(-) delete mode 100644 host/utils/discover_usrps.cpp create mode 100644 host/utils/uhd_find_devices.cpp (limited to 'host/lib/usrp/usrp2/usrp2_impl.cpp') diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp index 1d0360799..4d4196d98 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -38,22 +38,22 @@ class UHD_API device : boost::noncopyable, public wax::obj{ public: typedef boost::shared_ptr sptr; - typedef boost::function discover_t; + typedef boost::function find_t; typedef boost::function make_t; /*! * Register a device into the discovery and factory system. * - * \param discover a function that discovers devices + * \param find a function that discovers devices * \param make a factory function that makes a device */ static void register_device( - const discover_t &discover, + const find_t &find, const make_t &make ); /*! - * \brief Discover usrp devices attached to the host. + * \brief Find usrp devices attached to the host. * * The hint device address should be used to narrow down the search * to particular transport types and/or transport arguments. @@ -61,17 +61,17 @@ public: * \param hint a partially (or fully) filled in device address * \return a vector of device addresses for all usrps on the system */ - static device_addrs_t discover(const device_addr_t &hint); + static device_addrs_t find(const device_addr_t &hint); /*! * \brief Create a new usrp device from the device address hint. * - * The make routine will call discover and pick one of the results. + * The make routine will call find and pick one of the results. * By default, the first result will be used to create a new device. * Use the which parameter as an index into the list of results. * * \param hint a partially (or fully) filled in device address - * \param which which address to use when multiple are discovered + * \param which which address to use when multiple are found * \return a shared pointer to a new device instance */ static sptr make(const device_addr_t &hint, size_t which = 0); diff --git a/host/include/uhd/usrp/usrp1e.hpp b/host/include/uhd/usrp/usrp1e.hpp index 5cba4ef52..cee9dc3d5 100644 --- a/host/include/uhd/usrp/usrp1e.hpp +++ b/host/include/uhd/usrp/usrp1e.hpp @@ -29,12 +29,11 @@ namespace uhd{ namespace usrp{ class UHD_API usrp1e : public device{ public: /*! - * Discover usrp1e devices on the system via the device node. - * This static method will be called by the device::discover. + * Find usrp1e devices on the system via the device node. * \param hint a device addr with the usrp1e address filled in * \return a vector of device addresses for all usrp1es found */ - static device_addrs_t discover(const device_addr_t &hint); + static device_addrs_t find(const device_addr_t &hint); /*! * Make a usrp1e from a device address. diff --git a/host/include/uhd/usrp/usrp2.hpp b/host/include/uhd/usrp/usrp2.hpp index 277ddc131..613b40ae3 100644 --- a/host/include/uhd/usrp/usrp2.hpp +++ b/host/include/uhd/usrp/usrp2.hpp @@ -29,17 +29,16 @@ namespace uhd{ namespace usrp{ class UHD_API usrp2 : public device{ public: /*! - * Discover usrp2 devices over the ethernet. + * Find usrp2 devices over the ethernet. * * Recommended key/value pairs for the device hint address: * hint["addr"] = address, where address is a resolvable address * or ip address, which may or may not be a broadcast address. * - * This static method will be called by the device::discover. * \param hint a device addr with the usrp2 address filled in * \return a vector of device addresses for all usrp2s found */ - static device_addrs_t discover(const device_addr_t &hint); + static device_addrs_t find(const device_addr_t &hint); /*! * Make a usrp2 from a device address. diff --git a/host/lib/device.cpp b/host/lib/device.cpp index ca45d0795..27a365d34 100644 --- a/host/lib/device.cpp +++ b/host/lib/device.cpp @@ -57,23 +57,23 @@ static size_t hash_device_addr( /*********************************************************************** * Registration **********************************************************************/ -typedef boost::tuple dev_fcn_reg_t; +typedef boost::tuple dev_fcn_reg_t; // instantiate the device function registry container UHD_SINGLETON_FCN(std::vector, get_dev_fcn_regs) void device::register_device( - const discover_t &discover, + const find_t &find, const make_t &make ){ //std::cout << "registering device" << std::endl; - get_dev_fcn_regs().push_back(dev_fcn_reg_t(discover, make)); + get_dev_fcn_regs().push_back(dev_fcn_reg_t(find, make)); } /*********************************************************************** * Discover **********************************************************************/ -device_addrs_t device::discover(const device_addr_t &hint){ +device_addrs_t device::find(const device_addr_t &hint){ device_addrs_t device_addrs; BOOST_FOREACH(const dev_fcn_reg_t &fcn, get_dev_fcn_regs()){ diff --git a/host/lib/usrp/usrp1e/usrp1e_none.cpp b/host/lib/usrp/usrp1e/usrp1e_none.cpp index 1c8cf9a5b..84fb9276c 100644 --- a/host/lib/usrp/usrp1e/usrp1e_none.cpp +++ b/host/lib/usrp/usrp1e/usrp1e_none.cpp @@ -25,7 +25,7 @@ using namespace uhd::usrp; * when the required kernel module headers are not present. */ -device_addrs_t usrp1e::discover(const device_addr_t &){ +device_addrs_t usrp1e::find(const device_addr_t &){ return device_addrs_t(); //return empty list } diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 9dce351be..b0ee395fb 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -30,13 +30,13 @@ using namespace uhd::transport; namespace asio = boost::asio; UHD_STATIC_BLOCK(register_usrp2_device){ - device::register_device(&usrp2::discover, &usrp2::make); + device::register_device(&usrp2::find, &usrp2::make); } /*********************************************************************** * Discovery over the udp transport **********************************************************************/ -uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ +uhd::device_addrs_t usrp2::find(const device_addr_t &hint){ device_addrs_t usrp2_addrs; //if no address was specified, send a broadcast on each interface @@ -50,7 +50,7 @@ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ new_hint["addr"] = if_addrs.bcast; //call discover with the new hint and append results - device_addrs_t new_usrp2_addrs = usrp2::discover(new_hint); + device_addrs_t new_usrp2_addrs = usrp2::find(new_hint); usrp2_addrs.insert(usrp2_addrs.begin(), new_usrp2_addrs.begin(), new_usrp2_addrs.end() ); @@ -83,7 +83,6 @@ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ boost::asio::ip::address_v4 ip_addr(ntohl(ctrl_data_in.data.ip_addr)); device_addr_t new_addr; new_addr["name"] = "USRP2"; - new_addr["transport"] = "udp"; new_addr["addr"] = ip_addr.to_string(); usrp2_addrs.push_back(new_addr); //dont break here, it will exit the while loop diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index 1fb132937..aa01d1e35 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -15,9 +15,9 @@ # along with this program. If not, see . # -ADD_EXECUTABLE(discover_usrps discover_usrps.cpp) -TARGET_LINK_LIBRARIES(discover_usrps uhd) -INSTALL(TARGETS discover_usrps RUNTIME DESTINATION ${RUNTIME_DIR}) +ADD_EXECUTABLE(uhd_find_devices uhd_find_devices.cpp) +TARGET_LINK_LIBRARIES(uhd_find_devices uhd) +INSTALL(TARGETS uhd_find_devices RUNTIME DESTINATION ${RUNTIME_DIR}) ADD_EXECUTABLE(usrp2_burner usrp2_burner.cpp) TARGET_LINK_LIBRARIES(usrp2_burner uhd) diff --git a/host/utils/discover_usrps.cpp b/host/utils/discover_usrps.cpp deleted file mode 100644 index 72c5b8822..000000000 --- a/host/utils/discover_usrps.cpp +++ /dev/null @@ -1,71 +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 - -namespace po = boost::program_options; - -int UHD_SAFE_MAIN(int argc, char *argv[]){ - po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ("addr", po::value(), "resolvable network address") - ("node", po::value(), "path to linux device node") - ; - - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - - //print the help message - if (vm.count("help")){ - std::cout << boost::format("Discover USRPs %s") % desc << std::endl; - return ~0; - } - - //load the options into the address - uhd::device_addr_t device_addr; - if (vm.count("addr")){ - device_addr["addr"] = vm["addr"].as(); - } - if (vm.count("node")){ - device_addr["node"] = vm["node"].as(); - } - - //discover the usrps and print the results - uhd::device_addrs_t device_addrs = uhd::device::discover(device_addr); - - if (device_addrs.size() == 0){ - std::cerr << "No USRP Devices Found" << std::endl; - return ~0; - } - - for (size_t i = 0; i < device_addrs.size(); i++){ - std::cout << "--------------------------------------------------" << std::endl; - std::cout << "-- USRP Device " << i << std::endl; - std::cout << "--------------------------------------------------" << std::endl; - std::cout << device_addrs[i].to_string() << std::endl << std::endl; - uhd::device::make(device_addrs[i]); //test make - } - - return 0; -} diff --git a/host/utils/uhd_find_devices.cpp b/host/utils/uhd_find_devices.cpp new file mode 100644 index 000000000..b328216d0 --- /dev/null +++ b/host/utils/uhd_find_devices.cpp @@ -0,0 +1,71 @@ +// +// 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 + +namespace po = boost::program_options; + +int UHD_SAFE_MAIN(int argc, char *argv[]){ + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("addr", po::value(), "resolvable network address") + ("node", po::value(), "path to linux device node") + ; + + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout << boost::format("UHD Find Devices %s") % desc << std::endl; + return ~0; + } + + //load the options into the address + uhd::device_addr_t device_addr; + if (vm.count("addr")){ + device_addr["addr"] = vm["addr"].as(); + } + if (vm.count("node")){ + device_addr["node"] = vm["node"].as(); + } + + //discover the usrps and print the results + uhd::device_addrs_t device_addrs = uhd::device::find(device_addr); + + if (device_addrs.size() == 0){ + std::cerr << "No UHD Devices Found" << std::endl; + return ~0; + } + + for (size_t i = 0; i < device_addrs.size(); i++){ + std::cout << "--------------------------------------------------" << std::endl; + std::cout << "-- UHD Device " << i << std::endl; + std::cout << "--------------------------------------------------" << std::endl; + std::cout << device_addrs[i].to_string() << std::endl << std::endl; + uhd::device::make(device_addrs[i]); //test make + } + + return 0; +} -- cgit v1.2.3 From c81a975766a8831cab1e3123af94b4fe4a09d9bc Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 30 Mar 2010 14:12:11 +0000 Subject: compiling with master merge, renamed usrp1e to usrp_e --- host/apps/usrp1e_load_fpga.cpp | 47 ------ host/include/uhd/usrp/CMakeLists.txt | 2 +- host/include/uhd/usrp/usrp1e.hpp | 54 ------ host/include/uhd/usrp/usrp_e.hpp | 54 ++++++ host/lib/CMakeLists.txt | 20 ++- host/lib/usrp/usrp1e/dboard_impl.cpp | 76 --------- host/lib/usrp/usrp1e/dboard_interface.cpp | 189 --------------------- host/lib/usrp/usrp1e/dsp_impl.cpp | 70 -------- host/lib/usrp/usrp1e/fpga-downloader.cc | 262 ------------------------------ host/lib/usrp/usrp1e/mboard_impl.cpp | 46 ------ host/lib/usrp/usrp1e/usrp1e_impl.cpp | 178 -------------------- host/lib/usrp/usrp1e/usrp1e_impl.hpp | 135 --------------- host/lib/usrp/usrp1e/usrp1e_none.cpp | 38 ----- host/lib/usrp/usrp2/usrp2_impl.cpp | 2 +- host/lib/usrp/usrp_e/dboard_impl.cpp | 76 +++++++++ host/lib/usrp/usrp_e/dboard_interface.cpp | 189 +++++++++++++++++++++ host/lib/usrp/usrp_e/dsp_impl.cpp | 69 ++++++++ host/lib/usrp/usrp_e/fpga-downloader.cc | 262 ++++++++++++++++++++++++++++++ host/lib/usrp/usrp_e/mboard_impl.cpp | 45 +++++ host/lib/usrp/usrp_e/usrp_e_impl.cpp | 179 ++++++++++++++++++++ host/lib/usrp/usrp_e/usrp_e_impl.hpp | 135 +++++++++++++++ host/lib/usrp/usrp_e/usrp_e_none.cpp | 38 +++++ host/utils/CMakeLists.txt | 5 +- host/utils/usrp_e_load_fpga.cpp | 47 ++++++ 24 files changed, 1110 insertions(+), 1108 deletions(-) delete mode 100644 host/apps/usrp1e_load_fpga.cpp delete mode 100644 host/include/uhd/usrp/usrp1e.hpp create mode 100644 host/include/uhd/usrp/usrp_e.hpp delete mode 100644 host/lib/usrp/usrp1e/dboard_impl.cpp delete mode 100644 host/lib/usrp/usrp1e/dboard_interface.cpp delete mode 100644 host/lib/usrp/usrp1e/dsp_impl.cpp delete mode 100644 host/lib/usrp/usrp1e/fpga-downloader.cc delete mode 100644 host/lib/usrp/usrp1e/mboard_impl.cpp delete mode 100644 host/lib/usrp/usrp1e/usrp1e_impl.cpp delete mode 100644 host/lib/usrp/usrp1e/usrp1e_impl.hpp delete mode 100644 host/lib/usrp/usrp1e/usrp1e_none.cpp create mode 100644 host/lib/usrp/usrp_e/dboard_impl.cpp create mode 100644 host/lib/usrp/usrp_e/dboard_interface.cpp create mode 100644 host/lib/usrp/usrp_e/dsp_impl.cpp create mode 100644 host/lib/usrp/usrp_e/fpga-downloader.cc create mode 100644 host/lib/usrp/usrp_e/mboard_impl.cpp create mode 100644 host/lib/usrp/usrp_e/usrp_e_impl.cpp create mode 100644 host/lib/usrp/usrp_e/usrp_e_impl.hpp create mode 100644 host/lib/usrp/usrp_e/usrp_e_none.cpp create mode 100644 host/utils/usrp_e_load_fpga.cpp (limited to 'host/lib/usrp/usrp2/usrp2_impl.cpp') diff --git a/host/apps/usrp1e_load_fpga.cpp b/host/apps/usrp1e_load_fpga.cpp deleted file mode 100644 index d5960b391..000000000 --- a/host/apps/usrp1e_load_fpga.cpp +++ /dev/null @@ -1,47 +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 - -namespace po = boost::program_options; - -int main(int argc, char *argv[]){ - po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ("file", po::value(), "path to fpga bin file") - ; - - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - - //print the help message - if (vm.count("help") or vm.count("file") == 0){ - std::cout << boost::format("USRP1E Load FPGA %s") % desc << std::endl; - return ~0; - } - - //load the fpga - std::string file = vm["file"].as(); - uhd::usrp::usrp1e::load_fpga(file); - - return 0; -} diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt index bab01fdeb..b9be370bd 100644 --- a/host/include/uhd/usrp/CMakeLists.txt +++ b/host/include/uhd/usrp/CMakeLists.txt @@ -21,7 +21,7 @@ INSTALL(FILES dboard_id.hpp dboard_interface.hpp dboard_manager.hpp - usrp1e.hpp + usrp_e.hpp usrp2.hpp DESTINATION ${INCLUDE_DIR}/uhd/usrp ) diff --git a/host/include/uhd/usrp/usrp1e.hpp b/host/include/uhd/usrp/usrp1e.hpp deleted file mode 100644 index 75da58453..000000000 --- a/host/include/uhd/usrp/usrp1e.hpp +++ /dev/null @@ -1,54 +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_USRP_USRP1E_HPP -#define INCLUDED_UHD_USRP_USRP1E_HPP - -#include -#include - -namespace uhd{ namespace usrp{ - -/*! - * The usrp1e device class. - */ -class UHD_API usrp1e : public device{ -public: - /*! - * Find usrp1e devices on the system via the device node. - * \param hint a device addr with the usrp1e address filled in - * \return a vector of device addresses for all usrp1es found - */ - static device_addrs_t find(const device_addr_t &hint); - - /*! - * Make a usrp1e from a device address. - * \param addr the device address - * \return a device sptr to a new usrp1e - */ - static device::sptr make(const device_addr_t &addr); - - /*! - * Load the FPGA with an image file. - * \param bin_file the name of the fpga image file - */ - static void load_fpga(const std::string &bin_file); -}; - -}} //namespace - -#endif /* INCLUDED_UHD_USRP_USRP1E_HPP */ diff --git a/host/include/uhd/usrp/usrp_e.hpp b/host/include/uhd/usrp/usrp_e.hpp new file mode 100644 index 000000000..557058261 --- /dev/null +++ b/host/include/uhd/usrp/usrp_e.hpp @@ -0,0 +1,54 @@ +// +// 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_USRP_USRP_E_HPP +#define INCLUDED_UHD_USRP_USRP_E_HPP + +#include +#include + +namespace uhd{ namespace usrp{ + +/*! + * The USRP-Embedded device class. + */ +class UHD_API usrp_e : public device{ +public: + /*! + * Find usrp_e devices on the system via the device node. + * \param hint a device addr with the usrp_e address filled in + * \return a vector of device addresses for all usrp-e's found + */ + static device_addrs_t find(const device_addr_t &hint); + + /*! + * Make a usrp_e from a device address. + * \param addr the device address + * \return a device sptr to a new usrp_e + */ + static device::sptr make(const device_addr_t &addr); + + /*! + * Load the FPGA with an image file. + * \param bin_file the name of the fpga image file + */ + static void load_fpga(const std::string &bin_file); +}; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_USRP_E_HPP */ diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 323b69b14..db5e9d273 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -51,6 +51,8 @@ LIST(APPEND libuhd_sources ######################################################################## # Conditionally add the usrp1e sources ######################################################################## +MESSAGE(STATUS "Configuring usrp-e support...") + INCLUDE(CheckIncludeFiles) SET(usrp1e_required_headers linux/ioctl.h @@ -63,19 +65,19 @@ CHECK_INCLUDE_FILES( ) IF(HAS_USRP1E_REQUIRED_HEADERS) - MESSAGE(STATUS "Building usrp1e support...") + MESSAGE(STATUS " Building usrp1e support.") LIST(APPEND libuhd_sources - usrp/usrp1e/dboard_impl.cpp - usrp/usrp1e/dboard_interface.cpp - usrp/usrp1e/dsp_impl.cpp - usrp/usrp1e/fpga-downloader.cc - usrp/usrp1e/mboard_impl.cpp - usrp/usrp1e/usrp1e_impl.cpp + usrp/usrp_e/dboard_impl.cpp + usrp/usrp_e/dboard_interface.cpp + usrp/usrp_e/dsp_impl.cpp + usrp/usrp_e/fpga-downloader.cc + usrp/usrp_e/mboard_impl.cpp + usrp/usrp_e/usrp_e_impl.cpp ) ELSE(HAS_USRP1E_REQUIRED_HEADERS) - MESSAGE(STATUS "Skipping usrp1e support...") + MESSAGE(STATUS " Skipping usrp1e support.") LIST(APPEND libuhd_sources - usrp/usrp1e/usrp1e_none.cpp + usrp/usrp_e/usrp_e_none.cpp ) ENDIF(HAS_USRP1E_REQUIRED_HEADERS) diff --git a/host/lib/usrp/usrp1e/dboard_impl.cpp b/host/lib/usrp/usrp1e/dboard_impl.cpp deleted file mode 100644 index a2798dce3..000000000 --- a/host/lib/usrp/usrp1e/dboard_impl.cpp +++ /dev/null @@ -1,76 +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 "usrp1e_impl.hpp" - -using namespace uhd::usrp; - -/*********************************************************************** - * Dboard Initialization - **********************************************************************/ -void usrp1e_impl::dboard_init(void){ - dboard_id_t rx_dboard_id = dboard_id::NONE; //TODO get these from the eeprom - dboard_id_t tx_dboard_id = dboard_id::NONE; - - //create a new dboard interface and manager - dboard_interface::sptr dboard_interface( - make_usrp1e_dboard_interface(this) - ); - _dboard_manager = dboard_manager::make( - rx_dboard_id, tx_dboard_id, dboard_interface - ); - - //setup the dboard proxies - _rx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::rx_dboard_get, this, _1, _2), - boost::bind(&usrp1e_impl::rx_dboard_set, this, _1, _2) - ); - _tx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::tx_dboard_get, this, _1, _2), - boost::bind(&usrp1e_impl::tx_dboard_set, this, _1, _2) - ); -} - -/*********************************************************************** - * RX Dboard Get - **********************************************************************/ -void usrp1e_impl::rx_dboard_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * RX Dboard Set - **********************************************************************/ -void usrp1e_impl::rx_dboard_set(const wax::obj &, const wax::obj &){ - -} - -/*********************************************************************** - * TX Dboard Get - **********************************************************************/ -void usrp1e_impl::tx_dboard_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * TX Dboard Set - **********************************************************************/ -void usrp1e_impl::tx_dboard_set(const wax::obj &, const wax::obj &){ - -} diff --git a/host/lib/usrp/usrp1e/dboard_interface.cpp b/host/lib/usrp/usrp1e/dboard_interface.cpp deleted file mode 100644 index ef91014ac..000000000 --- a/host/lib/usrp/usrp1e/dboard_interface.cpp +++ /dev/null @@ -1,189 +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 //std::copy -#include "usrp1e_impl.hpp" -#include - -using namespace uhd::usrp; - -class usrp1e_dboard_interface : public dboard_interface{ -public: - usrp1e_dboard_interface(usrp1e_impl *impl); - ~usrp1e_dboard_interface(void); - - void write_aux_dac(unit_type_t, int, int); - int read_aux_adc(unit_type_t, int); - - void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t); - void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t); - void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t); - boost::uint16_t read_gpio(gpio_bank_t); - - void write_i2c(int, const byte_vector_t &); - byte_vector_t read_i2c(int, size_t); - - double get_rx_clock_rate(void); - double get_tx_clock_rate(void); - -private: - byte_vector_t transact_spi( - spi_dev_t dev, - spi_latch_t latch, - spi_push_t push, - const byte_vector_t &buf, - bool readback - ); - - usrp1e_impl *_impl; -}; - -/*********************************************************************** - * Make Function - **********************************************************************/ -dboard_interface::sptr make_usrp1e_dboard_interface(usrp1e_impl *impl){ - return dboard_interface::sptr(new usrp1e_dboard_interface(impl)); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -usrp1e_dboard_interface::usrp1e_dboard_interface(usrp1e_impl *impl){ - _impl = impl; -} - -usrp1e_dboard_interface::~usrp1e_dboard_interface(void){ - /* NOP */ -} - -/*********************************************************************** - * Clock Rates - **********************************************************************/ -double usrp1e_dboard_interface::get_rx_clock_rate(void){ - throw std::runtime_error("not implemented"); -} - -double usrp1e_dboard_interface::get_tx_clock_rate(void){ - throw std::runtime_error("not implemented"); -} - -/*********************************************************************** - * GPIO - **********************************************************************/ -void usrp1e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); -} - -void usrp1e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); -} - -boost::uint16_t usrp1e_dboard_interface::read_gpio(gpio_bank_t bank){ - throw std::runtime_error("not implemented"); -} - -void usrp1e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); -} - -/*********************************************************************** - * SPI - **********************************************************************/ -dboard_interface::byte_vector_t usrp1e_dboard_interface::transact_spi( - spi_dev_t dev, - spi_latch_t latch, - spi_push_t push, - const byte_vector_t &buf, - bool readback -){ - //load data struct - usrp_e_spi data; - data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; - data.slave = (dev == SPI_RX_DEV)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG; - data.length = buf.size() * 8; //bytes to bits - boost::uint8_t *data_bytes = reinterpret_cast(&data.data); - - //load the data - ASSERT_THROW(buf.size() <= sizeof(data.data)); - std::copy(buf.begin(), buf.end(), data_bytes); - - //load the flags - data.flags = 0; - data.flags |= (latch == SPI_LATCH_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; - data.flags |= (push == SPI_PUSH_RISE)? UE_SPI_PUSH_RISE : UE_SPI_PUSH_FALL; - - //call the spi ioctl - _impl->ioctl(USRP_E_SPI, &data); - - //unload the data - byte_vector_t ret(data.length/8); //bits to bytes - ASSERT_THROW(ret.size() <= sizeof(data.data)); - std::copy(data_bytes, data_bytes+ret.size(), ret.begin()); - return ret; -} - -/*********************************************************************** - * I2C - **********************************************************************/ -static const size_t max_i2c_data_bytes = 10; - -void usrp1e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ - //allocate some memory for this transaction - ASSERT_THROW(buf.size() <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = i2c_addr; - data.len = buf.size(); - std::copy(buf.begin(), buf.end(), data.data); - - //call the spi ioctl - _impl->ioctl(USRP_E_I2C_WRITE, &data); -} - -dboard_interface::byte_vector_t usrp1e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ - //allocate some memory for this transaction - ASSERT_THROW(num_bytes <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c &data = reinterpret_cast(mem); - data.addr = i2c_addr; - data.len = num_bytes; - - //call the spi ioctl - _impl->ioctl(USRP_E_I2C_READ, &data); - - //unload the data - byte_vector_t ret(data.len); - ASSERT_THROW(ret.size() == num_bytes); - std::copy(data.data, data.data+ret.size(), ret.begin()); - return ret; -} - -/*********************************************************************** - * Aux DAX/ADC - **********************************************************************/ -void usrp1e_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ - throw std::runtime_error("not implemented"); -} - -int usrp1e_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ - throw std::runtime_error("not implemented"); -} diff --git a/host/lib/usrp/usrp1e/dsp_impl.cpp b/host/lib/usrp/usrp1e/dsp_impl.cpp deleted file mode 100644 index 862b89184..000000000 --- a/host/lib/usrp/usrp1e/dsp_impl.cpp +++ /dev/null @@ -1,70 +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 "usrp1e_impl.hpp" - -using namespace uhd::usrp; - -/*********************************************************************** - * RX DDC Initialization - **********************************************************************/ -void usrp1e_impl::rx_ddc_init(void){ - _rx_ddc_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::rx_ddc_get, this, _1, _2), - boost::bind(&usrp1e_impl::rx_ddc_set, this, _1, _2) - ); -} - -/*********************************************************************** - * RX DDC Get - **********************************************************************/ -void usrp1e_impl::rx_ddc_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * RX DDC Set - **********************************************************************/ -void usrp1e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ - -} - -/*********************************************************************** - * TX DUC Initialization - **********************************************************************/ -void usrp1e_impl::tx_duc_init(void){ - _tx_duc_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::tx_duc_get, this, _1, _2), - boost::bind(&usrp1e_impl::tx_duc_set, this, _1, _2) - ); -} - -/*********************************************************************** - * TX DUC Get - **********************************************************************/ -void usrp1e_impl::tx_duc_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * TX DUC Set - **********************************************************************/ -void usrp1e_impl::tx_duc_set(const wax::obj &, const wax::obj &){ - -} diff --git a/host/lib/usrp/usrp1e/fpga-downloader.cc b/host/lib/usrp/usrp1e/fpga-downloader.cc deleted file mode 100644 index f7c78b875..000000000 --- a/host/lib/usrp/usrp1e/fpga-downloader.cc +++ /dev/null @@ -1,262 +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 -#include -#include - -#include - -/* - * Configuration connections - * - * CCK - MCSPI1_CLK - * DIN - MCSPI1_MOSI - * PROG_B - GPIO_175 - output (change mux) - * DONE - GPIO_173 - input (change mux) - * INIT_B - GPIO_114 - input (change mux) - * -*/ - -const unsigned int PROG_B = 175; -const unsigned int DONE = 173; -const unsigned int INIT_B = 114; - -//static std::string bit_file = "safe_u1e.bin"; - -const int BUF_SIZE = 4096; - -enum gpio_direction {IN, OUT}; - -class gpio { - public: - - gpio(unsigned int gpio_num, gpio_direction pin_direction); - - bool get_value(); - void set_value(bool state); - - private: - - std::stringstream base_path; - std::fstream value_file; -}; - -class spidev { - public: - - spidev(std::string dev_name); - ~spidev(); - - void send(char *wbuf, char *rbuf, unsigned int nbytes); - - private: - - int fd; - -}; - -gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction) -{ - std::fstream export_file; - - export_file.open("/sys/class/gpio/export", std::ios::out); - if (!export_file.is_open()) ///\todo Poor error handling - std::cout << "Failed to open gpio export file." << std::endl; - - export_file << gpio_num << std::endl; - - base_path << "/sys/class/gpio/gpio" << gpio_num << std::flush; - - std::fstream direction_file; - std::string direction_file_name; - - direction_file_name = base_path.str() + "/direction"; - - direction_file.open(direction_file_name.c_str()); - if (!direction_file.is_open()) - std::cout << "Failed to open direction file." << std::endl; - if (pin_direction == OUT) - direction_file << "out" << std::endl; - else - direction_file << "in" << std::endl; - - std::string value_file_name; - - value_file_name = base_path.str() + "/value"; - - value_file.open(value_file_name.c_str(), std::ios_base::in | std::ios_base::out); - if (!value_file.is_open()) - std::cout << "Failed to open value file." << std::endl; -} - -bool gpio::get_value() -{ - - std::string val; - - std::getline(value_file, val); - value_file.seekg(0); - - if (val == "0") - return false; - else if (val == "1") - return true; - else - std::cout << "Data read from value file|" << val << "|" << std::endl; - - return false; -} - -void gpio::set_value(bool state) -{ - - if (state) - value_file << "1" << std::endl; - else - value_file << "0" << std::endl; -} - -static void prepare_fpga_for_configuration(gpio &prog, gpio &)//init) -{ - - prog.set_value(true); - prog.set_value(false); - prog.set_value(true); - -#if 0 - bool ready_to_program(false); - unsigned int count(0); - do { - ready_to_program = init.get_value(); - count++; - - sleep(1); - } while (count < 10 && !ready_to_program); - - if (count == 10) { - std::cout << "FPGA not ready for programming." << std::endl; - exit(-1); - } -#endif -} - -spidev::spidev(std::string fname) -{ - int ret; - int mode = 0; - int speed = 12000000; - int bits = 8; - - fd = open(fname.c_str(), O_RDWR); - - ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); - ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); - ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); -} - - -spidev::~spidev() -{ - close(fd); -} - -void spidev::send(char *buf, char *rbuf, unsigned int nbytes) -{ - int ret; - - struct spi_ioc_transfer tr; - tr.tx_buf = (unsigned long) buf; - tr.rx_buf = (unsigned long) rbuf; - tr.len = nbytes; - tr.delay_usecs = 0; - tr.speed_hz = 48000000; - tr.bits_per_word = 8; - - ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); - -} - -static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &done) -{ - std::ifstream bitstream; - - std::cout << "File name - " << file_name.c_str() << std::endl; - - bitstream.open(file_name.c_str(), std::ios::binary); - if (!bitstream.is_open()) - std::cout << "File " << file_name << " not opened succesfully." << std::endl; - - spidev spi("/dev/spidev1.0"); - char buf[BUF_SIZE]; - char rbuf[BUF_SIZE]; - - do { - bitstream.read(buf, BUF_SIZE); - spi.send(buf, rbuf, bitstream.gcount()); - - if (error.get_value()) - std::cout << "INIT_B went high, error occured." << std::endl; - - if (!done.get_value()) - std::cout << "Configuration complete." << std::endl; - - } while (bitstream.gcount() == BUF_SIZE); -} - -/* -int main(int argc, char *argv[]) -{ - - gpio gpio_prog_b(PROG_B, OUT); - gpio gpio_init_b(INIT_B, IN); - gpio gpio_done (DONE, IN); - - if (argc == 2) - bit_file = argv[1]; - - std::cout << "FPGA config file: " << bit_file << std::endl; - - prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); - - std::cout << "Done = " << gpio_done.get_value() << std::endl; - - send_file_to_fpga(bit_file, gpio_init_b, gpio_done); -} -*/ - -#include -void uhd::usrp::usrp1e::load_fpga(const std::string &bin_file){ - gpio gpio_prog_b(PROG_B, OUT); - gpio gpio_init_b(INIT_B, IN); - gpio gpio_done (DONE, IN); - - std::cout << "FPGA config file: " << bin_file << std::endl; - - prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); - - std::cout << "Done = " << gpio_done.get_value() << std::endl; - - send_file_to_fpga(bin_file, gpio_init_b, gpio_done); -} diff --git a/host/lib/usrp/usrp1e/mboard_impl.cpp b/host/lib/usrp/usrp1e/mboard_impl.cpp deleted file mode 100644 index b480f7616..000000000 --- a/host/lib/usrp/usrp1e/mboard_impl.cpp +++ /dev/null @@ -1,46 +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 "usrp1e_impl.hpp" - -using namespace uhd::usrp; - -/*********************************************************************** - * Mboard Initialization - **********************************************************************/ -void usrp1e_impl::mboard_init(void){ - _mboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp1e_impl::mboard_get, this, _1, _2), - boost::bind(&usrp1e_impl::mboard_set, this, _1, _2) - ); -} - -/*********************************************************************** - * Mboard Get - **********************************************************************/ -void usrp1e_impl::mboard_get(const wax::obj &, wax::obj &){ - -} - -/*********************************************************************** - * Mboard Set - **********************************************************************/ -void usrp1e_impl::mboard_set(const wax::obj &, const wax::obj &){ - -} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.cpp b/host/lib/usrp/usrp1e/usrp1e_impl.cpp deleted file mode 100644 index 8230cc8e4..000000000 --- a/host/lib/usrp/usrp1e/usrp1e_impl.cpp +++ /dev/null @@ -1,178 +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 "usrp1e_impl.hpp" -#include //open -#include //ioctl - -using namespace uhd; -using namespace uhd::usrp; -namespace fs = boost::filesystem; - -STATIC_BLOCK(register_usrp1e_device){ - device::register_device(&usrp1e::discover, &usrp1e::make); -} - -/*********************************************************************** - * Helper Functions - **********************************************************************/ -static std::string abs_path(const std::string &file_path){ - return fs::system_complete(fs::path(file_path)).file_string(); -} - -/*********************************************************************** - * Discovery - **********************************************************************/ -device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ - device_addrs_t usrp1e_addrs; - - //if a node was provided, use it and only it - if (device_addr.has_key("node")){ - if (not fs::exists(device_addr["node"])) return usrp1e_addrs; - device_addr_t new_addr; - new_addr["name"] = "USRP1E"; - new_addr["node"] = abs_path(device_addr["node"]); - usrp1e_addrs.push_back(new_addr); - } - - //otherwise look for a few nodes at small indexes - else{ - for(size_t i = 0; i < 5; i++){ - std::string node = str(boost::format("/dev/usrp1_e%d") % i); - if (not fs::exists(node)) continue; - device_addr_t new_addr; - new_addr["name"] = "USRP1E"; - new_addr["node"] = abs_path(node); - usrp1e_addrs.push_back(new_addr); - } - } - - return usrp1e_addrs; -} - -/*********************************************************************** - * Make - **********************************************************************/ -device::sptr usrp1e::make(const device_addr_t &device_addr){ - return sptr(new usrp1e_impl(device_addr["node"])); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -usrp1e_impl::usrp1e_impl(const std::string &node){ - //open the device node and check file descriptor - if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ - throw std::runtime_error(str( - boost::format("Failed to open %s") % node - )); - } - - //initialize the mboard - mboard_init(); - - //initialize the dboards - dboard_init(); - - //initialize the dsps - rx_ddc_init(); - tx_duc_init(); -} - -usrp1e_impl::~usrp1e_impl(void){ - //close the device node file descriptor - ::close(_node_fd); -} - -/*********************************************************************** - * Misc Methods - **********************************************************************/ -void usrp1e_impl::ioctl(int request, void *mem){ - if (::ioctl(_node_fd, request, mem) < 0){ - throw std::runtime_error(str( - boost::format("ioctl failed with request %d") % request - )); - } -} - -/*********************************************************************** - * Device Get - **********************************************************************/ -void usrp1e_impl::get(const wax::obj &key_, wax::obj &val){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); - - //handle the get request conditioned on the key - switch(key.as()){ - case DEVICE_PROP_NAME: - val = std::string("usrp1e device"); - return; - - case DEVICE_PROP_MBOARD: - ASSERT_THROW(name == ""); - val = _mboard_proxy->get_link(); - return; - - case DEVICE_PROP_MBOARD_NAMES: - val = prop_names_t(1, ""); //vector of size 1 with empty string - return; - - case DEVICE_PROP_MAX_RX_SAMPLES: - val = size_t(_max_num_samples); - return; - - case DEVICE_PROP_MAX_TX_SAMPLES: - val = size_t(_max_num_samples); - return; - - } -} - -/*********************************************************************** - * Device Set - **********************************************************************/ -void usrp1e_impl::set(const wax::obj &, const wax::obj &){ - throw std::runtime_error("Cannot set in usrp1e device"); -} - -/*********************************************************************** - * Device IO (TODO) - **********************************************************************/ -size_t usrp1e_impl::send( - const boost::asio::const_buffer &, - const uhd::tx_metadata_t &, - const std::string &type -){ - if (type != "16sc"){ - throw std::runtime_error(str(boost::format("usrp1e send: cannot handle type \"%s\"") % type)); - } - return 0; -} - -size_t usrp1e_impl::recv( - const boost::asio::mutable_buffer &, - uhd::rx_metadata_t &, - const std::string &type -){ - if (type != "16sc"){ - throw std::runtime_error(str(boost::format("usrp1e recv: cannot handle type \"%s\"") % type)); - } - return 0; -} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.hpp b/host/lib/usrp/usrp1e/usrp1e_impl.hpp deleted file mode 100644 index c199a0465..000000000 --- a/host/lib/usrp/usrp1e/usrp1e_impl.hpp +++ /dev/null @@ -1,135 +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 - -#ifndef INCLUDED_USRP1E_IMPL_HPP -#define INCLUDED_USRP1E_IMPL_HPP - -class usrp1e_impl; // dummy class declaration - -/*! - * Make a usrp1e dboard interface. - * \param impl a pointer to the usrp1e impl object - * \return a sptr to a new dboard interface - */ -uhd::usrp::dboard_interface::sptr make_usrp1e_dboard_interface(usrp1e_impl *impl); - -/*! - * Simple wax obj proxy class: - * Provides a wax obj interface for a set and a get function. - * This allows us to create nested properties structures - * while maintaining flattened code within the implementation. - */ -class wax_obj_proxy : public wax::obj{ -public: - typedef boost::function get_t; - typedef boost::function set_t; - typedef boost::shared_ptr sptr; - - static sptr make(const get_t &get, const set_t &set){ - return sptr(new wax_obj_proxy(get, set)); - } - - ~wax_obj_proxy(void){ - /* NOP */ - } - -private: - get_t _get; - set_t _set; - - wax_obj_proxy(const get_t &get, const set_t &set){ - _get = get; - _set = set; - }; - - void get(const wax::obj &key, wax::obj &val){ - return _get(key, val); - } - - void set(const wax::obj &key, const wax::obj &val){ - return _set(key, val); - } -}; - -/*! - * USRP1E implementation guts: - * The implementation details are encapsulated here. - * Handles properties on the mboard, dboard, dsps... - */ -class usrp1e_impl : public uhd::device{ -public: - //structors - usrp1e_impl(const std::string &node); - ~usrp1e_impl(void); - - //the io interface - size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &); - size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &); - - /*! - * Perform an ioctl call on the device node file descriptor. - * This will throw when the internal ioctl call fails. - * \param request the control word - * \param mem pointer to some memory - */ - void ioctl(int request, void *mem); - -private: - static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); - int _node_fd; - - //device functions and settings - void get(const wax::obj &, wax::obj &); - void set(const wax::obj &, const wax::obj &); - - //mboard functions and settings - void mboard_init(void); - void mboard_get(const wax::obj &, wax::obj &); - void mboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _mboard_proxy; - - //xx dboard functions and settings - void dboard_init(void); - uhd::usrp::dboard_manager::sptr _dboard_manager; - - //rx dboard functions and settings - void rx_dboard_get(const wax::obj &, wax::obj &); - void rx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_dboard_proxy; - - //tx dboard functions and settings - void tx_dboard_get(const wax::obj &, wax::obj &); - void tx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _tx_dboard_proxy; - - //rx ddc functions and settings - void rx_ddc_init(void); - void rx_ddc_get(const wax::obj &, wax::obj &); - void rx_ddc_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_ddc_proxy; - - //tx duc functions and settings - void tx_duc_init(void); - void tx_duc_get(const wax::obj &, wax::obj &); - void tx_duc_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _tx_duc_proxy; -}; - -#endif /* INCLUDED_USRP1E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp1e/usrp1e_none.cpp b/host/lib/usrp/usrp1e/usrp1e_none.cpp deleted file mode 100644 index 94243523d..000000000 --- a/host/lib/usrp/usrp1e/usrp1e_none.cpp +++ /dev/null @@ -1,38 +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; -using namespace uhd::usrp; - -/*! - * This file defines the usrp1e discover and make functions - * when the required kernel module headers are not present. - */ - -device_addrs_t usrp1e::find(const device_addr_t &){ - return device_addrs_t(); //return empty list -} - -device::sptr usrp1e::make(const device_addr_t &){ - throw std::runtime_error("this build has no usrp1e support"); -} - -void usrp1e::load_fpga(const std::string &){ - throw std::runtime_error("this build has no usrp1e support"); -} diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 67fbdf8d2..b0ee395fb 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -29,7 +29,7 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace asio = boost::asio; -STATIC_BLOCK(register_usrp2_device){ +UHD_STATIC_BLOCK(register_usrp2_device){ device::register_device(&usrp2::find, &usrp2::make); } diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp new file mode 100644 index 000000000..88d04ce7a --- /dev/null +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -0,0 +1,76 @@ +// +// 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 "usrp_e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * Dboard Initialization + **********************************************************************/ +void usrp_e_impl::dboard_init(void){ + dboard_id_t rx_dboard_id = dboard_id::NONE; //TODO get these from the eeprom + dboard_id_t tx_dboard_id = dboard_id::NONE; + + //create a new dboard interface and manager + dboard_interface::sptr dboard_interface( + make_usrp_e_dboard_interface(this) + ); + _dboard_manager = dboard_manager::make( + rx_dboard_id, tx_dboard_id, dboard_interface + ); + + //setup the dboard proxies + _rx_dboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::rx_dboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_dboard_set, this, _1, _2) + ); + _tx_dboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::tx_dboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_dboard_set, this, _1, _2) + ); +} + +/*********************************************************************** + * RX Dboard Get + **********************************************************************/ +void usrp_e_impl::rx_dboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * RX Dboard Set + **********************************************************************/ +void usrp_e_impl::rx_dboard_set(const wax::obj &, const wax::obj &){ + +} + +/*********************************************************************** + * TX Dboard Get + **********************************************************************/ +void usrp_e_impl::tx_dboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * TX Dboard Set + **********************************************************************/ +void usrp_e_impl::tx_dboard_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp_e/dboard_interface.cpp b/host/lib/usrp/usrp_e/dboard_interface.cpp new file mode 100644 index 000000000..c7c7d8c1f --- /dev/null +++ b/host/lib/usrp/usrp_e/dboard_interface.cpp @@ -0,0 +1,189 @@ +// +// 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 //std::copy +#include "usrp_e_impl.hpp" +#include + +using namespace uhd::usrp; + +class usrp_e_dboard_interface : public dboard_interface{ +public: + usrp_e_dboard_interface(usrp_e_impl *impl); + ~usrp_e_dboard_interface(void); + + void write_aux_dac(unit_type_t, int, int); + int read_aux_adc(unit_type_t, int); + + void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t); + void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t); + void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t); + boost::uint16_t read_gpio(gpio_bank_t); + + void write_i2c(int, const byte_vector_t &); + byte_vector_t read_i2c(int, size_t); + + double get_rx_clock_rate(void); + double get_tx_clock_rate(void); + +private: + byte_vector_t transact_spi( + spi_dev_t dev, + spi_latch_t latch, + spi_push_t push, + const byte_vector_t &buf, + bool readback + ); + + usrp_e_impl *_impl; +}; + +/*********************************************************************** + * Make Function + **********************************************************************/ +dboard_interface::sptr make_usrp_e_dboard_interface(usrp_e_impl *impl){ + return dboard_interface::sptr(new usrp_e_dboard_interface(impl)); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp_e_dboard_interface::usrp_e_dboard_interface(usrp_e_impl *impl){ + _impl = impl; +} + +usrp_e_dboard_interface::~usrp_e_dboard_interface(void){ + /* NOP */ +} + +/*********************************************************************** + * Clock Rates + **********************************************************************/ +double usrp_e_dboard_interface::get_rx_clock_rate(void){ + throw std::runtime_error("not implemented"); +} + +double usrp_e_dboard_interface::get_tx_clock_rate(void){ + throw std::runtime_error("not implemented"); +} + +/*********************************************************************** + * GPIO + **********************************************************************/ +void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ + throw std::runtime_error("not implemented"); +} + +void usrp_e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ + throw std::runtime_error("not implemented"); +} + +boost::uint16_t usrp_e_dboard_interface::read_gpio(gpio_bank_t bank){ + throw std::runtime_error("not implemented"); +} + +void usrp_e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){ + throw std::runtime_error("not implemented"); +} + +/*********************************************************************** + * SPI + **********************************************************************/ +dboard_interface::byte_vector_t usrp_e_dboard_interface::transact_spi( + spi_dev_t dev, + spi_latch_t latch, + spi_push_t push, + const byte_vector_t &buf, + bool readback +){ + //load data struct + usrp_e_spi data; + data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; + data.slave = (dev == SPI_RX_DEV)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG; + data.length = buf.size() * 8; //bytes to bits + boost::uint8_t *data_bytes = reinterpret_cast(&data.data); + + //load the data + ASSERT_THROW(buf.size() <= sizeof(data.data)); + std::copy(buf.begin(), buf.end(), data_bytes); + + //load the flags + data.flags = 0; + data.flags |= (latch == SPI_LATCH_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (push == SPI_PUSH_RISE)? UE_SPI_PUSH_RISE : UE_SPI_PUSH_FALL; + + //call the spi ioctl + _impl->ioctl(USRP_E_SPI, &data); + + //unload the data + byte_vector_t ret(data.length/8); //bits to bytes + ASSERT_THROW(ret.size() <= sizeof(data.data)); + std::copy(data_bytes, data_bytes+ret.size(), ret.begin()); + return ret; +} + +/*********************************************************************** + * I2C + **********************************************************************/ +static const size_t max_i2c_data_bytes = 10; + +void usrp_e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ + //allocate some memory for this transaction + ASSERT_THROW(buf.size() <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c &data = reinterpret_cast(mem); + data.addr = i2c_addr; + data.len = buf.size(); + std::copy(buf.begin(), buf.end(), data.data); + + //call the spi ioctl + _impl->ioctl(USRP_E_I2C_WRITE, &data); +} + +dboard_interface::byte_vector_t usrp_e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ + //allocate some memory for this transaction + ASSERT_THROW(num_bytes <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c &data = reinterpret_cast(mem); + data.addr = i2c_addr; + data.len = num_bytes; + + //call the spi ioctl + _impl->ioctl(USRP_E_I2C_READ, &data); + + //unload the data + byte_vector_t ret(data.len); + ASSERT_THROW(ret.size() == num_bytes); + std::copy(data.data, data.data+ret.size(), ret.begin()); + return ret; +} + +/*********************************************************************** + * Aux DAX/ADC + **********************************************************************/ +void usrp_e_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ + throw std::runtime_error("not implemented"); +} + +int usrp_e_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ + throw std::runtime_error("not implemented"); +} diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp new file mode 100644 index 000000000..e32c76a3d --- /dev/null +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -0,0 +1,69 @@ +// +// 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 "usrp_e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * RX DDC Initialization + **********************************************************************/ +void usrp_e_impl::rx_ddc_init(void){ + _rx_ddc_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::rx_ddc_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_ddc_set, this, _1, _2) + ); +} + +/*********************************************************************** + * RX DDC Get + **********************************************************************/ +void usrp_e_impl::rx_ddc_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * RX DDC Set + **********************************************************************/ +void usrp_e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ + +} + +/*********************************************************************** + * TX DUC Initialization + **********************************************************************/ +void usrp_e_impl::tx_duc_init(void){ + _tx_duc_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::tx_duc_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_duc_set, this, _1, _2) + ); +} + +/*********************************************************************** + * TX DUC Get + **********************************************************************/ +void usrp_e_impl::tx_duc_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * TX DUC Set + **********************************************************************/ +void usrp_e_impl::tx_duc_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp_e/fpga-downloader.cc b/host/lib/usrp/usrp_e/fpga-downloader.cc new file mode 100644 index 000000000..4429786a9 --- /dev/null +++ b/host/lib/usrp/usrp_e/fpga-downloader.cc @@ -0,0 +1,262 @@ +// +// 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 +#include +#include + +#include + +/* + * Configuration connections + * + * CCK - MCSPI1_CLK + * DIN - MCSPI1_MOSI + * PROG_B - GPIO_175 - output (change mux) + * DONE - GPIO_173 - input (change mux) + * INIT_B - GPIO_114 - input (change mux) + * +*/ + +const unsigned int PROG_B = 175; +const unsigned int DONE = 173; +const unsigned int INIT_B = 114; + +//static std::string bit_file = "safe_u1e.bin"; + +const int BUF_SIZE = 4096; + +enum gpio_direction {IN, OUT}; + +class gpio { + public: + + gpio(unsigned int gpio_num, gpio_direction pin_direction); + + bool get_value(); + void set_value(bool state); + + private: + + std::stringstream base_path; + std::fstream value_file; +}; + +class spidev { + public: + + spidev(std::string dev_name); + ~spidev(); + + void send(char *wbuf, char *rbuf, unsigned int nbytes); + + private: + + int fd; + +}; + +gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction) +{ + std::fstream export_file; + + export_file.open("/sys/class/gpio/export", std::ios::out); + if (!export_file.is_open()) ///\todo Poor error handling + std::cout << "Failed to open gpio export file." << std::endl; + + export_file << gpio_num << std::endl; + + base_path << "/sys/class/gpio/gpio" << gpio_num << std::flush; + + std::fstream direction_file; + std::string direction_file_name; + + direction_file_name = base_path.str() + "/direction"; + + direction_file.open(direction_file_name.c_str()); + if (!direction_file.is_open()) + std::cout << "Failed to open direction file." << std::endl; + if (pin_direction == OUT) + direction_file << "out" << std::endl; + else + direction_file << "in" << std::endl; + + std::string value_file_name; + + value_file_name = base_path.str() + "/value"; + + value_file.open(value_file_name.c_str(), std::ios_base::in | std::ios_base::out); + if (!value_file.is_open()) + std::cout << "Failed to open value file." << std::endl; +} + +bool gpio::get_value() +{ + + std::string val; + + std::getline(value_file, val); + value_file.seekg(0); + + if (val == "0") + return false; + else if (val == "1") + return true; + else + std::cout << "Data read from value file|" << val << "|" << std::endl; + + return false; +} + +void gpio::set_value(bool state) +{ + + if (state) + value_file << "1" << std::endl; + else + value_file << "0" << std::endl; +} + +static void prepare_fpga_for_configuration(gpio &prog, gpio &)//init) +{ + + prog.set_value(true); + prog.set_value(false); + prog.set_value(true); + +#if 0 + bool ready_to_program(false); + unsigned int count(0); + do { + ready_to_program = init.get_value(); + count++; + + sleep(1); + } while (count < 10 && !ready_to_program); + + if (count == 10) { + std::cout << "FPGA not ready for programming." << std::endl; + exit(-1); + } +#endif +} + +spidev::spidev(std::string fname) +{ + int ret; + int mode = 0; + int speed = 12000000; + int bits = 8; + + fd = open(fname.c_str(), O_RDWR); + + ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); + ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); +} + + +spidev::~spidev() +{ + close(fd); +} + +void spidev::send(char *buf, char *rbuf, unsigned int nbytes) +{ + int ret; + + struct spi_ioc_transfer tr; + tr.tx_buf = (unsigned long) buf; + tr.rx_buf = (unsigned long) rbuf; + tr.len = nbytes; + tr.delay_usecs = 0; + tr.speed_hz = 48000000; + tr.bits_per_word = 8; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + +} + +static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &done) +{ + std::ifstream bitstream; + + std::cout << "File name - " << file_name.c_str() << std::endl; + + bitstream.open(file_name.c_str(), std::ios::binary); + if (!bitstream.is_open()) + std::cout << "File " << file_name << " not opened succesfully." << std::endl; + + spidev spi("/dev/spidev1.0"); + char buf[BUF_SIZE]; + char rbuf[BUF_SIZE]; + + do { + bitstream.read(buf, BUF_SIZE); + spi.send(buf, rbuf, bitstream.gcount()); + + if (error.get_value()) + std::cout << "INIT_B went high, error occured." << std::endl; + + if (!done.get_value()) + std::cout << "Configuration complete." << std::endl; + + } while (bitstream.gcount() == BUF_SIZE); +} + +/* +int main(int argc, char *argv[]) +{ + + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + if (argc == 2) + bit_file = argv[1]; + + std::cout << "FPGA config file: " << bit_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bit_file, gpio_init_b, gpio_done); +} +*/ + +#include +void uhd::usrp::usrp_e::load_fpga(const std::string &bin_file){ + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + std::cout << "FPGA config file: " << bin_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bin_file, gpio_init_b, gpio_done); +} diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp new file mode 100644 index 000000000..333fb2e51 --- /dev/null +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -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 . +// + +#include +#include "usrp_e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * Mboard Initialization + **********************************************************************/ +void usrp_e_impl::mboard_init(void){ + _mboard_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::mboard_get, this, _1, _2), + boost::bind(&usrp_e_impl::mboard_set, this, _1, _2) + ); +} + +/*********************************************************************** + * Mboard Get + **********************************************************************/ +void usrp_e_impl::mboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * Mboard Set + **********************************************************************/ +void usrp_e_impl::mboard_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp new file mode 100644 index 000000000..e821add8c --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -0,0 +1,179 @@ +// +// 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 "usrp_e_impl.hpp" +#include +#include +#include +#include +#include //open +#include //ioctl + +using namespace uhd; +using namespace uhd::usrp; +namespace fs = boost::filesystem; + +UHD_STATIC_BLOCK(register_usrp_e_device){ + device::register_device(&usrp_e::find, &usrp_e::make); +} + +/*********************************************************************** + * Helper Functions + **********************************************************************/ +static std::string abs_path(const std::string &file_path){ + return fs::system_complete(fs::path(file_path)).file_string(); +} + +/*********************************************************************** + * Discovery + **********************************************************************/ +device_addrs_t usrp_e::find(const device_addr_t &device_addr){ + device_addrs_t usrp_e_addrs; + + //if a node was provided, use it and only it + if (device_addr.has_key("node")){ + if (not fs::exists(device_addr["node"])) return usrp_e_addrs; + device_addr_t new_addr; + new_addr["name"] = "USRP-E"; + new_addr["node"] = abs_path(device_addr["node"]); + usrp_e_addrs.push_back(new_addr); + } + + //otherwise look for a few nodes at small indexes + else{ + for(size_t i = 0; i < 5; i++){ + std::string node = str(boost::format("/dev/usrp1_e%d") % i); + if (not fs::exists(node)) continue; + device_addr_t new_addr; + new_addr["name"] = "USRP-E"; + new_addr["node"] = abs_path(node); + usrp_e_addrs.push_back(new_addr); + } + } + + return usrp_e_addrs; +} + +/*********************************************************************** + * Make + **********************************************************************/ +device::sptr usrp_e::make(const device_addr_t &device_addr){ + return sptr(new usrp_e_impl(device_addr["node"])); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp_e_impl::usrp_e_impl(const std::string &node){ + //open the device node and check file descriptor + if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ + throw std::runtime_error(str( + boost::format("Failed to open %s") % node + )); + } + + //initialize the mboard + mboard_init(); + + //initialize the dboards + dboard_init(); + + //initialize the dsps + rx_ddc_init(); + tx_duc_init(); +} + +usrp_e_impl::~usrp_e_impl(void){ + //close the device node file descriptor + ::close(_node_fd); +} + +/*********************************************************************** + * Misc Methods + **********************************************************************/ +void usrp_e_impl::ioctl(int request, void *mem){ + if (::ioctl(_node_fd, request, mem) < 0){ + throw std::runtime_error(str( + boost::format("ioctl failed with request %d") % request + )); + } +} + +/*********************************************************************** + * Device Get + **********************************************************************/ +void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case DEVICE_PROP_NAME: + val = std::string("usrp-e device"); + return; + + case DEVICE_PROP_MBOARD: + ASSERT_THROW(name == ""); + val = _mboard_proxy->get_link(); + return; + + case DEVICE_PROP_MBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case DEVICE_PROP_MAX_RX_SAMPLES: + val = size_t(_max_num_samples); + return; + + case DEVICE_PROP_MAX_TX_SAMPLES: + val = size_t(_max_num_samples); + return; + + } +} + +/*********************************************************************** + * Device Set + **********************************************************************/ +void usrp_e_impl::set(const wax::obj &, const wax::obj &){ + throw std::runtime_error("Cannot set in usrp-e device"); +} + +/*********************************************************************** + * Device IO (TODO) + **********************************************************************/ +size_t usrp_e_impl::send( + const boost::asio::const_buffer &, + const uhd::tx_metadata_t &, + const io_type_t & +){ + if (true){ + throw std::runtime_error(str(boost::format("usrp-e send: cannot handle type \"%s\"") % "")); + } + return 0; +} + +size_t usrp_e_impl::recv( + const boost::asio::mutable_buffer &, + uhd::rx_metadata_t &, + const io_type_t & +){ + if (true){ + throw std::runtime_error(str(boost::format("usrp-e recv: cannot handle type \"%s\"") % "")); + } + return 0; +} diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp new file mode 100644 index 000000000..e593b13ad --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -0,0 +1,135 @@ +// +// 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 + +#ifndef INCLUDED_USRP_E_IMPL_HPP +#define INCLUDED_USRP_E_IMPL_HPP + +class usrp_e_impl; // dummy class declaration + +/*! + * Make a usrp_e dboard interface. + * \param impl a pointer to the usrp_e impl object + * \return a sptr to a new dboard interface + */ +uhd::usrp::dboard_interface::sptr make_usrp_e_dboard_interface(usrp_e_impl *impl); + +/*! + * Simple wax obj proxy class: + * Provides a wax obj interface for a set and a get function. + * This allows us to create nested properties structures + * while maintaining flattened code within the implementation. + */ +class wax_obj_proxy : public wax::obj{ +public: + typedef boost::function get_t; + typedef boost::function set_t; + typedef boost::shared_ptr sptr; + + static sptr make(const get_t &get, const set_t &set){ + return sptr(new wax_obj_proxy(get, set)); + } + + ~wax_obj_proxy(void){ + /* NOP */ + } + +private: + get_t _get; + set_t _set; + + wax_obj_proxy(const get_t &get, const set_t &set){ + _get = get; + _set = set; + }; + + void get(const wax::obj &key, wax::obj &val){ + return _get(key, val); + } + + void set(const wax::obj &key, const wax::obj &val){ + return _set(key, val); + } +}; + +/*! + * USRP1E implementation guts: + * The implementation details are encapsulated here. + * Handles properties on the mboard, dboard, dsps... + */ +class usrp_e_impl : public uhd::device{ +public: + //structors + usrp_e_impl(const std::string &node); + ~usrp_e_impl(void); + + //the io interface + size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &); + size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &); + + /*! + * Perform an ioctl call on the device node file descriptor. + * This will throw when the internal ioctl call fails. + * \param request the control word + * \param mem pointer to some memory + */ + void ioctl(int request, void *mem); + +private: + static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); + int _node_fd; + + //device functions and settings + void get(const wax::obj &, wax::obj &); + void set(const wax::obj &, const wax::obj &); + + //mboard functions and settings + void mboard_init(void); + void mboard_get(const wax::obj &, wax::obj &); + void mboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _mboard_proxy; + + //xx dboard functions and settings + void dboard_init(void); + uhd::usrp::dboard_manager::sptr _dboard_manager; + + //rx dboard functions and settings + void rx_dboard_get(const wax::obj &, wax::obj &); + void rx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_dboard_proxy; + + //tx dboard functions and settings + void tx_dboard_get(const wax::obj &, wax::obj &); + void tx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _tx_dboard_proxy; + + //rx ddc functions and settings + void rx_ddc_init(void); + void rx_ddc_get(const wax::obj &, wax::obj &); + void rx_ddc_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_ddc_proxy; + + //tx duc functions and settings + void tx_duc_init(void); + void tx_duc_get(const wax::obj &, wax::obj &); + void tx_duc_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _tx_duc_proxy; +}; + +#endif /* INCLUDED_USRP_E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp_e/usrp_e_none.cpp b/host/lib/usrp/usrp_e/usrp_e_none.cpp new file mode 100644 index 000000000..09a3c6946 --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_none.cpp @@ -0,0 +1,38 @@ +// +// 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; +using namespace uhd::usrp; + +/*! + * This file defines the usrp1e discover and make functions + * when the required kernel module headers are not present. + */ + +device_addrs_t usrp_e::find(const device_addr_t &){ + return device_addrs_t(); //return empty list +} + +device::sptr usrp_e::make(const device_addr_t &){ + throw std::runtime_error("this build has no usrp1e support"); +} + +void usrp_e::load_fpga(const std::string &){ + throw std::runtime_error("this build has no usrp1e support"); +} diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index 99e648d8a..0b1e058ef 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -19,8 +19,9 @@ ADD_EXECUTABLE(uhd_find_devices uhd_find_devices.cpp) TARGET_LINK_LIBRARIES(uhd_find_devices uhd) INSTALL(TARGETS uhd_find_devices RUNTIME DESTINATION ${RUNTIME_DIR}) -ADD_EXECUTABLE(usrp1e_load_fpga usrp1e_load_fpga.cpp) -TARGET_LINK_LIBRARIES(usrp1e_load_fpga uhd) +ADD_EXECUTABLE(usrp_e_load_fpga usrp_e_load_fpga.cpp) +TARGET_LINK_LIBRARIES(usrp_e_load_fpga uhd) +INSTALL(TARGETS usrp_e_load_fpga RUNTIME DESTINATION ${PKG_DATA_DIR}/utils) ADD_EXECUTABLE(usrp2_burner usrp2_burner.cpp) TARGET_LINK_LIBRARIES(usrp2_burner uhd) diff --git a/host/utils/usrp_e_load_fpga.cpp b/host/utils/usrp_e_load_fpga.cpp new file mode 100644 index 000000000..403130b53 --- /dev/null +++ b/host/utils/usrp_e_load_fpga.cpp @@ -0,0 +1,47 @@ +// +// 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 + +namespace po = boost::program_options; + +int main(int argc, char *argv[]){ + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("file", po::value(), "path to fpga bin file") + ; + + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help") or vm.count("file") == 0){ + std::cout << boost::format("USRP1E Load FPGA %s") % desc << std::endl; + return ~0; + } + + //load the fpga + std::string file = vm["file"].as(); + uhd::usrp::usrp_e::load_fpga(file); + + return 0; +} -- cgit v1.2.3