summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clients/tde/src/app/views/instrumentview.cpp21
-rw-r--r--clients/tde/src/app/views/instrumentview.h1
-rw-r--r--clients/tde/src/part/scope/layout.ui56
-rw-r--r--clients/tde/src/part/scope/part.cpp505
-rw-r--r--clients/tde/src/part/scope/part.h45
-rw-r--r--clients/tde/src/widgets/tracewidget.cpp23
-rw-r--r--clients/tde/src/widgets/tracewidget.h5
-rw-r--r--lib/libtqtrla/src/tqtrla.h7
-rw-r--r--servers/gpib_server_lin/src/gpib_conn.cpp30
-rw-r--r--servers/gpib_server_lin/src/scope_functions.cpp86
-rw-r--r--servers/gpib_server_lin/src/scope_functions.h6
11 files changed, 662 insertions, 123 deletions
diff --git a/clients/tde/src/app/views/instrumentview.cpp b/clients/tde/src/app/views/instrumentview.cpp
index 429f670..494b947 100644
--- a/clients/tde/src/app/views/instrumentview.cpp
+++ b/clients/tde/src/app/views/instrumentview.cpp
@@ -48,10 +48,27 @@ void InstrumentView::init() {
m_instrumentPart = (InstrumentPart *)factory->create(TQT_TQOBJECT(this), "part", "KParts::RemoteInstrumentPart");
connect(m_instrumentPart, SIGNAL(statusMessageSet(const TQString&)), this, SLOT(setStatusMessage(const TQString&)));
connect(m_instrumentPart, SIGNAL(usingFixedSizeChanged(bool)), this, SLOT(setUsingFixedSize(bool)));
- connect(m_instrumentPart, SIGNAL(resizeToHintRequested()), this, SLOT(setChildSizeToHint()));
+ TQWidget *childPartWidget = m_instrumentPart->widget();
+ if (childPartWidget) {
+ childPartWidget->installEventFilter(this);
+ }
}
}
+bool InstrumentView::eventFilter(TQObject *o, TQEvent *e) {
+ TQWidget *childPartWidget = m_instrumentPart->widget();
+ if (childPartWidget) {
+ if (o == childPartWidget) {
+ if (e->type() == TQEvent::Resize) {
+ setChildSizeToHint();
+ }
+ }
+ }
+
+ // Allow event processing by other routines
+ return FALSE;
+}
+
void InstrumentView::setChildSizeToHint() {
if (m_instrumentPart) {
TQWidget *childPartWidget = m_instrumentPart->widget();
@@ -62,7 +79,7 @@ void InstrumentView::setChildSizeToHint() {
else {
TQSize childSizeHint = childPartWidget->sizeHint();
setMinimumSize(childSizeHint.width(), childSizeHint.height());
- childPartWidget->resize(size());
+ resize(childPartWidget->size());
}
}
}
diff --git a/clients/tde/src/app/views/instrumentview.h b/clients/tde/src/app/views/instrumentview.h
index f51fab8..ed592dd 100644
--- a/clients/tde/src/app/views/instrumentview.h
+++ b/clients/tde/src/app/views/instrumentview.h
@@ -34,6 +34,7 @@ class InstrumentView : public KMdiChildView
virtual void readProperties(KConfig *);
virtual bool queryExit();
virtual void resizeEvent(TQResizeEvent *);
+ virtual bool eventFilter(TQObject *o, TQEvent *e);
private slots:
void setStatusMessage(const TQString& message);
diff --git a/clients/tde/src/part/scope/layout.ui b/clients/tde/src/part/scope/layout.ui
index 9390e82..ee3bb81 100644
--- a/clients/tde/src/part/scope/layout.ui
+++ b/clients/tde/src/part/scope/layout.ui
@@ -98,63 +98,15 @@
</widget>
<widget class="TQGroupBox" row="0" column="1">
<property name="name">
- <cstring>groupOscilloscopeTraceControls</cstring>
+ <cstring>groupOscilloscopeCaptureControls</cstring>
</property>
<property name="title">
- <string>Receiver Controls</string>
+ <string>Capture Controls</string>
</property>
<grid>
- <widget class="TQLabel" row="0" column="0" colspan="1">
+ <widget class="TQWidget" row="0" column="0" colspan="4">
<property name="name">
- <cstring>unnamed</cstring>
- </property>
- <property name="text">
- <string>Reference Power Level:</string>
- </property>
- <property name="textFormat">
- <enum>PlainText</enum>
- </property>
- </widget>
- <widget class="FloatSpinBox" row="0" column="1" colspan="1">
- <property name="name">
- <cstring>saRefLevel</cstring>
- </property>
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy>
- <hsizetype>3</hsizetype>
- <vsizetype>0</vsizetype>
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>80</width>
- <height>0</height>
- </size>
- </property>
- <property name="maxValue">
- <number>128</number>
- </property>
- <property name="minValue">
- <number>-128</number>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- </widget>
- <widget class="TQLabel" row="0" column="3" colspan="1">
- <property name="name">
- <cstring>unnamed</cstring>
- </property>
- <property name="text">
- <string>dBm</string>
- </property>
- <property name="textFormat">
- <enum>PlainText</enum>
+ <cstring>traceControlLayoutWidget</cstring>
</property>
</widget>
</grid>
diff --git a/clients/tde/src/part/scope/part.cpp b/clients/tde/src/part/scope/part.cpp
index 9909e65..17c137d 100644
--- a/clients/tde/src/part/scope/part.cpp
+++ b/clients/tde/src/part/scope/part.cpp
@@ -18,6 +18,9 @@
#include <tqsocket.h>
#include <tqmutex.h>
#include <tqgroupbox.h>
+#include <tqlayout.h>
+#include <tqcombobox.h>
+#include <tqcheckbox.h>
#include <tqpushbutton.h>
#include <tqeventloop.h>
#include <tqapplication.h>
@@ -38,19 +41,23 @@ struct exit_exception {
};
enum connectionStates {
- ScopeState_InitialRequest = 0,
- ScopeState_ResetRequest = 2,
- ScopeState_HorizontalDivCountRequest = 4,
- ScopeState_VerticalDivCountRequest = 6,
- ScopeState_ChannelCountRequest = 8,
- ScopeState_ChannelActiveStateRequest = 10,
- ScopeState_TraceSampleCountRequest = 12,
- ScopeState_TraceVoltsDivRequest = 14,
- ScopeState_TraceSecondsDivRequest = 16,
- ScopeState_TriggerChannelRequest = 18,
- ScopeState_TriggerLevelRequest = 20,
- ScopeState_TraceRequest = 50,
- ScopeState_ExternalCommandRequest = 255
+ ScopeState_InitialRequest = 0,
+ 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_TraceRequest = 50,
+ ScopeState_ChannelActiveStateUpdate = 100,
+ ScopeState_TraceVoltsDivUpdate = 102,
+ ScopeState_TriggerLevelUpdate = 104,
+ ScopeState_ExternalCommandRequest = 255
};
namespace RemoteLab {
@@ -59,6 +66,80 @@ typedef KParts::GenericFactory<RemoteLab::ScopePart> Factory;
#define CLIENT_LIBRARY "libremotelab_scope"
K_EXPORT_COMPONENT_FACTORY( libremotelab_scope, RemoteLab::Factory )
+TraceControlWidget::TraceControlWidget(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("Unknown Channel"));
+ m_primaryLayout = new TQGridLayout(m_groupBox->layout(), KDialog::marginHint(), KDialog::spacingHint());
+
+ m_channelEnabledCheckBox = new TQCheckBox(m_groupBox);
+ connect(m_channelEnabledCheckBox, SIGNAL(clicked()), this, SLOT(enableClicked()));
+ m_channelEnabledCheckBox->setText(i18n("Enable"));
+ m_primaryLayout->addMultiCellWidget(m_channelEnabledCheckBox, 0, 0, 0, 0);
+
+ m_voltsDivComboBox = new TQComboBox(m_groupBox);
+ connect(m_voltsDivComboBox, SIGNAL(activated(int)), this, SLOT(vdivChanged(int)));
+ m_primaryLayout->addMultiCellWidget(m_voltsDivComboBox, 0, 0, 1, 1);
+
+ TQLabel* label = new TQLabel(m_groupBox);
+ label->setText(i18n("V/div"));
+ m_primaryLayout->addMultiCellWidget(label, 0, 0, 2, 2);
+}
+
+TraceControlWidget::~TraceControlWidget() {
+ //
+}
+
+void TraceControlWidget::setVoltsPerDivList(TQDoubleList list) {
+ m_voltsDivList = list;
+
+ // Update drop down list
+ double prevValue = m_voltsDivComboBox->currentText().toDouble();
+ m_voltsDivComboBox->clear();
+ TQDoubleList::iterator it;
+ int i = 0;
+ for (it = m_voltsDivList.begin(); it != m_voltsDivList.end(); ++it) {
+ m_voltsDivComboBox->insertItem(TQString("%1").arg(*it), i);
+ if (prevValue == (*it)) {
+ m_voltsDivComboBox->setCurrentItem(i);
+ }
+ i++;
+ }
+}
+
+void TraceControlWidget::setSelectedVoltsPerDiv(double vdiv) {
+ int i = 0;
+ for (i=0;i<m_voltsDivComboBox->count();i++) {
+ if (m_voltsDivComboBox->text(i).toDouble() == vdiv) {
+ m_voltsDivComboBox->setCurrentItem(i);
+ }
+ }
+}
+
+void TraceControlWidget::setTraceEnabled(bool enabled) {
+ m_channelEnabledCheckBox->setChecked(enabled);
+ m_voltsDivComboBox->setEnabled(enabled);
+}
+
+void TraceControlWidget::setTraceName(TQString name) {
+ m_groupBox->setTitle(name);
+}
+
+void TraceControlWidget::enableClicked() {
+ bool enabled = m_channelEnabledCheckBox->isOn();
+ m_voltsDivComboBox->setEnabled(enabled);
+ emit(enableChanged(enabled));
+}
+
+void TraceControlWidget::vdivChanged(int index) {
+ Q_UNUSED(index)
+ double value = m_voltsDivComboBox->currentText().toDouble();
+ emit(voltsPerDivChanged(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),
@@ -88,11 +169,18 @@ ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject *
m_channelActive[traceno] = false;
m_voltsDiv[traceno] = 0;
m_secsDiv[traceno] = 0;
+ m_traceControlWidgetList[traceno] = NULL;
+
+ m_voltsDivSet[traceno] = false;
+ m_channelActiveSet[traceno] = false;
}
+ m_triggerLevelSet = false;
// Create widgets
m_base = new ScopeBase(widget());
+ m_traceControlWidgetGrid = new TQGridLayout(m_base->traceControlLayoutWidget);
m_traceWidget = m_base->traceWidget;
+ connect(m_traceWidget, SIGNAL(cursorDragged(uint, double)), this, SLOT(cursorLevelChanged(uint, double)));
m_traceWidget->setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding));
m_traceWidget->setNumberOfCursors(5);
m_traceWidget->setZoomCursorStartIndex(1);
@@ -132,19 +220,12 @@ ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject *
connect(m_traceWidget, SIGNAL(zoomBoxChanged(const TQRectF&)), this, SLOT(updateZoomWidgetLimits(const TQRectF&)));
connect(m_traceWidget, SIGNAL(offsetChanged(uint, double)), m_base->traceZoomWidget, SLOT(setTraceOffset(uint, double)));
- m_base->saRefLevel->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed));
- m_base->saRefLevel->setFloatMin(-128);
- m_base->saRefLevel->setFloatMax(128);
- m_base->saRefLevel->setLineStep(1);
-
connect(m_base->acqStart, SIGNAL(clicked()), this, SLOT(startDAQ()));
connect(m_base->acqStop, SIGNAL(clicked()), this, SLOT(stopDAQ()));
connect(m_base->waveformSave, SIGNAL(clicked()), this, SLOT(saveWaveforms()));
connect(m_base->waveformRecall, SIGNAL(clicked()), this, SLOT(recallWaveforms()));
- connect(m_base->saRefLevel, SIGNAL(floatValueChanged(double)), this, SLOT(saRefLevelChanged(double)));
-
TQTimer::singleShot(0, this, TQT_SLOT(postInit()));
}
@@ -190,11 +271,11 @@ void ScopePart::processLockouts() {
}
// Middle area
- if ((m_commHandlerMode < 2) && (m_commHandlerState < 50)) {
- m_base->groupOscilloscopeTraceControls->setEnabled(false);
+ if (((m_commHandlerMode < 2) && (m_commHandlerState < 50)) || (stopTraceUpdate)) {
+ m_base->groupOscilloscopeCaptureControls->setEnabled(false);
}
else {
- m_base->groupOscilloscopeTraceControls->setEnabled(true);
+ m_base->groupOscilloscopeCaptureControls->setEnabled(true);
}
// Least area
@@ -237,6 +318,14 @@ void ScopePart::connectionStatusChangedCallback() {
}
void ScopePart::setTickerMessage(TQString message) {
+ int i;
+ bool updatesPending = false;
+ for (i=0; i<=MAXTRACES;i++) {
+ if (m_channelActiveSet[i]) updatesPending = true;
+ if (m_voltsDivSet[i]) updatesPending = true;
+ if (m_triggerLevelSet) updatesPending = true;
+ }
+
m_connectionActiveAndValid = true;
TQString tickerChar;
switch (m_tickerState) {
@@ -253,7 +342,12 @@ void ScopePart::setTickerMessage(TQString message) {
tickerChar = "/";
break;
}
- setStatusMessage(message + TQString("... %1").arg(tickerChar));
+ if (updatesPending) {
+ setStatusMessage(i18n("Updates pending") + ", " + message + TQString("... %1").arg(tickerChar));
+ }
+ else {
+ setStatusMessage(message + TQString("... %1").arg(tickerChar));
+ }
m_tickerState++;
if (m_tickerState > 3) {
m_tickerState = 0;
@@ -474,6 +568,7 @@ void ScopePart::mainEventLoop() {
if (m_maxNumberOfTraces > MAXTRACES) {
m_maxNumberOfTraces = MAXTRACES;
}
+ updateTraceControlWidgets();
}
m_socket->clearFrameTail();
@@ -574,6 +669,54 @@ void ScopePart::mainEventLoop() {
}
else {
m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
+ SET_NEXT_STATE(ScopeState_TracePermittedVoltsDivRequest)
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ COMMUNICATIONS_FAILED
+ }
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ }
+ else if (m_commHandlerState == ScopeState_TracePermittedVoltsDivRequest) {
+ // Get permitted volts/div settings, step 1
+ ds << TQString("GETPERMITTEDVDIVS");
+ ds << m_currentOpChannel;
+ m_socket->writeEndOfFrame();
+
+ SET_NEXT_STATE(ScopeState_TracePermittedVoltsDivRequest+1)
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else if (m_commHandlerState == ScopeState_TracePermittedVoltsDivRequest+1) {
+ // Get response data
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+ setTickerMessage(i18n("Loading [Received allowed V/div list for channel %1]").arg(m_currentOpChannel));
+
+ // Get permitted volts/div settings, step 2
+ TQString result;
+ ds >> result;
+ if (result == "ACK") {
+ TQDoubleList list;
+ ds >> list;
+ if (m_traceControlWidgetList[m_currentOpChannel-1]) {
+ m_traceControlWidgetList[m_currentOpChannel-1]->setVoltsPerDivList(list);
+ }
+ }
+ m_socket->clearFrameTail();
+
+ if (result == "ACK") {
+ if (m_currentOpChannel < m_maxNumberOfTraces) {
+ m_currentOpChannel++;
+ SET_NEXT_STATE(ScopeState_TracePermittedVoltsDivRequest)
+ }
+ else {
+ m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
SET_NEXT_STATE(ScopeState_TraceVoltsDivRequest)
}
EXEC_NEXT_STATE_IMMEDIATELY
@@ -645,7 +788,7 @@ void ScopePart::mainEventLoop() {
// Get response data
if (m_socket->canReadFrame()) {
PAT_WATCHDOG_TIMER
- setTickerMessage(i18n("Loading [Received seconds/div]"));
+ setTickerMessage(i18n("Loading [Received seconds/div for channel %1]").arg(m_currentOpChannel));
// Get seconds per division, step 2
TQString result;
@@ -738,9 +881,6 @@ void ScopePart::mainEventLoop() {
if (result == "ACK") {
// Update display widget(s)
updateGraticule();
- // HACK
- // Force resize of parent frame
- emit(resizeToHintRequested());
}
if (result == "ACK") {
@@ -764,6 +904,7 @@ void ScopePart::mainEventLoop() {
ds << m_currentOpChannel;
m_socket->writeEndOfFrame();
+ m_lastChangesRequireFullUpdate = false;
SET_NEXT_STATE(ScopeState_TraceRequest+1)
EXEC_NEXT_STATE_IMMEDIATELY
}
@@ -797,12 +938,16 @@ void ScopePart::mainEventLoop() {
if (result == "ACK") {
m_currentOpChannel = getNextActiveChannel(m_currentOpChannel, m_channelActive, m_maxNumberOfTraces);
- if (m_currentOpChannel > 0) {
+ if ((m_currentOpChannel > 0)
+ && (m_channelActiveSet[m_currentOpChannel] == false)
+ && (m_voltsDivSet[m_currentOpChannel] == false)
+ && (m_triggerLevelSet == false)
+ ) {
SET_NEXT_STATE(ScopeState_TraceRequest)
}
else {
m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
- SET_NEXT_STATE(ScopeState_TraceRequest)
+ SET_NEXT_STATE(ScopeState_ChannelActiveStateUpdate)
}
EXEC_NEXT_STATE_IMMEDIATELY
}
@@ -816,6 +961,168 @@ void ScopePart::mainEventLoop() {
}
}
}
+ else if (m_commHandlerState == ScopeState_ChannelActiveStateUpdate) {
+ if (m_channelActiveSet[m_currentOpChannel]) {
+ // Set channel active, step 1
+ ds << TQString("SETCHANNELACTIVE");
+ ds << m_currentOpChannel;
+ TQ_INT16 active = (m_channelActive[m_currentOpChannel])?1:0;
+ ds << active;
+ m_socket->writeEndOfFrame();
+
+ m_lastChangesRequireFullUpdate = true;
+ m_channelActiveSet[m_currentOpChannel] = false;
+ SET_NEXT_STATE(ScopeState_ChannelActiveStateUpdate+1)
+ }
+ else {
+ 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)
+ }
+ }
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else if (m_commHandlerState == ScopeState_ChannelActiveStateUpdate+1) {
+ // Get response data
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+ setTickerMessage(i18n("Updating [Set channel %1 activity status]").arg(m_currentOpChannel));
+
+ // Set channel active, 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) {
+ 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)
+ }
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ COMMUNICATIONS_FAILED
+ }
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ }
+ else if (m_commHandlerState == ScopeState_TraceVoltsDivUpdate) {
+ if (m_voltsDivSet[m_currentOpChannel]) {
+ // Set volts per division, step 1
+ ds << TQString("SETVOLTSDIV");
+ ds << m_currentOpChannel;
+ ds << m_voltsDiv[m_currentOpChannel];
+ m_socket->writeEndOfFrame();
+
+ m_voltsDivSet[m_currentOpChannel] = false;
+ SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate+1)
+ }
+ else {
+ m_currentOpChannel = getNextActiveChannel(m_currentOpChannel, m_channelActive, m_maxNumberOfTraces);
+ if (m_currentOpChannel > 0) {
+ SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate)
+ }
+ else {
+ SET_NEXT_STATE(ScopeState_TriggerLevelUpdate)
+ }
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else if (m_commHandlerState == ScopeState_TraceVoltsDivUpdate+1) {
+ // 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) {
+ SET_NEXT_STATE(ScopeState_TraceVoltsDivUpdate)
+ }
+ else {
+ SET_NEXT_STATE(ScopeState_TriggerLevelUpdate)
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ COMMUNICATIONS_FAILED
+ }
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ }
+ else if (m_commHandlerState == ScopeState_TriggerLevelUpdate) {
+ if (m_voltsDivSet[m_currentOpChannel]) {
+ // Set trigger level, step 1
+ ds << TQString("SETTRIGGERLEVEL");
+ ds << m_triggerLevel;
+ m_socket->writeEndOfFrame();
+
+ m_triggerLevelSet = false;
+ SET_NEXT_STATE(ScopeState_TriggerLevelUpdate+1)
+ }
+ else {
+ m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
+ SET_NEXT_STATE(ScopeState_TraceRequest)
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else if (m_commHandlerState == ScopeState_TriggerLevelUpdate+1) {
+ // 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") {
+ m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
+ SET_NEXT_STATE(ScopeState_TraceRequest)
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ COMMUNICATIONS_FAILED
+ }
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ }
else if (m_commHandlerState == ScopeState_ExternalCommandRequest) {
// Execute pending command
m_commHandlerMode = 2;
@@ -892,12 +1199,18 @@ void ScopePart::postProcessTrace() {
void ScopePart::startDAQ() {
stopTraceUpdate = false;
+ if (m_socket) m_socket->clearIncomingData();
EXEC_NEXT_STATE_IMMEDIATELY
}
void ScopePart::stopDAQ() {
if (m_commHandlerMode < 2) {
stopTraceUpdate = true;
+ for (int i=0; i<=MAXTRACES;i++) {
+ m_channelActiveSet[i] = false;
+ m_voltsDivSet[i] = false;
+ }
+ m_triggerLevelSet = false;
m_commHandlerMode = 1;
m_commHandlerCommandState = 3;
mainEventLoop();
@@ -976,11 +1289,9 @@ void ScopePart::recallWaveforms() {
m_triggerLevel = 0;
updateGraticule();
postProcessTrace();
- // HACK
- // Force resize of parent frame
- emit(resizeToHintRequested());
m_traceWidget->repaint(false);
m_base->traceZoomWidget->repaint(false);
+ updateTraceControlWidgets();
}
else {
KMessageBox::error(0, i18n("<qt>The selected waveform file version does not match this client</qt>"), i18n("Invalid File"));
@@ -1010,26 +1321,28 @@ void ScopePart::updateGraticule() {
m_base->traceZoomWidget->setNumberOfHorizontalDivisions(m_hdivs);
m_base->traceZoomWidget->setNumberOfVerticalDivisions(m_vdivs);
- if ((m_triggerChannel > 0) && (m_triggerChannel <= m_maxNumberOfTraces)) {
- TraceNumberList activeTraces;
- activeTraces.append(m_triggerChannel-1);
- m_traceWidget->setCursorActiveTraceList(0, activeTraces);
- m_traceWidget->setCursorPosition(0, (50.0-((m_triggerLevel*100.0)/(m_voltsDiv[m_triggerChannel]*m_vdivs))));
- m_traceWidget->setCursorEnabled(0, true);
- }
- else {
- m_traceWidget->setCursorEnabled(0, false);
+ if (!m_triggerLevelSet) {
+ if ((m_triggerChannel > 0) && (m_triggerChannel <= m_maxNumberOfTraces)) {
+ TraceNumberList activeTraces;
+ activeTraces.append(m_triggerChannel-1);
+ m_traceWidget->setCursorActiveTraceList(0, activeTraces);
+ m_traceWidget->setCursorPosition(0, (50.0-((m_triggerLevel*100.0)/(m_voltsDiv[m_triggerChannel]*m_vdivs))));
+ m_traceWidget->setCursorEnabled(0, true);
+ }
+ else {
+ m_traceWidget->setCursorEnabled(0, false);
+ }
}
- m_traceWidget->setTraceColor(0, TQColor(255, 255, 255));
- m_traceWidget->setTraceColor(1, TQColor(128, 255, 128));
- m_traceWidget->setTraceColor(2, TQColor(255, 255, 128));
- m_traceWidget->setTraceColor(3, TQColor(128, 128, 255));
+ if (m_maxNumberOfTraces > 0) m_traceWidget->setTraceColor(0, TQColor(255, 255, 255));
+ if (m_maxNumberOfTraces > 1) m_traceWidget->setTraceColor(1, TQColor(128, 255, 128));
+ if (m_maxNumberOfTraces > 2) m_traceWidget->setTraceColor(2, TQColor(255, 255, 128));
+ if (m_maxNumberOfTraces > 3) m_traceWidget->setTraceColor(3, TQColor(128, 128, 255));
- m_base->traceZoomWidget->setTraceColor(0, TQColor(255, 255, 255));
- m_base->traceZoomWidget->setTraceColor(1, TQColor(128, 255, 128));
- m_base->traceZoomWidget->setTraceColor(2, TQColor(255, 255, 128));
- m_base->traceZoomWidget->setTraceColor(3, TQColor(128, 128, 255));
+ if (m_maxNumberOfTraces > 0) m_base->traceZoomWidget->setTraceColor(0, TQColor(255, 255, 255));
+ if (m_maxNumberOfTraces > 1) m_base->traceZoomWidget->setTraceColor(1, TQColor(128, 255, 128));
+ if (m_maxNumberOfTraces > 2) m_base->traceZoomWidget->setTraceColor(2, TQColor(255, 255, 128));
+ if (m_maxNumberOfTraces > 3) m_base->traceZoomWidget->setTraceColor(3, TQColor(128, 128, 255));
for (int traceno=1; traceno<=m_maxNumberOfTraces; traceno++) {
m_traceWidget->setTraceEnabled(traceno-1, m_channelActive[traceno]);
@@ -1046,22 +1359,92 @@ void ScopePart::updateGraticule() {
m_base->traceZoomWidget->setNumberOfSamples(traceno-1, m_samplesInTrace[traceno]);
m_traceWidget->setDisplayLimits(traceno-1, TQRectF(0.0, (m_voltsDiv[traceno]*m_vdivs)/2.0, (m_secsDiv[traceno]*m_hdivs), (m_voltsDiv[traceno]*m_vdivs)/-2.0));
+ if (m_traceControlWidgetList[traceno-1]) {
+ m_traceControlWidgetList[traceno-1]->setSelectedVoltsPerDiv(m_voltsDiv[traceno]);
+ m_traceControlWidgetList[traceno-1]->setTraceEnabled(m_channelActive[traceno]);
+ }
}
updateZoomWidgetLimits(m_traceWidget->zoomBox());
+}
+
+void ScopePart::updateTraceControlWidgets() {
+ // Add or remove trace control widgets as needed...
+ int i;
+ for (i=0; i<m_maxNumberOfTraces;i++) {
+ if (!m_traceControlWidgetList[i]) {
+ m_traceControlWidgetList[i] = new TraceControlWidget(m_base->traceControlLayoutWidget);
+ connect(m_traceControlWidgetList[i], SIGNAL(enableChanged(bool)), this, SLOT(traceControlEnableChanged(bool)));
+ connect(m_traceControlWidgetList[i], SIGNAL(voltsPerDivChanged(double)), this, SLOT(traceControlVDivChanged(double)));
+ m_traceControlWidgetGrid->addMultiCellWidget(m_traceControlWidgetList[i], i, i, 0, 0);
+ m_traceControlWidgetList[i]->setTraceName(i18n("Channel %1").arg(i+1));
+ m_traceControlWidgetList[i]->show();
+ }
+ }
+ for (i=m_maxNumberOfTraces; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i]) {
+ m_traceControlWidgetGrid->remove(m_traceControlWidgetList[i]);
+ delete m_traceControlWidgetList[i];
+ }
+ }
+}
+
+void ScopePart::traceControlEnableChanged(bool enabled) {
+ int i;
+ int channel = -1;
+ const TraceControlWidget* widget = dynamic_cast<const TraceControlWidget*>(sender());
+ if (widget) {
+ for (i=0; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i] == widget) {
+ channel = i;
+ break;
+ }
+ }
+ if ((channel >= 0) && (channel <=MAXTRACES)) {
+ m_channelActive[channel+1] = enabled;
+ m_channelActiveSet[channel+1] = true;
+ }
+ }
+
+ updateGraticule();
+ m_traceWidget->repaint(false);
+ m_base->traceZoomWidget->repaint(false);
+ updateTraceControlWidgets();
+}
+
+void ScopePart::traceControlVDivChanged(double vdiv) {
+ int i;
+ int channel = -1;
+ const TraceControlWidget* widget = dynamic_cast<const TraceControlWidget*>(sender());
+ if (widget) {
+ for (i=0; i<MAXTRACES;i++) {
+ if (m_traceControlWidgetList[i] == widget) {
+ channel = i;
+ break;
+ }
+ }
+ if ((channel >= 0) && (channel <=MAXTRACES)) {
+ m_voltsDiv[channel+1] = vdiv;
+ m_voltsDivSet[channel+1] = true;
+ }
+ }
-// // Also update controls
-// m_base->saRefLevel->blockSignals(true);
-// m_base->saRefLevel->setFloatValue(m_voltsDiv);
-// m_base->saRefLevel->blockSignals(false);
+ updateGraticule();
+ m_traceWidget->repaint(false);
+ m_base->traceZoomWidget->repaint(false);
+ updateTraceControlWidgets();
}
-void ScopePart::saRefLevelChanged(double newval) {
-// if (m_commHandlerMode < 2) {
-// m_voltsDiv = newval;
-// m_commHandlerMode = 1;
-// m_commHandlerCommandState = 1;
-// mainEventLoop();
-// }
+void ScopePart::cursorLevelChanged(uint cursor, double level) {
+ if (cursor == 0) {
+ // Trigger level changed
+ m_triggerLevel = (((50.0-level)*(m_voltsDiv[m_triggerChannel]*m_vdivs))/100.0);
+ m_triggerLevelSet = true;
+
+ updateGraticule();
+ m_traceWidget->repaint(false);
+ m_base->traceZoomWidget->repaint(false);
+ updateTraceControlWidgets();
+ }
}
KAboutData* ScopePart::createAboutData() {
diff --git a/clients/tde/src/part/scope/part.h b/clients/tde/src/part/scope/part.h
index 1e342da..24e2c84 100644
--- a/clients/tde/src/part/scope/part.h
+++ b/clients/tde/src/part/scope/part.h
@@ -20,10 +20,44 @@ class TQSocket;
class TQTimer;
class TQMutex;
class TQRectF;
+class TQGridLayout;
+class TQCheckBox;
+class TQGroupBox;
class ScopeBase;
namespace RemoteLab
{
+ class TraceControlWidget : public TQWidget
+ {
+ Q_OBJECT
+
+ public:
+ TraceControlWidget(TQWidget *parent=0, const char *name=0);
+ ~TraceControlWidget();
+
+ public:
+ void setVoltsPerDivList(TQDoubleList list);
+ void setSelectedVoltsPerDiv(double vdiv);
+ void setTraceEnabled(bool enabled);
+ void setTraceName(TQString name);
+
+ signals:
+ void enableChanged(bool enabled);
+ void voltsPerDivChanged(double vdiv);
+
+ private slots:
+ void enableClicked();
+ void vdivChanged(int index);
+
+ private:
+ TQGroupBox* m_groupBox;
+ TQGridLayout* m_primaryLayout;
+ TQComboBox* m_voltsDivComboBox;
+ TQCheckBox* m_channelEnabledCheckBox;
+
+ TQDoubleList m_voltsDivList;
+ };
+
class ScopePart : public KParts::RemoteInstrumentPart
{
Q_OBJECT
@@ -51,13 +85,17 @@ namespace RemoteLab
void mainEventLoop();
void startDAQ();
void stopDAQ();
+ void updateTraceControlWidgets();
+ void traceControlEnableChanged(bool enabled);
+ void traceControlVDivChanged(double vdiv);
+ void cursorLevelChanged(uint cursor, double level);
void saveWaveforms();
void recallWaveforms();
virtual void postProcessTrace();
- void saRefLevelChanged(double);
private:
TraceWidget* m_traceWidget;
+ TQGridLayout* m_traceControlWidgetGrid;
int m_commHandlerState;
int m_commHandlerMode;
int m_commHandlerCommandState;
@@ -77,6 +115,11 @@ namespace RemoteLab
bool m_channelActive[MAXTRACES+1];
double m_voltsDiv[MAXTRACES+1];
double m_secsDiv[MAXTRACES+1];
+ TraceControlWidget* m_traceControlWidgetList[MAXTRACES];
+ bool m_triggerLevelSet;
+ bool m_voltsDivSet[MAXTRACES+1];
+ bool m_channelActiveSet[MAXTRACES+1];
+ bool m_lastChangesRequireFullUpdate;
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 6375a13..1ee9721 100644
--- a/clients/tde/src/widgets/tracewidget.cpp
+++ b/clients/tde/src/widgets/tracewidget.cpp
@@ -372,6 +372,7 @@ void CursorData::movePosOneTick() {
if (position < 0.0) position = 0.0;
if (position > 100.0) position = 100.0;
+ emit(positionChanged(position));
parentWidget->updateCursorText();
parentWidget->m_graticuleWidget->updateGraticule();
parentWidget->m_graticuleWidget->repaint(false);
@@ -394,6 +395,7 @@ void CursorData::moveNegOneTick() {
if (position < 0.0) position = 0.0;
if (position > 100.0) position = 100.0;
+ emit(positionChanged(position));
parentWidget->updateCursorText();
parentWidget->m_graticuleWidget->updateGraticule();
parentWidget->m_graticuleWidget->repaint(false);
@@ -416,6 +418,7 @@ void CursorData::movePosMultiTicks() {
if (position < 0.0) position = 0.0;
if (position > 100.0) position = 100.0;
+ emit(positionChanged(position));
parentWidget->updateCursorText();
parentWidget->m_graticuleWidget->updateGraticule();
parentWidget->m_graticuleWidget->repaint(false);
@@ -438,6 +441,7 @@ void CursorData::moveNegMultiTicks() {
if (position < 0.0) position = 0.0;
if (position > 100.0) position = 100.0;
+ emit(positionChanged(position));
parentWidget->updateCursorText();
parentWidget->m_graticuleWidget->updateGraticule();
parentWidget->m_graticuleWidget->repaint(false);
@@ -1528,8 +1532,24 @@ void TraceWidget::processChangedOffset(double offset) {
}
}
+void TraceWidget::processChangedCusorPosition(double position) {
+ // Find the sending cursor number
+ const CursorData* sendingCursor = dynamic_cast<const CursorData*>(sender());
+ if (sendingCursor) {
+ int cursornumber = -1;
+ for (uint cursor=0;cursor<m_cursorArray.count();cursor++) {
+ if (sendingCursor == m_cursorArray[cursor]) {
+ cursornumber = cursor;
+ }
+ }
+ if (cursornumber >= 0) {
+ emit(cursorDragged(cursornumber, position));
+ }
+ }
+}
+
void TraceWidget::processChangedCursor(uint cursorNumber, double newPosition) {
- emit(cursorPositionChanged(cursorNumber, newPosition));
+ emit(cursorDragged(cursorNumber, newPosition));
}
void TraceWidget::resizeTraceArray(uint newsize) {
@@ -1573,6 +1593,7 @@ void TraceWidget::resizeCursorArray(uint newsize) {
m_cursorArray.resize(newsize);
for (uint i=oldcount;i<newsize;i++) {
m_cursorArray[i] = new CursorData(this, this);
+ connect(m_cursorArray[i], SIGNAL(positionChanged(double)), this, SLOT(processChangedCusorPosition(double)));
if (m_cursorArray[i]->paramLabel) {
m_cursorLabelLayout->addMultiCellWidget(m_cursorArray[i]->paramLabel, i*2, i*2, 0, 3);
m_cursorLabelLayout->addMultiCellWidget(m_cursorArray[i]->multiIncrBtn, (i*2)+1, (i*2)+1, 0, 0);
diff --git a/clients/tde/src/widgets/tracewidget.h b/clients/tde/src/widgets/tracewidget.h
index 7ca1e24..fec91e3 100644
--- a/clients/tde/src/widgets/tracewidget.h
+++ b/clients/tde/src/widgets/tracewidget.h
@@ -109,6 +109,9 @@ class CursorData : public TQObject
protected:
virtual bool eventFilter(TQObject *o, TQEvent *e);
+ signals:
+ void positionChanged(double newPosition);
+
private:
TQColor color;
TQColor highlightColor;
@@ -237,11 +240,13 @@ class TraceWidget : public TQWidget
void updateCursorText();
void processChangedOffset(double offset);
void processChangedCursor(uint cursorNumber, double newPosition);
+ void processChangedCusorPosition(double position);
signals:
void zoomBoxChanged(const TQRectF&);
void offsetChanged(uint traceNumber, double offset);
void cursorPositionChanged(uint cursorNumber, double newPosition);
+ void cursorDragged(uint cursorNumber, double newPosition);
private:
void resizeTraceArray(uint newsize);
diff --git a/lib/libtqtrla/src/tqtrla.h b/lib/libtqtrla/src/tqtrla.h
index 129eac9..be105b8 100644
--- a/lib/libtqtrla/src/tqtrla.h
+++ b/lib/libtqtrla/src/tqtrla.h
@@ -33,6 +33,13 @@
// =============================================================================
+typedef TQValueList<float> TQFloatList;
+typedef TQValueList<double> TQDoubleList;
+typedef TQValueList<TQ_INT32> TQInt32List;
+typedef TQValueList<TQ_INT16> TQInt16List;
+
+// =============================================================================
+
namespace KParts
{
class RemoteInstrumentPartPrivate;
diff --git a/servers/gpib_server_lin/src/gpib_conn.cpp b/servers/gpib_server_lin/src/gpib_conn.cpp
index b46f469..dc081a3 100644
--- a/servers/gpib_server_lin/src/gpib_conn.cpp
+++ b/servers/gpib_server_lin/src/gpib_conn.cpp
@@ -313,7 +313,7 @@ void GPIBSocket::commandLoop() {
else if (m_instrumentCommand == "SETVOLTSDIV") { // Want to change volts per division
TQ_INT32 value1;
ds >> value1;
- float value2;
+ double value2;
ds >> value2;
if (scope_set_volts_div(value1, value2, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) {
ds << TQString("ACK");
@@ -507,6 +507,34 @@ void GPIBSocket::commandLoop() {
writeEndOfFrame();
}
}
+ else if (m_instrumentCommand == "GETPERMITTEDVDIVS") { // Want to get permitted volts/div settings
+ double attenuation_mult;
+ double* permitted_array;
+ int permitted_count;
+ TQ_INT32 value;
+ ds >> value;
+ if (scope_get_probe_attenuation_multiplier(&attenuation_mult, value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) {
+ if (scope_get_permitted_volts_div_settings_at_1x(&permitted_count, &permitted_array, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) {
+ long i;
+ TQDoubleList permittedValues;
+ for (i=0; i<permitted_count; i++) {
+ permittedValues.append(permitted_array[i]/attenuation_mult);
+ }
+ free(permitted_array);
+ ds << TQString("ACK");
+ ds << permittedValues;
+ writeEndOfFrame();
+ }
+ else {
+ ds << TQString("NCK");
+ writeEndOfFrame();
+ }
+ }
+ else {
+ ds << TQString("NCK");
+ writeEndOfFrame();
+ }
+ }
else {
printf("[WARNING] Received unknown command %s from host %s\n\r", m_instrumentCommand.ascii(), m_remoteHost.ascii()); fflush(stdout);
}
diff --git a/servers/gpib_server_lin/src/scope_functions.cpp b/servers/gpib_server_lin/src/scope_functions.cpp
index ce5adcd..0ba0bc1 100644
--- a/servers/gpib_server_lin/src/scope_functions.cpp
+++ b/servers/gpib_server_lin/src/scope_functions.cpp
@@ -273,9 +273,9 @@ int scope_set_timebase(float desired_timebase,const char * scopeType, int gpibDe
}
}
-int scope_set_volts_div(int desired_channel, float desired_volts,const char * scopeType, int gpibDevice) {
+int scope_set_volts_div(int desired_channel, double desired_volts, const char * scopeType, int gpibDevice) {
if ((strcmp("HP54600OS", scopeType) == 0) || (strcmp("TDS744AOS", scopeType) == 0)) {
- printf("[INFO] Setting scope volts/div on channel %d to %f\n\r", desired_channel, desired_volts/8);
+ printf("[INFO] Setting scope volts/div on channel %d to %E\n\r", desired_channel, desired_volts);
if (strcmp("HP54600OS", scopeType) == 0) {
sprintf(falpha, "CHAN%d:RANG %E", desired_channel, desired_volts);
#ifdef ENABLE_EXTRA_DEBUGGING
@@ -289,7 +289,7 @@ int scope_set_volts_div(int desired_channel, float desired_volts,const char * sc
}
}
else if (strcmp("TDS744AOS", scopeType) == 0) {
- sprintf(falpha, "CH%d:SCALE %f", desired_channel, desired_volts/8);
+ sprintf(falpha, "CH%d:SCALE %E", desired_channel, desired_volts);
#ifdef ENABLE_EXTRA_DEBUGGING
printf("[DEBG] Writing: %s\n\r", falpha);
#endif
@@ -387,6 +387,7 @@ int scope_set_channel_state(int desired_channel, int status,const char * scopeTy
printf("[DEBG] Writing: %s\n\r", falpha);
#endif
if (gpib_write(gpibDevice, falpha) == 0) {
+ usleep(2*1000000); // The scope is slow to respond, and also blind to commands during the update window! [RAJA TESTME]
return 0;
}
else {
@@ -1118,4 +1119,83 @@ int scope_get_channel_sample_count(unsigned long * retval, int desired_channel,
else {
return -1;
}
+}
+
+int scope_get_probe_attenuation_multiplier(double * retval, int desired_channel, const char * scopeType, int gpibDevice) {
+ char floatstring[1024];
+ long ai;
+ int max_num_bytes = 0;
+
+ if (strcmp("HP54600OS", scopeType) == 0) {
+ // FIXME
+ // Not supported (yet)
+ return -1;
+ }
+ else if (strcmp("TDS744AOS", scopeType) == 0) {
+ // Send request
+ printf("[INFO] Getting trigger level for channel %d\n\r", desired_channel);
+ sprintf(falpha,"CH%d:PROBE?", desired_channel);
+ #ifdef ENABLE_EXTRA_DEBUGGING
+ printf("[DEBG] Writing: %s\n\r", falpha);
+ #endif
+ if (gpib_write(gpibDevice, falpha) == 0) {
+ max_num_bytes = 24; // Request more bytes than are possible to ensure no bytes are left behind
+ }
+ else {
+ return 2;
+ }
+
+ // Read response
+ #ifdef ENABLE_EXTRA_DEBUGGING
+ printf("[DEBG] Trying to read %i bytes from GPIB device...\n", max_num_bytes);
+ #endif
+
+ ai = gpib_read_array(gpibDevice, max_num_bytes, floatstring);
+ if (ai == -1) {
+ return 1;
+ }
+ else {
+ floatstring[ai]=0;
+ *retval = atof(floatstring);
+ }
+
+ #ifdef ENABLE_EXTRA_DEBUGGING
+ printf("[DEBG] Read %li bytes from GPIB device\n", ai);
+ #endif
+
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+int scope_get_permitted_volts_div_settings_at_1x(int * number_of_values, double ** retarray, const char * scopeType, int gpibDevice) {
+ if (strcmp("HP54600OS", scopeType) == 0) {
+ // FIXME
+ // Not supported (yet)
+ return -1;
+ }
+ else if (strcmp("TDS744AOS", scopeType) == 0) {
+ *number_of_values = 13;
+ double* values = (double*)malloc(sizeof(double)*(*number_of_values));
+ values[0] = 1e-3;
+ values[1] = 2e-3;
+ values[2] = 5e-3;
+ values[3] = 1e-2;
+ values[4] = 2e-2;
+ values[5] = 5e-2;
+ values[6] = 1e-1;
+ values[7] = 2e-1;
+ values[8] = 5e-1;
+ values[9] = 1e0;
+ values[10] = 2e0;
+ values[11] = 5e0;
+ values[12] = 1e1;
+ *retarray = values;
+ return 0;
+ }
+ else {
+ return -1;
+ }
} \ No newline at end of file
diff --git a/servers/gpib_server_lin/src/scope_functions.h b/servers/gpib_server_lin/src/scope_functions.h
index b38f821..a83ab9a 100644
--- a/servers/gpib_server_lin/src/scope_functions.h
+++ b/servers/gpib_server_lin/src/scope_functions.h
@@ -33,7 +33,7 @@ int scope_get_screenshot(const char * scopeType, int gpibDevice);
int scope_get_screenshot_stage2(const char * scopeType, int gpibDevice);
int scope_perform_initial_setup(const char * scopeType, int gpibDevice);
int scope_set_timebase(float desired_timebase,const char * scopeType, int gpibDevice);
-int scope_set_volts_div(int desired_channel, float desired_volts,const char * scopeType, int gpibDevice);
+int scope_set_volts_div(int desired_channel, double desired_volts, const char * scopeType, int gpibDevice);
int scope_set_acquisition(int status,const char * scopeType, int gpibDevice);
int scope_set_channel_state(int desired_channel, int status,const char * scopeType, int gpibDevice);
int scope_get_channel_state(int * retval, int desired_channel, const char * scopeType, int gpibDevice);
@@ -48,4 +48,6 @@ int scope_get_trigger_channel(int * retval, const char * scopeType, int gpibDevi
int scope_get_trigger_level(double * retval, const char * scopeType, int gpibDevice);
int scope_get_channel_volts_div(double * retval, int desired_channel, const char * scopeType, int gpibDevice);
int scope_get_channel_seconds_div(double * retval, int desired_channel, const char * scopeType, int gpibDevice);
-int scope_get_channel_sample_count(unsigned long * retval, int desired_channel, const char * scopeType, int gpibDevice); \ No newline at end of file
+int scope_get_channel_sample_count(unsigned long * retval, int desired_channel, const char * scopeType, int gpibDevice);
+int scope_get_probe_attenuation_multiplier(double * retval, int desired_channel, const char * scopeType, int gpibDevice);
+int scope_get_permitted_volts_div_settings_at_1x(int * number_of_values, double ** retarray, const char * scopeType, int gpibDevice); \ No newline at end of file