Commit 25e567f1c53ecfa7fbbbb9d3f23ecb4a8dd71bac

Authored by David Graeff
Committed by David Gräff
1 parent a496ceb1

Concentrate model implementation differences to hantekdsocontrol

* Remove usbdevice special case for the 6022 model and introduce a feature flag instead.
* Remove all specific model checks across the hantekdsocontrol class and introduce feature flags instead.

Bigger picture: All model differences should be described in the controlsettings and specification structures
within the constructor of hantekdsocontrol. The rest of the class should be model independant code or marked as
very model dependant code. This should allow to split the class into smaller parts to realize Separation of concerns.

TODO: getSamples() has basically two code paths: One for the 6022Bx and one for all other devices.
I suggest getSamples() and getSamples6022Bx() for instance.
openhantek/src/hantek/hantekdsocontrol.cpp
... ... @@ -23,15 +23,18 @@ void HantekDsoControl::startSampling() {
23 23 sampling = true;
24 24  
25 25 // Emit signals for initial settings
26   - emit availableRecordLengthsChanged(settings.samplerate.limits->recordLengths);
  26 + emit availableRecordLengthsChanged(controlsettings.samplerate.limits->recordLengths);
27 27 updateSamplerateLimits();
28 28 emit recordLengthChanged(getRecordLength());
29   - if (!isRollMode()) emit recordTimeChanged((double)getRecordLength() / settings.samplerate.current);
30   - emit samplerateChanged(settings.samplerate.current);
  29 + if (!isRollMode()) emit recordTimeChanged((double)getRecordLength() / controlsettings.samplerate.current);
  30 + emit samplerateChanged(controlsettings.samplerate.current);
31 31  
32   - if (device->getUniqueModelID() == MODEL_DSO6022BE) {
  32 + if (specification.isSoftwareTriggerDevice) {
  33 + // Convert to GUI presentable values (1e5 -> 1.0, 48e6 -> 480.0 etc)
33 34 QList<double> sampleSteps;
34   - sampleSteps << 1.0 << 2.0 << 5.0 << 10.0 << 20.0 << 40.0 << 80.0 << 160.0 << 240.0 << 480.0;
  35 + for (double v: specification.sampleSteps) {
  36 + sampleSteps << v/1e5;
  37 + }
35 38 emit samplerateSet(1, sampleSteps);
36 39 }
37 40  
... ... @@ -83,33 +86,24 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) {
83 86 }
84 87  
85 88 // Set settings to default values
86   - settings.samplerate.limits = &(specification.samplerate.single);
87   - settings.samplerate.downsampler = 1;
88   - settings.samplerate.current = 1e8;
89   - settings.trigger.position = 0;
90   - settings.trigger.point = 0;
91   - settings.trigger.mode = Dso::TRIGGERMODE_NORMAL;
92   - settings.trigger.slope = Dso::SLOPE_POSITIVE;
93   - settings.trigger.special = false;
94   - settings.trigger.source = 0;
  89 + controlsettings.samplerate.limits = &(specification.samplerate.single);
  90 + controlsettings.samplerate.downsampler = 1;
  91 + controlsettings.samplerate.current = 1e8;
  92 + controlsettings.trigger.position = 0;
  93 + controlsettings.trigger.point = 0;
  94 + controlsettings.trigger.mode = Dso::TRIGGERMODE_NORMAL;
  95 + controlsettings.trigger.slope = Dso::SLOPE_POSITIVE;
  96 + controlsettings.trigger.special = false;
  97 + controlsettings.trigger.source = 0;
95 98 for (unsigned channel = 0; channel < HANTEK_CHANNELS; ++channel) {
96   - settings.trigger.level[channel] = 0.0;
97   - settings.voltage[channel].gain = 0;
98   - settings.voltage[channel].offset = 0.0;
99   - settings.voltage[channel].offsetReal = 0.0;
100   - settings.voltage[channel].used = false;
101   - }
102   - settings.recordLengthId = 1;
103   - settings.usedChannels = 0;
104   -
105   - // Special trigger sources
106   - this->specialTriggerSources << tr("EXT") << tr("EXT/10");
107   -
108   - // Instantiate bulk command later, some are not the same for all models
109   - for (int cIndex = 0; cIndex < BULK_COUNT; ++cIndex) {
110   - command[cIndex] = 0;
111   - commandPending[cIndex] = false;
  99 + controlsettings.trigger.level[channel] = 0.0;
  100 + controlsettings.voltage[channel].gain = 0;
  101 + controlsettings.voltage[channel].offset = 0.0;
  102 + controlsettings.voltage[channel].offsetReal = 0.0;
  103 + controlsettings.voltage[channel].used = false;
112 104 }
  105 + controlsettings.recordLengthId = 1;
  106 + controlsettings.usedChannels = 0;
113 107  
114 108 // Transmission-ready control commands
115 109 this->control[CONTROLINDEX_SETOFFSET] = new ControlSetOffset();
... ... @@ -119,24 +113,11 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) {
119 113  
120 114 for (int cIndex = 0; cIndex < CONTROLINDEX_COUNT; ++cIndex) this->controlPending[cIndex] = false;
121 115  
122   - // State of the device
123   - this->captureState = CAPTURE_WAITING;
124   - this->rollState = 0;
125   - this->_samplingStarted = false;
126   - this->lastTriggerMode = (Dso::TriggerMode)-1;
127   -
128 116 // Sample buffers
129 117 result.data.resize(HANTEK_CHANNELS);
130 118  
131   - this->previousSampleCount = 0;
132   -
133 119 int errorCode;
134 120  
135   - // Clean up commands and their pending state
136   - for (int cIndex = 0; cIndex < BULK_COUNT; ++cIndex) {
137   - if (command[cIndex]) delete command[cIndex];
138   - commandPending[cIndex] = false;
139   - }
140 121 // Instantiate the commands needed for all models
141 122 command[BULK_FORCETRIGGER] = new BulkForceTrigger();
142 123 command[BULK_STARTSAMPLING] = new BulkCaptureStart();
... ... @@ -157,23 +138,58 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) {
157 138 specification.command.values.voltageLimits = (ControlValue)-1;
158 139  
159 140 // Determine the command version we need for this model
160   - bool unsupported = false;
161   - int lastControlIndex = 0;
162 141 switch (device->getUniqueModelID()) {
163 142 case MODEL_DSO2150:
164   - unsupported = true;
  143 + command[BULK_SETTRIGGERANDSAMPLERATE] = new BulkSetTriggerAndSamplerate();
  144 + specification.command.bulk.setRecordLength = BULK_SETTRIGGERANDSAMPLERATE;
  145 + specification.command.bulk.setChannels = BULK_SETTRIGGERANDSAMPLERATE;
  146 + specification.command.bulk.setSamplerate = BULK_SETTRIGGERANDSAMPLERATE;
  147 + specification.command.bulk.setTrigger = BULK_SETTRIGGERANDSAMPLERATE;
  148 + specification.command.bulk.setPretrigger = BULK_SETTRIGGERANDSAMPLERATE;
  149 + for (int cIndex = 0; cIndex <= CONTROLINDEX_SETRELAYS; ++cIndex) this->controlPending[cIndex] = true;
  150 + // Initialize those as pending
  151 + commandPending[BULK_SETTRIGGERANDSAMPLERATE] = true;
165 152  
  153 + specification.samplerate.single.base = 50e6;
  154 + specification.samplerate.single.max = 75e6;
  155 + specification.samplerate.single.maxDownsampler = 131072;
  156 + specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 32768;
  157 + specification.samplerate.multi.base = 100e6;
  158 + specification.samplerate.multi.max = 150e6;
  159 + specification.samplerate.multi.maxDownsampler = 131072;
  160 + specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 65536;
  161 + specification.bufferDividers << 1000 << 1 << 1;
  162 + specification.gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0;
  163 + for (int channel = 0; channel < HANTEK_CHANNELS; ++channel)
  164 + specification.voltageLimit[channel] << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255;
  165 + specification.gainIndex << 0 << 1 << 2 << 0 << 1 << 2 << 0 << 1 << 2;
  166 + specification.sampleSize = 8;
  167 + break;
166 168 case MODEL_DSO2090:
167   - // Instantiate additional commands for the DSO-2090
168 169 command[BULK_SETTRIGGERANDSAMPLERATE] = new BulkSetTriggerAndSamplerate();
169 170 specification.command.bulk.setRecordLength = BULK_SETTRIGGERANDSAMPLERATE;
170 171 specification.command.bulk.setChannels = BULK_SETTRIGGERANDSAMPLERATE;
171 172 specification.command.bulk.setSamplerate = BULK_SETTRIGGERANDSAMPLERATE;
172 173 specification.command.bulk.setTrigger = BULK_SETTRIGGERANDSAMPLERATE;
173 174 specification.command.bulk.setPretrigger = BULK_SETTRIGGERANDSAMPLERATE;
174   - lastControlIndex = CONTROLINDEX_SETRELAYS;
  175 + for (int cIndex = 0; cIndex <= CONTROLINDEX_SETRELAYS; ++cIndex) this->controlPending[cIndex] = true;
175 176 // Initialize those as pending
176 177 commandPending[BULK_SETTRIGGERANDSAMPLERATE] = true;
  178 +
  179 + specification.samplerate.single.base = 50e6;
  180 + specification.samplerate.single.max = 50e6;
  181 + specification.samplerate.single.maxDownsampler = 131072;
  182 + specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 32768;
  183 + specification.samplerate.multi.base = 100e6;
  184 + specification.samplerate.multi.max = 100e6;
  185 + specification.samplerate.multi.maxDownsampler = 131072;
  186 + specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 65536;
  187 + specification.bufferDividers << 1000 << 1 << 1;
  188 + specification.gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0;
  189 + for (int channel = 0; channel < HANTEK_CHANNELS; ++channel)
  190 + specification.voltageLimit[channel] << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255;
  191 + specification.gainIndex << 0 << 1 << 2 << 0 << 1 << 2 << 0 << 1 << 2;
  192 + specification.sampleSize = 8;
177 193 break;
178 194  
179 195 case MODEL_DSO2250:
... ... @@ -188,8 +204,8 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) {
188 204 specification.command.bulk.setSamplerate = BULK_ESETTRIGGERORSAMPLERATE;
189 205 specification.command.bulk.setTrigger = BULK_CSETTRIGGERORSAMPLERATE;
190 206 specification.command.bulk.setPretrigger = BULK_FSETBUFFER;
191   - /// \todo Test if lastControlIndex is correct
192   - lastControlIndex = CONTROLINDEX_SETRELAYS;
  207 +
  208 + for (int cIndex = 0; cIndex <= CONTROLINDEX_SETRELAYS; ++cIndex) this->controlPending[cIndex] = true;
193 209  
194 210 commandPending[BULK_BSETCHANNELS] = true;
195 211 commandPending[BULK_CSETTRIGGERORSAMPLERATE] = true;
... ... @@ -197,11 +213,24 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) {
197 213 commandPending[BULK_ESETTRIGGERORSAMPLERATE] = true;
198 214 commandPending[BULK_FSETBUFFER] = true;
199 215  
  216 + specification.samplerate.single.base = 100e6;
  217 + specification.samplerate.single.max = 100e6;
  218 + specification.samplerate.single.maxDownsampler = 65536;
  219 + specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 524288;
  220 + specification.samplerate.multi.base = 200e6;
  221 + specification.samplerate.multi.max = 250e6;
  222 + specification.samplerate.multi.maxDownsampler = 65536;
  223 + specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 1048576;
  224 + specification.bufferDividers << 1000 << 1 << 1;
  225 + specification.gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0;
  226 + for (int channel = 0; channel < HANTEK_CHANNELS; ++channel)
  227 + specification.voltageLimit[channel] << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255;
  228 + specification.gainIndex << 0 << 2 << 3 << 0 << 2 << 3 << 0 << 2 << 3;
  229 + specification.sampleSize = 8;
200 230 break;
201 231  
202 232 case MODEL_DSO5200A:
203   - unsupported = true;
204   -
  233 + [[clang::fallthrough]];
205 234 case MODEL_DSO5200:
206 235 // Instantiate additional commands for the DSO-5200
207 236 command[BULK_CSETTRIGGERORSAMPLERATE] = new BulkSetSamplerate5200();
... ... @@ -213,17 +242,39 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) {
213 242 specification.command.bulk.setTrigger = BULK_ESETTRIGGERORSAMPLERATE;
214 243 specification.command.bulk.setPretrigger = BULK_ESETTRIGGERORSAMPLERATE;
215 244 // specification.command.values.voltageLimits = VALUE_ETSCORRECTION;
216   - /// \todo Test if lastControlIndex is correct
217   - lastControlIndex = CONTROLINDEX_SETRELAYS;
  245 + for (int cIndex = 0; cIndex <= CONTROLINDEX_SETRELAYS; ++cIndex) this->controlPending[cIndex] = true;
218 246  
219 247 commandPending[BULK_CSETTRIGGERORSAMPLERATE] = true;
220 248 commandPending[BULK_DSETBUFFER] = true;
221 249 commandPending[BULK_ESETTRIGGERORSAMPLERATE] = true;
222 250  
  251 + specification.samplerate.single.base = 100e6;
  252 + specification.samplerate.single.max = 125e6;
  253 + specification.samplerate.single.maxDownsampler = 131072;
  254 + specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 14336;
  255 + specification.samplerate.multi.base = 200e6;
  256 + specification.samplerate.multi.max = 250e6;
  257 + specification.samplerate.multi.maxDownsampler = 131072;
  258 + specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 28672;
  259 + specification.bufferDividers << 1000 << 1 << 1;
  260 + specification.gainSteps << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0 << 80.0;
  261 + /// \todo Use calibration data to get the DSO-5200(A) sample ranges
  262 + for (int channel = 0; channel < HANTEK_CHANNELS; ++channel)
  263 + specification.voltageLimit[channel] << 368 << 454 << 908 << 368 << 454 << 908 << 368 << 454 << 908;
  264 + specification.gainIndex << 1 << 0 << 0 << 1 << 0 << 0 << 1 << 0 << 0;
  265 + specification.sampleSize = 10;
223 266 break;
224 267  
225 268 case MODEL_DSO6022BE:
  269 + device->overwriteInPacketLength(16384);
226 270 // 6022BE do not support any bulk commands
  271 + device->setEnableBulkTransfer(false);
  272 + specification.useControlNoBulk = true;
  273 + specification.isSoftwareTriggerDevice = true;
  274 + specification.supportsCaptureState = false;
  275 + specification.supportsOffset = false;
  276 + specification.supportsCouplingRelays = false;
  277 +
227 278 this->control[CONTROLINDEX_SETVOLTDIV_CH1] = new ControlSetVoltDIV_CH1();
228 279 this->controlCode[CONTROLINDEX_SETVOLTDIV_CH1] = CONTROL_SETVOLTDIV_CH1;
229 280 this->controlPending[CONTROLINDEX_SETVOLTDIV_CH1] = true;
... ... @@ -239,96 +290,10 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) {
239 290 this->control[CONTROLINDEX_ACQUIIRE_HARD_DATA] = new ControlAcquireHardData();
240 291 this->controlCode[CONTROLINDEX_ACQUIIRE_HARD_DATA] = CONTROL_ACQUIIRE_HARD_DATA;
241 292 this->controlPending[CONTROLINDEX_ACQUIIRE_HARD_DATA] = true;
242   - /// \todo Test if lastControlIndex is correct
243   - lastControlIndex = CONTROLINDEX_ACQUIIRE_HARD_DATA;
244   - break;
245   -
246   - default:
247   - device->disconnect();
248   - emit statusMessage(tr("Unknown model"), 0);
249   - return;
250   - }
251   -
252   - if (unsupported)
253   - qWarning("Warning: This Hantek DSO model isn't supported officially, so it "
254   - "may not be working as expected. Reports about your experiences "
255   - "are very welcome though (Please open a feature request in the "
256   - "tracker at https://sf.net/projects/openhantek/ or email me "
257   - "directly to oliver.haag@gmail.com). If it's working perfectly I "
258   - "can remove this warning, if not it should be possible to get it "
259   - "working with your help soon.");
260   -
261   - for (int cIndex = 0; cIndex <= lastControlIndex; ++cIndex) this->controlPending[cIndex] = true;
262 293  
263   - // Disable controls not supported by 6022BE
264   - if (device->getUniqueModelID() == MODEL_DSO6022BE) {
265 294 this->controlPending[CONTROLINDEX_SETOFFSET] = false;
266 295 this->controlPending[CONTROLINDEX_SETRELAYS] = false;
267   - }
268   -
269   - // Maximum possible samplerate for a single channel and dividers for record
270   - // lengths
271   - specification.bufferDividers.clear();
272   - specification.samplerate.single.recordLengths.clear();
273   - specification.samplerate.multi.recordLengths.clear();
274   - specification.gainSteps.clear();
275   - for (int channel = 0; channel < HANTEK_CHANNELS; ++channel) specification.voltageLimit[channel].clear();
276   -
277   - switch (device->getUniqueModelID()) {
278   - case MODEL_DSO5200:
279   - case MODEL_DSO5200A:
280   - specification.samplerate.single.base = 100e6;
281   - specification.samplerate.single.max = 125e6;
282   - specification.samplerate.single.maxDownsampler = 131072;
283   - specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 14336;
284   - specification.samplerate.multi.base = 200e6;
285   - specification.samplerate.multi.max = 250e6;
286   - specification.samplerate.multi.maxDownsampler = 131072;
287   - specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 28672;
288   - specification.bufferDividers << 1000 << 1 << 1;
289   - specification.gainSteps << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0 << 80.0;
290   - /// \todo Use calibration data to get the DSO-5200(A) sample ranges
291   - for (int channel = 0; channel < HANTEK_CHANNELS; ++channel)
292   - specification.voltageLimit[channel] << 368 << 454 << 908 << 368 << 454 << 908 << 368 << 454 << 908;
293   - specification.gainIndex << 1 << 0 << 0 << 1 << 0 << 0 << 1 << 0 << 0;
294   - specification.sampleSize = 10;
295   - break;
296 296  
297   - case MODEL_DSO2250:
298   - specification.samplerate.single.base = 100e6;
299   - specification.samplerate.single.max = 100e6;
300   - specification.samplerate.single.maxDownsampler = 65536;
301   - specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 524288;
302   - specification.samplerate.multi.base = 200e6;
303   - specification.samplerate.multi.max = 250e6;
304   - specification.samplerate.multi.maxDownsampler = 65536;
305   - specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 1048576;
306   - specification.bufferDividers << 1000 << 1 << 1;
307   - specification.gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0;
308   - for (int channel = 0; channel < HANTEK_CHANNELS; ++channel)
309   - specification.voltageLimit[channel] << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255;
310   - specification.gainIndex << 0 << 2 << 3 << 0 << 2 << 3 << 0 << 2 << 3;
311   - specification.sampleSize = 8;
312   - break;
313   -
314   - case MODEL_DSO2150:
315   - specification.samplerate.single.base = 50e6;
316   - specification.samplerate.single.max = 75e6;
317   - specification.samplerate.single.maxDownsampler = 131072;
318   - specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 32768;
319   - specification.samplerate.multi.base = 100e6;
320   - specification.samplerate.multi.max = 150e6;
321   - specification.samplerate.multi.maxDownsampler = 131072;
322   - specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 65536;
323   - specification.bufferDividers << 1000 << 1 << 1;
324   - specification.gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0;
325   - for (int channel = 0; channel < HANTEK_CHANNELS; ++channel)
326   - specification.voltageLimit[channel] << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255;
327   - specification.gainIndex << 0 << 1 << 2 << 0 << 1 << 2 << 0 << 1 << 2;
328   - specification.sampleSize = 8;
329   - break;
330   -
331   - case MODEL_DSO6022BE:
332 297 specification.samplerate.single.base = 1e6;
333 298 specification.samplerate.single.max = 48e6;
334 299 specification.samplerate.single.maxDownsampler = 10;
... ... @@ -350,25 +315,12 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) {
350 315 break;
351 316  
352 317 default:
353   - specification.samplerate.single.base = 50e6;
354   - specification.samplerate.single.max = 50e6;
355   - specification.samplerate.single.maxDownsampler = 131072;
356   - specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 32768;
357   - specification.samplerate.multi.base = 100e6;
358   - specification.samplerate.multi.max = 100e6;
359   - specification.samplerate.multi.maxDownsampler = 131072;
360   - specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 65536;
361   - specification.bufferDividers << 1000 << 1 << 1;
362   - specification.gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0;
363   - for (int channel = 0; channel < HANTEK_CHANNELS; ++channel)
364   - specification.voltageLimit[channel] << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255 << 255;
365   - specification.gainIndex << 0 << 1 << 2 << 0 << 1 << 2 << 0 << 1 << 2;
366   - specification.sampleSize = 8;
367   - break;
  318 + throw new std::runtime_error("unknown model");
368 319 }
369   - settings.recordLengthId = 1;
370   - settings.samplerate.limits = &(specification.samplerate.single);
371   - settings.samplerate.downsampler = 1;
  320 +
  321 + controlsettings.recordLengthId = 1;
  322 + controlsettings.samplerate.limits = &(specification.samplerate.single);
  323 + controlsettings.samplerate.downsampler = 1;
372 324 this->previousSampleCount = 0;
373 325  
374 326 // Get channel level data
... ... @@ -395,7 +347,7 @@ unsigned HantekDsoControl::getChannelCount() { return HANTEK_CHANNELS; }
395 347  
396 348 /// \brief Get available record lengths for this oscilloscope.
397 349 /// \return The number of physical channels, empty list for continuous.
398   -QList<unsigned> *HantekDsoControl::getAvailableRecordLengths() { return &settings.samplerate.limits->recordLengths; }
  350 +QList<unsigned> *HantekDsoControl::getAvailableRecordLengths() { return &controlsettings.samplerate.limits->recordLengths; }
399 351  
400 352 /// \brief Get minimum samplerate for this oscilloscope.
401 353 /// \return The minimum samplerate for the current configuration in S/s.
... ... @@ -407,7 +359,7 @@ double HantekDsoControl::getMinSamplerate() {
407 359 /// \return The maximum samplerate for the current configuration in S/s.
408 360 double HantekDsoControl::getMaxSamplerate() {
409 361 ControlSamplerateLimits *limits =
410   - (settings.usedChannels <= 1) ? &specification.samplerate.multi : &specification.samplerate.single;
  362 + (controlsettings.usedChannels <= 1) ? &specification.samplerate.multi : &specification.samplerate.single;
411 363 return limits->max;
412 364 }
413 365  
... ... @@ -417,20 +369,20 @@ void HantekDsoControl::updateInterval() {
417 369 // should be refilled
418 370 if (isRollMode())
419 371 cycleTime = (int)((double)device->getPacketSize() /
420   - ((settings.samplerate.limits == &specification.samplerate.multi) ? 1 : HANTEK_CHANNELS) /
421   - settings.samplerate.current * 250);
  372 + ((controlsettings.samplerate.limits == &specification.samplerate.multi) ? 1 : HANTEK_CHANNELS) /
  373 + controlsettings.samplerate.current * 250);
422 374 else
423   - cycleTime = (int)((double)getRecordLength() / settings.samplerate.current * 250);
  375 + cycleTime = (int)((double)getRecordLength() / controlsettings.samplerate.current * 250);
424 376  
425 377 // Not more often than every 10 ms though but at least once every second
426 378 cycleTime = qBound(10, cycleTime, 1000);
427 379 }
428 380  
429 381 bool HantekDsoControl::isRollMode() {
430   - return settings.samplerate.limits->recordLengths[settings.recordLengthId] == UINT_MAX;
  382 + return controlsettings.samplerate.limits->recordLengths[controlsettings.recordLengthId] == UINT_MAX;
431 383 }
432 384  
433   -int HantekDsoControl::getRecordLength() { return settings.samplerate.limits->recordLengths[settings.recordLengthId]; }
  385 +int HantekDsoControl::getRecordLength() { return controlsettings.samplerate.limits->recordLengths[controlsettings.recordLengthId]; }
434 386  
435 387 /// \brief Calculates the trigger point from the CommandGetCaptureState data.
436 388 /// \param value The data value that contains the trigger point.
... ... @@ -451,8 +403,7 @@ unsigned HantekDsoControl::calculateTriggerPoint(unsigned value) {
451 403 int HantekDsoControl::getCaptureState() {
452 404 int errorCode;
453 405  
454   - // Command not supported by this model
455   - if (device->getUniqueModelID() == MODEL_DSO6022BE) return CAPTURE_READY;
  406 + if (!specification.supportsCaptureState) return CAPTURE_READY;
456 407  
457 408 errorCode = device->bulkCommand(command[BULK_GETCAPTURESTATE], 1);
458 409 if (errorCode < 0) return errorCode;
... ... @@ -461,13 +412,14 @@ int HantekDsoControl::getCaptureState() {
461 412 errorCode = device->bulkRead(response.data(), response.getSize());
462 413 if (errorCode < 0) return errorCode;
463 414  
464   - settings.trigger.point = this->calculateTriggerPoint(response.getTriggerPoint());
  415 + controlsettings.trigger.point = this->calculateTriggerPoint(response.getTriggerPoint());
465 416  
466 417 return (int)response.getCaptureState();
467 418 }
468 419  
469 420 /// \brief Gets sample data from the oscilloscope and converts it.
470 421 /// \return sample count on success, libusb error code on error.
  422 +/// TODO Refactor. MODEL_DSO6022BE needs to be handled differently most of the time
471 423 int HantekDsoControl::getSamples(bool process) {
472 424 int errorCode;
473 425  
... ... @@ -518,14 +470,14 @@ int HantekDsoControl::getSamples(bool process) {
518 470 // Convert channel data
519 471 if (fastRate) {
520 472 QWriteLocker locker(&result.lock);
521   - result.samplerate = settings.samplerate.current;
  473 + result.samplerate = controlsettings.samplerate.current;
522 474 result.append = isRollMode();
523 475  
524 476 // Fast rate mode, one channel is using all buffers
525 477 sampleCount = totalSampleCount;
526 478 int channel = 0;
527 479 for (; channel < HANTEK_CHANNELS; ++channel) {
528   - if (settings.voltage[channel].used) break;
  480 + if (controlsettings.voltage[channel].used) break;
529 481 }
530 482  
531 483 // Clear unused channels
... ... @@ -538,7 +490,7 @@ int HantekDsoControl::getSamples(bool process) {
538 490  
539 491 // Convert data from the oscilloscope and write it into the sample
540 492 // buffer
541   - unsigned bufferPosition = settings.trigger.point * 2;
  493 + unsigned bufferPosition = controlsettings.trigger.point * 2;
542 494 if (specification.sampleSize > 8) {
543 495 // Additional most significant bits after the normal data
544 496 unsigned extraBitsPosition; // Track the position of the extra
... ... @@ -556,9 +508,9 @@ int HantekDsoControl::getSamples(bool process) {
556 508 (((unsigned short int)data[sampleCount + bufferPosition - extraBitsPosition]
557 509 << (8 - (HANTEK_CHANNELS - 1 - extraBitsPosition) * extraBitsSize)) &
558 510 extraBitsMask)) /
559   - specification.voltageLimit[channel][settings.voltage[channel].gain] -
560   - settings.voltage[channel].offsetReal) *
561   - specification.gainSteps[settings.voltage[channel].gain];
  511 + specification.voltageLimit[channel][controlsettings.voltage[channel].gain] -
  512 + controlsettings.voltage[channel].offsetReal) *
  513 + specification.gainSteps[controlsettings.voltage[channel].gain];
562 514 }
563 515 } else {
564 516 for (unsigned realPosition = 0; realPosition < sampleCount; ++realPosition, ++bufferPosition) {
... ... @@ -566,15 +518,15 @@ int HantekDsoControl::getSamples(bool process) {
566 518  
567 519 double dataBuf = (double)((int)data[bufferPosition]);
568 520 result.data[channel][realPosition] =
569   - (dataBuf / specification.voltageLimit[channel][settings.voltage[channel].gain] -
570   - settings.voltage[channel].offsetReal) *
571   - specification.gainSteps[settings.voltage[channel].gain];
  521 + (dataBuf / specification.voltageLimit[channel][controlsettings.voltage[channel].gain] -
  522 + controlsettings.voltage[channel].offsetReal) *
  523 + specification.gainSteps[controlsettings.voltage[channel].gain];
572 524 }
573 525 }
574 526 }
575 527 } else {
576 528 QWriteLocker locker(&result.lock);
577   - result.samplerate = settings.samplerate.current;
  529 + result.samplerate = controlsettings.samplerate.current;
578 530 result.append = isRollMode();
579 531  
580 532 // Normal mode, channels are using their separate buffers
... ... @@ -582,13 +534,13 @@ int HantekDsoControl::getSamples(bool process) {
582 534 // if device is 6022BE, drop heading & trailing samples
583 535 if (device->getUniqueModelID() == MODEL_DSO6022BE) sampleCount -= (DROP_DSO6022_HEAD + DROP_DSO6022_TAIL);
584 536 for (int channel = 0; channel < HANTEK_CHANNELS; ++channel) {
585   - if (settings.voltage[channel].used) {
  537 + if (controlsettings.voltage[channel].used) {
586 538 // Resize sample vector
587 539 if (result.data[channel].size() < sampleCount) { result.data[channel].resize(sampleCount); }
588 540  
589 541 // Convert data from the oscilloscope and write it into the sample
590 542 // buffer
591   - unsigned bufferPosition = settings.trigger.point * 2;
  543 + unsigned bufferPosition = controlsettings.trigger.point * 2;
592 544 if (specification.sampleSize > 8) {
593 545 // Additional most significant bits after the normal data
594 546 unsigned extraBitsSize = specification.sampleSize - 8; // Number of extra bits
... ... @@ -604,9 +556,9 @@ int HantekDsoControl::getSamples(bool process) {
604 556 ((double)((unsigned short int)data[bufferPosition + HANTEK_CHANNELS - 1 - channel] +
605 557 (((unsigned short int)data[totalSampleCount + bufferPosition] << extraBitsIndex) &
606 558 extraBitsMask)) /
607   - specification.voltageLimit[channel][settings.voltage[channel].gain] -
608   - settings.voltage[channel].offsetReal) *
609   - specification.gainSteps[settings.voltage[channel].gain];
  559 + specification.voltageLimit[channel][controlsettings.voltage[channel].gain] -
  560 + controlsettings.voltage[channel].offsetReal) *
  561 + specification.gainSteps[controlsettings.voltage[channel].gain];
610 562 }
611 563 } else {
612 564 if (device->getUniqueModelID() == MODEL_DSO6022BE) {
... ... @@ -623,14 +575,14 @@ int HantekDsoControl::getSamples(bool process) {
623 575 if (device->getUniqueModelID() == MODEL_DSO6022BE) {
624 576 double dataBuf = (double)((int)(data[bufferPosition] - 0x83));
625 577 result.data[channel][realPosition] =
626   - (dataBuf / specification.voltageLimit[channel][settings.voltage[channel].gain]) *
627   - specification.gainSteps[settings.voltage[channel].gain];
  578 + (dataBuf / specification.voltageLimit[channel][controlsettings.voltage[channel].gain]) *
  579 + specification.gainSteps[controlsettings.voltage[channel].gain];
628 580 } else {
629 581 double dataBuf = (double)((int)(data[bufferPosition]));
630 582 result.data[channel][realPosition] =
631   - (dataBuf / specification.voltageLimit[channel][settings.voltage[channel].gain] -
632   - settings.voltage[channel].offsetReal) *
633   - specification.gainSteps[settings.voltage[channel].gain];
  583 + (dataBuf / specification.voltageLimit[channel][controlsettings.voltage[channel].gain] -
  584 + controlsettings.voltage[channel].offsetReal) *
  585 + specification.gainSteps[controlsettings.voltage[channel].gain];
634 586 }
635 587 }
636 588 }
... ... @@ -673,12 +625,12 @@ double HantekDsoControl::getBestSamplerate(double samplerate, bool fastRate, boo
673 625 limits = &(specification.samplerate.single);
674 626  
675 627 // Get downsampling factor that would provide the requested rate
676   - double bestDownsampler = (double)limits->base / specification.bufferDividers[settings.recordLengthId] / samplerate;
  628 + double bestDownsampler = (double)limits->base / specification.bufferDividers[controlsettings.recordLengthId] / samplerate;
677 629 // Base samplerate sufficient, or is the maximum better?
678 630 if (bestDownsampler < 1.0 &&
679   - (samplerate <= limits->max / specification.bufferDividers[settings.recordLengthId] || !maximum)) {
  631 + (samplerate <= limits->max / specification.bufferDividers[controlsettings.recordLengthId] || !maximum)) {
680 632 bestDownsampler = 0.0;
681   - bestSamplerate = limits->max / specification.bufferDividers[settings.recordLengthId];
  633 + bestSamplerate = limits->max / specification.bufferDividers[controlsettings.recordLengthId];
682 634 } else {
683 635 switch (specification.command.bulk.setSamplerate) {
684 636 case BULK_SETTRIGGERANDSAMPLERATE:
... ... @@ -735,7 +687,7 @@ double HantekDsoControl::getBestSamplerate(double samplerate, bool fastRate, boo
735 687 // Limit maximum downsampler value to avoid overflows in the sent commands
736 688 if (bestDownsampler > limits->maxDownsampler) bestDownsampler = limits->maxDownsampler;
737 689  
738   - bestSamplerate = limits->base / bestDownsampler / specification.bufferDividers[settings.recordLengthId];
  690 + bestSamplerate = limits->base / bestDownsampler / specification.bufferDividers[controlsettings.recordLengthId];
739 691 }
740 692  
741 693 if (downsampler) *downsampler = (unsigned)bestDownsampler;
... ... @@ -747,7 +699,7 @@ double HantekDsoControl::getBestSamplerate(double samplerate, bool fastRate, boo
747 699 /// \return The total number of samples the scope should return.
748 700 unsigned HantekDsoControl::getSampleCount(bool *fastRate) {
749 701 unsigned totalSampleCount = getRecordLength();
750   - bool fastRateEnabled = settings.samplerate.limits == &specification.samplerate.multi;
  702 + bool fastRateEnabled = controlsettings.samplerate.limits == &specification.samplerate.multi;
751 703  
752 704 if (totalSampleCount == UINT_MAX) {
753 705 // Roll mode
... ... @@ -767,7 +719,7 @@ unsigned HantekDsoControl::getSampleCount(bool *fastRate) {
767 719 /// \param index The record length index that should be set.
768 720 /// \return The record length that has been set, 0 on error.
769 721 unsigned HantekDsoControl::updateRecordLength(unsigned index) {
770   - if (index >= (unsigned)settings.samplerate.limits->recordLengths.size()) return 0;
  722 + if (index >= (unsigned)controlsettings.samplerate.limits->recordLengths.size()) return 0;
771 723  
772 724 switch (specification.command.bulk.setRecordLength) {
773 725 case BULK_SETTRIGGERANDSAMPLERATE:
... ... @@ -802,9 +754,9 @@ unsigned HantekDsoControl::updateRecordLength(unsigned index) {
802 754 }
803 755  
804 756 // Check if the divider has changed and adapt samplerate limits accordingly
805   - bool bDividerChanged = specification.bufferDividers[index] != specification.bufferDividers[settings.recordLengthId];
  757 + bool bDividerChanged = specification.bufferDividers[index] != specification.bufferDividers[controlsettings.recordLengthId];
806 758  
807   - settings.recordLengthId = index;
  759 + controlsettings.recordLengthId = index;
808 760  
809 761 if (bDividerChanged) {
810 762 this->updateSamplerateLimits();
... ... @@ -813,7 +765,7 @@ unsigned HantekDsoControl::updateRecordLength(unsigned index) {
813 765 this->restoreTargets();
814 766 }
815 767  
816   - return settings.samplerate.limits->recordLengths[index];
  768 + return controlsettings.samplerate.limits->recordLengths[index];
817 769 }
818 770  
819 771 /// \brief Sets the samplerate based on the parameters calculated by
... ... @@ -915,36 +867,36 @@ unsigned HantekDsoControl::updateSamplerate(unsigned downsampler, bool fastRate)
915 867 }
916 868  
917 869 // Update settings
918   - bool fastRateChanged = fastRate != (settings.samplerate.limits == &specification.samplerate.multi);
919   - if (fastRateChanged) { settings.samplerate.limits = limits; }
  870 + bool fastRateChanged = fastRate != (controlsettings.samplerate.limits == &specification.samplerate.multi);
  871 + if (fastRateChanged) { controlsettings.samplerate.limits = limits; }
920 872  
921   - settings.samplerate.downsampler = downsampler;
  873 + controlsettings.samplerate.downsampler = downsampler;
922 874 if (downsampler)
923   - settings.samplerate.current =
924   - settings.samplerate.limits->base / specification.bufferDividers[settings.recordLengthId] / downsampler;
  875 + controlsettings.samplerate.current =
  876 + controlsettings.samplerate.limits->base / specification.bufferDividers[controlsettings.recordLengthId] / downsampler;
925 877 else
926   - settings.samplerate.current =
927   - settings.samplerate.limits->max / specification.bufferDividers[settings.recordLengthId];
  878 + controlsettings.samplerate.current =
  879 + controlsettings.samplerate.limits->max / specification.bufferDividers[controlsettings.recordLengthId];
928 880  
929 881 // Update dependencies
930   - this->setPretriggerPosition(settings.trigger.position);
  882 + this->setPretriggerPosition(controlsettings.trigger.position);
931 883  
932 884 // Emit signals for changed settings
933 885 if (fastRateChanged) {
934   - emit availableRecordLengthsChanged(settings.samplerate.limits->recordLengths);
  886 + emit availableRecordLengthsChanged(controlsettings.samplerate.limits->recordLengths);
935 887 emit recordLengthChanged(getRecordLength());
936 888 }
937 889  
938 890 // Check for Roll mode
939   - if (!isRollMode()) emit recordTimeChanged((double)getRecordLength() / settings.samplerate.current);
940   - emit samplerateChanged(settings.samplerate.current);
  891 + if (!isRollMode()) emit recordTimeChanged((double)getRecordLength() / controlsettings.samplerate.current);
  892 + emit samplerateChanged(controlsettings.samplerate.current);
941 893  
942 894 return downsampler;
943 895 }
944 896  
945 897 /// \brief Restore the samplerate/timebase targets after divider updates.
946 898 void HantekDsoControl::restoreTargets() {
947   - if (settings.samplerate.target.samplerateSet)
  899 + if (controlsettings.samplerate.target.samplerateSet)
948 900 this->setSamplerate();
949 901 else
950 902 this->setRecordTime();
... ... @@ -955,11 +907,11 @@ void HantekDsoControl::updateSamplerateLimits() {
955 907 // Works only if the minimum samplerate for normal mode is lower than for fast
956 908 // rate mode, which is the case for all models
957 909 ControlSamplerateLimits *limits =
958   - (settings.usedChannels <= 1) ? &specification.samplerate.multi : &specification.samplerate.single;
  910 + (controlsettings.usedChannels <= 1) ? &specification.samplerate.multi : &specification.samplerate.single;
959 911 emit samplerateLimitsChanged((double)specification.samplerate.single.base /
960 912 specification.samplerate.single.maxDownsampler /
961   - specification.bufferDividers[settings.recordLengthId],
962   - limits->max / specification.bufferDividers[settings.recordLengthId]);
  913 + specification.bufferDividers[controlsettings.recordLengthId],
  914 + limits->max / specification.bufferDividers[controlsettings.recordLengthId]);
963 915 }
964 916  
965 917 /// \brief Sets the size of the oscilloscopes sample buffer.
... ... @@ -971,7 +923,7 @@ unsigned HantekDsoControl::setRecordLength(unsigned index) {
971 923 if (!this->updateRecordLength(index)) return 0;
972 924  
973 925 this->restoreTargets();
974   - this->setPretriggerPosition(settings.trigger.position);
  926 + this->setPretriggerPosition(controlsettings.trigger.position);
975 927  
976 928 emit recordLengthChanged(getRecordLength());
977 929 return getRecordLength();
... ... @@ -985,18 +937,18 @@ double HantekDsoControl::setSamplerate(double samplerate) {
985 937 if (!device->isConnected()) return 0.0;
986 938  
987 939 if (samplerate == 0.0) {
988   - samplerate = settings.samplerate.target.samplerate;
  940 + samplerate = controlsettings.samplerate.target.samplerate;
989 941 } else {
990   - settings.samplerate.target.samplerate = samplerate;
991   - settings.samplerate.target.samplerateSet = true;
  942 + controlsettings.samplerate.target.samplerate = samplerate;
  943 + controlsettings.samplerate.target.samplerateSet = true;
992 944 }
993 945  
994   - if (device->getUniqueModelID() != MODEL_DSO6022BE) {
  946 + if (!specification.isSoftwareTriggerDevice) {
995 947 // When possible, enable fast rate if it is required to reach the requested
996 948 // samplerate
997 949 bool fastRate =
998   - (settings.usedChannels <= 1) &&
999   - (samplerate > specification.samplerate.single.max / specification.bufferDividers[settings.recordLengthId]);
  950 + (controlsettings.usedChannels <= 1) &&
  951 + (samplerate > specification.samplerate.single.max / specification.bufferDividers[controlsettings.recordLengthId]);
1000 952  
1001 953 // What is the nearest, at least as high samplerate the scope can provide?
1002 954 unsigned downsampler = 0;
... ... @@ -1016,14 +968,14 @@ double HantekDsoControl::setSamplerate(double samplerate) {
1016 968 static_cast<ControlSetTimeDIV *>(this->control[CONTROLINDEX_SETTIMEDIV])
1017 969 ->setDiv(specification.sampleDiv[sampleId]);
1018 970 this->controlPending[CONTROLINDEX_SETTIMEDIV] = true;
1019   - settings.samplerate.current = samplerate;
  971 + controlsettings.samplerate.current = samplerate;
1020 972  
1021 973 // Provide margin for SW trigger
1022 974 unsigned sampleMargin = 2000;
1023 975 // Check for Roll mode
1024 976 if (!isRollMode())
1025   - emit recordTimeChanged((double)(getRecordLength() - sampleMargin) / settings.samplerate.current);
1026   - emit samplerateChanged(settings.samplerate.current);
  977 + emit recordTimeChanged((double)(getRecordLength() - sampleMargin) / controlsettings.samplerate.current);
  978 + emit samplerateChanged(controlsettings.samplerate.current);
1027 979  
1028 980 return samplerate;
1029 981 }
... ... @@ -1037,23 +989,23 @@ double HantekDsoControl::setRecordTime(double duration) {
1037 989 if (!device->isConnected()) return 0.0;
1038 990  
1039 991 if (duration == 0.0) {
1040   - duration = settings.samplerate.target.duration;
  992 + duration = controlsettings.samplerate.target.duration;
1041 993 } else {
1042   - settings.samplerate.target.duration = duration;
1043   - settings.samplerate.target.samplerateSet = false;
  994 + controlsettings.samplerate.target.duration = duration;
  995 + controlsettings.samplerate.target.samplerateSet = false;
1044 996 }
1045 997  
1046   - if (device->getUniqueModelID() != MODEL_DSO6022BE) {
  998 + if (!specification.isSoftwareTriggerDevice) {
1047 999 // Calculate the maximum samplerate that would still provide the requested
1048 1000 // duration
1049 1001 double maxSamplerate =
1050   - (double)specification.samplerate.single.recordLengths[settings.recordLengthId] / duration;
  1002 + (double)specification.samplerate.single.recordLengths[controlsettings.recordLengthId] / duration;
1051 1003  
1052 1004 // When possible, enable fast rate if the record time can't be set that low
1053 1005 // to improve resolution
1054   - bool fastRate = (settings.usedChannels <= 1) &&
  1006 + bool fastRate = (controlsettings.usedChannels <= 1) &&
1055 1007 (maxSamplerate >=
1056   - specification.samplerate.multi.base / specification.bufferDividers[settings.recordLengthId]);
  1008 + specification.samplerate.multi.base / specification.bufferDividers[controlsettings.recordLengthId]);
1057 1009  
1058 1010 // What is the nearest, at most as high samplerate the scope can provide?
1059 1011 unsigned downsampler = 0;
... ... @@ -1084,10 +1036,10 @@ double HantekDsoControl::setRecordTime(double duration) {
1084 1036 static_cast<ControlSetTimeDIV *>(this->control[CONTROLINDEX_SETTIMEDIV])
1085 1037 ->setDiv(specification.sampleDiv[sampleId]);
1086 1038 this->controlPending[CONTROLINDEX_SETTIMEDIV] = true;
1087   - settings.samplerate.current = specification.sampleSteps[sampleId];
  1039 + controlsettings.samplerate.current = specification.sampleSteps[sampleId];
1088 1040  
1089   - emit samplerateChanged(settings.samplerate.current);
1090   - return settings.samplerate.current;
  1041 + emit samplerateChanged(controlsettings.samplerate.current);
  1042 + return controlsettings.samplerate.current;
1091 1043 }
1092 1044 }
1093 1045  
... ... @@ -1101,17 +1053,17 @@ int HantekDsoControl::setChannelUsed(unsigned channel, bool used) {
1101 1053 if (channel >= HANTEK_CHANNELS) return Dso::ERROR_PARAMETER;
1102 1054  
1103 1055 // Update settings
1104   - settings.voltage[channel].used = used;
  1056 + controlsettings.voltage[channel].used = used;
1105 1057 unsigned channelCount = 0;
1106 1058 for (int channelCounter = 0; channelCounter < HANTEK_CHANNELS; ++channelCounter) {
1107   - if (settings.voltage[channelCounter].used) ++channelCount;
  1059 + if (controlsettings.voltage[channelCounter].used) ++channelCount;
1108 1060 }
1109 1061  
1110 1062 // Calculate the UsedChannels field for the command
1111 1063 unsigned char usedChannels = USED_CH1;
1112 1064  
1113   - if (settings.voltage[1].used) {
1114   - if (settings.voltage[0].used) {
  1065 + if (controlsettings.voltage[1].used) {
  1066 + if (controlsettings.voltage[0].used) {
1115 1067 usedChannels = USED_CH1CH2;
1116 1068 } else {
1117 1069 // DSO-2250 uses a different value for channel 2
... ... @@ -1148,8 +1100,8 @@ int HantekDsoControl::setChannelUsed(unsigned channel, bool used) {
1148 1100 }
1149 1101  
1150 1102 // Check if fast rate mode availability changed
1151   - bool fastRateChanged = (settings.usedChannels <= 1) != (channelCount <= 1);
1152   - settings.usedChannels = channelCount;
  1103 + bool fastRateChanged = (controlsettings.usedChannels <= 1) != (channelCount <= 1);
  1104 + controlsettings.usedChannels = channelCount;
1153 1105  
1154 1106 if (fastRateChanged) this->updateSamplerateLimits();
1155 1107  
... ... @@ -1165,11 +1117,8 @@ int HantekDsoControl::setCoupling(unsigned channel, Dso::Coupling coupling) {
1165 1117  
1166 1118 if (channel >= HANTEK_CHANNELS) return Dso::ERROR_PARAMETER;
1167 1119  
1168   - // if (device->getModel() == MODEL_DSO6022BE)
1169   - // Dso::ERROR_NONE;
1170   -
1171 1120 // SetRelays control command for coupling relays
1172   - if (device->getUniqueModelID() != MODEL_DSO6022BE) {
  1121 + if (specification.supportsCouplingRelays) {
1173 1122 static_cast<ControlSetRelays *>(this->control[CONTROLINDEX_SETRELAYS])
1174 1123 ->setCoupling(channel, coupling != Dso::COUPLING_AC);
1175 1124 this->controlPending[CONTROLINDEX_SETRELAYS] = true;
... ... @@ -1192,8 +1141,7 @@ double HantekDsoControl::setGain(unsigned channel, double gain) {
1192 1141 for (gainId = 0; gainId < specification.gainSteps.count() - 1; ++gainId)
1193 1142 if (specification.gainSteps[gainId] >= gain) break;
1194 1143  
1195   - // Fixme, shoulb be some kind of protocol check instead of model check.
1196   - if (device->getUniqueModelID() == MODEL_DSO6022BE) {
  1144 + if (specification.useControlNoBulk) {
1197 1145 if (channel == 0) {
1198 1146 static_cast<ControlSetVoltDIV_CH1 *>(this->control[CONTROLINDEX_SETVOLTDIV_CH1])
1199 1147 ->setDiv(specification.gainDiv[gainId]);
... ... @@ -1216,9 +1164,9 @@ double HantekDsoControl::setGain(unsigned channel, double gain) {
1216 1164 this->controlPending[CONTROLINDEX_SETRELAYS] = true;
1217 1165 }
1218 1166  
1219   - settings.voltage[channel].gain = gainId;
  1167 + controlsettings.voltage[channel].gain = gainId;
1220 1168  
1221   - this->setOffset(channel, settings.voltage[channel].offset);
  1169 + this->setOffset(channel, controlsettings.voltage[channel].offset);
1222 1170  
1223 1171 return specification.gainSteps[gainId];
1224 1172 }
... ... @@ -1236,29 +1184,26 @@ double HantekDsoControl::setOffset(unsigned channel, double offset) {
1236 1184 // The range is given by the calibration data (convert from big endian)
1237 1185 unsigned short int minimum =
1238 1186 ((unsigned short int)*(
1239   - (unsigned char *)&(specification.offsetLimit[channel][settings.voltage[channel].gain][OFFSET_START]))
  1187 + (unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_START]))
1240 1188 << 8) +
1241   - *((unsigned char *)&(specification.offsetLimit[channel][settings.voltage[channel].gain][OFFSET_START]) + 1);
  1189 + *((unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_START]) + 1);
1242 1190 unsigned short int maximum =
1243 1191 ((unsigned short int)*(
1244   - (unsigned char *)&(specification.offsetLimit[channel][settings.voltage[channel].gain][OFFSET_END]))
  1192 + (unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_END]))
1245 1193 << 8) +
1246   - *((unsigned char *)&(specification.offsetLimit[channel][settings.voltage[channel].gain][OFFSET_END]) + 1);
  1194 + *((unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_END]) + 1);
1247 1195 unsigned short int offsetValue = offset * (maximum - minimum) + minimum + 0.5;
1248 1196 double offsetReal = (double)(offsetValue - minimum) / (maximum - minimum);
1249 1197  
1250   - // SetOffset control command for channel offset
1251   - // Don't set control command if 6022be.
1252   - // Otherwise, pipe error messages will be appeared.
1253   - if (device->getUniqueModelID() != MODEL_DSO6022BE) {
  1198 + if (specification.supportsOffset) {
1254 1199 static_cast<ControlSetOffset *>(this->control[CONTROLINDEX_SETOFFSET])->setChannel(channel, offsetValue);
1255 1200 this->controlPending[CONTROLINDEX_SETOFFSET] = true;
1256 1201 }
1257 1202  
1258   - settings.voltage[channel].offset = offset;
1259   - settings.voltage[channel].offsetReal = offsetReal;
  1203 + controlsettings.voltage[channel].offset = offset;
  1204 + controlsettings.voltage[channel].offsetReal = offsetReal;
1260 1205  
1261   - this->setTriggerLevel(channel, settings.trigger.level[channel]);
  1206 + this->setTriggerLevel(channel, controlsettings.trigger.level[channel]);
1262 1207  
1263 1208 return offsetReal;
1264 1209 }
... ... @@ -1270,7 +1215,7 @@ int HantekDsoControl::setTriggerMode(Dso::TriggerMode mode) {
1270 1215  
1271 1216 if (mode < Dso::TRIGGERMODE_AUTO || mode >= Dso::TRIGGERMODE_COUNT) return Dso::ERROR_PARAMETER;
1272 1217  
1273   - settings.trigger.mode = mode;
  1218 + controlsettings.trigger.mode = mode;
1274 1219 return Dso::ERROR_NONE;
1275 1220 }
1276 1221  
... ... @@ -1313,8 +1258,8 @@ int HantekDsoControl::setTriggerSource(bool special, unsigned id) {
1313 1258 static_cast<ControlSetRelays *>(this->control[CONTROLINDEX_SETRELAYS])->setTrigger(special);
1314 1259 this->controlPending[CONTROLINDEX_SETRELAYS] = true;
1315 1260  
1316   - settings.trigger.special = special;
1317   - settings.trigger.source = id;
  1261 + controlsettings.trigger.special = special;
  1262 + controlsettings.trigger.source = id;
1318 1263  
1319 1264 // Apply trigger level of the new source
1320 1265 if (special) {
... ... @@ -1322,7 +1267,7 @@ int HantekDsoControl::setTriggerSource(bool special, unsigned id) {
1322 1267 static_cast<ControlSetOffset *>(this->control[CONTROLINDEX_SETOFFSET])->setTrigger(0x7f);
1323 1268 this->controlPending[CONTROLINDEX_SETOFFSET] = true;
1324 1269 } else
1325   - this->setTriggerLevel(id, settings.trigger.level[id]);
  1270 + this->setTriggerLevel(id, controlsettings.trigger.level[id]);
1326 1271  
1327 1272 return Dso::ERROR_NONE;
1328 1273 }
... ... @@ -1336,47 +1281,38 @@ double HantekDsoControl::setTriggerLevel(unsigned channel, double level) {
1336 1281  
1337 1282 if (channel >= HANTEK_CHANNELS) return Dso::ERROR_PARAMETER;
1338 1283  
1339   - // if (device->getModel() == MODEL_DSO6022BE)
1340   - // return Dso::ERROR_NONE;
1341   -
1342 1284 // Calculate the trigger level value
1343 1285 unsigned short int minimum, maximum;
1344   - switch (device->getUniqueModelID()) {
1345   - case MODEL_DSO5200:
1346   - case MODEL_DSO5200A:
  1286 + if (specification.sampleSize>8) {
1347 1287 // The range is the same as used for the offsets for 10 bit models
1348 1288 minimum =
1349 1289 ((unsigned short int)*(
1350   - (unsigned char *)&(specification.offsetLimit[channel][settings.voltage[channel].gain][OFFSET_START]))
  1290 + (unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_START]))
1351 1291 << 8) +
1352   - *((unsigned char *)&(specification.offsetLimit[channel][settings.voltage[channel].gain][OFFSET_START]) + 1);
  1292 + *((unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_START]) + 1);
1353 1293 maximum =
1354 1294 ((unsigned short int)*(
1355   - (unsigned char *)&(specification.offsetLimit[channel][settings.voltage[channel].gain][OFFSET_END]))
  1295 + (unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_END]))
1356 1296 << 8) +
1357   - *((unsigned char *)&(specification.offsetLimit[channel][settings.voltage[channel].gain][OFFSET_END]) + 1);
1358   - break;
1359   -
1360   - default:
  1297 + *((unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_END]) + 1);
  1298 + } else {
1361 1299 // It's from 0x00 to 0xfd for the 8 bit models
1362 1300 minimum = 0x00;
1363 1301 maximum = 0xfd;
1364   - break;
1365 1302 }
1366 1303  
1367 1304 // Never get out of the limits
1368 1305 unsigned short int levelValue =
1369 1306 qBound((long int)minimum,
1370   - (long int)((settings.voltage[channel].offsetReal +
1371   - level / specification.gainSteps[settings.voltage[channel].gain]) *
  1307 + (long int)((controlsettings.voltage[channel].offsetReal +
  1308 + level / specification.gainSteps[controlsettings.voltage[channel].gain]) *
1372 1309 (maximum - minimum) +
1373 1310 0.5) +
1374 1311 minimum,
1375 1312 (long int)maximum);
1376 1313  
1377 1314 // Check if the set channel is the trigger source
1378   - if (!settings.trigger.special && channel == settings.trigger.source &&
1379   - device->getUniqueModelID() != MODEL_DSO6022BE) {
  1315 + if (!controlsettings.trigger.special && channel == controlsettings.trigger.source && specification.supportsOffset) {
1380 1316 // SetOffset control command for trigger level
1381 1317 static_cast<ControlSetOffset *>(this->control[CONTROLINDEX_SETOFFSET])->setTrigger(levelValue);
1382 1318 this->controlPending[CONTROLINDEX_SETOFFSET] = true;
... ... @@ -1384,9 +1320,9 @@ double HantekDsoControl::setTriggerLevel(unsigned channel, double level) {
1384 1320  
1385 1321 /// \todo Get alternating trigger in here
1386 1322  
1387   - settings.trigger.level[channel] = level;
1388   - return (double)((levelValue - minimum) / (maximum - minimum) - settings.voltage[channel].offsetReal) *
1389   - specification.gainSteps[settings.voltage[channel].gain];
  1323 + controlsettings.trigger.level[channel] = level;
  1324 + return (double)((levelValue - minimum) / (maximum - minimum) - controlsettings.voltage[channel].offsetReal) *
  1325 + specification.gainSteps[controlsettings.voltage[channel].gain];
1390 1326 }
1391 1327  
1392 1328 /// \brief Set the trigger slope.
... ... @@ -1395,7 +1331,7 @@ double HantekDsoControl::setTriggerLevel(unsigned channel, double level) {
1395 1331 int HantekDsoControl::setTriggerSlope(Dso::Slope slope) {
1396 1332 if (!device->isConnected()) return Dso::ERROR_CONNECTION;
1397 1333  
1398   - if (slope != Dso::SLOPE_NEGATIVE && slope != Dso::SLOPE_POSITIVE) return Dso::ERROR_PARAMETER;
  1334 + if (slope >= Dso::SLOPE_COUNT) return Dso::ERROR_PARAMETER;
1399 1335  
1400 1336 switch (specification.command.bulk.setTrigger) {
1401 1337 case BULK_SETTRIGGERANDSAMPLERATE: {
... ... @@ -1420,7 +1356,7 @@ int HantekDsoControl::setTriggerSlope(Dso::Slope slope) {
1420 1356 return Dso::ERROR_UNSUPPORTED;
1421 1357 }
1422 1358  
1423   - settings.trigger.slope = slope;
  1359 + controlsettings.trigger.slope = slope;
1424 1360 return Dso::ERROR_NONE;
1425 1361 }
1426 1362  
... ... @@ -1436,10 +1372,10 @@ double HantekDsoControl::setPretriggerPosition(double position) {
1436 1372 if (!device->isConnected()) return -2;
1437 1373  
1438 1374 // All trigger positions are measured in samples
1439   - unsigned positionSamples = position * settings.samplerate.current;
  1375 + unsigned positionSamples = position * controlsettings.samplerate.current;
1440 1376 unsigned recordLength = getRecordLength();
1441 1377 // Fast rate mode uses both channels
1442   - if (settings.samplerate.limits == &specification.samplerate.multi) positionSamples /= HANTEK_CHANNELS;
  1378 + if (controlsettings.samplerate.limits == &specification.samplerate.multi) positionSamples /= HANTEK_CHANNELS;
1443 1379  
1444 1380 switch (specification.command.bulk.setPretrigger) {
1445 1381 case BULK_SETTRIGGERANDSAMPLERATE: {
... ... @@ -1482,8 +1418,8 @@ double HantekDsoControl::setPretriggerPosition(double position) {
1482 1418 return Dso::ERROR_UNSUPPORTED;
1483 1419 }
1484 1420  
1485   - settings.trigger.position = position;
1486   - return (double)positionSamples / settings.samplerate.current;
  1421 + controlsettings.trigger.position = position;
  1422 + return (double)positionSamples / controlsettings.samplerate.current;
1487 1423 }
1488 1424  
1489 1425 int HantekDsoControl::stringCommand(const QString &commandString) {
... ... @@ -1643,7 +1579,7 @@ void HantekDsoControl::run() {
1643 1579 timestampDebug(QString("Received %1 B of sampling data").arg(errorCode));
1644 1580  
1645 1581 // Check if we're in single trigger mode
1646   - if (settings.trigger.mode == Dso::TRIGGERMODE_SINGLE && this->_samplingStarted) this->stopSampling();
  1582 + if (controlsettings.trigger.mode == Dso::TRIGGERMODE_SINGLE && this->_samplingStarted) this->stopSampling();
1647 1583  
1648 1584 // Sampling completed, restart it when necessary
1649 1585 this->_samplingStarted = false;
... ... @@ -1681,7 +1617,7 @@ void HantekDsoControl::run() {
1681 1617 timestampDebug(QString("Received %1 B of sampling data").arg(errorCode));
1682 1618  
1683 1619 // Check if we're in single trigger mode
1684   - if (settings.trigger.mode == Dso::TRIGGERMODE_SINGLE && this->_samplingStarted) this->stopSampling();
  1620 + if (controlsettings.trigger.mode == Dso::TRIGGERMODE_SINGLE && this->_samplingStarted) this->stopSampling();
1685 1621  
1686 1622 // Sampling completed, restart it when necessary
1687 1623 this->_samplingStarted = false;
... ... @@ -1693,7 +1629,7 @@ void HantekDsoControl::run() {
1693 1629 // Sampling hasn't started, update the expected sample count
1694 1630 this->previousSampleCount = this->getSampleCount();
1695 1631  
1696   - if (this->_samplingStarted && this->lastTriggerMode == settings.trigger.mode) {
  1632 + if (this->_samplingStarted && this->lastTriggerMode == controlsettings.trigger.mode) {
1697 1633 ++this->cycleCounter;
1698 1634  
1699 1635 if (this->cycleCounter == this->startCycle && !isRollMode()) {
... ... @@ -1710,7 +1646,7 @@ void HantekDsoControl::run() {
1710 1646  
1711 1647 timestampDebug("Enabling trigger");
1712 1648 } else if (this->cycleCounter >= 8 + this->startCycle &&
1713   - settings.trigger.mode == Dso::TRIGGERMODE_AUTO) {
  1649 + controlsettings.trigger.mode == Dso::TRIGGERMODE_AUTO) {
1714 1650 // Force triggering
1715 1651 errorCode = device->bulkCommand(command[BULK_FORCETRIGGER]);
1716 1652 if (errorCode < 0) {
... ... @@ -1741,8 +1677,8 @@ void HantekDsoControl::run() {
1741 1677  
1742 1678 this->_samplingStarted = true;
1743 1679 this->cycleCounter = 0;
1744   - this->startCycle = settings.trigger.position * 1000 / cycleTime + 1;
1745   - this->lastTriggerMode = settings.trigger.mode;
  1680 + this->startCycle = controlsettings.trigger.position * 1000 / cycleTime + 1;
  1681 + this->lastTriggerMode = controlsettings.trigger.mode;
1746 1682 break;
1747 1683  
1748 1684 case CAPTURE_SAMPLING:
... ...
openhantek/src/hantek/hantekdsocontrol.h
... ... @@ -95,26 +95,26 @@ class HantekDsoControl : public QObject {
95 95 USBDevice *device; ///< The USB device for the oscilloscope
96 96 bool sampling = false; ///< true, if the oscilloscope is taking samples
97 97  
98   - QStringList specialTriggerSources; ///< Names of the special trigger sources
  98 + QStringList specialTriggerSources = {tr("EXT"),tr("EXT/10")}; ///< Names of the special trigger sources
99 99  
100   - DataArray<unsigned char> *command[Hantek::BULK_COUNT]; ///< Pointers to bulk
  100 + DataArray<unsigned char> *command[Hantek::BULK_COUNT] = {0}; ///< Pointers to bulk
101 101 /// commands, ready to
102 102 /// be transmitted
103   - bool commandPending[Hantek::BULK_COUNT]; ///< true, when the command should be
  103 + bool commandPending[Hantek::BULK_COUNT] = {false}; ///< true, when the command should be
104 104 /// executed
105   - DataArray<unsigned char> *control[Hantek::CONTROLINDEX_COUNT]; ///< Pointers to control commands
  105 + DataArray<unsigned char> *control[Hantek::CONTROLINDEX_COUNT] = {0}; ///< Pointers to control commands
106 106 unsigned char controlCode[Hantek::CONTROLINDEX_COUNT]; ///< Request codes for
107 107 /// control commands
108   - bool controlPending[Hantek::CONTROLINDEX_COUNT]; ///< true, when the control
  108 + bool controlPending[Hantek::CONTROLINDEX_COUNT]= {false}; ///< true, when the control
109 109 /// command should be executed
110 110  
111 111 // Device setup
112 112 Hantek::ControlSpecification specification; ///< The specifications of the device
113   - Hantek::ControlSettings settings; ///< The current settings of the device
  113 + Hantek::ControlSettings controlsettings; ///< The current settings of the device
114 114  
115 115 // Results
116 116 DSOsamples result;
117   - unsigned previousSampleCount; ///< The expected total number of samples at
  117 + unsigned previousSampleCount = 0; ///< The expected total number of samples at
118 118 /// the last check before sampling started
119 119  
120 120 // State of the communication thread
... ... @@ -125,6 +125,7 @@ class HantekDsoControl : public QObject {
125 125 int cycleCounter = 0;
126 126 int startCycle = 0;
127 127 int cycleTime = 0;
  128 +
128 129 public slots:
129 130 void startSampling();
130 131 void stopSampling();
... ...
openhantek/src/hantek/stateStructs.h
... ... @@ -115,6 +115,12 @@ struct ControlSpecification {
115 115 /// Calibration data for the channel offsets \todo Should probably be a QList
116 116 /// too
117 117 unsigned short int offsetLimit[HANTEK_CHANNELS][9][OFFSET_COUNT];
  118 +
  119 + bool isSoftwareTriggerDevice=false;
  120 + bool useControlNoBulk = false;
  121 + bool supportsCaptureState = true;
  122 + bool supportsOffset = true;
  123 + bool supportsCouplingRelays = true;
118 124 };
119 125  
120 126 //////////////////////////////////////////////////////////////////////////////
... ...
openhantek/src/hantek/usb/usbdevice.cpp
... ... @@ -75,8 +75,7 @@ int USBDevice::claimInterface(const libusb_interface_descriptor *interfaceDescri
75 75 if (endpointDescriptor->bEndpointAddress == endpointOut) {
76 76 this->outPacketLength = endpointDescriptor->wMaxPacketSize;
77 77 } else if (endpointDescriptor->bEndpointAddress == endPointIn) {
78   - this->inPacketLength =
79   - (model.uniqueModelID == MODEL_DSO6022BE) ? 16384 : endpointDescriptor->wMaxPacketSize;
  78 + this->inPacketLength = endpointDescriptor->wMaxPacketSize;
80 79 }
81 80 }
82 81 return LIBUSB_SUCCESS;
... ... @@ -155,8 +154,7 @@ int USBDevice::bulkRead(unsigned char *data, unsigned int length, int attempts)
155 154 int USBDevice::bulkCommand(DataArray<unsigned char> *command, int attempts) {
156 155 if (!this->handle) return LIBUSB_ERROR_NO_DEVICE;
157 156  
158   - // don't send bulk command if dso6022be
159   - if (this->getUniqueModelID() == MODEL_DSO6022BE) return 0;
  157 + if (!allowBulkTransfer) return LIBUSB_SUCCESS;
160 158  
161 159 // Send BeginCommand control command
162 160 int errorCode = this->controlWrite(CONTROL_BEGINCOMMAND, this->beginCommandControl->data(),
... ... @@ -283,3 +281,13 @@ int USBDevice::getUniqueModelID() { return model.uniqueModelID; }
283 281 libusb_device *USBDevice::getRawDevice() const { return device; }
284 282  
285 283 const DSOModel &USBDevice::getModel() const { return model; }
  284 +
  285 +void USBDevice::setEnableBulkTransfer(bool enable)
  286 +{
  287 + allowBulkTransfer = enable;
  288 +}
  289 +
  290 +void USBDevice::overwriteInPacketLength(int len)
  291 +{
  292 + inPacketLength = len;
  293 +}
... ...
openhantek/src/hantek/usb/usbdevice.h
... ... @@ -63,6 +63,8 @@ class USBDevice : public QObject {
63 63  
64 64 libusb_device *getRawDevice() const;
65 65 const DSOModel &getModel() const;
  66 + void setEnableBulkTransfer(bool enable);
  67 + void overwriteInPacketLength(int len);
66 68  
67 69 protected:
68 70 int claimInterface(const libusb_interface_descriptor *interfaceDescriptor, int endpointOut, int endPointIn);
... ... @@ -79,6 +81,7 @@ class USBDevice : public QObject {
79 81 int interface;
80 82 int outPacketLength; ///< Packet length for the OUT endpoint
81 83 int inPacketLength; ///< Packet length for the IN endpoint
  84 + bool allowBulkTransfer = true;
82 85 signals:
83 86 void deviceDisconnected(); ///< The device has been disconnected
84 87 };
... ...