|
| 1 | +import argparse |
| 2 | +import sys |
| 3 | + |
1 | 4 | from .pybladerf_tools import ( |
2 | | - pybladerf_sweep, |
3 | 5 | pybladerf_info, |
| 6 | + pybladerf_sweep, |
| 7 | + pybladerf_transfer, |
4 | 8 | ) |
5 | 9 | from .pylibbladerf import pybladerf |
6 | | -import argparse |
7 | | -import sys |
8 | 10 |
|
9 | 11 |
|
10 | | -def main(): |
| 12 | +def main() -> None: |
| 13 | + |
11 | 14 | parser = argparse.ArgumentParser( |
12 | | - description="python_bladerf is a Python wrapper for libbladerf. It also contains some additional tools.", |
13 | | - usage="python_bladerf [-h] {info, sweep} ..." |
| 15 | + description='python_bladerf is a Python wrapper for libbladerf. It also contains some additional tools.', |
| 16 | + usage='python_bladerf [-h] {info, sweep} ...', |
14 | 17 | ) |
15 | | - subparsers = parser.add_subparsers(dest="command", title="Available commands") |
| 18 | + subparsers = parser.add_subparsers(dest='command', title='Available commands') |
16 | 19 | subparsers.required = True |
17 | 20 | pybladerf_info_parser = subparsers.add_parser( |
18 | | - 'info', help='Read device information from Bladerf such as serial number and FPGA version.', usage="python_bladerf info [-h] [-f] [-s]" |
| 21 | + 'info', help='Read device information from Bladerf such as serial number and FPGA version.', usage="python_bladerf info [-h] [-f] [-i]", |
19 | 22 | ) |
20 | 23 | pybladerf_info_parser.add_argument('-f', '--full', action='store_true', help='show full info') |
21 | 24 | pybladerf_info_parser.add_argument('-i', '--device_identifiers', action='store_true', help='show only founded device_identifiers') |
22 | 25 |
|
23 | 26 | pybladerf_sweep_parser = subparsers.add_parser( |
24 | | - 'sweep', help='a command-line spectrum analyzer.', usage='python_bladerf sweep [-h] [-d] [-f] [-g] [-w] [-ch] [-1] [-N] [-o] [-B] [-s] [-SR] [-BW] -[FIR] [-r]' |
| 27 | + 'sweep', help='a command-line spectrum analyzer.', usage='python_bladerf sweep [-h] [-d] [-f] [-g] [-w] [-c] [-1] [-N] [-o] [-p] [-B] [-S] [-s] [-b] [-r]', |
25 | 28 | ) |
26 | | - pybladerf_sweep_parser.add_argument('-d', action='store', help='device_identifier. device identifier of desired BladeRF', metavar='', default='') |
27 | | - pybladerf_sweep_parser.add_argument('-f', action='store', help='freq_min:freq_max. minimum and maximum frequencies in MHz start:stop. Default is 71:5999', metavar='', default='71:5999') |
28 | | - pybladerf_sweep_parser.add_argument('-g', action='store', help='gain_db. RX gain, -15 - 60dB, 1dB steps', metavar='', default=20) |
29 | | - pybladerf_sweep_parser.add_argument('-w', action='store', help='bin_width. FFT bin width (frequency resolution) in Hz, 245-30000000', metavar='', default=1000000) |
30 | | - pybladerf_sweep_parser.add_argument('-ch', action='store', help='RX channel. which channel to use (0, 1). Default is 0', metavar='', default=0) |
| 29 | + |
| 30 | + pybladerf_sweep_parser.add_argument('-d', action='store', help='device identifier of desired BladeRF', metavar='', default='') |
| 31 | + pybladerf_sweep_parser.add_argument('-f', action='store', help='freq_min:freq_max. minimum and maximum frequencies in MHz start:stop or start1:stop1,start2:stop2', metavar='', default='70:6000') |
| 32 | + pybladerf_sweep_parser.add_argument('-g', action='store', help='RX gain, -15 - 60dB, 1dB steps', metavar='', default=20) |
| 33 | + pybladerf_sweep_parser.add_argument('-w', action='store', help='FFT bin width (frequency resolution) in Hz', metavar='', default=1000000) |
| 34 | + pybladerf_sweep_parser.add_argument('-c', action='store', help='RX channel. which channel to use (0, 1). Default is 0', metavar='', default=0) |
31 | 35 | pybladerf_sweep_parser.add_argument('-1', action='store_true', help='one shot mode. If specified = Enable') |
32 | | - pybladerf_sweep_parser.add_argument('-N', action='store', help='num_sweeps. Number of sweeps to perform', metavar='') |
| 36 | + pybladerf_sweep_parser.add_argument('-N', action='store', help='Number of sweeps to perform', metavar='') |
33 | 37 | pybladerf_sweep_parser.add_argument('-o', action='store_true', help='oversample. If specified = Enable') |
| 38 | + pybladerf_sweep_parser.add_argument('-p', action='store_true', help='antenna port power. If specified = Enable') |
34 | 39 | pybladerf_sweep_parser.add_argument('-B', action='store_true', help='binary output. If specified = Enable') |
35 | | - pybladerf_sweep_parser.add_argument('-s', action='store', help='sweep style ("L" - LINEAR, "I" - INTERLEAVED). Default is INTERLEAVED', metavar='', default='I') |
36 | | - pybladerf_sweep_parser.add_argument('-SR', action='store', help='sample rate in Hz (0.5 MHz - 122 MHz). Default is 57. To use a sample rate higher than 61, specify oversample', metavar='', default=57) |
37 | | - pybladerf_sweep_parser.add_argument('-BW', action='store', help='bandwidth in Hz (0.2 MHz - 56 MHz). Default is 56000000', metavar='', default=56.0) |
38 | | - pybladerf_sweep_parser.add_argument('-FIR', action='store', help='RFIC RX FIR filter ("1" - Enable, "0" - Disable). Default is Disable', metavar='', default='0') |
39 | | - pybladerf_sweep_parser.add_argument('-r', action='store', help='filename. output file', metavar='') |
| 40 | + pybladerf_sweep_parser.add_argument('-S', action='store', help='sweep style ("L" - LINEAR, "I" - INTERLEAVED). Default is INTERLEAVED', metavar='', default='I') |
| 41 | + pybladerf_sweep_parser.add_argument('-s', action='store', help='sample rate in MHz (0.5 MHz - 122 MHz). Default is 61. To use a sample rate higher than 61, specify oversample', metavar='', default=61) |
| 42 | + pybladerf_sweep_parser.add_argument('-b', action='store', help='baseband filter bandwidth in MHz (0.2 MHz - 56 MHz). Default .75 * sample rate', metavar='') |
| 43 | + pybladerf_sweep_parser.add_argument('-r', action='store', help='<filename> output file', metavar='') |
| 44 | + |
| 45 | + |
| 46 | + pybladerf_transfer_parser = subparsers.add_parser( |
| 47 | + 'transfer', help='Send and receive signals using BladeRF. Input/output files consist of complex64 quadrature samples.', usage='python_bladerf transfer [-h] [-d] [-r] [-t] [-f] [-p] [-c] [-g] [-N] [-R] [-s] -[b] [-H] -[o]', |
| 48 | + ) |
| 49 | + pybladerf_transfer_parser.add_argument('-d', action='store', help='device identifier of desired BladeRF', metavar='') |
| 50 | + pybladerf_transfer_parser.add_argument('-r', action='store', help='<filename> receive data into file (use "-" for stdout)', metavar='') |
| 51 | + pybladerf_transfer_parser.add_argument('-t', action='store', help='<filename> transmit data from file (use "-" for stdin)', metavar='') |
| 52 | + pybladerf_transfer_parser.add_argument('-f', '--freq_hz', action='store', help='frequency in Hz (0MHz to 6000MHz supported). Default is 900MHz', metavar='', default=900_000_000) |
| 53 | + pybladerf_transfer_parser.add_argument('-p', action='store_true', help='antenna port power. If specified = Enable') |
| 54 | + pybladerf_transfer_parser.add_argument('-c', action='store', help='RX or TX channel. which channel to use (0, 1). Default is 0', metavar='', default=0) |
| 55 | + pybladerf_transfer_parser.add_argument('-g', action='store', help='RX or TX gain, RX: -15 - 60dB, 1dB steps, TX: -24 - 66 dB, 1dB steps', metavar='', default=20) |
| 56 | + pybladerf_transfer_parser.add_argument('-N', action='store', help='number of samples to transfer (default is unlimited)', metavar='') |
| 57 | + pybladerf_transfer_parser.add_argument('-R', action='store_true', help='repeat TX mode. Fefault is off') |
| 58 | + pybladerf_transfer_parser.add_argument('-s', action='store', help='sample rate in MHz (0.5 MHz - 122 MHz). Default is 61. To use a sample rate higher than 61, specify oversample', metavar='', default=61) |
| 59 | + pybladerf_transfer_parser.add_argument('-b', action='store', help='baseband filter bandwidth in MHz (0.2 MHz - 56 MHz). Default .75 * sample rate', metavar='') |
| 60 | + pybladerf_transfer_parser.add_argument('-H', action='store_true', help='synchronize RX/TX to external trigger input') |
| 61 | + pybladerf_transfer_parser.add_argument('-o', action='store_true', help='oversample. If specified = Enable') |
| 62 | + |
40 | 63 |
|
41 | 64 | if len(sys.argv) == 1: |
42 | 65 | parser.print_help() |
43 | 66 | sys.exit(0) |
44 | 67 |
|
45 | | - args, unparsed_args = parser.parse_known_args() |
| 68 | + args, _ = parser.parse_known_args() |
46 | 69 | if args.command == 'info': |
47 | 70 | if args.device_identifiers: |
48 | 71 | pybladerf_info.pybladerf_device_identifiers_list_info() |
49 | 72 | else: |
50 | 73 | pybladerf_info.pybladerf_info() |
51 | 74 |
|
52 | 75 | elif args.command == 'sweep': |
53 | | - frequency_range = args.f.split(':') |
54 | | - frequencies = [71, 5999] |
55 | | - freq_min, freq_max = None, None |
56 | | - try: |
57 | | - freq_min = int(frequency_range[0]) |
58 | | - except Exception: |
59 | | - pass |
60 | | - try: |
61 | | - freq_max = int(frequency_range[1]) |
62 | | - except Exception: |
63 | | - pass |
64 | | - if freq_min is not None and freq_max is not None: |
65 | | - frequencies = [freq_min, freq_max] |
| 76 | + str_frequencies = args.f.split(',') |
| 77 | + frequencies = [] |
| 78 | + for frequency_range in str_frequencies: |
| 79 | + try: |
| 80 | + freq_min, freq_max = map(int, frequency_range.split(':')) |
| 81 | + frequencies.extend([freq_min, freq_max]) |
| 82 | + except Exception: |
| 83 | + pass |
66 | 84 |
|
67 | 85 | pybladerf_sweep.pybladerf_sweep(frequencies=frequencies, |
| 86 | + sample_rate=float(args.s) * 1e6, |
| 87 | + baseband_filter_bandwidth=float(args.b) * 1e6 if args.b is not None else None, |
68 | 88 | gain=int(args.g), |
69 | 89 | bin_width=int(args.w), |
70 | | - sample_rate=float(args.SR) * 1e6, |
71 | | - bandwidth=float(args.BW) * 1e6, |
72 | | - channel=int(args.ch), |
| 90 | + channel=int(args.c), |
73 | 91 | oversample=args.o, |
74 | | - num_sweeps=int(args.N) if args.N is not None else None, |
| 92 | + antenna_enable=args.p, |
| 93 | + sweep_style=pybladerf.pybladerf_sweep_style.PYBLADERF_SWEEP_STYLE_LINEAR if args.s == 'L' else (pybladerf.pybladerf_sweep_style.PYBLADERF_SWEEP_STYLE_INTERLEAVED if args.s == 'I' else -1), |
| 94 | + device_identifier=args.d, |
75 | 95 | binary_output=args.B, |
76 | 96 | one_shot=args.__dict__.get('1'), |
| 97 | + num_sweeps=int(args.N) if args.N is not None else None, |
77 | 98 | filename=args.r, |
78 | | - device_identifier=args.d, |
79 | | - rxfir=pybladerf.pybladerf_rfic_rxfir.PYBLADERF_RFIC_RXFIR_DEC1 if args.FIR == '1' else (pybladerf.pybladerf_rfic_rxfir.PYBLADERF_RFIC_RXFIR_BYPASS if args.FIR == '0' else -1), |
80 | | - sweep_style=pybladerf.pybladerf_sweep_style.PYBLADERF_SWEEP_STYLE_LINEAR if args.s == 'L' else (pybladerf.pybladerf_sweep_style.PYBLADERF_SWEEP_STYLE_INTERLEAVED if args.s == 'I' else -1), |
81 | 99 | print_to_console=True) |
82 | 100 |
|
| 101 | + elif args.command == 'transfer': |
| 102 | + pybladerf_transfer.pybladerf_transfer( |
| 103 | + frequency=int(args.freq_hz), |
| 104 | + sample_rate=int(args.s) * 1e6, |
| 105 | + baseband_filter_bandwidth=float(args.b) * 1e6 if args.b is not None else None, |
| 106 | + gain=int(args.g), |
| 107 | + channel=int(args.c), |
| 108 | + oversample=args.o, |
| 109 | + antenna_enable=args.p, |
| 110 | + repeat_tx=args.R, |
| 111 | + synchronize=args.H, |
| 112 | + num_samples=int(args.N) if args.N is not None else None, |
| 113 | + device_identifier=args.d, |
| 114 | + rx_filename=args.r, |
| 115 | + tx_filename=args.t, |
| 116 | + print_to_console=True, |
| 117 | + ) |
| 118 | + |
83 | 119 |
|
84 | 120 | if __name__ == '__main__': |
85 | 121 | main() |
0 commit comments