14 #include "thamwaydso.h"
16 #include "xwavengraph.h"
18 REGISTER_TYPE(
XDriverList, ThamwayDVUSBDSO,
"Thamway DV14U25 A/D conversion board");
21 #define INTERNAL_CLOCK 25e6 //Hz
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
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
46 #define MAX_SMPL 0x80000u //512kwords
48 XThamwayDVUSBDSO::XThamwayDVUSBDSO(
const char *name,
bool runtime,
49 Transaction &tr_meas,
const shared_ptr<XMeasure> &meas) :
52 std::vector<shared_ptr<XNode>> unnecessary_ui{
53 vFullScale3(), vFullScale4(), vOffset1(), vOffset2(), vOffset3(), vOffset4(),
54 trigPos(), trigSource(), trigLevel(), trigFalling(), forceTrigger()
58 tr[ *recordLength()] = 2000;
59 tr[ *timeWidth()] = 1e-2;
61 for(
auto &&x: {vFullScale1(), vFullScale2()}) {
65 for(
auto &&x: unnecessary_ui)
69 XThamwayDVUSBDSO::~XThamwayDVUSBDSO() {
74 XString idn = interface()->getIDN();
75 fprintf(stderr,
"DV IDN=%s\n", idn.c_str());
78 for(
auto &&x: {trace1(), trace2()})
79 tr[ *x].add({
"CH1",
"CH2"});
84 int smps = interface()->readRegister16(ADDR_SAMPLES_MSW);
85 smps = smps * 0x10000L + interface()->readRegister16(ADDR_SAMPLES_LSW);
87 double intv = getTimeInterval();
90 tr[ *recordLength()] = smps;
91 tr[ *timeWidth()] = smps * intv;
98 onAverageChanged(shot, 0);
99 interface()->writeToRegister8(ADDR_FRAMESM1, 0);
123 interface()->writeToRegister8(ADDR_CTRL, 0);
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);
130 interface()->writeToRegister8(ADDR_CTRL, 1);
138 if(seq_busy) *seq_busy =
true;
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++;
148 *seq_busy = !is_started || !is_ad_finished;
154 XThamwayDVUSBDSO::getTimeInterval() {
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);
166 interface()->writeToRegister8(ADDR_CTRL, 0);
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);
172 int smps = interface()->readRegister16(ADDR_SAMPLES_MSW);
173 smps = smps * 0x10000L + interface()->readRegister16(ADDR_SAMPLES_LSW);
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 );
185 writer->push((uint16_t)adds.size());
186 writer->push((uint32_t)0);
187 writer->push((uint32_t)0);
188 int acq = interface()->readRegister16(ADDR_ACQCNTM1_MSW);
189 acq = acq * 0x10000L + interface()->readRegister16(ADDR_ACQCNTM1_LSW);
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);
198 writer->push((
double)-2.5);
199 writer->insert(writer->end(), buf.begin(), buf.end());
204 const unsigned int num_ch = reader.pop<uint16_t>();
205 reader.pop<uint32_t>();
206 reader.pop<uint32_t>();
207 unsigned int accum_count = reader.pop<uint32_t>();
208 unsigned int len = reader.pop<uint32_t>();
209 double interval = reader.pop<
double>();
211 tr[ *
this].setParameters(num_ch, 0.0, interval, len);
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;
226 interface()->writeToRegister8(ADDR_CTRL, 0);
228 unsigned int avg = shot[ *average()];
230 interface()->writeToRegister16(ADDR_AVGM1_LSW, avg % 0x10000uL);
231 interface()->writeToRegister16(ADDR_AVGM1_MSW, avg / 0x10000uL);
256 int smps =
Snapshot( *
this)[ *recordLength()];
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));
262 div = std::max(1L, lrint(div / pow(2.0, pres)));
267 interface()->writeToRegister8(ADDR_CTRL, 0);
270 interface()->writeToRegister8(ADDR_CFG, cfg | pres);
271 interface()->writeToRegister8(ADDR_DIVISOR, div);
278 interface()->writeToRegister8(ADDR_CTRL, 0);
280 unsigned int smps = shot[ *recordLength()];
281 interface()->writeToRegister16(ADDR_SAMPLES_LSW, smps % 0x10000uL);
282 interface()->writeToRegister16(ADDR_SAMPLES_MSW, smps / 0x10000uL);
284 onTimeWidthChanged(
Snapshot( *
this), 0);