Commit e78ab7bd711f736588ad56112b71c8c6af7ed3cb

Authored by oliverhaag
1 parent 5c0400d5

Samplerate values are calculated now, so every samplerate supported by the hardware is possible

openhantek/AUTHORS
1   -Oleg Khudyakov <prcoder@potrebitel.ru>
2 1 Oliver Haag <oliver.haag@gmail.com>
3 2 \ No newline at end of file
... ...
openhantek/ChangeLog
... ... @@ -51,3 +51,13 @@
51 51 * Added zoomed scope and markers to exports
52 52 * Darker default colors for channels in print mode
53 53 * Added enum values for DSO-5200 bulk commands
  54 +
  55 +2010-08-24 Oliver Haag <oliver.haag@gmail.com>
  56 +* Documentation of Hantek::Device corrected
  57 +* Hantek::Device::bulkReadMulti improved
  58 +
  59 +2010-08-26 Oliver Haag <oliver.haag@gmail.com>
  60 +* Samplerate values sent to device are calculated now, only limited by hardware
  61 +* Added the samplerate formula to the documentation
  62 +* Documentation updated with additional information from Oleg
  63 +* Removed Oleg from AUTHORS
... ...
openhantek/mainpage.dox
... ... @@ -20,7 +20,7 @@ After installing these you can build it by running:
20 20 <pre>
21 21 $ qmake
22 22 $ make
23   - $ make install
  23 + $ sudo make install
