Initial revision.
git-svn-id: http://op25.osmocom.org/svn/trunk@4 65a5c917-d112-43f1-993d-58c26a4786be
This commit is contained in:
parent
9efb460101
commit
f4de17dfb0
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env python
|
||||
from gnuradio import gr, gru, usrp, audio, eng_notation, blks
|
||||
from gnuradio.eng_option import eng_option
|
||||
from optparse import OptionParser
|
||||
|
||||
"""
|
||||
This app reads baseband data from file and demodulates that baseband
|
||||
as a P25 DQPSK signal (in theory, this is sufficient to capture both
|
||||
phase I and phase II signals).
|
||||
"""
|
||||
|
||||
class app_flow_graph(gr.flow_graph):
|
||||
def __init__(self, options):
|
||||
gr.flow_graph.__init__(self)
|
||||
|
||||
usrp_rate = 64000000
|
||||
sample_rate = usrp_rate // options.decim
|
||||
|
||||
reqd_sample_rate = 57600
|
||||
symbol_rate = 4800
|
||||
|
||||
IN = gr.file_source(gr.sizeof_gr_complex, options.input_file)
|
||||
|
||||
coeffs = gr.firdes.low_pass (1.0, sample_rate, 11.5e3, 1.0e3, gr.firdes.WIN_HANN)
|
||||
FILT = gr.freq_xlating_fir_filter_ccf(1, coeffs, 0, sample_rate)
|
||||
|
||||
lcm = gru.lcm(sample_rate, reqd_sample_rate)
|
||||
intrp = int(lcm // sample_rate)
|
||||
decim = int(lcm // reqd_sample_rate)
|
||||
RSAMP = blks.rational_resampler_ccc(self, intrp, decim)
|
||||
|
||||
DEMOD = blks.dqpsk_demod(self,
|
||||
samples_per_symbol = reqd_sample_rate // symbol_rate,
|
||||
excess_bw=0.35,
|
||||
costas_alpha=0.03,
|
||||
gain_mu=0.05,
|
||||
mu=0.005,
|
||||
omega_relative_limit=0.05,
|
||||
gray_code=options.gray_code,
|
||||
verbose=options.verbose)
|
||||
|
||||
# FS "$5575f5ff77ff"
|
||||
fsm="010101010111010111110101111111110111011111111111"
|
||||
CORR = gr.correlate_access_code_bb(fsm, 0)
|
||||
|
||||
OUT = gr.file_sink(gr.sizeof_char, options.output_file)
|
||||
|
||||
self.connect(IN, FILT, RSAMP, DEMOD, CORR, OUT)
|
||||
|
||||
def main():
|
||||
parser = OptionParser(option_class=eng_option)
|
||||
parser.add_option("-d", "--decim", type="int", default=256, help="set decimation")
|
||||
parser.add_option("-g", "--gray-code", action="store_true", default=False, help="use gray code")
|
||||
parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file")
|
||||
parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file")
|
||||
parser.add_option("-r", "--repeat", action="store_true", default=False, help="repeat input in a loop")
|
||||
parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
fg = app_flow_graph(options)
|
||||
try:
|
||||
fg.run()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env python
|
||||
from gnuradio import gr, gru, usrp, audio, eng_notation, blks
|
||||
from gnuradio.eng_option import eng_option
|
||||
from optparse import OptionParser
|
||||
|
||||
"""
|
||||
This application samples a narrowband channel and writes complex
|
||||
baseband data to file. To collect data only for transmissions the
|
||||
channel is gated using a power squelch.
|
||||
"""
|
||||
|
||||
class usrp_source_c(gr.hier_block):
|
||||
|
||||
"""
|
||||
Initialize the USRP.
|
||||
"""
|
||||
|
||||
def __init__(self, fg, subdev_spec, decim, gain=None):
|
||||
self._decim = decim
|
||||
self._src = usrp.source_c()
|
||||
if subdev_spec is None:
|
||||
subdev_spec = usrp.pick_rx_subdevice(self._src)
|
||||
self._subdev = usrp.selected_subdev(self._src, subdev_spec)
|
||||
print "Using RX d'board %s" % (self._subdev.side_and_name(),)
|
||||
self._src.set_mux(usrp.determine_rx_mux_value(self._src, subdev_spec))
|
||||
self._src.set_decim_rate(self._decim)
|
||||
if gain is None:
|
||||
g = self._subdev.gain_range()
|
||||
gain = (g[0]+g[1])/2.0
|
||||
self._subdev.set_gain(gain)
|
||||
gr.hier_block.__init__(self, fg, self._src, self._src)
|
||||
|
||||
def tune(self, freq):
|
||||
r = usrp.tune(self._src, 0, self._subdev, freq)
|
||||
|
||||
class app_flow_graph(gr.flow_graph):
|
||||
def __init__(self, options):
|
||||
gr.flow_graph.__init__(self)
|
||||
|
||||
usrp_rate = 64000000
|
||||
sample_rate = usrp_rate // options.decim
|
||||
|
||||
if options.frequency:
|
||||
USRP = usrp_source_c(self, options.rx_subdev_spec, options.decim, options.gain)
|
||||
USRP.tune(options.frequency)
|
||||
IN = USRP
|
||||
elif options.input:
|
||||
FILE = gr.file_source(gr.sizeof_gr_complex, options.input)
|
||||
THROTTLE = gr.throttle(gr.sizeof_gr_complex, sample_rate);
|
||||
self.connect(FILE, THROTTLE)
|
||||
IN = THROTTLE
|
||||
else:
|
||||
print "error: no source selected"
|
||||
exit
|
||||
|
||||
coeffs = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN)
|
||||
FILT = gr.freq_xlating_fir_filter_ccf(1, coeffs, options.calibration, sample_rate)
|
||||
self.connect(IN, FILT)
|
||||
|
||||
RFSQL = gr.pwr_squelch_cc(options.rf_squelch, 1e-3, 0, True)
|
||||
self.connect(FILT, RFSQL)
|
||||
|
||||
OUT = gr.file_sink(gr.sizeof_gr_complex, options.output)
|
||||
self.connect(RFSQL, OUT)
|
||||
|
||||
def main():
|
||||
parser = OptionParser(option_class=eng_option)
|
||||
parser.add_option("-c", "--calibration", type="eng_float", default=0, help="calibration offset", metavar="Hz")
|
||||
parser.add_option("-d", "--decim", type="int", default=256, help="set decimation")
|
||||
parser.add_option("-f", "--frequency", type="eng_float", default=None, help="set receive frequency", metavar="Hz")
|
||||
parser.add_option("-g", "--gain", type="int", default=None, help="set RF gain", metavar="dB")
|
||||
parser.add_option("-i", "--input", type="string", default=None, help="the input file")
|
||||
parser.add_option("-l", "--low-pass", type="eng_float", default=25e3, help="low pass cut-off", metavar="Hz")
|
||||
parser.add_option("-o", "--output", type="string", default="baseband.dat", help="the output file")
|
||||
parser.add_option("-r", "--rf-squelch", type="eng_float", default=0.0, help="set RF squelch to dB", metavar="dB")
|
||||
parser.add_option("-R", "--rx-subdev-spec", type="subdev", help="select USRP Rx side A or B", metavar="SUBDEV")
|
||||
(options, args) = parser.parse_args()
|
||||
if options.frequency:
|
||||
if options.frequency < 1e6:
|
||||
options.frequency *= 1e6
|
||||
fg = app_flow_graph(options)
|
||||
try:
|
||||
fg.run()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from gnuradio import gr, gru
|
||||
from gnuradio import eng_notation
|
||||
from gnuradio.eng_option import eng_option
|
||||
from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider
|
||||
from optparse import OptionParser
|
||||
import wx
|
||||
import sys
|
||||
|
||||
class app_flow_graph(stdgui.gui_flow_graph):
|
||||
|
||||
def __init__(self, frame, panel, vbox, argv):
|
||||
stdgui.gui_flow_graph.__init__(self)
|
||||
|
||||
self.frame = frame
|
||||
self.panel = panel
|
||||
|
||||
parser = OptionParser(option_class=eng_option)
|
||||
parser.add_option("-d", "--decim", type="int", default=256, help="set decimation")
|
||||
parser.add_option("-i", "--input", default="baseband.dat", help="specify input file")
|
||||
parser.add_option("-r", "--repeat", action="store_true", default=False, help="repeat in a loop")
|
||||
parser.add_option("-W", "--waterfall", action="store_true", default=False, help="enable waterfall display")
|
||||
parser.add_option("-S", "--oscilloscope", action="store_true", default=False, help="enable simple oscilloscope")
|
||||
parser.add_option("-c", "--complex-scope", action="store_true", default=False, help="enable complex oscilloscope")
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) != 0:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
usrp_rate = 64000000
|
||||
sample_rate = usrp_rate // options.decim
|
||||
|
||||
FILE = gr.file_source(gr.sizeof_gr_complex, options.input, options.repeat)
|
||||
|
||||
THROTTLE = gr.throttle(gr.sizeof_gr_complex, sample_rate);
|
||||
|
||||
if options.waterfall:
|
||||
SCOPE = waterfallsink.waterfall_sink_c (self, panel, fft_size=1024, sample_rate=sample_rate)
|
||||
self.connect(FILE, THROTTLE, SCOPE)
|
||||
elif options.complex_scope:
|
||||
SCOPE = scopesink.scope_sink_c(self, panel, sample_rate=sample_rate)
|
||||
self.connect(FILE, THROTTLE, SCOPE)
|
||||
elif options.oscilloscope:
|
||||
CONV = gr.complex_to_float()
|
||||
SCOPE = scopesink.scope_sink_f(self, panel, sample_rate=sample_rate)
|
||||
self.connect(FILE, THROTTLE, CONV, SCOPE)
|
||||
else:
|
||||
SCOPE = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=sample_rate)
|
||||
self.connect(FILE, THROTTLE, SCOPE)
|
||||
|
||||
vbox.Add(SCOPE.win, 10, wx.EXPAND)
|
||||
|
||||
def main ():
|
||||
app = stdgui.stdapp(app_flow_graph, "Signal Scope", nstatus=1)
|
||||
app.MainLoop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main ()
|
Reference in New Issue