Commit 9c6b32e786599adc932880eba5406682c28d45f0

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

Move all control command structs back to controlstructs. Move control functional…

…ity from usb device into hantekdsocontrol. Remove fixed HANTEK_CHANNELS definitions. We allow an arbitray number of channels, depending on the device.
openhantek/src/hantekdso/controlsettings.cpp
1 1 #include "controlsettings.h"
  2 +#include "hantekprotocol/definitions.h"
2 3  
3 4 namespace Dso {
4 5  
... ... @@ -7,13 +8,12 @@ ControlSettings::ControlSettings(ControlSamplerateLimits* limits, size_t channel
7 8 samplerate.limits = limits;
8 9 trigger.level.resize(channelCount);
9 10 voltage.resize(channelCount);
10   - for (ChannelID channel = 0; channel < channelCount; ++channel) {
11   - trigger.level[channel] = 0.0;
12   - voltage[channel].gain = 0;
13   - voltage[channel].offset = 0.0;
14   - voltage[channel].offsetReal = 0.0;
15   - voltage[channel].used = false;
16   - }
  11 + offsetLimit = new Hantek::OffsetsPerGainStep[channelCount];
  12 +}
  13 +
  14 +ControlSettings::~ControlSettings()
  15 +{
  16 + delete [] offsetLimit;
17 17 }
18 18  
19 19 }
... ...
openhantek/src/hantekdso/controlsettings.h
1 1 #pragma once
2 2  
3   -#include "controlspecification.h"
4 3 #include "enums.h"
  4 +#include "hantekprotocol/types.h"
  5 +
  6 +namespace Hantek {
  7 +struct OffsetsPerGainStep;
  8 +}