24 24 </pre>
25 25  
26 26 \subsection ssec_options Build options
... ... @@ -38,7 +38,7 @@ You can set environment variables to set various build options (Done best by pre
38 38  
39 39 \section sec_firmware Installation of the firmware
40 40 \subsection ssec_drivers Gettings the Windows drivers
41   -Before using OpenHantek you have to extract the firmware from the official Windows drivers. You can get them from the <a href="http://www.hantek.ru/download.html">Hantek website</a> (<a href="http://translate.google.com/translate?sl=ru&tl=en&u=http%3A%2F%2Fwww.hantek.ru%2F">English translation</a>).
  41 +Before using OpenHantek you have to extract the firmware from the official Windows drivers. You can get them from the <a href="http://www.hantek.ru/download.html">Hantek website</a> (<a href="http://translate.google.com/translate?sl=ru&tl=en&u=http%3A%2F%2Fwww.hantek.ru%2Fdownload.html">English translation</a>).
42 42 \subsection ssec_dsoextractfw The firmware extraction tool
43 43 You need the tool dsoextractfw from the sourceforge page too extract the firmware. You have to install libbfd development files and build it by typing:
44 44 <pre>
... ...
openhantek/src/hantek/control.cpp
... ... @@ -42,9 +42,7 @@ namespace Hantek {
42 42 // Values for the Gain and Timebase enums
43 43 this->gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00
44 44 << 8.0 << 16.0 << 40.0;
45   - this->samplerateSteps << 1e8 << 5e7 << 25e6 << 1e7
46   - << 5e6 << 25e5 << 1e6 << 5e5 << 25e4 << 1e5 << 5e4 << 25e3 << 1e4
47   - << 5e3 << 25e2 << 1e3;
  45 + this->samplerateChannelMax = 50e6;
48 46  
49 47 // Special trigger sources
50 48 this->specialTriggerSources << tr("EXT") << tr("EXT/10");
... ... @@ -83,10 +81,10 @@ namespace Hantek {
83 81 this->setOffset(channel, 0.5);
84 82 this->setTriggerLevel(channel, 0.0);
85 83 }
86   - this->setSamplerate(1e6);
87 84 this->setBufferSize(BUFFER_SMALL);
  85 + this->setSamplerate(1e6);
88 86 this->setTriggerMode(Dso::TRIGGERMODE_NORMAL);
89   - this->setTriggerPosition(5e3 / this->samplerateSteps[this->samplerate]);
  87 + this->setTriggerPosition(5e3 / (this->samplerateMax / this->samplerateDivider));
90 88 this->setTriggerSlope(Dso::SLOPE_POSITIVE);
91 89 this->setTriggerSource(false, 0);
92 90  
... ... @@ -135,7 +133,26 @@ namespace Hantek {
135 133 for(int control = 0; control < CONTROLINDEX_COUNT; control++)
136 134 this->controlPending[control] = true;
137 135  
138   - // Get calibration data
  136 + // Maximum possible samplerate for a single channel
  137 + switch(this->device->getModel()) {
  138 + case MODEL_DSO2090:
  139 + case MODEL_DSO2100:
  140 + this->samplerateChannelMax = 50e6;
  141 + break;
  142 + case MODEL_DSO2150:
  143 + this->samplerateChannelMax = 75e6;
  144 + break;
  145 + case MODEL_DSO2250:
  146 + case MODEL_DSO5200:
  147 + case MODEL_DSO5200A:
  148 + this->samplerateChannelMax = 125e6;
  149 + break;
  150 + default:
  151 + this->samplerateChannelMax = 50e6;
  152 + break;
  153 + }
  154 +
  155 + // Get channel level data
139 156 errorCode = this->device->controlRead(CONTROL_VALUE, (unsigned char*) &(this->channelLevels), sizeof(this->channelLevels), (int) VALUE_CHANNELLEVEL);
140 157 if(errorCode < 0) {
141 158 this->device->disconnect();
... ... @@ -146,6 +163,8 @@ namespace Hantek {
146 163 // Adapt offsets
147 164 for(unsigned int channel = 0; channel < HANTEK_CHANNELS; channel++)
148 165 this->setOffset(channel, this->offset[channel]);
  166 + this->setSamplerate(this->samplerateMax / this->samplerateDivider);
  167 + this->setTriggerPosition(this->triggerPosition);
149 168  
150 169 // The control loop is running until the device is disconnected
151 170 int captureState = CAPTURE_WAITING;
... ... @@ -405,7 +424,7 @@ namespace Hantek {
405 424 }
406 425  
407 426 this->samplesMutex.unlock();
408   - emit samplesAvailable(&(this->samples), &(this->samplesSize), this->samplerateSteps[this->samplerate], &(this->samplesMutex));
  427 + emit samplesAvailable(&(this->samples), &(this->samplesSize), (double) this->samplerateMax / this->samplerateDivider, &(this->samplesMutex));
409 428 }
410 429  
411 430 return 0;
... ... @@ -415,13 +434,13 @@ namespace Hantek {
415 434 /// \param size The buffer size that should be met (S).
416 435 /// \return The buffer size that has been set.
417 436 unsigned long int Control::updateBufferSize(unsigned long int size) {
418   - unsigned int sizeId = (size <= BUFFER_SMALL) ? 1 : 2;
  437 + BufferSizeId sizeId = (size <= BUFFER_SMALL) ? BUFFERID_SMALL : BUFFERID_LARGE;
419 438  
420 439 // SetTriggerAndSamplerate bulk command for samplerate
421   - ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->setSampleSize(sizeId);
  440 + ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->setBufferSize(sizeId);
422 441 this->commandPending[COMMAND_SETTRIGGERANDSAMPLERATE] = true;
423 442  
424   - this->bufferSize = (sizeId == 1) ? BUFFER_SMALL : BUFFER_LARGE;
  443 + this->bufferSize = (sizeId == BUFFERID_SMALL) ? BUFFER_SMALL : BUFFER_LARGE;
425 444  
426 445 return this->bufferSize;
427 446 }
... ... @@ -433,7 +452,7 @@ namespace Hantek {
433 452 this->updateBufferSize(size);
434 453  
435 454 this->setTriggerPosition(this->triggerPosition);
436   - this->setSamplerate(this->samplerateSteps[this->samplerate]);
  455 + this->setSamplerate(this->samplerateMax / this->samplerateDivider);
437 456 this->setTriggerSlope(this->triggerSlope);
438 457  
439 458 return this->bufferSize;
... ... @@ -443,47 +462,59 @@ namespace Hantek {
443 462 /// \param samplerate The samplerate that should be met (S/s).
444 463 /// \return The samplerate that has been set.
445 464 unsigned long int Control::setSamplerate(unsigned long int samplerate) {
446   - // Find lowest supported samplerate thats at least as high as the requested
447   - int samplerateId;
448   - for(samplerateId = SAMPLERATE_COUNT - 1; samplerateId > 0; samplerateId--)
449   - if(this->samplerateSteps[samplerateId] >= samplerate)
450   - break;
451   - // Fastrate is only possible if we're not using both channels
452   - if(samplerateId == SAMPLERATE_100MS && ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->getUsedChannel() == USED_CH1CH2)
453   - samplerateId = SAMPLERATE_50MS;
454   -
455   - // The values that are understood by the oscilloscope
456   - /// \todo Check large buffer values, seem to be crap
457   - static const unsigned char valueFastSmall[5] = {0, 1, 2, 3, 4};
458   - static const unsigned char valueFastLarge[5] = {0, 0, 0, 2, 3};
459   - static const unsigned short int valueSlowSmall[13] = {0xfffe, 0xfffc, 0xfff7, 0xffe8, 0xffce, 0xff9c, 0xff07, 0xfe0d, 0xfc19, 0xf63d, 0xec79, 0xd8f1, 0xffed};
460   - static const unsigned short int valueSlowLarge[13] = {0xffff, 0x0000, 0xfffc, 0xfff7, 0xffe8, 0xffce, 0xff9d, 0xff07, 0xfe0d, 0xfc19, 0xf63d, 0xec79, 0xffed};
  465 + if(samplerate == 0)
  466 + return 0;
461 467  
462 468 // SetTriggerAndSamplerate bulk command for samplerate
463 469 CommandSetTriggerAndSamplerate *commandSetTriggerAndSamplerate = (CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE];
464 470  
465   - // Set SamplerateFast bits for high sampling rates
466   - if(samplerateId <= SAMPLERATE_5MS)
467   - commandSetTriggerAndSamplerate->setSamplerateFast(this->bufferSize == BUFFER_SMALL ? valueFastSmall[samplerateId - SAMPLERATE_100MS] : valueFastLarge[samplerateId - SAMPLERATE_100MS]);
468   - else
469   - commandSetTriggerAndSamplerate->setSamplerateFast(4);
  471 + // Calculate with fast rate first if only one channel is used
  472 + bool fastRate = false;
  473 + this->samplerateMax = this->samplerateChannelMax;
  474 + if(((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->getUsedChannel() != USED_CH1CH2) {
  475 + fastRate = true;
  476 + this->samplerateMax *= HANTEK_CHANNELS;
  477 + }
470 478  
471   - // Set normal Samplerate value for lower sampling rates
472   - if(samplerateId >= SAMPLERATE_10MS)
473   - commandSetTriggerAndSamplerate->setSamplerate(this->bufferSize == BUFFER_SMALL ? valueSlowSmall[samplerateId - SAMPLERATE_10MS] : valueSlowLarge[samplerateId - SAMPLERATE_10MS]);
474   - else
475   - commandSetTriggerAndSamplerate->setSamplerate(0x0000);
  479 + // The maximum sample rate depends on the buffer size
  480 + switch(commandSetTriggerAndSamplerate->getBufferSize()) {
  481 + case BUFFERID_ROLL:
  482 + this->samplerateMax /= 1000;
  483 + break;
  484 + case BUFFERID_LARGE:
  485 + this->samplerateMax /= 2;
  486 + break;
  487 + default:
  488 + break;
  489 + }
  490 +
  491 + // Get divider that would provide the requested rate, can't be zero
  492 + this->samplerateDivider = qMax(this->samplerateMax / samplerate, (long unsigned int) 1);
476 493  
  494 + // Use normal mode if it would meet the rate as exactly as fast rate mode
  495 + if(fastRate && this->samplerateDivider % HANTEK_CHANNELS == 0) {
  496 + fastRate = false;
  497 + this->samplerateMax /= 2;
  498 + this->samplerateDivider /= HANTEK_CHANNELS;
  499 + }
  500 +
  501 + // Split the resulting divider into the values understood by the device
  502 + // The fast value is kept at 4 (or 3) for slow sample rates
  503 + long int valueSlow = qMax(((long int) this->samplerateDivider - 3) / 2, (long int) 0);
  504 + unsigned char valueFast = this->samplerateDivider - valueSlow * 2;
  505 +
  506 + // Store samplerate fast value
  507 + commandSetTriggerAndSamplerate->setSamplerateFast(valueFast);
  508 + // Store samplerate slow value (two's complement)
  509 + commandSetTriggerAndSamplerate->setSamplerateSlow(valueSlow == 0 ? 0 : 0xffff - valueSlow);
477 510 // Set fast rate when used
478   - commandSetTriggerAndSamplerate->setFastRate(samplerateId == SAMPLERATE_100MS);
  511 + commandSetTriggerAndSamplerate->setFastRate(fastRate);
479 512  
480 513 this->commandPending[COMMAND_SETTRIGGERANDSAMPLERATE] = true;
481 514  
482   - this->samplerate = (Samplerate) samplerateId;
483   -
484 515 this->updateBufferSize(this->bufferSize);
485 516 this->setTriggerSlope(this->triggerSlope);
486   - return this->samplerateSteps[samplerateId];
  517 + return this->samplerateMax / this->samplerateDivider;
487 518 }
488 519  
489 520 /// \brief Enables/disables filtering of the given channel.
... ... @@ -664,9 +695,12 @@ namespace Hantek {
664 695 return -1;
665 696  
666 697 // SetTriggerAndSamplerate bulk command for trigger position
667   - ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->setTriggerSlope((this->bufferSize != BUFFER_SMALL || this->samplerate > SAMPLERATE_10MS || (SAMPLERATE_10MS - this->samplerate) % 2) ? slope : Dso::SLOPE_NEGATIVE - slope);
  698 + CommandSetTriggerAndSamplerate *commandSetTriggerAndSamplerate = (CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE];
  699 +
  700 + commandSetTriggerAndSamplerate->setTriggerSlope((/*this->bufferSize != BUFFER_SMALL ||*/ commandSetTriggerAndSamplerate->getSamplerateFast() % 2 == 0) ? slope : Dso::SLOPE_NEGATIVE - slope);
668 701 this->commandPending[COMMAND_SETTRIGGERANDSAMPLERATE] = true;
669 702  
  703 + this->triggerSlope = slope;
670 704 return 0;
671 705 }
672 706  
... ... @@ -677,13 +711,13 @@ namespace Hantek {
677 711 // Calculate the position value (Varying start point, measured in samples)
678 712 //unsigned long int positionRange = (this->bufferSize == BUFFER_SMALL) ? 10000 : 32768;
679 713 unsigned long int positionStart = (this->bufferSize == BUFFER_SMALL) ? 0x77660 : 0x78000;
680   - unsigned long int positionValue = position * this->samplerateSteps[this->samplerate] + positionStart;
  714 + unsigned long int positionValue = position * this->samplerateMax / this->samplerateDivider + positionStart;
681 715  
682 716 // SetTriggerAndSamplerate bulk command for trigger position
683 717 ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->setTriggerPosition(positionValue);
684 718 this->commandPending[COMMAND_SETTRIGGERANDSAMPLERATE] = true;
685 719  
686 720 this->triggerPosition = position;
687   - return (double) (positionValue - positionStart) / this->samplerateSteps[this->samplerate];
  721 + return (double) (positionValue - positionStart) / this->samplerateMax * this->samplerateDivider;
688 722 }
689 723 }
... ...
openhantek/src/hantek/control.h
... ... @@ -81,10 +81,12 @@ namespace Hantek {
81 81 bool controlPending[CONTROLINDEX_COUNT]; ///< true, when the control command should be executed
82 82  
83 83 /// Calibration data for the channel offsets
84   - unsigned short channelLevels[HANTEK_CHANNELS][GAIN_COUNT][OFFSET_COUNT];
  84 + unsigned short int channelLevels[HANTEK_CHANNELS][GAIN_COUNT][OFFSET_COUNT];
85 85  
86 86 // Various cached settings
87   - Samplerate samplerate; ///< The samplerate id
  87 + unsigned long int samplerateDivider; ///< The samplerate divider
  88 + unsigned long int samplerateMax; ///< The maximum sample rate for the current setup
  89 + unsigned long int samplerateChannelMax; ///< The maximum sample rate for a single channel
88 90 Gain gain[HANTEK_CHANNELS]; ///< The gain id
89 91 double offset[HANTEK_CHANNELS]; ///< The current screen offset for each channel
90 92 double offsetReal[HANTEK_CHANNELS]; ///< The real offset for each channel (Due to quantization)
... ... @@ -103,8 +105,6 @@ namespace Hantek {
103 105  
104 106 // Lists for enums
105 107 QList<double> gainSteps; ///< Voltage steps in V/screenheight
106   - QList<unsigned long int> samplerateSteps; ///< Samplerate steps in S/s
107   - QList<unsigned short int> samplerateValues; ///< Values sent to the oscilloscope
108 108  
109 109 public slots:
110 110 unsigned long int setSamplerate(unsigned long int samplerate);
... ...
openhantek/src/hantek/device.cpp
... ... @@ -44,6 +44,7 @@ namespace Hantek {
44 44 << 0x5200 << 0x520A;
45 45 this->modelStrings << "DSO-2090" << "DSO-2100" << "DSO-2150" << "DSO-2250"
46 46 << "DSO-5200" << "DSO-5200A";
  47 + this->model = MODEL_UNKNOWN;
47 48  
48 49 this->beginCommandControl = new ControlBeginCommand();
49 50  
... ... @@ -283,7 +284,7 @@ namespace Hantek {
283 284 /// \param data Buffer for the sent/recieved data.
284 285 /// \param length The length of the packet.
285 286 /// \param attempts The number of attempts, that are done on timeouts.
286   - /// \return 0 on success, libusb error code on error.
  287 + /// \return Number of transferred bytes on success, libusb error code on error.
287 288 int Device::bulkTransfer(unsigned char endpoint, unsigned char *data, unsigned int length, int attempts) {
288 289 if(!this->handle)
289 290 return LIBUSB_ERROR_NO_DEVICE;
... ... @@ -306,7 +307,7 @@ namespace Hantek {
306 307 /// \param data Buffer for the sent/recieved data.
307 308 /// \param length The length of the packet.
308 309 /// \param attempts The number of attempts, that are done on timeouts.
309   - /// \return 0 on success, libusb error code on error.
  310 + /// \return Number of sent bytes on success, libusb error code on error.
310 311 int Device::bulkWrite(unsigned char *data, unsigned int length, int attempts) {
311 312 if(!this->handle)
312 313 return LIBUSB_ERROR_NO_DEVICE;
... ... @@ -333,7 +334,7 @@ namespace Hantek {
333 334 /// \param data Buffer for the sent/recieved data.
334 335 /// \param length The length of the packet.
335 336 /// \param attempts The number of attempts, that are done on timeouts.
336   - /// \return 0 on success, libusb error code on error.
  337 + /// \return Number of received bytes on success, libusb error code on error.
337 338 int Device::bulkRead(unsigned char *data, unsigned int length, int attempts) {
338 339 if(!this->handle)
339 340 return LIBUSB_ERROR_NO_DEVICE;
... ... @@ -359,7 +360,7 @@ namespace Hantek {
359 360 /// \brief Send a bulk command to the oscilloscope.
360 361 /// \param command The command, that should be sent.
361 362 /// \param attempts The number of attempts, that are done on timeouts.
362   - /// \return 0 on success, libusb error code on error.
  363 + /// \return Number of sent bytes on success, libusb error code on error.
363 364 int Device::bulkCommand(Helper::DataArray<unsigned char> *command, int attempts) {
364 365 if(!this->handle)
365 366 return LIBUSB_ERROR_NO_DEVICE;
... ... @@ -377,7 +378,7 @@ namespace Hantek {
377 378 /// \param data Buffer for the sent/recieved data.
378 379 /// \param length The length of data contained in the packets.
379 380 /// \param attempts The number of attempts, that are done on timeouts.
380   - /// \return 0 on success, libusb error code on error.
  381 + /// \return Number of received bytes on success, libusb error code on error.
381 382 int Device::bulkReadMulti(unsigned char *data, unsigned int length, int attempts) {
382 383 if(!this->handle)
383 384 return LIBUSB_ERROR_NO_DEVICE;
... ... @@ -388,24 +389,24 @@ namespace Hantek {
388 389 if(errorCode < 0)
389 390 return errorCode;
390 391  
391   - int packetCount = length / this->inPacketLength;
392   -
393 392 errorCode = this->inPacketLength;
394   - int packet;
395   - for(packet = 0; packet < packetCount && errorCode == this->inPacketLength; packet++) {
  393 + unsigned int packet, received = 0;
  394 + for(packet = 0; received < length && errorCode == this->inPacketLength; packet++) {
396 395 #if LIBUSB_VERSION == 0
397 396 errorCode = LIBUSB_ERROR_TIMEOUT;
398 397 for(int attempt = 0; (attempt < attempts || attempts == -1) && errorCode == LIBUSB_ERROR_TIMEOUT; attempt++)
399   - errorCode = usb_bulk_read(this->handle, HANTEK_EP_IN, (char *) data + packet * this->inPacketLength, this->inPacketLength, HANTEK_TIMEOUT);
  398 + errorCode = usb_bulk_read(this->handle, HANTEK_EP_IN, (char *) data + packet * this->inPacketLength, qMin(length - received, (unsigned int) this->inPacketLength), HANTEK_TIMEOUT);
400 399 #else
401   - errorCode = this->bulkTransfer(HANTEK_EP_IN, data + packet * this->inPacketLength, this->inPacketLength, attempts);
  400 + errorCode = this->bulkTransfer(HANTEK_EP_IN, data + packet * this->inPacketLength, qMin(length - received, (unsigned int) this->inPacketLength), attempts);
402 401 #endif
  402 + if(errorCode > 0)
  403 + received += errorCode;
403 404 }
404 405  
405 406 if(errorCode < 0)
406 407 return errorCode;
407 408 else
408   - return (packet - 1) * this->inPacketLength + errorCode;
  409 + return received;
409 410 }
410 411  
411 412 /// \brief Control transfer to the oscilloscope.
... ... @@ -416,7 +417,7 @@ namespace Hantek {
416 417 /// \param value The value field of the packet.
417 418 /// \param index The index field of the packet.
418 419 /// \param attempts The number of attempts, that are done on timeouts.
419   - /// \return 0 on success, libusb error code on error.
  420 + /// \return Number of transferred bytes on success, libusb error code on error.
420 421 int Device::controlTransfer(unsigned char type, unsigned char request, unsigned char *data, unsigned int length, int value, int index, int attempts) {
421 422 if(!this->handle)
422 423 return LIBUSB_ERROR_NO_DEVICE;
... ... @@ -441,7 +442,7 @@ namespace Hantek {
441 442 /// \param value The value field of the packet.
442 443 /// \param index The index field of the packet.
443 444 /// \param attempts The number of attempts, that are done on timeouts.
444   - /// \return 0 on success, libusb error code on error.
  445 + /// \return Number of sent bytes on success, libusb error code on error.
445 446 int Device::controlWrite(unsigned char request, unsigned char *data, unsigned int length, int value, int index, int attempts) {
446 447 if(!this->handle)
447 448 return LIBUSB_ERROR_NO_DEVICE;
... ... @@ -456,7 +457,7 @@ namespace Hantek {
456 457 /// \param value The value field of the packet.
457 458 /// \param index The index field of the packet.
458 459 /// \param attempts The number of attempts, that are done on timeouts.
459   - /// \return 0 on success, libusb error code on error.
  460 + /// \return Number of received bytes on success, libusb error code on error.
460 461 int Device::controlRead(unsigned char request, unsigned char *data, unsigned int length, int value, int index, int attempts) {
461 462 if(!this->handle)
462 463 return LIBUSB_ERROR_NO_DEVICE;
... ... @@ -476,4 +477,10 @@ namespace Hantek {
476 477  
477 478 return response.getSpeed();
478 479 }
  480 +
  481 + /// \brief Get the oscilloscope model.
  482 + /// \return The #Model of the connected Hantek DSO.
  483 + Model Device::getModel() {
  484 + return this->model;
  485 + }
479 486 }
... ...
openhantek/src/hantek/device.h
... ... @@ -75,6 +75,7 @@ namespace Hantek {
75 75 int controlRead(unsigned char request, unsigned char *data, unsigned int length, int value = 0, int index = 0, int attempts = HANTEK_ATTEMPTS_DEFAULT);
76 76  
77 77 int getConnectionSpeed();
  78 + Model getModel();
78 79  
79 80 protected:
80 81 // Lists for enums
... ...
openhantek/src/hantek/types.cpp
... ... @@ -113,12 +113,12 @@ namespace Hantek {
113 113 this->init();
114 114  
115 115 this->setTriggerSource(triggerSource);
116   - this->setSampleSize(sampleSize);
  116 + this->setBufferSize(sampleSize);
117 117 this->setSamplerateFast(samplerateFast);
118 118 this->setUsedChannel(usedChannel);
119 119 this->setFastRate(fastRate);
120 120 this->setTriggerSlope(triggerSlope);
121   - this->setSamplerate(samplerate);
  121 + this->setSamplerateSlow(samplerate);
122 122 this->setTriggerPosition(triggerPosition);
123 123 }
124 124  
... ... @@ -136,13 +136,13 @@ namespace Hantek {
136 136  
137 137 /// \brief Get the sampleSize value in Tsr1Bits.
138 138 /// \return The sampleSize value.
139   - unsigned char CommandSetTriggerAndSamplerate::getSampleSize() {
  139 + unsigned char CommandSetTriggerAndSamplerate::getBufferSize() {
140 140 return ((Tsr1Bits *) &(this->array[2]))->sampleSize;
141 141 }
142 142  
143 143 /// \brief Set the sampleSize in Tsr1Bits to the given value.
144 144 /// \param value The new sampleSize value.
145   - void CommandSetTriggerAndSamplerate::setSampleSize(unsigned char value) {
  145 + void CommandSetTriggerAndSamplerate::setBufferSize(unsigned char value) {
146 146 ((Tsr1Bits *) &(this->array[2]))->sampleSize = value;
147 147 }
148 148  
... ... @@ -202,7 +202,7 @@ namespace Hantek {
202 202  
203 203 /// \brief Set the Samplerate to the given value.
204 204 /// \param samplerate The new samplerate value.
205   - void CommandSetTriggerAndSamplerate::setSamplerate(unsigned short int samplerate) {
  205 + void CommandSetTriggerAndSamplerate::setSamplerateSlow(unsigned short int samplerate) {
206 206 this->array[4] = (unsigned char) samplerate;
207 207 this->array[5] = (unsigned char) (samplerate >> 8);
208 208 }
... ...
openhantek/src/hantek/types.h
... ... @@ -73,8 +73,12 @@ namespace Hantek {
73 73 /// <td>0x00</td>
74 74 /// <td>Tsr1Bits</td>
75 75 /// <td>Tsr2Bits</td>
76   - /// <td>Samplerate[0]</td>
77   - /// <td>Samplerate[1]</td>
  76 + /// <td>SamplerateValue[0]</td>
  77 + /// <td>SamplerateValue[1]</td>
  78 + /// </tr>
  79 + /// </table>
  80 + /// <table>
  81 + /// <tr>
78 82 /// <td>TriggerPosition[0]</td>
79 83 /// <td>TriggerPosition[1]</td>
80 84 /// <td>0x00</td>
... ... @@ -83,6 +87,11 @@ namespace Hantek {
83 87 /// <td>0x00</td>
84 88 /// </tr>
85 89 /// </table>
  90 + /// The samplerate is set relative to the maximum sample rate by a divider that is set in Tsr1Bits.samplerateFast and the 16-bit value in the two SamplerateValue bytes.<br />
  91 + /// Without using fast rate mode, the samplerate is:<br />
  92 + /// <i>Samplerate = SamplerateMax / (2comp(SamplerateValue) * 2 + Tsr1Bits.samplerateFast)</i><br />
  93 + /// SamplerateMax is 50 MHz for the DSO-2090.<br />
  94 + /// When using fast rate mode the resulting samplerate is twice as fast, when using the large buffer it is half as fast. When Tsr1Bits.sampleSize is 0 (Roll mode) the sampling rate is divided by 1000. Setting Tsr1Bits.samplerateFast to 0 doesn't work, the result will be the same as Tsr1Bits.samplerateFast = 1.
86 95 COMMAND_SETTRIGGERANDSAMPLERATE,
87 96  
88 97 /// This command forces triggering:
... ... @@ -180,7 +189,7 @@ namespace Hantek {
180 189 /// <tr>
181 190 /// <td>0x08</td>
182 191 /// <td>0x0f</td>
183   - /// <td>Data</td>
  192 + /// <td>Data | 0x01</td>
184 193 /// <td>0x00</td>
185 194 /// <td>0x00</td>
186 195 /// <td>0x00</td>
... ... @@ -197,7 +206,7 @@ namespace Hantek {
197 206 /// <td>0x00</td>
198 207 /// </tr>
199 208 /// </table>
200   - /// The oscilloscope returns the logical data:
  209 + /// The oscilloscope returns the logical data, which is 64 or 512 bytes long:
201 210 /// <table>
202 211 /// <tr>
203 212 /// <td>?</td>
... ... @@ -233,11 +242,11 @@ namespace Hantek {
233 242 /// <td>0x00</td>
234 243 /// <td>Samplerate[0] (?)</td>
235 244 /// <td>Samplerate[1] (?)</td>
236   - /// <td>Unknown</td>
  245 + /// <td>Tsr1.samplerateFast replacement (?)</td>
237 246 /// <td>0x00</td>
238 247 /// </tr>
239 248 /// </table>
240   - COMMAND_DSO5200_0C,
  249 + COMMAND_SETSAMPLERATE5200,
241 250  
242 251 /// This command seems to set trigger settings for the DSO-5200:
243 252 /// <table>
... ... @@ -324,6 +333,10 @@ namespace Hantek {
324 333 /// <td>Ch2Offset[0]</td>
325 334 /// <td>TriggerOffset[1] | 0x20</td>
326 335 /// <td>TriggerOffset[0]</td>
  336 + /// </tr>
  337 + /// </table>
  338 + /// <table>
  339 + /// <tr>
327 340 /// <td>0x00</td>
328 341 /// <td>0x00</td>
329 342 /// <td>0x00</td>
... ... @@ -346,10 +359,18 @@ namespace Hantek {
346 359 /// <td>0x04 ^ (Ch1Gain < 1 V)</td>
347 360 /// <td>0x08 ^ (Ch1Gain < 100 mV)</td>
348 361 /// <td>0x02 ^ (Ch1Coupling == DC)</td>
  362 + /// </tr>
  363 + /// </table>
  364 + /// <table>
  365 + /// <tr>
349 366 /// <td>0x20 ^ (Ch2Gain < 1 V)</td>
350 367 /// <td>0x40 ^ (Ch2Gain < 100 mV)</td>
351 368 /// <td>0x10 ^ (Ch2Coupling == DC)</td>
352 369 /// <td>0x01 ^ (Trigger == EXT)</td>
  370 + /// </tr>
  371 + /// </table>
  372 + /// <table>
  373 + /// <tr>
353 374 /// <td>0x00</td>
354 375 /// <td>0x00</td>
355 376 /// <td>0x00</td>
... ... @@ -368,9 +389,18 @@ namespace Hantek {
368 389 /// \enum ControlValue hantek/types.h
369 390 /// \brief All supported values for control commands.
370 391 enum ControlValue {
  392 + /// Value 0x08 is the calibration data for the channels offsets. It holds the offset value for the top and bottom of the scope screen for every gain step on every channel. The data is stored as a three-dimensional array:<br />
  393 + /// <i>channelLevels[channel][#Gain][#LevelOffset]</i>
371 394 VALUE_CHANNELLEVEL = 0x08,
372   - VALUE_DEVICEADDRESS = 0x0A,
373   - VALUE_CALIBRATIONDATA = 0x60
  395 +
  396 + /// Value 0x0a is the address of the device. It has a length of one byte.
  397 + VALUE_DEVICEADDRESS = 0x0a,
  398 +
  399 + /// Value 0x60 seems to be some calibration data with a length of four bytes. What it is good for is unknown so far.
  400 + VALUE_CALIBRATIONDATA = 0x60,
  401 +
  402 + /// Value 0x70 is an additional data that is used on the DSO-5200, it's six bytes long.
  403 + VALUE_UNKNOWN_70 = 0x70
374 404 };
375 405  
376 406 //////////////////////////////////////////////////////////////////////////////
... ... @@ -387,8 +417,8 @@ namespace Hantek {
387 417 /// \enum ConnectionSpeed hantek/types.h
388 418 /// \brief The speed level of the USB connection.
389 419 enum ConnectionSpeed {
390   - CONNECTION_FULLSPEED = 0,
391   - CONNECTION_HIGHSPEED = 1
  420 + CONNECTION_FULLSPEED = 0, ///< FullSpeed USB, 64 byte bulk transfers
  421 + CONNECTION_HIGHSPEED = 1 ///< HighSpeed USB, 512 byte bulk transfers
392 422 };
393 423  
394 424 //////////////////////////////////////////////////////////////////////////////
... ... @@ -440,6 +470,15 @@ namespace Hantek {
440 470 };
441 471  
442 472 //////////////////////////////////////////////////////////////////////////////
  473 + /// \enum BufferSizeId hantek/types.h
  474 + /// \brief The size id for CommandSetTriggerAndSamplerate.
  475 + enum BufferSizeId {
  476 + BUFFERID_ROLL = 0,
  477 + BUFFERID_SMALL,
  478 + BUFFERID_LARGE
  479 + };
  480 +
  481 + //////////////////////////////////////////////////////////////////////////////
443 482 /// \enum CaptureState hantek/types.h
444 483 /// \brief The different capture states which the oscilloscope returns.
445 484 enum CaptureState {
... ... @@ -453,10 +492,10 @@ namespace Hantek {
453 492 /// \enum CommandIndex hantek/types.h
454 493 /// \brief Can be set by CONTROL_BEGINCOMMAND, maybe it allows multiple commands at the same time?
455 494 enum CommandIndex {
456   - COMMANDINDEX_0 = 0x03,
  495 + COMMANDINDEX_0 = 0x03, ///< Used most of the time
457 496 COMMANDINDEX_1 = 0x0a,
458 497 COMMANDINDEX_2 = 0x09,
459   - COMMANDINDEX_3 = 0x01,
  498 + COMMANDINDEX_3 = 0x01, ///< Used for #COMMAND_SETTRIGGERANDSAMPLERATE sometimes
460 499 COMMANDINDEX_4 = 0x02,
461 500 COMMANDINDEX_5 = 0x08
462 501 };
... ... @@ -511,7 +550,7 @@ namespace Hantek {
511 550 struct Tsr1Bits {
512 551 unsigned char triggerSource:2; ///< The trigger source, see Hantek::TriggerSource
513 552 unsigned char sampleSize:3; ///< Buffer size, 0 = Roll, 1 = 10240 S, 2 = 32768 S
514   - unsigned char samplerateFast:3; ///< samplerate id for fast sampling rates
  553 + unsigned char samplerateFast:3; ///< samplerate value for fast sampling rates
515 554 };
516 555  
517 556 //////////////////////////////////////////////////////////////////////////////
... ... @@ -528,7 +567,7 @@ namespace Hantek {
528 567 struct Tsr2Bits {
529 568 unsigned char usedChannel:2; ///< Used channels, see Hantek::UsedChannels
530 569 unsigned char fastRate:1; ///< true, if one channels uses all buffers
531   - unsigned char triggerSlope:1; ///< The trigger slope, see Dso::Slope
  570 + unsigned char triggerSlope:1; ///< The trigger slope, see Dso::Slope, inverted when Tsr1Bits.samplerateFast is uneven
532 571 unsigned char reserved:4; ///< Unused bits
533 572 };
534 573  
... ... @@ -567,8 +606,8 @@ namespace Hantek {
567 606  
568 607 unsigned char getTriggerSource();
569 608 void setTriggerSource(unsigned char value);
570   - unsigned char getSampleSize();
571   - void setSampleSize(unsigned char value);
  609 + unsigned char getBufferSize();
  610 + void setBufferSize(unsigned char value);
572 611 unsigned char getSamplerateFast();
573 612 void setSamplerateFast(unsigned char value);
574 613 unsigned char getUsedChannel();
... ... @@ -578,7 +617,7 @@ namespace Hantek {
578 617 unsigned char getTriggerSlope();
579 618 void setTriggerSlope(unsigned char slope);
580 619 unsigned short int getSamplerate();
581   - void setSamplerate(unsigned short int samplerate);
  620 + void setSamplerateSlow(unsigned short int samplerate);
582 621 unsigned long int getTriggerPosition();
583 622 void setTriggerPosition(unsigned long int position);
584 623  
... ...