From 2e9e87f4671e0512b1ee427488707a51b57f60bb Mon Sep 17 00:00:00 2001 From: oliverhaag Date: Tue, 31 Aug 2010 14:34:02 +0000 Subject: [PATCH] Some bugfixes and additional functionality in debug mode --- openhantek/ChangeLog | 5 +++++ openhantek/OpenHantek.pro | 5 ++--- openhantek/src/dsocontrol.h | 4 ++++ openhantek/src/glgenerator.cpp | 1 + openhantek/src/hantek/control.cpp | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------ openhantek/src/hantek/control.h | 4 ++++ openhantek/src/helper.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ openhantek/src/helper.h | 5 +++++ openhantek/src/openhantek.cpp | 43 ++++++++++++++++++++++++++++++++++--------- openhantek/src/openhantek.h | 15 +++++++++++++++ 10 files changed, 240 insertions(+), 24 deletions(-) diff --git a/openhantek/ChangeLog b/openhantek/ChangeLog index ee76e6b..f00ad4a 100644 --- a/openhantek/ChangeLog +++ b/openhantek/ChangeLog @@ -68,3 +68,8 @@ * DSO is started after the settings have been transferred * Added additional debug messages when building as debug binary * Added support for DSO-5200 + +2010-08-31 Oliver Haag +* Added manual command sending with Shift+C when bulding as debug binary +* Fixed some uninitialized values in Hantek::Control +* Added debug messages for capture state when building as debug binary diff --git a/openhantek/OpenHantek.pro b/openhantek/OpenHantek.pro index 54aa9e0..00f5f14 100644 --- a/openhantek/OpenHantek.pro +++ b/openhantek/OpenHantek.pro @@ -85,7 +85,7 @@ QMAKE_CXXFLAGS += "-iquote $${IN_PWD}/src" # libusb version LIBUSB_VERSION = $$(LIBUSB_VERSION) -contains(LIBUSB_VERSION, 0):LIBS += -lusb +contains(LIBUSB_VERSION, 0): LIBS += -lusb else { LIBUSB_VERSION = 1 LIBS += -lusb-1.0 @@ -93,8 +93,7 @@ else { DEFINES += LIBUSB_VERSION=$${LIBUSB_VERSION} # Debug output -CONFIG(debug, debug|release): - DEFINES += DEBUG +CONFIG(debug, debug|release): DEFINES += DEBUG # Settings for different operating systems unix:!macx { diff --git a/openhantek/src/dsocontrol.h b/openhantek/src/dsocontrol.h index 9ac702e..aba5200 100644 --- a/openhantek/src/dsocontrol.h +++ b/openhantek/src/dsocontrol.h @@ -84,6 +84,10 @@ class DsoControl : public QThread { virtual int setCoupling(unsigned int channel, Dso::Coupling coupling) = 0; ///< Set the coupling for a channel virtual double setGain(unsigned int channel, double gain) = 0; ///< Set the gain for a channel virtual double setOffset(unsigned int channel, double offset) = 0; ///< Set the graph offset of a channel + +#ifdef DEBUG + virtual int stringCommand(QString command) = 0; ///< Sends commands directly, for debugging +#endif }; diff --git a/openhantek/src/glgenerator.cpp b/openhantek/src/glgenerator.cpp index 7b32ff2..cdabeee 100644 --- a/openhantek/src/glgenerator.cpp +++ b/openhantek/src/glgenerator.cpp @@ -79,6 +79,7 @@ GlGenerator::GlGenerator(DsoSettings *settings, QObject *parent) : QObject(paren this->settings = settings; this->dataAnalyzer = 0; + this->digitalPhosphorDepth = 0; this->generateGrid(); } diff --git a/openhantek/src/hantek/control.cpp b/openhantek/src/hantek/control.cpp index 5676b82..cfd57e0 100644 --- a/openhantek/src/hantek/control.cpp +++ b/openhantek/src/hantek/control.cpp @@ -43,6 +43,13 @@ namespace Hantek { this->gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00 << 8.0 << 16.0 << 40.0; this->samplerateChannelMax = 50e6; + this->samplerateMax = this->samplerateChannelMax; + this->samplerateDivider = 1; + this->triggerPosition = 0; + this->triggerSlope = Dso::SLOPE_POSITIVE; + this->triggerSpecial = false; + this->triggerSource = 0; + this->commandVersion = 0; // Special trigger sources this->specialTriggerSources << tr("EXT") << tr("EXT/10"); @@ -62,12 +69,18 @@ namespace Hantek { this->command[COMMAND_SETBUFFER5200] = new CommandSetBuffer5200(); this->command[COMMAND_SETTRIGGER5200] = new CommandSetTrigger5200(); + for(int command = 0; command < COMMAND_COUNT; command++) + this->commandPending[command] = false; + // Transmission-ready control commands this->control[CONTROLINDEX_SETOFFSET] = new ControlSetOffset(); this->controlCode[CONTROLINDEX_SETOFFSET] = CONTROL_SETOFFSET; this->control[CONTROLINDEX_SETRELAYS] = new ControlSetRelays(); this->controlCode[CONTROLINDEX_SETRELAYS] = CONTROL_SETRELAYS; + for(int control = 0; control < CONTROLINDEX_COUNT; control++) + this->controlPending[control] = false; + // Channel level data for(unsigned int channel = 0; channel < HANTEK_CHANNELS; channel++) { for(unsigned int gainId = 0; gainId < GAIN_COUNT; gainId++) { @@ -115,10 +128,7 @@ namespace Hantek { continue; #ifdef DEBUG - QString hexDump, hexByte; - for(unsigned int index = 0; index < this->command[command]->getSize(); index++) - hexDump.append(hexByte.sprintf(" %02x", this->command[command]->data()[index])); - qDebug("Sending bulk command:%s", hexDump.toLocal8Bit().data()); + qDebug("Sending bulk command:%s", Helper::hexDump(this->command[command]->data(), this->command[command]->getSize()).toLocal8Bit().data()); #endif errorCode = this->device->bulkCommand(this->command[command]); @@ -142,10 +152,7 @@ namespace Hantek { continue; #ifdef DEBUG - QString hexDump, hexByte; - for(unsigned int index = 0; index < this->control[control]->getSize(); index++) - hexDump.append(hexByte.sprintf(" %02x", this->control[control]->data()[index])); - qDebug("Sending control command 0x%02x:%s", control, hexDump.toLocal8Bit().data()); + qDebug("Sending control command 0x%02x:%s", control, Helper::hexDump(this->control[control]->data(), this->control[control]->getSize()).toLocal8Bit().data()); #endif errorCode = this->device->controlWrite(this->controlCode[control], this->control[control]->data(), this->control[control]->getSize()); @@ -172,7 +179,14 @@ namespace Hantek { continue; } +#ifdef DEBUG + int lastCaptureState = captureState; +#endif captureState = this->getCaptureState(); +#ifdef DEBUG + if(captureState != lastCaptureState) + qDebug("Capture state changed to %d", captureState); +#endif switch(captureState) { case CAPTURE_READY: case CAPTURE_READY5200: @@ -203,6 +217,10 @@ namespace Hantek { captureState = LIBUSB_ERROR_NO_DEVICE; break; } +#ifdef DEBUG + qDebug("Starting to capture"); +#endif + // Enable trigger errorCode = this->device->bulkCommand(this->command[COMMAND_ENABLETRIGGER]); if(errorCode < 0) { @@ -210,11 +228,18 @@ namespace Hantek { captureState = LIBUSB_ERROR_NO_DEVICE; break; } +#ifdef DEBUG + qDebug("Enabling trigger"); +#endif + if(this->triggerMode == Dso::TRIGGERMODE_AUTO) { // Force triggering errorCode = this->device->bulkCommand(this->command[COMMAND_FORCETRIGGER]); if(errorCode == LIBUSB_ERROR_NO_DEVICE) captureState = LIBUSB_ERROR_NO_DEVICE; +#ifdef DEBUG + qDebug("Forcing trigger"); +#endif } samplingStarted = true; lastTriggerMode = this->triggerMode; @@ -519,6 +544,8 @@ namespace Hantek { this->samplerateChannelMax = 125e6; break; } + this->samplerateMax = this->samplerateChannelMax; + this->samplerateDivider = 1; // Get channel level data errorCode = this->device->controlRead(CONTROL_VALUE, (unsigned char*) &(this->channelLevels), sizeof(this->channelLevels), (int) VALUE_CHANNELLEVEL); @@ -535,6 +562,9 @@ namespace Hantek { /// \param size The buffer size that should be met (S). /// \return The buffer size that has been set. unsigned long int Control::setBufferSize(unsigned long int size) { + if(!this->device->isConnected()) + return 0; + this->updateBufferSize(size); this->setTriggerPosition(this->triggerPosition); @@ -548,7 +578,7 @@ namespace Hantek { /// \param samplerate The samplerate that should be met (S/s). /// \return The samplerate that has been set. unsigned long int Control::setSamplerate(unsigned long int samplerate) { - if(samplerate == 0) + if(!this->device->isConnected() || samplerate == 0) return 0; // Pointers to needed commands @@ -629,6 +659,9 @@ namespace Hantek { /// \param used true if the channel should be sampled. /// \return 0 on success, -1 on invalid channel. int Control::setChannelUsed(unsigned int channel, bool used) { + if(!this->device->isConnected()) + return -2; + if(channel >= HANTEK_CHANNELS) return -1; @@ -673,6 +706,9 @@ namespace Hantek { /// \param coupling The new coupling for the channel. /// \return 0 on success, -1 on invalid channel. int Control::setCoupling(unsigned int channel, Dso::Coupling coupling) { + if(!this->device->isConnected()) + return -2; + if(channel >= HANTEK_CHANNELS) return -1; @@ -686,10 +722,13 @@ namespace Hantek { /// \brief Sets the gain for the given channel. /// \param channel The channel that should be set. /// \param gain The gain that should be met (V/div). - /// \return The gain that has been set, -1.0 on invalid channel. + /// \return The gain that has been set, -1 on invalid channel. double Control::setGain(unsigned int channel, double gain) { + if(!this->device->isConnected()) + return -2; + if(channel >= HANTEK_CHANNELS) - return -1.0; + return -1; // Find lowest gain voltage thats at least as high as the requested int gainId; @@ -719,8 +758,11 @@ namespace Hantek { /// \param offset The new offset value (0.0 - 1.0). /// \return The offset that has been set, -1.0 on invalid channel. double Control::setOffset(unsigned int channel, double offset) { + if(!this->device->isConnected()) + return -2; + if(channel >= HANTEK_CHANNELS) - return -1.0; + return -1; // Calculate the offset value (The range is given by the calibration data) unsigned short int minimum = this->channelLevels[channel][this->gain[channel]][OFFSET_START] >> 8; @@ -743,6 +785,9 @@ namespace Hantek { /// \brief Set the trigger mode. /// \return 0 on success, -1 on invalid mode. int Control::setTriggerMode(Dso::TriggerMode mode) { + if(!this->device->isConnected()) + return -2; + if(mode < Dso::TRIGGERMODE_AUTO || mode > Dso::TRIGGERMODE_SINGLE) return -1; @@ -755,6 +800,9 @@ namespace Hantek { /// \param id The number of the channel, that should be used as trigger. /// \return 0 on success, -1 on invalid channel. int Control::setTriggerSource(bool special, unsigned int id) { + if(!this->device->isConnected()) + return -2; + if((!special && id >= HANTEK_CHANNELS) || (special && id >= HANTEK_SPECIAL_CHANNELS)) return -1; @@ -803,6 +851,9 @@ namespace Hantek { /// \param level The new trigger level (V). /// \return The trigger level that has been set, -1.0 on invalid channel. double Control::setTriggerLevel(unsigned int channel, double level) { + if(!this->device->isConnected()) + return -2; + if(channel >= HANTEK_CHANNELS) return -1.0; @@ -825,6 +876,9 @@ namespace Hantek { /// \param slope The Slope that should cause a trigger. /// \return 0 on success, -1 on invalid slope. int Control::setTriggerSlope(Dso::Slope slope) { + if(!this->device->isConnected()) + return -2; + if(slope != Dso::SLOPE_NEGATIVE && slope != Dso::SLOPE_POSITIVE) return -1; @@ -853,6 +907,9 @@ namespace Hantek { /// \param position The new trigger position (in s). /// \return The trigger position that has been set. double Control::setTriggerPosition(double position) { + if(!this->device->isConnected()) + return -2; + // All trigger position are measured in samples unsigned long int positionSamples = position * this->samplerateMax / this->samplerateDivider; @@ -885,4 +942,60 @@ namespace Hantek { this->triggerPosition = position; return (double) positionSamples / this->samplerateMax * this->samplerateDivider; } + +#ifdef DEBUG + /// \brief Sends bulk/control commands directly. + /// \param command The command as string (Has to be parsed). + /// \return 0 on success, -1 on unknown command, -2 on syntax error. + int Control::stringCommand(QString command) { + if(!this->device->isConnected()) + return -3; + + QStringList commandParts = command.split(' ', QString::SkipEmptyParts); + + if(commandParts.count() >= 1) { + if(commandParts[0] == "send") { + if(commandParts.count() >= 2) { + if(commandParts[1] == "bulk") { + QString data = command.section(' ', 2, -1, QString::SectionSkipEmpty); + unsigned char commandCode = 0; + + // Read command code (First byte) + Helper::hexParse(data, &commandCode, 1); + if(commandCode > COMMAND_COUNT) + return -2; + + // Update bulk command and mark as pending + Helper::hexParse(data, this->command[commandCode]->data(), this->command[commandCode]->getSize()); + this->commandPending[commandCode] = true; + return 0; + } + else if(commandParts[1] == "control") { + if(commandParts.count() <= 1) + return -2; + + // Get control code from third part + unsigned char controlCode = commandParts[2].toUShort(); + int control; + for(control = 0; control < CONTROLINDEX_COUNT; control++) { + if(this->controlCode[control] == controlCode) + break; + } + if(control >= CONTROLINDEX_COUNT) + return -2; + + QString data = command.section(' ', 3, -1, QString::SectionSkipEmpty); + + // Update control command and mark as pending + Helper::hexParse(data, this->control[control]->data(), this->control[control]->getSize()); + this->controlPending[control] = true; + return 0; + } + } + } + } + + return -1; + } +#endif } diff --git a/openhantek/src/hantek/control.h b/openhantek/src/hantek/control.h index 0e3d70e..a494bf5 100644 --- a/openhantek/src/hantek/control.h +++ b/openhantek/src/hantek/control.h @@ -124,6 +124,10 @@ namespace Hantek { double setTriggerLevel(unsigned int channel, double level); int setTriggerSlope(Dso::Slope slope); double setTriggerPosition(double position); + +#ifdef DEBUG + int stringCommand(QString command); +#endif }; } diff --git a/openhantek/src/helper.cpp b/openhantek/src/helper.cpp index 21f669a..fb242d3 100644 --- a/openhantek/src/helper.cpp +++ b/openhantek/src/helper.cpp @@ -142,4 +142,49 @@ namespace Helper { return QString(); } } + +#ifdef DEBUG + /// \brief Returns the hex dump for the given data. + /// \param data Pointer to the data bytes that should be dumped. + /// \param length The length of the data array in bytes. + /// \return String with the hex dump of the data. + QString hexDump(unsigned char *data, unsigned int length) { + QString dumpString, byteString; + + for(unsigned int index = 0; index < length; index++) + dumpString.append(byteString.sprintf(" %02x", data[index])); + + return dumpString; + } + + /// \brief Returns the hex dump for the given data. + /// \param dump The string with the hex dump of the data. + /// \param data Pointer to the address where the data bytes should be saved. + /// \param length The maximum length of the data array in bytes. + /// \return The length of the saved data. + unsigned int hexParse(const QString dump, unsigned char *data, unsigned int length) { + QString dumpString = dump; + dumpString.remove(' '); + QString byteString; + unsigned int index; + + for(index = 0; index < length; index++) { + byteString = dumpString.mid(index * 2, 2); + + // Check if we reached the end of the string + if(byteString.isNull()) + break; + + // Check for parsing errors + bool ok; + unsigned char byte = (unsigned char) byteString.toUShort(&ok, 16); + if(!ok) + break; + + data[index] = byte; + } + + return index; + } +#endif } diff --git a/openhantek/src/helper.h b/openhantek/src/helper.h index e3197e1..cd897b0 100644 --- a/openhantek/src/helper.h +++ b/openhantek/src/helper.h @@ -66,6 +66,11 @@ namespace Helper { QString libUsbErrorString(int error); QString valueToString(double value, Unit unit, int precision = -1); +#ifdef DEBUG + QString hexDump(unsigned char *data, unsigned int length); + unsigned int hexParse(const QString dump, unsigned char *data, unsigned int length); +#endif + ////////////////////////////////////////////////////////////////////////////// /// \class DataArray helper.h /// \brief A class template for a simple array with a fixed size. diff --git a/openhantek/src/openhantek.cpp b/openhantek/src/openhantek.cpp index c5a2ea2..f796572 100644 --- a/openhantek/src/openhantek.cpp +++ b/openhantek/src/openhantek.cpp @@ -235,6 +235,11 @@ void OpenHantekMainWindow::createActions() { this->aboutQtAction = new QAction(tr("About &Qt"), this); this->aboutQtAction->setStatusTip(tr("Show the Qt library's About box")); connect(this->aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + +#ifdef DEBUG + this->commandAction = new QAction(tr("Send command"), this); + this->commandAction->setShortcut(tr("Shift+C")); +#endif } /// \brief Create the menus and menuitems. @@ -257,6 +262,9 @@ void OpenHantekMainWindow::createMenus() { this->oscilloscopeMenu->addAction(this->configAction); this->oscilloscopeMenu->addSeparator(); this->oscilloscopeMenu->addAction(this->startStopAction); +#ifdef DEBUG + this->oscilloscopeMenu->addAction(this->commandAction); +#endif this->oscilloscopeMenu->addSeparator(); this->bufferSizeMenu = this->oscilloscopeMenu->addMenu(tr("&Buffer size")); this->bufferSizeMenu->addAction(this->bufferSizeSmallAction); @@ -289,17 +297,21 @@ void OpenHantekMainWindow::createToolBars() { /// \brief Create the status bar. void OpenHantekMainWindow::createStatusBar() { - // Progressbar inside the status bar - /*this->progressBar = new QProgressBar(); - this->progressBar->setMinimumWidth(100); - this->progressBar->setRange(0, 256); - this->progressBar->setValue(0); - this->progressBar->setTextVisible(true); - this->progressBar->hide();*/ - - //this->statusBar()->addPermanentWidget(this->progressBar); +#ifdef DEBUG + // Command field inside the status bar + this->commandEdit = new QLineEdit(); + this->commandEdit->hide(); + this->statusBar()->addPermanentWidget(this->commandEdit, 1); +#endif + this->statusBar()->showMessage(tr("Ready")); + +#ifdef DEBUG + connect(this->commandAction, SIGNAL(triggered()), this->commandEdit, SLOT(show())); + connect(this->commandAction, SIGNAL(triggered()), this->commandEdit, SLOT(setFocus())); + connect(this->commandEdit, SIGNAL(returnPressed()), this, SLOT(sendCommand())); +#endif } /// \brief Create all docking windows. @@ -692,3 +704,16 @@ void OpenHantekMainWindow::updateVoltageGain(unsigned int channel) { this->dsoControl->setGain(channel, this->settings->scope.voltage[channel].gain * DIVS_VOLTAGE); } + +#ifdef DEBUG +/// \brief Send the command in the commandEdit to the oscilloscope. +void OpenHantekMainWindow::sendCommand() { + int errorCode = this->dsoControl->stringCommand(this->commandEdit->text()); + + this->commandEdit->hide(); + this->commandEdit->clear(); + + if(errorCode < 0) + this->statusBar()->showMessage(tr("Invalid command"), 3000); +} +#endif diff --git a/openhantek/src/openhantek.h b/openhantek/src/openhantek.h index 4c0dc82..000c85e 100644 --- a/openhantek/src/openhantek.h +++ b/openhantek/src/openhantek.h @@ -31,6 +31,7 @@ class QActionGroup; +class QLineEdit; class DataAnalyzer; class DsoControl; @@ -81,6 +82,10 @@ class OpenHantekMainWindow : public QMainWindow { QAction *digitalPhosphorAction, *zoomAction; QAction *aboutAction, *aboutQtAction; + +#ifdef DEBUG + QAction *commandAction; +#endif // Menus QMenu *fileMenu; @@ -100,6 +105,11 @@ class OpenHantekMainWindow : public QMainWindow { // Central widgets DsoWidget *dsoWidget; + // Other widgets +#ifdef DEBUG + QLineEdit *commandEdit; +#endif + // Data handling classes DataAnalyzer *dataAnalyzer; DsoControl *dsoControl; @@ -107,6 +117,7 @@ class OpenHantekMainWindow : public QMainWindow { // Other variables QString currentFile; + // Settings used for the whole program DsoSettings *settings; private slots: @@ -131,6 +142,10 @@ class OpenHantekMainWindow : public QMainWindow { void updateTimebase(); void updateUsed(unsigned int channel); void updateVoltageGain(unsigned int channel); + +#ifdef DEBUG + void sendCommand(); +#endif signals: void settingsChanged(); ///< The settings have changed (Option dialog, loading...) -- libgit2 0.21.4