Add initial batch mode processing logic

master
Timothy Pearson 12 years ago
parent 9b06e81c07
commit 3218775391

@ -571,7 +571,7 @@
<cstring>batchTestOutputFile</cstring>
</property>
<property name="mode">
<number>25</number>
<number>17</number>
</property>
<property name="filter">
<cstring>*.txt|Text Files (*.txt)</cstring>

@ -31,6 +31,7 @@
#include <kstatusbar.h>
#include <kstdaction.h>
#include <knuminput.h>
#include <kurlrequester.h>
#include <tqfile.h> //encodeName()
#include <tqtimer.h> //postInit() hack
#include <tqvbox.h>
@ -39,6 +40,9 @@
#include <tqeventloop.h>
#include <tqapplication.h>
#include <tqgroupbox.h>
#include <tqcheckbox.h>
#include <tqpushbutton.h>
#include <tqprogressbar.h>
#include <unistd.h> //access()
#include <stdint.h>
@ -559,7 +563,8 @@ K_EXPORT_COMPONENT_FACTORY(libremotelab_fpgaviewer, RemoteLab::Factory)
FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList&)
: RemoteInstrumentPart( parent, name ), m_socket(0), m_base(0), connToServerConnecting(false), connToServerState(-1), connToServerTimeoutTimer(NULL), m_interfaceMode(BasicInterfaceMode),
m_commHandlerState(0), m_connectionActiveAndValid(false), m_tickerState(0), m_remoteInputModeEnabled(false), m_4bitInputValue(0), m_4bitOutputValue(0), m_8bitInputValue(0), m_8bitOutputValue(0),
m_16bitInputValue(0), m_16bitOutputValue(0), m_7segDigit3OutputValue(0xffffffff), m_7segDigit2OutputValue(0xffffffff), m_7segDigit1OutputValue(0xffffffff), m_7segDigit0OutputValue(0xffffffff)
m_16bitInputValue(0), m_16bitOutputValue(0), m_7segDigit3OutputValue(0xffffffff), m_7segDigit2OutputValue(0xffffffff), m_7segDigit1OutputValue(0xffffffff), m_7segDigit0OutputValue(0xffffffff),
m_batchOutputFile(NULL)
{
// Initialize mutex
m_connectionMutex = new TQMutex(false);
@ -686,6 +691,8 @@ FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObj
m_base->frameLEDDisplay->setFrameStyle(TQFrame::Box | TQFrame::Raised);
#endif
connect(m_base->batchTestRunButton, SIGNAL(clicked()), this, SLOT(batchTestRunButtonClicked()));
processAllGraphicsUpdates();
TQTimer::singleShot(0, this, TQT_SLOT(postInit()));
@ -854,6 +861,24 @@ void FPGAViewPart::processLockouts() {
m_modeIntermediateEnabled->setChecked(false);
m_modeAdvancedEnabled->setChecked(true);
}
if ((m_base->batchTestInputFile->url() != "") && (m_base->batchTestOutputFile->url() != "") && (m_commHandlerMode != 1) && (m_connectionActiveAndValid == true)) {
m_base->batchTestRunButton->setEnabled(true);
m_base->batchTest16BitCheckBox->setEnabled(true);
}
else {
m_base->batchTestRunButton->setEnabled(false);
m_base->batchTest16BitCheckBox->setEnabled(false);
}
if (m_commHandlerMode == 1) {
m_base->batchTestInputFile->setEnabled(false);
m_base->batchTestOutputFile->setEnabled(false);
}
else {
m_base->batchTestInputFile->setEnabled(true);
m_base->batchTestOutputFile->setEnabled(true);
}
}
void FPGAViewPart::switchToBasicMode() {
@ -1044,9 +1069,98 @@ TQPtrList<KAction> FPGAViewPart::menuActionList() {
return m_menuActionList;
}
void FPGAViewPart::batchTestRunButtonClicked() {
m_commHandlerState = 0;
m_commHandlerMode = 1;
m_batchUsing16Bit = m_base->batchTest16BitCheckBox->isChecked();
processLockouts();
}
void FPGAViewPart::sendInputStatesToRemoteFPGA() {
if (m_socket) {
char data[64];
process4BitInputChanges();
process8BitInputChanges();
process16BitInputChanges();
// 4-bit inputs
data[0] = 'I';
data[1] = '\r';
data[2] = m_4bitInputValue;
data[3] = '\r';
// 8-bit inputs
data[4] = 'B';
data[5] = '\r';
data[6] = m_8bitInputValue;
data[7] = '\r';
// 16-bit inputs
data[8] = 'C';
data[9] = '\r';
data[10] = (m_16bitInputValue&0xff00)>>8;
data[11] = m_16bitInputValue&0xff;
data[12] = '\r';
m_socket->writeBlock(data, 13);
}
}
void FPGAViewPart::receiveInputStatesFromRemoteFPGA() {
if (m_socket) {
char data[64];
// LCD
m_socket->readBlock(data, 32);
char line[34];
memcpy(line, data, 16);
line[16] = '\n';
memcpy(line+17, data+16, 16);
line[33] = 0;
m_base->LCDOutputLabel->setText(line);
// Remote/Local input mode
m_socket->readBlock(data, 1);
if (data[0] == 0) {
// Local mode
m_remoteInputModeEnabled = false;
}
else {
// Remote mode
m_remoteInputModeEnabled = true;
}
// 4-bit outputs
m_socket->readBlock(data, 1);
m_4bitOutputValue = data[0];
// 8-bit outputs
m_socket->readBlock(data, 1);
m_8bitOutputValue = data[0];
// 16-bit outputs
m_socket->readBlock(data, 2);
m_16bitOutputValue = (data[0] << 8) | data[1];
// 7-segment LED display
m_socket->readBlock(data, 4);
m_7segDigit3OutputValue = data[0];
m_7segDigit2OutputValue = data[1];
m_7segDigit1OutputValue = data[2];
m_7segDigit0OutputValue = data[3];
// Write changes to GUI
process4BitOutputChanges();
process8BitInputChanges();
process8BitOutputChanges();
process16BitOutputChanges();
processLCDOutputChanges();
process7SegmentLEDOutputChanges();
}
}
#define UPDATEDISPLAY_TIMEOUT m_connectionActiveAndValid = false; \
m_tickerState = 0; \
m_commHandlerState = 0; \
m_commHandlerMode = 0; \
while (m_socket->bytesAvailable() > 0) { \
m_socket->readBlock(data, 64); \
} \
@ -1060,124 +1174,163 @@ void FPGAViewPart::updateDisplay() {
if (m_socket) {
char data[64];
switch (m_commHandlerState) {
case 0:
// Send current input states to remote system
process4BitInputChanges();
process8BitInputChanges();
process16BitInputChanges();
// 4-bit inputs
data[0] = 'I';
data[1] = '\r';
data[2] = m_4bitInputValue;
data[3] = '\r';
// 8-bit inputs
data[4] = 'B';
data[5] = '\r';
data[6] = m_8bitInputValue;
data[7] = '\r';
// 16-bit inputs
data[8] = 'C';
data[9] = '\r';
data[10] = (m_16bitInputValue&0xff00)>>8;
data[11] = m_16bitInputValue&0xff;
data[12] = '\r';
m_socket->writeBlock(data, 13);
// Send request for all output states
m_socket->writeLine("L\r");
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE);
m_commHandlerState = 1;
break;
case 1:
if (m_commHandlerMode == 0) {
// Normal operation
switch (m_commHandlerState) {
case 0:
// Send current input states to remote system
sendInputStatesToRemoteFPGA();
// Send request for all output states
m_socket->writeLine("L\r");
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE);
m_commHandlerState = 1;
break;
case 1:
// Get all data
if (m_socket->bytesAvailable() >= 41) {
// Process the received data packet
receiveInputStatesFromRemoteFPGA();
m_connectionActiveAndValid = true;
TQString tickerChar;
switch (m_tickerState) {
case 0:
tickerChar = "-";
break;
case 1:
tickerChar = "\\";
break;
case 2:
tickerChar = "|";
break;
case 3:
tickerChar = "/";
break;
}
setStatusMessage(i18n("Running") + TQString("... %1").arg(tickerChar));
m_tickerState++;
if (m_tickerState > 3) {
m_tickerState = 0;
}
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE);
m_commHandlerState = 0;
}
else {
if (!m_updateTimer->isActive()) {
UPDATEDISPLAY_TIMEOUT
}
}
break;
}
}
else if (m_commHandlerMode == 1) {
// Batch test mode
// This expects to see a newline-delimited text file containing input values to test
if (m_commHandlerState == 0) {
m_batchInputValueList.clear();
TQFile file(m_base->batchTestInputFile->url());
if (file.open(IO_ReadOnly)) {
TQTextStream stream(&file);
TQString line;
while (!stream.atEnd()) {
line = stream.readLine();
m_batchInputValueList.append(line.toUInt());
}
file.close();
m_base->batchTestProgressBar->setTotalSteps(m_batchInputValueList.count());
m_batchOutputFile = new TQFile(m_base->batchTestOutputFile->url());
if (m_batchOutputFile->open(IO_WriteOnly)) {
m_batchCurrentValueIndex = 0;
m_commHandlerState = 1;
}
else {
KMessageBox::error(0, i18n("<qt>Unable to open selected batch output file</qt>"), i18n("Batch Failed"));
m_commHandlerMode = 0;
m_commHandlerState = 0;
m_base->batchTestProgressBar->setProgress(0);
processLockouts();
}
}
else {
KMessageBox::error(0, i18n("<qt>Unable to open selected batch input file</qt>"), i18n("Batch Failed"));
m_commHandlerMode = 0;
m_commHandlerState = 0;
m_base->batchTestProgressBar->setProgress(0);
processLockouts();
}
}
else if (m_commHandlerState == 1) {
if (m_batchCurrentValueIndex >= m_batchInputValueList.count()) {
// Done!
m_commHandlerMode = 0;
m_commHandlerState = 0;
m_base->batchTestProgressBar->setProgress(0);
processLockouts();
}
else {
if (m_batchUsing16Bit) {
m_16bitInputValue = m_batchInputValueList[m_batchCurrentValueIndex];
}
else {
m_8bitInputValue = m_batchInputValueList[m_batchCurrentValueIndex];
}
sendInputStatesToRemoteFPGA();
// Send request for all output states
m_socket->writeLine("L\r");
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE);
m_commHandlerState = 2;
}
}
else if (m_commHandlerState == 2) {
// Get all data
if (m_socket->bytesAvailable() >= 41) {
TQString line;
// Process the received data packet
// LCD
m_socket->readBlock(data, 32);
char line[34];
memcpy(line, data, 16);
line[16] = '\n';
memcpy(line+17, data+16, 16);
line[33] = 0;
m_base->LCDOutputLabel->setText(line);
// Remote/Local input mode
m_socket->readBlock(data, 1);
if (data[0] == 0) {
// Local mode
m_remoteInputModeEnabled = false;
receiveInputStatesFromRemoteFPGA();
// Write received data to batch output file
if (m_batchUsing16Bit) {
line = TQString("%1\n").arg(m_16bitOutputValue);
}
else {
// Remote mode
m_remoteInputModeEnabled = true;
line = TQString("%1\n").arg(m_8bitOutputValue);
}
// 4-bit outputs
m_socket->readBlock(data, 1);
m_4bitOutputValue = data[0];
// 8-bit outputs
m_socket->readBlock(data, 1);
m_8bitOutputValue = data[0];
// 16-bit outputs
m_socket->readBlock(data, 2);
m_16bitOutputValue = (data[0] << 8) | data[1];
// 7-segment LED display
m_socket->readBlock(data, 4);
m_7segDigit3OutputValue = data[0];
m_7segDigit2OutputValue = data[1];
m_7segDigit1OutputValue = data[2];
m_7segDigit0OutputValue = data[3];
// Write changes to GUI
process4BitOutputChanges();
process8BitInputChanges();
process8BitOutputChanges();
process16BitOutputChanges();
processLCDOutputChanges();
process7SegmentLEDOutputChanges();
m_batchOutputFile->writeBlock(line.ascii(), line.length());
m_base->batchTestProgressBar->setProgress(m_batchCurrentValueIndex);
m_batchCurrentValueIndex++;
m_connectionActiveAndValid = true;
TQString tickerChar;
switch (m_tickerState) {
case 0:
tickerChar = "-";
break;
case 1:
tickerChar = "\\";
break;
case 2:
tickerChar = "|";
break;
case 3:
tickerChar = "/";
break;
}
setStatusMessage(i18n("Running") + TQString("... %1").arg(tickerChar));
m_tickerState++;
if (m_tickerState > 3) {
m_tickerState = 0;
}
setStatusMessage(i18n("Running batch test") + "...");
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE);
m_commHandlerState = 0;
m_commHandlerState = 1;
}
else {
if (!m_updateTimer->isActive()) {
UPDATEDISPLAY_TIMEOUT
m_base->batchTestProgressBar->setProgress(0);
processLockouts();
}
}
break;
}
}
else if (m_commHandlerMode == 2) {
// Data processing mode
// This detects when the incoming data file is a picture (bmp, png, etc.) and processes it accordingly
// RAJA FIXME
}
}
else {
m_commHandlerState = 0;
m_commHandlerMode = 0;
}
}

