From aca19119fd7790b083e6777d7ba29f8da0f83c06 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 20 Aug 2015 22:32:35 +0200 Subject: [PATCH] Add support for transmission via UHD devices this is currently only tested with an USRP2, but should work similarly with other UHD devices. --- README.md | 13 +++++++- gps-sdr-sim-uhd.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100755 gps-sdr-sim-uhd.py diff --git a/README.md b/README.md index 26d93e9..60d4649 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,11 @@ Doppler for the GPS satellites in view. This simulated range data is then used to generate the digitized I/Q samples for the GPS signal. The bladeRF command line interface requires I/Q pairs stored as signed -16-bit integers, while the hackrf_transfer supports signed bytes. +16-bit integers, while the hackrf_transfer and gps-sdr-sim-uhd.py +supports signed bytes. + +HackRF + bladeRF require 2.6 MHz sample rate, while the USRP2 requires +2.5 MHz (an even integral decimator of 100 MHz). ``` Usage: gps-sdr-sim [options] @@ -92,6 +96,13 @@ For the HackRF: > hackrf_transfer -t gpssim.bin -f 1575420000 -s 2600000 -a 1 -x 0 ``` +For UHD supported devices (tested with USRP2 only): + +``` +> gps-sdr-sim-uhd.py -t gpssim.bin -s 2500000 -x 0 +``` + + ### License Copyright © 2015 Takuji Ebinuma diff --git a/gps-sdr-sim-uhd.py b/gps-sdr-sim-uhd.py new file mode 100755 index 0000000..06da2ce --- /dev/null +++ b/gps-sdr-sim-uhd.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# a small script to transmit simulated GPS samples via UHD +# (C) 2015 by Harald Welte +# Licensed under the MIT License (see LICENSE) + +from gnuradio import blocks +from gnuradio import eng_notation +from gnuradio import gr +from gnuradio import uhd +from gnuradio.eng_option import eng_option +from gnuradio.filter import firdes +from optparse import OptionParser +import time + +class top_block(gr.top_block): + + def __init__(self, options): + gr.top_block.__init__(self, "GPS-SDR-SIM") + + ################################################## + # Blocks + ################################################## + self.uhd_usrp_sink = uhd.usrp_sink( + ",".join(("", "")), + uhd.stream_args( + cpu_format="fc32", + channels=range(1), + ), + ) + self.uhd_usrp_sink.set_samp_rate(options.sample_rate) + self.uhd_usrp_sink.set_center_freq(options.frequency, 0) + self.uhd_usrp_sink.set_gain(options.gain, 0) + + # a file source for the file generated by the gps-sdr-sim + self.blocks_file_source = blocks.file_source(gr.sizeof_char*1, options.filename, True) + + # convert from signed bytes to short + self.blocks_char_to_short = blocks.char_to_short(1) + + # convert from interleaved short to complex values + self.blocks_interleaved_short_to_complex = blocks.interleaved_short_to_complex(False, False) + + # establish the connections + self.connect((self.blocks_file_source, 0), (self.blocks_char_to_short, 0)) + self.connect((self.blocks_char_to_short, 0), (self.blocks_interleaved_short_to_complex, 0)) + self.connect((self.blocks_interleaved_short_to_complex, 0), (self.uhd_usrp_sink, 0)) + +def get_options(): + parser = OptionParser(option_class=eng_option) + parser.add_option("-x", "--gain", type="eng_float", default=0, + help="set transmitter gain [default=0]") + parser.add_option("-f", "--frequency", type="eng_float", default=1575420000, + help="set transmit frequency [default=1575420000]") + # On USRP2, the sample rate should lead to an even decimator + # based on the 100 MHz clock. At 2.5 MHz, we end up with 40 + parser.add_option("-s", "--sample-rate", type="eng_float", default=2500000, + help="set sample rate [default=2500000]") + parser.add_option("-t", "--filename", type="string", default="gpssim.bin", + help="set output file name [default=gpssim.bin]") + + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + raise SystemExit, 1 + + return (options) + +if __name__ == '__main__': + (options) = get_options() + tb = top_block(options) + tb.start() + raw_input('Press Enter to quit: ') + tb.stop() + tb.wait()