1# 2# Copyright 2010-2012 Free Software Foundation, Inc. 3# 4# This file is part of GNU Radio 5# 6# GNU Radio is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 3, or (at your option) 9# any later version. 10# 11# GNU Radio is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with GNU Radio; see the file COPYING. If not, write to 18# the Free Software Foundation, Inc., 51 Franklin Street, 19# Boston, MA 02110-1301, USA. 20# 21 22''' 23Provides source and sink blocks to interface with the UHD library. 24Used to send and receive data between the Ettus Research, LLC product 25line. 26''' 27 28from __future__ import absolute_import 29from __future__ import unicode_literals 30 31######################################################################## 32# Prepare uhd swig module to make it more pythonic 33######################################################################## 34def _prepare_uhd_swig(): 35 try: 36 from . import uhd_swig 37 except ImportError: 38 import os 39 dirname, filename = os.path.split(os.path.abspath(__file__)) 40 __path__.append(os.path.join(dirname, "..", "..", "swig")) 41 from . import uhd_swig 42 43 #some useful typedefs for the user 44 setattr(uhd_swig, 'freq_range_t', uhd_swig.meta_range_t) 45 setattr(uhd_swig, 'gain_range_t', uhd_swig.meta_range_t) 46 47 #Make the python tune request object inherit from float 48 #so that it can be passed in GRC as a frequency parameter. 49 #The type checking in GRC will accept the tune request. 50 #Also use kwargs to construct individual struct elements. 51 class tune_request_t(uhd_swig.tune_request_t, float): 52 def __new__(self, *args, **kwargs): return float.__new__(self) 53 def __float__(self): return self.target_freq 54 def __init__(self, *args, **kwargs): 55 super(tune_request_t, self).__init__(*args) 56 for key, val in list(kwargs.items()): setattr(self, key, val) 57 setattr(uhd_swig, 'tune_request_t', tune_request_t) 58 59 #Make the python tune request object inherit from string 60 #so that it can be passed in GRC as a string parameter. 61 #The type checking in GRC will accept the device address. 62 #Define the set/get item special methods for dict access. 63 class device_addr_t(uhd_swig.device_addr_t, str): 64 def __new__(self, *args): return str.__new__(self) 65 def __getitem__(self, key): return self.get(key) 66 def __setitem__(self, key, val): self.set(key, val) 67 def __init__(self, *args, **kwargs): 68 super(device_addr_t, self).__init__(*args) 69 if args and isinstance(args[0], device_addr_t): 70 for key in list(args[0].keys()): self[key] = args[0][key] 71 setattr(uhd_swig, 'device_addr_t', device_addr_t) 72 73 #make the streamer args take **kwargs on init 74 class stream_args_t(uhd_swig.stream_args_t): 75 def __init__(self, *args, **kwargs): 76 super(stream_args_t, self).__init__(*args) 77 for key, val in list(kwargs.items()): 78 #for some reason, I can't assign a list in the constructor 79 #but what I can do is append the elements individually 80 if key == 'channels': 81 for v in val: self.channels.append(v) 82 elif key == 'args': 83 self.args = device_addr_t(val) 84 else: setattr(self, key, val) 85 setattr(uhd_swig, 'stream_args_t', stream_args_t) 86 87 #handle general things on all uhd_swig attributes 88 #Install the __str__ and __repr__ handlers if applicable 89 #Create aliases for uhd swig attributes to avoid the "_t" 90 for attr in dir(uhd_swig): 91 myobj = getattr(uhd_swig, attr) 92 if hasattr(myobj, 'to_string'): myobj.__repr__ = lambda o: o.to_string().strip() 93 if hasattr(myobj, 'to_pp_string'): myobj.__str__ = lambda o: o.to_pp_string().strip() 94 if hasattr(myobj, 'to_bool'): myobj.__nonzero__ = lambda o: o.to_bool() 95 if hasattr(myobj, 'to_int'): myobj.__int__ = lambda o: o.to_int() 96 if hasattr(myobj, 'to_real'): myobj.__float__ = lambda o: o.to_real() 97 if attr.endswith('_t'): setattr(uhd_swig, attr[:-2], myobj) 98 99 #make a new find devices that casts everything with the pythonized device_addr_t which has __str__ 100 def find_devices(*args, **kwargs): 101 def to_pythonized_dev_addr(dev_addr): 102 new_dev_addr = uhd_swig.device_addr_t() 103 for key in list(dev_addr.keys()): new_dev_addr[key] = dev_addr.get(key) 104 return new_dev_addr 105 return __builtins__['map'](to_pythonized_dev_addr, uhd_swig.find_devices_raw(*args, **kwargs)) 106 setattr(uhd_swig, 'find_devices', find_devices) 107 108 #Cast constructor args (FIXME swig handle overloads?) 109 for attr in ('usrp_source', 'usrp_sink', 'amsg_source'): 110 def constructor_factory(old_constructor): 111 def constructor_interceptor(*args, **kwargs): 112 args = list(args) 113 kwargs = dict(kwargs) 114 for index, key, cast in ( 115 (0, 'device_addr', device_addr), 116 ): 117 if len(args) > index: 118 args[index] = cast(args[index]) 119 if key in kwargs: 120 kwargs[key] = cast(kwargs[key]) 121 #don't pass kwargs, it confuses swig, map into args list: 122 for key in ('device_addr', 'stream_args', 123 'issue_stream_cmd_on_start', 'tsb_tag_name', 'msgq'): 124 if key in kwargs: args.append(kwargs[key]) 125 return old_constructor(*args) 126 return constructor_interceptor 127 setattr(uhd_swig, attr, constructor_factory(getattr(uhd_swig, attr))) 128 129 #Aliases for deprecated constructors 130 setattr(uhd_swig, 'single_usrp_source', uhd_swig.usrp_source) 131 setattr(uhd_swig, 'single_usrp_sink', uhd_swig.usrp_sink) 132 setattr(uhd_swig, 'multi_usrp_source', uhd_swig.usrp_source) 133 setattr(uhd_swig, 'multi_usrp_sink', uhd_swig.usrp_sink) 134 135######################################################################## 136# Initialize this module with the contents of uhd swig 137######################################################################## 138_prepare_uhd_swig() 139from .uhd_swig import * 140