thamwaydso.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 "thamwaydso.h"
15 
16 #include "xwavengraph.h"
17 
18 REGISTER_TYPE(XDriverList, ThamwayDVUSBDSO, "Thamway DV14U25 A/D conversion board");
19 
20 #define NUM_MAX_CH 2
21 #define INTERNAL_CLOCK 25e6 //Hz
22 
23 #define ADDR_STS 0
24 #define ADDR_CTRL 1
25 #define ADDR_CFG 2
26 #define ADDR_DIVISOR 3
27 #define ADDR_SAMPLES_LSW 4
28 #define ADDR_SAMPLES_MSW 6
29 #define ADDR_AVGM1_LSW 0x8 //average count minus 1
30 #define ADDR_AVGM1_MSW 0xa
31 #define ADDR_ACQCNTM1_LSW 0x8 //acquision count minus 1
32 #define ADDR_ACQCNTM1_MSW 0xa
33 #define ADDR_FRAMESM1 0xc //# of frames minus 1
34 
35 #define ADDR_BURST_CH1 0x18
36 #define ADDR_BURST_CH2 0x19
37 #define ADDR_CH1_SET_MEM_ADDR_LSW 0x10
38 #define ADDR_CH1_SET_MEM_ADDR_MSW 0x12
39 #define ADDR_CH2_SET_MEM_ADDR_LSW 0x14
40 #define ADDR_CH2_SET_MEM_ADDR_MSW 0x16
41 //#define ADDR_CH1_GET_MEM_ADDR_LSW 0x4
42 //#define ADDR_CH1_GET_MEM_ADDR_MSW 0x6
43 //#define ADDR_CH2_GET_MEM_ADDR_LSW 0x10
44 //#define ADDR_CH2_GET_MEM_ADDR_MSW 0x12
45 
46 #define MAX_SMPL 0x80000u //512kwords
47 
48 XThamwayDVUSBDSO::XThamwayDVUSBDSO(const char *name, bool runtime,
49  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
50  XCharDeviceDriver<XDSO, XThamwayDVCUSBInterface>(name, runtime, ref(tr_meas), meas) {
51 
52  std::vector<shared_ptr<XNode>> unnecessary_ui{
53  vFullScale3(), vFullScale4(), vOffset1(), vOffset2(), vOffset3(), vOffset4(),
54  trigPos(), trigSource(), trigLevel(), trigFalling(), forceTrigger()
55  };
56 
57  iterate_commit([=](Transaction &tr){
58  tr[ *recordLength()] = 2000;
59  tr[ *timeWidth()] = 1e-2;
60  tr[ *average()] = 1;
61  for(auto &&x: {vFullScale1(), vFullScale2()}) {
62  tr[ *x].add({"5"});
63  tr[ *x] = "5";
64  }
65  for(auto &&x: unnecessary_ui)
66  tr[ *x].disable();
67  });
68 }
69 XThamwayDVUSBDSO::~XThamwayDVUSBDSO() {
70 }
71 void
73  XScopedLock<XInterface> lock( *interface());
74  XString idn = interface()->getIDN();
75  fprintf(stderr, "DV IDN=%s\n", idn.c_str());
76 
77  iterate_commit([=](Transaction &tr){
78  for(auto &&x: {trace1(), trace2()})
79  tr[ *x].add({"CH1", "CH2"});
80  tr[ *trace1()] = 0;
81  tr[ *trace2()] = 1;
82  });
83 
84  int smps = interface()->readRegister16(ADDR_SAMPLES_MSW);
85  smps = smps * 0x10000L + interface()->readRegister16(ADDR_SAMPLES_LSW);
86  smps--;
87  double intv = getTimeInterval();
88 // fprintf(stderr, "smps%u,avg%u,intv%g\n",smps,avg,intv);
89  iterate_commit([=](Transaction &tr){
90  tr[ *recordLength()] = smps;
91  tr[ *timeWidth()] = smps * intv;
92  });
93 
94  m_pending = true;
95  Snapshot shot( *this);
96 // onTimeWidthChanged(shot, 0);
97 // onRecordLengthChanged(shot, 0);
98  onAverageChanged(shot, 0);
99  interface()->writeToRegister8(ADDR_FRAMESM1, 0); //1 frame.
100  m_pending = false;
101 
102  this->start();
103 
104  startSequence();
105 }
106 void
108  interface()->stop();
109 }
110 void
111 XThamwayDVUSBDSO::onForceTriggerTouched(const Snapshot &shot, XTouchableNode *) {
112 // XScopedLock<XInterface> lock( *interface());
113 // interface()->writeToRegister8(ADDR_CTRL, 0); //stops.
114 
115 // interface()->writeToRegister8(ADDR_STS, 0x80); //soft trigger? undocumented.
116 
117 // startSequence();
118 }
119 
120 void
122  XScopedLock<XInterface> lock( *interface());
123  interface()->writeToRegister8(ADDR_CTRL, 0); //stops.
124  if( !m_pending) {
125  interface()->writeToRegister16(ADDR_CH1_SET_MEM_ADDR_LSW, 0);
126  interface()->writeToRegister16(ADDR_CH1_SET_MEM_ADDR_MSW, 0);
127  interface()->writeToRegister16(ADDR_CH2_SET_MEM_ADDR_LSW, 0);
128  interface()->writeToRegister16(ADDR_CH2_SET_MEM_ADDR_MSW, 0);
129 
130  interface()->writeToRegister8(ADDR_CTRL, 1); //starts.
131  }
132 }
133 
134 int
135 XThamwayDVUSBDSO::acqCount(bool *seq_busy) {
136  XScopedLock<XInterface> lock( *interface());
137  if(m_pending) {
138  if(seq_busy) *seq_busy = true;
139  return 0;
140  }
141  uint8_t sts = interface()->singleRead(ADDR_STS);
142  bool is_started = sts & 2;
143  bool is_ad_finished = sts & 4;
144  int acq = interface()->readRegister16(ADDR_ACQCNTM1_MSW);
145  acq = acq * 0x10000L + interface()->readRegister16(ADDR_ACQCNTM1_LSW);
146  if(is_started && is_ad_finished) acq++;
147  if(seq_busy) {
148  *seq_busy = !is_started || !is_ad_finished;
149  }
150  return acq;
151 }
152 
153 double
154 XThamwayDVUSBDSO::getTimeInterval() {
155  XScopedLock<XInterface> lock( *interface());
156  int div = interface()->singleRead(ADDR_DIVISOR);
157  int pres = interface()->singleRead(ADDR_CFG) % 0x8u;
158  double clk = INTERNAL_CLOCK / pow(2.0, pres) / std::max(div, 1);
159  return 1.0/clk;
160 }
161 
162 void
163 XThamwayDVUSBDSO::getWave(shared_ptr<RawData> &writer, std::deque<XString> &) {
164  XScopedLock<XInterface> lock( *interface());
165 
166  interface()->writeToRegister8(ADDR_CTRL, 0); //stops.
167  interface()->writeToRegister16(ADDR_CH1_SET_MEM_ADDR_LSW, 0);
168  interface()->writeToRegister16(ADDR_CH1_SET_MEM_ADDR_MSW, 0);
169  interface()->writeToRegister16(ADDR_CH2_SET_MEM_ADDR_LSW, 0);
170  interface()->writeToRegister16(ADDR_CH2_SET_MEM_ADDR_MSW, 0);
171 
172  int smps = interface()->readRegister16(ADDR_SAMPLES_MSW);
173  smps = smps * 0x10000L + interface()->readRegister16(ADDR_SAMPLES_LSW);
174  smps--;
175 // fprintf(stderr, "samps%d\n", smps);
176  Snapshot shot( *this);
177 // smps = shot[ *recordLength()];
178  if(smps > MAX_SMPL)
179  throw XInterface::XInterfaceError(i18n("# of samples exceeded the limit."), __FILE__, __LINE__);
180 
181  std::deque<uint8_t> adds;
182  if(shot[ *trace1()] >= 0) adds.push_back( (shot[ *trace1()] == 0) ? ADDR_BURST_CH1 : ADDR_BURST_CH2 );
183  if(shot[ *trace2()] >= 0) adds.push_back( (shot[ *trace2()] == 0) ? ADDR_BURST_CH1 : ADDR_BURST_CH2 );
184 
185  writer->push((uint16_t)adds.size()); //channels
186  writer->push((uint32_t)0); //reserve
187  writer->push((uint32_t)0); //reserve
188  int acq = interface()->readRegister16(ADDR_ACQCNTM1_MSW);
189  acq = acq * 0x10000L + interface()->readRegister16(ADDR_ACQCNTM1_LSW);
190  acq++;
191  writer->push((uint32_t)acq);
192  writer->push((uint32_t)smps);
193  writer->push((double)getTimeInterval());
194  std::vector<uint8_t> buf(smps * sizeof(uint32_t));
195  for(auto it = adds.begin(); it != adds.end(); ++it) {
196  interface()->burstRead( *it, &buf[0], buf.size());
197  writer->push((double)1.0/3276.8); //[V/bit]
198  writer->push((double)-2.5); //offset[V]
199  writer->insert(writer->end(), buf.begin(), buf.end());
200  }
201 }
202 void
204  const unsigned int num_ch = reader.pop<uint16_t>();
205  reader.pop<uint32_t>(); //reserve
206  reader.pop<uint32_t>(); //reserve
207  unsigned int accum_count = reader.pop<uint32_t>();
208  unsigned int len = reader.pop<uint32_t>();
209  double interval = reader.pop<double>();
210 
211  tr[ *this].setParameters(num_ch, 0.0, interval, len);
212 
213  for(unsigned int j = 0; j < num_ch; j++) {
214  double prop = reader.pop<double>() / accum_count;
215  double offset = reader.pop<double>();
216  double *wave = tr[ *this].waveDisp(j);
217  for(unsigned int i = 0; i < len; i++) {
218  *wave++ = prop * reader.pop<uint32_t>() + offset;
219  }
220  }
221 }
222 
223 void
224 XThamwayDVUSBDSO::onAverageChanged(const Snapshot &shot, XValueNodeBase *) {
225  XScopedLock<XInterface> lock( *interface());
226  interface()->writeToRegister8(ADDR_CTRL, 0); //stops.
227 
228  unsigned int avg = shot[ *average()];
229  avg--;
230  interface()->writeToRegister16(ADDR_AVGM1_LSW, avg % 0x10000uL);
231  interface()->writeToRegister16(ADDR_AVGM1_MSW, avg / 0x10000uL);
232 
233  startSequence();
234 }
235 
236 void
237 XThamwayDVUSBDSO::onSingleChanged(const Snapshot &shot, XValueNodeBase *) {
238 }
239 void
240 XThamwayDVUSBDSO::onTrigPosChanged(const Snapshot &shot, XValueNodeBase *) {
241 }
242 void
243 XThamwayDVUSBDSO::onTrigSourceChanged(const Snapshot &shot, XValueNodeBase *) {
244 }
245 void
246 XThamwayDVUSBDSO::onTrigLevelChanged(const Snapshot &shot, XValueNodeBase *) {
247 }
248 void
249 XThamwayDVUSBDSO::onTrigFallingChanged(const Snapshot &shot, XValueNodeBase *) {
250 }
251 void
252 XThamwayDVUSBDSO::onTimeWidthChanged(const Snapshot &shot, XValueNodeBase *) {
253 // int smps = interface()->readRegister16(ADDR_SAMPLES_MSW);
254 // smps = smps * 0x10000L + interface()->readRegister16(ADDR_SAMPLES_LSW);
255 // smps--;
256  int smps = Snapshot( *this)[ *recordLength()];
257 
258  double interval = shot[ *timeWidth()] / smps;
259  int div = std::max(1L, lrint(INTERNAL_CLOCK * interval));
260  int pres = std::min(7, std::max(0, (int)floor(log(div / 256.0) / log(2.0)) + 1));
261 
262  div = std::max(1L, lrint(div / pow(2.0, pres)));
263  if(div > 255)
264  throw XInterface::XInterfaceError(i18n("Too long time intervals."), __FILE__, __LINE__);
265 
266  XScopedLock<XInterface> lock( *interface());
267  interface()->writeToRegister8(ADDR_CTRL, 0); //stops.
268 
269  uint8_t cfg = 0x20; //8:ext_clock 0x40:flip
270  interface()->writeToRegister8(ADDR_CFG, cfg | pres);
271  interface()->writeToRegister8(ADDR_DIVISOR, div);
272 
273  startSequence();
274 }
275 void
276 XThamwayDVUSBDSO::onRecordLengthChanged(const Snapshot &shot, XValueNodeBase *) {
277  XScopedLock<XInterface> lock( *interface());
278  interface()->writeToRegister8(ADDR_CTRL, 0); //stops.
279 
280  unsigned int smps = shot[ *recordLength()];
281  interface()->writeToRegister16(ADDR_SAMPLES_LSW, smps % 0x10000uL);
282  interface()->writeToRegister16(ADDR_SAMPLES_MSW, smps / 0x10000uL);
283 
284  onTimeWidthChanged(Snapshot( *this), 0);
285 }
286 void
287 XThamwayDVUSBDSO::onTrace1Changed(const Snapshot &shot, XValueNodeBase *) {
288 }
289 void
290 XThamwayDVUSBDSO::onTrace2Changed(const Snapshot &shot, XValueNodeBase *) {
291 }
292 void
293 XThamwayDVUSBDSO::onTrace3Changed(const Snapshot &shot, XValueNodeBase *) {
294 }
295 void
296 XThamwayDVUSBDSO::onTrace4Changed(const Snapshot &shot, XValueNodeBase *) {
297 }
298 void
299 XThamwayDVUSBDSO::onVFullScale1Changed(const Snapshot &shot, XValueNodeBase *) {
300 }
301 void
302 XThamwayDVUSBDSO::onVFullScale2Changed(const Snapshot &shot, XValueNodeBase *) {
303 }
304 void
305 XThamwayDVUSBDSO::onVFullScale3Changed(const Snapshot &shot, XValueNodeBase *) {
306 }
307 void
308 XThamwayDVUSBDSO::onVFullScale4Changed(const Snapshot &shot, XValueNodeBase *) {
309 }
310 void
311 XThamwayDVUSBDSO::onVOffset1Changed(const Snapshot &shot, XValueNodeBase *) {
312 }
313 void
314 XThamwayDVUSBDSO::onVOffset2Changed(const Snapshot &shot, XValueNodeBase *) {
315 }
316 void
317 XThamwayDVUSBDSO::onVOffset3Changed(const Snapshot &shot, XValueNodeBase *) {
318 }
319 void
320 XThamwayDVUSBDSO::onVOffset4Changed(const Snapshot &shot, XValueNodeBase *) {
321 }
322 

Generated for KAME4 by  doxygen 1.8.3