|
1 # -*- coding: utf-8 -*- |
|
2 """ |
|
3 state_decoder |
|
4 ============= |
|
5 |
|
6 Module for decoding the internal state of the HP3562A DSA, using the |
|
7 GPIB command "DSBN" (Dump State BiNary). |
|
8 |
|
9 This file can be exectued as a python script. Use '-h' for more informations. |
|
10 """ |
|
11 from HP3562A import format_header, decode_float, decode_string, decode_header |
|
12 |
|
13 from HP3562A.enum_types import * |
|
14 |
|
15 HEADER = [("Measurement mode", EMEAS, 'h', 2), |
|
16 ("Measurement 1", EMTYP, 'h', 2), |
|
17 ("Measurement 2", EMTYP, 'h', 2), |
|
18 ("Window type", EWINTYP, 'h', 2), |
|
19 ("Force/Expon window 1", EFEXPW, 'h', 2), |
|
20 ("Force/Expon window 2", EFEXPW, 'h', 2), |
|
21 ("Average type", EAVGTYP, 'h', 2), |
|
22 ("Overlap percentage", int, 'h', 2), |
|
23 ("Number of averages", int, 'h', 2), |
|
24 ("Sweep # of averages", int, 'h', 2), |
|
25 ("Trigger type", ETRGTYP, 'h', 2), |
|
26 ("Trigger slope", ETRGSLP, 'h', 2), |
|
27 ("Preview type", EPRVTYP, 'h', 2), |
|
28 ("Sample type", ESMPTYP, 'h', 2), |
|
29 ("Range units chan 1", ERNGUNT, 'h', 2), |
|
30 ("Range units chan 2", ERNGUNT, 'h', 2), |
|
31 ("Range type 1", ERNGTYP, 'h', 2), |
|
32 ("Range type 2", ERNGTYP, 'h', 2), |
|
33 ("Input coupling 1", EINCPL, 'h', 2), |
|
34 ("Input coupling 2", EINCPL, 'h', 2), |
|
35 ("Source type", ESRCTYP, 'h', 2), |
|
36 ("Chirp percent", int, 'h', 2), |
|
37 ("Burst percent", int, 'h', 2), |
|
38 ("Sweep direction", ESWPDIR, 'h', 2), |
|
39 ("Sweep mode", ESWPMOD, 'h', 2), |
|
40 ("Ext sample freq untis", EXAXIS, 'h', 2), |
|
41 ("Bandwidth units", EXAXIS, 'h', 2), |
|
42 ("Log span index", int, 'h', 2), |
|
43 ("Log start index", int, 'h', 2), |
|
44 ("Sweep rate units", EXAXIS, 'h', 2), |
|
45 ("Auto gain ref chan", EDEMODCH, 'h', 2), |
|
46 ("Demod channels", EDEMODCH, 'h', 2), |
|
47 ("Demod type chan 1", EDEMOD, 'h', 2), |
|
48 ("Demod type chan 2", EDEMOD, 'h', 2), |
|
49 ("Source level units", EXAXIS, 'h', 2), |
|
50 ("Source offset units", EXAXIS, 'h', 2), |
|
51 ("Trigger level units", EXAXIS, 'h', 2), |
|
52 ("Capt/thru length units", EXAXIS, 'h', 2), |
|
53 ("EU label 1", str, 's', 6), |
|
54 ("EU label 2", str, 's', 6), |
|
55 ("Auto carrier on/off", bool, 'h', 2), |
|
56 ("Time average on/off", bool, 'h', 2), |
|
57 ("Auto/fixed resolution", bool, 'h', 2), |
|
58 ("Auto gain on/off", bool, 'h', 2), |
|
59 ("Auto/fixed integrate",bool, 'h', 2), |
|
60 ("Fast average on/off", bool, 'h', 2), |
|
61 ("Overload reject on/off", bool, 'h', 2), |
|
62 ("Chan 1 float/ground", bool, 'h', 2), |
|
63 ("Chan 2 float/ground", bool, 'h', 2), |
|
64 ("Time throughput on/off", bool, 'h', 2), |
|
65 ("Demodulation on/off", bool, 'h', 2), |
|
66 ("EU/volts chan 1", bool, 'h', 2), |
|
67 ("EU/volts chan 2", bool, 'h', 2), |
|
68 ("Manual/auto arm", bool, 'h', 2), |
|
69 ("Demod preview on/off", bool, 'h', 2), |
|
70 ("Delete freq on/off", bool, 'h', 2), |
|
71 ("Lin res Fstart pegged", bool, 'h', 2), |
|
72 ("Swept Fstart pegged", bool, 'h', 2), |
|
73 ("Force length chan 1", decode_float, None, 4), |
|
74 ("Force length chan 2", decode_float, None, 4), |
|
75 ("Expon time constant 1", decode_float, None, 4), |
|
76 ("Expon time constant 2", decode_float, None, 4), |
|
77 ("Sweep time", decode_float, None, 4), |
|
78 ("Sweep rate", decode_float, None, 4), |
|
79 ("Sweep resolution", decode_float, None, 4), |
|
80 ("Sweep integrate time", decode_float, None, 4), |
|
81 ("Auto gain level", decode_float, None, 4), |
|
82 ("Auto gain limit", decode_float, None, 4), |
|
83 ("Source level", decode_float, None, 4), |
|
84 ("EU value chan 1", decode_float, None, 4), |
|
85 ("EU value chan 2", decode_float, None, 4), |
|
86 ("Trigger delay chan 1", decode_float, None, 4), |
|
87 ("Trigger delay chan 2", decode_float, None, 4), |
|
88 ("Integrate var thresh", decode_float, None, 4), |
|
89 ("Capt/thru length", decode_float, None, 4), |
|
90 ("Frequency span", decode_float, None, 4), |
|
91 ("Time record length", decode_float, None, 4), |
|
92 ("Frequency resolution", decode_float, None, 4), |
|
93 ("Time resolution", decode_float, None, 4), |
|
94 ("External sample rate", decode_float, None, 4), |
|
95 ("Sample rate (actual)", decode_float, None, 4), |
|
96 ("Range channel 1", decode_float, None, 4), |
|
97 ("Range channel 2", decode_float, None, 4), |
|
98 ("Preview time", decode_float, None, 4), |
|
99 ("Trigger level", decode_float, None, 4), |
|
100 ("Source dc offset", decode_float, None, 4), |
|
101 ("Fixed sine frequency", decode_float, None, 8), |
|
102 ("Start frequency", decode_float, None, 8), |
|
103 ("Center frequency", decode_float, None, 8), |
|
104 ("Sweep start", decode_float, None, 8), |
|
105 ("Sweep end", decode_float, None, 8), |
|
106 ("Carrier frequency", decode_float, None, 8), |
|
107 ] |
|
108 |
|
109 def decode_state(data): |
|
110 """ |
|
111 Decode the data (as generated by the HP3562A DSA in response to a |
|
112 "DSBN" command), and returns a dict (header) |
|
113 |
|
114 header is the dictionnary of the header of the dumped data block, |
|
115 """ |
|
116 header, idx = decode_header(data, HEADER) |
|
117 return header |
|
118 |
|
119 |
|
120 def main(): |
|
121 import sys |
|
122 import optparse |
|
123 opt = optparse.OptionParser("A simple tool for tracing a dumped trace") |
|
124 opt.add_option('-f', '--filename', default=None, |
|
125 dest='filename', |
|
126 help='Output filename. If not set, read from stdin') |
|
127 opt.add_option('-m', '--mode', default='binary', |
|
128 dest='mode', |
|
129 help='Dumping mode (may be "binary" [default], "ascii" or "ansi")', |
|
130 ) |
|
131 |
|
132 options, argv = opt.parse_args(sys.argv) |
|
133 |
|
134 |
|
135 if options.filename is None: |
|
136 print "Can't deal stdin for now..." |
|
137 sys.exit(1) |
|
138 #try: |
|
139 if 1: |
|
140 header = decode_state(open(options.filename, 'rb').read()) |
|
141 else: |
|
142 #except Exception, e: |
|
143 print "ERROR: can't read %s an interpret it as a HP3562 trace"%options.filename |
|
144 print e |
|
145 sys.exit(1) |
|
146 |
|
147 print format_header(header, HEADER, 100) |
|
148 |
|
149 if __name__ == "__main__": |
|
150 main() |
|
151 |