5 9  
6 10 namespace Dso {
7 11  
8 12 struct ControlSamplerateLimits;
9 13  
10   -//////////////////////////////////////////////////////////////////////////////
11   -/// \struct ControlSettingsSamplerateTarget hantek/control.h
12 14 /// \brief Stores the target samplerate settings of the device.
13 15 struct ControlSettingsSamplerateTarget {
14 16 double samplerate; ///< The target samplerate set via setSamplerate
... ... @@ -16,8 +18,6 @@ struct ControlSettingsSamplerateTarget {
16 18 enum SamplerrateSet { Duration, Samplerrate } samplerateSet;
17 19 };
18 20  
19   -//////////////////////////////////////////////////////////////////////////////
20   -/// \struct ControlSettingsSamplerate hantek/control.h
21 21 /// \brief Stores the current samplerate settings of the device.
22 22 struct ControlSettingsSamplerate {
23 23 ControlSettingsSamplerateTarget target; ///< The target samplerate values
... ... @@ -26,39 +26,35 @@ struct ControlSettingsSamplerate {
26 26 double current = 1e8; ///< The current samplerate
27 27 };
28 28  
29   -//////////////////////////////////////////////////////////////////////////////
30   -/// \struct ControlSettingsTrigger hantek/control.h
31 29 /// \brief Stores the current trigger settings of the device.
32 30 struct ControlSettingsTrigger {
33   - std::vector<double> level; ///< The trigger level for each channel in V
34   - double position = 0.0; ///< The current pretrigger position
35   - unsigned int point = 0; ///< The trigger position in Hantek coding
  31 + std::vector<double> level; ///< The trigger level for each channel in V
  32 + double position = 0.0; ///< The current pretrigger position
  33 + unsigned int point = 0; ///< The trigger position in Hantek coding
36 34 Dso::TriggerMode mode = Dso::TriggerMode::HARDWARE_SOFTWARE; ///< The trigger mode
37   - Dso::Slope slope = Dso::Slope::Positive; ///< The trigger slope
38   - bool special = false; ///< true, if the trigger source is special
39   - unsigned int source = 0; ///< The trigger source
  35 + Dso::Slope slope = Dso::Slope::Positive; ///< The trigger slope
  36 + bool special = false; ///< true, if the trigger source is special
  37 + unsigned int source = 0; ///< The trigger source
40 38 };
41 39  
42   -//////////////////////////////////////////////////////////////////////////////
43   -/// \struct ControlSettingsVoltage hantek/control.h
44 40 /// \brief Stores the current amplification settings of the device.
45 41 struct ControlSettingsVoltage {
46   - double offset; ///< The screen offset for each channel
47   - double offsetReal; ///< The real offset for each channel (Due to quantization)
48   - unsigned gain; ///< The gain id
49   - bool used; ///< true, if the channel is used
  42 + double offset = 0.0; ///< The screen offset for each channel
  43 + double offsetReal = 0.0; ///< The real offset for each channel (Due to quantization)
  44 + unsigned gain = 0; ///< The gain id
  45 + bool used = false; ///< true, if the channel is used
50 46 };
51 47  
52   -//////////////////////////////////////////////////////////////////////////////
53   -/// \struct ControlSettings hantek/control.h
54 48 /// \brief Stores the current settings of the device.
55 49 struct ControlSettings {
56 50 ControlSettings(ControlSamplerateLimits *limits, size_t channelCount);
  51 + ~ControlSettings();
57 52 ControlSettingsSamplerate samplerate; ///< The samplerate settings
58 53 std::vector<ControlSettingsVoltage> voltage; ///< The amplification settings
59 54 ControlSettingsTrigger trigger; ///< The trigger settings
60 55 RecordLengthID recordLengthId = 1; ///< The id in the record length array
61 56 unsigned usedChannels = 0; ///< Number of activated channels
62 57 unsigned swSampleMargin = 2000; ///< Software trigger, sample margin
  58 + Hantek::OffsetsPerGainStep *offsetLimit; ///< Calibration data for the channel offsets
63 59 };
64 60 }
... ...
openhantek/src/hantekdso/controlspecification.cpp 0 → 100644
  1 +#include "controlspecification.h"
  2 +
  3 +Dso::ControlSpecification::ControlSpecification(unsigned channels) : channels(channels), cmdGetLimits(channels)
  4 +{
  5 + voltageLimit.resize(channels);
  6 +}
... ...
openhantek/src/hantekdso/controlspecification.h
... ... @@ -4,8 +4,7 @@
4 4  
5 5 #include "enums.h"
6 6 #include "hantekprotocol/bulkcode.h"
7   -#include "hantekprotocol/controlcode.h"
8   -#include "hantekprotocol/controlvalue.h"
  7 +#include "hantekprotocol/controlStructs.h"
9 8 #include "hantekprotocol/definitions.h"
10 9 #include <QList>
11 10  
... ... @@ -13,22 +12,6 @@ namespace Dso {
13 12  
14 13 using namespace Hantek;
15 14  
16   -/// \brief Stores the bulk command codes used for this device.
17   -struct ControlSpecificationCommandsBulk {
18   - BulkCode setChannels = BulkCode::INVALID; ///< Command for setting used channels
19   - BulkCode setSamplerate = BulkCode::INVALID; ///< Command for samplerate settings
20   - BulkCode setGain = BulkCode::SETGAIN; ///< Command for gain settings (Usually in combination with
21   - /// CONTROL_SETRELAYS)
22   - BulkCode setRecordLength = BulkCode::INVALID; ///< Command for buffer settings
23   - BulkCode setTrigger = BulkCode::INVALID; ///< Command for trigger settings
24   - BulkCode setPretrigger = BulkCode::INVALID; ///< Command for pretrigger settings
25   -};
26   -
27   -/// \brief Stores the command codes used for this device.
28   -struct ControlSpecificationCommands {
29   - ControlSpecificationCommandsBulk bulk; ///< The used bulk commands
30   -};
31   -
32 15 /// \brief Stores the samplerate limits for calculations.
33 16 struct ControlSamplerateLimits {
34 17 double base; ///< The base for sample rate calculations
... ... @@ -62,32 +45,47 @@ struct SpecialTriggerChannel {
62 45  
63 46 /// \brief Stores the specifications of the currently connected device.
64 47 struct ControlSpecification {
65   - ChannelID channels = HANTEK_CHANNELS;
  48 + ControlSpecification(unsigned channels);
  49 + const ChannelID channels;
66 50  
67 51 // Interface
68   - ControlSpecificationCommands command; ///< The commands for this device
  52 + BulkCode cmdSetChannels = BulkCode::INVALID; ///< Command for setting used channels
  53 + BulkCode cmdSetSamplerate = BulkCode::INVALID; ///< Command for samplerate settings
  54 + BulkCode cmdSetRecordLength = BulkCode::INVALID; ///< Command for buffer settings
  55 + BulkCode cmdSetTrigger = BulkCode::INVALID; ///< Command for trigger settings
  56 + BulkCode cmdSetPretrigger = BulkCode::INVALID; ///< Command for pretrigger settings
  57 + BulkCode cmdForceTrigger = BulkCode::FORCETRIGGER; ///< Command for forcing a trigger event
  58 + BulkCode cmdCaptureStart = BulkCode::STARTSAMPLING; ///< Command for starting the sampling
  59 + BulkCode cmdTriggerEnabled = BulkCode::ENABLETRIGGER; ///< Command for enabling the trigger
  60 + BulkCode cmdGetData = BulkCode::GETDATA; ///< Command for retrieve sample data
  61 + BulkCode cmdGetCaptureState = BulkCode::GETCAPTURESTATE; ///< Command for retrieve the capture state
  62 + BulkCode cmdSetGain = BulkCode::SETGAIN; ///< Command for setting the gain
  63 +
  64 + ControlBeginCommand beginCommandControl;
  65 + ControlGetLimits cmdGetLimits;
69 66  
70 67 // Limits
71 68 ControlSpecificationSamplerate samplerate; ///< The samplerate specifications
72 69 std::vector<RecordLengthID> bufferDividers; ///< Samplerate dividers for record lengths
73 70 unsigned char sampleSize; ///< Number of bits per sample
74 71  
  72 + /// For devices that support only fixed sample rates (isFixedSamplerateDevice=true)
  73 + std::vector<FixedSampleRate> fixedSampleRates;
  74 +
75 75 // Calibration
  76 +
76 77 /// The sample values at the top of the screen
77   - std::vector<unsigned short> voltageLimit[HANTEK_CHANNELS];
78   - /// Calibration data for the channel offsets
79   - OffsetsPerGainStep offsetLimit[HANTEK_CHANNELS];
  78 + typedef std::vector<unsigned short> VoltageLimit;
  79 + std::vector<VoltageLimit> voltageLimit; // Per channel
80 80  
81 81 /// Gain levels
82 82 std::vector<ControlSpecificationGainLevel> gain;
83 83  
84   - /// For devices that support only fixed sample rates (isFixedSamplerateDevice=true)
85   - std::vector<FixedSampleRate> fixedSampleRates;
86   -
  84 + // Features
87 85 std::vector<SpecialTriggerChannel> specialTriggerChannels;
88 86 std::vector<Coupling> couplings = {Dso::Coupling::DC, Dso::Coupling::AC};
89   - std::vector<TriggerMode> triggerModes = {TriggerMode::HARDWARE_SOFTWARE, TriggerMode::WAIT_FORCE, TriggerMode::SINGLE};
90   -
  87 + std::vector<TriggerMode> triggerModes = {TriggerMode::HARDWARE_SOFTWARE, TriggerMode::WAIT_FORCE,
  88 + TriggerMode::SINGLE};
91 89 bool isFixedSamplerateDevice = false;
92 90 bool isSoftwareTriggerDevice = false;
93 91 bool useControlNoBulk = false;
... ...
openhantek/src/hantekdso/enums.cpp
... ... @@ -4,5 +4,4 @@ namespace Dso {
4 4 Enum<Dso::TriggerMode, Dso::TriggerMode::HARDWARE_SOFTWARE, Dso::TriggerMode::SINGLE> TriggerModeEnum;
5 5 Enum<Dso::Slope, Dso::Slope::Positive, Dso::Slope::Negative> SlopeEnum;
6 6 Enum<Dso::GraphFormat, Dso::GraphFormat::TY, Dso::GraphFormat::XY> GraphFormatEnum;
7   - Enum<Dso::ChannelMode, Dso::ChannelMode::Voltage, Dso::ChannelMode::Spectrum> ChannelModeEnum;
8 7 }
... ...
openhantek/src/hantekdso/enums.h
... ... @@ -9,8 +9,6 @@ enum class ChannelMode {
9 9 Voltage, ///< Standard voltage view
10 10 Spectrum ///< Spectrum view
11 11 };
12   -constexpr int ChannelModes = 2;
13   -extern Enum<Dso::ChannelMode, Dso::ChannelMode::Voltage, Dso::ChannelMode::Spectrum> ChannelModeEnum;
14 12  
15 13 /// \enum GraphFormat
16 14 /// \brief The possible viewing formats for the graphs on the scope.
... ...
openhantek/src/hantekdso/hantekdsocontrol.cpp
... ... @@ -49,7 +49,7 @@ void HantekDsoControl::stopSampling() {
49 49 emit samplingStopped();
50 50 }
51 51  
52   -USBDevice *HantekDsoControl::getDevice() { return device; }
  52 +const USBDevice *HantekDsoControl::getDevice() const { return device; }
53 53  
54 54 const DSOsamples &HantekDsoControl::getLastSamples() { return result; }
55 55  
... ... @@ -58,9 +58,7 @@ HantekDsoControl::HantekDsoControl(USBDevice *device)
58 58 controlsettings(&(specification.samplerate.single), specification.channels) {
59 59 if (device == nullptr) throw new std::runtime_error("No usb device for HantekDsoControl");
60 60  
61   - if (specification.useControlNoBulk) {
62   - device->setEnableBulkTransfer(false);
63   - }
  61 + qRegisterMetaType<DSOsamples *>();
64 62  
65 63 if (specification.fixedUSBinLength)
66 64 device->overwriteInPacketLength(specification.fixedUSBinLength);
... ... @@ -84,6 +82,17 @@ HantekDsoControl::~HantekDsoControl() {
84 82 }
85 83 }
86 84  
  85 +int HantekDsoControl::bulkCommand(const DataArray<unsigned char> *command, int attempts) const {
  86 + if (specification.useControlNoBulk) return LIBUSB_SUCCESS;
  87 +
  88 + // Send BeginCommand control command
  89 + int errorCode = device->controlWrite(&specification.beginCommandControl);
  90 + if (errorCode < 0) return errorCode;
  91 +
  92 + // Send bulk command
  93 + return device->bulkWrite(command->data(), command->getSize(), attempts);
  94 +}
  95 +
87 96 unsigned HantekDsoControl::getChannelCount() { return specification.channels; }
88 97  
89 98 const ControlSettings *HantekDsoControl::getDeviceSettings() const { return &controlsettings; }
... ... @@ -107,7 +116,7 @@ void HantekDsoControl::updateInterval() {
107 116 // Check the current oscilloscope state everytime 25% of the time the buffer
108 117 // should be refilled
109 118 if (isRollMode())
110   - cycleTime = (int)((double)device->getPacketSize() / (isFastRate() ? 1 : specification.channels) /
  119 + cycleTime = (int)((double)getPacketSize() / (isFastRate() ? 1 : specification.channels) /
111 120 controlsettings.samplerate.current * 250);
112 121 else
113 122 cycleTime = (int)((double)getRecordLength() / controlsettings.samplerate.current * 250);
... ... @@ -130,16 +139,16 @@ unsigned HantekDsoControl::getRecordLength() const {
130 139  
131 140 Dso::ErrorCode HantekDsoControl::retrieveChannelLevelData() {
132 141 // Get channel level data
133   - ControlGetLimits c(2);
134   - int errorCode =
135   - device->controlRead(&c);
  142 + int errorCode = device->controlRead(&specification.cmdGetLimits);
136 143 if (errorCode < 0) {
137 144 qWarning() << tr("Couldn't get channel level data from oscilloscope");
138 145 emit statusMessage(tr("Couldn't get channel level data from oscilloscope"), 0);
139 146 emit communicationError();
140 147 return Dso::ErrorCode::CONNECTION;
141 148 }
142   - memcpy(specification.offsetLimit,c.offsetLimit,sizeof(specification.offsetLimit));
  149 +
  150 + memcpy(controlsettings.offsetLimit, specification.cmdGetLimits.offsetLimit,
  151 + sizeof(OffsetsPerGainStep)*specification.channels);
143 152  
144 153 return Dso::ErrorCode::NONE;
145 154 }
... ... @@ -159,14 +168,14 @@ std::pair&lt;int, unsigned&gt; HantekDsoControl::getCaptureState() const {
159 168  
160 169 if (!specification.supportsCaptureState) return std::make_pair(CAPTURE_READY, 0);
161 170  
162   - errorCode = device->bulkCommand(getCommand(BulkCode::GETCAPTURESTATE), 1);
  171 + errorCode = bulkCommand(getCommand(BulkCode::GETCAPTURESTATE), 1);
163 172 if (errorCode < 0) {
164 173 qWarning() << "Getting capture state failed: " << libUsbErrorString(errorCode);
165 174 return std::make_pair(CAPTURE_ERROR, 0);
166 175 }
167 176  
168 177 BulkResponseGetCaptureState response;
169   - errorCode = device->bulkRead(response.data(), response.getSize());
  178 + errorCode = device->bulkRead(&response);
170 179 if (errorCode < 0) {
171 180 qWarning() << "Getting capture state failed: " << libUsbErrorString(errorCode);
172 181 return std::make_pair(CAPTURE_ERROR, 0);
... ... @@ -179,7 +188,7 @@ std::vector&lt;unsigned char&gt; HantekDsoControl::getSamples(unsigned &amp;previousSample
179 188 int errorCode;
180 189 if (!specification.useControlNoBulk) {
181 190 // Request data
182   - errorCode = device->bulkCommand(getCommand(BulkCode::GETDATA), 1);
  191 + errorCode = bulkCommand(getCommand(BulkCode::GETDATA), 1);
183 192 } else {
184 193 errorCode = device->controlWrite(getCommand(ControlCode::CONTROL_ACQUIIRE_HARD_DATA));
185 194 }
... ... @@ -345,7 +354,7 @@ double HantekDsoControl::getBestSamplerate(double samplerate, bool fastRate, boo
345 354 bestDownsampler = 0.0;
346 355 bestSamplerate = limits->max / specification.bufferDividers[controlsettings.recordLengthId];
347 356 } else {
348   - switch (specification.command.bulk.setSamplerate) {
  357 + switch (specification.cmdSetSamplerate) {
349 358 case BulkCode::SETTRIGGERANDSAMPLERATE:
350 359 // DSO-2090 supports the downsampling factors 1, 2, 4 and 5 using
351 360 // valueFast or all even values above using valueSlow
... ... @@ -410,7 +419,7 @@ double HantekDsoControl::getBestSamplerate(double samplerate, bool fastRate, boo
410 419 unsigned HantekDsoControl::getSampleCount() const {
411 420 if (isRollMode()) {
412 421 // TODO handle libusb error
413   - return device->getPacketSize();
  422 + return getPacketSize();
414 423 } else {
415 424 if (isFastRate())
416 425 return getRecordLength();
... ... @@ -422,20 +431,20 @@ unsigned HantekDsoControl::getSampleCount() const {
422 431 unsigned HantekDsoControl::updateRecordLength(RecordLengthID index) {
423 432 if (index >= controlsettings.samplerate.limits->recordLengths.size()) return 0;
424 433  
425   - switch (specification.command.bulk.setRecordLength) {
  434 + switch (specification.cmdSetRecordLength) {
426 435 case BulkCode::SETTRIGGERANDSAMPLERATE:
427 436 modifyCommand<BulkSetTriggerAndSamplerate>(BulkCode::SETTRIGGERANDSAMPLERATE)->setRecordLength(index);
428 437 break;
429 438  
430 439 case BulkCode::DSETBUFFER:
431   - if (specification.command.bulk.setPretrigger == BulkCode::FSETBUFFER) {
  440 + if (specification.cmdSetPretrigger == BulkCode::FSETBUFFER) {
432 441 modifyCommand<BulkSetRecordLength2250>(BulkCode::DSETBUFFER)->setRecordLength(index);
433 442 } else {
434 443 // SetBuffer5200 bulk command for record length
435 444 BulkSetBuffer5200 *commandSetBuffer5200 = modifyCommand<BulkSetBuffer5200>(BulkCode::DSETBUFFER);
436 445  
437   - commandSetBuffer5200->setUsedPre(DTriggerPositionUsed::DTRIGGERPOSITION_ON);
438   - commandSetBuffer5200->setUsedPost(DTriggerPositionUsed::DTRIGGERPOSITION_ON);
  446 + commandSetBuffer5200->setUsedPre(DTriggerPositionUsed::ON);
  447 + commandSetBuffer5200->setUsedPost(DTriggerPositionUsed::ON);
439 448 commandSetBuffer5200->setRecordLength(index);
440 449 }
441 450  
... ... @@ -466,7 +475,7 @@ unsigned HantekDsoControl::updateSamplerate(unsigned downsampler, bool fastRate)
466 475 ControlSamplerateLimits *limits = fastRate ? &specification.samplerate.multi : &specification.samplerate.single;
467 476  
468 477 // Set the calculated samplerate
469   - switch (specification.command.bulk.setSamplerate) {
  478 + switch (specification.cmdSetSamplerate) {
470 479 case BulkCode::SETTRIGGERANDSAMPLERATE: {
471 480 short int downsamplerValue = 0;
472 481 unsigned char samplerateId = 0;
... ... @@ -720,14 +729,14 @@ Dso::ErrorCode HantekDsoControl::setChannelUsed(ChannelID channel, bool used) {
720 729 usedChannels = UsedChannels::USED_CH1CH2;
721 730 } else {
722 731 // DSO-2250 uses a different value for channel 2
723   - if (specification.command.bulk.setChannels == BulkCode::BSETCHANNELS)
  732 + if (specification.cmdSetChannels == BulkCode::BSETCHANNELS)
724 733 usedChannels = UsedChannels::BUSED_CH2;
725 734 else
726 735 usedChannels = UsedChannels::USED_CH2;
727 736 }
728 737 }
729 738  
730   - switch (specification.command.bulk.setChannels) {
  739 + switch (specification.cmdSetChannels) {
731 740 case BulkCode::SETTRIGGERANDSAMPLERATE: {
732 741 // SetTriggerAndSamplerate bulk command for trigger source
733 742 modifyCommand<BulkSetTriggerAndSamplerate>(BulkCode::SETTRIGGERANDSAMPLERATE)
... ... @@ -813,7 +822,7 @@ Dso::ErrorCode HantekDsoControl::setOffset(ChannelID channel, const double offse
813 822 if (channel >= specification.channels) return Dso::ErrorCode::PARAMETER;
814 823  
815 824 if (specification.supportsOffset) {
816   - Offset &channelOffLimit = specification.offsetLimit[channel].step[controlsettings.voltage[channel].gain];
  825 + Offset &channelOffLimit = controlsettings.offsetLimit[channel].step[controlsettings.voltage[channel].gain];
817 826 // Calculate the offset value
818 827 // The range is given by the calibration data (convert from big endian)
819 828 unsigned short int minimum = ((unsigned short int)*((unsigned char *)&(channelOffLimit.start)) << 8) +
... ... @@ -851,7 +860,7 @@ Dso::ErrorCode HantekDsoControl::setTriggerSource(bool special, unsigned id) {
851 860  
852 861 int hardwareID = special ? specification.specialTriggerChannels[id].hardwareID : (int)id;
853 862  
854   - switch (specification.command.bulk.setTrigger) {
  863 + switch (specification.cmdSetTrigger) {
855 864 case BulkCode::SETTRIGGERANDSAMPLERATE:
856 865 // SetTriggerAndSamplerate bulk command for trigger source
857 866 modifyCommand<BulkSetTriggerAndSamplerate>(BulkCode::SETTRIGGERANDSAMPLERATE)->setTriggerSource(1 - hardwareID);
... ... @@ -898,7 +907,7 @@ Dso::ErrorCode HantekDsoControl::setTriggerLevel(ChannelID channel, double level
898 907 // Calculate the trigger level value
899 908 unsigned short minimum, maximum;
900 909 if (specification.sampleSize > 8) {
901   - Offset &offsetLimit = specification.offsetLimit[channel].step[controlsettings.voltage[channel].gain];
  910 + Offset &offsetLimit = controlsettings.offsetLimit[channel].step[controlsettings.voltage[channel].gain];
902 911 // The range is the same as used for the offsets for 10 bit models
903 912 minimum = ((unsigned short)*((unsigned char *)&(offsetLimit.start)) << 8) +
904 913 *((unsigned char *)&(offsetLimit.start) + 1);
... ... @@ -931,7 +940,7 @@ Dso::ErrorCode HantekDsoControl::setTriggerLevel(ChannelID channel, double level
931 940 Dso::ErrorCode HantekDsoControl::setTriggerSlope(Dso::Slope slope) {
932 941 if (!device->isConnected()) return Dso::ErrorCode::CONNECTION;
933 942  
934   - switch (specification.command.bulk.setTrigger) {
  943 + switch (specification.cmdSetTrigger) {
935 944 case BulkCode::SETTRIGGERANDSAMPLERATE: {
936 945 // SetTriggerAndSamplerate bulk command for trigger slope
937 946 modifyCommand<BulkSetTriggerAndSamplerate>(BulkCode::SETTRIGGERANDSAMPLERATE)->setTriggerSlope((uint8_t)slope);
... ... @@ -966,7 +975,7 @@ Dso::ErrorCode HantekDsoControl::setPretriggerPosition(double position) {
966 975 // Fast rate mode uses both channels
967 976 if (isFastRate()) positionSamples /= specification.channels;
968 977  
969   - switch (specification.command.bulk.setPretrigger) {
  978 + switch (specification.cmdSetPretrigger) {
970 979 case BulkCode::SETTRIGGERANDSAMPLERATE: {
971 980 // Calculate the position value (Start point depending on record length)
972 981 unsigned triggerPosition = isRollMode() ? 0x1 : 0x7ffff - recordLength + (unsigned)positionSamples;
... ... @@ -1057,21 +1066,21 @@ void HantekDsoControl::run() {
1057 1066 int errorCode = 0;
1058 1067  
1059 1068 // Send all pending bulk commands
1060   - BulkCommand *bulkCommand = firstBulkCommand;
1061   - while (bulkCommand) {
1062   - if (bulkCommand->pending) {
  1069 + BulkCommand *command = firstBulkCommand;
  1070 + while (command) {
  1071 + if (command->pending) {
1063 1072 timestampDebug(
1064   - QString("Sending bulk command:%1").arg(hexDump(bulkCommand->data(), bulkCommand->getSize())));
  1073 + QString("Sending bulk command:%1").arg(hexDump(command->data(), command->getSize())));
1065 1074  
1066   - errorCode = device->bulkCommand(bulkCommand);
  1075 + errorCode = bulkCommand(command);
1067 1076 if (errorCode < 0) {
1068 1077 qWarning() << "Sending bulk command failed: " << libUsbErrorString(errorCode);
1069 1078 emit communicationError();
1070 1079 return;
1071 1080 } else
1072   - bulkCommand->pending = false;
  1081 + command->pending = false;
1073 1082 }
1074   - bulkCommand = bulkCommand->next;
  1083 + command = command->next;
1075 1084 }
1076 1085  
1077 1086 // Send all pending control commands
... ... @@ -1079,8 +1088,8 @@ void HantekDsoControl::run() {
1079 1088 while (controlCommand) {
1080 1089 if (controlCommand->pending) {
1081 1090 timestampDebug(QString("Sending control command %1:%2")
1082   - .arg(QString::number(control[cIndex], 16),
1083   - hexDump(this->control[control]->data(), this->control[control]->getSize())));
  1091 + .arg(QString::number(controlCommand->code, 16),
  1092 + hexDump(controlCommand->data(), controlCommand->getSize())));
1084 1093  
1085 1094 errorCode = device->controlWrite(controlCommand);
1086 1095 if (errorCode < 0) {
... ... @@ -1114,7 +1123,7 @@ void HantekDsoControl::run() {
1114 1123 // Sampling hasn't started, update the expected sample count
1115 1124 expectedSampleCount = this->getSampleCount();
1116 1125  
1117   - errorCode = device->bulkCommand(getCommand(BulkCode::STARTSAMPLING));
  1126 + errorCode = bulkCommand(getCommand(BulkCode::STARTSAMPLING));
1118 1127 if (errorCode < 0) {
1119 1128 if (errorCode == LIBUSB_ERROR_NO_DEVICE) {
1120 1129 emit communicationError();
... ... @@ -1130,7 +1139,7 @@ void HantekDsoControl::run() {
1130 1139 break;
1131 1140  
1132 1141 case RollState::ENABLETRIGGER:
1133   - errorCode = device->bulkCommand(getCommand(BulkCode::ENABLETRIGGER));
  1142 + errorCode = bulkCommand(getCommand(BulkCode::ENABLETRIGGER));
1134 1143 if (errorCode < 0) {
1135 1144 if (errorCode == LIBUSB_ERROR_NO_DEVICE) {
1136 1145 emit communicationError();
... ... @@ -1144,7 +1153,7 @@ void HantekDsoControl::run() {
1144 1153 break;
1145 1154  
1146 1155 case RollState::FORCETRIGGER:
1147   - errorCode = device->bulkCommand(getCommand(BulkCode::FORCETRIGGER));
  1156 + errorCode = bulkCommand(getCommand(BulkCode::FORCETRIGGER));
1148 1157 if (errorCode < 0) {
1149 1158 if (errorCode == LIBUSB_ERROR_NO_DEVICE) {
1150 1159 emit communicationError();
... ... @@ -1161,7 +1170,7 @@ void HantekDsoControl::run() {
1161 1170 std::vector<unsigned char> rawData = this->getSamples(expectedSampleCount);
1162 1171 if (this->_samplingStarted) {
1163 1172 convertRawDataToSamples(rawData);
1164   - emit samplesAvailable();
  1173 + emit samplesAvailable(&result);
1165 1174 }
1166 1175 }
1167 1176  
... ... @@ -1202,7 +1211,7 @@ void HantekDsoControl::run() {
1202 1211 std::vector<unsigned char> rawData = this->getSamples(expectedSampleCount);
1203 1212 if (this->_samplingStarted) {
1204 1213 convertRawDataToSamples(rawData);
1205   - emit samplesAvailable();
  1214 + emit samplesAvailable(&result);
1206 1215 }
1207 1216 }
1208 1217  
... ... @@ -1216,10 +1225,16 @@ void HantekDsoControl::run() {
1216 1225 // Start next capture if necessary by leaving out the break statement
1217 1226  
1218 1227 if (!this->sampling) break;
1219   -#if __has_cpp_attribute(fallthrough) // Make compiler happy
1220   - else
1221   - [[fallthrough]];
  1228 +#if __has_cpp_attribute(clang::fallthrough)
  1229 +#define FALLTHROUGH [[clang::fallthrough]];
  1230 +#elif __has_cpp_attribute(fallthrough)
  1231 +#define FALLTHROUGH [[fallthrough]];
  1232 +#else
  1233 +#define FALLTHROUGH
1222 1234 #endif
  1235 + else {
  1236 + FALLTHROUGH
  1237 + }
1223 1238 case CAPTURE_WAITING:
1224 1239 // Sampling hasn't started, update the expected sample count
1225 1240 expectedSampleCount = this->getSampleCount();
... ... @@ -1230,7 +1245,7 @@ void HantekDsoControl::run() {
1230 1245 if (this->cycleCounter == this->startCycle && !isRollMode()) {
1231 1246 // Buffer refilled completely since start of sampling, enable the
1232 1247 // trigger now
1233   - errorCode = device->bulkCommand(getCommand(BulkCode::ENABLETRIGGER));
  1248 + errorCode = bulkCommand(getCommand(BulkCode::ENABLETRIGGER));
1234 1249 if (errorCode < 0) {
1235 1250 if (errorCode == LIBUSB_ERROR_NO_DEVICE) {
1236 1251 emit communicationError();
... ... @@ -1243,7 +1258,7 @@ void HantekDsoControl::run() {
1243 1258 } else if (cycleCounter >= 8 + this->startCycle &&
1244 1259 controlsettings.trigger.mode == Dso::TriggerMode::WAIT_FORCE) {
1245 1260 // Force triggering
1246   - errorCode = device->bulkCommand(getCommand(BulkCode::FORCETRIGGER));
  1261 + errorCode = bulkCommand(getCommand(BulkCode::FORCETRIGGER));
1247 1262 if (errorCode < 0) {
1248 1263 if (errorCode == LIBUSB_ERROR_NO_DEVICE) {
1249 1264 emit communicationError();
... ... @@ -1259,7 +1274,7 @@ void HantekDsoControl::run() {
1259 1274 }
1260 1275  
1261 1276 // Start capturing
1262   - errorCode = device->bulkCommand(getCommand(BulkCode::STARTSAMPLING));
  1277 + errorCode = bulkCommand(getCommand(BulkCode::STARTSAMPLING));
1263 1278 if (errorCode < 0) {
1264 1279 if (errorCode == LIBUSB_ERROR_NO_DEVICE) {
1265 1280 emit communicationError();
... ... @@ -1290,3 +1305,27 @@ void HantekDsoControl::run() {
1290 1305 QTimer::singleShot(cycleTime, this, SLOT(run()));
1291 1306 #endif
1292 1307 }
  1308 +
  1309 +
  1310 +int HantekDsoControl::getConnectionSpeed() const {
  1311 + int errorCode;
  1312 + ControlGetSpeed response;
  1313 + errorCode = device->controlRead(&response);
  1314 + if (errorCode < 0) return errorCode;
  1315 +
  1316 + return response.getSpeed();
  1317 +}
  1318 +
  1319 +int HantekDsoControl::getPacketSize() const {
  1320 + const int s = getConnectionSpeed();
  1321 + if (s == CONNECTION_FULLSPEED)
  1322 + return 64;
  1323 + else if (s == CONNECTION_HIGHSPEED)
  1324 + return 512;
  1325 + else if (s > CONNECTION_HIGHSPEED) {
  1326 + qWarning() << "Unknown USB speed. Please correct source code in USBDevice::getPacketSize()";
  1327 + throw new std::runtime_error("Unknown USB speed");
  1328 + } else if (s < 0)
  1329 + return s;
  1330 + return 0;
  1331 +}
... ...
openhantek/src/hantekdso/hantekdsocontrol.h
... ... @@ -5,16 +5,16 @@
5 5 #define NOMINMAX // disable windows.h min/max global methods
6 6 #include <limits>
7 7  
8   -#include "errorcodes.h"
  8 +#include "controlsettings.h"
  9 +#include "controlspecification.h"
9 10 #include "dsosamples.h"
  11 +#include "errorcodes.h"
10 12 #include "states.h"
11   -#include "controlspecification.h"
12   -#include "controlsettings.h"
13 13 #include "utils/printutils.h"
14 14  
15   -#include "hantekprotocol/definitions.h"
16 15 #include "hantekprotocol/bulkStructs.h"
17 16 #include "hantekprotocol/controlStructs.h"
  17 +#include "hantekprotocol/definitions.h"
18 18  
19 19 #include <vector>
20 20  
... ... @@ -71,7 +71,15 @@ class HantekDsoControl : public QObject {
71 71 double getMaxSamplerate();
72 72  
73 73 /// Return the associated usb device.
74   - USBDevice *getDevice();
  74 + const USBDevice *getDevice() const;
  75 +
  76 + /// \brief Gets the speed of the connection.
  77 + /// \return The ::ConnectionSpeed of the USB connection.
  78 + int getConnectionSpeed() const;
  79 +
  80 + /// \brief Gets the maximum size of one packet transmitted via bulk transfer.
  81 + /// \return The maximum packet size in bytes, negative libusb error code on error.
  82 + int getPacketSize() const;
75 83  
76 84 /// Return the last sample set
77 85 const DSOsamples &getLastSamples();
... ... @@ -89,19 +97,20 @@ class HantekDsoControl : public QObject {
89 97 /// \return See ::Dso::ErrorCode.
90 98 Dso::ErrorCode stringCommand(const QString &commandString);
91 99  
92   - void addCommand(BulkCommand* newCommand, bool pending = true);
93   - template<class T> T* modifyCommand(Hantek::BulkCode code) {
  100 + void addCommand(BulkCommand *newCommand, bool pending = true);
  101 + template <class T> T *modifyCommand(Hantek::BulkCode code) {
94 102 command[(uint8_t)code]->pending = true;
95   - return static_cast<T*>(command[(uint8_t)code]);
  103 + return static_cast<T *>(command[(uint8_t)code]);
96 104 }
97   - const BulkCommand* getCommand(Hantek::BulkCode code) const;
  105 + const BulkCommand *getCommand(Hantek::BulkCode code) const;
98 106  
99   - void addCommand(ControlCommand* newCommand, bool pending = true);
100   - template<class T> T* modifyCommand(Hantek::ControlCode code) {
  107 + void addCommand(ControlCommand *newCommand, bool pending = true);
  108 + template <class T> T *modifyCommand(Hantek::ControlCode code) {
101 109 control[(uint8_t)code]->pending = true;
102   - return static_cast<T*>(control[(uint8_t)code]);
  110 + return static_cast<T *>(control[(uint8_t)code]);
103 111 }
104   - const ControlCommand* getCommand(Hantek::ControlCode code) const;
  112 + const ControlCommand *getCommand(Hantek::ControlCode code) const;
  113 +
105 114 private:
106 115 bool isRollMode() const;
107 116 bool isFastRate() const;
... ... @@ -164,9 +173,9 @@ class HantekDsoControl : public QObject {
164 173 private:
165 174 /// Pointers to bulk/control commands
166 175 BulkCommand *command[255] = {0};
167   - BulkCommand* firstBulkCommand = nullptr;
  176 + BulkCommand *firstBulkCommand = nullptr;
168 177 ControlCommand *control[255] = {0};
169   - ControlCommand* firstControlCommand = nullptr;
  178 + ControlCommand *firstControlCommand = nullptr;
170 179  
171 180 // Communication with device
172 181 USBDevice *device; ///< The USB device for the oscilloscope
... ... @@ -190,6 +199,12 @@ class HantekDsoControl : public QObject {
190 199 int startCycle = 0;
191 200 int cycleTime = 0;
192 201  
  202 + /// \brief Send a bulk command to the oscilloscope.
  203 + /// \param command The command, that should be sent.
  204 + /// \param attempts The number of attempts, that are done on timeouts.
  205 + /// \return Number of sent bytes on success, libusb error code on error.
  206 + int bulkCommand(const DataArray<unsigned char> *command, int attempts = HANTEK_ATTEMPTS) const;
  207 +
193 208 public slots:
194 209 void startSampling();
195 210 void stopSampling();
... ... @@ -258,7 +273,7 @@ class HantekDsoControl : public QObject {
258 273 void samplingStarted(); ///< The oscilloscope started sampling/waiting for trigger
259 274 void samplingStopped(); ///< The oscilloscope stopped sampling/waiting for trigger
260 275 void statusMessage(const QString &message, int timeout); ///< Status message about the oscilloscope
261   - void samplesAvailable(); ///< New sample data is available
  276 + void samplesAvailable(const DSOsamples *samples); ///< New sample data is available
262 277  
263 278 void availableRecordLengthsChanged(const std::vector<unsigned> &recordLengths); ///< The available record
264 279 /// lengths, empty list for
... ... @@ -271,3 +286,5 @@ class HantekDsoControl : public QObject {
271 286  
272 287 void communicationError() const;
273 288 };
  289 +
  290 +Q_DECLARE_METATYPE(DSOsamples *)
... ...
openhantek/src/hantekdso/models/modelDSO2090.cpp
... ... @@ -5,12 +5,13 @@
5 5  
6 6 using namespace Hantek;
7 7  
8   -ModelDSO2090::ModelDSO2090() : DSOModel(ID, 0x04b5, 0x2090, 0x04b4, 0x2090, "dso2090x86", "DSO-2090", Dso::ControlSpecification()) {
9   - specification.command.bulk.setRecordLength = BulkCode::SETTRIGGERANDSAMPLERATE;
10   - specification.command.bulk.setChannels = BulkCode::SETTRIGGERANDSAMPLERATE;
11   - specification.command.bulk.setSamplerate = BulkCode::SETTRIGGERANDSAMPLERATE;
12   - specification.command.bulk.setTrigger = BulkCode::SETTRIGGERANDSAMPLERATE;
13   - specification.command.bulk.setPretrigger = BulkCode::SETTRIGGERANDSAMPLERATE;
  8 +ModelDSO2090::ModelDSO2090() : DSOModel(ID, 0x04b5, 0x2090, 0x04b4, 0x2090, "dso2090x86", "DSO-2090",
  9 + Dso::ControlSpecification(2)) {
  10 + specification.cmdSetRecordLength = BulkCode::SETTRIGGERANDSAMPLERATE;
  11 + specification.cmdSetChannels = BulkCode::SETTRIGGERANDSAMPLERATE;
  12 + specification.cmdSetSamplerate = BulkCode::SETTRIGGERANDSAMPLERATE;
  13 + specification.cmdSetTrigger = BulkCode::SETTRIGGERANDSAMPLERATE;
  14 + specification.cmdSetPretrigger = BulkCode::SETTRIGGERANDSAMPLERATE;
14 15  
15 16 specification.samplerate.single.base = 50e6;
16 17 specification.samplerate.single.max = 50e6;
... ...
openhantek/src/hantekdso/models/modelDSO2150.cpp
... ... @@ -5,12 +5,13 @@
5 5  
6 6 using namespace Hantek;
7 7  
8   -ModelDSO2150::ModelDSO2150() : DSOModel(ID, 0x04b5, 0x2150, 0x04b4, 0x2150, "dso2150x86", "DSO-2150", Dso::ControlSpecification()) {
9   - specification.command.bulk.setRecordLength = BulkCode::SETTRIGGERANDSAMPLERATE;
10   - specification.command.bulk.setChannels = BulkCode::SETTRIGGERANDSAMPLERATE;
11   - specification.command.bulk.setSamplerate = BulkCode::SETTRIGGERANDSAMPLERATE;
12   - specification.command.bulk.setTrigger = BulkCode::SETTRIGGERANDSAMPLERATE;
13   - specification.command.bulk.setPretrigger = BulkCode::SETTRIGGERANDSAMPLERATE;
  8 +ModelDSO2150::ModelDSO2150() : DSOModel(ID, 0x04b5, 0x2150, 0x04b4, 0x2150, "dso2150x86", "DSO-2150",
  9 + Dso::ControlSpecification(2)) {
  10 + specification.cmdSetRecordLength = BulkCode::SETTRIGGERANDSAMPLERATE;
  11 + specification.cmdSetChannels = BulkCode::SETTRIGGERANDSAMPLERATE;
  12 + specification.cmdSetSamplerate = BulkCode::SETTRIGGERANDSAMPLERATE;
  13 + specification.cmdSetTrigger = BulkCode::SETTRIGGERANDSAMPLERATE;
  14 + specification.cmdSetPretrigger = BulkCode::SETTRIGGERANDSAMPLERATE;
14 15  
15 16 specification.samplerate.single.base = 50e6;
16 17 specification.samplerate.single.max = 75e6;
... ...
openhantek/src/hantekdso/models/modelDSO2250.cpp
... ... @@ -5,12 +5,13 @@
5 5  
6 6 using namespace Hantek;
7 7  
8   -ModelDSO2250::ModelDSO2250() : DSOModel(ID, 0x04b5, 0x2250, 0x04b4, 0x2250, "dso2250x86", "DSO-2250", Dso::ControlSpecification()) {
9   - specification.command.bulk.setRecordLength = BulkCode::DSETBUFFER;
10   - specification.command.bulk.setChannels = BulkCode::BSETCHANNELS;
11   - specification.command.bulk.setSamplerate = BulkCode::ESETTRIGGERORSAMPLERATE;
12   - specification.command.bulk.setTrigger = BulkCode::CSETTRIGGERORSAMPLERATE;
13   - specification.command.bulk.setPretrigger = BulkCode::FSETBUFFER;
  8 +ModelDSO2250::ModelDSO2250() : DSOModel(ID, 0x04b5, 0x2250, 0x04b4, 0x2250, "dso2250x86", "DSO-2250",
  9 + Dso::ControlSpecification(2)) {
  10 + specification.cmdSetRecordLength = BulkCode::DSETBUFFER;
  11 + specification.cmdSetChannels = BulkCode::BSETCHANNELS;
  12 + specification.cmdSetSamplerate = BulkCode::ESETTRIGGERORSAMPLERATE;
  13 + specification.cmdSetTrigger = BulkCode::CSETTRIGGERORSAMPLERATE;
  14 + specification.cmdSetPretrigger = BulkCode::FSETBUFFER;
14 15  
15 16 specification.samplerate.single.base = 100e6;
16 17 specification.samplerate.single.max = 100e6;
... ...
openhantek/src/hantekdso/models/modelDSO5200.cpp
... ... @@ -5,12 +5,13 @@
5 5  
6 6 using namespace Hantek;
7 7  
8   -ModelDSO5200::ModelDSO5200() : DSOModel(ID, 0x04b5, 0x5200, 0x04b4, 0x5200, "dso5200x86", "DSO-5200", Dso::ControlSpecification()) {
9   - specification.command.bulk.setRecordLength = BulkCode::DSETBUFFER;
10   - specification.command.bulk.setChannels = BulkCode::ESETTRIGGERORSAMPLERATE;
11   - specification.command.bulk.setSamplerate = BulkCode::CSETTRIGGERORSAMPLERATE;
12   - specification.command.bulk.setTrigger = BulkCode::ESETTRIGGERORSAMPLERATE;
13   - specification.command.bulk.setPretrigger = BulkCode::ESETTRIGGERORSAMPLERATE;
  8 +ModelDSO5200::ModelDSO5200() : DSOModel(ID, 0x04b5, 0x5200, 0x04b4, 0x5200, "dso5200x86", "DSO-5200",
  9 + Dso::ControlSpecification(2)) {
  10 + specification.cmdSetRecordLength = BulkCode::DSETBUFFER;
  11 + specification.cmdSetChannels = BulkCode::ESETTRIGGERORSAMPLERATE;
  12 + specification.cmdSetSamplerate = BulkCode::CSETTRIGGERORSAMPLERATE;
  13 + specification.cmdSetTrigger = BulkCode::ESETTRIGGERORSAMPLERATE;
  14 + specification.cmdSetPretrigger = BulkCode::ESETTRIGGERORSAMPLERATE;
14 15  
15 16 specification.samplerate.single.base = 100e6;
16 17 specification.samplerate.single.max = 125e6;
... ...
openhantek/src/hantekdso/models/modelDSO6022.cpp
... ... @@ -5,7 +5,8 @@
5 5  
6 6 using namespace Hantek;
7 7  
8   -ModelDSO6022BE::ModelDSO6022BE() : DSOModel(ID, 0x04b5, 0x6022, 0x04b4, 0x6022, "dso6022be", "DSO-6022BE", Dso::ControlSpecification()) {
  8 +ModelDSO6022BE::ModelDSO6022BE() : DSOModel(ID, 0x04b5, 0x6022, 0x04b4, 0x6022, "dso6022be", "DSO-6022BE",
  9 + Dso::ControlSpecification(2)) {
9 10 // 6022xx do not support any bulk commands
10 11 specification.useControlNoBulk = true;
11 12 specification.isSoftwareTriggerDevice = true;
... ...
openhantek/src/hantekprotocol/bulkStructs.h
... ... @@ -7,6 +7,7 @@
7 7  
8 8 #include <QString>
9 9  
  10 +#include "types.h"
10 11 #include "definitions.h"
11 12 #include "states.h"
12 13 #include "usb/bulkcommand.h"
... ... @@ -190,8 +191,8 @@ class BulkSetRecordLength2250 : public BulkCommand {
190 191 class BulkSetBuffer5200 : public BulkCommand {
191 192 public:
192 193 BulkSetBuffer5200();
193   - BulkSetBuffer5200(uint16_t triggerPositionPre, uint16_t triggerPositionPost, DTriggerPositionUsed usedPre = DTriggerPositionUsed::DTRIGGERPOSITION_OFF,
194   - DTriggerPositionUsed usedPost = DTriggerPositionUsed::DTRIGGERPOSITION_OFF, uint8_t recordLength = 0);
  194 + BulkSetBuffer5200(uint16_t triggerPositionPre, uint16_t triggerPositionPost, DTriggerPositionUsed usedPre = DTriggerPositionUsed::OFF,
  195 + DTriggerPositionUsed usedPost = DTriggerPositionUsed::OFF, uint8_t recordLength = 0);
195 196  
196 197 uint16_t getTriggerPositionPre();
197 198 void setTriggerPositionPre(uint16_t value);
... ...
openhantek/src/hantekprotocol/controlStructs.cpp
... ... @@ -4,12 +4,24 @@
4 4  
5 5 #include "controlStructs.h"
6 6 #include "controlvalue.h"
  7 +#include "definitions.h"
7 8  
8 9 namespace Hantek {
9 10  
  11 +ControlBeginCommand::ControlBeginCommand(BulkIndex index)
  12 + : ControlCommand(Hantek::ControlCode::CONTROL_BEGINCOMMAND, 10) {
  13 + array[0] = 0x0f;
  14 + array[1] = (uint8_t)index;
  15 +}
  16 +
  17 +ControlGetSpeed::ControlGetSpeed() : ControlCommand(Hantek::ControlCode::CONTROL_GETSPEED, 10) {}
  18 +
  19 +ConnectionSpeed ControlGetSpeed::getSpeed() { return (ConnectionSpeed)this->array[0]; }
  20 +
10 21 ControlSetOffset::ControlSetOffset() : ControlCommand(ControlCode::CONTROL_SETOFFSET, 17) {}
11 22  
12   -ControlSetOffset::ControlSetOffset(uint16_t channel1, uint16_t channel2, uint16_t trigger) : ControlCommand(ControlCode::CONTROL_SETOFFSET, 17) {
  23 +ControlSetOffset::ControlSetOffset(uint16_t channel1, uint16_t channel2, uint16_t trigger)
  24 + : ControlCommand(ControlCode::CONTROL_SETOFFSET, 17) {
13 25 this->setChannel(0, channel1);
14 26 this->setChannel(1, channel2);
15 27 this->setTrigger(trigger);
... ... @@ -41,7 +53,7 @@ void ControlSetOffset::setTrigger(uint16_t level) {
41 53  
42 54 ControlSetRelays::ControlSetRelays(bool ch1Below1V, bool ch1Below100mV, bool ch1CouplingDC, bool ch2Below1V,
43 55 bool ch2Below100mV, bool ch2CouplingDC, bool triggerExt)
44   - : ControlCommand(ControlCode::CONTROL_SETRELAYS,17) {
  56 + : ControlCommand(ControlCode::CONTROL_SETRELAYS, 17) {
45 57 this->setBelow1V(0, ch1Below1V);
46 58 this->setBelow100mV(0, ch1Below100mV);
47 59 this->setCoupling(0, ch1CouplingDC);
... ... @@ -97,27 +109,31 @@ bool ControlSetRelays::getTrigger() { return (this-&gt;array[7] &amp; 0x01) == 0x00; }
97 109  
98 110 void ControlSetRelays::setTrigger(bool ext) { this->array[7] = ext ? 0xfe : 0x01; }
99 111  
100   -ControlSetVoltDIV_CH1::ControlSetVoltDIV_CH1() : ControlCommand(ControlCode::CONTROL_SETVOLTDIV_CH1,1) { this->setDiv(5); }
  112 +ControlSetVoltDIV_CH1::ControlSetVoltDIV_CH1() : ControlCommand(ControlCode::CONTROL_SETVOLTDIV_CH1, 1) {
  113 + this->setDiv(5);
  114 +}
101 115  
102 116 void ControlSetVoltDIV_CH1::setDiv(uint8_t val) { this->array[0] = val; }
103 117  
104   -ControlSetVoltDIV_CH2::ControlSetVoltDIV_CH2() : ControlCommand(ControlCode::CONTROL_SETVOLTDIV_CH2,1) { this->setDiv(5); }
  118 +ControlSetVoltDIV_CH2::ControlSetVoltDIV_CH2() : ControlCommand(ControlCode::CONTROL_SETVOLTDIV_CH2, 1) {
  119 + this->setDiv(5);
  120 +}
105 121  
106 122 void ControlSetVoltDIV_CH2::setDiv(uint8_t val) { this->array[0] = val; }
107 123  
108   -ControlSetTimeDIV::ControlSetTimeDIV() : ControlCommand(ControlCode::CONTROL_SETTIMEDIV,1) { this->setDiv(1); }
  124 +ControlSetTimeDIV::ControlSetTimeDIV() : ControlCommand(ControlCode::CONTROL_SETTIMEDIV, 1) { this->setDiv(1); }
109 125  
110 126 void ControlSetTimeDIV::setDiv(uint8_t val) { this->array[0] = val; }
111 127  
112   -ControlAcquireHardData::ControlAcquireHardData() : ControlCommand(ControlCode::CONTROL_ACQUIIRE_HARD_DATA,1) { this->array[0] = 0x01; }
  128 +ControlAcquireHardData::ControlAcquireHardData() : ControlCommand(ControlCode::CONTROL_ACQUIIRE_HARD_DATA, 1) {
  129 + this->array[0] = 0x01;
  130 +}
113 131  
114   -ControlGetLimits::ControlGetLimits(unsigned channels) : ControlCommand(ControlCode::CONTROL_VALUE,1), offsetLimit(new OffsetsPerGainStep[channels]) {
  132 +ControlGetLimits::ControlGetLimits(unsigned channels)
  133 + : ControlCommand(ControlCode::CONTROL_VALUE, 1), offsetLimit(new OffsetsPerGainStep[channels]) {
115 134 value = (uint8_t)ControlValue::VALUE_OFFSETLIMITS;
116 135 array[0] = 0x01;
117 136 }
118 137  
119   -ControlGetLimits::~ControlGetLimits()
120   -{
121   - delete [] offsetLimit;
122   -}
  138 +ControlGetLimits::~ControlGetLimits() { delete[] offsetLimit; }
123 139 }
... ...
openhantek/src/hantekprotocol/controlStructs.h
1 1 #pragma once
2 2  
3   -#include "definitions.h"
  3 +#include "types.h"
4 4 #include "usb/usbdevicedefinitions.h"
5 5 #include "usb/controlcommand.h"
6 6 #include "controlcode.h"
7 7  
8 8 namespace Hantek {
  9 +struct OffsetsPerGainStep;
  10 +
  11 +/// \enum BulkIndex
  12 +/// \brief Can be set by CONTROL_BEGINCOMMAND, maybe it allows multiple commands
  13 +/// at the same time?
  14 +enum BulkIndex {
  15 + COMMANDINDEX_0 = 0x03, ///< Used most of the time
  16 + COMMANDINDEX_1 = 0x0a,
  17 + COMMANDINDEX_2 = 0x09,
  18 + COMMANDINDEX_3 = 0x01, ///< Used for ::BulkCode::SETTRIGGERANDSAMPLERATE sometimes
  19 + COMMANDINDEX_4 = 0x02,
  20 + COMMANDINDEX_5 = 0x08
  21 +};
  22 +
  23 +/// \class ControlBeginCommand
  24 +class ControlBeginCommand : public ControlCommand {
  25 + public:
  26 + /// \brief Sets the command index to the given value.
  27 + /// \param index The CommandIndex for the command.
  28 + ControlBeginCommand(BulkIndex index = COMMANDINDEX_0);
  29 +};
  30 +
  31 +/// \brief The CONTROL_GETSPEED parser.
  32 +class ControlGetSpeed : public ControlCommand {
  33 + public:
  34 + ControlGetSpeed();
  35 + /// \brief Gets the speed of the connection.
  36 + /// \return The speed level of the USB connection.
  37 + ConnectionSpeed getSpeed();
  38 +};
9 39  
10 40 struct ControlSetOffset : public ControlCommand {
11 41 ControlSetOffset();
... ...
openhantek/src/hantekprotocol/definitions.h
... ... @@ -7,10 +7,6 @@
7 7 #include <stdint.h>
8 8  
9 9 #define HANTEK_GAIN_STEPS 9
10   -#define HANTEK_CHANNELS 2 ///< Number of physical channels
11   -
12   -typedef unsigned RecordLengthID;
13   -typedef unsigned ChannelID;
14 10  
15 11 namespace Hantek {
16 12 /// \enum UsedChannels
... ... @@ -31,8 +27,8 @@ enum class UsedChannels : uint8_t {
31 27 /// \enum DTriggerPositionUsed hantek/types.h
32 28 /// \brief The trigger position states for the 0x0d command.
33 29 enum class DTriggerPositionUsed: uint8_t {
34   - DTRIGGERPOSITION_OFF = 0, ///< Used for Roll mode
35   - DTRIGGERPOSITION_ON = 7 ///< Used for normal operation
  30 + OFF = 0, ///< Used for Roll mode
  31 + ON = 7 ///< Used for normal operation
36 32 };
37 33  
38 34 #pragma pack(push, 1)
... ...
openhantek/src/hantekprotocol/types.h 0 → 100644
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +
  3 +#pragma once
  4 +
  5 +typedef unsigned RecordLengthID;
  6 +typedef unsigned ChannelID;
... ...
openhantek/src/usb/controlbegin.cpp deleted
1   -#include "controlbegin.h"
2   -#include "hantekprotocol/controlcode.h"
3   -
4   -ControlBeginCommand::ControlBeginCommand(BulkIndex index) : ControlCommand(Hantek::ControlCode::CONTROL_BEGINCOMMAND, 10) {
5   - array[0] = 0x0f;
6   - array[1] = (uint8_t)index;
7   -}
openhantek/src/usb/controlbegin.h deleted
1   -
2   -// SPDX-License-Identifier: GPL-2.0+
3   -
4   -#pragma once
5   -#include "controlcommand.h"
6   -#include <inttypes.h>
7   -
8   -/// \enum BulkIndex
9   -/// \brief Can be set by CONTROL_BEGINCOMMAND, maybe it allows multiple commands
10   -/// at the same time?
11   -enum BulkIndex {
12   - COMMANDINDEX_0 = 0x03, ///< Used most of the time
13   - COMMANDINDEX_1 = 0x0a,
14   - COMMANDINDEX_2 = 0x09,
15   - COMMANDINDEX_3 = 0x01, ///< Used for ::BulkCode::SETTRIGGERANDSAMPLERATE sometimes
16   - COMMANDINDEX_4 = 0x02,
17   - COMMANDINDEX_5 = 0x08
18   -};
19   -
20   -/// \class ControlBeginCommand
21   -class ControlBeginCommand : public ControlCommand {
22   - public:
23   - /// \brief Sets the command index to the given value.
24   - /// \param index The CommandIndex for the command.
25   - ControlBeginCommand(BulkIndex index = COMMANDINDEX_0);
26   -};
openhantek/src/usb/controlgetspeed.cpp deleted
1   -#include "controlgetspeed.h"
2   -#include "hantekprotocol/controlcode.h"
3   -
4   -ControlGetSpeed::ControlGetSpeed() : ControlCommand(Hantek::ControlCode::CONTROL_GETSPEED, 10) {}
5   -
6   -ConnectionSpeed ControlGetSpeed::getSpeed() { return (ConnectionSpeed)this->array[0]; }
7   -
openhantek/src/usb/controlgetspeed.h deleted
1   -// SPDX-License-Identifier: GPL-2.0+
2   -
3   -#pragma once
4   -#include "controlcommand.h"
5   -#include "usbdevicedefinitions.h"
6   -
7   -/// \brief The CONTROL_GETSPEED parser.
8   -class ControlGetSpeed : public ControlCommand {
9   - public:
10   - ControlGetSpeed();
11   - /// \brief Gets the speed of the connection.
12   - /// \return The speed level of the USB connection.
13   - ConnectionSpeed getSpeed();
14   -};
openhantek/src/usb/usbdevice.cpp
... ... @@ -6,20 +6,19 @@
6 6  
7 7 #include "usbdevice.h"
8 8  
9   -#include "hantekprotocol/controlStructs.h"
10 9 #include "hantekprotocol/bulkStructs.h"
11   -#include "controlgetspeed.h"
  10 +#include "hantekprotocol/controlStructs.h"
12 11 #include "models.h"
13 12 #include "utils/printutils.h"
14 13  
15 14 UniqueUSBid USBDevice::computeUSBdeviceID(libusb_device *device) {
16   - UniqueUSBid v=0;
17   - libusb_get_port_numbers(device, (uint8_t*)&v, sizeof(v));
  15 + UniqueUSBid v = 0;
  16 + libusb_get_port_numbers(device, (uint8_t *)&v, sizeof(v));
18 17 return v;
19 18 }
20 19  
21   -USBDevice::USBDevice(DSOModel *model, libusb_device *device, unsigned findIteration) :
22   - model(model), device(device), findIteration(findIteration), uniqueUSBdeviceID(computeUSBdeviceID(device)) {
  20 +USBDevice::USBDevice(DSOModel *model, libusb_device *device, unsigned findIteration)
  21 + : model(model), device(device), findIteration(findIteration), uniqueUSBdeviceID(computeUSBdeviceID(device)) {
23 22 libusb_ref_device(device);
24 23 libusb_get_device_descriptor(device, &descriptor);
25 24 }
... ... @@ -115,15 +114,9 @@ bool USBDevice::needsFirmware() {
115 114 return this->descriptor.idProduct != model->productID || this->descriptor.idVendor != model->vendorID;
116 115 }
117 116  
118   -void USBDevice::setFindIteration(unsigned iteration)
119   -{
120   - findIteration = iteration;
121   -}
  117 +void USBDevice::setFindIteration(unsigned iteration) { findIteration = iteration; }
122 118  
123   -unsigned USBDevice::getFindIteration() const
124   -{
125   - return findIteration;
126   -}
  119 +unsigned USBDevice::getFindIteration() const { return findIteration; }
127 120  
128 121 int USBDevice::bulkTransfer(unsigned char endpoint, const unsigned char *data, unsigned int length, int attempts,
129 122 unsigned int timeout) {
... ... @@ -132,7 +125,8 @@ int USBDevice::bulkTransfer(unsigned char endpoint, const unsigned char *data, u
132 125 int errorCode = LIBUSB_ERROR_TIMEOUT;
133 126 int transferred = 0;
134 127 for (int attempt = 0; (attempt < attempts || attempts == -1) && errorCode == LIBUSB_ERROR_TIMEOUT; ++attempt)
135   - errorCode = libusb_bulk_transfer(this->handle, endpoint, (unsigned char*) data, (int)length, &transferred, timeout);
  128 + errorCode =
  129 + libusb_bulk_transfer(this->handle, endpoint, (unsigned char *)data, (int)length, &transferred, timeout);
136 130  
137 131 if (errorCode == LIBUSB_ERROR_NO_DEVICE) disconnectFromDevice();
138 132 if (errorCode < 0)
... ... @@ -142,55 +136,27 @@ int USBDevice::bulkTransfer(unsigned char endpoint, const unsigned char *data, u
142 136 }
143 137  
144 138 int USBDevice::bulkWrite(const unsigned char *data, unsigned int length, int attempts) {
145   - if (!this->handle) return LIBUSB_ERROR_NO_DEVICE;
146   -
147   - int errorCode = this->getConnectionSpeed();
148   - if (errorCode < 0) return errorCode;
149   -
150   - return this->bulkTransfer(HANTEK_EP_OUT, data, length, attempts);
  139 + return bulkTransfer(HANTEK_EP_OUT, data, length, attempts);
151 140 }
152 141  
153   -int USBDevice::bulkRead(unsigned char *data, unsigned int length, int attempts) {
154   - if (!this->handle) return LIBUSB_ERROR_NO_DEVICE;
155   -
156   - int errorCode = this->getConnectionSpeed();
157   - if (errorCode < 0) return errorCode;
158   -
159   - return this->bulkTransfer(HANTEK_EP_IN, data, length, attempts);
160   -}
161   -
162   -int USBDevice::bulkCommand(const DataArray<unsigned char> *command, int attempts) {
163   - if (!this->handle) return LIBUSB_ERROR_NO_DEVICE;
164   -
165   - if (!allowBulkTransfer) return LIBUSB_SUCCESS;
166   -
167   - // Send BeginCommand control command
168   - int errorCode = this->controlWrite(&beginCommandControl);
169   - if (errorCode < 0) return errorCode;
170   -
171   - // Send bulk command
172   - return this->bulkWrite(command->data(), command->getSize(), attempts);
  142 +int USBDevice::bulkRead(const DataArray<unsigned char> *command, int attempts) {
  143 + return bulkTransfer(HANTEK_EP_IN, command->data(), command->getSize(), attempts);
173 144 }
174 145  
175 146 int USBDevice::bulkReadMulti(unsigned char *data, unsigned length, int attempts) {
176 147 if (!this->handle) return LIBUSB_ERROR_NO_DEVICE;
177 148  
178   - int errorCode = 0;
179   -
180   - errorCode = this->getConnectionSpeed();
181   - if (errorCode < 0) return errorCode;
182   -
183   - errorCode = this->inPacketLength;
  149 + int errorCode = this->inPacketLength;
184 150 unsigned int packet, received = 0;
185 151 for (packet = 0; received < length && errorCode == this->inPacketLength; ++packet) {
186 152 errorCode = this->bulkTransfer(HANTEK_EP_IN, data + packet * this->inPacketLength,
187 153 qMin(length - received, (unsigned int)this->inPacketLength), attempts,
188 154 HANTEK_TIMEOUT_MULTI);
189   - if (errorCode > 0) received += errorCode;
  155 + if (errorCode > 0) received += (unsigned)errorCode;
190 156 }
191 157  
192 158 if (received > 0)
193   - return received;
  159 + return (int)received;
194 160 else
195 161 return errorCode;
196 162 }
... ... @@ -207,51 +173,23 @@ int USBDevice::controlTransfer(unsigned char type, unsigned char request, unsign
207 173 return errorCode;
208 174 }
209 175  
210   -int USBDevice::controlWrite(const ControlCommand* command) {
  176 +int USBDevice::controlWrite(const ControlCommand *command) {
211 177 if (!this->handle) return LIBUSB_ERROR_NO_DEVICE;
212   - // std::cout << "control" << (int)request << " l:"<<length<<" d:"<<(int)data[0] << std::endl;
213   - return this->controlTransfer(LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT,
214   - (uint8_t)command->code, command->data(), command->getSize(), command->value, 0, HANTEK_ATTEMPTS);
  178 + return controlTransfer(LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, (uint8_t)command->code, command->data(),
  179 + command->getSize(), command->value, 0, HANTEK_ATTEMPTS);
215 180 }
216 181  
217 182 int USBDevice::controlRead(const ControlCommand *command) {
218 183 if (!this->handle) return LIBUSB_ERROR_NO_DEVICE;
219 184  
220   - return this->controlTransfer(LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN,
221   - (uint8_t)command->code, command->data(), command->getSize(), command->value, 0, HANTEK_ATTEMPTS);
222   -}
223   -
224   -int USBDevice::getConnectionSpeed() {
225   - int errorCode;
226   - ControlGetSpeed response;
227   - errorCode = this->controlRead(&response);
228   - if (errorCode < 0) return errorCode;
229   -
230   - return response.getSpeed();
231   -}
232   -
233   -int USBDevice::getPacketSize() {
234   - const int s = this->getConnectionSpeed();
235   - if (s == CONNECTION_FULLSPEED)
236   - return 64;
237   - else if (s == CONNECTION_HIGHSPEED)
238   - return 512;
239   - else if (s > CONNECTION_HIGHSPEED) {
240   - std::cerr << "Unknown USB speed. Please correct source code in USBDevice::getPacketSize()" << std::endl;
241   - throw new std::runtime_error("Unknown USB speed");
242   - } else if (s<0) return s;
243   - return 0;
  185 + return controlTransfer(LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN, (uint8_t)command->code, command->data(),
  186 + command->getSize(), command->value, 0, HANTEK_ATTEMPTS);
244 187 }
245 188  
246 189 libusb_device *USBDevice::getRawDevice() const { return device; }
247 190  
248   -unsigned long USBDevice::getUniqueUSBDeviceID() const
249   -{
250   - return uniqueUSBdeviceID;
251   -}
252   -
253   -const DSOModel* USBDevice::getModel() const { return model; }
  191 +unsigned long USBDevice::getUniqueUSBDeviceID() const { return uniqueUSBdeviceID; }
254 192  
255   -void USBDevice::setEnableBulkTransfer(bool enable) { allowBulkTransfer = enable; }
  193 +const DSOModel *USBDevice::getModel() const { return model; }
256 194  
257 195 void USBDevice::overwriteInPacketLength(int len) { inPacketLength = len; }
... ...
openhantek/src/usb/usbdevice.h
... ... @@ -8,7 +8,7 @@
8 8 #include <memory>
9 9  
10 10 #include "usbdevicedefinitions.h"
11   -#include "controlbegin.h"
  11 +#include "dataarray.h"
12 12  
13 13 class DSOModel;
14 14 class ControlCommand;
... ... @@ -65,13 +65,7 @@ class USBDevice : public QObject {
65 65 /// \param length The length of the packet.
66 66 /// \param attempts The number of attempts, that are done on timeouts.
67 67 /// \return Number of received bytes on success, libusb error code on error.
68   - int bulkRead(unsigned char *data, unsigned int length, int attempts = HANTEK_ATTEMPTS);
69   -
70   - /// \brief Send a bulk command to the oscilloscope.
71   - /// \param command The command, that should be sent.
72   - /// \param attempts The number of attempts, that are done on timeouts.
73   - /// \return Number of sent bytes on success, libusb error code on error.
74   - int bulkCommand(const DataArray<unsigned char> *command, int attempts = HANTEK_ATTEMPTS);
  68 + int bulkRead(const DataArray<unsigned char> *command, int attempts = HANTEK_ATTEMPTS);
75 69  
76 70 /// \brief Multi packet bulk read from the oscilloscope.
77 71 /// \param data Buffer for the sent/recieved data.
... ... @@ -93,33 +87,15 @@ class USBDevice : public QObject {
93 87 int index, int attempts = HANTEK_ATTEMPTS);
94 88  
95 89 /// \brief Control write to the oscilloscope.
96   - /// \param request The request field of the packet.
97   - /// \param data Buffer for the sent/recieved data.
98   - /// \param length The length field of the packet.
99   - /// \param value The value field of the packet.
100   - /// \param index The index field of the packet.
101   - /// \param attempts The number of attempts, that are done on timeouts.
  90 + /// \param command Buffer for the sent/recieved data.
102 91 /// \return Number of sent bytes on success, libusb error code on error.
103 92 int controlWrite(const ControlCommand *command);
104 93  
105 94 /// \brief Control read to the oscilloscope.
106   - /// \param request The request field of the packet.
107   - /// \param data Buffer for the sent/recieved data.
108   - /// \param length The length field of the packet.
109   - /// \param value The value field of the packet.
110   - /// \param index The index field of the packet.
111   - /// \param attempts The number of attempts, that are done on timeouts.
  95 + /// \param command Buffer for the sent/recieved data.
112 96 /// \return Number of received bytes on success, libusb error code on error.
113 97 int controlRead(const ControlCommand *command);
114 98  
115   - /// \brief Gets the speed of the connection.
116   - /// \return The ::ConnectionSpeed of the USB connection.
117   - int getConnectionSpeed();
118   -
119   - /// \brief Gets the maximum size of one packet transmitted via bulk transfer.
120   - /// \return The maximum packet size in bytes, negative libusb error code on error.
121   - int getPacketSize();
122   -
123 99 /**
124 100 * @return Returns the raw libusb device
125 101 */
... ... @@ -141,13 +117,11 @@ class USBDevice : public QObject {
141 117 /// \brief Get the oscilloscope model.
142 118 /// \return The ::Model of the connected Hantek DSO.
143 119 const DSOModel *getModel() const;
144   - void setEnableBulkTransfer(bool enable);
145 120 void overwriteInPacketLength(int len);
146 121 protected:
147 122 int claimInterface(const libusb_interface_descriptor *interfaceDescriptor, int endpointOut, int endPointIn);
148 123  
149   - // Command buffers
150   - ControlBeginCommand beginCommandControl;
  124 + // Device model data
151 125 DSOModel* model;
152 126  
153 127 // Libusb specific variables
... ... @@ -159,7 +133,6 @@ class USBDevice : public QObject {
159 133 int interface;
160 134 int outPacketLength; ///< Packet length for the OUT endpoint
161 135 int inPacketLength; ///< Packet length for the IN endpoint
162   - bool allowBulkTransfer = true;
163 136 signals:
164 137 void deviceDisconnected(); ///< The device has been disconnected
165 138 };
... ...