Commit f97d46677f12b808621914d1caf46c080434e955
1 parent
926ac526
Completed libusb 0.1 downward compatibility, added the basic stuff for the XY-mo…
…de and fixed a small bug
Showing
7 changed files
with
249 additions
and
216 deletions
openhantek/ChangeLog
| ... | ... | @@ -27,4 +27,9 @@ |
| 27 | 27 | |
| 28 | 28 | 2010-08-06 Oliver Haag <oliver.haag@gmail.com> |
| 29 | 29 | * Bugfix: Mode shown below scope instead of coupling for the math channel |
| 30 | -* Documentation updated | |
| 31 | 30 | \ No newline at end of file |
| 31 | +* Documentation updated | |
| 32 | + | |
| 33 | +2010-08-16 Oliver Haag <oliver.haag@gmail.com> | |
| 34 | +* Completed libusb 0.1 downwards compatibility mode (env LIBUSB_VERSION=0) | |
| 35 | +* Bugfix: Grid of scopes drawn even if there aren't any graphs available | |
| 36 | +* Implemented basics of the XY-mode | |
| 32 | 37 | \ No newline at end of file | ... | ... |
openhantek/OpenHantek.pro
| ... | ... | @@ -80,7 +80,7 @@ UI_DIR = build/ui |
| 80 | 80 | MOC_DIR = build/moc |
| 81 | 81 | |
| 82 | 82 | # Include directory |
| 83 | -QMAKE_CXXFLAGS += "-iquote src" | |
| 83 | +QMAKE_CXXFLAGS += "-iquote $${IN_PWD}/src" | |
| 84 | 84 | |
| 85 | 85 | # libusb version |
| 86 | 86 | LIBUSB_VERSION = $$(LIBUSB_VERSION) |
| ... | ... | @@ -88,7 +88,6 @@ contains(LIBUSB_VERSION, 0):LIBS += -lusb |
| 88 | 88 | else { |
| 89 | 89 | LIBUSB_VERSION = 1 |
| 90 | 90 | LIBS += -lusb-1.0 |
| 91 | - DEFINES += LIBUSB_VERSION=1 | |
| 92 | 91 | } |
| 93 | 92 | DEFINES += LIBUSB_VERSION=$${LIBUSB_VERSION} |
| 94 | 93 | |
| ... | ... | @@ -141,4 +140,4 @@ doxygen.commands = rm \ |
| 141 | 140 | doxygen.depends = $${SOURCES} \ |
| 142 | 141 | $${HEADERS} \ |
| 143 | 142 | $${DOXYFILES} |
| 144 | -QMAKE_EXTRA_UNIX_TARGETS += doxygen | |
| 143 | +QMAKE_EXTRA_TARGETS += doxygen | ... | ... |
openhantek/src/glgenerator.cpp
| ... | ... | @@ -59,9 +59,8 @@ void GlArray::setSize(unsigned long int size) { |
| 59 | 59 | if(this->size == size) |
| 60 | 60 | return; |
| 61 | 61 | |
| 62 | - if(this->data) { | |
| 62 | + if(this->data) | |
| 63 | 63 | delete[] this->data; |
| 64 | - } | |
| 65 | 64 | if(size) |
| 66 | 65 | this->data = new GLfloat[size]; |
| 67 | 66 | else |
| ... | ... | @@ -140,7 +139,7 @@ void GlGenerator::generateGraphs() { |
| 140 | 139 | case Dso::GRAPHFORMAT_TY: |
| 141 | 140 | // Add graphs for channels |
| 142 | 141 | for(int mode = Dso::CHANNELMODE_VOLTAGE; mode < Dso::CHANNELMODE_COUNT; mode++) { |
| 143 | - for(int channel = 0 ; channel < this->settings->scope.voltage.count(); channel++) { | |
| 142 | + for(int channel = 0; channel < this->settings->scope.voltage.count(); channel++) { | |
| 144 | 143 | // Check if this channel is used and available at the data analyzer |
| 145 | 144 | if(((mode == Dso::CHANNELMODE_VOLTAGE) ? this->settings->scope.voltage[channel].used : this->settings->scope.spectrum[channel].used) && this->dataAnalyzer->data(channel)->samples.voltage.sample) { |
| 146 | 145 | // Check if the sample count has changed |
| ... | ... | @@ -188,6 +187,41 @@ void GlGenerator::generateGraphs() { |
| 188 | 187 | break; |
| 189 | 188 | |
| 190 | 189 | case Dso::GRAPHFORMAT_XY: |
| 190 | + for(int channel = 0; channel < this->settings->scope.voltage.count(); channel ++) { | |
| 191 | + // For even channel numbers check if this channel is used and this and the following channel are available at the data analyzer | |
| 192 | + if(channel % 2 == 0 && channel + 1 < this->settings->scope.voltage.count() && this->settings->scope.voltage[channel].used && this->dataAnalyzer->data(channel)->samples.voltage.sample && this->dataAnalyzer->data(channel + 1)->samples.voltage.sample) { | |
| 193 | + // Check if the sample count has changed | |
| 194 | + unsigned int neededSize = qMin(this->dataAnalyzer->data(channel)->samples.voltage.count, this->dataAnalyzer->data(channel + 1)->samples.voltage.count) * 2; | |
| 195 | + for(int index = 0; index < this->digitalPhosphorDepth; index++) { | |
| 196 | + if(this->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel][index]->getSize() != neededSize) | |
| 197 | + this->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel][index]->setSize(0); | |
| 198 | + } | |
| 199 | + | |
| 200 | + // Check if the array is allocated | |
| 201 | + if(!this->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel].first()->data) | |
| 202 | + this->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel].first()->setSize(neededSize); | |
| 203 | + | |
| 204 | + GLfloat *vaNewChannel = this->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel].first()->data; | |
| 205 | + | |
| 206 | + // Fill vector array | |
| 207 | + unsigned int arrayPosition = 0; | |
| 208 | + unsigned int xChannel = channel; | |
| 209 | + unsigned int yChannel = channel + 1; | |
| 210 | + for(unsigned int position = 0; position < this->dataAnalyzer->data(channel)->samples.voltage.count; position++) { | |
| 211 | + vaNewChannel[arrayPosition++] = this->dataAnalyzer->data(xChannel)->samples.voltage.sample[position] / this->settings->scope.voltage[xChannel].gain + this->settings->scope.voltage[xChannel].offset; | |
| 212 | + vaNewChannel[arrayPosition++] = this->dataAnalyzer->data(yChannel)->samples.voltage.sample[position] / this->settings->scope.voltage[yChannel].gain + this->settings->scope.voltage[yChannel].offset; | |
| 213 | + } | |
| 214 | + } | |
| 215 | + else { | |
| 216 | + // Delete all vector arrays | |
| 217 | + for(int index = 0; index < this->digitalPhosphorDepth; index++) | |
| 218 | + this->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel][index]->setSize(0); | |
| 219 | + } | |
| 220 | + | |
| 221 | + // Delete all spectrum graphs | |
| 222 | + for(int index = 0; index < this->digitalPhosphorDepth; index++) | |
| 223 | + this->vaChannel[Dso::CHANNELMODE_SPECTRUM][channel][index]->setSize(0); | |
| 224 | + } | |
| 191 | 225 | break; |
| 192 | 226 | } |
| 193 | 227 | ... | ... |
openhantek/src/glscope.cpp
| ... | ... | @@ -70,68 +70,84 @@ void GlScope::initializeGL() { |
| 70 | 70 | |
| 71 | 71 | /// \brief Draw the graphs and the grid. |
| 72 | 72 | void GlScope::paintGL() { |
| 73 | - if(!this->generator || !this->isVisible()) | |
| 73 | + if(!this->isVisible()) | |
| 74 | 74 | return; |
| 75 | 75 | |
| 76 | 76 | // Clear OpenGL buffer and configure settings |
| 77 | 77 | glClear(GL_COLOR_BUFFER_BIT); |
| 78 | 78 | glLineWidth(1); |
| 79 | - if(this->settings->view.antialiasing) { | |
| 80 | - glEnable(GL_POINT_SMOOTH); | |
| 81 | - glEnable(GL_LINE_SMOOTH); | |
| 82 | - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); | |
| 83 | - } | |
| 84 | - | |
| 85 | - // Apply zoom settings via matrix transformation | |
| 86 | - if(this->zoomed) { | |
| 87 | - glPushMatrix(); | |
| 88 | - glScalef(DIVS_TIME / fabs(this->settings->scope.horizontal.marker[1] - this->settings->scope.horizontal.marker[0]), 1.0, 1.0); | |
| 89 | - glTranslatef(-(this->settings->scope.horizontal.marker[0] + this->settings->scope.horizontal.marker[1]) / 2, 0.0, 0.0); | |
| 90 | - } | |
| 91 | 79 | |
| 92 | - // Values we need for the fading of the digital phosphor | |
| 93 | - double *fadingFactor = new double[this->generator->digitalPhosphorDepth]; | |
| 94 | - fadingFactor[0] = 100; | |
| 95 | - double fadingRatio = pow(10.0, 2.0 / this->generator->digitalPhosphorDepth); | |
| 96 | - for(int index = 1; index < this->generator->digitalPhosphorDepth; index++) | |
| 97 | - fadingFactor[index] = fadingFactor[index - 1] * fadingRatio; | |
| 98 | - | |
| 99 | - switch(this->settings->scope.horizontal.format) { | |
| 100 | - case Dso::GRAPHFORMAT_TY: { | |
| 101 | - // Real and virtual channels | |
| 102 | - for(int mode = Dso::CHANNELMODE_VOLTAGE; mode < Dso::CHANNELMODE_COUNT; mode++) { | |
| 103 | - for(int channel = 0; channel < this->settings->scope.voltage.count(); channel++) { | |
| 104 | - if((mode == Dso::CHANNELMODE_VOLTAGE) ? this->settings->scope.voltage[channel].used : this->settings->scope.spectrum[channel].used) { | |
| 80 | + // Draw the graphs | |
| 81 | + if(this->generator && this->generator->digitalPhosphorDepth > 0) { | |
| 82 | + if(this->settings->view.antialiasing) { | |
| 83 | + glEnable(GL_POINT_SMOOTH); | |
| 84 | + glEnable(GL_LINE_SMOOTH); | |
| 85 | + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); | |
| 86 | + } | |
| 87 | + | |
| 88 | + // Apply zoom settings via matrix transformation | |
| 89 | + if(this->zoomed) { | |
| 90 | + glPushMatrix(); | |
| 91 | + glScalef(DIVS_TIME / fabs(this->settings->scope.horizontal.marker[1] - this->settings->scope.horizontal.marker[0]), 1.0, 1.0); | |
| 92 | + glTranslatef(-(this->settings->scope.horizontal.marker[0] + this->settings->scope.horizontal.marker[1]) / 2, 0.0, 0.0); | |
| 93 | + } | |
| 94 | + | |
| 95 | + // Values we need for the fading of the digital phosphor | |
| 96 | + double *fadingFactor = new double[this->generator->digitalPhosphorDepth]; | |
| 97 | + fadingFactor[0] = 100; | |
| 98 | + double fadingRatio = pow(10.0, 2.0 / this->generator->digitalPhosphorDepth); | |
| 99 | + for(int index = 1; index < this->generator->digitalPhosphorDepth; index++) | |
| 100 | + fadingFactor[index] = fadingFactor[index - 1] * fadingRatio; | |
| 101 | + | |
| 102 | + switch(this->settings->scope.horizontal.format) { | |
| 103 | + case Dso::GRAPHFORMAT_TY: | |
| 104 | + // Real and virtual channels | |
| 105 | + for(int mode = Dso::CHANNELMODE_VOLTAGE; mode < Dso::CHANNELMODE_COUNT; mode++) { | |
| 106 | + for(int channel = 0; channel < this->settings->scope.voltage.count(); channel++) { | |
| 107 | + if((mode == Dso::CHANNELMODE_VOLTAGE) ? this->settings->scope.voltage[channel].used : this->settings->scope.spectrum[channel].used) { | |
| 108 | + // Draw graph for all available depths | |
| 109 | + for(int index = this->generator->digitalPhosphorDepth - 1; index >= 0; index--) { | |
| 110 | + if(this->generator->vaChannel[mode][channel][index]->data) { | |
| 111 | + if(mode == Dso::CHANNELMODE_VOLTAGE) | |
| 112 | + this->qglColor(this->settings->view.color.screen.voltage[channel].darker(fadingFactor[index])); | |
| 113 | + else | |
| 114 | + this->qglColor(this->settings->view.color.screen.spectrum[channel].darker(fadingFactor[index])); | |
| 115 | + glVertexPointer(2, GL_FLOAT, 0, this->generator->vaChannel[mode][channel][index]->data); | |
| 116 | + glDrawArrays((this->settings->view.interpolation == INTERPOLATION_OFF) ? GL_POINTS : GL_LINE_STRIP, 0, this->generator->vaChannel[mode][channel][index]->getSize() / 2); | |
| 117 | + } | |
| 118 | + } | |
| 119 | + } | |
| 120 | + } | |
| 121 | + } | |
| 122 | + break; | |
| 123 | + | |
| 124 | + case Dso::GRAPHFORMAT_XY: | |
| 125 | + // Real and virtual channels | |
| 126 | + for(int channel = 0; channel < this->settings->scope.voltage.count() - 1; channel += 2) { | |
| 127 | + if(this->settings->scope.voltage[channel].used) { | |
| 105 | 128 | // Draw graph for all available depths |
| 106 | 129 | for(int index = this->generator->digitalPhosphorDepth - 1; index >= 0; index--) { |
| 107 | - if(this->generator->vaChannel[mode][channel][index]->data) { | |
| 108 | - if(mode == Dso::CHANNELMODE_VOLTAGE) | |
| 109 | - this->qglColor(this->settings->view.color.screen.voltage[channel].darker(fadingFactor[index])); | |
| 110 | - else | |
| 111 | - this->qglColor(this->settings->view.color.screen.spectrum[channel].darker(fadingFactor[index])); | |
| 112 | - glVertexPointer(2, GL_FLOAT, 0, this->generator->vaChannel[mode][channel][index]->data); | |
| 113 | - glDrawArrays((this->settings->view.interpolation == INTERPOLATION_OFF) ? GL_POINTS : GL_LINE_STRIP, 0, this->generator->vaChannel[mode][channel][index]->getSize() / 2); | |
| 130 | + if(this->generator->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel][index]->data) { | |
| 131 | + this->qglColor(this->settings->view.color.screen.voltage[channel].darker(fadingFactor[index])); | |
| 132 | + glVertexPointer(2, GL_FLOAT, 0, this->generator->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel][index]->data); | |
| 133 | + glDrawArrays((this->settings->view.interpolation == INTERPOLATION_OFF) ? GL_POINTS : GL_LINE_STRIP, 0, this->generator->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel][index]->getSize() / 2); | |
| 114 | 134 | } |
| 115 | 135 | } |
| 116 | 136 | } |
| 117 | 137 | } |
| 118 | - } | |
| 119 | - | |
| 120 | - delete[] fadingFactor; | |
| 121 | - | |
| 122 | - break; | |
| 138 | + break; | |
| 123 | 139 | } |
| 124 | 140 | |
| 125 | - case Dso::GRAPHFORMAT_XY: | |
| 126 | - break; | |
| 141 | + delete[] fadingFactor; | |
| 142 | + | |
| 143 | + glDisable(GL_POINT_SMOOTH); | |
| 144 | + glDisable(GL_LINE_SMOOTH); | |
| 145 | + | |
| 146 | + if(this->zoomed) | |
| 147 | + glPopMatrix(); | |
| 127 | 148 | } |
| 128 | 149 | |
| 129 | - glDisable(GL_POINT_SMOOTH); | |
| 130 | - glDisable(GL_LINE_SMOOTH); | |
| 131 | - | |
| 132 | - if(this->zoomed) | |
| 133 | - glPopMatrix(); | |
| 134 | - else { | |
| 150 | + if(!this->zoomed) { | |
| 135 | 151 | // Draw vertical lines at marker positions |
| 136 | 152 | glEnable(GL_LINE_STIPPLE); |
| 137 | 153 | this->qglColor(this->settings->view.color.screen.markers); | ... | ... |
openhantek/src/hantek/device.cpp
| ... | ... | @@ -49,7 +49,13 @@ namespace Hantek { |
| 49 | 49 | |
| 50 | 50 | this->handle = 0; |
| 51 | 51 | this->interface = -1; |
| 52 | + | |
| 53 | +#if LIBUSB_VERSION == 0 | |
| 54 | + usb_init(); | |
| 55 | + this->error = LIBUSB_SUCCESS; | |
| 56 | +#else | |
| 52 | 57 | this->error = libusb_init(&(this->context)); |
| 58 | +#endif | |
| 53 | 59 | } |
| 54 | 60 | |
| 55 | 61 | /// \brief Disconnects the device. |
| ... | ... | @@ -61,120 +67,98 @@ namespace Hantek { |
| 61 | 67 | /// \return A string with the result of the search. |
| 62 | 68 | QString Device::search() { |
| 63 | 69 | if(this->error) |
| 64 | - return tr("Can't search for Hantek oscilloscopes: ").arg(Helper::libUsbErrorString(this->error)); | |
| 70 | + return tr("Can't search for Hantek oscilloscopes: %1").arg(Helper::libUsbErrorString(this->error)); | |
| 71 | + | |
| 65 | 72 | QString message; |
| 73 | + QString deviceAddress; | |
| 74 | + int errorCode = LIBUSB_SUCCESS; | |
| 66 | 75 | |
| 67 | 76 | #if LIBUSB_VERSION == 0 |
| 68 | - usb_init(); | |
| 69 | - usb_find_busses(); | |
| 70 | - usb_find_devices(); | |
| 71 | - | |
| 72 | - struct usb_device *usbDSO = NULL; | |
| 73 | - for (struct usb_bus *usb_bus = usb_busses; usb_bus; usb_bus = usb_bus->next) | |
| 74 | - { | |
| 75 | - for (struct usb_device *dev = usb_bus->devices; dev; dev = dev->next) | |
| 76 | - { | |
| 77 | - if (dev->descriptor.idVendor == deviceVendor) | |
| 78 | - { | |
| 79 | - for (int i = 0; deviceModelsList[i] != DSO_LAST; i++) | |
| 80 | - { | |
| 81 | - if (dev->descriptor.idProduct == deviceModelsList[i]) | |
| 82 | - { | |
| 83 | - usbDSO = dev; | |
| 84 | - deviceModel = dev->descriptor.idProduct; | |
| 85 | - qDebug("Hantek DSO model %4X found", deviceModel); | |
| 86 | - break; | |
| 87 | - } | |
| 88 | - } | |
| 77 | + errorCode = usb_find_busses(); | |
| 78 | + if(errorCode >= 0) | |
| 79 | + errorCode = usb_find_devices(); | |
| 80 | + if(errorCode < 0) | |
| 81 | + return tr("Failed to get device list: %3").arg(Helper::libUsbErrorString(errorCode)); | |
| 82 | + | |
| 83 | + struct usb_device *device = NULL; | |
| 84 | + | |
| 85 | + // Iterate through all usb devices | |
| 86 | + for(struct usb_bus *bus = usb_busses; bus; bus = bus->next) { | |
| 87 | + for(device = bus->devices; device; device = device->next) { | |
| 88 | + // Check VID and PID | |
| 89 | + if(device->descriptor.idVendor == HANTEK_VENDOR_ID) { | |
| 90 | + this->model = (Model) this->modelIds.indexOf(device->descriptor.idProduct); | |
| 91 | + if(this->model >= 0) | |
| 92 | + break; // Found a compatible device, ignore others | |
| 89 | 93 | } |
| 90 | 94 | } |
| 95 | + if(this->model >= 0) { | |
| 96 | + deviceAddress = QString("%1:%2").arg(bus->dirname).arg(device->filename); | |
| 97 | + break; // Found a compatible device, ignore other busses | |
| 98 | + } | |
| 91 | 99 | } |
| 92 | - | |
| 93 | - if (usbDSO == NULL) | |
| 94 | - { | |
| 95 | - dsoIOMutex.unlock(); | |
| 96 | - qDebug("Hantek DSO not found"); | |
| 97 | - return -1; | |
| 98 | - } | |
| 99 | - | |
| 100 | - if ((deviceModel == DSO_5200) || (deviceModel == DSO_5200A)) | |
| 100 | + | |
| 101 | + /// \todo Use 9 bit data model of DSO-5200(A) | |
| 102 | + /* if ((deviceModel == DSO_5200) || (deviceModel == DSO_5200A)) | |
| 101 | 103 | { |
| 102 | 104 | extraBitsData = true; |
| 103 | 105 | qDebug("Using a 9-bita data model"); |
| 104 | - } | |
| 105 | - | |
| 106 | - usbDSOHandle = ::usb_open(usbDSO); | |
| 107 | - if (usbDSOHandle == NULL) | |
| 108 | - { | |
| 109 | - dsoIOMutex.unlock(); | |
| 110 | - qDebug("Can't open USB device"); | |
| 111 | - return -2; | |
| 112 | - } | |
| 106 | + }*/ | |
| 113 | 107 | |
| 114 | - struct usb_config_descriptor *usbConfig = usbDSO->config; | |
| 115 | - for (int i = 0; i < usbConfig->bNumInterfaces; i++) | |
| 116 | - { | |
| 117 | - struct usb_interface *usbInterface = &usbConfig->interface[i]; | |
| 118 | - if (usbInterface->num_altsetting < 1) | |
| 119 | - continue; | |
| 120 | - | |
| 121 | - struct usb_interface_descriptor *usbInterfaceDescr = &usbInterface->altsetting[0]; | |
| 122 | - if (usbInterfaceDescr->bInterfaceClass == USB_CLASS_VENDOR_SPEC | |
| 123 | - && usbInterfaceDescr->bInterfaceSubClass == 0 | |
| 124 | - && usbInterfaceDescr->bInterfaceProtocol == 0 | |
| 125 | - && usbInterfaceDescr->bNumEndpoints == 2) | |
| 126 | - { | |
| 127 | - if (::usb_claim_interface(usbDSOHandle, usbInterfaceDescr->bInterfaceNumber)) | |
| 128 | - { | |
| 129 | - if (::usb_close(usbDSOHandle)) | |
| 130 | - { | |
| 131 | - qDebug("Can't close USB handle"); | |
| 132 | - } | |
| 133 | - | |
| 134 | - dsoIOMutex.unlock(); | |
| 135 | - qDebug("Not able to claim USB interface"); | |
| 136 | - return -3; | |
| 137 | - } | |
| 138 | - | |
| 139 | - interfaceNumber = usbInterfaceDescr->bInterfaceNumber; | |
| 140 | - interfaceIsClaimed = true; | |
| 141 | - | |
| 142 | - for (int i = 0; i < usbInterfaceDescr->bNumEndpoints; i++) | |
| 143 | - { | |
| 144 | - usb_endpoint_descriptor *usbEndpointDescr = &usbInterfaceDescr->endpoint[i]; | |
| 145 | - switch (usbEndpointDescr->bEndpointAddress) | |
| 146 | - { | |
| 147 | - case 0x02: // EP OUT | |
| 148 | - epOutMaxPacketLen = usbEndpointDescr->wMaxPacketSize; | |
| 149 | - qDebug("EP OUT MaxPacketLen = %i", epOutMaxPacketLen); | |
| 150 | - break; | |
| 151 | - case 0x86: // EP IN | |
| 152 | - epInMaxPacketLen = usbEndpointDescr->wMaxPacketSize; | |
| 153 | - qDebug("EP IN MaxPacketLen = %i", epInMaxPacketLen); | |
| 154 | - break; | |
| 155 | - default: | |
| 156 | - qDebug("Unknown endpoint #%02X", usbEndpointDescr->bEndpointAddress); | |
| 108 | + if(this->model >= 0) { | |
| 109 | + // Open device | |
| 110 | + deviceAddress = QString("%1:%2").arg(device->bus->location, 3, 10, QLatin1Char('0')).arg(device->devnum, 3, 10, QLatin1Char('0')); | |
| 111 | + this->handle = usb_open(device); | |
| 112 | + if(this->handle) { | |
| 113 | + struct usb_config_descriptor *configDescriptor = device->config; | |
| 114 | + struct usb_interface *interface; | |
| 115 | + struct usb_interface_descriptor *interfaceDescriptor; | |
| 116 | + for(int interfaceIndex = 0; interfaceIndex < configDescriptor->bNumInterfaces; interfaceIndex++) { | |
| 117 | + interface = &configDescriptor->interface[interfaceIndex]; | |
| 118 | + if(interface->num_altsetting < 1) | |
| 119 | + continue; | |
| 120 | + | |
| 121 | + interfaceDescriptor = &interface->altsetting[0]; | |
| 122 | + if(interfaceDescriptor->bInterfaceClass == USB_CLASS_VENDOR_SPEC && interfaceDescriptor->bInterfaceSubClass == 0 && interfaceDescriptor->bInterfaceProtocol == 0 && interfaceDescriptor->bNumEndpoints == 2) { | |
| 123 | + // That's the interface we need, claim it | |
| 124 | + errorCode = usb_claim_interface(this->handle, interfaceDescriptor->bInterfaceNumber); | |
| 125 | + if(errorCode < 0) { | |
| 126 | + usb_close(this->handle); | |
| 127 | + this->handle = 0; | |
| 128 | + message = tr("Failed to claim interface %1 of device %2: %3").arg(QString::number(interfaceDescriptor->bInterfaceNumber), deviceAddress, Helper::libUsbErrorString(errorCode)); | |
| 129 | + } | |
| 130 | + else { | |
| 131 | + this->interface = interfaceDescriptor->bInterfaceNumber; | |
| 132 | + | |
| 133 | + // Check the maximum endpoint packet size | |
| 134 | + usb_endpoint_descriptor *endpointDescriptor; | |
| 135 | + this->outPacketLength = 0; | |
| 136 | + this->inPacketLength = 0; | |
| 137 | + for (int endpoint = 0; endpoint < interfaceDescriptor->bNumEndpoints; endpoint++) { | |
| 138 | + endpointDescriptor = &interfaceDescriptor->endpoint[endpoint]; | |
| 139 | + switch(endpointDescriptor->bEndpointAddress) { | |
| 140 | + case HANTEK_EP_OUT: | |
| 141 | + this->outPacketLength = endpointDescriptor->wMaxPacketSize; | |
| 142 | + break; | |
| 143 | + case HANTEK_EP_IN: | |
| 144 | + this->inPacketLength = endpointDescriptor->wMaxPacketSize; | |
| 145 | + break; | |
| 146 | + } | |
| 147 | + } | |
| 148 | + message = tr("Device found: Hantek %1 (%2)").arg(this->modelStrings[this->model], deviceAddress); | |
| 149 | + emit connected(); | |
| 150 | + } | |
| 157 | 151 | } |
| 158 | 152 | } |
| 159 | - | |
| 160 | - break; | |
| 161 | 153 | } |
| 154 | + else | |
| 155 | + message = tr("Couldn't open device %1").arg(deviceAddress); | |
| 162 | 156 | } |
| 163 | - | |
| 164 | - if (!interfaceIsClaimed) | |
| 165 | - { | |
| 166 | - qDebug("Can't find USB interface (Class:0xFF, SubClass:0, Protocol:0) with two endpoints"); | |
| 167 | - return -4; | |
| 168 | - } | |
| 169 | - | |
| 170 | - dsoIOMutex.unlock(); | |
| 171 | - | |
| 172 | - return 0; | |
| 157 | + else | |
| 158 | + message = tr("No Hantek oscilloscope found"); | |
| 173 | 159 | #else |
| 174 | 160 | libusb_device **deviceList; |
| 175 | 161 | libusb_device *device; |
| 176 | - int errorCode = LIBUSB_SUCCESS; | |
| 177 | - QString deviceAddress; | |
| 178 | 162 | |
| 179 | 163 | if(this->handle) |
| 180 | 164 | libusb_close(this->handle); |
| ... | ... | @@ -258,9 +242,9 @@ namespace Hantek { |
| 258 | 242 | message = tr("No Hantek oscilloscope found"); |
| 259 | 243 | |
| 260 | 244 | libusb_free_device_list(deviceList, true); |
| 245 | +#endif | |
| 261 | 246 | |
| 262 | 247 | return message; |
| 263 | -#endif | |
| 264 | 248 | } |
| 265 | 249 | |
| 266 | 250 | /// \brief Disconnect the device. |
| ... | ... | @@ -269,11 +253,19 @@ namespace Hantek { |
| 269 | 253 | return; |
| 270 | 254 | |
| 271 | 255 | // Release claimed interface |
| 256 | +#if LIBUSB_VERSION == 0 | |
| 257 | + usb_release_interface(this->handle, this->interface); | |
| 258 | +#else | |
| 272 | 259 | libusb_release_interface(this->handle, this->interface); |
| 260 | +#endif | |
| 273 | 261 | this->interface = -1; |
| 274 | 262 | |
| 275 | 263 | // Close device handle |
| 264 | +#if LIBUSB_VERSION == 0 | |
| 265 | + usb_close(this->handle); | |
| 266 | +#else | |
| 276 | 267 | libusb_close(this->handle); |
| 268 | +#endif | |
| 277 | 269 | this->handle = 0; |
| 278 | 270 | |
| 279 | 271 | emit disconnected(); |
| ... | ... | @@ -324,20 +316,14 @@ namespace Hantek { |
| 324 | 316 | return errorCode; |
| 325 | 317 | |
| 326 | 318 | #if LIBUSB_VERSION == 0 |
| 327 | - int i, rv = -ETIMEDOUT; | |
| 328 | - for(i = 0; (rv == -ETIMEDOUT) && (i < attempts); i++) | |
| 329 | - { | |
| 330 | - rv = ::usb_bulk_write(usbDSOHandle, EP_BULK_OUT | USB_ENDPOINT_OUT, (char*)data, length, timeout); | |
| 331 | - } | |
| 319 | + errorCode = LIBUSB_ERROR_TIMEOUT; | |
| 320 | + for(int attempt = 0; (attempt < attempts || attempts == -1) && errorCode == LIBUSB_ERROR_TIMEOUT; attempt++) | |
| 321 | + errorCode = usb_bulk_write(this->handle, HANTEK_EP_OUT, (char *) data, length, HANTEK_TIMEOUT); | |
| 332 | 322 | |
| 333 | - if (rv < 0) | |
| 334 | - { | |
| 335 | - qDebug("Usb write bulk returns error %i", rv); | |
| 336 | - qDebug("Error: %s", ::usb_strerror()); | |
| 337 | - return rv; | |
| 338 | - } | |
| 323 | + if(errorCode == LIBUSB_ERROR_NO_DEVICE) | |
| 324 | + this->disconnect(); | |
| 339 | 325 | |
| 340 | - return 0; | |
| 326 | + return errorCode; | |
| 341 | 327 | #else |
| 342 | 328 | return this->bulkTransfer(HANTEK_EP_OUT, data, length, attempts); |
| 343 | 329 | #endif |
| ... | ... | @@ -357,20 +343,14 @@ namespace Hantek { |
| 357 | 343 | return errorCode; |
| 358 | 344 | |
| 359 | 345 | #if LIBUSB_VERSION == 0 |
| 360 | - int i, rv = -ETIMEDOUT; | |
| 361 | - for(i = 0; (rv == -ETIMEDOUT) && (i < attempts); i++) | |
| 362 | - { | |
| 363 | - rv = ::usb_bulk_read(usbDSOHandle, EP_BULK_IN | USB_ENDPOINT_IN, (char*)data, length, timeout); | |
| 364 | - } | |
| 346 | + errorCode = LIBUSB_ERROR_TIMEOUT; | |
| 347 | + for(int attempt = 0; (attempt < attempts || attempts == -1) && errorCode == LIBUSB_ERROR_TIMEOUT; attempt++) | |
| 348 | + errorCode = usb_bulk_read(this->handle, HANTEK_EP_IN, (char *) data, length, HANTEK_TIMEOUT); | |
| 365 | 349 | |
| 366 | - if (rv < 0) | |
| 367 | - { | |
| 368 | - qDebug("Usb read bulk returns error %i", rv); | |
| 369 | - qDebug("Error: %s", ::usb_strerror()); | |
| 370 | - return rv; | |
| 371 | - } | |
| 350 | + if(errorCode == LIBUSB_ERROR_NO_DEVICE) | |
| 351 | + this->disconnect(); | |
| 372 | 352 | |
| 373 | - return 0; | |
| 353 | + return errorCode; | |
| 374 | 354 | #else |
| 375 | 355 | return this->bulkTransfer(HANTEK_EP_IN, data, length, attempts); |
| 376 | 356 | #endif |
| ... | ... | @@ -412,8 +392,15 @@ namespace Hantek { |
| 412 | 392 | |
| 413 | 393 | errorCode = this->inPacketLength; |
| 414 | 394 | int packet; |
| 415 | - for(packet = 0; packet < packetCount && errorCode == this->inPacketLength; packet++) | |
| 395 | + for(packet = 0; packet < packetCount && errorCode == this->inPacketLength; packet++) { | |
| 396 | +#if LIBUSB_VERSION == 0 | |
| 397 | + errorCode = LIBUSB_ERROR_TIMEOUT; | |
| 398 | + for(int attempt = 0; (attempt < attempts || attempts == -1) && errorCode == LIBUSB_ERROR_TIMEOUT; attempt++) | |
| 399 | + errorCode = usb_bulk_read(this->handle, HANTEK_EP_IN, (char *) data + packet * this->inPacketLength, this->inPacketLength, HANTEK_TIMEOUT); | |
| 400 | +#else | |
| 416 | 401 | errorCode = this->bulkTransfer(HANTEK_EP_IN, data + packet * this->inPacketLength, this->inPacketLength, attempts); |
| 402 | +#endif | |
| 403 | + } | |
| 417 | 404 | |
| 418 | 405 | if(errorCode < 0) |
| 419 | 406 | return errorCode; |
| ... | ... | @@ -421,7 +408,6 @@ namespace Hantek { |
| 421 | 408 | return (packet - 1) * this->inPacketLength + errorCode; |
| 422 | 409 | } |
| 423 | 410 | |
| 424 | -#if LIBUSB_VERSION != 0 | |
| 425 | 411 | /// \brief Control transfer to the oscilloscope. |
| 426 | 412 | /// \param type The request type, also sets the direction of the transfer. |
| 427 | 413 | /// \param request The request field of the packet. |
| ... | ... | @@ -437,13 +423,16 @@ namespace Hantek { |
| 437 | 423 | |
| 438 | 424 | int errorCode = LIBUSB_ERROR_TIMEOUT; |
| 439 | 425 | for(int attempt = 0; (attempt < attempts || attempts == -1) && errorCode == LIBUSB_ERROR_TIMEOUT; attempt++) |
| 426 | +#if LIBUSB_VERSION == 0 | |
| 427 | + errorCode = usb_control_msg(this->handle, type, request, value, index, (char *) data, length, HANTEK_TIMEOUT); | |
| 428 | +#else | |
| 440 | 429 | errorCode = libusb_control_transfer(this->handle, type, request, value, index, data, length, HANTEK_TIMEOUT); |
| 430 | +#endif | |
| 441 | 431 | |
| 442 | 432 | if(errorCode == LIBUSB_ERROR_NO_DEVICE) |
| 443 | 433 | this->disconnect(); |
| 444 | 434 | return errorCode; |
| 445 | 435 | } |
| 446 | -#endif | |
| 447 | 436 | |
| 448 | 437 | /// \brief Control write to the oscilloscope. |
| 449 | 438 | /// \param request The request field of the packet. |
| ... | ... | @@ -457,25 +446,7 @@ namespace Hantek { |
| 457 | 446 | if(!this->handle) |
| 458 | 447 | return LIBUSB_ERROR_NO_DEVICE; |
| 459 | 448 | |
| 460 | -#if LIBUSB_VERSION == 0 | |
| 461 | - int i, rv = -ETIMEDOUT; | |
| 462 | - for(i = 0; (rv == -ETIMEDOUT) && (i < attempts); i++) | |
| 463 | - { | |
| 464 | - rv = ::usb_control_msg(usbDSOHandle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR, | |
| 465 | - request, value, index, (char*)data, length, timeout); | |
| 466 | - } | |
| 467 | - | |
| 468 | - if (rv < 0) | |
| 469 | - { | |
| 470 | - qDebug("Usb write control message %02X returns error %i", request, rv); | |
| 471 | - qDebug("Error: %s", ::usb_strerror()); | |
| 472 | - return rv; | |
| 473 | - } | |
| 474 | - | |
| 475 | - return 0; | |
| 476 | -#else | |
| 477 | 449 | return this->controlTransfer(LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, request, data, length, value, index,attempts); |
| 478 | -#endif | |
| 479 | 450 | } |
| 480 | 451 | |
| 481 | 452 | /// \brief Control read to the oscilloscope. |
| ... | ... | @@ -490,25 +461,7 @@ namespace Hantek { |
| 490 | 461 | if(!this->handle) |
| 491 | 462 | return LIBUSB_ERROR_NO_DEVICE; |
| 492 | 463 | |
| 493 | -#if LIBUSB_VERSION == 0 | |
| 494 | - int i, rv = -ETIMEDOUT; | |
| 495 | - for(i = 0; (rv == -ETIMEDOUT) && (i < attempts); i++) | |
| 496 | - { | |
| 497 | - rv = ::usb_control_msg(usbDSOHandle, USB_ENDPOINT_IN | USB_TYPE_VENDOR, | |
| 498 | - request, value, index, (char*)data, length, timeout); | |
| 499 | - } | |
| 500 | - | |
| 501 | - if (rv < 0) | |
| 502 | - { | |
| 503 | - qDebug("Usb read control message %02X returns error %i", request, rv); | |
| 504 | - qDebug("Error: %s", ::usb_strerror()); | |
| 505 | - return rv; | |
| 506 | - } | |
| 507 | - | |
| 508 | - return 0; | |
| 509 | -#else | |
| 510 | 464 | return this->controlTransfer(LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN, request, data, length, value, index, attempts); |
| 511 | -#endif | |
| 512 | 465 | } |
| 513 | 466 | |
| 514 | 467 | /// \brief Gets the speed of the connection. | ... | ... |
openhantek/src/hantek/device.h
| ... | ... | @@ -70,9 +70,7 @@ namespace Hantek { |
| 70 | 70 | int bulkCommand(Helper::DataArray<unsigned char> *command, int attempts = HANTEK_ATTEMPTS_DEFAULT); |
| 71 | 71 | int bulkReadMulti(unsigned char *data, unsigned int length, int attempts = HANTEK_ATTEMPTS_DEFAULT); |
| 72 | 72 | |
| 73 | -#if LIBUSB_VERSION != 0 | |
| 74 | 73 | int controlTransfer(unsigned char type, unsigned char request, unsigned char *data, unsigned int length, int value, int index, int attempts = HANTEK_ATTEMPTS_DEFAULT); |
| 75 | -#endif | |
| 76 | 74 | int controlWrite(unsigned char request, unsigned char *data, unsigned int length, int value = 0, int index = 0, int attempts = HANTEK_ATTEMPTS_DEFAULT); |
| 77 | 75 | int controlRead(unsigned char request, unsigned char *data, unsigned int length, int value = 0, int index = 0, int attempts = HANTEK_ATTEMPTS_DEFAULT); |
| 78 | 76 | |
| ... | ... | @@ -91,8 +89,13 @@ namespace Hantek { |
| 91 | 89 | libusb_context *context; ///< The usb context used for this device |
| 92 | 90 | #endif |
| 93 | 91 | Model model; ///< The model of the connected oscilloscope |
| 92 | +#if LIBUSB_VERSION == 0 | |
| 93 | + usb_dev_handle *handle; ///< The USB handle for the oscilloscope | |
| 94 | + usb_device_descriptor descriptor; ///< The device descriptor of the oscilloscope | |
| 95 | +#else | |
| 94 | 96 | libusb_device_handle *handle; ///< The USB handle for the oscilloscope |
| 95 | 97 | libusb_device_descriptor descriptor; ///< The device descriptor of the oscilloscope |
| 98 | +#endif | |
| 96 | 99 | int interface; ///< The number of the claimed interface |
| 97 | 100 | int error; ///< The libusb error, that happened on initialization |
| 98 | 101 | int outPacketLength; ///< Packet length for the OUT endpoint | ... | ... |
openhantek/src/helper.h
| ... | ... | @@ -27,9 +27,32 @@ |
| 27 | 27 | #define HELPER_H |
| 28 | 28 | |
| 29 | 29 | |
| 30 | +#include <cerrno> | |
| 31 | + | |
| 30 | 32 | #include <QString> |
| 31 | 33 | |
| 32 | 34 | |
| 35 | +#if LIBUSB_VERSION == 0 | |
| 36 | +#define LIBUSB_SUCCESS 0 | |
| 37 | +#define LIBUSB_ERROR_IO -EIO | |
| 38 | +#define LIBUSB_ERROR_INVALID_PARAM -EINVAL | |
| 39 | +#define LIBUSB_ERROR_ACCESS -EACCES | |
| 40 | +#define LIBUSB_ERROR_NO_DEVICE -ENXIO | |
| 41 | +#define LIBUSB_ERROR_NOT_FOUND -ENOENT | |
| 42 | +#define LIBUSB_ERROR_BUSY -EBUSY | |
| 43 | +#define LIBUSB_ERROR_TIMEOUT -ETIMEDOUT | |
| 44 | +#define LIBUSB_ERROR_OVERFLOW -EFBIG | |
| 45 | +#define LIBUSB_ERROR_PIPE -EPIPE | |
| 46 | +#define LIBUSB_ERROR_INTERRUPTED -EINTR | |
| 47 | +#define LIBUSB_ERROR_NO_MEM -ENOMEM | |
| 48 | +#define LIBUSB_ERROR_NOT_SUPPORTED -ENOSYS | |
| 49 | + | |
| 50 | +#define LIBUSB_ENDPOINT_IN USB_ENDPOINT_IN | |
| 51 | +#define LIBUSB_ENDPOINT_OUT USB_ENDPOINT_OUT | |
| 52 | +#define LIBUSB_REQUEST_TYPE_VENDOR USB_TYPE_VENDOR | |
| 53 | +#endif | |
| 54 | + | |
| 55 | + | |
| 33 | 56 | namespace Helper { |
| 34 | 57 | ////////////////////////////////////////////////////////////////////////////// |
| 35 | 58 | /// \enum Unit helper.h | ... | ... |