Commit b935f4e0bd826bc7bc5f26ed99505392e5b547eb

Authored by oliverhaag
1 parent f37ff582

Mostly DSO-5200 bugfixes, thanks to Ash

openhantek/ChangeLog
@@ -92,3 +92,8 @@ @@ -92,3 +92,8 @@
92 * DSO-5200 data conversion bugfix 92 * DSO-5200 data conversion bugfix
93 * Exporter::setFormat not filtering CSV format out anymore 93 * Exporter::setFormat not filtering CSV format out anymore
94 * Removed misplaced " before voltages in exported CSV file 94 * Removed misplaced " before voltages in exported CSV file
  95 +
  96 +2010-09-27 Oliver Haag <oliver.haag@gmail.com>
  97 +* Some bugfixes for the DSO-5200
  98 +* Simplified trigger point calculation and correct handling for fast rate mode
  99 +* Recalculating pretrigger position after samplerate changes
openhantek/mainpage.dox
@@ -37,7 +37,7 @@ You can set environment variables to set various build options (Done best by pre @@ -37,7 +37,7 @@ You can set environment variables to set various build options (Done best by pre
37 </ul> 37 </ul>
38 38
39 \section sec_firmware Installation of the firmware 39 \section sec_firmware Installation of the firmware
40 -\subsection ssec_drivers Gettings the Windows drivers 40 +\subsection ssec_drivers Getting 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%2Fdownload.html">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 \subsection ssec_dsoextractfw The firmware extraction tool 42 \subsection ssec_dsoextractfw The firmware extraction tool
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: 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:
openhantek/src/hantek/control.cpp
@@ -262,34 +262,15 @@ namespace Hantek { @@ -262,34 +262,15 @@ namespace Hantek {
262 /// \brief Calculates the trigger point from the CommandGetCaptureState data. 262 /// \brief Calculates the trigger point from the CommandGetCaptureState data.
263 /// \param value The data value that contains the trigger point. 263 /// \param value The data value that contains the trigger point.
264 /// \return The calculated trigger point for the given data. 264 /// \return The calculated trigger point for the given data.
265 - unsigned int Control::calculateTriggerPoint(unsigned int value) {  
266 - unsigned int min = value;  
267 - unsigned int max = 1;  
268 - while(min > 0) {  
269 - min >>= 1;  
270 - max <<= 1;  
271 - }  
272 - max--;  
273 -  
274 - unsigned check = 0;  
275 - unsigned lastLowCheck = 0;  
276 - bool tooHigh = true;  
277 -  
278 - while(max > min) {  
279 - check = (max - min + 1) / 2 + lastLowCheck;  
280 -  
281 - bool higher = check > value;  
282 - if(!higher)  
283 - lastLowCheck = check;  
284 -  
285 - tooHigh = higher == tooHigh;  
286 - if(tooHigh)  
287 - max = (max + min - 1) / 2;  
288 - else  
289 - min = (max + min + 1) / 2;  
290 - }  
291 -  
292 - return min; 265 + unsigned short int Control::calculateTriggerPoint(unsigned short int value) {
  266 + unsigned short int result = value;
  267 +
  268 + // Each set bit inverts all bits with a lower value
  269 + for(unsigned short int bitValue = 1; bitValue; bitValue <<= 1)
  270 + if(result & bitValue)
  271 + result ^= bitValue - 1;
  272 +
  273 + return result;
293 } 274 }
294 275
295 /// \brief Gets the current state. 276 /// \brief Gets the current state.
@@ -324,9 +305,9 @@ namespace Hantek { @@ -324,9 +305,9 @@ namespace Hantek {
324 // Save raw data to temporary buffer 305 // Save raw data to temporary buffer
325 unsigned int dataCount = this->bufferSize * HANTEK_CHANNELS; 306 unsigned int dataCount = this->bufferSize * HANTEK_CHANNELS;
326 unsigned int dataLength = dataCount; 307 unsigned int dataLength = dataCount;
327 - bool using9Bits = false; 308 + bool using10Bits = false;
328 if(this->device->getModel() == MODEL_DSO5200 || this->device->getModel() == MODEL_DSO5200A) { 309 if(this->device->getModel() == MODEL_DSO5200 || this->device->getModel() == MODEL_DSO5200A) {
329 - using9Bits = true; 310 + using10Bits = true;
330 dataLength *= 2; 311 dataLength *= 2;
331 } 312 }
332 313
@@ -339,23 +320,33 @@ namespace Hantek { @@ -339,23 +320,33 @@ namespace Hantek {
339 if(process) { 320 if(process) {
340 // How much data did we really receive? 321 // How much data did we really receive?
341 dataLength = errorCode; 322 dataLength = errorCode;
342 - if(using9Bits) 323 + if(using10Bits)
343 dataCount = dataLength / 2; 324 dataCount = dataLength / 2;
344 else 325 else
345 dataCount = dataLength; 326 dataCount = dataLength;
346 327
347 this->samplesMutex.lock(); 328 this->samplesMutex.lock();
348 329
  330 + // Get oscilloscope settings
  331 + bool fastRate;
  332 + UsedChannels usedChannels;
  333 + if(this->commandVersion == 0) {
  334 + fastRate = ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->getFastRate();
  335 + usedChannels = (UsedChannels) ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->getUsedChannels();
  336 + }
  337 + else {
  338 + fastRate = ((CommandSetTrigger5200 *) this->command[COMMAND_SETTRIGGER5200])->getFastRate();
  339 + usedChannels = (UsedChannels) ((CommandSetTrigger5200 *) this->command[COMMAND_SETTRIGGER5200])->getUsedChannels();
  340 + }
349 // Convert channel data 341 // Convert channel data
350 - if(((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->getFastRate()) { 342 + if(fastRate) {
351 // Fast rate mode, one channel is using all buffers 343 // Fast rate mode, one channel is using all buffers
352 int channel; 344 int channel;
353 - if(((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->getUsedChannels() == USED_CH1) 345 + if(usedChannels == USED_CH1)
354 channel = 0; 346 channel = 0;
355 else 347 else
356 channel = 1; 348 channel = 1;
357 349
358 -  
359 // Clear unused channels 350 // Clear unused channels
360 for(int channelCounter = 0; channelCounter < HANTEK_CHANNELS; channelCounter++) 351 for(int channelCounter = 0; channelCounter < HANTEK_CHANNELS; channelCounter++)
361 if(channelCounter != channel && this->samples[channelCounter]) { 352 if(channelCounter != channel && this->samples[channelCounter]) {
@@ -374,14 +365,18 @@ namespace Hantek { @@ -374,14 +365,18 @@ namespace Hantek {
374 } 365 }
375 366
376 // Convert data from the oscilloscope and write it into the sample buffer 367 // Convert data from the oscilloscope and write it into the sample buffer
377 - unsigned int bufferPosition = this->triggerPoint;  
378 - if(using9Bits) {  
379 - // Additional MSBs after the normal data 368 + unsigned int bufferPosition = this->triggerPoint * 2;
  369 + if(using10Bits) {
  370 + // Additional 2 most significant bits after the normal data
  371 + unsigned int extraBitsPosition; // Track the position of the extra bits in the additional byte
  372 +
380 for(unsigned int realPosition = 0; realPosition < dataCount; realPosition++, bufferPosition++) { 373 for(unsigned int realPosition = 0; realPosition < dataCount; realPosition++, bufferPosition++) {
381 if(bufferPosition >= dataCount) 374 if(bufferPosition >= dataCount)
382 bufferPosition %= dataCount; 375 bufferPosition %= dataCount;
383 376
384 - this->samples[channel][realPosition] = ((double) ((unsigned short int) data[bufferPosition] + ((unsigned short int) data[dataCount + bufferPosition] << 8)) / 0x1ff - this->offsetReal[channel]) * this->gainSteps[this->gain[channel]]; 377 + extraBitsPosition = bufferPosition % HANTEK_CHANNELS;
  378 +
  379 + this->samples[channel][realPosition] = ((double) ((unsigned short int) data[bufferPosition] + (((unsigned short int) data[dataCount + bufferPosition - extraBitsPosition] << (8 - (HANTEK_CHANNELS - 1 - extraBitsPosition) * 2)) & 0x0200)) / this->sampleRange[HANTEK_CHANNELS - 1 - extraBitsPosition] - this->offsetReal[channel]) * this->gainSteps[this->gain[channel]];
385 } 380 }
386 } 381 }
387 else { 382 else {
@@ -389,15 +384,15 @@ namespace Hantek { @@ -389,15 +384,15 @@ namespace Hantek {
389 if(bufferPosition >= dataCount) 384 if(bufferPosition >= dataCount)
390 bufferPosition %= dataCount; 385 bufferPosition %= dataCount;
391 386
392 - this->samples[channel][realPosition] = ((double) data[bufferPosition] / 0xff - this->offsetReal[channel]) * this->gainSteps[this->gain[channel]]; 387 + this->samples[channel][realPosition] = ((double) data[bufferPosition] / this->sampleRange[channel] - this->offsetReal[channel]) * this->gainSteps[this->gain[channel]];
393 } 388 }
394 } 389 }
395 } 390 }
396 } 391 }
397 else { 392 else {
398 - // Normal mode, channel are using their separate buffers 393 + // Normal mode, channels are using their separate buffers
399 unsigned int channelDataCount = dataCount / HANTEK_CHANNELS; 394 unsigned int channelDataCount = dataCount / HANTEK_CHANNELS;
400 - unsigned char usedChannels = ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->getUsedChannels(); 395 +
401 for(int channel = 0; channel < HANTEK_CHANNELS; channel++) { 396 for(int channel = 0; channel < HANTEK_CHANNELS; channel++) {
402 if(usedChannels == USED_CH1CH2 || channel == usedChannels) { 397 if(usedChannels == USED_CH1CH2 || channel == usedChannels) {
403 // Reallocate memory for samples if the sample count has changed 398 // Reallocate memory for samples if the sample count has changed
@@ -410,13 +405,13 @@ namespace Hantek { @@ -410,13 +405,13 @@ namespace Hantek {
410 405
411 // Convert data from the oscilloscope and write it into the sample buffer 406 // Convert data from the oscilloscope and write it into the sample buffer
412 unsigned int bufferPosition = this->triggerPoint * 2; 407 unsigned int bufferPosition = this->triggerPoint * 2;
413 - if(using9Bits) {  
414 - // Additional MSBs after the normal data 408 + if(using10Bits) {
  409 + // Additional 2 most significant bits after the normal data
415 for(unsigned int realPosition = 0; realPosition < channelDataCount; realPosition++, bufferPosition += 2) { 410 for(unsigned int realPosition = 0; realPosition < channelDataCount; realPosition++, bufferPosition += 2) {
416 if(bufferPosition >= dataCount) 411 if(bufferPosition >= dataCount)
417 bufferPosition %= dataCount; 412 bufferPosition %= dataCount;
418 413
419 - this->samples[channel][realPosition] = ((double) ((unsigned short int) data[bufferPosition + HANTEK_CHANNELS - 1 - channel] + ((unsigned short int) data[dataCount + bufferPosition + HANTEK_CHANNELS - 1 - channel] << 8)) / 0x1ff - this->offsetReal[channel]) * this->gainSteps[this->gain[channel]]; 414 + this->samples[channel][realPosition] = ((double) ((unsigned short int) data[bufferPosition + HANTEK_CHANNELS - 1 - channel] + (((unsigned short int) data[dataCount + bufferPosition] << (8 - channel * 2)) & 0x0200)) / this->sampleRange[channel] - this->offsetReal[channel]) * this->gainSteps[this->gain[channel]];
420 } 415 }
421 } 416 }
422 else { 417 else {
@@ -424,7 +419,7 @@ namespace Hantek { @@ -424,7 +419,7 @@ namespace Hantek {
424 if(bufferPosition >= dataCount) 419 if(bufferPosition >= dataCount)
425 bufferPosition %= dataCount; 420 bufferPosition %= dataCount;
426 421
427 - this->samples[channel][realPosition] = ((double) data[bufferPosition + HANTEK_CHANNELS - 1 - channel] / 0xff - this->offsetReal[channel]) * this->gainSteps[this->gain[channel]]; 422 + this->samples[channel][realPosition] = ((double) data[bufferPosition + HANTEK_CHANNELS - 1 - channel] / this->sampleRange[channel] - this->offsetReal[channel]) * this->gainSteps[this->gain[channel]];
428 } 423 }
429 } 424 }
430 } 425 }
@@ -544,7 +539,7 @@ namespace Hantek { @@ -544,7 +539,7 @@ namespace Hantek {
544 break; 539 break;
545 540
546 default: 541 default:
547 - this->samplerateChannelMax = 125e6; 542 + this->samplerateChannelMax = 100e6;
548 this->samplerateFastMax = 250e6; 543 this->samplerateFastMax = 250e6;
549 break; 544 break;
550 } 545 }
@@ -594,7 +589,7 @@ namespace Hantek { @@ -594,7 +589,7 @@ namespace Hantek {
594 // Calculate with fast rate first if only one channel is used 589 // Calculate with fast rate first if only one channel is used
595 bool fastRate = false; 590 bool fastRate = false;
596 this->samplerateMax = this->samplerateChannelMax; 591 this->samplerateMax = this->samplerateChannelMax;
597 - if((this->commandVersion == 0) ? (commandSetTriggerAndSamplerate->getUsedChannels() != USED_CH1CH2) : (commandSetTrigger5200->getUsedChannels() != EUSED_CH1CH2)) { 592 + if(((this->commandVersion == 0) ? commandSetTriggerAndSamplerate->getUsedChannels() : commandSetTrigger5200->getUsedChannels()) != USED_CH1CH2) {
598 fastRate = true; 593 fastRate = true;
599 this->samplerateMax = this->samplerateFastMax; 594 this->samplerateMax = this->samplerateFastMax;
600 } 595 }
@@ -661,6 +656,7 @@ namespace Hantek { @@ -661,6 +656,7 @@ namespace Hantek {
661 } 656 }
662 657
663 this->updateBufferSize(this->bufferSize); 658 this->updateBufferSize(this->bufferSize);
  659 + this->setTriggerPosition(this->triggerPosition);
664 this->setTriggerSlope(this->triggerSlope); 660 this->setTriggerSlope(this->triggerSlope);
665 return this->samplerateMax / this->samplerateDivider; 661 return this->samplerateMax / this->samplerateDivider;
666 } 662 }
@@ -681,28 +677,23 @@ namespace Hantek { @@ -681,28 +677,23 @@ namespace Hantek {
681 commandSetFilter->setChannel(channel, !used); 677 commandSetFilter->setChannel(channel, !used);
682 this->commandPending[COMMAND_SETFILTER] = true; 678 this->commandPending[COMMAND_SETFILTER] = true;
683 679
  680 + unsigned char usedChannels = USED_CH1;
  681 + if(!commandSetFilter->getChannel(1)) {
  682 + if(commandSetFilter->getChannel(0))
  683 + usedChannels = USED_CH2;
  684 + else
  685 + usedChannels = USED_CH1CH2;
  686 + }
  687 +
684 switch(this->commandVersion) { 688 switch(this->commandVersion) {
685 case 0: { 689 case 0: {
686 // SetTriggerAndSamplerate bulk command for trigger source 690 // SetTriggerAndSamplerate bulk command for trigger source
687 - unsigned char usedChannels = USED_CH1;  
688 - if(!commandSetFilter->getChannel(1)) {  
689 - if(commandSetFilter->getChannel(0))  
690 - usedChannels = USED_CH2;  
691 - else  
692 - usedChannels = USED_CH1CH2;  
693 - }  
694 ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->setUsedChannels(usedChannels); 691 ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->setUsedChannels(usedChannels);
695 this->commandPending[COMMAND_SETTRIGGERANDSAMPLERATE] = true; 692 this->commandPending[COMMAND_SETTRIGGERANDSAMPLERATE] = true;
696 break; 693 break;
697 } 694 }
698 case 1: { 695 case 1: {
699 - unsigned char usedChannels = EUSED_CH1;  
700 - if(!commandSetFilter->getChannel(1)) {  
701 - if(commandSetFilter->getChannel(0))  
702 - usedChannels = EUSED_CH2;  
703 - else  
704 - usedChannels = EUSED_CH1CH2;  
705 - } 696 + // SetTrigger5200s bulk command for trigger source
706 ((CommandSetTrigger5200 *) this->command[COMMAND_SETTRIGGER5200])->setUsedChannels(usedChannels); 697 ((CommandSetTrigger5200 *) this->command[COMMAND_SETTRIGGER5200])->setUsedChannels(usedChannels);
707 this->commandPending[COMMAND_SETTRIGGER5200] = true; 698 this->commandPending[COMMAND_SETTRIGGER5200] = true;
708 break; 699 break;
@@ -747,14 +738,54 @@ namespace Hantek { @@ -747,14 +738,54 @@ namespace Hantek {
747 if(this->gainSteps[gainId] >= gain) 738 if(this->gainSteps[gainId] >= gain)
748 break; 739 break;
749 740
  741 + // Get the voltage scaler id and it's sample range for this gain
  742 + int scalerId;
  743 + switch(this->commandVersion) {
  744 + case 0:
  745 + scalerId = gainId % 3;
  746 + this->sampleRange[channel] = 0xff;
  747 + break;
  748 + case 1:
  749 + /// \todo Use calibration data to get the DSO-5200 sample ranges
  750 + if(gainId == GAIN_10MV) {
  751 + scalerId = 1;
  752 + this->sampleRange[channel] = 184;
  753 + }
  754 + else {
  755 + switch(gainId % 3) {
  756 + case 1:
  757 + scalerId = 1;
  758 + this->sampleRange[channel] = 368;
  759 + break;
  760 + case 2:
  761 + scalerId = 0;
  762 + this->sampleRange[channel] = 454;
  763 + break;
  764 + default:
  765 + scalerId = 0;
  766 + this->sampleRange[channel] = 908;
  767 + break;
  768 + }
  769 + }
  770 + break;
  771 + }
  772 +
750 // SetGain bulk command for gain 773 // SetGain bulk command for gain
751 - ((CommandSetGain *) this->command[COMMAND_SETGAIN])->setGain(channel, gainId % 3); 774 + ((CommandSetGain *) this->command[COMMAND_SETGAIN])->setGain(channel, scalerId);
752 this->commandPending[COMMAND_SETGAIN] = true; 775 this->commandPending[COMMAND_SETGAIN] = true;
753 776
754 // SetRelays control command for gain relays 777 // SetRelays control command for gain relays
755 ControlSetRelays *controlSetRelays = (ControlSetRelays *) this->control[CONTROLINDEX_SETRELAYS]; 778 ControlSetRelays *controlSetRelays = (ControlSetRelays *) this->control[CONTROLINDEX_SETRELAYS];
756 - controlSetRelays->setBelow1V(channel, gainId < GAIN_1V);  
757 - controlSetRelays->setBelow100mV(channel, gainId < GAIN_100MV); 779 + switch(this->commandVersion) {
  780 + case 0:
  781 + controlSetRelays->setBelow1V(channel, gainId < GAIN_1V);
  782 + controlSetRelays->setBelow100mV(channel, gainId < GAIN_100MV);
  783 + break;
  784 + case 1:
  785 + controlSetRelays->setBelow1V(channel, gainId <= GAIN_1V);
  786 + controlSetRelays->setBelow100mV(channel, gainId <= GAIN_100MV);
  787 + break;
  788 + }
758 this->controlPending[CONTROLINDEX_SETRELAYS] = true; 789 this->controlPending[CONTROLINDEX_SETRELAYS] = true;
759 790
760 this->gain[channel] = (Gain) gainId; 791 this->gain[channel] = (Gain) gainId;
@@ -775,9 +806,10 @@ namespace Hantek { @@ -775,9 +806,10 @@ namespace Hantek {
775 if(channel >= HANTEK_CHANNELS) 806 if(channel >= HANTEK_CHANNELS)
776 return -1; 807 return -1;
777 808
778 - // Calculate the offset value (The range is given by the calibration data)  
779 - unsigned short int minimum = this->channelLevels[channel][this->gain[channel]][OFFSET_START] >> 8;  
780 - unsigned short int maximum = this->channelLevels[channel][this->gain[channel]][OFFSET_END] >> 8; 809 + // Calculate the offset value
  810 + // The range is given by the calibration data (convert from big endian)
  811 + unsigned short int minimum = ((unsigned short int) *((unsigned char *) &(this->channelLevels[channel][this->gain[channel]][OFFSET_START])) << 8) + *((unsigned char *) &(this->channelLevels[channel][this->gain[channel]][OFFSET_START]) + 1);
  812 + unsigned short int maximum = ((unsigned short int) *((unsigned char *) &(this->channelLevels[channel][this->gain[channel]][OFFSET_START])) << 8) + *((unsigned char *) &(this->channelLevels[channel][this->gain[channel]][OFFSET_END]) + 1);
781 unsigned short int offsetValue = offset * (maximum - minimum) + minimum + 0.5; 813 unsigned short int offsetValue = offset * (maximum - minimum) + minimum + 0.5;
782 double offsetReal = (double) (offsetValue - minimum) / (maximum - minimum); 814 double offsetReal = (double) (offsetValue - minimum) / (maximum - minimum);
783 815
@@ -868,9 +900,26 @@ namespace Hantek { @@ -868,9 +900,26 @@ namespace Hantek {
868 if(channel >= HANTEK_CHANNELS) 900 if(channel >= HANTEK_CHANNELS)
869 return -1.0; 901 return -1.0;
870 902
871 - // Calculate the trigger level value (0x00 - 0xfe)  
872 - unsigned short int levelValue = (this->offsetReal[channel] + level / this->gainSteps[this->gain[channel]]) * 0xfe + 0.5; 903 + // Calculate the trigger level value
  904 + unsigned short int minimum, maximum;
  905 + switch(this->commandVersion) {
  906 + case 0:
  907 + // It's from 0x00 to 0xfd for the 8 bit models
  908 + minimum = 0x00;
  909 + maximum = 0xfd;
  910 + break;
  911 +
  912 + case 1:
  913 + // The range is the same as used for the offsets for 10 bit models
  914 + minimum = ((unsigned short int) *((unsigned char *) &(this->channelLevels[channel][this->gain[channel]][OFFSET_START])) << 8) + *((unsigned char *) &(this->channelLevels[channel][this->gain[channel]][OFFSET_START]) + 1);
  915 + maximum = ((unsigned short int) *((unsigned char *) &(this->channelLevels[channel][this->gain[channel]][OFFSET_START])) << 8) + *((unsigned char *) &(this->channelLevels[channel][this->gain[channel]][OFFSET_END]) + 1);
  916 + break;
  917 + }
  918 +
  919 + // Never get out of the limits
  920 + unsigned short int levelValue = qBound((long int) minimum, (long int) ((this->offsetReal[channel] + level / this->gainSteps[this->gain[channel]]) * (maximum - minimum) + 0.5) + minimum, (long int) maximum);
873 921
  922 + // Check if the set channel is the trigger source
874 if(!this->triggerSpecial && channel == this->triggerSource) { 923 if(!this->triggerSpecial && channel == this->triggerSource) {
875 // SetOffset control command for trigger level 924 // SetOffset control command for trigger level
876 ((ControlSetOffset *) this->control[CONTROLINDEX_SETOFFSET])->setTrigger(levelValue); 925 ((ControlSetOffset *) this->control[CONTROLINDEX_SETOFFSET])->setTrigger(levelValue);
@@ -880,7 +929,7 @@ namespace Hantek { @@ -880,7 +929,7 @@ namespace Hantek {
880 /// \todo Get alternating trigger in here 929 /// \todo Get alternating trigger in here
881 930
882 this->triggerLevel[channel] = level; 931 this->triggerLevel[channel] = level;
883 - return (double) (levelValue / 0xfe - this->offsetReal[channel]) * this->gainSteps[this->gain[channel]]; 932 + return (double) ((levelValue - minimum) / (maximum - minimum) - this->offsetReal[channel]) * this->gainSteps[this->gain[channel]];
884 } 933 }
885 934
886 /// \brief Set the trigger slope. 935 /// \brief Set the trigger slope.
@@ -921,11 +970,15 @@ namespace Hantek { @@ -921,11 +970,15 @@ namespace Hantek {
921 if(!this->device->isConnected()) 970 if(!this->device->isConnected())
922 return -2; 971 return -2;
923 972
924 - // All trigger position are measured in samples 973 + // All trigger positions are measured in samples
925 unsigned long int positionSamples = position * this->samplerateMax / this->samplerateDivider; 974 unsigned long int positionSamples = position * this->samplerateMax / this->samplerateDivider;
926 975
927 switch(this->commandVersion) { 976 switch(this->commandVersion) {
928 case 0: { 977 case 0: {
  978 + // Fast rate mode uses both channels
  979 + if(((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->getFastRate())
  980 + positionSamples /= HANTEK_CHANNELS;
  981 +
929 // Calculate the position value (Start point depending on buffer size) 982 // Calculate the position value (Start point depending on buffer size)
930 unsigned long int positionStart = (this->bufferSize == BUFFER_SMALL) ? 0x77660 : 0x78000; 983 unsigned long int positionStart = (this->bufferSize == BUFFER_SMALL) ? 0x77660 : 0x78000;
931 984
@@ -936,6 +989,10 @@ namespace Hantek { @@ -936,6 +989,10 @@ namespace Hantek {
936 break; 989 break;
937 } 990 }
938 case 1: { 991 case 1: {
  992 + // Fast rate mode uses both channels
  993 + if(((CommandSetTrigger5200 *) this->command[COMMAND_SETTRIGGER5200])->getFastRate())
  994 + positionSamples /= HANTEK_CHANNELS;
  995 +
939 // Calculate the position values (Inverse, maximum is 0xffff) 996 // Calculate the position values (Inverse, maximum is 0xffff)
940 unsigned short int positionPre = 0xffff - this->bufferSize + positionSamples; 997 unsigned short int positionPre = 0xffff - this->bufferSize + positionSamples;
941 unsigned short int positionPost = 0xffff - positionSamples; 998 unsigned short int positionPost = 0xffff - positionSamples;
openhantek/src/hantek/control.h
@@ -67,7 +67,7 @@ namespace Hantek { @@ -67,7 +67,7 @@ namespace Hantek {
67 protected: 67 protected:
68 void run(); 68 void run();
69 69
70 - unsigned int calculateTriggerPoint(unsigned int value); 70 + unsigned short int calculateTriggerPoint(unsigned short int value);
71 int getCaptureState(); 71 int getCaptureState();
72 int getSamples(bool process); 72 int getSamples(bool process);
73 unsigned long int updateBufferSize(unsigned long int size); 73 unsigned long int updateBufferSize(unsigned long int size);
@@ -91,6 +91,7 @@ namespace Hantek { @@ -91,6 +91,7 @@ namespace Hantek {
91 unsigned long int samplerateChannelMax; ///< The maximum sample rate for a single channel 91 unsigned long int samplerateChannelMax; ///< The maximum sample rate for a single channel
92 unsigned long int samplerateFastMax; ///< The maximum sample rate for fast rate mode 92 unsigned long int samplerateFastMax; ///< The maximum sample rate for fast rate mode
93 Gain gain[HANTEK_CHANNELS]; ///< The gain id 93 Gain gain[HANTEK_CHANNELS]; ///< The gain id
  94 + unsigned short int sampleRange[HANTEK_CHANNELS]; ///< The sample values at the top of the screen
94 double offset[HANTEK_CHANNELS]; ///< The current screen offset for each channel 95 double offset[HANTEK_CHANNELS]; ///< The current screen offset for each channel
95 double offsetReal[HANTEK_CHANNELS]; ///< The real offset for each channel (Due to quantization) 96 double offsetReal[HANTEK_CHANNELS]; ///< The real offset for each channel (Due to quantization)
96 double triggerLevel[HANTEK_CHANNELS]; ///< The trigger level for each channel in V 97 double triggerLevel[HANTEK_CHANNELS]; ///< The trigger level for each channel in V
openhantek/src/hantek/types.cpp
@@ -437,9 +437,9 @@ namespace Hantek { @@ -437,9 +437,9 @@ namespace Hantek {
437 /// \return The channel offset value. 437 /// \return The channel offset value.
438 unsigned short int ControlSetOffset::getChannel(unsigned int channel) { 438 unsigned short int ControlSetOffset::getChannel(unsigned int channel) {
439 if(channel == 0) 439 if(channel == 0)
440 - return ((this->array[0] & 0xdf) << 8) | this->array[1]; 440 + return ((this->array[0] & 0x0f) << 8) | this->array[1];
441 else 441 else
442 - return ((this->array[2] & 0xdf) << 8) | this->array[3]; 442 + return ((this->array[2] & 0x0f) << 8) | this->array[3];
443 } 443 }
444 444
445 /// \brief Set the offset for the given channel. 445 /// \brief Set the offset for the given channel.
@@ -447,11 +447,11 @@ namespace Hantek { @@ -447,11 +447,11 @@ namespace Hantek {
447 /// \param offset The new channel offset value. 447 /// \param offset The new channel offset value.
448 void ControlSetOffset::setChannel(unsigned int channel, unsigned short int offset) { 448 void ControlSetOffset::setChannel(unsigned int channel, unsigned short int offset) {
449 if(channel == 0) { 449 if(channel == 0) {
450 - this->array[0] = (unsigned char) (offset >> 8) | 0x20; 450 + this->array[0] = (unsigned char) (offset >> 8);
451 this->array[1] = (unsigned char) offset; 451 this->array[1] = (unsigned char) offset;
452 } 452 }
453 else { 453 else {
454 - this->array[2] = (unsigned char) (offset >> 8) | 0x20; 454 + this->array[2] = (unsigned char) (offset >> 8);
455 this->array[3] = (unsigned char) offset; 455 this->array[3] = (unsigned char) offset;
456 } 456 }
457 } 457 }
@@ -459,13 +459,13 @@ namespace Hantek { @@ -459,13 +459,13 @@ namespace Hantek {
459 /// \brief Get the trigger level. 459 /// \brief Get the trigger level.
460 /// \return The trigger level value. 460 /// \return The trigger level value.
461 unsigned short int ControlSetOffset::getTrigger() { 461 unsigned short int ControlSetOffset::getTrigger() {
462 - return ((this->array[4] & 0xdf) << 8) | this->array[5]; 462 + return ((this->array[4] & 0x0f) << 8) | this->array[5];
463 } 463 }
464 464
465 /// \brief Set the trigger level. 465 /// \brief Set the trigger level.
466 /// \param level The new trigger level value. 466 /// \param level The new trigger level value.
467 void ControlSetOffset::setTrigger(unsigned short int level) { 467 void ControlSetOffset::setTrigger(unsigned short int level) {
468 - this->array[4] = (unsigned char) (level >> 8) | 0x20; 468 + this->array[4] = (unsigned char) (level >> 8);
469 this->array[5] = (unsigned char) level; 469 this->array[5] = (unsigned char) level;
470 } 470 }
471 471
@@ -707,7 +707,7 @@ namespace Hantek { @@ -707,7 +707,7 @@ namespace Hantek {
707 ////////////////////////////////////////////////////////////////////////////// 707 //////////////////////////////////////////////////////////////////////////////
708 // class CommandSetTrigger5200 708 // class CommandSetTrigger5200
709 /// \brief Sets the data array to the default values. 709 /// \brief Sets the data array to the default values.
710 - CommandSetTrigger5200::CommandSetTrigger5200() : Helper::DataArray<unsigned char>(10) { 710 + CommandSetTrigger5200::CommandSetTrigger5200() : Helper::DataArray<unsigned char>(8) {
711 this->init(); 711 this->init();
712 } 712 }
713 713
@@ -740,13 +740,13 @@ namespace Hantek { @@ -740,13 +740,13 @@ namespace Hantek {
740 } 740 }
741 741
742 /// \brief Get the usedChannels value in ETsrBits. 742 /// \brief Get the usedChannels value in ETsrBits.
743 - /// \return The #EUsedChannels value. 743 + /// \return The #UsedChannels value.
744 unsigned char CommandSetTrigger5200::getUsedChannels() { 744 unsigned char CommandSetTrigger5200::getUsedChannels() {
745 return ((ETsrBits *) &(this->array[2]))->usedChannels; 745 return ((ETsrBits *) &(this->array[2]))->usedChannels;
746 } 746 }
747 747
748 /// \brief Set the usedChannels in ETsrBits to the given value. 748 /// \brief Set the usedChannels in ETsrBits to the given value.
749 - /// \param value The new #EUsedChannels value. 749 + /// \param value The new #UsedChannels value.
750 void CommandSetTrigger5200::setUsedChannels(unsigned char value) { 750 void CommandSetTrigger5200::setUsedChannels(unsigned char value) {
751 ((ETsrBits *) &(this->array[2]))->usedChannels = value; 751 ((ETsrBits *) &(this->array[2]))->usedChannels = value;
752 } 752 }
openhantek/src/hantek/types.h
@@ -286,7 +286,7 @@ namespace Hantek { @@ -286,7 +286,7 @@ namespace Hantek {
286 /// <p> 286 /// <p>
287 /// The values are similar to the ones used on the DSO-2090. The formula is a bit different here:<br /> 287 /// The values are similar to the ones used on the DSO-2090. The formula is a bit different here:<br />
288 /// <i>Samplerate = SamplerateMax / (2comp(SamplerateSlow) * 2 + 4 - SamplerateFast)</i><br /> 288 /// <i>Samplerate = SamplerateMax / (2comp(SamplerateSlow) * 2 + 4 - SamplerateFast)</i><br />
289 - /// SamplerateMax is 125 MHz for the DSO-5200 in default configuration though, the modifications regarding fast rate and buffer size are the the same that apply for the DSO-2090. 289 + /// SamplerateMax is 100 MS/s for the DSO-5200 in default configuration and 250 MS/s in fast rate mode though, the modifications regarding buffer size are the the same that apply for the DSO-2090.
290 /// </p> 290 /// </p>
291 COMMAND_SETSAMPLERATE5200, 291 COMMAND_SETSAMPLERATE5200,
292 292
@@ -340,101 +340,114 @@ namespace Hantek { @@ -340,101 +340,114 @@ namespace Hantek {
340 /// \enum ControlCode hantek/types.h 340 /// \enum ControlCode hantek/types.h
341 /// \brief All supported control commands. 341 /// \brief All supported control commands.
342 enum ControlCode { 342 enum ControlCode {
343 - /// The 0xa2 control read/write command gives access to a #ControlValue. 343 + /// <p>
  344 + /// The 0xa2 control read/write command gives access to a #ControlValue.
  345 + /// </p>
344 CONTROL_VALUE = 0xa2, 346 CONTROL_VALUE = 0xa2,
345 347
346 - /// The 0xb2 control read command gets the speed level of the USB connection:  
347 - /// <table>  
348 - /// <tr>  
349 - /// <td>#ConnectionSpeed</td>  
350 - /// <td>0x00</td>  
351 - /// <td>0x00</td>  
352 - /// <td>0x00</td>  
353 - /// <td>0x00</td>  
354 - /// <td>0x00</td>  
355 - /// <td>0x00</td>  
356 - /// <td>0x00</td>  
357 - /// <td>0x00</td>  
358 - /// <td>0x00</td>  
359 - /// </tr>  
360 - /// </table> 348 + /// <p>
  349 + /// The 0xb2 control read command gets the speed level of the USB connection:
  350 + /// <table>
  351 + /// <tr>
  352 + /// <td>#ConnectionSpeed</td>
  353 + /// <td>0x00</td>
  354 + /// <td>0x00</td>
  355 + /// <td>0x00</td>
  356 + /// <td>0x00</td>
  357 + /// <td>0x00</td>
  358 + /// <td>0x00</td>
  359 + /// <td>0x00</td>
  360 + /// <td>0x00</td>
  361 + /// <td>0x00</td>
  362 + /// </tr>
  363 + /// </table>
  364 + /// </p>
361 CONTROL_GETSPEED = 0xb2, 365 CONTROL_GETSPEED = 0xb2,
362 366
363 - /// The 0xb3 control write command is sent before any bulk command:  
364 - /// <table>  
365 - /// <tr>  
366 - /// <td>0x0f</td>  
367 - /// <td>#CommandIndex</td>  
368 - /// <td>#CommandIndex</td>  
369 - /// <td>#CommandIndex</td>  
370 - /// <td>0x00</td>  
371 - /// <td>0x00</td>  
372 - /// <td>0x00</td>  
373 - /// <td>0x00</td>  
374 - /// <td>0x00</td>  
375 - /// <td>0x00</td>  
376 - /// </tr>  
377 - /// </table> 367 + /// <p>
  368 + /// The 0xb3 control write command is sent before any bulk command:
  369 + /// <table>
  370 + /// <tr>
  371 + /// <td>0x0f</td>
  372 + /// <td>#CommandIndex</td>
  373 + /// <td>#CommandIndex</td>
  374 + /// <td>#CommandIndex</td>
  375 + /// <td>0x00</td>
  376 + /// <td>0x00</td>
  377 + /// <td>0x00</td>
  378 + /// <td>0x00</td>
  379 + /// <td>0x00</td>
  380 + /// <td>0x00</td>
  381 + /// </tr>
  382 + /// </table>
  383 + /// </p>
378 CONTROL_BEGINCOMMAND = 0xb3, 384 CONTROL_BEGINCOMMAND = 0xb3,
379 385
380 - /// The 0xb4 control write command sets the channel offsets:  
381 - /// <table>  
382 - /// <tr>  
383 - /// <td>Ch1Offset[1] | 0x20</td>  
384 - /// <td>Ch1Offset[0]</td>  
385 - /// <td>Ch2Offset[1] | 0x20</td>  
386 - /// <td>Ch2Offset[0]</td>  
387 - /// <td>TriggerOffset[1] | 0x20</td>  
388 - /// <td>TriggerOffset[0]</td>  
389 - /// </tr>  
390 - /// </table>  
391 - /// <table>  
392 - /// <tr>  
393 - /// <td>0x00</td>  
394 - /// <td>0x00</td>  
395 - /// <td>0x00</td>  
396 - /// <td>0x00</td>  
397 - /// <td>0x00</td>  
398 - /// <td>0x00</td>  
399 - /// <td>0x00</td>  
400 - /// <td>0x00</td>  
401 - /// <td>0x00</td>  
402 - /// <td>0x00</td>  
403 - /// <td>0x00</td>  
404 - /// </tr>  
405 - /// </table> 386 + /// <p>
  387 + /// The 0xb4 control write command sets the channel offsets:
  388 + /// <table>
  389 + /// <tr>
  390 + /// <td>Ch1Offset[1]</td>
  391 + /// <td>Ch1Offset[0]</td>
  392 + /// <td>Ch2Offset[1]</td>
  393 + /// <td>Ch2Offset[0]</td>
  394 + /// <td>TriggerOffset[1]</td>
  395 + /// <td>TriggerOffset[0]</td>
  396 + /// </tr>
  397 + /// </table>
  398 + /// <table>
  399 + /// <tr>
  400 + /// <td>0x00</td>
  401 + /// <td>0x00</td>
  402 + /// <td>0x00</td>
  403 + /// <td>0x00</td>
  404 + /// <td>0x00</td>
  405 + /// <td>0x00</td>
  406 + /// <td>0x00</td>
  407 + /// <td>0x00</td>
  408 + /// <td>0x00</td>
  409 + /// <td>0x00</td>
  410 + /// <td>0x00</td>
  411 + /// </tr>
  412 + /// </table>
  413 + /// </p>
406 CONTROL_SETOFFSET = 0xb4, 414 CONTROL_SETOFFSET = 0xb4,
407 415
408 - /// The 0xb5 control write command sets the internal relays:  
409 - /// <table>  
410 - /// <tr>  
411 - /// <td>0x00</td>  
412 - /// <td>0x04 ^ (Ch1Gain < 1 V)</td>  
413 - /// <td>0x08 ^ (Ch1Gain < 100 mV)</td>  
414 - /// <td>0x02 ^ (Ch1Coupling == DC)</td>  
415 - /// </tr>  
416 - /// </table>  
417 - /// <table>  
418 - /// <tr>  
419 - /// <td>0x20 ^ (Ch2Gain < 1 V)</td>  
420 - /// <td>0x40 ^ (Ch2Gain < 100 mV)</td>  
421 - /// <td>0x10 ^ (Ch2Coupling == DC)</td>  
422 - /// <td>0x01 ^ (Trigger == EXT)</td>  
423 - /// </tr>  
424 - /// </table>  
425 - /// <table>  
426 - /// <tr>  
427 - /// <td>0x00</td>  
428 - /// <td>0x00</td>  
429 - /// <td>0x00</td>  
430 - /// <td>0x00</td>  
431 - /// <td>0x00</td>  
432 - /// <td>0x00</td>  
433 - /// <td>0x00</td>  
434 - /// <td>0x00</td>  
435 - /// <td>0x00</td>  
436 - /// </tr>  
437 - /// </table> 416 + /// <p>
  417 + /// The 0xb5 control write command sets the internal relays:
  418 + /// <table>
  419 + /// <tr>
  420 + /// <td>0x00</td>
  421 + /// <td>0x04 ^ (Ch1Gain < 1 V)</td>
  422 + /// <td>0x08 ^ (Ch1Gain < 100 mV)</td>
  423 + /// <td>0x02 ^ (Ch1Coupling == DC)</td>
  424 + /// </tr>
  425 + /// </table>
  426 + /// <table>
  427 + /// <tr>
  428 + /// <td>0x20 ^ (Ch2Gain < 1 V)</td>
  429 + /// <td>0x40 ^ (Ch2Gain < 100 mV)</td>
  430 + /// <td>0x10 ^ (Ch2Coupling == DC)</td>
  431 + /// <td>0x01 ^ (Trigger == EXT)</td>
  432 + /// </tr>
  433 + /// </table>
  434 + /// <table>
  435 + /// <tr>
  436 + /// <td>0x00</td>
  437 + /// <td>0x00</td>
  438 + /// <td>0x00</td>
  439 + /// <td>0x00</td>
  440 + /// <td>0x00</td>
  441 + /// <td>0x00</td>
  442 + /// <td>0x00</td>
  443 + /// <td>0x00</td>
  444 + /// <td>0x00</td>
  445 + /// </tr>
  446 + /// </table>
  447 + /// </p>
  448 + /// <p>
  449 + /// The limits are <= instead of < for the 10 bit models, since those support voltages up to 10 V.
  450 + /// </p>
438 CONTROL_SETRELAYS = 0xb5 451 CONTROL_SETRELAYS = 0xb5
439 }; 452 };
440 453
@@ -572,14 +585,6 @@ namespace Hantek { @@ -572,14 +585,6 @@ namespace Hantek {
572 }; 585 };
573 586
574 ////////////////////////////////////////////////////////////////////////////// 587 //////////////////////////////////////////////////////////////////////////////
575 - /// \enum EUsedChannels hantek/types.h  
576 - /// \brief The enabled channels in command 0x0e.  
577 - enum EUsedChannels {  
578 - EUSED_CH1 = 2, EUSED_CH2 = 3,  
579 - EUSED_CH1CH2 = 0  
580 - };  
581 -  
582 - //////////////////////////////////////////////////////////////////////////////  
583 /// \struct FilterBits hantek/types.h 588 /// \struct FilterBits hantek/types.h
584 /// \brief The bits for COMMAND_SETFILTER. 589 /// \brief The bits for COMMAND_SETFILTER.
585 struct FilterBits { 590 struct FilterBits {
@@ -631,7 +636,7 @@ namespace Hantek { @@ -631,7 +636,7 @@ namespace Hantek {
631 /// \brief Trigger and samplerate bits for 0x0e command. 636 /// \brief Trigger and samplerate bits for 0x0e command.
632 struct ETsrBits { 637 struct ETsrBits {
633 unsigned char fastRate:1; ///< false, if one channels uses all buffers 638 unsigned char fastRate:1; ///< false, if one channels uses all buffers
634 - unsigned char usedChannels:2; ///< Used channels, see Hantek::EUsedChannels 639 + unsigned char usedChannels:2; ///< Used channels, see Hantek::UsedChannels
635 unsigned char triggerSource:2; ///< The trigger source, see Hantek::TriggerSource 640 unsigned char triggerSource:2; ///< The trigger source, see Hantek::TriggerSource
636 unsigned char triggerSlope:2; ///< The trigger slope, see Dso::Slope 641 unsigned char triggerSlope:2; ///< The trigger slope, see Dso::Slope
637 unsigned char triggerPulse:1; ///< Pulses are causing trigger events 642 unsigned char triggerPulse:1; ///< Pulses are causing trigger events
openhantek/src/openhantek.cpp
@@ -676,6 +676,9 @@ void OpenHantekMainWindow::updateOffset(unsigned int channel) { @@ -676,6 +676,9 @@ void OpenHantekMainWindow::updateOffset(unsigned int channel) {
676 void OpenHantekMainWindow::updateTimebase() { 676 void OpenHantekMainWindow::updateTimebase() {
677 this->settings->scope.horizontal.samplerate = this->dsoControl->setSamplerate(1e3 / this->settings->scope.horizontal.timebase); 677 this->settings->scope.horizontal.samplerate = this->dsoControl->setSamplerate(1e3 / this->settings->scope.horizontal.timebase);
678 this->dsoWidget->updateSamplerate(); 678 this->dsoWidget->updateSamplerate();
  679 +
  680 + // The trigger position should be kept at the same place but the timebase has changed
  681 + this->dsoControl->setTriggerPosition(this->settings->scope.trigger.position * this->settings->scope.horizontal.timebase * DIVS_TIME);
679 } 682 }
680 683
681 /// \brief Sets the state of the given oscilloscope channel. 684 /// \brief Sets the state of the given oscilloscope channel.