From a963caab9b6500ecef015fa5c514f2a7ae23046f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 21 Mar 2011 16:40:21 -0700 Subject: uhd: setup cpack components for component based installers --- host/docs/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'host/docs') diff --git a/host/docs/CMakeLists.txt b/host/docs/CMakeLists.txt index c04262b63..1a2738647 100644 --- a/host/docs/CMakeLists.txt +++ b/host/docs/CMakeLists.txt @@ -64,14 +64,14 @@ IF(ENABLE_MANUAL) #make the manual target depend on the html file LIST(APPEND manual_html_files ${htmlfile}) - INSTALL(FILES ${htmlfile} DESTINATION ${PKG_DOC_DIR}/manual/html) + INSTALL(FILES ${htmlfile} DESTINATION ${PKG_DOC_DIR}/manual/html COMPONENT manual) ENDFOREACH(rstfile ${manual_sources}) #make the html manual a build-time dependency ADD_CUSTOM_TARGET(manual_html ALL DEPENDS ${manual_html_files}) ENDIF(ENABLE_MANUAL) -INSTALL(FILES ${manual_sources} DESTINATION ${PKG_DOC_DIR}/manual/rst) +INSTALL(FILES ${manual_sources} DESTINATION ${PKG_DOC_DIR}/manual/rst COMPONENT manual) ######################################################################## # Setup Doxygen @@ -99,5 +99,5 @@ IF(ENABLE_DOXYGEN) #make the doxygen generation a built-time dependency ADD_CUSTOM_TARGET(doxygen_docs ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR_DOXYGEN}) - INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR_DOXYGEN} DESTINATION ${PKG_DOC_DIR}) + INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR_DOXYGEN} DESTINATION ${PKG_DOC_DIR} COMPONENT doxygen) ENDIF(ENABLE_DOXYGEN) -- cgit v1.2.3 From 8d8c694baecccd3cff52c95cae8a7d2afae615d7 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 26 Mar 2011 23:03:04 -0700 Subject: usrp2: created net burner gui wrapper for N series The gui looks and works much like the card burner gui. However, the possible devices are not enumerated. Handles errors, resetting, and showing progress. Added hooks to net burner for progress callbacks (progress meter). Changed --ip option to --addr (any resolvable address will work). Fixes issue with "timeout" on reset, by catching socket.timeout. Updated the manual to reflect using the gui app and --addr option. --- host/docs/usrp2.rst | 11 +- host/utils/usrp_n2xx_net_burner.py | 54 ++++++---- host/utils/usrp_n2xx_net_burner_gui.py | 188 +++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+), 27 deletions(-) create mode 100644 host/utils/usrp_n2xx_net_burner_gui.py (limited to 'host/docs') diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst index 70101bd87..912f7d2bd 100644 --- a/host/docs/usrp2.rst +++ b/host/docs/usrp2.rst @@ -58,17 +58,20 @@ Use the net burner tool (unix) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: + sudo /share/uhd/utils/usrp_n2xx_net_burner_gui.py + + -- OR -- + cd /share/uhd/utils - ./usrp_n2xx_net_burner.py --ip= --fw= - ./usrp_n2xx_net_burner.py --ip= --fpga= + ./usrp_n2xx_net_burner.py --addr= --fw= + ./usrp_n2xx_net_burner.py --addr= --fpga= ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use the net burner tool (Windows) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - /share/uhd/utils/usrp_n2xx_net_burner.py --ip= --fw= - /share/uhd/utils/usrp_n2xx_net_burner.py --ip= --fpga= + /share/uhd/utils/usrp_n2xx_net_burner_gui.py ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Device recovery and bricking diff --git a/host/utils/usrp_n2xx_net_burner.py b/host/utils/usrp_n2xx_net_burner.py index 6fdc9df20..c715f3364 100755 --- a/host/utils/usrp_n2xx_net_burner.py +++ b/host/utils/usrp_n2xx_net_burner.py @@ -118,31 +118,29 @@ def is_valid_fw_image(fw_image): # Burner class, holds a socket and send/recv routines ######################################################################## class burner_socket(object): - def __init__(self, ip): + def __init__(self, addr): self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self._sock.settimeout(UDP_TIMEOUT) - self._sock.connect((ip, UDP_FW_UPDATE_PORT)) + self._sock.connect((addr, UDP_FW_UPDATE_PORT)) + self.set_callbacks(lambda *a: None, lambda *a: None) + self.init_update() #check that the device is there - def send_and_recv(self, pkt): - try: self._sock.send(pkt) - except Exception, e: - print e - sys.exit(1) - - try: recv_pkt = self._sock.recv(UDP_MAX_XFER_BYTES) - except Exception, e: - print e - sys.exit(1) + def set_callbacks(self, progress_cb, status_cb): + self._progress_cb = progress_cb + self._status_cb = status_cb - return recv_pkt + def send_and_recv(self, pkt): + self._sock.send(pkt) + return self._sock.recv(UDP_MAX_XFER_BYTES) #just here to validate comms def init_update(self): out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_OHAI_LOL, seq(), 0, 0, "") - in_pkt = self.send_and_recv(out_pkt) + try: in_pkt = self.send_and_recv(out_pkt) + except socket.timeout: raise Exception, "No response from device" (proto_ver, pktid, rxseq, ip_addr) = unpack_flash_ip_fmt(in_pkt) if pktid == update_id_t.USRP2_FW_UPDATE_ID_OHAI_OMG: - print "USRP2P found." + print "USRP-N2XX found." else: raise Exception, "Invalid reply received from device." @@ -214,9 +212,11 @@ class burner_socket(object): def write_image(self, image, addr): print "Writing image" + self._status_cb("Writing") + writedata = image #we split the image into smaller (256B) bits and send them down the wire - while image: - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL, seq(), addr, FLASH_DATA_PACKET_SIZE, image[:FLASH_DATA_PACKET_SIZE]) + while writedata: + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL, seq(), addr, FLASH_DATA_PACKET_SIZE, writedata[:FLASH_DATA_PACKET_SIZE]) in_pkt = self.send_and_recv(out_pkt) (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) @@ -224,11 +224,13 @@ class burner_socket(object): if pktid != update_id_t.USRP2_FW_UPDATE_ID_WROTE_TEH_FLASHES_OMG: raise Exception, "Invalid reply %c from device." % (chr(pktid)) - image = image[FLASH_DATA_PACKET_SIZE:] + writedata = writedata[FLASH_DATA_PACKET_SIZE:] addr += FLASH_DATA_PACKET_SIZE + self._progress_cb(float(len(image)-len(writedata))/len(image)) def verify_image(self, image, addr): print "Verifying data" + self._status_cb("Verifying") readsize = len(image) readdata = str() while readsize > 0: @@ -245,6 +247,7 @@ class burner_socket(object): readdata += data[:thisreadsize] readsize -= FLASH_DATA_PACKET_SIZE addr += FLASH_DATA_PACKET_SIZE + self._progress_cb(float(len(readdata))/len(image)) print "Read back %i bytes" % len(readdata) # print readdata @@ -253,7 +256,7 @@ class burner_socket(object): # print "out: %i in: %i" % (ord(image[i]), ord(readdata[i])) if readdata != image: - print "Verify failed. Image did not write correctly." + raise Exception, "Verify failed. Image did not write correctly." else: print "Success." @@ -285,13 +288,15 @@ class burner_socket(object): def reset_usrp(self): out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL, seq(), 0, 0, "") - in_pkt = self.send_and_recv(out_pkt) + try: in_pkt = self.send_and_recv(out_pkt) + except socket.timeout: return (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) if pktid == update_id_t.USRP2_FW_UPDATE_ID_RESETTIN_TEH_COMPUTORZ_OMG: raise Exception, "Device failed to reset." def erase_image(self, addr, length): + self._status_cb("Erasing") #get flash info first out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL, seq(), addr, length, "") in_pkt = self.send_and_recv(out_pkt) @@ -302,6 +307,7 @@ class burner_socket(object): raise Exception, "Invalid reply %c from device." % (chr(pktid)) print "Erasing %i bytes at %i" % (length, addr) + start_time = time.time() #now wait for it to finish while(True): @@ -313,6 +319,8 @@ class burner_socket(object): if pktid == update_id_t.USRP2_FW_UPDATE_ID_IM_DONE_ERASING_OMG: break elif pktid != update_id_t.USRP2_FW_UPDATE_ID_NOPE_NOT_DONE_ERASING_OMG: raise Exception, "Invalid reply %c from device." % (chr(pktid)) + time.sleep(0.01) #decrease network overhead by waiting a bit before polling + self._progress_cb(min(1.0, (time.time() - start_time)/(length/80e3))) ######################################################################## @@ -320,7 +328,7 @@ class burner_socket(object): ######################################################################## def get_options(): parser = optparse.OptionParser() - parser.add_option("--ip", type="string", help="USRP2P firmware address", default='') + parser.add_option("--addr", type="string", help="USRP-N2XX device address", default='') parser.add_option("--fw", type="string", help="firmware image path (optional)", default='') parser.add_option("--fpga", type="string", help="fpga image path (optional)", default='') parser.add_option("--reset", action="store_true", help="reset the device after writing", default=False) @@ -335,7 +343,7 @@ def get_options(): ######################################################################## if __name__=='__main__': options = get_options() - if not options.ip: raise Exception, 'no ip address specified' + if not options.addr: raise Exception, 'no address specified' if not options.fpga and not options.fw and not options.reset: raise Exception, 'Must specify either a firmware image or FPGA image, and/or reset.' @@ -345,7 +353,7 @@ if __name__=='__main__': response = raw_input("""Type "yes" to continue, or anything else to quit: """) if response != "yes": sys.exit(0) - burner = burner_socket(ip=options.ip) + burner = burner_socket(addr=options.addr) if options.read: if options.fw: diff --git a/host/utils/usrp_n2xx_net_burner_gui.py b/host/utils/usrp_n2xx_net_burner_gui.py new file mode 100644 index 000000000..7fcb7d121 --- /dev/null +++ b/host/utils/usrp_n2xx_net_burner_gui.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python +# +# Copyright 2011 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import threading +import usrp_n2xx_net_burner #import implementation +import Tkinter, tkFileDialog, tkFont, tkMessageBox +import os + +class BinFileEntry(Tkinter.Frame): + """ + Simple file entry widget for getting the file path of bin files. + Combines a label, entry, and button with file dialog callback. + """ + + def __init__(self, root, what, def_path=''): + self._what = what + Tkinter.Frame.__init__(self, root) + Tkinter.Label(self, text=what+":").pack(side=Tkinter.LEFT) + self._entry = Tkinter.Entry(self, width=50) + self._entry.insert(Tkinter.END, def_path) + self._entry.pack(side=Tkinter.LEFT) + Tkinter.Button(self, text="...", command=self._button_cb).pack(side=Tkinter.LEFT) + + def _button_cb(self): + filename = tkFileDialog.askopenfilename( + parent=self, + filetypes=[('bin files', '*.bin'), ('all files', '*.*')], + title="Select bin file for %s"%self._what, + initialdir=os.path.dirname(self.get_filename()), + ) + + # open file on your own + if filename: + self._entry.delete(0, Tkinter.END) + self._entry.insert(0, filename) + + def get_filename(self): + return self._entry.get() + +class ProgressBar(Tkinter.Canvas): + """ + A simple implementation of a progress bar. + Draws rectangle that fills from left to right. + """ + + def __init__(self, root, width=500, height=20): + self._width = width + self._height = height + Tkinter.Canvas.__init__(self, root, relief="sunken", borderwidth=2, width=self._width-2, height=self._height-2) + self._last_fill_pixels = None + self.set(0.0) + + def set(self, frac): + """ + Update the progress where fraction is between 0.0 and 1.0 + """ + #determine the number of pixels to draw + fill_pixels = int(round(self._width*frac)) + if fill_pixels == self._last_fill_pixels: return + self._last_fill_pixels = fill_pixels + + #draw a rectangle representing the progress + if frac: self.create_rectangle(0, 0, fill_pixels, self._height, fill="#357EC7") + else: self.create_rectangle(0, 0, self._width, self._height, fill="#E8E8E8") + +class SectionLabel(Tkinter.Label): + """ + Make a text label with bold font. + """ + + def __init__(self, root, text): + Tkinter.Label.__init__(self, root, text=text) + + #set the font bold + f = tkFont.Font(font=self['font']) + f['weight'] = 'bold' + self['font'] = f.name + +class USRPN2XXNetBurnerApp(Tkinter.Frame): + """ + The top level gui application for the usrp-n2xx network burner. + Creates entry widgets and button with callback to write images. + """ + + def __init__(self, root, addr, fw, fpga): + + Tkinter.Frame.__init__(self, root) + + #pack the file entry widgets + SectionLabel(self, text="Select Images").pack(pady=5) + self._fw_img_entry = BinFileEntry(self, "Firmware Image", def_path=fw) + self._fw_img_entry.pack() + self._fpga_img_entry = BinFileEntry(self, "FPGA Image", def_path=fpga) + self._fpga_img_entry.pack() + + #pack the destination entry widget + SectionLabel(self, text="Select Address").pack(pady=5) + self._addr_entry = Tkinter.Entry(self, width=30) + self._addr_entry.insert(Tkinter.END, addr) + self._addr_entry.pack() + + #the do it button + SectionLabel(self, text="").pack(pady=5) + button = Tkinter.Button(self, text="Burn Images", command=self._burn) + self._enable_input = lambda: button.configure(state=Tkinter.NORMAL) + self._disable_input = lambda: button.configure(state=Tkinter.DISABLED) + button.pack() + + #a progress bar to monitor the status + progress_frame = Tkinter.Frame(self) + progress_frame.pack() + self._status = Tkinter.StringVar() + Tkinter.Label(progress_frame, textvariable=self._status).pack(side=Tkinter.LEFT) + self._pbar = ProgressBar(progress_frame) + self._pbar.pack(side=Tkinter.RIGHT, expand=True) + + def _burn(self): + self._disable_input() + threading.Thread(target=self._burn_bg).start() + + def _burn_bg(self): + #grab strings from the gui + fw = self._fw_img_entry.get_filename() + fpga = self._fpga_img_entry.get_filename() + addr = self._addr_entry.get() + + #check input + if not addr: + tkMessageBox.showerror('Error:', 'No address specified!') + return + if not fw and not fpga: + tkMessageBox.showerror('Error:', 'No images specified!') + return + if fw and not os.path.exists(fw): + tkMessageBox.showerror('Error:', 'Firmware image not found!') + return + if fpga and not os.path.exists(fpga): + tkMessageBox.showerror('Error:', 'FPGA image not found!') + return + + try: + #make a new burner object and attempt the burner operation + burner = usrp_n2xx_net_burner.burner_socket(addr=addr) + + for (image_type, fw_img, fpga_img) in (('FPGA', '', fpga), ('Firmware', fw, '')): + #setup callbacks that update the gui + def status_cb(status): + self._pbar.set(0.0) #status change, reset the progress + self._status.set("%s %s "%(status.title(), image_type)) + burner.set_callbacks(progress_cb=self._pbar.set, status_cb=status_cb) + burner.burn_fw(fw=fw_img, fpga=fpga_img, reset=False, safe=False) + + if tkMessageBox.askyesno("Burn was successful!", "Reset the device?"): + burner.reset_usrp() + + except Exception, e: + tkMessageBox.showerror('Verbose:', 'Error: %s'%str(e)) + + #reset the progress bar + self._pbar.set(0.0) + self._status.set("") + self._enable_input() + +######################################################################## +# main +######################################################################## +if __name__=='__main__': + options = usrp_n2xx_net_burner.get_options() + root = Tkinter.Tk() + root.title('USRP-N2XX Net Burner') + USRPN2XXNetBurnerApp(root, addr=options.addr, fw=options.fw, fpga=options.fpga).pack() + root.mainloop() + exit() -- cgit v1.2.3 From 9d91d5518751d37b32c86fe4f0c17f0b480fd0bb Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 29 Mar 2011 11:22:57 -0700 Subject: usb: tweaks to the build guide (libusb + windows) --- host/docs/build.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'host/docs') diff --git a/host/docs/build.rst b/host/docs/build.rst index de7c544f2..b81e25de1 100644 --- a/host/docs/build.rst +++ b/host/docs/build.rst @@ -165,12 +165,13 @@ LibUSB cmake notes On Windows, cmake does not have the advantage of pkg-config, so we must manually tell cmake how to locate the LibUSB header and lib. -From the cmake gui, select "Advanded View": - +* From the cmake gui, select "Advanded View" * Set LIBUSB_INCLUDE_DIR to the directory with "libusb.h". * Set LIBUSB_LIBRARIES to the full path for "libusb-1.0.lib". -Then check the boxes to enable USRP1 support, click configure and generate. + * Recommend the static libusb-1.0.lib to simplify runtime dependencies. + +* Check the box to enable USB support, click configure and generate. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Build the project in MSVC -- cgit v1.2.3 From 1721352e905e10dbff48d44b66b1684020a103d7 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 1 Apr 2011 10:27:54 -0700 Subject: uhd: install dlls into runtime path, updated docs --- host/docs/build.rst | 4 +--- host/docs/index.rst | 4 +--- host/lib/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) (limited to 'host/docs') diff --git a/host/docs/build.rst b/host/docs/build.rst index b81e25de1..c645817ab 100644 --- a/host/docs/build.rst +++ b/host/docs/build.rst @@ -197,9 +197,7 @@ Open the Visual Studio Command Prompt Shorcut: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Setup the PATH environment variable ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -* Add the boost library path to %PATH% (usually c:\\program files\\boost\\\\lib) -* Add the uhd library path to %PATH% (usually c:\\program files\\uhd\\lib) -* Add the libusb library to %PATH% (if using usb support) +* Add the uhd bin path to %PATH% (usually c:\\program files\\uhd\\bin) **Note:** The interface for editing environment variable paths in Windows is very poor. diff --git a/host/docs/index.rst b/host/docs/index.rst index 734300164..467d5f385 100644 --- a/host/docs/index.rst +++ b/host/docs/index.rst @@ -4,9 +4,7 @@ UHD - Universal Hardware Driver The UHD is the universal hardware driver for Ettus Research products. The goal of the UHD is to provide a host driver and api for current and future Ettus Research products. -Users will be able to use the UHD driver standalone/without gnuradio. -Also, a dual license option will be available for those who build against the UHD -but cannot release their software products under the GPL. +Users will be able to use the UHD driver standalone or with 3rd party applications. ------------------------------------------------------------------------ Contents diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 54f4893e3..f8886566a 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -121,5 +121,5 @@ ENDIF(DEFINED LIBUHD_OUTPUT_NAME) INSTALL(TARGETS uhd LIBRARY DESTINATION ${LIBRARY_DIR} COMPONENT libraries # .so file ARCHIVE DESTINATION ${LIBRARY_DIR} COMPONENT libraries # .lib file - RUNTIME DESTINATION ${LIBRARY_DIR} COMPONENT libraries # .dll file + RUNTIME DESTINATION ${RUNTIME_DIR} COMPONENT libraries # .dll file ) -- cgit v1.2.3 From af2ab1c688d641e82060016aa772432de6445633 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 5 Apr 2011 15:32:41 -0700 Subject: uhd: replace with in docs for clarity --- host/docs/build.rst | 2 +- host/docs/dboards.rst | 4 ++-- host/docs/general.rst | 2 +- host/docs/identification.rst | 2 +- host/docs/images.rst | 4 ++-- host/docs/usrp2.rst | 18 +++++++++--------- host/docs/usrp_e1xx.rst | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) (limited to 'host/docs') diff --git a/host/docs/build.rst b/host/docs/build.rst index c645817ab..063b2b371 100644 --- a/host/docs/build.rst +++ b/host/docs/build.rst @@ -116,7 +116,7 @@ Generate Makefiles with cmake Additionally, configuration variables can be passed into cmake via the command line. The following common-use configuration variables are listed below: -* For a custom install prefix: -DCMAKE_INSTALL_PREFIX= +* For a custom install prefix: -DCMAKE_INSTALL_PREFIX= * To install libs into lib64: cmake -DLIB_SUFFIX=64 Example usage: diff --git a/host/docs/dboards.rst b/host/docs/dboards.rst index 7f205c404..419456df2 100644 --- a/host/docs/dboards.rst +++ b/host/docs/dboards.rst @@ -182,7 +182,7 @@ If you lose R193, you can use anything from 0 to 10 ohms there. With the daughterboard plugged-in, run the following commands: :: - cd /share/uhd/utils + cd /share/uhd/utils ./usrp_burn_db_eeprom --id=0x000d --unit=RX --args= --slot= * are device address arguments (optional if only one USRP is on your machine) @@ -209,7 +209,7 @@ These are all 0-ohm, so if you lose one, just short across the appropriate pads With the daughterboard plugged-in, run the following commands: :: - cd /share/uhd/utils + cd /share/uhd/utils ./usrp_burn_db_eeprom --id= --unit=RX --args= --slot= ./usrp_burn_db_eeprom --id= --unit=TX --args= --slot= diff --git a/host/docs/general.rst b/host/docs/general.rst index 2894fbf88..73b820c84 100644 --- a/host/docs/general.rst +++ b/host/docs/general.rst @@ -52,5 +52,5 @@ Support for dynamically loadable modules For a module to be loaded at runtime, it must be: * found in the UHD_MODULE_PATH environment variable, -* installed into the /share/uhd/modules directory, +* installed into the /share/uhd/modules directory, * or installed into /usr/share/uhd/modules directory (unix only). diff --git a/host/docs/identification.rst b/host/docs/identification.rst index 90484744c..deda61531 100644 --- a/host/docs/identification.rst +++ b/host/docs/identification.rst @@ -107,7 +107,7 @@ Set a custom name Run the following commands: :: - cd /share/uhd/utils + cd /share/uhd/utils ./usrp_burn_mb_eeprom --args= --key=name --val=lab1_xcvr ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/host/docs/images.rst b/host/docs/images.rst index f5be88a65..adfa6d530 100644 --- a/host/docs/images.rst +++ b/host/docs/images.rst @@ -54,8 +54,8 @@ When installing images from an archive, there are two options: **Option 1:** Unpack the archive into the UHD installation prefix. -The UHD will always search /share/uhd/images for image files. -Where was set by the CMAKE_INSTALL_PREFIX at configure-time. +The UHD will always search /share/uhd/images for image files. +Where was set by the CMAKE_INSTALL_PREFIX at configure-time. **Option 2:** diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst index 912f7d2bd..161170f2c 100644 --- a/host/docs/usrp2.rst +++ b/host/docs/usrp2.rst @@ -25,11 +25,11 @@ Use the card burner tool (unix) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - sudo /share/uhd/utils/usrp2_card_burner_gui.py + sudo /share/uhd/utils/usrp2_card_burner_gui.py -- OR -- - cd /share/uhd/utils + cd /share/uhd/utils sudo ./usrp2_card_burner.py --dev=/dev/sd --fpga= sudo ./usrp2_card_burner.py --dev=/dev/sd --fw= @@ -42,7 +42,7 @@ Use the card burner tool (windows) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - /share/uhd/utils/usrp2_card_burner_gui.py + /share/uhd/utils/usrp2_card_burner_gui.py ------------------------------------------------------------------------ @@ -58,11 +58,11 @@ Use the net burner tool (unix) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - sudo /share/uhd/utils/usrp_n2xx_net_burner_gui.py + sudo /share/uhd/utils/usrp_n2xx_net_burner_gui.py -- OR -- - cd /share/uhd/utils + cd /share/uhd/utils ./usrp_n2xx_net_burner.py --addr= --fw= ./usrp_n2xx_net_burner.py --addr= --fpga= @@ -71,7 +71,7 @@ Use the net burner tool (Windows) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - /share/uhd/utils/usrp_n2xx_net_burner_gui.py + /share/uhd/utils/usrp_n2xx_net_burner_gui.py ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Device recovery and bricking @@ -145,7 +145,7 @@ and the network must be setup properly as described above. Run the following commands: :: - cd /share/uhd/utils + cd /share/uhd/utils ./usrp_burn_mb_eeprom --args= --key=ip-addr --val=192.168.10.3 **Method 2 (Linux Only):** @@ -154,7 +154,7 @@ It uses raw ethernet packets to bypass the IP/UDP layer to communicate with the Run the following commands: :: - cd /share/uhd/utils + cd /share/uhd/utils sudo ./usrp2_recovery.py --ifc=eth0 --new-ip=192.168.10.3 ------------------------------------------------------------------------ @@ -343,5 +343,5 @@ Test the PPS input with the following app: :: - cd /share/uhd/examples + cd /share/uhd/examples ./test_pps_input --args= diff --git a/host/docs/usrp_e1xx.rst b/host/docs/usrp_e1xx.rst index ffcd370dd..fb5848bad 100644 --- a/host/docs/usrp_e1xx.rst +++ b/host/docs/usrp_e1xx.rst @@ -61,5 +61,5 @@ can talk directly to the clock generator over a SPI interface. Run the following commands to restore the clock generator to a usable state: :: - cd /share/uhd/usrp_e_utilities + cd /share/uhd/usrp_e_utilities ./usrp-e-utility --fpga=../images/usrp_e100_pt_fpga.bin --reclk -- cgit v1.2.3 From 98a05d85cd6537dee9bf2f48d0e068d322363fc4 Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Wed, 13 Apr 2011 19:03:18 -0700 Subject: Updated documentation and improved XCVR RSSI calculation Documented dboard sensors Documented DBSRX2 Added description of direct conversion vs low IF for each dboard Added E1xx docs for adding refclock and pps connectors XCVR rssi calculation was in unscaled dB units Used chart in datasheet (pg 16) to rescale to dBm --- host/docs/dboards.rst | 119 ++++++++++++++++++++++++++++------- host/docs/usrp_e1xx.rst | 38 +++++++++++ host/lib/usrp/dboard/db_xcvr2450.cpp | 13 +++- 3 files changed, 144 insertions(+), 26 deletions(-) (limited to 'host/docs') diff --git a/host/docs/dboards.rst b/host/docs/dboards.rst index 419456df2..373189441 100644 --- a/host/docs/dboards.rst +++ b/host/docs/dboards.rst @@ -27,12 +27,14 @@ Though the magic of aliasing, you can down-convert signals greater than the Nyquist rate of the ADC. BasicRX Bandwidth (Hz): - For Real-Mode (A or B subdevice): 250M - For Complex (AB or BA subdevice): 500M + +* For Real-Mode (A or B subdevice): 250M +* For Complex (AB or BA subdevice): 500M LFRX Bandwidth (Hz): - For Real-Mode (A or B subdevice): 33M - For Complex (AB or BA subdevice): 66M + +* For Real-Mode (A or B subdevice): 33M +* For Complex (AB or BA subdevice): 66M ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Basic TX and and LFTX @@ -49,31 +51,67 @@ Though the magic of aliasing, you can up-convert signals greater than the Nyquist rate of the DAC. BasicTX Bandwidth (Hz): 250M - For Real-Mode (A or B subdevice): 250M - For Complex (AB or BA subdevice): 500M + +* For Real-Mode (A or B subdevice): 250M +* For Complex (AB or BA subdevice): 500M LFTX Bandwidth (Hz): 33M - For Real-Mode (A or B subdevice): 33M - For Complex (AB or BA subdevice): 66M + +* For Real-Mode (A or B subdevice): 33M +* For Complex (AB or BA subdevice): 66M ^^^^^^^^^^^^^^^^^^^^^^^^^^^ DBSRX ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The DBSRX board has 1 quadrature subdevice. +The DBSRX board has 1 quadrature subdevice. +It defaults to direct conversion, but can use a low IF through lo_offset in uhd::tune_request_t Receive Antennas: **J3** The board has no user selectable antenna setting -Receive Gains: - **GC1**, Range: 0-56dB - **GC2**, Range: 0-24dB +Receive Gains: + +* **GC1**, Range: 0-56dB +* **GC2**, Range: 0-24dB Bandwidth (Hz): 8M-66M +Sensors: + +* **lo_locked**: boolean for LO lock state + +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +DBSRX2 +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The DBSRX2 board has 1 quadrature subdevice. +It defaults to direct conversion, but can use a low IF through lo_offset in uhd::tune_request_t + +Receive Antennas: **J3** + +The board has no user selectable antenna setting + +Receive Gains: + +* **GC1**, Range: 0-73dB +* **BBG**, Range: 0-15dB + +Bandwidth (Hz): 8M-80M + +Sensors: + +* **lo_locked**: boolean for LO lock state + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ RFX Series ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The RFX Series boards have 2 quadrature subdevices, one transmit, one receive. +Transmit defaults to low IF and Receive defaults to direct conversion. +The IF can be adjusted through lo_offset in uhd::tune_request_t + +The RFX Series boards have independent receive and transmit LO's and synthesizers +allowing full-duplex operation on different transmit and receive frequencies. + Transmit Antennas: **TX/RX** Receive Antennas: **TX/RX** or **RX2** @@ -85,12 +123,21 @@ the receive antenna will always be set to RX2, regardless of the settings. Receive Gains: **PGA0**, Range: 0-70dB (except RFX400 range is 0-45dB) Bandwidths (Hz): - * **RX**: 40M - * **TX**: 40M + +* **RX**: 40M +* **TX**: 40M + +Sensors: + +* **lo_locked**: boolean for LO lock state ^^^^^^^^^^^^^^^^^^^^^^^^^^^ XCVR 2450 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The XCVR2450 has 2 quadrature subdevices, one transmit, one receive. +Transmit and Receive default to direct conversion but +can be used in low IF mode through lo_offset in uhd::tune_request_t + The XCVR2450 has a non-contiguous tuning range consisting of a high band (4.9-6.0GHz) and a low band (2.4-2.5GHz). @@ -106,20 +153,35 @@ The XCVR2450 does not support full-duplex mode, attempting to operate in full-duplex will result in transmit-only operation. Transmit Gains: - * **VGA**, Range: 0-30dB - * **BB**, Range: 0-5dB + +* **VGA**, Range: 0-30dB +* **BB**, Range: 0-5dB Receive Gains: - * **LNA**, Range: 0-30.5dB - * **VGA**, Range: 0-62dB + +* **LNA**, Range: 0-30.5dB +* **VGA**, Range: 0-62dB Bandwidths (Hz): - * **RX**: 15M, 19M, 28M, 36M; (each +-0, 5, or 10%) - * **TX**: 24M, 36M, 48M + +* **RX**: 15M, 19M, 28M, 36M; (each +-0, 5, or 10%) +* **TX**: 24M, 36M, 48M + +Sensors: + +* **lo_locked**: boolean for LO lock state +* **rssi**: float for rssi in dBm ^^^^^^^^^^^^^^^^^^^^^^^^^^^ WBX Series ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The WBX Series boards have 2 quadrature subdevices, one transmit, one receive. +Transmit and Receive default to direct conversion but +can be used in low IF mode through lo_offset in uhd::tune_request_t + +The WBX Series boards have independent receive and transmit LO's and synthesizers +allowing full-duplex operation on different transmit and receive frequencies. + Transmit Antennas: **TX/RX** Receive Antennas: **TX/RX** or **RX2** @@ -133,17 +195,26 @@ Transmit Gains: **PGA0**, Range: 0-25dB Receive Gains: **PGA0**, Range: 0-31.5dB Bandwidths (Hz): - * **RX**: 40M - * **TX**: 40M + +* **RX**: 40M +* **TX**: 40M + +Sensors: + +* **lo_locked**: boolean for LO lock state ^^^^^^^^^^^^^^^^^^^^^^^^^^^ TVRX ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The TVRX board has 1 real-mode subdevice. +It is operated at a low IF. + Receive Antennas: RX Receive Gains: - * **RF**, Range: -13.3-50.3dB (frequency-dependent) - * **IF**, Range: -1.5-32.5dB + +* **RF**, Range: -13.3-50.3dB (frequency-dependent) +* **IF**, Range: -1.5-32.5dB Bandwidth: 6MHz diff --git a/host/docs/usrp_e1xx.rst b/host/docs/usrp_e1xx.rst index fb5848bad..2818a0a65 100644 --- a/host/docs/usrp_e1xx.rst +++ b/host/docs/usrp_e1xx.rst @@ -63,3 +63,41 @@ Run the following commands to restore the clock generator to a usable state: cd /share/uhd/usrp_e_utilities ./usrp-e-utility --fpga=../images/usrp_e100_pt_fpga.bin --reclk + + +------------------------------------------------------------------------ +Clock Synchronization +------------------------------------------------------------------------ + + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Ref Clock - 10MHz +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The E1xx has a 10MHz TCXO which can be used to discipline the flexible clocking by +selecting REF_INT for the clock_config_t. + +Alternately, an external 10MHz reference clock can be supplied by soldering a connector. + +* Connector J10 (REF_IN) needs MCX connector WM5541-ND or similar +* Square wave will offer the best phase noise performance, but sinusoid is acceptable +* Power level: 0 to 15dBm +* Select REF_SMA in clock_config_t + + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +PPS - Pulse Per Second +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +An exteral PPS signal for timestamp synchronization can be supplied by soldering a connector. + +* Connector J13 (PPS) needs MCX connector WM5541-ND or similar +* Requires a square wave signal +* Amplitude: 3.3 to 5Vpp + +Test the PPS input with the following app: + +* are device address arguments (optional if only one USRP is on your machine) + +:: + + cd /share/uhd/examples + ./test_pps_input --args= diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index 9d25b30a5..70b0bbabd 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -152,12 +152,21 @@ private: * \return the rssi in dB */ double get_rssi(void){ + //*FIXME* RSSI depends on LNA Gain Setting (datasheet pg 16 top middle chart) + double max_power; + switch(_max2829_regs.rx_lna_gain){ + case 0: + case 1: max_power = 0; break; + case 2: max_power = -15; break; + case 3: max_power = -30.5; break; + } + //constants for the rssi calculation static const double min_v = 0.5, max_v = 2.5; static const double rssi_dyn_range = 60; //calculate the rssi from the voltage double voltage = this->get_iface()->read_aux_adc(dboard_iface::UNIT_RX, dboard_iface::AUX_ADC_B); - return rssi_dyn_range*(voltage - min_v)/(max_v - min_v); + return max_power - rssi_dyn_range*(voltage - min_v)/(max_v - min_v); } }; @@ -621,7 +630,7 @@ void xcvr2450::rx_get(const wax::obj &key_, wax::obj &val){ if (key.name == "lo_locked") val = sensor_value_t("LO", this->get_locked(), "locked", "unlocked"); else if (key.name == "rssi") - val = sensor_value_t("RSSI", this->get_rssi(), "dB"); + val = sensor_value_t("RSSI", this->get_rssi(), "dBm"); else UHD_THROW_INVALID_CODE_PATH(); return; -- cgit v1.2.3