Commit f3ea2602f29f961a6369ee6ab1810e55acffdd15
Committed by
David Gräff
1 parent
c8f3559b
hantekdsocontrol: Modernize and make it more readable. Use const on all get meth…
…ods. Use error enum consistently
Showing
5 changed files
with
409 additions
and
436 deletions
openhantek/src/hantek/definitions.h
| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | namespace Dso { |
| 20 | 20 | /// \enum ErrorCode hantek/control.h |
| 21 | 21 | /// \brief The return codes for device control methods. |
| 22 | -enum ErrorCode { | |
| 22 | +enum class ErrorCode { | |
| 23 | 23 | ERROR_NONE = 0, ///< Successful operation |
| 24 | 24 | ERROR_CONNECTION = -1, ///< Device not connected or communication error |
| 25 | 25 | ERROR_UNSUPPORTED = -2, ///< Not supported by this device |
| ... | ... | @@ -821,7 +821,8 @@ enum CaptureState { |
| 821 | 821 | CAPTURE_SAMPLING = 1, ///< The scope is sampling data after triggering |
| 822 | 822 | CAPTURE_READY = 2, ///< Sampling data is available (DSO-2090/DSO-2150) |
| 823 | 823 | CAPTURE_READY2250 = 3, ///< Sampling data is available (DSO-2250) |
| 824 | - CAPTURE_READY5200 = 7 ///< Sampling data is available (DSO-5200/DSO-5200A) | |
| 824 | + CAPTURE_READY5200 = 7, ///< Sampling data is available (DSO-5200/DSO-5200A) | |
| 825 | + CAPTURE_ERROR = 1000 | |
| 825 | 826 | }; |
| 826 | 827 | |
| 827 | 828 | ////////////////////////////////////////////////////////////////////////////// | ... | ... |
openhantek/src/hantek/hantekdsocontrol.cpp
| ... | ... | @@ -32,9 +32,7 @@ void HantekDsoControl::startSampling() { |
| 32 | 32 | if (specification.isSoftwareTriggerDevice) { |
| 33 | 33 | // Convert to GUI presentable values (1e5 -> 1.0, 48e6 -> 480.0 etc) |
| 34 | 34 | QList<double> sampleSteps; |
| 35 | - for (double v: specification.sampleSteps) { | |
| 36 | - sampleSteps << v/1e5; | |
| 37 | - } | |
| 35 | + for (double v : specification.sampleSteps) { sampleSteps << v / 1e5; } | |
| 38 | 36 | emit samplerateSet(1, sampleSteps); |
| 39 | 37 | } |
| 40 | 38 | |
| ... | ... | @@ -47,15 +45,12 @@ void HantekDsoControl::stopSampling() { |
| 47 | 45 | emit samplingStopped(); |
| 48 | 46 | } |
| 49 | 47 | |
| 50 | -/// \brief Get a list of the names of the special trigger sources. | |
| 51 | 48 | const QStringList *HantekDsoControl::getSpecialTriggerSources() { return &(specialTriggerSources); } |
| 52 | 49 | |
| 53 | 50 | const USBDevice *HantekDsoControl::getDevice() const { return device; } |
| 54 | 51 | |
| 55 | 52 | const DSOsamples &HantekDsoControl::getLastSamples() { return result; } |
| 56 | 53 | |
| 57 | -/// \brief Initializes the command buffers and lists. | |
| 58 | -/// \param parent The parent widget. | |
| 59 | 54 | HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) { |
| 60 | 55 | if (device == nullptr) throw new std::runtime_error("No usb device for HantekDsoControl"); |
| 61 | 56 | |
| ... | ... | @@ -73,10 +68,8 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) { |
| 73 | 68 | |
| 74 | 69 | specification.samplerate.single.base = 50e6; |
| 75 | 70 | specification.samplerate.single.max = 50e6; |
| 76 | - specification.samplerate.single.recordLengths << 0; | |
| 77 | 71 | specification.samplerate.multi.base = 100e6; |
| 78 | 72 | specification.samplerate.multi.max = 100e6; |
| 79 | - specification.samplerate.multi.recordLengths << 0; | |
| 80 | 73 | |
| 81 | 74 | for (unsigned channel = 0; channel < HANTEK_CHANNELS; ++channel) { |
| 82 | 75 | for (unsigned gainId = 0; gainId < 9; ++gainId) { |
| ... | ... | @@ -102,8 +95,8 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) { |
| 102 | 95 | controlsettings.voltage[channel].offsetReal = 0.0; |
| 103 | 96 | controlsettings.voltage[channel].used = false; |
| 104 | 97 | } |
| 105 | - controlsettings.recordLengthId = 1; | |
| 106 | 98 | controlsettings.usedChannels = 0; |
| 99 | + controlsettings.recordLengthId = 1; | |
| 107 | 100 | |
| 108 | 101 | // Transmission-ready control commands |
| 109 | 102 | this->control[CONTROLINDEX_SETOFFSET] = new ControlSetOffset(); |
| ... | ... | @@ -113,9 +106,6 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) { |
| 113 | 106 | |
| 114 | 107 | for (int cIndex = 0; cIndex < CONTROLINDEX_COUNT; ++cIndex) this->controlPending[cIndex] = false; |
| 115 | 108 | |
| 116 | - // Sample buffers | |
| 117 | - result.data.resize(HANTEK_CHANNELS); | |
| 118 | - | |
| 119 | 109 | int errorCode; |
| 120 | 110 | |
| 121 | 111 | // Instantiate the commands needed for all models |
| ... | ... | @@ -153,11 +143,11 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) { |
| 153 | 143 | specification.samplerate.single.base = 50e6; |
| 154 | 144 | specification.samplerate.single.max = 75e6; |
| 155 | 145 | specification.samplerate.single.maxDownsampler = 131072; |
| 156 | - specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 32768; | |
| 146 | + specification.samplerate.single.recordLengths = {UINT_MAX, 10240, 32768}; | |
| 157 | 147 | specification.samplerate.multi.base = 100e6; |
| 158 | 148 | specification.samplerate.multi.max = 150e6; |
| 159 | 149 | specification.samplerate.multi.maxDownsampler = 131072; |
| 160 | - specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 65536; | |
| 150 | + specification.samplerate.multi.recordLengths = {UINT_MAX, 20480, 65536}; | |
| 161 | 151 | specification.bufferDividers << 1000 << 1 << 1; |
| 162 | 152 | specification.gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0; |
| 163 | 153 | for (int channel = 0; channel < HANTEK_CHANNELS; ++channel) |
| ... | ... | @@ -179,11 +169,11 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) { |
| 179 | 169 | specification.samplerate.single.base = 50e6; |
| 180 | 170 | specification.samplerate.single.max = 50e6; |
| 181 | 171 | specification.samplerate.single.maxDownsampler = 131072; |
| 182 | - specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 32768; | |
| 172 | + specification.samplerate.single.recordLengths = {UINT_MAX, 10240, 32768}; | |
| 183 | 173 | specification.samplerate.multi.base = 100e6; |
| 184 | 174 | specification.samplerate.multi.max = 100e6; |
| 185 | 175 | specification.samplerate.multi.maxDownsampler = 131072; |
| 186 | - specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 65536; | |
| 176 | + specification.samplerate.multi.recordLengths = {UINT_MAX, 20480, 65536}; | |
| 187 | 177 | specification.bufferDividers << 1000 << 1 << 1; |
| 188 | 178 | specification.gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0; |
| 189 | 179 | for (int channel = 0; channel < HANTEK_CHANNELS; ++channel) |
| ... | ... | @@ -216,11 +206,11 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) { |
| 216 | 206 | specification.samplerate.single.base = 100e6; |
| 217 | 207 | specification.samplerate.single.max = 100e6; |
| 218 | 208 | specification.samplerate.single.maxDownsampler = 65536; |
| 219 | - specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 524288; | |
| 209 | + specification.samplerate.single.recordLengths = {UINT_MAX, 10240, 524288}; | |
| 220 | 210 | specification.samplerate.multi.base = 200e6; |
| 221 | 211 | specification.samplerate.multi.max = 250e6; |
| 222 | 212 | specification.samplerate.multi.maxDownsampler = 65536; |
| 223 | - specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 1048576; | |
| 213 | + specification.samplerate.multi.recordLengths = {UINT_MAX, 20480, 1048576}; | |
| 224 | 214 | specification.bufferDividers << 1000 << 1 << 1; |
| 225 | 215 | specification.gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0; |
| 226 | 216 | for (int channel = 0; channel < HANTEK_CHANNELS; ++channel) |
| ... | ... | @@ -251,11 +241,11 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) { |
| 251 | 241 | specification.samplerate.single.base = 100e6; |
| 252 | 242 | specification.samplerate.single.max = 125e6; |
| 253 | 243 | specification.samplerate.single.maxDownsampler = 131072; |
| 254 | - specification.samplerate.single.recordLengths << UINT_MAX << 10240 << 14336; | |
| 244 | + specification.samplerate.single.recordLengths = {UINT_MAX, 10240, 14336}; | |
| 255 | 245 | specification.samplerate.multi.base = 200e6; |
| 256 | 246 | specification.samplerate.multi.max = 250e6; |
| 257 | 247 | specification.samplerate.multi.maxDownsampler = 131072; |
| 258 | - specification.samplerate.multi.recordLengths << UINT_MAX << 20480 << 28672; | |
| 248 | + specification.samplerate.multi.recordLengths = {UINT_MAX, 20480, 28672}; | |
| 259 | 249 | specification.bufferDividers << 1000 << 1 << 1; |
| 260 | 250 | specification.gainSteps << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0 << 80.0; |
| 261 | 251 | /// \todo Use calibration data to get the DSO-5200(A) sample ranges |
| ... | ... | @@ -297,11 +287,11 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) { |
| 297 | 287 | specification.samplerate.single.base = 1e6; |
| 298 | 288 | specification.samplerate.single.max = 48e6; |
| 299 | 289 | specification.samplerate.single.maxDownsampler = 10; |
| 300 | - specification.samplerate.single.recordLengths << UINT_MAX << 10240; | |
| 290 | + specification.samplerate.single.recordLengths = {UINT_MAX, 10240}; | |
| 301 | 291 | specification.samplerate.multi.base = 1e6; |
| 302 | 292 | specification.samplerate.multi.max = 48e6; |
| 303 | 293 | specification.samplerate.multi.maxDownsampler = 10; |
| 304 | - specification.samplerate.multi.recordLengths << UINT_MAX << 20480; | |
| 294 | + specification.samplerate.multi.recordLengths = {UINT_MAX, 20480}; | |
| 305 | 295 | specification.bufferDividers << 1000 << 1 << 1; |
| 306 | 296 | specification.gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0; |
| 307 | 297 | // This data was based on testing and depends on Divider. |
| ... | ... | @@ -318,45 +308,36 @@ HantekDsoControl::HantekDsoControl(USBDevice *device) : device(device) { |
| 318 | 308 | throw new std::runtime_error("unknown model"); |
| 319 | 309 | } |
| 320 | 310 | |
| 321 | - controlsettings.recordLengthId = 1; | |
| 322 | - controlsettings.samplerate.limits = &(specification.samplerate.single); | |
| 323 | - controlsettings.samplerate.downsampler = 1; | |
| 324 | 311 | this->previousSampleCount = 0; |
| 325 | 312 | |
| 326 | 313 | // Get channel level data |
| 327 | 314 | errorCode = device->controlRead(CONTROL_VALUE, (unsigned char *)&(specification.offsetLimit), |
| 328 | 315 | sizeof(specification.offsetLimit), (int)VALUE_OFFSETLIMITS); |
| 329 | 316 | if (errorCode < 0) { |
| 330 | - device->disconnect(); | |
| 317 | + qWarning() << tr("Couldn't get channel level data from oscilloscope"); | |
| 331 | 318 | emit statusMessage(tr("Couldn't get channel level data from oscilloscope"), 0); |
| 319 | + emit communicationError(); | |
| 332 | 320 | return; |
| 333 | 321 | } |
| 334 | 322 | |
| 335 | 323 | sampling = false; |
| 336 | 324 | } |
| 337 | 325 | |
| 338 | -/// \brief Disconnects the device. | |
| 339 | 326 | HantekDsoControl::~HantekDsoControl() { |
| 340 | 327 | // Clean up commands |
| 341 | 328 | for (int cIndex = 0; cIndex < BULK_COUNT; ++cIndex) { delete command[cIndex]; } |
| 342 | 329 | } |
| 343 | 330 | |
| 344 | -/// \brief Gets the physical channel count for this oscilloscope. | |
| 345 | -/// \return The number of physical channels. | |
| 346 | 331 | unsigned HantekDsoControl::getChannelCount() { return HANTEK_CHANNELS; } |
| 347 | 332 | |
| 348 | -/// \brief Get available record lengths for this oscilloscope. | |
| 349 | -/// \return The number of physical channels, empty list for continuous. | |
| 350 | -QList<unsigned> *HantekDsoControl::getAvailableRecordLengths() { return &controlsettings.samplerate.limits->recordLengths; } | |
| 333 | +const std::vector<unsigned> &HantekDsoControl::getAvailableRecordLengths() { // | |
| 334 | + return controlsettings.samplerate.limits->recordLengths; | |
| 335 | +} | |
| 351 | 336 | |
| 352 | -/// \brief Get minimum samplerate for this oscilloscope. | |
| 353 | -/// \return The minimum samplerate for the current configuration in S/s. | |
| 354 | 337 | double HantekDsoControl::getMinSamplerate() { |
| 355 | 338 | return (double)specification.samplerate.single.base / specification.samplerate.single.maxDownsampler; |
| 356 | 339 | } |
| 357 | 340 | |
| 358 | -/// \brief Get maximum samplerate for this oscilloscope. | |
| 359 | -/// \return The maximum samplerate for the current configuration in S/s. | |
| 360 | 341 | double HantekDsoControl::getMaxSamplerate() { |
| 361 | 342 | ControlSamplerateLimits *limits = |
| 362 | 343 | (controlsettings.usedChannels <= 1) ? &specification.samplerate.multi : &specification.samplerate.single; |
| ... | ... | @@ -368,8 +349,7 @@ void HantekDsoControl::updateInterval() { |
| 368 | 349 | // Check the current oscilloscope state everytime 25% of the time the buffer |
| 369 | 350 | // should be refilled |
| 370 | 351 | if (isRollMode()) |
| 371 | - cycleTime = (int)((double)device->getPacketSize() / | |
| 372 | - ((controlsettings.samplerate.limits == &specification.samplerate.multi) ? 1 : HANTEK_CHANNELS) / | |
| 352 | + cycleTime = (int)((double)device->getPacketSize() / (isFastRate() ? 1 : HANTEK_CHANNELS) / | |
| 373 | 353 | controlsettings.samplerate.current * 250); |
| 374 | 354 | else |
| 375 | 355 | cycleTime = (int)((double)getRecordLength() / controlsettings.samplerate.current * 250); |
| ... | ... | @@ -378,15 +358,18 @@ void HantekDsoControl::updateInterval() { |
| 378 | 358 | cycleTime = qBound(10, cycleTime, 1000); |
| 379 | 359 | } |
| 380 | 360 | |
| 381 | -bool HantekDsoControl::isRollMode() { | |
| 361 | +bool HantekDsoControl::isRollMode() const { | |
| 382 | 362 | return controlsettings.samplerate.limits->recordLengths[controlsettings.recordLengthId] == UINT_MAX; |
| 383 | 363 | } |
| 384 | 364 | |
| 385 | -int HantekDsoControl::getRecordLength() { return controlsettings.samplerate.limits->recordLengths[controlsettings.recordLengthId]; } | |
| 365 | +bool HantekDsoControl::isFastRate() const { | |
| 366 | + return controlsettings.samplerate.limits == &specification.samplerate.multi; | |
| 367 | +} | |
| 368 | + | |
| 369 | +int HantekDsoControl::getRecordLength() const { | |
| 370 | + return controlsettings.samplerate.limits->recordLengths[controlsettings.recordLengthId]; | |
| 371 | +} | |
| 386 | 372 | |
| 387 | -/// \brief Calculates the trigger point from the CommandGetCaptureState data. | |
| 388 | -/// \param value The data value that contains the trigger point. | |
| 389 | -/// \return The calculated trigger point for the given data. | |
| 390 | 373 | unsigned HantekDsoControl::calculateTriggerPoint(unsigned value) { |
| 391 | 374 | unsigned result = value; |
| 392 | 375 | |
| ... | ... | @@ -397,235 +380,192 @@ unsigned HantekDsoControl::calculateTriggerPoint(unsigned value) { |
| 397 | 380 | return result; |
| 398 | 381 | } |
| 399 | 382 | |
| 400 | -/// \brief Gets the current state. | |
| 401 | -/// \return The current CaptureState of the oscilloscope, libusb error code on | |
| 402 | -/// error. | |
| 403 | -int HantekDsoControl::getCaptureState() { | |
| 383 | +std::pair<int, unsigned> HantekDsoControl::getCaptureState() const { | |
| 404 | 384 | int errorCode; |
| 405 | 385 | |
| 406 | - if (!specification.supportsCaptureState) return CAPTURE_READY; | |
| 386 | + if (!specification.supportsCaptureState) return std::make_pair(CAPTURE_READY, 0); | |
| 407 | 387 | |
| 408 | 388 | errorCode = device->bulkCommand(command[BULK_GETCAPTURESTATE], 1); |
| 409 | - if (errorCode < 0) return errorCode; | |
| 389 | + if (errorCode < 0) { | |
| 390 | + qWarning() << "Getting capture state failed: " << libUsbErrorString(errorCode); | |
| 391 | + return std::make_pair(CAPTURE_ERROR, 0); | |
| 392 | + } | |
| 410 | 393 | |
| 411 | 394 | BulkResponseGetCaptureState response; |
| 412 | 395 | errorCode = device->bulkRead(response.data(), response.getSize()); |
| 413 | - if (errorCode < 0) return errorCode; | |
| 414 | - | |
| 415 | - controlsettings.trigger.point = this->calculateTriggerPoint(response.getTriggerPoint()); | |
| 396 | + if (errorCode < 0) { | |
| 397 | + qWarning() << "Getting capture state failed: " << libUsbErrorString(errorCode); | |
| 398 | + return std::make_pair(CAPTURE_ERROR, 0); | |
| 399 | + } | |
| 416 | 400 | |
| 417 | - return (int)response.getCaptureState(); | |
| 401 | + return std::make_pair((int)response.getCaptureState(), response.getTriggerPoint()); | |
| 418 | 402 | } |
| 419 | 403 | |
| 420 | -/// \brief Gets sample data from the oscilloscope and converts it. | |
| 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 | |
| 423 | -int HantekDsoControl::getSamples(bool process) { | |
| 424 | - int errorCode; | |
| 425 | - | |
| 426 | - const unsigned DROP_DSO6022_HEAD = 0x410; | |
| 427 | - const unsigned DROP_DSO6022_TAIL = 0x3F0; | |
| 428 | - | |
| 429 | - if (device->getUniqueModelID() != MODEL_DSO6022BE) { | |
| 404 | +std::vector<unsigned char> HantekDsoControl::getSamples(unsigned &previousSampleCount) const { | |
| 405 | + if (!specification.useControlNoBulk) { | |
| 430 | 406 | // Request data |
| 431 | - errorCode = device->bulkCommand(command[BULK_GETDATA], 1); | |
| 432 | - if (errorCode < 0) return errorCode; | |
| 407 | + int errorCode = device->bulkCommand(command[BULK_GETDATA], 1); | |
| 408 | + if (errorCode < 0) { | |
| 409 | + qWarning() << "Getting sample data failed: " << libUsbErrorString(errorCode); | |
| 410 | + emit communicationError(); | |
| 411 | + return std::vector<unsigned char>(); | |
| 412 | + } | |
| 433 | 413 | } |
| 434 | 414 | |
| 435 | - // Save raw data to temporary buffer | |
| 436 | - bool fastRate = false; | |
| 437 | - unsigned totalSampleCount = this->getSampleCount(&fastRate); | |
| 438 | - if (totalSampleCount == UINT_MAX) return LIBUSB_ERROR_INVALID_PARAM; | |
| 415 | + unsigned totalSampleCount = this->getSampleCount(); | |
| 439 | 416 | |
| 440 | 417 | // To make sure no samples will remain in the scope buffer, also check the |
| 441 | 418 | // sample count before the last sampling started |
| 442 | - if (totalSampleCount < this->previousSampleCount) { | |
| 443 | - unsigned currentSampleCount = totalSampleCount; | |
| 444 | - totalSampleCount = this->previousSampleCount; | |
| 445 | - this->previousSampleCount = currentSampleCount; // Using sampleCount as temporary buffer since it | |
| 446 | - // was set to totalSampleCount | |
| 419 | + if (totalSampleCount < previousSampleCount) { | |
| 420 | + std::swap(totalSampleCount, previousSampleCount); | |
| 447 | 421 | } else { |
| 448 | - this->previousSampleCount = totalSampleCount; | |
| 422 | + previousSampleCount = totalSampleCount; | |
| 449 | 423 | } |
| 450 | 424 | |
| 451 | - unsigned sampleCount = totalSampleCount; | |
| 452 | - if (!fastRate) sampleCount /= HANTEK_CHANNELS; | |
| 453 | - unsigned dataLength = totalSampleCount; | |
| 454 | - if (specification.sampleSize > 8) dataLength *= 2; | |
| 425 | + unsigned dataLength = (specification.sampleSize > 8) ? totalSampleCount * 2 : totalSampleCount; | |
| 455 | 426 | |
| 427 | + // Save raw data to temporary buffer | |
| 456 | 428 | std::vector<unsigned char> data(dataLength); |
| 457 | - errorCode = device->bulkReadMulti(data.data(), dataLength); | |
| 458 | - if (errorCode < 0) return errorCode; | |
| 429 | + int errorcode = device->bulkReadMulti(data.data(), dataLength); | |
| 430 | + if (errorcode < 0) { | |
| 431 | + qWarning() << "Getting sample data failed: " << libUsbErrorString(errorcode); | |
| 432 | + return std::vector<unsigned char>(); | |
| 433 | + } | |
| 434 | + data.resize((size_t)errorcode); | |
| 459 | 435 | |
| 460 | - // Process the data only if we want it | |
| 461 | - if (!process) return LIBUSB_SUCCESS; | |
| 436 | + static unsigned id = 0; | |
| 437 | + ++id; | |
| 438 | + timestampDebug(QString("Received packet %1").arg(id)); | |
| 462 | 439 | |
| 463 | - // How much data did we really receive? | |
| 464 | - dataLength = errorCode; | |
| 465 | - if (specification.sampleSize > 8) | |
| 466 | - totalSampleCount = dataLength / 2; | |
| 467 | - else | |
| 468 | - totalSampleCount = dataLength; | |
| 440 | + return data; | |
| 441 | +} | |
| 469 | 442 | |
| 470 | - // Convert channel data | |
| 471 | - if (fastRate) { | |
| 472 | - QWriteLocker locker(&result.lock); | |
| 473 | - result.samplerate = controlsettings.samplerate.current; | |
| 474 | - result.append = isRollMode(); | |
| 443 | +void HantekDsoControl::convertRawDataToSamples(const std::vector<unsigned char> &rawData) { | |
| 444 | + const size_t totalSampleCount = (specification.sampleSize > 8) ? rawData.size() / 2 : rawData.size(); | |
| 445 | + | |
| 446 | + QWriteLocker locker(&result.lock); | |
| 447 | + result.samplerate = controlsettings.samplerate.current; | |
| 448 | + result.append = isRollMode(); | |
| 449 | + // Prepare result buffers | |
| 450 | + result.data.resize(HANTEK_CHANNELS); | |
| 451 | + for (int channelCounter = 0; channelCounter < HANTEK_CHANNELS; ++channelCounter) | |
| 452 | + result.data[channelCounter].clear(); | |
| 453 | + | |
| 454 | + const unsigned extraBitsSize = specification.sampleSize - 8; // Number of extra bits | |
| 455 | + const unsigned short extraBitsMask = (0x00ff << extraBitsSize) & 0xff00; // Mask for extra bits extraction | |
| 475 | 456 | |
| 457 | + // Convert channel data | |
| 458 | + if (isFastRate()) { | |
| 476 | 459 | // Fast rate mode, one channel is using all buffers |
| 477 | - sampleCount = totalSampleCount; | |
| 478 | - int channel = 0; | |
| 460 | + unsigned channel = 0; | |
| 479 | 461 | for (; channel < HANTEK_CHANNELS; ++channel) { |
| 480 | 462 | if (controlsettings.voltage[channel].used) break; |
| 481 | 463 | } |
| 482 | 464 | |
| 483 | - // Clear unused channels | |
| 484 | - for (int channelCounter = 0; channelCounter < HANTEK_CHANNELS; ++channelCounter) | |
| 485 | - if (channelCounter != channel) { result.data[channelCounter].clear(); } | |
| 465 | + if (channel >= HANTEK_CHANNELS) return; | |
| 486 | 466 | |
| 487 | - if (channel < HANTEK_CHANNELS) { | |
| 488 | - // Resize sample vector | |
| 489 | - result.data[channel].resize(sampleCount); | |
| 467 | + // Resize sample vector | |
| 468 | + result.data[channel].resize(totalSampleCount); | |
| 469 | + | |
| 470 | + const int gainID = (int)controlsettings.voltage[channel].gain; | |
| 471 | + const unsigned short limit = specification.voltageLimit[channel][gainID]; | |
| 472 | + const double offset = controlsettings.voltage[channel].offsetReal; | |
| 473 | + const double gainStep = specification.gainSteps[gainID]; | |
| 474 | + | |
| 475 | + // Convert data from the oscilloscope and write it into the sample buffer | |
| 476 | + unsigned bufferPosition = controlsettings.trigger.point * 2; | |
| 477 | + if (specification.sampleSize > 8) { | |
| 478 | + for (unsigned pos = 0; pos < totalSampleCount; ++pos, ++bufferPosition) { | |
| 479 | + if (bufferPosition >= totalSampleCount) bufferPosition %= totalSampleCount; | |
| 480 | + | |
| 481 | + const unsigned short low = rawData[bufferPosition]; | |
| 482 | + const unsigned extraBitsPosition = bufferPosition % HANTEK_CHANNELS; | |
| 483 | + const unsigned shift = (8 - (HANTEK_CHANNELS - 1 - extraBitsPosition) * extraBitsSize); | |
| 484 | + const unsigned short high = | |
| 485 | + ((unsigned short int)rawData[totalSampleCount + bufferPosition - extraBitsPosition] << shift) & | |
| 486 | + extraBitsMask; | |
| 487 | + | |
| 488 | + result.data[channel][pos] = ((double)(low + high) / limit - offset) * gainStep; | |
| 489 | + } | |
| 490 | + } else { | |
| 491 | + for (unsigned pos = 0; pos < totalSampleCount; ++pos, ++bufferPosition) { | |
| 492 | + if (bufferPosition >= totalSampleCount) bufferPosition %= totalSampleCount; | |
| 493 | + | |
| 494 | + double dataBuf = (double)((int)rawData[bufferPosition]); | |
| 495 | + result.data[channel][pos] = (dataBuf / limit - offset) * gainStep; | |
| 496 | + } | |
| 497 | + } | |
| 498 | + } else { | |
| 499 | + // Normal mode, channels are using their separate buffers | |
| 500 | + for (unsigned channel = 0; channel < HANTEK_CHANNELS; ++channel) { | |
| 501 | + result.data[channel].resize(totalSampleCount / HANTEK_CHANNELS); | |
| 490 | 502 | |
| 491 | - // Convert data from the oscilloscope and write it into the sample | |
| 492 | - // buffer | |
| 503 | + const int gainID = controlsettings.voltage[channel].gain; | |
| 504 | + const unsigned short limit = specification.voltageLimit[channel][gainID]; | |
| 505 | + const double offset = controlsettings.voltage[channel].offsetReal; | |
| 506 | + const double gainStep = specification.gainSteps[gainID]; | |
| 507 | + | |
| 508 | + // Convert data from the oscilloscope and write it into the sample buffer | |
| 493 | 509 | unsigned bufferPosition = controlsettings.trigger.point * 2; |
| 494 | 510 | if (specification.sampleSize > 8) { |
| 495 | 511 | // Additional most significant bits after the normal data |
| 496 | - unsigned extraBitsPosition; // Track the position of the extra | |
| 497 | - // bits in the additional byte | |
| 498 | - unsigned extraBitsSize = specification.sampleSize - 8; // Number of extra bits | |
| 499 | - unsigned short int extraBitsMask = (0x00ff << extraBitsSize) & 0xff00; // Mask for extra bits extraction | |
| 500 | - | |
| 501 | - for (unsigned realPosition = 0; realPosition < sampleCount; ++realPosition, ++bufferPosition) { | |
| 502 | - if (bufferPosition >= sampleCount) bufferPosition %= sampleCount; | |
| 503 | - | |
| 504 | - extraBitsPosition = bufferPosition % HANTEK_CHANNELS; | |
| 505 | - | |
| 506 | - result.data[channel][realPosition] = | |
| 507 | - ((double)((unsigned short int)data[bufferPosition] + | |
| 508 | - (((unsigned short int)data[sampleCount + bufferPosition - extraBitsPosition] | |
| 509 | - << (8 - (HANTEK_CHANNELS - 1 - extraBitsPosition) * extraBitsSize)) & | |
| 510 | - extraBitsMask)) / | |
| 511 | - specification.voltageLimit[channel][controlsettings.voltage[channel].gain] - | |
| 512 | - controlsettings.voltage[channel].offsetReal) * | |
| 513 | - specification.gainSteps[controlsettings.voltage[channel].gain]; | |
| 512 | + unsigned extraBitsIndex = 8 - channel * 2; // Bit position offset for extra bits extraction | |
| 513 | + | |
| 514 | + for (unsigned realPosition = 0; realPosition < result.data[channel].size(); | |
| 515 | + ++realPosition, bufferPosition += HANTEK_CHANNELS) { | |
| 516 | + if (bufferPosition >= totalSampleCount) bufferPosition %= totalSampleCount; | |
| 517 | + | |
| 518 | + const unsigned short low = rawData[bufferPosition + HANTEK_CHANNELS - 1 - channel]; | |
| 519 | + const unsigned short high = | |
| 520 | + ((unsigned short int)rawData[totalSampleCount + bufferPosition] << extraBitsIndex) & | |
| 521 | + extraBitsMask; | |
| 522 | + | |
| 523 | + result.data[channel][realPosition] = ((double)(low + high) / limit - offset) * gainStep; | |
| 514 | 524 | } |
| 515 | - } else { | |
| 516 | - for (unsigned realPosition = 0; realPosition < sampleCount; ++realPosition, ++bufferPosition) { | |
| 517 | - if (bufferPosition >= sampleCount) bufferPosition %= sampleCount; | |
| 518 | - | |
| 519 | - double dataBuf = (double)((int)data[bufferPosition]); | |
| 520 | - result.data[channel][realPosition] = | |
| 521 | - (dataBuf / specification.voltageLimit[channel][controlsettings.voltage[channel].gain] - | |
| 522 | - controlsettings.voltage[channel].offsetReal) * | |
| 523 | - specification.gainSteps[controlsettings.voltage[channel].gain]; | |
| 525 | + } else if (device->getUniqueModelID() == MODEL_DSO6022BE) { | |
| 526 | + // if device is 6022BE, drop heading & trailing samples | |
| 527 | + const unsigned DROP_DSO6022_HEAD = 0x410; | |
| 528 | + const unsigned DROP_DSO6022_TAIL = 0x3F0; | |
| 529 | + if (!isRollMode()) { | |
| 530 | + result.data[channel].resize(result.data[channel].size() - (DROP_DSO6022_HEAD + DROP_DSO6022_TAIL)); | |
| 531 | + // if device is 6022BE, offset DROP_DSO6022_HEAD incrementally | |
| 532 | + bufferPosition += DROP_DSO6022_HEAD * 2; | |
| 524 | 533 | } |
| 525 | - } | |
| 526 | - } | |
| 527 | - } else { | |
| 528 | - QWriteLocker locker(&result.lock); | |
| 529 | - result.samplerate = controlsettings.samplerate.current; | |
| 530 | - result.append = isRollMode(); | |
| 531 | - | |
| 532 | - // Normal mode, channels are using their separate buffers | |
| 533 | - sampleCount = totalSampleCount / HANTEK_CHANNELS; | |
| 534 | - // if device is 6022BE, drop heading & trailing samples | |
| 535 | - if (device->getUniqueModelID() == MODEL_DSO6022BE) sampleCount -= (DROP_DSO6022_HEAD + DROP_DSO6022_TAIL); | |
| 536 | - for (int channel = 0; channel < HANTEK_CHANNELS; ++channel) { | |
| 537 | - if (controlsettings.voltage[channel].used) { | |
| 538 | - // Resize sample vector | |
| 539 | - if (result.data[channel].size() < sampleCount) { result.data[channel].resize(sampleCount); } | |
| 540 | - | |
| 541 | - // Convert data from the oscilloscope and write it into the sample | |
| 542 | - // buffer | |
| 543 | - unsigned bufferPosition = controlsettings.trigger.point * 2; | |
| 544 | - if (specification.sampleSize > 8) { | |
| 545 | - // Additional most significant bits after the normal data | |
| 546 | - unsigned extraBitsSize = specification.sampleSize - 8; // Number of extra bits | |
| 547 | - unsigned short int extraBitsMask = | |
| 548 | - (0x00ff << extraBitsSize) & 0xff00; // Mask for extra bits extraction | |
| 549 | - unsigned extraBitsIndex = 8 - channel * 2; // Bit position offset for extra bits extraction | |
| 550 | - | |
| 551 | - for (unsigned realPosition = 0; realPosition < sampleCount; | |
| 552 | - ++realPosition, bufferPosition += HANTEK_CHANNELS) { | |
| 553 | - if (bufferPosition >= totalSampleCount) bufferPosition %= totalSampleCount; | |
| 554 | - | |
| 555 | - result.data[channel][realPosition] = | |
| 556 | - ((double)((unsigned short int)data[bufferPosition + HANTEK_CHANNELS - 1 - channel] + | |
| 557 | - (((unsigned short int)data[totalSampleCount + bufferPosition] << extraBitsIndex) & | |
| 558 | - extraBitsMask)) / | |
| 559 | - specification.voltageLimit[channel][controlsettings.voltage[channel].gain] - | |
| 560 | - controlsettings.voltage[channel].offsetReal) * | |
| 561 | - specification.gainSteps[controlsettings.voltage[channel].gain]; | |
| 562 | - } | |
| 563 | - } else { | |
| 564 | - if (device->getUniqueModelID() == MODEL_DSO6022BE) { | |
| 565 | - bufferPosition += channel; | |
| 566 | - // if device is 6022BE, offset DROP_DSO6022_HEAD incrementally | |
| 567 | - bufferPosition += DROP_DSO6022_HEAD * 2; | |
| 568 | - } else | |
| 569 | - bufferPosition += HANTEK_CHANNELS - 1 - channel; | |
| 570 | - | |
| 571 | - for (unsigned realPosition = 0; realPosition < sampleCount; | |
| 572 | - ++realPosition, bufferPosition += HANTEK_CHANNELS) { | |
| 573 | - if (bufferPosition >= totalSampleCount) bufferPosition %= totalSampleCount; | |
| 574 | - | |
| 575 | - if (device->getUniqueModelID() == MODEL_DSO6022BE) { | |
| 576 | - double dataBuf = (double)((int)(data[bufferPosition] - 0x83)); | |
| 577 | - result.data[channel][realPosition] = | |
| 578 | - (dataBuf / specification.voltageLimit[channel][controlsettings.voltage[channel].gain]) * | |
| 579 | - specification.gainSteps[controlsettings.voltage[channel].gain]; | |
| 580 | - } else { | |
| 581 | - double dataBuf = (double)((int)(data[bufferPosition])); | |
| 582 | - result.data[channel][realPosition] = | |
| 583 | - (dataBuf / specification.voltageLimit[channel][controlsettings.voltage[channel].gain] - | |
| 584 | - controlsettings.voltage[channel].offsetReal) * | |
| 585 | - specification.gainSteps[controlsettings.voltage[channel].gain]; | |
| 586 | - } | |
| 587 | - } | |
| 534 | + bufferPosition += channel; | |
| 535 | + for (unsigned pos = 0; pos < result.data[channel].size(); ++pos, bufferPosition += HANTEK_CHANNELS) { | |
| 536 | + if (bufferPosition >= totalSampleCount) bufferPosition %= totalSampleCount; | |
| 537 | + double dataBuf = (double)((int)(rawData[bufferPosition] - 0x83)); | |
| 538 | + result.data[channel][pos] = (dataBuf / limit) * gainStep; | |
| 588 | 539 | } |
| 589 | 540 | } else { |
| 590 | - // Clear unused channels | |
| 591 | - result.data[channel].clear(); | |
| 541 | + bufferPosition += HANTEK_CHANNELS - 1 - channel; | |
| 542 | + for (unsigned pos = 0; pos < result.data[channel].size(); ++pos, bufferPosition += HANTEK_CHANNELS) { | |
| 543 | + if (bufferPosition >= totalSampleCount) bufferPosition %= totalSampleCount; | |
| 544 | + double dataBuf = (double)((int)(rawData[bufferPosition])); | |
| 545 | + result.data[channel][pos] = (dataBuf / limit - offset) * gainStep; | |
| 546 | + } | |
| 592 | 547 | } |
| 593 | 548 | } |
| 594 | 549 | } |
| 595 | - | |
| 596 | - static unsigned id = 0; | |
| 597 | - ++id; | |
| 598 | - timestampDebug(QString("Received packet %1").arg(id)); | |
| 599 | - | |
| 600 | - emit samplesAvailable(); | |
| 601 | - | |
| 602 | - return errorCode; | |
| 603 | 550 | } |
| 604 | 551 | |
| 605 | -/// \brief Calculated the nearest samplerate supported by the oscilloscope. | |
| 606 | -/// \param samplerate The target samplerate, that should be met as good as | |
| 607 | -/// possible. | |
| 608 | -/// \param fastRate true, if the fast rate mode is enabled. | |
| 609 | -/// \param maximum The target samplerate is the maximum allowed when true, the | |
| 610 | -/// minimum otherwise. | |
| 611 | -/// \param downsampler Pointer to where the selected downsampling factor should | |
| 612 | -/// be written. | |
| 613 | -/// \return The nearest samplerate supported, 0.0 on error. | |
| 614 | -double HantekDsoControl::getBestSamplerate(double samplerate, bool fastRate, bool maximum, unsigned *downsampler) { | |
| 552 | +double HantekDsoControl::getBestSamplerate(double samplerate, bool fastRate, bool maximum, | |
| 553 | + unsigned *downsampler) const { | |
| 615 | 554 | // Abort if the input value is invalid |
| 616 | 555 | if (samplerate <= 0.0) return 0.0; |
| 617 | 556 | |
| 618 | 557 | double bestSamplerate = 0.0; |
| 619 | 558 | |
| 620 | 559 | // Get samplerate specifications for this mode and model |
| 621 | - ControlSamplerateLimits *limits; | |
| 560 | + const ControlSamplerateLimits *limits; | |
| 622 | 561 | if (fastRate) |
| 623 | 562 | limits = &(specification.samplerate.multi); |
| 624 | 563 | else |
| 625 | 564 | limits = &(specification.samplerate.single); |
| 626 | 565 | |
| 627 | 566 | // Get downsampling factor that would provide the requested rate |
| 628 | - double bestDownsampler = (double)limits->base / specification.bufferDividers[controlsettings.recordLengthId] / samplerate; | |
| 567 | + double bestDownsampler = | |
| 568 | + (double)limits->base / specification.bufferDividers[controlsettings.recordLengthId] / samplerate; | |
| 629 | 569 | // Base samplerate sufficient, or is the maximum better? |
| 630 | 570 | if (bestDownsampler < 1.0 && |
| 631 | 571 | (samplerate <= limits->max / specification.bufferDividers[controlsettings.recordLengthId] || !maximum)) { |
| ... | ... | @@ -694,30 +634,17 @@ double HantekDsoControl::getBestSamplerate(double samplerate, bool fastRate, boo |
| 694 | 634 | return bestSamplerate; |
| 695 | 635 | } |
| 696 | 636 | |
| 697 | -/// \brief Get the count of samples that are expected returned by the scope. | |
| 698 | -/// \param fastRate Is set to the state of the fast rate mode when provided. | |
| 699 | -/// \return The total number of samples the scope should return. | |
| 700 | -unsigned HantekDsoControl::getSampleCount(bool *fastRate) { | |
| 701 | - unsigned totalSampleCount = getRecordLength(); | |
| 702 | - bool fastRateEnabled = controlsettings.samplerate.limits == &specification.samplerate.multi; | |
| 703 | - | |
| 704 | - if (totalSampleCount == UINT_MAX) { | |
| 705 | - // Roll mode | |
| 706 | - const int packetSize = device->getPacketSize(); | |
| 707 | - if (packetSize < 0) | |
| 708 | - totalSampleCount = UINT_MAX; | |
| 709 | - else | |
| 710 | - totalSampleCount = packetSize; | |
| 637 | +unsigned HantekDsoControl::getSampleCount() const { | |
| 638 | + if (isRollMode()) { | |
| 639 | + return device->getPacketSize(); | |
| 711 | 640 | } else { |
| 712 | - if (!fastRateEnabled) totalSampleCount *= HANTEK_CHANNELS; | |
| 641 | + if (isFastRate()) | |
| 642 | + return getRecordLength(); | |
| 643 | + else | |
| 644 | + return getRecordLength() * HANTEK_CHANNELS; | |
| 713 | 645 | } |
| 714 | - if (fastRate) *fastRate = fastRateEnabled; | |
| 715 | - return totalSampleCount; | |
| 716 | 646 | } |
| 717 | 647 | |
| 718 | -/// \brief Sets the size of the sample buffer without updating dependencies. | |
| 719 | -/// \param index The record length index that should be set. | |
| 720 | -/// \return The record length that has been set, 0 on error. | |
| 721 | 648 | unsigned HantekDsoControl::updateRecordLength(unsigned index) { |
| 722 | 649 | if (index >= (unsigned)controlsettings.samplerate.limits->recordLengths.size()) return 0; |
| 723 | 650 | |
| ... | ... | @@ -754,7 +681,8 @@ unsigned HantekDsoControl::updateRecordLength(unsigned index) { |
| 754 | 681 | } |
| 755 | 682 | |
| 756 | 683 | // Check if the divider has changed and adapt samplerate limits accordingly |
| 757 | - bool bDividerChanged = specification.bufferDividers[index] != specification.bufferDividers[controlsettings.recordLengthId]; | |
| 684 | + bool bDividerChanged = | |
| 685 | + specification.bufferDividers[index] != specification.bufferDividers[controlsettings.recordLengthId]; | |
| 758 | 686 | |
| 759 | 687 | controlsettings.recordLengthId = index; |
| 760 | 688 | |
| ... | ... | @@ -768,11 +696,6 @@ unsigned HantekDsoControl::updateRecordLength(unsigned index) { |
| 768 | 696 | return controlsettings.samplerate.limits->recordLengths[index]; |
| 769 | 697 | } |
| 770 | 698 | |
| 771 | -/// \brief Sets the samplerate based on the parameters calculated by | |
| 772 | -/// Control::getBestSamplerate. | |
| 773 | -/// \param downsampler The downsampling factor. | |
| 774 | -/// \param fastRate true, if one channel uses all buffers. | |
| 775 | -/// \return The downsampling factor that has been set. | |
| 776 | 699 | unsigned HantekDsoControl::updateSamplerate(unsigned downsampler, bool fastRate) { |
| 777 | 700 | // Get samplerate limits |
| 778 | 701 | Hantek::ControlSamplerateLimits *limits = |
| ... | ... | @@ -872,8 +795,8 @@ unsigned HantekDsoControl::updateSamplerate(unsigned downsampler, bool fastRate) |
| 872 | 795 | |
| 873 | 796 | controlsettings.samplerate.downsampler = downsampler; |
| 874 | 797 | if (downsampler) |
| 875 | - controlsettings.samplerate.current = | |
| 876 | - controlsettings.samplerate.limits->base / specification.bufferDividers[controlsettings.recordLengthId] / downsampler; | |
| 798 | + controlsettings.samplerate.current = controlsettings.samplerate.limits->base / | |
| 799 | + specification.bufferDividers[controlsettings.recordLengthId] / downsampler; | |
| 877 | 800 | else |
| 878 | 801 | controlsettings.samplerate.current = |
| 879 | 802 | controlsettings.samplerate.limits->max / specification.bufferDividers[controlsettings.recordLengthId]; |
| ... | ... | @@ -894,7 +817,6 @@ unsigned HantekDsoControl::updateSamplerate(unsigned downsampler, bool fastRate) |
| 894 | 817 | return downsampler; |
| 895 | 818 | } |
| 896 | 819 | |
| 897 | -/// \brief Restore the samplerate/timebase targets after divider updates. | |
| 898 | 820 | void HantekDsoControl::restoreTargets() { |
| 899 | 821 | if (controlsettings.samplerate.target.samplerateSet) |
| 900 | 822 | this->setSamplerate(); |
| ... | ... | @@ -902,7 +824,6 @@ void HantekDsoControl::restoreTargets() { |
| 902 | 824 | this->setRecordTime(); |
| 903 | 825 | } |
| 904 | 826 | |
| 905 | -/// \brief Update the minimum and maximum supported samplerate. | |
| 906 | 827 | void HantekDsoControl::updateSamplerateLimits() { |
| 907 | 828 | // Works only if the minimum samplerate for normal mode is lower than for fast |
| 908 | 829 | // rate mode, which is the case for all models |
| ... | ... | @@ -917,24 +838,24 @@ void HantekDsoControl::updateSamplerateLimits() { |
| 917 | 838 | /// \brief Sets the size of the oscilloscopes sample buffer. |
| 918 | 839 | /// \param index The record length index that should be set. |
| 919 | 840 | /// \return The record length that has been set, 0 on error. |
| 920 | -unsigned HantekDsoControl::setRecordLength(unsigned index) { | |
| 921 | - if (!device->isConnected()) return 0; | |
| 841 | +Dso::ErrorCode HantekDsoControl::setRecordLength(unsigned index) { | |
| 842 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 922 | 843 | |
| 923 | - if (!this->updateRecordLength(index)) return 0; | |
| 844 | + if (!this->updateRecordLength(index)) return Dso::ErrorCode::ERROR_PARAMETER; | |
| 924 | 845 | |
| 925 | 846 | this->restoreTargets(); |
| 926 | 847 | this->setPretriggerPosition(controlsettings.trigger.position); |
| 927 | 848 | |
| 928 | 849 | emit recordLengthChanged(getRecordLength()); |
| 929 | - return getRecordLength(); | |
| 850 | + return Dso::ErrorCode::ERROR_NONE; | |
| 930 | 851 | } |
| 931 | 852 | |
| 932 | 853 | /// \brief Sets the samplerate of the oscilloscope. |
| 933 | 854 | /// \param samplerate The samplerate that should be met (S/s), 0.0 to restore |
| 934 | 855 | /// current samplerate. |
| 935 | 856 | /// \return The samplerate that has been set, 0.0 on error. |
| 936 | -double HantekDsoControl::setSamplerate(double samplerate) { | |
| 937 | - if (!device->isConnected()) return 0.0; | |
| 857 | +Dso::ErrorCode HantekDsoControl::setSamplerate(double samplerate) { | |
| 858 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 938 | 859 | |
| 939 | 860 | if (samplerate == 0.0) { |
| 940 | 861 | samplerate = controlsettings.samplerate.target.samplerate; |
| ... | ... | @@ -946,19 +867,19 @@ double HantekDsoControl::setSamplerate(double samplerate) { |
| 946 | 867 | if (!specification.isSoftwareTriggerDevice) { |
| 947 | 868 | // When possible, enable fast rate if it is required to reach the requested |
| 948 | 869 | // samplerate |
| 949 | - bool fastRate = | |
| 950 | - (controlsettings.usedChannels <= 1) && | |
| 951 | - (samplerate > specification.samplerate.single.max / specification.bufferDividers[controlsettings.recordLengthId]); | |
| 870 | + bool fastRate = (controlsettings.usedChannels <= 1) && | |
| 871 | + (samplerate > specification.samplerate.single.max / | |
| 872 | + specification.bufferDividers[controlsettings.recordLengthId]); | |
| 952 | 873 | |
| 953 | 874 | // What is the nearest, at least as high samplerate the scope can provide? |
| 954 | 875 | unsigned downsampler = 0; |
| 955 | - double bestSamplerate = getBestSamplerate(samplerate, fastRate, false, &(downsampler)); | |
| 876 | + getBestSamplerate(samplerate, fastRate, false, &(downsampler)); | |
| 956 | 877 | |
| 957 | 878 | // Set the calculated samplerate |
| 958 | 879 | if (this->updateSamplerate(downsampler, fastRate) == UINT_MAX) |
| 959 | - return 0.0; | |
| 880 | + return Dso::ErrorCode::ERROR_PARAMETER; | |
| 960 | 881 | else { |
| 961 | - return bestSamplerate; | |
| 882 | + return Dso::ErrorCode::ERROR_NONE; | |
| 962 | 883 | } |
| 963 | 884 | } else { |
| 964 | 885 | int sampleId; |
| ... | ... | @@ -977,7 +898,7 @@ double HantekDsoControl::setSamplerate(double samplerate) { |
| 977 | 898 | emit recordTimeChanged((double)(getRecordLength() - sampleMargin) / controlsettings.samplerate.current); |
| 978 | 899 | emit samplerateChanged(controlsettings.samplerate.current); |
| 979 | 900 | |
| 980 | - return samplerate; | |
| 901 | + return Dso::ErrorCode::ERROR_NONE; | |
| 981 | 902 | } |
| 982 | 903 | } |
| 983 | 904 | |
| ... | ... | @@ -985,8 +906,8 @@ double HantekDsoControl::setSamplerate(double samplerate) { |
| 985 | 906 | /// \param duration The record time duration that should be met (s), 0.0 to |
| 986 | 907 | /// restore current record time. |
| 987 | 908 | /// \return The record time duration that has been set, 0.0 on error. |
| 988 | -double HantekDsoControl::setRecordTime(double duration) { | |
| 989 | - if (!device->isConnected()) return 0.0; | |
| 909 | +Dso::ErrorCode HantekDsoControl::setRecordTime(double duration) { | |
| 910 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 990 | 911 | |
| 991 | 912 | if (duration == 0.0) { |
| 992 | 913 | duration = controlsettings.samplerate.target.duration; |
| ... | ... | @@ -1004,18 +925,17 @@ double HantekDsoControl::setRecordTime(double duration) { |
| 1004 | 925 | // When possible, enable fast rate if the record time can't be set that low |
| 1005 | 926 | // to improve resolution |
| 1006 | 927 | bool fastRate = (controlsettings.usedChannels <= 1) && |
| 1007 | - (maxSamplerate >= | |
| 1008 | - specification.samplerate.multi.base / specification.bufferDividers[controlsettings.recordLengthId]); | |
| 928 | + (maxSamplerate >= specification.samplerate.multi.base / | |
| 929 | + specification.bufferDividers[controlsettings.recordLengthId]); | |
| 1009 | 930 | |
| 1010 | 931 | // What is the nearest, at most as high samplerate the scope can provide? |
| 1011 | 932 | unsigned downsampler = 0; |
| 1012 | - double bestSamplerate = getBestSamplerate(maxSamplerate, fastRate, true, &(downsampler)); | |
| 1013 | 933 | |
| 1014 | 934 | // Set the calculated samplerate |
| 1015 | 935 | if (this->updateSamplerate(downsampler, fastRate) == UINT_MAX) |
| 1016 | - return 0.0; | |
| 936 | + return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1017 | 937 | else { |
| 1018 | - return (double)getRecordLength() / bestSamplerate; | |
| 938 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1019 | 939 | } |
| 1020 | 940 | } else { |
| 1021 | 941 | // For now - we go for the 10240 size sampling - the other seems not to be |
| ... | ... | @@ -1039,7 +959,7 @@ double HantekDsoControl::setRecordTime(double duration) { |
| 1039 | 959 | controlsettings.samplerate.current = specification.sampleSteps[sampleId]; |
| 1040 | 960 | |
| 1041 | 961 | emit samplerateChanged(controlsettings.samplerate.current); |
| 1042 | - return controlsettings.samplerate.current; | |
| 962 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1043 | 963 | } |
| 1044 | 964 | } |
| 1045 | 965 | |
| ... | ... | @@ -1047,10 +967,10 @@ double HantekDsoControl::setRecordTime(double duration) { |
| 1047 | 967 | /// \param channel The channel that should be set. |
| 1048 | 968 | /// \param used true if the channel should be sampled. |
| 1049 | 969 | /// \return See ::Dso::ErrorCode. |
| 1050 | -int HantekDsoControl::setChannelUsed(unsigned channel, bool used) { | |
| 1051 | - if (!device->isConnected()) return Dso::ERROR_CONNECTION; | |
| 970 | +Dso::ErrorCode HantekDsoControl::setChannelUsed(unsigned channel, bool used) { | |
| 971 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 1052 | 972 | |
| 1053 | - if (channel >= HANTEK_CHANNELS) return Dso::ERROR_PARAMETER; | |
| 973 | + if (channel >= HANTEK_CHANNELS) return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1054 | 974 | |
| 1055 | 975 | // Update settings |
| 1056 | 976 | controlsettings.voltage[channel].used = used; |
| ... | ... | @@ -1105,17 +1025,17 @@ int HantekDsoControl::setChannelUsed(unsigned channel, bool used) { |
| 1105 | 1025 | |
| 1106 | 1026 | if (fastRateChanged) this->updateSamplerateLimits(); |
| 1107 | 1027 | |
| 1108 | - return Dso::ERROR_NONE; | |
| 1028 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1109 | 1029 | } |
| 1110 | 1030 | |
| 1111 | 1031 | /// \brief Set the coupling for the given channel. |
| 1112 | 1032 | /// \param channel The channel that should be set. |
| 1113 | 1033 | /// \param coupling The new coupling for the channel. |
| 1114 | 1034 | /// \return See ::Dso::ErrorCode. |
| 1115 | -int HantekDsoControl::setCoupling(unsigned channel, Dso::Coupling coupling) { | |
| 1116 | - if (!device->isConnected()) return Dso::ERROR_CONNECTION; | |
| 1035 | +Dso::ErrorCode HantekDsoControl::setCoupling(unsigned channel, Dso::Coupling coupling) { | |
| 1036 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 1117 | 1037 | |
| 1118 | - if (channel >= HANTEK_CHANNELS) return Dso::ERROR_PARAMETER; | |
| 1038 | + if (channel >= HANTEK_CHANNELS) return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1119 | 1039 | |
| 1120 | 1040 | // SetRelays control command for coupling relays |
| 1121 | 1041 | if (specification.supportsCouplingRelays) { |
| ... | ... | @@ -1124,17 +1044,18 @@ int HantekDsoControl::setCoupling(unsigned channel, Dso::Coupling coupling) { |
| 1124 | 1044 | this->controlPending[CONTROLINDEX_SETRELAYS] = true; |
| 1125 | 1045 | } |
| 1126 | 1046 | |
| 1127 | - return Dso::ERROR_NONE; | |
| 1047 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1128 | 1048 | } |
| 1129 | 1049 | |
| 1130 | 1050 | /// \brief Sets the gain for the given channel. |
| 1051 | +/// Get the actual gain by specification.gainSteps[gainId] | |
| 1131 | 1052 | /// \param channel The channel that should be set. |
| 1132 | 1053 | /// \param gain The gain that should be met (V/div). |
| 1133 | 1054 | /// \return The gain that has been set, ::Dso::ErrorCode on error. |
| 1134 | -double HantekDsoControl::setGain(unsigned channel, double gain) { | |
| 1135 | - if (!device->isConnected()) return Dso::ERROR_CONNECTION; | |
| 1055 | +Dso::ErrorCode HantekDsoControl::setGain(unsigned channel, double gain) { | |
| 1056 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 1136 | 1057 | |
| 1137 | - if (channel >= HANTEK_CHANNELS) return Dso::ERROR_PARAMETER; | |
| 1058 | + if (channel >= HANTEK_CHANNELS) return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1138 | 1059 | |
| 1139 | 1060 | // Find lowest gain voltage thats at least as high as the requested |
| 1140 | 1061 | int gainId; |
| ... | ... | @@ -1168,30 +1089,25 @@ double HantekDsoControl::setGain(unsigned channel, double gain) { |
| 1168 | 1089 | |
| 1169 | 1090 | this->setOffset(channel, controlsettings.voltage[channel].offset); |
| 1170 | 1091 | |
| 1171 | - return specification.gainSteps[gainId]; | |
| 1092 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1172 | 1093 | } |
| 1173 | 1094 | |
| 1174 | 1095 | /// \brief Set the offset for the given channel. |
| 1096 | +/// Get the actual offset for the channel from controlsettings.voltage[channel].offsetReal | |
| 1175 | 1097 | /// \param channel The channel that should be set. |
| 1176 | 1098 | /// \param offset The new offset value (0.0 - 1.0). |
| 1177 | -/// \return The offset that has been set, ::Dso::ErrorCode on error. | |
| 1178 | -double HantekDsoControl::setOffset(unsigned channel, double offset) { | |
| 1179 | - if (!device->isConnected()) return Dso::ERROR_CONNECTION; | |
| 1099 | +Dso::ErrorCode HantekDsoControl::setOffset(unsigned channel, double offset) { | |
| 1100 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 1180 | 1101 | |
| 1181 | - if (channel >= HANTEK_CHANNELS) return Dso::ERROR_PARAMETER; | |
| 1102 | + if (channel >= HANTEK_CHANNELS) return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1182 | 1103 | |
| 1104 | + unsigned short *channelOffLimit = specification.offsetLimit[channel][controlsettings.voltage[channel].gain]; | |
| 1183 | 1105 | // Calculate the offset value |
| 1184 | 1106 | // The range is given by the calibration data (convert from big endian) |
| 1185 | - unsigned short int minimum = | |
| 1186 | - ((unsigned short int)*( | |
| 1187 | - (unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_START])) | |
| 1188 | - << 8) + | |
| 1189 | - *((unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_START]) + 1); | |
| 1190 | - unsigned short int maximum = | |
| 1191 | - ((unsigned short int)*( | |
| 1192 | - (unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_END])) | |
| 1193 | - << 8) + | |
| 1194 | - *((unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_END]) + 1); | |
| 1107 | + unsigned short int minimum = ((unsigned short int)*((unsigned char *)&(channelOffLimit[OFFSET_START])) << 8) + | |
| 1108 | + *((unsigned char *)&(channelOffLimit[OFFSET_START]) + 1); | |
| 1109 | + unsigned short int maximum = ((unsigned short int)*((unsigned char *)&(channelOffLimit[OFFSET_END])) << 8) + | |
| 1110 | + *((unsigned char *)&(channelOffLimit[OFFSET_END]) + 1); | |
| 1195 | 1111 | unsigned short int offsetValue = offset * (maximum - minimum) + minimum + 0.5; |
| 1196 | 1112 | double offsetReal = (double)(offsetValue - minimum) / (maximum - minimum); |
| 1197 | 1113 | |
| ... | ... | @@ -1205,28 +1121,29 @@ double HantekDsoControl::setOffset(unsigned channel, double offset) { |
| 1205 | 1121 | |
| 1206 | 1122 | this->setTriggerLevel(channel, controlsettings.trigger.level[channel]); |
| 1207 | 1123 | |
| 1208 | - return offsetReal; | |
| 1124 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1209 | 1125 | } |
| 1210 | 1126 | |
| 1211 | 1127 | /// \brief Set the trigger mode. |
| 1212 | 1128 | /// \return See ::Dso::ErrorCode. |
| 1213 | -int HantekDsoControl::setTriggerMode(Dso::TriggerMode mode) { | |
| 1214 | - if (!device->isConnected()) return Dso::ERROR_CONNECTION; | |
| 1129 | +Dso::ErrorCode HantekDsoControl::setTriggerMode(Dso::TriggerMode mode) { | |
| 1130 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 1215 | 1131 | |
| 1216 | - if (mode < Dso::TRIGGERMODE_AUTO || mode >= Dso::TRIGGERMODE_COUNT) return Dso::ERROR_PARAMETER; | |
| 1132 | + if (mode < Dso::TRIGGERMODE_AUTO || mode >= Dso::TRIGGERMODE_COUNT) return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1217 | 1133 | |
| 1218 | 1134 | controlsettings.trigger.mode = mode; |
| 1219 | - return Dso::ERROR_NONE; | |
| 1135 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1220 | 1136 | } |
| 1221 | 1137 | |
| 1222 | 1138 | /// \brief Set the trigger source. |
| 1223 | 1139 | /// \param special true for a special channel (EXT, ...) as trigger source. |
| 1224 | 1140 | /// \param id The number of the channel, that should be used as trigger. |
| 1225 | 1141 | /// \return See ::Dso::ErrorCode. |
| 1226 | -int HantekDsoControl::setTriggerSource(bool special, unsigned id) { | |
| 1227 | - if (!device->isConnected()) return Dso::ERROR_CONNECTION; | |
| 1142 | +Dso::ErrorCode HantekDsoControl::setTriggerSource(bool special, unsigned id) { | |
| 1143 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 1228 | 1144 | |
| 1229 | - if ((!special && id >= HANTEK_CHANNELS) || (special && id >= HANTEK_SPECIAL_CHANNELS)) return Dso::ERROR_PARAMETER; | |
| 1145 | + if ((!special && id >= HANTEK_CHANNELS) || (special && id >= HANTEK_SPECIAL_CHANNELS)) | |
| 1146 | + return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1230 | 1147 | |
| 1231 | 1148 | switch (specification.command.bulk.setTrigger) { |
| 1232 | 1149 | case BULK_SETTRIGGERANDSAMPLERATE: |
| ... | ... | @@ -1251,7 +1168,7 @@ int HantekDsoControl::setTriggerSource(bool special, unsigned id) { |
| 1251 | 1168 | break; |
| 1252 | 1169 | |
| 1253 | 1170 | default: |
| 1254 | - return Dso::ERROR_UNSUPPORTED; | |
| 1171 | + return Dso::ErrorCode::ERROR_UNSUPPORTED; | |
| 1255 | 1172 | } |
| 1256 | 1173 | |
| 1257 | 1174 | // SetRelays control command for external trigger relay |
| ... | ... | @@ -1269,32 +1186,27 @@ int HantekDsoControl::setTriggerSource(bool special, unsigned id) { |
| 1269 | 1186 | } else |
| 1270 | 1187 | this->setTriggerLevel(id, controlsettings.trigger.level[id]); |
| 1271 | 1188 | |
| 1272 | - return Dso::ERROR_NONE; | |
| 1189 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1273 | 1190 | } |
| 1274 | 1191 | |
| 1275 | 1192 | /// \brief Set the trigger level. |
| 1276 | 1193 | /// \param channel The channel that should be set. |
| 1277 | 1194 | /// \param level The new trigger level (V). |
| 1278 | 1195 | /// \return The trigger level that has been set, ::Dso::ErrorCode on error. |
| 1279 | -double HantekDsoControl::setTriggerLevel(unsigned channel, double level) { | |
| 1280 | - if (!device->isConnected()) return Dso::ERROR_CONNECTION; | |
| 1196 | +Dso::ErrorCode HantekDsoControl::setTriggerLevel(unsigned channel, double level) { | |
| 1197 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 1281 | 1198 | |
| 1282 | - if (channel >= HANTEK_CHANNELS) return Dso::ERROR_PARAMETER; | |
| 1199 | + if (channel >= HANTEK_CHANNELS) return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1283 | 1200 | |
| 1284 | 1201 | // Calculate the trigger level value |
| 1285 | - unsigned short int minimum, maximum; | |
| 1286 | - if (specification.sampleSize>8) { | |
| 1202 | + unsigned short minimum, maximum; | |
| 1203 | + if (specification.sampleSize > 8) { | |
| 1204 | + const unsigned short *offsetLimit = specification.offsetLimit[channel][controlsettings.voltage[channel].gain]; | |
| 1287 | 1205 | // The range is the same as used for the offsets for 10 bit models |
| 1288 | - minimum = | |
| 1289 | - ((unsigned short int)*( | |
| 1290 | - (unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_START])) | |
| 1291 | - << 8) + | |
| 1292 | - *((unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_START]) + 1); | |
| 1293 | - maximum = | |
| 1294 | - ((unsigned short int)*( | |
| 1295 | - (unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_END])) | |
| 1296 | - << 8) + | |
| 1297 | - *((unsigned char *)&(specification.offsetLimit[channel][controlsettings.voltage[channel].gain][OFFSET_END]) + 1); | |
| 1206 | + minimum = ((unsigned short int)*((unsigned char *)&(offsetLimit[OFFSET_START])) << 8) + | |
| 1207 | + *((unsigned char *)&(offsetLimit[OFFSET_START]) + 1); | |
| 1208 | + maximum = ((unsigned short int)*((unsigned char *)&(offsetLimit[OFFSET_END])) << 8) + | |
| 1209 | + *((unsigned char *)&(offsetLimit[OFFSET_END]) + 1); | |
| 1298 | 1210 | } else { |
| 1299 | 1211 | // It's from 0x00 to 0xfd for the 8 bit models |
| 1300 | 1212 | minimum = 0x00; |
| ... | ... | @@ -1302,14 +1214,10 @@ double HantekDsoControl::setTriggerLevel(unsigned channel, double level) { |
| 1302 | 1214 | } |
| 1303 | 1215 | |
| 1304 | 1216 | // Never get out of the limits |
| 1305 | - unsigned short int levelValue = | |
| 1306 | - qBound((long int)minimum, | |
| 1307 | - (long int)((controlsettings.voltage[channel].offsetReal + | |
| 1308 | - level / specification.gainSteps[controlsettings.voltage[channel].gain]) * | |
| 1309 | - (maximum - minimum) + | |
| 1310 | - 0.5) + | |
| 1311 | - minimum, | |
| 1312 | - (long int)maximum); | |
| 1217 | + const double offsetReal = controlsettings.voltage[channel].offsetReal; | |
| 1218 | + const double gainStep = specification.gainSteps[controlsettings.voltage[channel].gain]; | |
| 1219 | + unsigned short levelValue = qBound( | |
| 1220 | + minimum, (unsigned short)(((offsetReal + level / gainStep) * (maximum - minimum) + 0.5) + minimum), maximum); | |
| 1313 | 1221 | |
| 1314 | 1222 | // Check if the set channel is the trigger source |
| 1315 | 1223 | if (!controlsettings.trigger.special && channel == controlsettings.trigger.source && specification.supportsOffset) { |
| ... | ... | @@ -1321,17 +1229,16 @@ double HantekDsoControl::setTriggerLevel(unsigned channel, double level) { |
| 1321 | 1229 | /// \todo Get alternating trigger in here |
| 1322 | 1230 | |
| 1323 | 1231 | controlsettings.trigger.level[channel] = level; |
| 1324 | - return (double)((levelValue - minimum) / (maximum - minimum) - controlsettings.voltage[channel].offsetReal) * | |
| 1325 | - specification.gainSteps[controlsettings.voltage[channel].gain]; | |
| 1232 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1326 | 1233 | } |
| 1327 | 1234 | |
| 1328 | 1235 | /// \brief Set the trigger slope. |
| 1329 | 1236 | /// \param slope The Slope that should cause a trigger. |
| 1330 | 1237 | /// \return See ::Dso::ErrorCode. |
| 1331 | -int HantekDsoControl::setTriggerSlope(Dso::Slope slope) { | |
| 1332 | - if (!device->isConnected()) return Dso::ERROR_CONNECTION; | |
| 1238 | +Dso::ErrorCode HantekDsoControl::setTriggerSlope(Dso::Slope slope) { | |
| 1239 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 1333 | 1240 | |
| 1334 | - if (slope >= Dso::SLOPE_COUNT) return Dso::ERROR_PARAMETER; | |
| 1241 | + if (slope >= Dso::SLOPE_COUNT) return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1335 | 1242 | |
| 1336 | 1243 | switch (specification.command.bulk.setTrigger) { |
| 1337 | 1244 | case BULK_SETTRIGGERANDSAMPLERATE: { |
| ... | ... | @@ -1353,23 +1260,20 @@ int HantekDsoControl::setTriggerSlope(Dso::Slope slope) { |
| 1353 | 1260 | break; |
| 1354 | 1261 | } |
| 1355 | 1262 | default: |
| 1356 | - return Dso::ERROR_UNSUPPORTED; | |
| 1263 | + return Dso::ErrorCode::ERROR_UNSUPPORTED; | |
| 1357 | 1264 | } |
| 1358 | 1265 | |
| 1359 | 1266 | controlsettings.trigger.slope = slope; |
| 1360 | - return Dso::ERROR_NONE; | |
| 1267 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1361 | 1268 | } |
| 1362 | 1269 | |
| 1363 | -int HantekDsoControl::forceTrigger() { | |
| 1364 | - commandPending[BULK_FORCETRIGGER] = true; | |
| 1365 | - return 0; | |
| 1366 | -} | |
| 1270 | +void HantekDsoControl::forceTrigger() { commandPending[BULK_FORCETRIGGER] = true; } | |
| 1367 | 1271 | |
| 1368 | 1272 | /// \brief Set the trigger position. |
| 1369 | 1273 | /// \param position The new trigger position (in s). |
| 1370 | 1274 | /// \return The trigger position that has been set. |
| 1371 | -double HantekDsoControl::setPretriggerPosition(double position) { | |
| 1372 | - if (!device->isConnected()) return -2; | |
| 1275 | +Dso::ErrorCode HantekDsoControl::setPretriggerPosition(double position) { | |
| 1276 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 1373 | 1277 | |
| 1374 | 1278 | // All trigger positions are measured in samples |
| 1375 | 1279 | unsigned positionSamples = position * controlsettings.samplerate.current; |
| ... | ... | @@ -1415,23 +1319,23 @@ double HantekDsoControl::setPretriggerPosition(double position) { |
| 1415 | 1319 | break; |
| 1416 | 1320 | } |
| 1417 | 1321 | default: |
| 1418 | - return Dso::ERROR_UNSUPPORTED; | |
| 1322 | + return Dso::ErrorCode::ERROR_UNSUPPORTED; | |
| 1419 | 1323 | } |
| 1420 | 1324 | |
| 1421 | 1325 | controlsettings.trigger.position = position; |
| 1422 | - return (double)positionSamples / controlsettings.samplerate.current; | |
| 1326 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1423 | 1327 | } |
| 1424 | 1328 | |
| 1425 | -int HantekDsoControl::stringCommand(const QString &commandString) { | |
| 1426 | - if (!device->isConnected()) return Dso::ERROR_CONNECTION; | |
| 1329 | +Dso::ErrorCode HantekDsoControl::stringCommand(const QString &commandString) { | |
| 1330 | + if (!device->isConnected()) return Dso::ErrorCode::ERROR_CONNECTION; | |
| 1427 | 1331 | |
| 1428 | 1332 | QStringList commandParts = commandString.split(' ', QString::SkipEmptyParts); |
| 1429 | 1333 | |
| 1430 | - if (commandParts.count() < 1) return Dso::ERROR_PARAMETER; | |
| 1334 | + if (commandParts.count() < 1) return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1431 | 1335 | |
| 1432 | - if (commandParts[0] != "send") return Dso::ERROR_UNSUPPORTED; | |
| 1336 | + if (commandParts[0] != "send") return Dso::ErrorCode::ERROR_UNSUPPORTED; | |
| 1433 | 1337 | |
| 1434 | - if (commandParts.count() < 2) return Dso::ERROR_PARAMETER; | |
| 1338 | + if (commandParts.count() < 2) return Dso::ErrorCode::ERROR_PARAMETER; | |
| 1435 | 1339 | |
| 1436 | 1340 | if (commandParts[1] == "bulk") { |
| 1437 | 1341 | QString data = commandString.section(' ', 2, -1, QString::SectionSkipEmpty); |
| ... | ... | @@ -1439,12 +1343,12 @@ int HantekDsoControl::stringCommand(const QString &commandString) { |
| 1439 | 1343 | |
| 1440 | 1344 | // Read command code (First byte) |
| 1441 | 1345 | hexParse(commandParts[2], &commandCode, 1); |
| 1442 | - if (commandCode > BULK_COUNT) return Dso::ERROR_UNSUPPORTED; | |
| 1346 | + if (commandCode > BULK_COUNT) return Dso::ErrorCode::ERROR_UNSUPPORTED; | |
| 1443 | 1347 | |
| 1444 | 1348 | // Update bulk command and mark as pending |
| 1445 | 1349 | hexParse(data, command[commandCode]->data(), command[commandCode]->getSize()); |
| 1446 | 1350 | commandPending[commandCode] = true; |
| 1447 | - return Dso::ERROR_NONE; | |
| 1351 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1448 | 1352 | } else if (commandParts[1] == "control") { |
| 1449 | 1353 | unsigned char controlCode = 0; |
| 1450 | 1354 | |
| ... | ... | @@ -1454,16 +1358,16 @@ int HantekDsoControl::stringCommand(const QString &commandString) { |
| 1454 | 1358 | for (cIndex = 0; cIndex < CONTROLINDEX_COUNT; ++cIndex) { |
| 1455 | 1359 | if (this->controlCode[cIndex] == controlCode) break; |
| 1456 | 1360 | } |
| 1457 | - if (cIndex >= CONTROLINDEX_COUNT) return Dso::ERROR_UNSUPPORTED; | |
| 1361 | + if (cIndex >= CONTROLINDEX_COUNT) return Dso::ErrorCode::ERROR_UNSUPPORTED; | |
| 1458 | 1362 | |
| 1459 | 1363 | QString data = commandString.section(' ', 3, -1, QString::SectionSkipEmpty); |
| 1460 | 1364 | |
| 1461 | 1365 | // Update control command and mark as pending |
| 1462 | 1366 | hexParse(data, this->control[cIndex]->data(), this->control[cIndex]->getSize()); |
| 1463 | 1367 | this->controlPending[cIndex] = true; |
| 1464 | - return Dso::ERROR_NONE; | |
| 1368 | + return Dso::ErrorCode::ERROR_NONE; | |
| 1465 | 1369 | } else |
| 1466 | - return Dso::ERROR_UNSUPPORTED; | |
| 1370 | + return Dso::ErrorCode::ERROR_UNSUPPORTED; | |
| 1467 | 1371 | } |
| 1468 | 1372 | |
| 1469 | 1373 | void HantekDsoControl::run() { |
| ... | ... | @@ -1479,11 +1383,8 @@ void HantekDsoControl::run() { |
| 1479 | 1383 | errorCode = device->bulkCommand(command[cIndex]); |
| 1480 | 1384 | if (errorCode < 0) { |
| 1481 | 1385 | qWarning("Sending bulk command %02x failed: %s", cIndex, libUsbErrorString(errorCode).toLocal8Bit().data()); |
| 1482 | - | |
| 1483 | - if (errorCode == LIBUSB_ERROR_NO_DEVICE) { | |
| 1484 | - emit communicationError(); | |
| 1485 | - return; | |
| 1486 | - } | |
| 1386 | + emit communicationError(); | |
| 1387 | + return; | |
| 1487 | 1388 | } else |
| 1488 | 1389 | commandPending[cIndex] = false; |
| 1489 | 1390 | } |
| ... | ... | @@ -1570,13 +1471,13 @@ void HantekDsoControl::run() { |
| 1570 | 1471 | |
| 1571 | 1472 | break; |
| 1572 | 1473 | |
| 1573 | - case ROLL_GETDATA: | |
| 1574 | - // Get data and process it, if we're still sampling | |
| 1575 | - errorCode = this->getSamples(this->_samplingStarted); | |
| 1576 | - if (errorCode < 0) | |
| 1577 | - qWarning("Getting sample data failed: %s", libUsbErrorString(errorCode).toLocal8Bit().data()); | |
| 1578 | - else | |
| 1579 | - timestampDebug(QString("Received %1 B of sampling data").arg(errorCode)); | |
| 1474 | + case ROLL_GETDATA: { | |
| 1475 | + std::vector<unsigned char> rawData = this->getSamples(previousSampleCount); | |
| 1476 | + if (this->_samplingStarted) { | |
| 1477 | + convertRawDataToSamples(rawData); | |
| 1478 | + emit samplesAvailable(); | |
| 1479 | + } | |
| 1480 | + } | |
| 1580 | 1481 | |
| 1581 | 1482 | // Check if we're in single trigger mode |
| 1582 | 1483 | if (controlsettings.trigger.mode == Dso::TRIGGERMODE_SINGLE && this->_samplingStarted) this->stopSampling(); |
| ... | ... | @@ -1598,23 +1499,25 @@ void HantekDsoControl::run() { |
| 1598 | 1499 | this->rollState = ROLL_STARTSAMPLING; |
| 1599 | 1500 | |
| 1600 | 1501 | const int lastCaptureState = this->captureState; |
| 1601 | - this->captureState = this->getCaptureState(); | |
| 1602 | - if (this->captureState < 0) | |
| 1603 | - qWarning("Getting capture state failed: %s", libUsbErrorString(this->captureState).toLocal8Bit().data()); | |
| 1604 | - | |
| 1605 | - else if (this->captureState != lastCaptureState) | |
| 1502 | + unsigned triggerPoint; | |
| 1503 | + std::tie(captureState, triggerPoint) = this->getCaptureState(); | |
| 1504 | + controlsettings.trigger.point = calculateTriggerPoint(triggerPoint); | |
| 1505 | + if (this->captureState < 0) { | |
| 1506 | + qWarning() << tr("Getting capture state failed: %1").arg(libUsbErrorString(this->captureState)); | |
| 1507 | + emit statusMessage(tr("Getting capture state failed: %1").arg(libUsbErrorString(this->captureState)), 0); | |
| 1508 | + } else if (this->captureState != lastCaptureState) | |
| 1606 | 1509 | timestampDebug(QString("Capture state changed to %1").arg(this->captureState)); |
| 1607 | 1510 | |
| 1608 | 1511 | switch (this->captureState) { |
| 1609 | 1512 | case CAPTURE_READY: |
| 1610 | 1513 | case CAPTURE_READY2250: |
| 1611 | - case CAPTURE_READY5200: | |
| 1612 | - // Get data and process it, if we're still sampling | |
| 1613 | - errorCode = this->getSamples(this->_samplingStarted); | |
| 1614 | - if (errorCode < 0) | |
| 1615 | - qWarning("Getting sample data failed: %s", libUsbErrorString(errorCode).toLocal8Bit().data()); | |
| 1616 | - else | |
| 1617 | - timestampDebug(QString("Received %1 B of sampling data").arg(errorCode)); | |
| 1514 | + case CAPTURE_READY5200: { | |
| 1515 | + std::vector<unsigned char> rawData = this->getSamples(previousSampleCount); | |
| 1516 | + if (this->_samplingStarted) { | |
| 1517 | + convertRawDataToSamples(rawData); | |
| 1518 | + emit samplesAvailable(); | |
| 1519 | + } | |
| 1520 | + } | |
| 1618 | 1521 | |
| 1619 | 1522 | // Check if we're in single trigger mode |
| 1620 | 1523 | if (controlsettings.trigger.mode == Dso::TRIGGERMODE_SINGLE && this->_samplingStarted) this->stopSampling(); | ... | ... |
openhantek/src/hantek/hantekdsocontrol.h
| ... | ... | @@ -27,10 +27,13 @@ class HantekDsoControl : public QObject { |
| 27 | 27 | * Creates a dsoControl object. The actual event loop / timer is not started. |
| 28 | 28 | * You can optionally create a thread and move the created object to the |
| 29 | 29 | * thread. |
| 30 | - * You need to call updateInterval() to start the timer. | |
| 31 | - * @param device | |
| 30 | + * You need to call updateInterval() to start the timer. This is done implicitly | |
| 31 | + * if run() is called. | |
| 32 | + * @param device The usb device. This object does not take ownership. | |
| 32 | 33 | */ |
| 33 | 34 | HantekDsoControl(USBDevice *device); |
| 35 | + | |
| 36 | + /// \brief Cleans up | |
| 34 | 37 | ~HantekDsoControl(); |
| 35 | 38 | |
| 36 | 39 | /// Call this to start the processing. This method will call itself |
| ... | ... | @@ -39,13 +42,29 @@ class HantekDsoControl : public QObject { |
| 39 | 42 | /// there. |
| 40 | 43 | void run(); |
| 41 | 44 | |
| 45 | + /// \brief Gets the physical channel count for this oscilloscope. | |
| 46 | + /// \return The number of physical channels. | |
| 42 | 47 | unsigned getChannelCount(); |
| 43 | - QList<unsigned> *getAvailableRecordLengths(); | |
| 48 | + | |
| 49 | + /// \brief Get available record lengths for this oscilloscope. | |
| 50 | + /// \return The number of physical channels, empty list for continuous. | |
| 51 | + const std::vector<unsigned> &getAvailableRecordLengths(); | |
| 52 | + | |
| 53 | + /// \brief Get minimum samplerate for this oscilloscope. | |
| 54 | + /// \return The minimum samplerate for the current configuration in S/s. | |
| 44 | 55 | double getMinSamplerate(); |
| 56 | + | |
| 57 | + /// \brief Get maximum samplerate for this oscilloscope. | |
| 58 | + /// \return The maximum samplerate for the current configuration in S/s. | |
| 45 | 59 | double getMaxSamplerate(); |
| 46 | 60 | |
| 61 | + /// \brief Get a list of the names of the special trigger sources. | |
| 47 | 62 | const QStringList *getSpecialTriggerSources(); |
| 63 | + | |
| 64 | + /// Return the associated usb device. | |
| 48 | 65 | const USBDevice *getDevice() const; |
| 66 | + | |
| 67 | + /// Return the last sample set | |
| 49 | 68 | const DSOsamples &getLastSamples(); |
| 50 | 69 | |
| 51 | 70 | /// \brief Sends bulk/control commands directly. |
| ... | ... | @@ -59,63 +78,91 @@ class HantekDsoControl : public QObject { |
| 59 | 78 | /// </p> |
| 60 | 79 | /// \param command The command as string (Has to be parsed). |
| 61 | 80 | /// \return See ::Dso::ErrorCode. |
| 62 | - int stringCommand(const QString &commandString); | |
| 63 | - signals: | |
| 64 | - void samplingStarted(); ///< The oscilloscope started sampling/waiting for trigger | |
| 65 | - void samplingStopped(); ///< The oscilloscope stopped sampling/waiting for trigger | |
| 66 | - void statusMessage(const QString &message, int timeout); ///< Status message about the oscilloscope | |
| 67 | - void samplesAvailable(); ///< New sample data is available | |
| 81 | + Dso::ErrorCode stringCommand(const QString &commandString); | |
| 82 | + | |
| 83 | + private: | |
| 84 | + bool isRollMode() const; | |
| 85 | + bool isFastRate() const; | |
| 86 | + int getRecordLength() const; | |
| 87 | + | |
| 88 | + /// \brief Calculated the nearest samplerate supported by the oscilloscope. | |
| 89 | + /// \param samplerate The target samplerate, that should be met as good as | |
| 90 | + /// possible. | |
| 91 | + /// \param fastRate true, if the fast rate mode is enabled. | |
| 92 | + /// \param maximum The target samplerate is the maximum allowed when true, the | |
| 93 | + /// minimum otherwise. | |
| 94 | + /// \param downsampler Pointer to where the selected downsampling factor should | |
| 95 | + /// be written. | |
| 96 | + /// \return The nearest samplerate supported, 0.0 on error. | |
| 97 | + double getBestSamplerate(double samplerate, bool fastRate = false, bool maximum = false, | |
| 98 | + unsigned *downsampler = 0) const; | |
| 99 | + | |
| 100 | + /// Get the number of samples that are expected returned by the scope. | |
| 101 | + /// In rolling mode this is depends on the usb speed and packet size. | |
| 102 | + /// \return The total number of samples the scope should return. | |
| 103 | + unsigned getSampleCount() const; | |
| 68 | 104 | |
| 69 | - void availableRecordLengthsChanged(const QList<unsigned> &recordLengths); ///< The available record | |
| 70 | - /// lengths, empty list for | |
| 71 | - /// continuous | |
| 72 | - void samplerateLimitsChanged(double minimum, double maximum); ///< The minimum or maximum samplerate has changed | |
| 73 | - void recordLengthChanged(unsigned long duration); ///< The record length has changed | |
| 74 | - void recordTimeChanged(double duration); ///< The record time duration has changed | |
| 75 | - void samplerateChanged(double samplerate); ///< The samplerate has changed | |
| 76 | - void samplerateSet(int mode, QList<double> sampleSteps); ///< The samplerate has changed | |
| 105 | + void updateInterval(); | |
| 77 | 106 | |
| 78 | - void communicationError(); | |
| 107 | + /// \brief Calculates the trigger point from the CommandGetCaptureState data. | |
| 108 | + /// \param value The data value that contains the trigger point. | |
| 109 | + /// \return The calculated trigger point for the given data. | |
| 110 | + static unsigned calculateTriggerPoint(unsigned value); | |
| 79 | 111 | |
| 80 | - protected: | |
| 81 | - bool isRollMode(); | |
| 82 | - int getRecordLength(); | |
| 83 | - void updateInterval(); | |
| 84 | - unsigned calculateTriggerPoint(unsigned value); | |
| 85 | - int getCaptureState(); | |
| 86 | - int getSamples(bool process); | |
| 87 | - double getBestSamplerate(double samplerate, bool fastRate = false, bool maximum = false, unsigned *downsampler = 0); | |
| 88 | - unsigned getSampleCount(bool *fastRate = 0); | |
| 112 | + /// \brief Gets the current state. | |
| 113 | + /// \return The current CaptureState of the oscilloscope. | |
| 114 | + std::pair<int, unsigned> getCaptureState() const; | |
| 115 | + | |
| 116 | + /// \brief Gets sample data from the oscilloscope | |
| 117 | + std::vector<unsigned char> getSamples(unsigned &previousSampleCount) const; | |
| 118 | + | |
| 119 | + /// \brief Converts raw oscilloscope data to sample data | |
| 120 | + void convertRawDataToSamples(const std::vector<unsigned char> &rawData); | |
| 121 | + | |
| 122 | + /// \brief Sets the size of the sample buffer without updating dependencies. | |
| 123 | + /// \param index The record length index that should be set. | |
| 124 | + /// \return The record length that has been set, 0 on error. | |
| 89 | 125 | unsigned updateRecordLength(unsigned size); |
| 126 | + | |
| 127 | + /// \brief Sets the samplerate based on the parameters calculated by | |
| 128 | + /// Control::getBestSamplerate. | |
| 129 | + /// \param downsampler The downsampling factor. | |
| 130 | + /// \param fastRate true, if one channel uses all buffers. | |
| 131 | + /// \return The downsampling factor that has been set. | |
| 90 | 132 | unsigned updateSamplerate(unsigned downsampler, bool fastRate); |
| 133 | + | |
| 134 | + /// \brief Restore the samplerate/timebase targets after divider updates. | |
| 91 | 135 | void restoreTargets(); |
| 136 | + | |
| 137 | + /// \brief Update the minimum and maximum supported samplerate. | |
| 92 | 138 | void updateSamplerateLimits(); |
| 93 | 139 | |
| 140 | + private: | |
| 94 | 141 | // Communication with device |
| 95 | 142 | USBDevice *device; ///< The USB device for the oscilloscope |
| 96 | 143 | bool sampling = false; ///< true, if the oscilloscope is taking samples |
| 97 | 144 | |
| 98 | - QStringList specialTriggerSources = {tr("EXT"),tr("EXT/10")}; ///< Names of the special trigger sources | |
| 145 | + QStringList specialTriggerSources = {tr("EXT"), tr("EXT/10")}; ///< Names of the special trigger sources | |
| 99 | 146 | |
| 100 | 147 | DataArray<unsigned char> *command[Hantek::BULK_COUNT] = {0}; ///< Pointers to bulk |
| 101 | - /// commands, ready to | |
| 148 | + /// commands, ready to | |
| 102 | 149 | /// be transmitted |
| 103 | - bool commandPending[Hantek::BULK_COUNT] = {false}; ///< true, when the command should be | |
| 104 | - /// executed | |
| 150 | + bool commandPending[Hantek::BULK_COUNT] = {false}; ///< true, when the command should be | |
| 151 | + /// executed | |
| 105 | 152 | DataArray<unsigned char> *control[Hantek::CONTROLINDEX_COUNT] = {0}; ///< Pointers to control commands |
| 106 | - unsigned char controlCode[Hantek::CONTROLINDEX_COUNT]; ///< Request codes for | |
| 107 | - /// control commands | |
| 108 | - bool controlPending[Hantek::CONTROLINDEX_COUNT]= {false}; ///< true, when the control | |
| 153 | + unsigned char controlCode[Hantek::CONTROLINDEX_COUNT]; ///< Request codes for | |
| 154 | + /// control commands | |
| 155 | + bool controlPending[Hantek::CONTROLINDEX_COUNT] = {false}; ///< true, when the control | |
| 109 | 156 | /// command should be executed |
| 110 | 157 | |
| 111 | 158 | // Device setup |
| 112 | 159 | Hantek::ControlSpecification specification; ///< The specifications of the device |
| 113 | - Hantek::ControlSettings controlsettings; ///< The current settings of the device | |
| 160 | + Hantek::ControlSettings controlsettings; ///< The current settings of the device | |
| 114 | 161 | |
| 115 | 162 | // Results |
| 116 | 163 | DSOsamples result; |
| 117 | 164 | unsigned previousSampleCount = 0; ///< The expected total number of samples at |
| 118 | - /// the last check before sampling started | |
| 165 | + /// the last check before sampling started | |
| 119 | 166 | |
| 120 | 167 | // State of the communication thread |
| 121 | 168 | int captureState = Hantek::CAPTURE_WAITING; |
| ... | ... | @@ -130,19 +177,36 @@ class HantekDsoControl : public QObject { |
| 130 | 177 | void startSampling(); |
| 131 | 178 | void stopSampling(); |
| 132 | 179 | |
| 133 | - unsigned setRecordLength(unsigned size); | |
| 134 | - double setSamplerate(double samplerate = 0.0); | |
| 135 | - double setRecordTime(double duration = 0.0); | |
| 136 | - | |
| 137 | - int setChannelUsed(unsigned channel, bool used); | |
| 138 | - int setCoupling(unsigned channel, Dso::Coupling coupling); | |
| 139 | - double setGain(unsigned channel, double gain); | |
| 140 | - double setOffset(unsigned channel, double offset); | |
| 141 | - | |
| 142 | - int setTriggerMode(Dso::TriggerMode mode); | |
| 143 | - int setTriggerSource(bool special, unsigned id); | |
| 144 | - double setTriggerLevel(unsigned channel, double level); | |
| 145 | - int setTriggerSlope(Dso::Slope slope); | |
| 146 | - double setPretriggerPosition(double position); | |
| 147 | - int forceTrigger(); | |
| 180 | + Dso::ErrorCode setRecordLength(unsigned size); | |
| 181 | + Dso::ErrorCode setSamplerate(double samplerate = 0.0); | |
| 182 | + Dso::ErrorCode setRecordTime(double duration = 0.0); | |
| 183 | + | |
| 184 | + Dso::ErrorCode setChannelUsed(unsigned channel, bool used); | |
| 185 | + Dso::ErrorCode setCoupling(unsigned channel, Dso::Coupling coupling); | |
| 186 | + Dso::ErrorCode setGain(unsigned channel, double gain); | |
| 187 | + Dso::ErrorCode setOffset(unsigned channel, double offset); | |
| 188 | + | |
| 189 | + Dso::ErrorCode setTriggerMode(Dso::TriggerMode mode); | |
| 190 | + Dso::ErrorCode setTriggerSource(bool special, unsigned id); | |
| 191 | + Dso::ErrorCode setTriggerLevel(unsigned channel, double level); | |
| 192 | + Dso::ErrorCode setTriggerSlope(Dso::Slope slope); | |
| 193 | + Dso::ErrorCode setPretriggerPosition(double position); | |
| 194 | + void forceTrigger(); | |
| 195 | + | |
| 196 | + signals: | |
| 197 | + void samplingStarted(); ///< The oscilloscope started sampling/waiting for trigger | |
| 198 | + void samplingStopped(); ///< The oscilloscope stopped sampling/waiting for trigger | |
| 199 | + void statusMessage(const QString &message, int timeout); ///< Status message about the oscilloscope | |
| 200 | + void samplesAvailable(); ///< New sample data is available | |
| 201 | + | |
| 202 | + void availableRecordLengthsChanged(const std::vector<unsigned> &recordLengths); ///< The available record | |
| 203 | + /// lengths, empty list for | |
| 204 | + | |
| 205 | + void samplerateLimitsChanged(double minimum, double maximum); ///< The minimum or maximum samplerate has changed | |
| 206 | + void recordLengthChanged(unsigned long duration); ///< The record length has changed | |
| 207 | + void recordTimeChanged(double duration); ///< The record time duration has changed | |
| 208 | + void samplerateChanged(double samplerate); ///< The samplerate has changed | |
| 209 | + void samplerateSet(int mode, QList<double> sampleSteps); ///< The samplerate has changed | |
| 210 | + | |
| 211 | + void communicationError() const; | |
| 148 | 212 | }; | ... | ... |
openhantek/src/main.cpp
| ... | ... | @@ -93,19 +93,22 @@ int main(int argc, char *argv[]) { |
| 93 | 93 | QString modelName = QString::fromStdString(i->getModel().name); |
| 94 | 94 | |
| 95 | 95 | if (i->needsFirmware()) { |
| 96 | - w->addItem(QCoreApplication::translate("Firmware upload dialog", "%1: Firmware upload failed").arg(modelName)); | |
| 96 | + w->addItem( | |
| 97 | + QCoreApplication::translate("Firmware upload dialog", "%1: Firmware upload failed").arg(modelName)); | |
| 97 | 98 | continue; |
| 98 | 99 | } |
| 99 | 100 | QString errorMessage; |
| 100 | 101 | if (i->connectDevice(errorMessage)) { |
| 101 | 102 | w->addItem(QCoreApplication::translate("Firmware upload dialog", "%1: Ready").arg(modelName)); |
| 102 | - w->setCurrentRow(w->count()-1); | |
| 103 | + w->setCurrentRow(w->count() - 1); | |
| 103 | 104 | } else { |
| 104 | - w->addItem(QCoreApplication::translate("Firmware upload dialog", "%1: %2").arg(modelName).arg(findDevices.getErrorMessage())); | |
| 105 | + w->addItem(QCoreApplication::translate("Firmware upload dialog", "%1: %2") | |
| 106 | + .arg(modelName) | |
| 107 | + .arg(findDevices.getErrorMessage())); | |
| 105 | 108 | } |
| 106 | 109 | } |
| 107 | 110 | |
| 108 | - if (w->currentRow() == -1 || devices.size()>1) { | |
| 111 | + if (w->currentRow() == -1 || devices.size() > 1) { | |
| 109 | 112 | QPushButton *btn = new QPushButton(QCoreApplication::translate("", "Connect to first device"), dialog.get()); |
| 110 | 113 | dialog->move(QApplication::desktop()->screen()->rect().center() - w->rect().center()); |
| 111 | 114 | dialog->setWindowTitle(QCoreApplication::translate("", "Firmware upload")); | ... | ... |
openhantek/src/mainwindow.cpp
| ... | ... | @@ -262,12 +262,12 @@ void OpenHantekMainWindow::addManualCommandEdit() { |
| 262 | 262 | commandEdit->setFocus(); |
| 263 | 263 | }); |
| 264 | 264 | connect(commandEdit, &QLineEdit::returnPressed, [this]() { |
| 265 | - int errorCode = dsoControl->stringCommand(commandEdit->text()); | |
| 265 | + Dso::ErrorCode errorCode = dsoControl->stringCommand(commandEdit->text()); | |
| 266 | 266 | |
| 267 | 267 | commandEdit->hide(); |
| 268 | 268 | commandEdit->clear(); |
| 269 | 269 | |
| 270 | - if (errorCode < 0) statusBar()->showMessage(tr("Invalid command"), 3000); | |
| 270 | + if (errorCode != Dso::ErrorCode::ERROR_NONE) statusBar()->showMessage(tr("Invalid command"), 3000); | |
| 271 | 271 | }); |
| 272 | 272 | } |
| 273 | 273 | |
| ... | ... | @@ -343,10 +343,12 @@ void OpenHantekMainWindow::applySettingsToDevice() { |
| 343 | 343 | samplerateSelected(); |
| 344 | 344 | else |
| 345 | 345 | timebaseSelected(); |
| 346 | - if (dsoControl->getAvailableRecordLengths()->isEmpty()) | |
| 346 | + if (dsoControl->getAvailableRecordLengths().empty()) | |
| 347 | 347 | dsoControl->setRecordLength(settings->scope.horizontal.recordLength); |
| 348 | 348 | else { |
| 349 | - int index = dsoControl->getAvailableRecordLengths()->indexOf(settings->scope.horizontal.recordLength); | |
| 349 | + auto recLenVec = dsoControl->getAvailableRecordLengths(); | |
| 350 | + ptrdiff_t index = std::distance( | |
| 351 | + recLenVec.begin(), std::find(recLenVec.begin(), recLenVec.end(), settings->scope.horizontal.recordLength)); | |
| 350 | 352 | dsoControl->setRecordLength(index < 0 ? 1 : index); |
| 351 | 353 | } |
| 352 | 354 | dsoControl->setTriggerMode(settings->scope.trigger.mode); | ... | ... |