tds.cpp
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #include "tds.h"
15 #include "charinterface.h"
16 #include "xwavengraph.h"
17 
18 REGISTER_TYPE(XDriverList, TDS, "Tektronix DSO");
19 
20 #ifdef _MSC_VER
21  #define strncasecmp strnicmp
22 #endif
23 
24 //---------------------------------------------------------------------------
25 XTDS::XTDS(const char *name, bool runtime,
26  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
27  XCharDeviceDriver<XDSO>(name, runtime, ref(tr_meas), meas) {
28  iterate_commit([=](Transaction &tr){
29  for(auto &&x: {trace1(), trace2(), trace3(), trace4()})
30  tr[ *x].add({"CH1", "CH2", "CH3", "CH4", "MATH1", "MATH2"});
31  for(auto &&x: {vFullScale1(), vFullScale2(), vFullScale3(), vFullScale4()})
32  tr[ *x].add({"0.02", "0.05", "0.1", "0.2", "0.5", "1", "2", "5", "10", "20", "50", "100"});
33  tr[ *trigSource()].add({"EXT", "EXT10", "CH1", "CH2", "CH3", "CH4", "LINE"});
34  });
35 
36  interface()->setGPIBWaitBeforeWrite(20); //20msec
37  interface()->setGPIBWaitBeforeSPoll(10); //10msec
38 
39  trans( *recordLength()) = 10000;
40 }
41 
42 void
43 XTDS::open() throw (XKameError &) {
44  interface()->send("HEADER ON");
45  interface()->query("ACQ:STOPAFTER?");
46  char buf[10];
47  if(interface()->scanf(":ACQ%*s %9s", buf) != 1)
48  throw XInterface::XConvError(__FILE__, __LINE__);
49  trans( *singleSequence()) = !strncmp(buf, "SEQ", 3);
50 
51  interface()->query("ACQ:MODE?");
52  if(interface()->scanf(":ACQ%*s %9s", buf) != 1)
53  throw XInterface::XConvError(__FILE__, __LINE__);
54  if( !strncmp(buf, "AVE", 3)) {
55  interface()->query("ACQ:NUMAVG?");
56  int x;
57  if(interface()->scanf(":ACQ%*s %d", &x) != 1)
58  throw XInterface::XConvError(__FILE__, __LINE__);
59  trans( *average()) = x;
60  }
61  if( !strncmp(buf, "SAM", 3))
62  trans( *average()) = 1;
63  interface()->send("DATA:ENC RPB;WIDTH 2"); //MSB first RIB
64 
65  start();
66 }
67 void
68 XTDS::onAverageChanged(const Snapshot &shot, XValueNodeBase *) {
69  if(shot[ *average()] == 1) {
70  interface()->send("ACQ:MODE SAMPLE");
71  }
72  else {
73  interface()->send("ACQ:MODE AVE;NUMAVG " + shot[ *average()].to_str());
74  }
75 }
76 
77 void
78 XTDS::onSingleChanged(const Snapshot &shot, XValueNodeBase *) {
79  if(shot[ *singleSequence()]) {
80  interface()->send("ACQ:STOPAFTER SEQUENCE;STATE ON");
81  }
82  else {
83  interface()->send("ACQ:STOPAFTER RUNSTOP;STATE ON");
84  }
85 }
86 void
87 XTDS::onTrigSourceChanged(const Snapshot &shot, XValueNodeBase *) {
88  interface()->send("TRIG:A:EDG:SOU " + shot[ *trigSource()].to_str());
89 }
90 void
91 XTDS::onTrigPosChanged(const Snapshot &shot, XValueNodeBase *) {
92  if(shot[ *trigPos()] >= 0)
93  interface()->sendf("HOR:DELAY:STATE OFF;TIME %.2g", (double)shot[ *trigPos()]);
94  else
95  interface()->sendf("HOR:DELAY:STATE ON;TIME %.2g", -(shot[ *trigPos()] - 50.0) / 100.0 * (double) ***timeWidth());
96 }
97 void
98 XTDS::onTrigLevelChanged(const Snapshot &shot, XValueNodeBase *) {
99  interface()->sendf("TRIG:A:EDG:LEV %g", (double)shot[ *trigLevel()]);
100 }
101 void
102 XTDS::onTrigFallingChanged(const Snapshot &shot, XValueNodeBase *) {
103  interface()->sendf("TRIG:A:EDG:SLOP %s", (shot[ *trigFalling()] ? "FALL" : "RISE"));
104 }
105 void
106 XTDS::onTimeWidthChanged(const Snapshot &shot, XValueNodeBase *) {
107  interface()->sendf("HOR:MAIN:SCALE %.1g", (double)shot[ *timeWidth()] / 10.0);
108 }
109 void
110 XTDS::onVFullScale1Changed(const Snapshot &shot, XValueNodeBase *) {
111  XString ch = ( **trace1())->to_str();
112  if(ch.empty()) return;
113  interface()->sendf("%s:SCALE %.1g", ch.c_str(), atof(shot[ *vFullScale1()].to_str().c_str()) / 10.0);
114 }
115 void
116 XTDS::onVFullScale2Changed(const Snapshot &shot, XValueNodeBase *) {
117  XString ch = ( **trace2())->to_str();
118  if(ch.empty()) return;
119  interface()->sendf("%s:SCALE %.1g", ch.c_str(), atof(shot[ *vFullScale2()].to_str().c_str()) / 10.0);
120 }
121 void
122 XTDS::onVFullScale3Changed(const Snapshot &shot, XValueNodeBase *) {
123  XString ch = ( **trace3())->to_str();
124  if(ch.empty()) return;
125  interface()->sendf("%s:SCALE %.1g", ch.c_str(), atof(shot[ *vFullScale3()].to_str().c_str())/10.0);
126 }
127 void
128 XTDS::onVFullScale4Changed(const Snapshot &shot, XValueNodeBase *) {
129  XString ch = ( **trace4())->to_str();
130  if(ch.empty()) return;
131  interface()->sendf("%s:SCALE %.1g", ch.c_str(), atof(shot[ *vFullScale4()].to_str().c_str())/10.0);
132 }
133 void
134 XTDS::onVOffset1Changed(const Snapshot &shot, XValueNodeBase *) {
135  XString ch = ( **trace1())->to_str();
136  if(ch.empty()) return;
137  interface()->sendf("%s:OFFSET %.8g", ch.c_str(), (double)shot[ *vOffset1()]);
138 }
139 void
140 XTDS::onVOffset2Changed(const Snapshot &shot, XValueNodeBase *) {
141  XString ch = ( **trace2())->to_str();
142  if(ch.empty()) return;
143  interface()->sendf("%s:OFFSET %.8g", ch.c_str(), (double)shot[ *vOffset2()]);
144 }
145 void
146 XTDS::onVOffset3Changed(const Snapshot &shot, XValueNodeBase *) {
147  XString ch = ( **trace3())->to_str();
148  if(ch.empty()) return;
149  interface()->sendf("%s:OFFSET %.8g", ch.c_str(), (double)shot[ *vOffset3()]);
150 }
151 void
152 XTDS::onVOffset4Changed(const Snapshot &shot, XValueNodeBase *) {
153  XString ch = ( **trace4())->to_str();
154  if(ch.empty()) return;
155  interface()->sendf("%s:OFFSET %.8g", ch.c_str(), (double)shot[ *vOffset4()]);
156 }
157 void
158 XTDS::onRecordLengthChanged(const Snapshot &shot, XValueNodeBase *) {
159  interface()->send("HOR:RECORD " +
160  shot[ *recordLength()].to_str());
161 }
162 void
163 XTDS::onForceTriggerTouched(const Snapshot &shot, XTouchableNode *) {
164  interface()->send("TRIG FORC");
165 }
166 
167 void
169  interface()->send("ACQ:STATE ON");
170 }
171 
172 int
173 XTDS::acqCount(bool *seq_busy) {
174  interface()->query("ACQ:NUMACQ?;:BUSY?");
175  int n;
176  int busy;
177  if(interface()->scanf(":ACQ%*s %d;:BUSY %d", &n, &busy) != 2)
178  throw XInterface::XConvError(__FILE__, __LINE__);
179  *seq_busy = busy;
180  return n;
181 }
182 
183 double
184 XTDS::getTimeInterval() {
185  interface()->query("WFMP?");
186  const char *cp = strstr(&interface()->buffer()[0], "XIN");
187  if( !cp) throw XInterface::XConvError(__FILE__, __LINE__);
188  double x;
189  int ret = sscanf(cp, "%*s %lf", &x);
190  if(ret != 1) throw XInterface::XConvError(__FILE__, __LINE__);
191  return x;
192 }
193 
194 void
195 XTDS::getWave(shared_ptr<RawData> &writer, std::deque<XString> &channels) {
196  XScopedLock<XInterface> lock( *interface());
197  int pos = 1;
198  int width = 20000;
199  for(std::deque<XString>::iterator it = channels.begin(); it != channels.end(); it++) {
200  int rsize = (2 * width + 1024);
201  interface()->sendf("DATA:SOURCE %s;START %u;STOP %u;:WAVF?",
202  (const char *)it->c_str(),
203  pos, pos + width);
204  interface()->receive(rsize);
205  writer->insert(writer->end(),
206  interface()->buffer().begin(), interface()->buffer().end());
207  }
208 }
209 void
211  double xin = 0;
212  double yin[256], yoff[256];
213  int width = 0;
214  double xoff = 0;
215  int triggerpos;
216 
217  int size = reader.size();
218  std::vector<char> bufcpy(reader.data());
219  bufcpy.push_back('\0');
220  char *buf = &bufcpy[0];
221 
222  int ch_cnt = 0;
223  //scan # of channels etc.
224  char *cp = buf;
225  for(;;) {
226  if(cp >= &buf[size]) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
227  if( *cp == ':') cp++;
228  if( !strncasecmp(cp, "XIN", 3))
229  sscanf(cp, "%*s %lf", &xin);
230  if( !strncasecmp(cp, "PT_O", 4))
231  sscanf(cp, "%*s %d", &triggerpos);
232  if( !strncasecmp(cp, "XZE", 3))
233  sscanf(cp, "%*s %lf", &xoff);
234  if( !strncasecmp(cp, "YMU", 3))
235  sscanf(cp, "%*s %lf", &yin[ch_cnt - 1]);
236  if( !strncasecmp(cp, "YOF", 3))
237  sscanf(cp, "%*s %lf", &yoff[ch_cnt - 1]);
238  if( !strncasecmp(cp, "NR_P", 4)) {
239  ch_cnt++;
240  sscanf(cp, "%*s %d", &width);
241  }
242  if( !strncasecmp(cp, "CURV", 4)) {
243  for(;;) {
244  cp = strchr(cp, '#');
245  if( !cp) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
246  int x;
247  if(sscanf(cp, "#%1d", &x) != 1) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
248  char fmt[9];
249  if(snprintf(fmt, sizeof(fmt), "#%%*1d%%%ud", x) < 0)
250  throw XBufferUnderflowRecordError(__FILE__, __LINE__);
251  int yyy;
252  if(sscanf(cp, fmt, &yyy) != 1) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
253  if(yyy == 0) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
254  cp += 2 + x;
255 
256  cp += yyy;
257  if( *cp != ',') break;
258  }
259  }
260  char *ncp = strchr(cp, ';');
261  if( !ncp)
262  cp = strchr(cp, ':');
263  else
264  cp = ncp;
265  if( !cp) break;
266  cp++;
267  }
268  if((width <= 0) || (width > size / 2)) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
269 
270  if(triggerpos != 0)
271  xoff = -triggerpos * xin;
272 
273  tr[ *this].setParameters(ch_cnt, xoff, xin, width);
274 
275  cp = buf;
276  for(int j = 0; j < ch_cnt; j++) {
277  double *wave = tr[ *this].waveDisp(j);
278  cp = strchr(cp, '#');
279  if( !cp) break;
280  int x;
281  if(sscanf(cp, "#%1d", &x) != 1) break;
282  char fmt[9];
283  if(snprintf(fmt, sizeof(fmt), "#%%*1d%%%ud", x) < 0)
284  throw XBufferUnderflowRecordError(__FILE__, __LINE__);
285  int yyy;
286  if(sscanf(cp, fmt, &yyy) != 1) break;
287  if(yyy == 0) break;
288  cp += 2 + x;
289 
290  int i = 0;
291  for(; i < std::min(width, yyy/2); i++) {
292  double val = *((unsigned char *)cp) * 0x100;
293  val += *((unsigned char *)cp + 1);
294  *(wave++) = yin[j] * (val - yoff[j] - 0.5);
295  cp += 2;
296  }
297  for(; i < width; i++) {
298  *(wave++) = 0.0;
299  }
300  }
301 }

Generated for KAME4 by  doxygen 1.8.3