From 55e9906b78d8d0d22359d67e8d98e8c8c49f5b28 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Thu, 24 Apr 2014 20:33:06 -0500 Subject: [PATCH] Add timebase controls to scope part Build debug symbols package --- clients/tde/debian/control | 10 + clients/tde/debian/rules | 5 +- .../tde/src/part/logicanalyzer/Makefile.in | 57 +-- clients/tde/src/part/scope/layout.ui | 23 ++ clients/tde/src/part/scope/part.cpp | 351 +++++++++++++++--- clients/tde/src/part/scope/part.h | 41 +- clients/tde/src/widgets/tracewidget.cpp | 56 +-- .../gpib_server_lin/src/scope_functions.cpp | 4 +- 8 files changed, 415 insertions(+), 132 deletions(-) diff --git a/clients/tde/debian/control b/clients/tde/debian/control index 85a06f6..8739149 100644 --- a/clients/tde/debian/control +++ b/clients/tde/debian/control @@ -12,3 +12,13 @@ Depends: ${shlibs:Depends}, ${misc:Depends} Recommends: kerberostray-trinity Description: remote laboratory client [Trinity] Remote Laboratory Client for Trinity + +Package: remote-laboratory-client-trinity-dbg +Section: devel +Architecture: any +Priority: extra +Depends: remote-laboratory-client-trinity (= ${binary:Version}), tdelibs-trinity-dbg +Description: debugging symbols for the Remote Laboratory Client [Trinity] + This package contains the debugging symbols associated with remote-laboratory-client-trinity. + They will automatically be used by gdb for debugging remote-laboratory-client-trinity-related + issues. diff --git a/clients/tde/debian/rules b/clients/tde/debian/rules index 1f58c4a..0316512 100755 --- a/clients/tde/debian/rules +++ b/clients/tde/debian/rules @@ -7,6 +7,7 @@ include /usr/share/cdbs/1/rules/debhelper.mk include debian/cdbs/kde.mk include /usr/share/cdbs/1/rules/patchsys-quilt.mk +include /usr/share/cdbs/1/rules/utils.mk DEB_CONFIGURE_INCLUDEDIR := /opt/trinity/include/tde DEB_CONFIGURE_MANDIR := /opt/trinity/share/man @@ -17,7 +18,7 @@ cdbs_configure_flags := --with-qt-dir=/usr/share/tqt3 --disable-rpath --with-xin DEB_DH_ALWAYS_EXCLUDE=.svn -DEB_CONFIGURE_EXTRA_FLAGS := --prefix=/opt/trinity --with-extra-libs=/opt/trinity/lib --disable-debug +DEB_CONFIGURE_EXTRA_FLAGS := --prefix=/opt/trinity --with-extra-libs=/opt/trinity/lib post-patches:: debian/stamp-bootstrap @@ -27,7 +28,7 @@ debian/stamp-bootstrap: ! [ -f /usr/share/libtool/config/ltmain.sh ] || \ cp -f /usr/share/libtool/config/ltmain.sh admin/ltmain.sh cp -f /usr/share/aclocal/libtool.m4 admin/libtool.m4.in - + make -f admin/Makefile.common cvs touch debian/stamp-bootstrap diff --git a/clients/tde/src/part/logicanalyzer/Makefile.in b/clients/tde/src/part/logicanalyzer/Makefile.in index e8301f4..38470dd 100644 --- a/clients/tde/src/part/logicanalyzer/Makefile.in +++ b/clients/tde/src/part/logicanalyzer/Makefile.in @@ -1,10 +1,10 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.11 from Makefile.am. # KDE tags expanded automatically by am_edit - $Revision$ # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -17,23 +17,6 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ - esac; \ - test $$am__dry = yes; \ - } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -85,12 +68,6 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } am__installdirs = "$(DESTDIR)$(kde_moduledir)" LTLIBRARIES = $(kde_module_LTLIBRARIES) am__DEPENDENCIES_1 = @@ -141,11 +118,6 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libremotelab_logicanalyzer_la_SOURCES) DIST_SOURCES = $(libremotelab_logicanalyzer_la_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac ETAGS = etags CTAGS = ctags #>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -177,7 +149,6 @@ DCOPIDLNG = @DCOPIDLNG@ DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ DOXYGEN = @DOXYGEN@ DOXYGEN_PROJECT_NAME = @DOXYGEN_PROJECT_NAME@ DOXYGEN_PROJECT_NUMBER = @DOXYGEN_PROJECT_NUMBER@ @@ -276,7 +247,6 @@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MAKETDEWIDGETS = @MAKETDEWIDGETS@ -MANIFEST_TOOL = @MANIFEST_TOOL@ MCOPIDL = @MCOPIDL@ MEINPROC = @MEINPROC@ MKDIR_P = @MKDIR_P@ @@ -295,7 +265,6 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ @@ -336,7 +305,6 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ @@ -394,6 +362,7 @@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ @@ -487,6 +456,7 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): install-kde_moduleLTLIBRARIES: $(kde_module_LTLIBRARIES) @$(NORMAL_INSTALL) + test -z "$(kde_moduledir)" || $(MKDIR_P) "$(DESTDIR)$(kde_moduledir)" @list='$(kde_module_LTLIBRARIES)'; test -n "$(kde_moduledir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -494,8 +464,6 @@ install-kde_moduleLTLIBRARIES: $(kde_module_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(kde_moduledir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(kde_moduledir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(kde_moduledir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(kde_moduledir)"; \ } @@ -517,7 +485,7 @@ clean-kde_moduleLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libremotelab_logicanalyzer.la: $(libremotelab_logicanalyzer_la_OBJECTS) $(libremotelab_logicanalyzer_la_DEPENDENCIES) $(EXTRA_libremotelab_logicanalyzer_la_DEPENDENCIES) +libremotelab_logicanalyzer.la: $(libremotelab_logicanalyzer_la_OBJECTS) $(libremotelab_logicanalyzer_la_DEPENDENCIES) $(libremotelab_logicanalyzer_la_LINK) -rpath $(kde_moduledir) $(libremotelab_logicanalyzer_la_OBJECTS) $(libremotelab_logicanalyzer_la_LIBADD) $(LIBS) mostlyclean-compile: @@ -654,15 +622,10 @@ install-am: all-am installcheck: installcheck-am install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: diff --git a/clients/tde/src/part/scope/layout.ui b/clients/tde/src/part/scope/layout.ui index b81f97b..f680d86 100644 --- a/clients/tde/src/part/scope/layout.ui +++ b/clients/tde/src/part/scope/layout.ui @@ -103,6 +103,11 @@ + + timebaseControlLayoutWidget + + + traceControlLayoutWidget @@ -151,6 +156,24 @@ + + + groupOscilloscopeTestNotes + + + Notes + + + + + userNotes + + + + + + + diff --git a/clients/tde/src/part/scope/part.cpp b/clients/tde/src/part/scope/part.cpp index 15fc12f..f61e8a9 100644 --- a/clients/tde/src/part/scope/part.cpp +++ b/clients/tde/src/part/scope/part.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include //encodeName() #include @@ -64,23 +65,28 @@ enum connectionStates { ScopeState_ResetRequest = 2, ScopeState_HorizontalDivCountRequest = 4, ScopeState_VerticalDivCountRequest = 6, - ScopeState_ChannelCountRequest = 8, - ScopeState_ChannelActiveStateRequest = 10, - ScopeState_TraceSampleCountRequest = 12, - ScopeState_TracePermittedVoltsDivRequest = 14, - ScopeState_TraceVoltsDivRequest = 16, - ScopeState_TraceSecondsDivRequest = 18, - ScopeState_TriggerChannelRequest = 20, - ScopeState_TriggerLevelRequest = 22, - ScopeState_RunningRequest = 24, + ScopeState_PermittedSecondsDivRequest = 8, + ScopeState_ChannelCountRequest = 10, + ScopeState_ChannelActiveStateRequest = 12, + ScopeState_TraceSampleCountRequest = 14, + ScopeState_TracePermittedVoltsDivRequest = 16, + ScopeState_TraceVoltsDivRequest = 18, + ScopeState_TraceSecondsDivRequest = 20, + ScopeState_HorizontalTimebaseRequest = 22, + ScopeState_TriggerChannelRequest = 24, + ScopeState_TriggerLevelRequest = 26, + ScopeState_RunningRequest = 28, ScopeState_TraceRequest = 50, ScopeState_ChannelActiveStateUpdate = 100, ScopeState_TraceVoltsDivUpdate = 102, ScopeState_TriggerLevelUpdate = 104, - ScopeState_RunningUpdate = 106, + ScopeState_HorizontalTimebaseUpdate = 106, + ScopeState_RunningUpdate = 108, ScopeState_ExternalCommandRequest = 255 }; +#define ScopeState_ReloadSettings ScopeState_ChannelActiveStateRequest + namespace RemoteLab { typedef KParts::GenericFactory Factory; @@ -162,9 +168,64 @@ void TraceControlWidget::vdivChanged(int index) { emit(voltsPerDivChanged(value)); } +TimebaseControlWidget::TimebaseControlWidget(TQWidget *parent, const char *name) + : TQWidget(parent, name) +{ + TQGridLayout *topGrid = new TQGridLayout(this); + m_groupBox = new TQGroupBox(this); + m_groupBox->setColumnLayout(0, TQt::Vertical); + topGrid->addMultiCellWidget(m_groupBox, 0, 0, 0, 0); + m_groupBox->setTitle(i18n("Timebase")); + m_primaryLayout = new TQGridLayout(m_groupBox->layout(), 1, 1, KDialog::spacingHint()); + + m_secondsDivComboBox = new TQComboBox(m_groupBox); + connect(m_secondsDivComboBox, SIGNAL(activated(int)), this, SLOT(sdivChanged(int))); + m_primaryLayout->addMultiCellWidget(m_secondsDivComboBox, 0, 0, 0, 0); + + TQLabel* label = new TQLabel(m_groupBox); + label->setText(i18n("/div")); + m_primaryLayout->addMultiCellWidget(label, 0, 0, 1, 1); +} + +TimebaseControlWidget::~TimebaseControlWidget() { + // +} + +void TimebaseControlWidget::setSecondsPerDivList(TQDoubleList list) { + m_secondsDivList = list; + + // Update drop down list + double prevValue = m_secondsDivComboBox->currentText().toDouble(); + m_secondsDivComboBox->clear(); + TQDoubleList::iterator it; + int i = 0; + for (it = m_secondsDivList.begin(); it != m_secondsDivList.end(); ++it) { + m_secondsDivComboBox->insertItem(TQString("%1").arg(TraceWidget::prettyFormat(*it, *it, "s", 3)), i); + if (prevValue == (*it)) { + m_secondsDivComboBox->setCurrentItem(i); + } + i++; + } +} + +void TimebaseControlWidget::setSelectedSecondsPerDiv(double sdiv) { + int i = 0; + for (i=0;icount();i++) { + if (m_secondsDivComboBox->text(i) == TraceWidget::prettyFormat(sdiv, sdiv, "s", 3)) { + m_secondsDivComboBox->setCurrentItem(i); + } + } +} + +void TimebaseControlWidget::sdivChanged(int index) { + Q_UNUSED(index) + double value = m_secondsDivList[m_secondsDivComboBox->currentItem()]; + emit(secondsPerDivChanged(value)); +} + ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList& ) : RemoteInstrumentPart( parent, name ), m_traceWidget(0), m_commHandlerState(-1), m_commHandlerMode(0), m_commHandlerCommandState(0), m_connectionActiveAndValid(false), - m_triggerChannel(-1), m_base(0), stopTraceUpdate(false) + m_triggerChannel(-1), m_settingsChanged(false), m_base(0), stopTraceUpdate(false) { // Initialize important base class variables m_clientLibraryName = CLIENT_LIBRARY; @@ -196,11 +257,16 @@ ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject * m_channelActiveSet[traceno] = false; } m_triggerLevelSet = false; + m_horizontalTimebaseSet = false; m_runningSet = false; // Create widgets m_base = new ScopeBase(widget()); m_traceControlWidgetGrid = new TQGridLayout(m_base->traceControlLayoutWidget); + m_timebaseControlWidgetGrid = new TQGridLayout(m_base->timebaseControlLayoutWidget); + m_timebaseControlWidget = new TimebaseControlWidget(m_base->timebaseControlLayoutWidget); + connect(m_timebaseControlWidget, SIGNAL(secondsPerDivChanged(double)), this, SLOT(traceControlSDivChanged(double))); + m_timebaseControlWidgetGrid->addMultiCellWidget(m_timebaseControlWidget, 0, 0, 0, 0); m_traceWidget = m_base->traceScrollWidget->traceWidget(); connect(m_traceWidget, SIGNAL(cursorDragged(uint, double)), this, SLOT(cursorLevelChanged(uint, double))); m_base->traceScrollWidget->setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding)); @@ -359,6 +425,7 @@ void ScopePart::setTickerMessage(TQString message) { if (m_channelActiveSet[i]) updatesPending = true; if (m_voltsDivSet[i]) updatesPending = true; if (m_triggerLevelSet) updatesPending = true; + if (m_horizontalTimebaseSet) updatesPending = true; if (m_runningSet) updatesPending = true; } @@ -459,12 +526,12 @@ void ScopePart::mainEventLoop() { if (m_socket->canReadFrame()) { PAT_WATCHDOG_TIMER setTickerMessage(i18n("Connected")); - + // Get command status TQString result; ds >> result; m_socket->clearFrameTail(); - + if (result == "ACK") { SET_NEXT_STATE(ScopeState_ResetRequest) EXEC_NEXT_STATE_IMMEDIATELY @@ -502,12 +569,12 @@ void ScopePart::mainEventLoop() { if (m_socket->canReadFrame()) { PAT_WATCHDOG_TIMER setTickerMessage(i18n("Loading [Reset complete]")); - + // Get command status TQString result; ds >> result; m_socket->clearFrameTail(); - + if (result == "ACK") { SET_NEXT_STATE(ScopeState_HorizontalDivCountRequest) EXEC_NEXT_STATE_IMMEDIATELY @@ -599,7 +666,56 @@ void ScopePart::mainEventLoop() { ds >> m_vdivs; } m_socket->clearFrameTail(); - + + if (result == "ACK") { + SET_NEXT_STATE(ScopeState_PermittedSecondsDivRequest) + EXEC_NEXT_STATE_IMMEDIATELY + } + else { + if (stopTraceUpdate == false) { + COMMUNICATIONS_FAILED + } + else { + setTickerMessage(i18n("Data acquisition stopped")); + } + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + if (stopTraceUpdate == false) { + UPDATEDISPLAY_TIMEOUT + } + else { + setTickerMessage(i18n("Data acquisition stopped")); + } + } + } + } + else if (m_commHandlerState == ScopeState_PermittedSecondsDivRequest) { + // Get permitted seconds/div settings, step 1 + ds << TQString("GETPERMITTEDSDIVS"); + ds << m_currentOpChannel; + m_socket->writeEndOfFrame(); + + SET_NEXT_STATE_DATA_WAITING(ScopeState_PermittedSecondsDivRequest+1) + EXEC_NEXT_STATE_IMMEDIATELY + } + else if (m_commHandlerState == ScopeState_PermittedSecondsDivRequest+1) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + setTickerMessage(i18n("Loading [Received allowed seconds/div list]")); + + // Get permitted seconds/div settings, step 2 + TQString result; + ds >> result; + if (result == "ACK") { + TQDoubleList list; + ds >> list; + m_timebaseControlWidget->setSecondsPerDivList(list); + } + m_socket->clearFrameTail(); + if (result == "ACK") { SET_NEXT_STATE(ScopeState_ChannelCountRequest) EXEC_NEXT_STATE_IMMEDIATELY @@ -637,7 +753,7 @@ void ScopePart::mainEventLoop() { if (m_socket->canReadFrame()) { PAT_WATCHDOG_TIMER setTickerMessage(i18n("Loading [Received number of channels]")); - + // Get number of channels, step 2 TQString result; ds >> result; @@ -649,7 +765,7 @@ void ScopePart::mainEventLoop() { updateTraceControlWidgets(); } m_socket->clearFrameTail(); - + if (result == "ACK") { m_currentOpChannel = 1; SET_NEXT_STATE(ScopeState_ChannelActiveStateRequest) @@ -751,7 +867,7 @@ void ScopePart::mainEventLoop() { if (m_socket->canReadFrame()) { PAT_WATCHDOG_TIMER setTickerMessage(i18n("Loading [Received trace sample count for channel %1]").arg(m_currentOpChannel)); - + // Get number of samples in trace, step 2 TQString result; ds >> result; @@ -759,7 +875,7 @@ void ScopePart::mainEventLoop() { ds >> m_samplesInTrace[m_currentOpChannel]; } m_socket->clearFrameTail(); - + if (result == "ACK") { m_currentOpChannel = getNextActiveChannel(m_currentOpChannel, m_channelActive, m_maxNumberOfTraces); if (m_currentOpChannel > 0) { @@ -863,7 +979,7 @@ void ScopePart::mainEventLoop() { if (m_socket->canReadFrame()) { PAT_WATCHDOG_TIMER setTickerMessage(i18n("Loading [Received volts/div for channel %1]").arg(m_currentOpChannel)); - + // Get volts per division, step 2 TQString result; ds >> result; @@ -871,7 +987,7 @@ void ScopePart::mainEventLoop() { ds >> m_voltsDiv[m_currentOpChannel]; } m_socket->clearFrameTail(); - + if (result == "ACK") { m_currentOpChannel = getNextActiveChannel(m_currentOpChannel, m_channelActive, m_maxNumberOfTraces); if (m_currentOpChannel > 0) { @@ -932,7 +1048,7 @@ void ScopePart::mainEventLoop() { SET_NEXT_STATE(ScopeState_TraceSecondsDivRequest) } else { - SET_NEXT_STATE(ScopeState_TriggerChannelRequest) + SET_NEXT_STATE(ScopeState_HorizontalTimebaseRequest) } EXEC_NEXT_STATE_IMMEDIATELY } @@ -956,6 +1072,54 @@ void ScopePart::mainEventLoop() { } } } + else if (m_commHandlerState == ScopeState_HorizontalTimebaseRequest) { + // Get horizontal timebase, step 1 + ds << TQString("GETHORIZTIMEBASE"); + m_socket->writeEndOfFrame(); + + SET_NEXT_STATE_DATA_WAITING(ScopeState_HorizontalTimebaseRequest+1) + EXEC_NEXT_STATE_IMMEDIATELY + } + else if (m_commHandlerState == ScopeState_HorizontalTimebaseRequest+1) { + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + setTickerMessage(i18n("Loading [Received horizontal timebase]")); + + // Get horizontal timebase, step 2 + TQString result; + ds >> result; + if (result == "ACK") { + ds >> m_horizontalTimebase; + m_timebaseControlWidget->setSelectedSecondsPerDiv(m_horizontalTimebase); + } + m_socket->clearFrameTail(); + + if (result == "ACK") { + m_currentOpChannel = 1; + SET_NEXT_STATE(ScopeState_TriggerChannelRequest) + EXEC_NEXT_STATE_IMMEDIATELY + } + else { + if (stopTraceUpdate == false) { + COMMUNICATIONS_FAILED + } + else { + setTickerMessage(i18n("Data acquisition stopped")); + } + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + if (stopTraceUpdate == false) { + UPDATEDISPLAY_TIMEOUT + } + else { + setTickerMessage(i18n("Data acquisition stopped")); + } + } + } + } else if (m_commHandlerState == ScopeState_TriggerChannelRequest) { // Get trigger channel, step 1 ds << TQString("GETTRIGGERCHANNEL"); @@ -978,7 +1142,7 @@ void ScopePart::mainEventLoop() { ds >> m_triggerChannel; } m_socket->clearFrameTail(); - + if (result == "ACK") { SET_NEXT_STATE(ScopeState_TriggerLevelRequest) EXEC_NEXT_STATE_IMMEDIATELY @@ -1025,7 +1189,7 @@ void ScopePart::mainEventLoop() { ds >> m_triggerLevel; } m_socket->clearFrameTail(); - + if (result == "ACK") { // Update display widget(s) updateGraticule(); @@ -1079,7 +1243,7 @@ void ScopePart::mainEventLoop() { m_running = (status != 0); } m_socket->clearFrameTail(); - + if (result == "ACK") { // Update display widget(s) updateGraticule(); @@ -1116,7 +1280,6 @@ void ScopePart::mainEventLoop() { ds << m_currentOpChannel; m_socket->writeEndOfFrame(); - m_lastChangesRequireFullUpdate = false; SET_NEXT_STATE_DATA_WAITING(ScopeState_TraceRequest+1) EXEC_NEXT_STATE_IMMEDIATELY } @@ -1154,12 +1317,13 @@ void ScopePart::mainEventLoop() { && (m_channelActiveSet[m_currentOpChannel] == false) && (m_voltsDivSet[m_currentOpChannel] == false) && (m_triggerLevelSet == false) + && (m_horizontalTimebaseSet == false) && (m_runningSet == false) ) { SET_NEXT_STATE(ScopeState_TraceRequest) } else { - m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces); + m_currentOpChannel = 1; SET_NEXT_STATE(ScopeState_ChannelActiveStateUpdate) } EXEC_NEXT_STATE_IMMEDIATELY @@ -1193,28 +1357,23 @@ void ScopePart::mainEventLoop() { ds << active; m_socket->writeEndOfFrame(); - m_lastChangesRequireFullUpdate = true; m_channelActiveSet[m_currentOpChannel] = false; SET_NEXT_STATE_DATA_WAITING(ScopeState_ChannelActiveStateUpdate+1) } else { + m_currentOpChannel = m_currentOpChannel + 1; if (m_currentOpChannel < m_maxNumberOfTraces) { - m_currentOpChannel++; SET_NEXT_STATE(ScopeState_ChannelActiveStateUpdate) } else { m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces); - if (m_lastChangesRequireFullUpdate) { - SET_NEXT_STATE(ScopeState_TraceVoltsDivRequest) - } - else { - SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate) - } + SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate) } } EXEC_NEXT_STATE_IMMEDIATELY } else if (m_commHandlerState == ScopeState_ChannelActiveStateUpdate+1) { + m_settingsChanged = true; // Get response data if (m_socket->canReadFrame()) { PAT_WATCHDOG_TIMER @@ -1224,18 +1383,19 @@ void ScopePart::mainEventLoop() { TQString result; ds >> result; m_socket->clearFrameTail(); - + if (result == "ACK") { m_currentOpChannel = getNextActiveChannel(m_currentOpChannel, m_channelActive, m_maxNumberOfTraces); if (m_currentOpChannel > 0) { SET_NEXT_STATE(ScopeState_ChannelActiveStateUpdate) } else { - m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces); - if (m_lastChangesRequireFullUpdate) { - SET_NEXT_STATE(ScopeState_TraceVoltsDivRequest) + m_currentOpChannel = m_currentOpChannel + 1; + if (m_currentOpChannel < m_maxNumberOfTraces) { + SET_NEXT_STATE(ScopeState_ChannelActiveStateUpdate) } else { + m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces); SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate) } } @@ -1284,16 +1444,17 @@ void ScopePart::mainEventLoop() { EXEC_NEXT_STATE_IMMEDIATELY } else if (m_commHandlerState == ScopeState_TraceVoltsDivUpdate+1) { + m_settingsChanged = true; // Get response data if (m_socket->canReadFrame()) { PAT_WATCHDOG_TIMER setTickerMessage(i18n("Updating [Set volts/div for channel %1]").arg(m_currentOpChannel)); - + // Set volts per division, step 2 TQString result; ds >> result; m_socket->clearFrameTail(); - + if (result == "ACK") { m_currentOpChannel = getNextActiveChannel(m_currentOpChannel, m_channelActive, m_maxNumberOfTraces); if (m_currentOpChannel > 0) { @@ -1325,7 +1486,7 @@ void ScopePart::mainEventLoop() { } } else if (m_commHandlerState == ScopeState_TriggerLevelUpdate) { - if (m_voltsDivSet[m_currentOpChannel]) { + if (m_triggerLevelSet) { // Set trigger level, step 1 ds << TQString("SETTRIGGERLEVEL"); ds << m_triggerLevel; @@ -1335,22 +1496,73 @@ void ScopePart::mainEventLoop() { SET_NEXT_STATE_DATA_WAITING(ScopeState_TriggerLevelUpdate+1) } else { - m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces); - SET_NEXT_STATE(ScopeState_TraceRequest) + SET_NEXT_STATE(ScopeState_HorizontalTimebaseUpdate) } EXEC_NEXT_STATE_IMMEDIATELY } else if (m_commHandlerState == ScopeState_TriggerLevelUpdate+1) { + m_settingsChanged = true; // Get response data if (m_socket->canReadFrame()) { PAT_WATCHDOG_TIMER setTickerMessage(i18n("Updating [Set trigger level]")); - + // Set trigger level, step 2 TQString result; ds >> result; m_socket->clearFrameTail(); - + + if (result == "ACK") { + SET_NEXT_STATE(ScopeState_HorizontalTimebaseUpdate) + EXEC_NEXT_STATE_IMMEDIATELY + } + else { + if (stopTraceUpdate == false) { + COMMUNICATIONS_FAILED + } + else { + setTickerMessage(i18n("Data acquisition stopped")); + } + } + } + else { + if (!m_updateTimeoutTimer->isActive()) { + if (stopTraceUpdate == false) { + UPDATEDISPLAY_TIMEOUT + } + else { + setTickerMessage(i18n("Data acquisition stopped")); + } + } + } + } + else if (m_commHandlerState == ScopeState_HorizontalTimebaseUpdate) { + if (m_horizontalTimebaseSet) { + // Set horizontal timebase, step 1 + ds << TQString("SETHORIZTIMEBASE"); + ds << m_horizontalTimebase; + m_socket->writeEndOfFrame(); + + m_horizontalTimebaseSet = false; + SET_NEXT_STATE_DATA_WAITING(ScopeState_HorizontalTimebaseUpdate+1) + } + else { + SET_NEXT_STATE(ScopeState_RunningUpdate) + } + EXEC_NEXT_STATE_IMMEDIATELY + } + else if (m_commHandlerState == ScopeState_HorizontalTimebaseUpdate+1) { + m_settingsChanged = true; + // Get response data + if (m_socket->canReadFrame()) { + PAT_WATCHDOG_TIMER + setTickerMessage(i18n("Updating [Set horizontal timebase]")); + + // Set horizontal timebase, step 2 + TQString result; + ds >> result; + m_socket->clearFrameTail(); + if (result == "ACK") { SET_NEXT_STATE(ScopeState_RunningUpdate) EXEC_NEXT_STATE_IMMEDIATELY @@ -1388,24 +1600,38 @@ void ScopePart::mainEventLoop() { } else { m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces); - SET_NEXT_STATE(ScopeState_TraceRequest) + if (m_settingsChanged) { + m_settingsChanged = false; + SET_NEXT_STATE(ScopeState_ReloadSettings) + } + else { + SET_NEXT_STATE(ScopeState_TraceRequest) + } + } EXEC_NEXT_STATE_IMMEDIATELY } else if (m_commHandlerState == ScopeState_RunningUpdate+1) { + m_settingsChanged = true; // Get response data if (m_socket->canReadFrame()) { PAT_WATCHDOG_TIMER setTickerMessage(i18n("Updating [Set run status]")); - + // Set running, step 2 TQString result; ds >> result; m_socket->clearFrameTail(); - + if (result == "ACK") { m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces); - SET_NEXT_STATE(ScopeState_TraceRequest) + if (m_settingsChanged) { + m_settingsChanged = false; + SET_NEXT_STATE(ScopeState_ReloadSettings) + } + else { + SET_NEXT_STATE(ScopeState_TraceRequest) + } EXEC_NEXT_STATE_IMMEDIATELY } else { @@ -1462,7 +1688,7 @@ void ScopePart::mainEventLoop() { TQString result; ds >> result; m_socket->clearFrameTail(); - + if (result == "ACK") { m_commHandlerCommandState = 0; EXEC_NEXT_STATE_IMMEDIATELY @@ -1526,6 +1752,7 @@ void ScopePart::stopDAQ() { m_voltsDivSet[i] = false; } m_triggerLevelSet = false; + m_horizontalTimebaseSet = false; m_runningSet = false; m_commHandlerMode = 1; m_commHandlerCommandState = 3; @@ -1534,7 +1761,7 @@ void ScopePart::stopDAQ() { } #define WAVEFORM_MAGIC_NUMBER 1 -#define WAVEFORM_FILE_VERSION 1 +#define WAVEFORM_FILE_VERSION 2 void ScopePart::saveWaveforms() { TQString saveFileName = KFileDialog::getSaveFileName(TQString::null, "*.wfm|Waveform Files (*.wfm)", 0, i18n("Save waveforms...")); @@ -1563,6 +1790,7 @@ void ScopePart::saveWaveforms() { for (int cursorno=0; cursorno<5; cursorno++) { ds << m_traceWidget->cursorPosition(cursorno); } + ds << m_base->userNotes->text(); } } @@ -1577,7 +1805,7 @@ void ScopePart::recallWaveforms() { ds >> magicNumber; if (magicNumber == WAVEFORM_MAGIC_NUMBER) { ds >> version; - if (version == WAVEFORM_FILE_VERSION) { + if ((version >= 1) && (version <= WAVEFORM_FILE_VERSION)) { ds >> m_hdivs; ds >> m_vdivs; ds >> m_maxNumberOfTraces; @@ -1607,6 +1835,14 @@ void ScopePart::recallWaveforms() { ds >> cursorPos; m_traceWidget->setCursorPosition(cursorno, cursorPos); } + if (version < 2) { + m_base->userNotes->setText(TQString::null); + } + else { + TQString notes; + ds >> notes; + m_base->userNotes->setText(notes); + } m_triggerChannel = -1; m_triggerLevel = 0; updateGraticule(); @@ -1616,7 +1852,7 @@ void ScopePart::recallWaveforms() { updateTraceControlWidgets(); } else { - KMessageBox::error(0, i18n("The selected waveform file version does not match this client"), i18n("Invalid File")); + KMessageBox::error(0, i18n("The selected waveform file version (%1) is not compatible with this client, which only understands versions %2-%3").arg(version).arg(1).arg(WAVEFORM_FILE_VERSION), i18n("Invalid File")); } } else { @@ -1756,6 +1992,11 @@ void ScopePart::traceControlVDivChanged(double vdiv) { updateTraceControlWidgets(); } +void ScopePart::traceControlSDivChanged(double sdiv) { + m_horizontalTimebase = sdiv; + m_horizontalTimebaseSet = true; +} + void ScopePart::cursorLevelChanged(uint cursor, double level) { if (cursor == 0) { // Trigger level changed diff --git a/clients/tde/src/part/scope/part.h b/clients/tde/src/part/scope/part.h index 2c65e01..22da008 100644 --- a/clients/tde/src/part/scope/part.h +++ b/clients/tde/src/part/scope/part.h @@ -77,14 +77,40 @@ namespace RemoteLab TQDoubleList m_voltsDivList; }; + class TimebaseControlWidget : public TQWidget + { + Q_OBJECT + + public: + TimebaseControlWidget(TQWidget *parent=0, const char *name=0); + ~TimebaseControlWidget(); + + public: + void setSecondsPerDivList(TQDoubleList list); + void setSelectedSecondsPerDiv(double sdiv); + + signals: + void secondsPerDivChanged(double sdiv); + + private slots: + void sdivChanged(int index); + + private: + TQGroupBox* m_groupBox; + TQGridLayout* m_primaryLayout; + TQComboBox* m_secondsDivComboBox; + + TQDoubleList m_secondsDivList; + }; + class ScopePart : public KParts::RemoteInstrumentPart { Q_OBJECT - + public: ScopePart( QWidget *, const char *, TQObject *, const char *, const TQStringList&); ~ScopePart(); - + virtual bool openFile() { return false; } // pure virtual in the base class virtual bool closeURL(); static TDEAboutData *createAboutData(); @@ -92,7 +118,7 @@ namespace RemoteLab public slots: virtual bool openURL(const KURL &url); void updateZoomWidgetLimits(const TQRectF& zoomRect); - + private slots: void postInit(); void processLockouts(); @@ -107,16 +133,18 @@ namespace RemoteLab void updateTraceControlWidgets(); void traceControlEnableChanged(bool enabled); void traceControlVDivChanged(double vdiv); + void traceControlSDivChanged(double sdiv); void cursorLevelChanged(uint cursor, double level); void startScope(); void stopScope(); void saveWaveforms(); void recallWaveforms(); virtual void postProcessTrace(); - + private: TraceWidget* m_traceWidget; TQGridLayout* m_traceControlWidgetGrid; + TQGridLayout* m_timebaseControlWidgetGrid; int m_commHandlerState; int m_commHandlerMode; int m_commHandlerCommandState; @@ -133,16 +161,19 @@ namespace RemoteLab TQ_INT16 m_triggerChannel; bool m_running; double m_triggerLevel; + double m_horizontalTimebase; TQ_INT32 m_samplesInTrace[MAXTRACES+1]; bool m_channelActive[MAXTRACES+1]; double m_voltsDiv[MAXTRACES+1]; double m_secsDiv[MAXTRACES+1]; TraceControlWidget* m_traceControlWidgetList[MAXTRACES]; + TimebaseControlWidget* m_timebaseControlWidget; bool m_triggerLevelSet; + bool m_horizontalTimebaseSet; bool m_runningSet; bool m_voltsDivSet[MAXTRACES+1]; bool m_channelActiveSet[MAXTRACES+1]; - bool m_lastChangesRequireFullUpdate; + bool m_settingsChanged; ScopeBase* m_base; TQMutex* m_instrumentMutex; bool stopTraceUpdate; diff --git a/clients/tde/src/widgets/tracewidget.cpp b/clients/tde/src/widgets/tracewidget.cpp index 8de3d52..c3c3475 100644 --- a/clients/tde/src/widgets/tracewidget.cpp +++ b/clients/tde/src/widgets/tracewidget.cpp @@ -136,9 +136,9 @@ TraceWidgetPushButton::~TraceWidgetPushButton() { // Largely taken from TQPushButton::sizeHint() TQSize TraceWidgetPushButton::sizeHint() const { constPolish(); - + int w = 0, h = 0; - + // calculate contents size... if (iconSet() && !iconSet()->isNull()) { int iw = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4; @@ -150,7 +150,7 @@ TQSize TraceWidgetPushButton::sizeHint() const { if (isMenuButton()) { w += style().pixelMetric(TQStyle::PM_MenuButtonIndicator, this); } - + if (pixmap()) { TQPixmap *pm = (TQPixmap *)pixmap(); w += pm->width(); @@ -171,7 +171,7 @@ TQSize TraceWidgetPushButton::sizeHint() const { h = TQMAX(h, sz.height()); } } - + return (TQSize(w, h).expandedTo(TQApplication::globalStrut()).expandedTo(TQSize(20, 20))); } @@ -221,7 +221,7 @@ class TraceLabelLayoutIterator : public TQGLayoutIterator TQLayoutItem *takeCurrent() { return list->take(idx); } - + private: int idx; TQPtrList *list; @@ -279,11 +279,11 @@ void TraceLabelLayout::setGeometry(const TQRect &rect) { break; } } - + TQFontMetrics fm(currentTrace->leftLabel->font()); int font_height = fm.boundingRect(currentTrace->leftLabel->text()).height(); int font_vertical_offset = font_height/2; - + int graticule_height = m_traceWidget->m_graticuleWidget->height(); int y = ((((currentTrace->offset+currentTrace->textOffset)-currentTrace->topEdge)/(currentTrace->bottomEdge-currentTrace->topEdge))*(graticule_height))-font_vertical_offset; if (m_traceWidget->m_showLeftTraceInfoArea) { @@ -400,7 +400,7 @@ class TraceCursorLabelLayoutIterator : public TQGLayoutIterator TQLayoutItem *takeCurrent() { return list->take(idx); } - + private: int idx; TQPtrList *list; @@ -458,11 +458,11 @@ void TraceCursorLabelLayout::setGeometry(const TQRect &rect) { break; } } - + TQFontMetrics fm(currentTrace->leftCursorLabel->font()); int font_height = fm.boundingRect(currentTrace->leftCursorLabel->text()).height(); int font_vertical_offset = font_height/2; - + int graticule_height = m_traceWidget->m_graticuleWidget->height(); int y = ((((currentTrace->offset+currentTrace->textOffset)-currentTrace->topEdge)/(currentTrace->bottomEdge-currentTrace->topEdge))*(graticule_height))-font_vertical_offset; if (m_traceWidget->m_showLeftTraceInfoArea) { @@ -1081,7 +1081,7 @@ int GraticuleWidget::virtualWidth() { } } } - + return m_virtualWidth; } @@ -1509,6 +1509,7 @@ TraceWidget::TraceWidget(TQWidget* parent, const char* name) : TQWidget(parent, TraceWidget::~TraceWidget() { for (uint i=0;iactiveTraceLabelList.contains(trace) > 0) { double horizontal_range = (m_traceArray[trace]->rightEdge-m_traceArray[trace]->leftEdge); double vertical_range = (m_traceArray[trace]->bottomEdge-m_traceArray[trace]->topEdge); - + if (m_cursorArray[cursor]->orientation == TQt::Horizontal) { double realCursorPosition = (m_traceArray[trace]->topEdge+((m_cursorArray[cursor]->position/100.0)*vertical_range)-m_traceArray[trace]->offset); TQString deltaText; @@ -1743,7 +1744,12 @@ void TraceWidget::updateCursorText() { } } - m_traceArray[trace]->leftCursorLabel->setText(TQString("%2").arg((m_traceArray[trace]->sampleArray[closest]==0)?"0":"1")); + if (m_traceArray[trace]->sampleArray.count() > 0) { + m_traceArray[trace]->leftCursorLabel->setText(TQString("%2").arg((m_traceArray[trace]->sampleArray[closest]==0)?"0":"1")); + } + else { + m_traceArray[trace]->leftCursorLabel->setText(TQString("")); + } } else { // Find closest data point @@ -1751,14 +1757,21 @@ void TraceWidget::updateCursorText() { unsigned int closest = 0; double diff; double distance = DBL_MAX; - for (n=0; nnumberOfSamples; n++) { - diff = fabs(m_traceArray[trace]->positionArray[n] - realCursorPosition); - if (diff < distance) { - distance = diff; - closest = n; + if (m_traceArray[trace]->positionArray.count() >= m_traceArray[trace]->numberOfSamples) { + for (n=0; nnumberOfSamples; n++) { + diff = fabs(m_traceArray[trace]->positionArray[n] - realCursorPosition); + if (diff < distance) { + distance = diff; + closest = n; + } } } - m_traceArray[trace]->leftCursorLabel->setText(TQString("%2").arg(TraceWidget::prettyFormat(m_traceArray[trace]->sampleArray[closest], m_traceArray[trace]->sampleArray[closest], m_traceArray[trace]->verticalUnits))); + if (m_traceArray[trace]->sampleArray.count() > 0) { + m_traceArray[trace]->leftCursorLabel->setText(TQString("%2").arg(TraceWidget::prettyFormat(m_traceArray[trace]->sampleArray[closest], m_traceArray[trace]->sampleArray[closest], m_traceArray[trace]->verticalUnits))); + } + else { + m_traceArray[trace]->leftCursorLabel->setText(TQString("")); + } } } } @@ -2479,8 +2492,7 @@ void TraceWidget::resizeTraceArray(uint newsize) { } } } - else { - m_traceArray.resize(newsize); + else if (newsize < oldcount) { for (uint i=newsize;iparamLabel) { m_traceLabelLayout->remove(m_traceArray[i]->paramLabel); @@ -2494,7 +2506,9 @@ void TraceWidget::resizeTraceArray(uint newsize) { m_statusLabelLayoutInner->remove(m_traceArray[i]->graphStatusLabelInner); } delete m_traceArray[i]; + m_traceArray[i] = NULL; } + m_traceArray.resize(newsize); } } diff --git a/servers/gpib_server_lin/src/scope_functions.cpp b/servers/gpib_server_lin/src/scope_functions.cpp index 1e7c4ae..81a31a5 100644 --- a/servers/gpib_server_lin/src/scope_functions.cpp +++ b/servers/gpib_server_lin/src/scope_functions.cpp @@ -253,7 +253,7 @@ int scope_set_timebase(float desired_timebase,const char * scopeType, int gpibDe } } else if (strcmp("TDS744AOS", scopeType) == 0) { - sprintf(falpha, "HORIZONTAL:MAIN:SCALE %E", desired_timebase/10); + sprintf(falpha, "HORIZONTAL:MAIN:SCALE %E", desired_timebase); #ifdef ENABLE_EXTRA_DEBUGGING printf("[DEBG] Writing: %s\n\r", falpha); #endif @@ -308,7 +308,7 @@ int scope_get_timebase(double * retval, const char * scopeType, int gpibDevice) } else { floatstring[ai]=0; - *retval = atof(floatstring)*10; + *retval = floatstring; } #ifdef ENABLE_EXTRA_DEBUGGING