@ -42,6 +42,7 @@ class TraceWidget;
class TQSocket;
class TQTimer;
class TQMutex;
class TQFile;
class FPGAViewBase;
class FPGALed : public KLed
@ -124,6 +125,8 @@ class Q_EXPORT FPGA7Segment : public TQFrame
FPGA7SegmentPrivate *d;
};
typedef TQValueList<unsigned int> UnsignedIntegerList;
namespace RemoteLab
{
class FPGAViewPart : public KParts::RemoteInstrumentPart
@ -170,6 +173,12 @@ namespace RemoteLab
void process16BitOutputChanges();
void processLCDOutputChanges();
void process7SegmentLEDOutputChanges();
void batchTestRunButtonClicked();
private:
void sendInputStatesToRemoteFPGA();
void receiveInputStatesFromRemoteFPGA();
private:
TDEKerberosClientSocket* m_socket;
@ -190,6 +199,7 @@ namespace RemoteLab
InterfaceMode m_interfaceMode;
int m_commHandlerState;
int m_commHandlerMode;
bool m_connectionActiveAndValid;
unsigned char m_tickerState;
bool m_remoteInputModeEnabled;
@ -204,6 +214,12 @@ namespace RemoteLab
unsigned int m_7segDigit2OutputValue;
unsigned int m_7segDigit1OutputValue;
unsigned int m_7segDigit0OutputValue;
UnsignedIntegerList m_batchInputValueList;
UnsignedIntegerList m_batchOutputValueList;
unsigned int m_batchCurrentValueIndex;
bool m_batchUsing16Bit;
TQFile* m_batchOutputFile;
};
}

Loading…
Cancel
Save