Commit 2e9e87f4671e0512b1ee427488707a51b57f60bb

Authored by oliverhaag
1 parent 104958b2

Some bugfixes and additional functionality in debug mode

openhantek/ChangeLog
... ... @@ -68,3 +68,8 @@
68 68 * DSO is started after the settings have been transferred
69 69 * Added additional debug messages when building as debug binary
70 70 * Added support for DSO-5200
  71 +
  72 +2010-08-31 Oliver Haag <oliver.haag@gmail.com>
  73 +* Added manual command sending with Shift+C when bulding as debug binary
  74 +* Fixed some uninitialized values in Hantek::Control
  75 +* Added debug messages for capture state when building as debug binary
... ...
openhantek/OpenHantek.pro
... ... @@ -85,7 +85,7 @@ QMAKE_CXXFLAGS += &quot;-iquote $${IN_PWD}/src&quot;
85 85  
86 86 # libusb version
87 87 LIBUSB_VERSION = $$(LIBUSB_VERSION)
88   -contains(LIBUSB_VERSION, 0):LIBS += -lusb
  88 +contains(LIBUSB_VERSION, 0): LIBS += -lusb
89 89 else {
90 90 LIBUSB_VERSION = 1
91 91 LIBS += -lusb-1.0
... ... @@ -93,8 +93,7 @@ else {
93 93 DEFINES += LIBUSB_VERSION=$${LIBUSB_VERSION}
94 94  
95 95 # Debug output
96   -CONFIG(debug, debug|release):
97   - DEFINES += DEBUG
  96 +CONFIG(debug, debug|release): DEFINES += DEBUG
98 97  
99 98 # Settings for different operating systems
100 99 unix:!macx {
... ...
openhantek/src/dsocontrol.h
... ... @@ -84,6 +84,10 @@ class DsoControl : public QThread {
84 84 virtual int setCoupling(unsigned int channel, Dso::Coupling coupling) = 0; ///< Set the coupling for a channel
85 85 virtual double setGain(unsigned int channel, double gain) = 0; ///< Set the gain for a channel
86 86 virtual double setOffset(unsigned int channel, double offset) = 0; ///< Set the graph offset of a channel
  87 +
  88 +#ifdef DEBUG
  89 + virtual int stringCommand(QString command) = 0; ///< Sends commands directly, for debugging
  90 +#endif
87 91 };
88 92  
89 93  
... ...
openhantek/src/glgenerator.cpp
... ... @@ -79,6 +79,7 @@ GlGenerator::GlGenerator(DsoSettings *settings, QObject *parent) : QObject(paren
79 79 this->settings = settings;
80 80  
81 81 this->dataAnalyzer = 0;
  82 + this->digitalPhosphorDepth = 0;
82 83  
83 84 this->generateGrid();
84 85 }
... ...
openhantek/src/hantek/control.cpp
... ... @@ -43,6 +43,13 @@ namespace Hantek {
43 43 this->gainSteps << 0.08 << 0.16 << 0.40 << 0.80 << 1.60 << 4.00
44 44 << 8.0 << 16.0 << 40.0;
45 45 this->samplerateChannelMax = 50e6;
  46 + this->samplerateMax = this->samplerateChannelMax;
  47 + this->samplerateDivider = 1;
  48 + this->triggerPosition = 0;
  49 + this->triggerSlope = Dso::SLOPE_POSITIVE;
  50 + this->triggerSpecial = false;
  51 + this->triggerSource = 0;
  52 + this->commandVersion = 0;
46 53  
47 54 // Special trigger sources
48 55 this->specialTriggerSources << tr("EXT") << tr("EXT/10");
... ... @@ -62,12 +69,18 @@ namespace Hantek {
62 69 this->command[COMMAND_SETBUFFER5200] = new CommandSetBuffer5200();
63 70 this->command[COMMAND_SETTRIGGER5200] = new CommandSetTrigger5200();
64 71  
  72 + for(int command = 0; command < COMMAND_COUNT; command++)
  73 + this->commandPending[command] = false;
  74 +
65 75 // Transmission-ready control commands
66 76 this->control[CONTROLINDEX_SETOFFSET] = new ControlSetOffset();
67 77 this->controlCode[CONTROLINDEX_SETOFFSET] = CONTROL_SETOFFSET;
68 78 this->control[CONTROLINDEX_SETRELAYS] = new ControlSetRelays();
69 79 this->controlCode[CONTROLINDEX_SETRELAYS] = CONTROL_SETRELAYS;
70 80  
  81 + for(int control = 0; control < CONTROLINDEX_COUNT; control++)
  82 + this->controlPending[control] = false;
  83 +
71 84 // Channel level data
72 85 for(unsigned int channel = 0; channel < HANTEK_CHANNELS; channel++) {
73 86 for(unsigned int gainId = 0; gainId < GAIN_COUNT; gainId++) {
... ... @@ -115,10 +128,7 @@ namespace Hantek {
115 128 continue;
116 129  
117 130 #ifdef DEBUG
118   - QString hexDump, hexByte;
119   - for(unsigned int index = 0; index < this->command[command]->getSize(); index++)
120   - hexDump.append(hexByte.sprintf(" %02x", this->command[command]->data()[index]));
121   - qDebug("Sending bulk command:%s", hexDump.toLocal8Bit().data());
  131 + qDebug("Sending bulk command:%s", Helper::hexDump(this->command[command]->data(), this->command[command]->getSize()).toLocal8Bit().data());
122 132 #endif
123 133  
124 134 errorCode = this->device->bulkCommand(this->command[command]);
... ... @@ -142,10 +152,7 @@ namespace Hantek {
142 152 continue;
143 153  
144 154 #ifdef DEBUG
145   - QString hexDump, hexByte;
146   - for(unsigned int index = 0; index < this->control[control]->getSize(); index++)
147   - hexDump.append(hexByte.sprintf(" %02x", this->control[control]->data()[index]));
148   - qDebug("Sending control command 0x%02x:%s", control, hexDump.toLocal8Bit().data());
  155 + qDebug("Sending control command 0x%02x:%s", control, Helper::hexDump(this->control[control]->data(), this->control[control]->getSize()).toLocal8Bit().data());
149 156 #endif
150 157  
151 158 errorCode = this->device->controlWrite(this->controlCode[control], this->control[control]->data(), this->control[control]->getSize());
... ... @@ -172,7 +179,14 @@ namespace Hantek {
172 179 continue;
173 180 }
174 181  
  182 +#ifdef DEBUG
  183 + int lastCaptureState = captureState;
  184 +#endif
175 185 captureState = this->getCaptureState();
  186 +#ifdef DEBUG
  187 + if(captureState != lastCaptureState)
  188 + qDebug("Capture state changed to %d", captureState);
  189 +#endif
176 190 switch(captureState) {
177 191 case CAPTURE_READY:
178 192 case CAPTURE_READY5200:
... ... @@ -203,6 +217,10 @@ namespace Hantek {
203 217 captureState = LIBUSB_ERROR_NO_DEVICE;
204 218 break;
205 219 }
  220 +#ifdef DEBUG
  221 + qDebug("Starting to capture");
  222 +#endif
  223 +
206 224 // Enable trigger
207 225 errorCode = this->device->bulkCommand(this->command[COMMAND_ENABLETRIGGER]);
208 226 if(errorCode < 0) {
... ... @@ -210,11 +228,18 @@ namespace Hantek {
210 228 captureState = LIBUSB_ERROR_NO_DEVICE;
211 229 break;
212 230 }
  231 +#ifdef DEBUG
  232 + qDebug("Enabling trigger");
  233 +#endif
  234 +
213 235 if(this->triggerMode == Dso::TRIGGERMODE_AUTO) {
214 236 // Force triggering
215 237 errorCode = this->device->bulkCommand(this->command[COMMAND_FORCETRIGGER]);
216 238 if(errorCode == LIBUSB_ERROR_NO_DEVICE)
217 239 captureState = LIBUSB_ERROR_NO_DEVICE;
  240 +#ifdef DEBUG
  241 + qDebug("Forcing trigger");
  242 +#endif
218 243 }
219 244 samplingStarted = true;
220 245 lastTriggerMode = this->triggerMode;
... ... @@ -519,6 +544,8 @@ namespace Hantek {
519 544 this->samplerateChannelMax = 125e6;
520 545 break;
521 546 }
  547 + this->samplerateMax = this->samplerateChannelMax;
  548 + this->samplerateDivider = 1;
522 549  
523 550 // Get channel level data
524 551 errorCode = this->device->controlRead(CONTROL_VALUE, (unsigned char*) &(this->channelLevels), sizeof(this->channelLevels), (int) VALUE_CHANNELLEVEL);
... ... @@ -535,6 +562,9 @@ namespace Hantek {
535 562 /// \param size The buffer size that should be met (S).
536 563 /// \return The buffer size that has been set.
537 564 unsigned long int Control::setBufferSize(unsigned long int size) {
  565 + if(!this->device->isConnected())
  566 + return 0;
  567 +
538 568 this->updateBufferSize(size);
539 569  
540 570 this->setTriggerPosition(this->triggerPosition);
... ... @@ -548,7 +578,7 @@ namespace Hantek {
548 578 /// \param samplerate The samplerate that should be met (S/s).
549 579 /// \return The samplerate that has been set.
550 580 unsigned long int Control::setSamplerate(unsigned long int samplerate) {
551   - if(samplerate == 0)
  581 + if(!this->device->isConnected() || samplerate == 0)
552 582 return 0;
553 583  
554 584 // Pointers to needed commands
... ... @@ -629,6 +659,9 @@ namespace Hantek {
629 659 /// \param used true if the channel should be sampled.
630 660 /// \return 0 on success, -1 on invalid channel.
631 661 int Control::setChannelUsed(unsigned int channel, bool used) {
  662 + if(!this->device->isConnected())
  663 + return -2;
  664 +
632 665 if(channel >= HANTEK_CHANNELS)
633 666 return -1;
634 667  
... ... @@ -673,6 +706,9 @@ namespace Hantek {
673 706 /// \param coupling The new coupling for the channel.
674 707 /// \return 0 on success, -1 on invalid channel.
675 708 int Control::setCoupling(unsigned int channel, Dso::Coupling coupling) {
  709 + if(!this->device->isConnected())
  710 + return -2;
  711 +
676 712 if(channel >= HANTEK_CHANNELS)
677 713 return -1;
678 714  
... ... @@ -686,10 +722,13 @@ namespace Hantek {
686 722 /// \brief Sets the gain for the given channel.
687 723 /// \param channel The channel that should be set.
688 724 /// \param gain The gain that should be met (V/div).
689   - /// \return The gain that has been set, -1.0 on invalid channel.
  725 + /// \return The gain that has been set, -1 on invalid channel.
690 726 double Control::setGain(unsigned int channel, double gain) {
  727 + if(!this->device->isConnected())
  728 + return -2;
  729 +
691 730 if(channel >= HANTEK_CHANNELS)
692   - return -1.0;
  731 + return -1;
693 732  
694 733 // Find lowest gain voltage thats at least as high as the requested
695 734 int gainId;
... ... @@ -719,8 +758,11 @@ namespace Hantek {
719 758 /// \param offset The new offset value (0.0 - 1.0).
720 759 /// \return The offset that has been set, -1.0 on invalid channel.
721 760 double Control::setOffset(unsigned int channel, double offset) {
  761 + if(!this->device->isConnected())
  762 + return -2;
  763 +
722 764 if(channel >= HANTEK_CHANNELS)
723   - return -1.0;
  765 + return -1;
724 766  
725 767 // Calculate the offset value (The range is given by the calibration data)
726 768 unsigned short int minimum = this->channelLevels[channel][this->gain[channel]][OFFSET_START] >> 8;
... ... @@ -743,6 +785,9 @@ namespace Hantek {
743 785 /// \brief Set the trigger mode.
744 786 /// \return 0 on success, -1 on invalid mode.
745 787 int Control::setTriggerMode(Dso::TriggerMode mode) {
  788 + if(!this->device->isConnected())
  789 + return -2;
  790 +
746 791 if(mode < Dso::TRIGGERMODE_AUTO || mode > Dso::TRIGGERMODE_SINGLE)
747 792 return -1;
748 793  
... ... @@ -755,6 +800,9 @@ namespace Hantek {
755 800 /// \param id The number of the channel, that should be used as trigger.
756 801 /// \return 0 on success, -1 on invalid channel.
757 802 int Control::setTriggerSource(bool special, unsigned int id) {
  803 + if(!this->device->isConnected())
  804 + return -2;
  805 +
758 806 if((!special && id >= HANTEK_CHANNELS) || (special && id >= HANTEK_SPECIAL_CHANNELS))
759 807 return -1;
760 808  
... ... @@ -803,6 +851,9 @@ namespace Hantek {
803 851 /// \param level The new trigger level (V).
804 852 /// \return The trigger level that has been set, -1.0 on invalid channel.
805 853 double Control::setTriggerLevel(unsigned int channel, double level) {
  854 + if(!this->device->isConnected())
  855 + return -2;
  856 +
806 857 if(channel >= HANTEK_CHANNELS)
807 858 return -1.0;
808 859  
... ... @@ -825,6 +876,9 @@ namespace Hantek {
825 876 /// \param slope The Slope that should cause a trigger.
826 877 /// \return 0 on success, -1 on invalid slope.
827 878 int Control::setTriggerSlope(Dso::Slope slope) {
  879 + if(!this->device->isConnected())
  880 + return -2;
  881 +
828 882 if(slope != Dso::SLOPE_NEGATIVE && slope != Dso::SLOPE_POSITIVE)
829 883 return -1;
830 884  
... ... @@ -853,6 +907,9 @@ namespace Hantek {
853 907 /// \param position The new trigger position (in s).
854 908 /// \return The trigger position that has been set.
855 909 double Control::setTriggerPosition(double position) {
  910 + if(!this->device->isConnected())
  911 + return -2;
  912 +
856 913 // All trigger position are measured in samples
857 914 unsigned long int positionSamples = position * this->samplerateMax / this->samplerateDivider;
858 915  
... ... @@ -885,4 +942,60 @@ namespace Hantek {
885 942 this->triggerPosition = position;
886 943 return (double) positionSamples / this->samplerateMax * this->samplerateDivider;
887 944 }
  945 +
  946 +#ifdef DEBUG
  947 + /// \brief Sends bulk/control commands directly.
  948 + /// \param command The command as string (Has to be parsed).
  949 + /// \return 0 on success, -1 on unknown command, -2 on syntax error.
  950 + int Control::stringCommand(QString command) {
  951 + if(!this->device->isConnected())
  952 + return -3;
  953 +
  954 + QStringList commandParts = command.split(' ', QString::SkipEmptyParts);
  955 +
  956 + if(commandParts.count() >= 1) {
  957 + if(commandParts[0] == "send") {
  958 + if(commandParts.count() >= 2) {
  959 + if(commandParts[1] == "bulk") {
  960 + QString data = command.section(' ', 2, -1, QString::SectionSkipEmpty);
  961 + unsigned char commandCode = 0;
  962 +
  963 + // Read command code (First byte)
  964 + Helper::hexParse(data, &commandCode, 1);
  965 + if(commandCode > COMMAND_COUNT)
  966 + return -2;
  967 +
  968 + // Update bulk command and mark as pending
  969 + Helper::hexParse(data, this->command[commandCode]->data(), this->command[commandCode]->getSize());
  970 + this->commandPending[commandCode] = true;
  971 + return 0;
  972 + }
  973 + else if(commandParts[1] == "control") {
  974 + if(commandParts.count() <= 1)
  975 + return -2;
  976 +
  977 + // Get control code from third part
  978 + unsigned char controlCode = commandParts[2].toUShort();
  979 + int control;
  980 + for(control = 0; control < CONTROLINDEX_COUNT; control++) {
  981 + if(this->controlCode[control] == controlCode)
  982 + break;
  983 + }
  984 + if(control >= CONTROLINDEX_COUNT)
  985 + return -2;
  986 +
  987 + QString data = command.section(' ', 3, -1, QString::SectionSkipEmpty);
  988 +
  989 + // Update control command and mark as pending
  990 + Helper::hexParse(data, this->control[control]->data(), this->control[control]->getSize());
  991 + this->controlPending[control] = true;
  992 + return 0;
  993 + }
  994 + }
  995 + }
  996 + }
  997 +
  998 + return -1;
  999 + }
  1000 +#endif
888 1001 }
... ...
openhantek/src/hantek/control.h
... ... @@ -124,6 +124,10 @@ namespace Hantek {
124 124 double setTriggerLevel(unsigned int channel, double level);
125 125 int setTriggerSlope(Dso::Slope slope);
126 126 double setTriggerPosition(double position);
  127 +
  128 +#ifdef DEBUG
  129 + int stringCommand(QString command);
  130 +#endif
127 131 };
128 132 }
129 133  
... ...
openhantek/src/helper.cpp
... ... @@ -142,4 +142,49 @@ namespace Helper {
142 142 return QString();
143 143 }
144 144 }
  145 +
  146 +#ifdef DEBUG
  147 + /// \brief Returns the hex dump for the given data.
  148 + /// \param data Pointer to the data bytes that should be dumped.
  149 + /// \param length The length of the data array in bytes.
  150 + /// \return String with the hex dump of the data.
  151 + QString hexDump(unsigned char *data, unsigned int length) {
  152 + QString dumpString, byteString;
  153 +
  154 + for(unsigned int index = 0; index < length; index++)
  155 + dumpString.append(byteString.sprintf(" %02x", data[index]));
  156 +
  157 + return dumpString;
  158 + }
  159 +
  160 + /// \brief Returns the hex dump for the given data.
  161 + /// \param dump The string with the hex dump of the data.
  162 + /// \param data Pointer to the address where the data bytes should be saved.
  163 + /// \param length The maximum length of the data array in bytes.
  164 + /// \return The length of the saved data.
  165 + unsigned int hexParse(const QString dump, unsigned char *data, unsigned int length) {
  166 + QString dumpString = dump;
  167 + dumpString.remove(' ');
  168 + QString byteString;
  169 + unsigned int index;
  170 +
  171 + for(index = 0; index < length; index++) {
  172 + byteString = dumpString.mid(index * 2, 2);
  173 +
  174 + // Check if we reached the end of the string
  175 + if(byteString.isNull())
  176 + break;
  177 +
  178 + // Check for parsing errors
  179 + bool ok;
  180 + unsigned char byte = (unsigned char) byteString.toUShort(&ok, 16);
  181 + if(!ok)
  182 + break;
  183 +
  184 + data[index] = byte;
  185 + }
  186 +
  187 + return index;
  188 + }
  189 +#endif
145 190 }
... ...
openhantek/src/helper.h
... ... @@ -66,6 +66,11 @@ namespace Helper {
66 66 QString libUsbErrorString(int error);
67 67 QString valueToString(double value, Unit unit, int precision = -1);
68 68  
  69 +#ifdef DEBUG
  70 + QString hexDump(unsigned char *data, unsigned int length);
  71 + unsigned int hexParse(const QString dump, unsigned char *data, unsigned int length);
  72 +#endif
  73 +
69 74 //////////////////////////////////////////////////////////////////////////////
70 75 /// \class DataArray helper.h
71 76 /// \brief A class template for a simple array with a fixed size.
... ...
openhantek/src/openhantek.cpp
... ... @@ -235,6 +235,11 @@ void OpenHantekMainWindow::createActions() {
235 235 this->aboutQtAction = new QAction(tr("About &Qt"), this);
236 236 this->aboutQtAction->setStatusTip(tr("Show the Qt library's About box"));
237 237 connect(this->aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
  238 +
  239 +#ifdef DEBUG
  240 + this->commandAction = new QAction(tr("Send command"), this);
  241 + this->commandAction->setShortcut(tr("Shift+C"));
  242 +#endif
238 243 }
239 244  
240 245 /// \brief Create the menus and menuitems.
... ... @@ -257,6 +262,9 @@ void OpenHantekMainWindow::createMenus() {
257 262 this->oscilloscopeMenu->addAction(this->configAction);
258 263 this->oscilloscopeMenu->addSeparator();
259 264 this->oscilloscopeMenu->addAction(this->startStopAction);
  265 +#ifdef DEBUG
  266 + this->oscilloscopeMenu->addAction(this->commandAction);
  267 +#endif
260 268 this->oscilloscopeMenu->addSeparator();
261 269 this->bufferSizeMenu = this->oscilloscopeMenu->addMenu(tr("&Buffer size"));
262 270 this->bufferSizeMenu->addAction(this->bufferSizeSmallAction);
... ... @@ -289,17 +297,21 @@ void OpenHantekMainWindow::createToolBars() {
289 297  
290 298 /// \brief Create the status bar.
291 299 void OpenHantekMainWindow::createStatusBar() {
292   - // Progressbar inside the status bar
293   - /*this->progressBar = new QProgressBar();
294   - this->progressBar->setMinimumWidth(100);
295   - this->progressBar->setRange(0, 256);
296   - this->progressBar->setValue(0);
297   - this->progressBar->setTextVisible(true);
298   - this->progressBar->hide();*/
299   -
300   - //this->statusBar()->addPermanentWidget(this->progressBar);
  300 +#ifdef DEBUG
  301 + // Command field inside the status bar
  302 + this->commandEdit = new QLineEdit();
  303 + this->commandEdit->hide();
301 304  
  305 + this->statusBar()->addPermanentWidget(this->commandEdit, 1);
  306 +#endif
  307 +
302 308 this->statusBar()->showMessage(tr("Ready"));
  309 +
  310 +#ifdef DEBUG
  311 + connect(this->commandAction, SIGNAL(triggered()), this->commandEdit, SLOT(show()));
  312 + connect(this->commandAction, SIGNAL(triggered()), this->commandEdit, SLOT(setFocus()));
  313 + connect(this->commandEdit, SIGNAL(returnPressed()), this, SLOT(sendCommand()));
  314 +#endif
303 315 }
304 316  
305 317 /// \brief Create all docking windows.
... ... @@ -692,3 +704,16 @@ void OpenHantekMainWindow::updateVoltageGain(unsigned int channel) {
692 704  
693 705 this->dsoControl->setGain(channel, this->settings->scope.voltage[channel].gain * DIVS_VOLTAGE);
694 706 }
  707 +
  708 +#ifdef DEBUG
  709 +/// \brief Send the command in the commandEdit to the oscilloscope.
  710 +void OpenHantekMainWindow::sendCommand() {
  711 + int errorCode = this->dsoControl->stringCommand(this->commandEdit->text());
  712 +
  713 + this->commandEdit->hide();
  714 + this->commandEdit->clear();
  715 +
  716 + if(errorCode < 0)
  717 + this->statusBar()->showMessage(tr("Invalid command"), 3000);
  718 +}
  719 +#endif
... ...
openhantek/src/openhantek.h
... ... @@ -31,6 +31,7 @@
31 31  
32 32  
33 33 class QActionGroup;
  34 +class QLineEdit;
34 35  
35 36 class DataAnalyzer;
36 37 class DsoControl;
... ... @@ -81,6 +82,10 @@ class OpenHantekMainWindow : public QMainWindow {
81 82 QAction *digitalPhosphorAction, *zoomAction;
82 83  
83 84 QAction *aboutAction, *aboutQtAction;
  85 +
  86 +#ifdef DEBUG
  87 + QAction *commandAction;
  88 +#endif
84 89  
85 90 // Menus
86 91 QMenu *fileMenu;
... ... @@ -100,6 +105,11 @@ class OpenHantekMainWindow : public QMainWindow {
100 105 // Central widgets
101 106 DsoWidget *dsoWidget;
102 107  
  108 + // Other widgets
  109 +#ifdef DEBUG
  110 + QLineEdit *commandEdit;
  111 +#endif
  112 +
103 113 // Data handling classes
104 114 DataAnalyzer *dataAnalyzer;
105 115 DsoControl *dsoControl;
... ... @@ -107,6 +117,7 @@ class OpenHantekMainWindow : public QMainWindow {
107 117 // Other variables
108 118 QString currentFile;
109 119  
  120 + // Settings used for the whole program
110 121 DsoSettings *settings;
111 122  
112 123 private slots:
... ... @@ -131,6 +142,10 @@ class OpenHantekMainWindow : public QMainWindow {
131 142 void updateTimebase();
132 143 void updateUsed(unsigned int channel);
133 144 void updateVoltageGain(unsigned int channel);
  145 +
  146 +#ifdef DEBUG
  147 + void sendCommand();
  148 +#endif
134 149  
135 150 signals:
136 151 void settingsChanged(); ///< The settings have changed (Option dialog, loading...)
... ...