mirror of
				https://github.com/brmlab/osmo-tetra.git
				synced 2025-10-31 15:33:59 +01:00 
			
		
		
		
	Add UHD based demodulator script (tested with N200+WBX)
This commit is contained in:
		
							parent
							
								
									5707cb731c
								
							
						
					
					
						commit
						e417cc16f5
					
				
					 1 changed files with 119 additions and 0 deletions
				
			
		
							
								
								
									
										119
									
								
								src/demod/python/uhd-tetra_demod.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/demod/python/uhd-tetra_demod.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,119 @@ | |||
| #!/usr/bin/env python | ||||
| 
 | ||||
| import sys | ||||
| import math | ||||
| from gnuradio import gr, gru, audio, eng_notation, blks2, optfir | ||||
| from gnuradio import uhd | ||||
| from gnuradio.eng_option import eng_option | ||||
| from optparse import OptionParser | ||||
| 
 | ||||
| # Load it locally or from the module | ||||
| try: | ||||
|     import cqpsk | ||||
| except: | ||||
|     from tetra_demod import cqpsk | ||||
| 
 | ||||
| # accepts an input file in complex format  | ||||
| # applies frequency translation, resampling (interpolation/decimation) | ||||
| 
 | ||||
| class my_top_block(gr.top_block): | ||||
|     def __init__(self, options): | ||||
|         gr.top_block.__init__(self) | ||||
| 
 | ||||
|         # Create a UHD source | ||||
|         self._u = uhd.usrp_source( | ||||
|                device_addr=options.device_addr, | ||||
|                io_type=uhd.io_type.COMPLEX_FLOAT32, | ||||
|                num_channels=1) | ||||
|          | ||||
|         sample_rate = 100e6/512 | ||||
|         symbol_rate = 18000 | ||||
|         sps = 2 | ||||
|          | ||||
|         # set sampling rate and antenna port | ||||
|         self._u.set_samp_rate(sample_rate) | ||||
|         self._u.set_antenna(options.antenna, 0) | ||||
|          | ||||
|         # output rate will be 36,000 | ||||
|         ntaps = 11 * sps | ||||
|         new_sample_rate = symbol_rate * sps | ||||
|          | ||||
|         # Set receive daughterboard gain | ||||
|         if options.gain is None: | ||||
|             g = self._u.get_gain_range() | ||||
|             options.gain = float(g.stop()+g.start())/2 | ||||
|             print "Using mid-point gain of", options.gain, "(", g.start(), "-", g.stop(), ")" | ||||
|         self._u.set_gain(options.gain) | ||||
|   | ||||
|         # Set receive frequency | ||||
|         if options.lo_offset is not None: | ||||
|             self._u.set_lo_offset(options.lo_offset) | ||||
| 
 | ||||
|         tr = self._u.set_center_freq(options.freq) | ||||
|         if tr == None: | ||||
|             sys.stderr.write('Failed to set center frequency\n') | ||||
|             raise SystemExit, 1 | ||||
| 
 | ||||
|         channel_taps = gr.firdes.low_pass(1.0, sample_rate, options.low_pass, options.low_pass * 0.1, gr.firdes.WIN_HANN) | ||||
| 
 | ||||
|         FILTER = gr.freq_xlating_fir_filter_ccf(1, channel_taps, options.calibration, sample_rate) | ||||
| 
 | ||||
|         sys.stderr.write("sample rate: %d\n" %(sample_rate)) | ||||
| 
 | ||||
|         DEMOD = cqpsk.cqpsk_demod( samples_per_symbol = sps, | ||||
|                                  excess_bw=0.35, | ||||
|                                  costas_alpha=0.03, | ||||
|                                  gain_mu=0.05, | ||||
|                                  mu=0.05, | ||||
|                                  omega_relative_limit=0.05, | ||||
|                                  log=options.log, | ||||
|                                  verbose=options.verbose) | ||||
| 
 | ||||
|         OUT = gr.file_sink(gr.sizeof_float, options.output_file) | ||||
| 
 | ||||
|         r = float(sample_rate) / float(new_sample_rate) | ||||
| 
 | ||||
|         INTERPOLATOR = gr.fractional_interpolator_cc(0, r) | ||||
| 
 | ||||
|         self.connect(self._u, FILTER, INTERPOLATOR, DEMOD, OUT) | ||||
| 
 | ||||
| def get_options(): | ||||
|     parser = OptionParser(option_class=eng_option) | ||||
|     # usrp related settings | ||||
|     parser.add_option("-d", "--device_addr", type="string", default="", | ||||
|                       help="UHD device address [default=%default]") | ||||
|     parser.add_option("-a", "--antenna", type="string", default="TX/RX", | ||||
|                       help="daughterboard antenna [default=%default]") | ||||
|     parser.add_option("-f", "--freq", type="eng_float", default=None, | ||||
|                       help="set frequency to FREQ", metavar="FREQ") | ||||
|     parser.add_option("-g", "--gain", type="eng_float", default=None, | ||||
|                       help="set gain in dB (default is midpoint)") | ||||
|     parser.add_option("", "--lo-offset", type="eng_float", default=None, | ||||
|                       help="set daughterboard LO offset to OFFSET [default=hw default]") | ||||
| 
 | ||||
|     # demodulator related settings | ||||
|     parser.add_option("-c", "--calibration", type="int", default=0, help="freq offset") | ||||
|     parser.add_option("-l", "--log", action="store_true", default=False, help="dump debug .dat files") | ||||
|     parser.add_option("-L", "--low-pass", type="eng_float", default=25e3, help="low pass cut-off", metavar="Hz") | ||||
|     parser.add_option("-o", "--output-file", type="string", default="out.float", help="specify the bit output file") | ||||
|     parser.add_option("-v", "--verbose", action="store_true", default=False, help="dump demodulation data") | ||||
| 
 | ||||
|     (options, args) = parser.parse_args() | ||||
|     if len(args) != 0: | ||||
|         parser.print_help() | ||||
|         raise SystemExit, 1 | ||||
|      | ||||
|     if options.freq is None: | ||||
|         parser.print_help() | ||||
|         sys.stderr.write('You must specify the frequency with -f FREQ\n'); | ||||
|         raise SystemExit, 1 | ||||
|      | ||||
|     return (options) | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     (options) = get_options() | ||||
|     tb = my_top_block(options) | ||||
|     try: | ||||
|         tb.run() | ||||
|     except KeyboardInterrupt: | ||||
|         tb.stop() | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Clemens Hopfer
						Clemens Hopfer