Fix FPGA programmer

master
Timothy Pearson 12 years ago
parent 0f3b0430e8
commit 9c3d84d0df

@ -62,7 +62,7 @@ bool InstrumentView::eventFilter(TQObject *o, TQEvent *e) {
if (childPartWidget) { if (childPartWidget) {
if (o == childPartWidget) { if (o == childPartWidget) {
if (e->type() == TQEvent::Resize) { if (e->type() == TQEvent::Resize) {
setChildSizeToHint(); setChildSizeData();
} }
} }
} }
@ -71,7 +71,7 @@ bool InstrumentView::eventFilter(TQObject *o, TQEvent *e) {
return FALSE; return FALSE;
} }
void InstrumentView::setChildSizeToHint() { void InstrumentView::setChildSizeData() {
if (m_instrumentPart) { if (m_instrumentPart) {
TQWidget *childPartWidget = m_instrumentPart->widget(); TQWidget *childPartWidget = m_instrumentPart->widget();
if (childPartWidget) { if (childPartWidget) {
@ -79,8 +79,14 @@ void InstrumentView::setChildSizeToHint() {
setFixedSize(childPartWidget->sizeHint()); setFixedSize(childPartWidget->sizeHint());
} }
else { else {
TQSize childSizeHint = childPartWidget->sizeHint(); TQSize minimumSizeHint;
setMinimumSize(childSizeHint.width(), childSizeHint.height()); if (childPartWidget->layout()) {
minimumSizeHint = childPartWidget->layout()->minimumSize();
}
else {
minimumSizeHint = childPartWidget->minimumSize();
}
setMinimumSize(minimumSizeHint.width(), minimumSizeHint.height());
resize(childPartWidget->size()); resize(childPartWidget->size());
} }
} }
@ -93,11 +99,11 @@ void InstrumentView::setUsingFixedSize(bool fixed) {
setMinimumSize(0, 0); setMinimumSize(0, 0);
setMaximumSize(TQWIDGETSIZE_MAX, TQWIDGETSIZE_MAX); setMaximumSize(TQWIDGETSIZE_MAX, TQWIDGETSIZE_MAX);
} }
setChildSizeToHint(); setChildSizeData();
} }
void InstrumentView::resizeEvent(TQResizeEvent *) { void InstrumentView::resizeEvent(TQResizeEvent *) {
setChildSizeToHint(); setChildSizeData();
} }
TQPtrList<KAction> InstrumentView::menuActionList() { TQPtrList<KAction> InstrumentView::menuActionList() {

@ -39,7 +39,7 @@ class InstrumentView : public KMdiChildView
private slots: private slots:
void setStatusMessage(const TQString& message); void setStatusMessage(const TQString& message);
void setUsingFixedSize(bool fixed); void setUsingFixedSize(bool fixed);
void setChildSizeToHint(); void setChildSizeData();
signals: signals:
void statusMessageSet(const TQString&); void statusMessageSet(const TQString&);

@ -51,7 +51,7 @@
<cstring>programRunButton</cstring> <cstring>programRunButton</cstring>
</property> </property>
<property name="text"> <property name="text">
<cstring>Upload File</cstring> <cstring>Program FPGA</cstring>
</property> </property>
</widget> </widget>
<widget class="TQProgressBar" row="2" column="0" colspan="3"> <widget class="TQProgressBar" row="2" column="0" colspan="3">
@ -77,11 +77,27 @@
<string>Log</string> <string>Log</string>
</property> </property>
<grid> <grid>
<widget class="KTextEdit" row="0" column="0" colspan="0"> <widget class="KTextEdit" row="0" column="0" colspan="2">
<property name="name"> <property name="name">
<cstring>programmingLogBox</cstring> <cstring>programmingLogBox</cstring>
</property> </property>
</widget> </widget>
<widget class="TQPushButton" row="1" column="0">
<property name="name">
<cstring>saveProgrammingLogButton</cstring>
</property>
<property name="text">
<cstring>Save</cstring>
</property>
</widget>
<widget class="TQPushButton" row="1" column="1">
<property name="name">
<cstring>clearProgrammingLogButton</cstring>
</property>
<property name="text">
<cstring>Clear</cstring>
</property>
</widget>
</grid> </grid>
</widget> </widget>
</grid> </grid>

@ -27,6 +27,7 @@
#include <kaction.h> #include <kaction.h>
#include <klocale.h> #include <klocale.h>
#include <ktextedit.h> #include <ktextedit.h>
#include <kfiledialog.h>
#include <kmessagebox.h> //::start() #include <kmessagebox.h> //::start()
#include <kparts/genericfactory.h> #include <kparts/genericfactory.h>
#include <kstatusbar.h> #include <kstatusbar.h>
@ -56,6 +57,22 @@
#define NETWORK_COMM_TIMEOUT_MS 2500 #define NETWORK_COMM_TIMEOUT_MS 2500
enum connectionModes {
ModeIdle = 0,
ModeProgramming = 1
};
enum connectionStates {
ModeIdle_StateStatusRequest = 0,
ModeIdle_StateProcessStatus = 1,
ModeIdle_StateDelay = 2,
ModeIdle_StateGetLogMessages = 3,
ModeProgramming_StateReadFile = 100,
ModeProgramming_StateInitProgramming = 101,
ModeProgramming_StateWaitForCompletion = 102,
ModeProgramming_StateRequestStatus = 103
};
namespace RemoteLab { namespace RemoteLab {
typedef KParts::GenericFactory<RemoteLab::FPGAProgramPart> Factory; typedef KParts::GenericFactory<RemoteLab::FPGAProgramPart> Factory;
@ -76,6 +93,8 @@ FPGAProgramPart::FPGAProgramPart(TQWidget *parentWidget, const char *widgetName,
setWidget(new TQVBox(parentWidget, widgetName)); setWidget(new TQVBox(parentWidget, widgetName));
// Create timers // Create timers
m_forcedUpdateTimer = new TQTimer(this);
connect(m_forcedUpdateTimer, SIGNAL(timeout()), this, SLOT(mainEventLoop()));
m_updateTimeoutTimer = new TQTimer(this); m_updateTimeoutTimer = new TQTimer(this);
connect(m_updateTimeoutTimer, SIGNAL(timeout()), this, SLOT(mainEventLoop())); connect(m_updateTimeoutTimer, SIGNAL(timeout()), this, SLOT(mainEventLoop()));
m_pingDelayTimer = new TQTimer(this); m_pingDelayTimer = new TQTimer(this);
@ -87,6 +106,8 @@ FPGAProgramPart::FPGAProgramPart(TQWidget *parentWidget, const char *widgetName,
// Initialize widgets // Initialize widgets
m_base->programmingLogBox->setReadOnly(true); m_base->programmingLogBox->setReadOnly(true);
connect(m_base->programRunButton, SIGNAL(clicked()), this, SLOT(programRunButtonClicked())); connect(m_base->programRunButton, SIGNAL(clicked()), this, SLOT(programRunButtonClicked()));
connect(m_base->clearProgrammingLogButton, SIGNAL(clicked()), this, SLOT(clearProgrammingLogBox()));
connect(m_base->saveProgrammingLogButton, SIGNAL(clicked()), this, SLOT(saveProgrammingLogBox()));
connect(m_base->programmingInputFile, SIGNAL(textChanged(const TQString &)), this, SLOT(processLockouts())); connect(m_base->programmingInputFile, SIGNAL(textChanged(const TQString &)), this, SLOT(processLockouts()));
TQTimer::singleShot(0, this, TQT_SLOT(postInit())); TQTimer::singleShot(0, this, TQT_SLOT(postInit()));
@ -140,7 +161,7 @@ void FPGAProgramPart::connectionClosed() {
} }
void FPGAProgramPart::postInit() { void FPGAProgramPart::postInit() {
setUsingFixedSize(true); setUsingFixedSize(false);
} }
bool FPGAProgramPart::openURL(const KURL &url) { bool FPGAProgramPart::openURL(const KURL &url) {
@ -157,6 +178,7 @@ bool FPGAProgramPart::closeURL() {
} }
void FPGAProgramPart::disconnectFromServerCallback() { void FPGAProgramPart::disconnectFromServerCallback() {
m_forcedUpdateTimer->stop();
m_updateTimeoutTimer->stop(); m_updateTimeoutTimer->stop();
} }
@ -165,8 +187,8 @@ void FPGAProgramPart::connectionFinishedCallback() {
m_socket->processPendingData(); m_socket->processPendingData();
connect(m_socket, SIGNAL(newDataReceived()), this, SLOT(mainEventLoop())); connect(m_socket, SIGNAL(newDataReceived()), this, SLOT(mainEventLoop()));
m_tickerState = 0; m_tickerState = 0;
m_commHandlerState = 0; m_commHandlerState = ModeIdle_StateStatusRequest;
m_commHandlerMode = 0; m_commHandlerMode = ModeIdle;
m_socket->setDataTimeout(NETWORK_COMM_TIMEOUT_MS); m_socket->setDataTimeout(NETWORK_COMM_TIMEOUT_MS);
m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE); m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
processLockouts(); processLockouts();
@ -179,23 +201,46 @@ void FPGAProgramPart::connectionStatusChangedCallback() {
} }
void FPGAProgramPart::programRunButtonClicked() { void FPGAProgramPart::programRunButtonClicked() {
m_commHandlerState = 0; m_commHandlerState = ModeProgramming_StateReadFile;
m_commHandlerMode = 1; m_commHandlerMode = ModeProgramming;
processLockouts(); processLockouts();
} }
#define UPDATEDISPLAY_TIMEOUT m_connectionActiveAndValid = false; \ void FPGAProgramPart::clearProgrammingLogBox() {
m_tickerState = 0; \ m_base->programmingLogBox->setText("");
m_commHandlerState = 0; \ }
m_commHandlerMode = 0; \
m_socket->clearIncomingData(); \ void FPGAProgramPart::saveProgrammingLogBox() {
setStatusMessage(i18n("Server ping timeout. Please verify the status of your network connection.")); \ TQString saveFileName = KFileDialog::getSaveFileName(TQString::null, "*.txt|Text Files (*.txt)", 0, i18n("Save log file..."));
m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE); \ if (saveFileName != "") {
m_connectionMutex->unlock(); \ TQFile file(saveFileName);
return; if (file.open(IO_WriteOnly)) {
TQCString logFile = m_base->programmingLogBox->text().ascii();
m_programmingFileData = file.writeBlock(logFile.data(), logFile.size());
file.close();
}
else {
KMessageBox::error(0, i18n("<qt>Unable to save log file<p>Please check permissions and try again</qt>"), i18n("Save Failed"));
}
}
}
#define SET_WATCHDOG_TIMER if (!m_updateTimeoutTimer->isActive()) m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE); #define UPDATEDISPLAY_TIMEOUT m_connectionActiveAndValid = false; \
#define PAT_WATCHDOG_TIMER m_updateTimeoutTimer->stop(); m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE); m_tickerState = 0; \
m_commHandlerState = ModeIdle_StateStatusRequest; \
m_commHandlerMode = ModeIdle; \
m_socket->clearIncomingData(); \
setStatusMessage(i18n("Server ping timeout. Please verify the status of your network connection.")); \
m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE); \
m_connectionMutex->unlock(); \
return;
#define SET_WATCHDOG_TIMER if (!m_updateTimeoutTimer->isActive()) m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
#define PAT_WATCHDOG_TIMER m_updateTimeoutTimer->stop(); m_updateTimeoutTimer->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
#define SET_NEXT_STATE(x) m_commHandlerState = x;
#define EXEC_NEXT_STATE_IMMEDIATELY m_forcedUpdateTimer->start(0, TRUE);
void FPGAProgramPart::setTickerMessage(TQString message) { void FPGAProgramPart::setTickerMessage(TQString message) {
m_connectionActiveAndValid = true; m_connectionActiveAndValid = true;
@ -226,24 +271,24 @@ void FPGAProgramPart::mainEventLoop() {
ds.setPrintableData(true); ds.setPrintableData(true);
if (!m_connectionMutex->tryLock()) { if (!m_connectionMutex->tryLock()) {
TQTimer::singleShot(0, this, SLOT(mainEventLoop())); // Handle the concurrently received call immediately after current execution EXEC_NEXT_STATE_IMMEDIATELY
return; return;
} }
if (m_socket) { if (m_socket) {
if (m_commHandlerMode == 0) { if (m_commHandlerMode == ModeIdle) {
// Normal operation // Normal operation
switch (m_commHandlerState) { switch (m_commHandlerState) {
case 0: case ModeIdle_StateStatusRequest:
// Get status of remote system // Get status of remote system
// Clear buffers to synchronize frames in case of data corruption // Clear buffers to synchronize frames in case of data corruption
m_socket->clearIncomingData(); m_socket->clearIncomingData();
ds << TQString("STATUS"); ds << TQString("STATUS");
m_socket->writeEndOfFrame(); m_socket->writeEndOfFrame();
m_commHandlerState = 1; SET_NEXT_STATE(ModeIdle_StateProcessStatus)
break; break;
case 1: case ModeIdle_StateProcessStatus:
// Get all data // Get all data
if (m_socket->canReadFrame()) { if (m_socket->canReadFrame()) {
PAT_WATCHDOG_TIMER PAT_WATCHDOG_TIMER
@ -260,19 +305,18 @@ void FPGAProgramPart::mainEventLoop() {
// Do nothing // Do nothing
} }
else if (status == "LOGMESSAGES") { else if (status == "LOGMESSAGES") {
// Fire next event loop immediately EXEC_NEXT_STATE_IMMEDIATELY
TQTimer::singleShot(0, this, SLOT(mainEventLoop()));
// Retrieve messages on next event loop // Retrieve messages on next event loop
m_commHandlerState = 3; SET_NEXT_STATE(ModeIdle_StateGetLogMessages);
m_commHandlerNextState = 2; m_commHandlerNextState = ModeIdle_StateDelay;
m_commHandlerNextMode = 0; m_commHandlerNextMode = ModeIdle;
} }
setTickerMessage(i18n("Connected")); setTickerMessage(i18n("Connected"));
if (m_commHandlerState == 1) { if (m_commHandlerState == ModeIdle_StateProcessStatus) {
m_pingDelayTimer->start(250, TRUE); m_pingDelayTimer->start(250, TRUE);
m_commHandlerState = 2; SET_NEXT_STATE(ModeIdle_StateDelay);
} }
} }
else { else {
@ -281,17 +325,16 @@ void FPGAProgramPart::mainEventLoop() {
} }
} }
break; break;
case 2: case ModeIdle_StateDelay:
// Let the client and server rest for a bit to lower CPU/network overhead // Let the client and server rest for a bit to lower CPU/network overhead
if (!m_pingDelayTimer->isActive()) { if (!m_pingDelayTimer->isActive()) {
// Fire next event loop immediately EXEC_NEXT_STATE_IMMEDIATELY
TQTimer::singleShot(0, this, SLOT(mainEventLoop()));
// Execute query on next event loop // Execute query on next event loop
m_commHandlerState = 0; SET_NEXT_STATE(ModeIdle_StateStatusRequest);
} }
PAT_WATCHDOG_TIMER PAT_WATCHDOG_TIMER
break; break;
case 3: case ModeIdle_StateGetLogMessages:
// Get new log messages // Get new log messages
if (m_socket->canReadFrame()) { if (m_socket->canReadFrame()) {
PAT_WATCHDOG_TIMER PAT_WATCHDOG_TIMER
@ -308,7 +351,7 @@ void FPGAProgramPart::mainEventLoop() {
m_base->programmingLogBox->append(messages); m_base->programmingLogBox->append(messages);
m_pingDelayTimer->start(250, TRUE); m_pingDelayTimer->start(250, TRUE);
m_commHandlerState = m_commHandlerNextState; SET_NEXT_STATE(m_commHandlerNextState);
m_commHandlerMode = m_commHandlerNextMode; m_commHandlerMode = m_commHandlerNextMode;
} }
} }
@ -322,7 +365,7 @@ void FPGAProgramPart::mainEventLoop() {
} }
else if (m_commHandlerMode == 1) { else if (m_commHandlerMode == 1) {
// Program mode! // Program mode!
if (m_commHandlerState == 0) { if (m_commHandlerState == ModeProgramming_StateReadFile) {
m_base->programmingStatusLabel->setText(i18n("Reading input file") + "..."); m_base->programmingStatusLabel->setText(i18n("Reading input file") + "...");
TQFile file(m_base->programmingInputFile->url()); TQFile file(m_base->programmingInputFile->url());
if (file.open(IO_ReadOnly)) { if (file.open(IO_ReadOnly)) {
@ -343,18 +386,18 @@ void FPGAProgramPart::mainEventLoop() {
m_socket->writeEndOfFrame(); m_socket->writeEndOfFrame();
m_base->programmingProgressBar->setTotalSteps(m_programmingFileTotalSize); m_base->programmingProgressBar->setTotalSteps(m_programmingFileTotalSize);
m_commHandlerState = 1; SET_NEXT_STATE(ModeProgramming_StateInitProgramming);
} }
else { else {
KMessageBox::error(0, i18n("<qt>Unable to open selected programming file</qt>"), i18n("Program Failed")); KMessageBox::error(0, i18n("<qt>Unable to open selected programming file</qt>"), i18n("Program Failed"));
m_commHandlerMode = 0; m_commHandlerMode = ModeIdle;
m_commHandlerState = 0; SET_NEXT_STATE(ModeIdle_StateStatusRequest);
m_base->programmingProgressBar->reset(); m_base->programmingProgressBar->reset();
processLockouts(); processLockouts();
} }
PAT_WATCHDOG_TIMER PAT_WATCHDOG_TIMER
} }
else if (m_commHandlerState == 1) { else if (m_commHandlerState == ModeProgramming_StateInitProgramming) {
TQ_ULONG bytesLeft = (m_programmingFileTotalSize-m_programmingFileTransferredBytes); TQ_ULONG bytesLeft = (m_programmingFileTotalSize-m_programmingFileTransferredBytes);
TQ_ULONG bytesToTransfer = bytesLeft; TQ_ULONG bytesToTransfer = bytesLeft;
TQ_ULONG maxTransferChunk = maximumSocketDataChunkSize(); TQ_ULONG maxTransferChunk = maximumSocketDataChunkSize();
@ -362,6 +405,7 @@ void FPGAProgramPart::mainEventLoop() {
bytesToTransfer = maxTransferChunk; bytesToTransfer = maxTransferChunk;
} }
m_programmingFileTransferredBytes = m_programmingFileTransferredBytes + m_socket->writeBlock(m_programmingFileData.data()+m_programmingFileTransferredBytes, bytesToTransfer); m_programmingFileTransferredBytes = m_programmingFileTransferredBytes + m_socket->writeBlock(m_programmingFileData.data()+m_programmingFileTransferredBytes, bytesToTransfer);
m_socket->flush();
m_base->programmingProgressBar->setProgress(m_programmingFileTransferredBytes); m_base->programmingProgressBar->setProgress(m_programmingFileTransferredBytes);
if (m_programmingFileTransferredBytes >= m_programmingFileTotalSize) { if (m_programmingFileTransferredBytes >= m_programmingFileTotalSize) {
// Initiate programming // Initiate programming
@ -377,38 +421,37 @@ void FPGAProgramPart::mainEventLoop() {
m_base->programmingProgressBar->setTotalSteps(0); m_base->programmingProgressBar->setTotalSteps(0);
m_base->programmingProgressBar->setProgress(0); m_base->programmingProgressBar->setProgress(0);
m_commHandlerState = 2; SET_NEXT_STATE(ModeProgramming_StateWaitForCompletion);
} }
else { else {
setTickerMessage(i18n("Transmitting data")); setTickerMessage(i18n("Transmitting data"));
// Fire next event loop immediately EXEC_NEXT_STATE_IMMEDIATELY
TQTimer::singleShot(0, this, SLOT(mainEventLoop()));
} }
PAT_WATCHDOG_TIMER PAT_WATCHDOG_TIMER
} }
else if (m_commHandlerState == 2) { else if (m_commHandlerState == ModeProgramming_StateWaitForCompletion) {
// Get response // Get response
if (m_socket->canReadFrame()) { if (m_socket->canReadFrame()) {
PAT_WATCHDOG_TIMER PAT_WATCHDOG_TIMER
TQString result; TQString result;
ds >> result; ds >> result;
m_socket->clearFrameTail();
if (result == "PROGRAMMING") { if (result == "PROGRAMMING") {
m_socket->clearFrameTail();
setTickerMessage(i18n("Programming device")); setTickerMessage(i18n("Programming device"));
// Request status // Request status
ds << TQString("STATUS"); ds << TQString("STATUS");
m_socket->writeEndOfFrame(); m_socket->writeEndOfFrame();
} }
else if (result == "LOGMESSAGES") { else if (result == "LOGMESSAGES") {
// Fire next event loop immediately m_socket->clearFrameTail();
TQTimer::singleShot(0, this, SLOT(mainEventLoop())); EXEC_NEXT_STATE_IMMEDIATELY
// Retrieve messages on next event loop // Retrieve messages on next event loop
m_commHandlerState = 3; SET_NEXT_STATE(ModeIdle_StateGetLogMessages);
m_commHandlerMode = 0; m_commHandlerMode = ModeIdle;
m_commHandlerNextState = 3; m_commHandlerNextState = ModeProgramming_StateRequestStatus;
m_commHandlerNextMode = 1; m_commHandlerNextMode = ModeProgramming;
} }
else if (result == "DONE") { else if (result == "DONE") {
TQ_INT32 retCode; TQ_INT32 retCode;
@ -419,27 +462,28 @@ void FPGAProgramPart::mainEventLoop() {
if (retCode != 0) { if (retCode != 0) {
// Error! // Error!
m_commHandlerMode = 0; m_commHandlerMode = ModeIdle;
m_commHandlerState = 0; SET_NEXT_STATE(ModeIdle_StateStatusRequest);
TQTimer::singleShot(0, this, SLOT(mainEventLoop())); EXEC_NEXT_STATE_IMMEDIATELY
m_base->programmingProgressBar->reset(); m_base->programmingProgressBar->reset();
KMessageBox::error(0, i18n("<qt>Programming process failure<p>Please see log for details</qt>"), i18n("Program Failed")); KMessageBox::error(0, i18n("<qt>Programming process failure<p>Please see log for details</qt>"), i18n("Program Failed"));
processLockouts(); processLockouts();
} }
else { else {
// Done! // Done!
m_commHandlerMode = 0; m_commHandlerMode = ModeIdle;
m_commHandlerState = 0; SET_NEXT_STATE(ModeIdle_StateStatusRequest);
TQTimer::singleShot(0, this, SLOT(mainEventLoop())); EXEC_NEXT_STATE_IMMEDIATELY
m_base->programmingProgressBar->reset(); m_base->programmingProgressBar->reset();
processLockouts(); processLockouts();
} }
} }
else if (result == "ERROR") { else if (result == "ERROR") {
// Error! // Error!
m_commHandlerMode = 0; m_socket->clearFrameTail();
m_commHandlerState = 0; m_commHandlerMode = ModeIdle;
TQTimer::singleShot(0, this, SLOT(mainEventLoop())); SET_NEXT_STATE(ModeIdle_StateStatusRequest);
EXEC_NEXT_STATE_IMMEDIATELY
m_base->programmingProgressBar->reset(); m_base->programmingProgressBar->reset();
KMessageBox::error(0, i18n("<qt>Unknown error</qt>"), i18n("Program Failed")); KMessageBox::error(0, i18n("<qt>Unknown error</qt>"), i18n("Program Failed"));
processLockouts(); processLockouts();
@ -447,26 +491,27 @@ void FPGAProgramPart::mainEventLoop() {
else { else {
// Unknown response // Unknown response
// Request status // Request status
m_socket->clearFrameTail();
ds << TQString("STATUS"); ds << TQString("STATUS");
m_socket->writeEndOfFrame(); m_socket->writeEndOfFrame();
} }
} }
else { else {
if (!m_updateTimeoutTimer->isActive()) { if (!m_updateTimeoutTimer->isActive()) {
m_commHandlerMode = 0; m_commHandlerMode = ModeIdle;
m_commHandlerState = 0; SET_NEXT_STATE(ModeIdle_StateStatusRequest);
TQTimer::singleShot(0, this, SLOT(mainEventLoop())); EXEC_NEXT_STATE_IMMEDIATELY
m_base->programmingProgressBar->reset(); m_base->programmingProgressBar->reset();
processLockouts(); processLockouts();
UPDATEDISPLAY_TIMEOUT UPDATEDISPLAY_TIMEOUT
} }
} }
} }
else if (m_commHandlerState == 3) { else if (m_commHandlerState == ModeProgramming_StateRequestStatus) {
// Request status // Request status
ds << TQString("STATUS"); ds << TQString("STATUS");
m_socket->writeEndOfFrame(); m_socket->writeEndOfFrame();
m_commHandlerState = 2; SET_NEXT_STATE(ModeProgramming_StateWaitForCompletion);
PAT_WATCHDOG_TIMER PAT_WATCHDOG_TIMER
} }
} }
@ -474,8 +519,8 @@ void FPGAProgramPart::mainEventLoop() {
SET_WATCHDOG_TIMER SET_WATCHDOG_TIMER
} }
else { else {
m_commHandlerState = 0; SET_NEXT_STATE(ModeIdle_StateStatusRequest);
m_commHandlerMode = 0; m_commHandlerMode = ModeIdle;
} }
m_connectionMutex->unlock(); m_connectionMutex->unlock();

@ -75,11 +75,14 @@ namespace RemoteLab
void setTickerMessage(TQString message); void setTickerMessage(TQString message);
void programRunButtonClicked(); void programRunButtonClicked();
void clearProgrammingLogBox();
void saveProgrammingLogBox();
private: private:
FPGAProgramBase* m_base; FPGAProgramBase* m_base;
TQMutex* m_connectionMutex; TQMutex* m_connectionMutex;
TQTimer* m_pingDelayTimer; TQTimer* m_pingDelayTimer;
TQTimer* m_forcedUpdateTimer;
TQTimer* m_updateTimeoutTimer; TQTimer* m_updateTimeoutTimer;
int m_commHandlerState; int m_commHandlerState;

@ -275,19 +275,29 @@ int AuthSocket::servLoop() {
break; break;
case 4: case 4:
if (m_servClientSocket->state() == TQSocket::Connected) { if (m_servClientSocket->state() == TQSocket::Connected) {
TQ_ULONG reclen; TQ_LONG reclen;
if (canReadData()) { if (canReadData()) {
reclen = readBlock(m_loopBuffer.data(), m_loopBuffer.size()); reclen = readBlock(m_loopBuffer.data(), m_loopBuffer.size());
m_servClientSocket->writeBlock(m_loopBuffer.data(), reclen); if (reclen > 0) {
m_servClientSocket->flush(); m_servClientSocket->writeBlock(m_loopBuffer.data(), reclen);
transferred_data = true; m_servClientSocket->flush();
transferred_data = true;
}
else {
printf("[WARNING] Remote server advertised data available but no data was able to be read!\n\r");
}
} }
if (m_servClientSocket->canReadData()) { if (m_servClientSocket->canReadData()) {
reclen = m_servClientSocket->readBlock(m_loopBuffer.data(), m_loopBuffer.size()); reclen = m_servClientSocket->readBlock(m_loopBuffer.data(), m_loopBuffer.size());
writeBlock(m_loopBuffer.data(), reclen); if (reclen > 0) {
flush(); writeBlock(m_loopBuffer.data(), reclen);
transferred_data = true; flush();
transferred_data = true;
}
else {
printf("[WARNING] Remote client advertised data available but no data was able to be read!\n\r");
}
} }
} }
else { else {

@ -55,13 +55,22 @@ struct exit_exception {
exit_exception(int c):c(c) { } exit_exception(int c):c(c) { }
}; };
enum connectionStates {
StateIdle = 0,
StateGetFileSize = 1,
StateGetFileContents = 2,
StateStartProgramming = 3,
StateCheckProgrammingStatus = 4,
StateProgammingFinished = 5
};
/* /*
The FPGASocket class provides a socket that is connected with a client. The FPGASocket class provides a socket that is connected with a client.
For every client that connects to the server, the server creates a new For every client that connects to the server, the server creates a new
instance of this class. instance of this class.
*/ */
FPGASocket::FPGASocket(int sock, TQObject *parent, const char *name) : FPGASocket::FPGASocket(int sock, TQObject *parent, const char *name) :
TDEKerberosServerSocket(parent, name), m_criticalSection(0), m_loopTimer(NULL), m_config(static_cast<FPGAServer*>(parent)->m_config), m_commandLoopState(0), TDEKerberosServerSocket(parent, name), m_criticalSection(0), m_loopTimer(NULL), m_config(static_cast<FPGAServer*>(parent)->m_config), m_commandLoopState(StateIdle),
m_progpipe(NULL), m_progpipefd(-1), m_progErrorFlag(false), m_progDoneFlag(false) m_progpipe(NULL), m_progpipefd(-1), m_progErrorFlag(false), m_progDoneFlag(false)
{ {
@ -159,7 +168,7 @@ void FPGASocket::commandLoop() {
try { try {
transferred_data = false; transferred_data = false;
if (state() == TQSocket::Connected) { if (state() == TQSocket::Connected) {
if ((m_commandLoopState == 0) || (m_commandLoopState == 3) || (m_commandLoopState == 4) || (m_commandLoopState == 5)) { if ((m_commandLoopState == StateIdle) || (m_commandLoopState == StateStartProgramming) || (m_commandLoopState == StateCheckProgrammingStatus) || (m_commandLoopState == StateProgammingFinished)) {
// Certain commands can come in at any time during some operations // Certain commands can come in at any time during some operations
if (canReadLine()) { if (canReadLine()) {
processPendingData(); processPendingData();
@ -185,16 +194,15 @@ void FPGASocket::commandLoop() {
} }
else if (m_progDoneFlag) { else if (m_progDoneFlag) {
ds << TQString("DONE"); ds << TQString("DONE");
m_progDoneFlag = false;
writeEndOfFrame();
ds << m_progRetCode; ds << m_progRetCode;
m_progDoneFlag = false;
writeEndOfFrame(); writeEndOfFrame();
} }
else if (m_commandLoopState == 0) { else if (m_commandLoopState == StateIdle) {
ds << TQString("IDLE"); ds << TQString("IDLE");
writeEndOfFrame(); writeEndOfFrame();
} }
else if ((m_commandLoopState == 3) || (m_commandLoopState == 4) || (m_commandLoopState == 5)) { else if ((m_commandLoopState == StateStartProgramming) || (m_commandLoopState == StateCheckProgrammingStatus) || (m_commandLoopState == StateProgammingFinished)) {
ds << TQString("PROGRAMMING"); ds << TQString("PROGRAMMING");
writeEndOfFrame(); writeEndOfFrame();
} }
@ -203,12 +211,12 @@ void FPGASocket::commandLoop() {
writeEndOfFrame(); writeEndOfFrame();
} }
} }
else if (m_commandLoopState == 0) { else if (m_commandLoopState == StateIdle) {
if (command == "FILE") { if (command == "FILE") {
m_commandLoopState = 1; m_commandLoopState = StateGetFileSize;
} }
else if (command == "PROGRAM") { else if (command == "PROGRAM") {
m_commandLoopState = 3; m_commandLoopState = StateStartProgramming;
} }
else { else {
printf("[WARNING] Received unknown command '%s'\n\r", command.ascii()); printf("[WARNING] Received unknown command '%s'\n\r", command.ascii());
@ -217,7 +225,7 @@ void FPGASocket::commandLoop() {
transferred_data = true; transferred_data = true;
} }
} }
if (m_commandLoopState == 1) { if (m_commandLoopState == StateGetFileSize) {
if (canReadLine()) { if (canReadLine()) {
processPendingData(); processPendingData();
} }
@ -227,10 +235,10 @@ void FPGASocket::commandLoop() {
ds >> m_programmingFileSize; ds >> m_programmingFileSize;
clearFrameTail(); clearFrameTail();
m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE); m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
m_commandLoopState = 2; m_commandLoopState = StateGetFileContents;
} }
} }
else if (m_commandLoopState == 2) { else if (m_commandLoopState == StateGetFileContents) {
if (canReadLine()) { if (canReadLine()) {
m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE); m_servClientTimeout->start(NETWORK_COMM_TIMEOUT_MS, TRUE);
processPendingData(); processPendingData();
@ -246,17 +254,17 @@ void FPGASocket::commandLoop() {
outputFile.close(); outputFile.close();
} }
transferred_data = true; transferred_data = true;
m_commandLoopState = 0; m_commandLoopState = StateIdle;
} }
else { else {
if (!m_servClientTimeout->isActive()) { if (!m_servClientTimeout->isActive()) {
m_progErrorFlag = true; m_progErrorFlag = true;
transferred_data = true; transferred_data = true;
m_commandLoopState = 0; m_commandLoopState = StateIdle;
} }
} }
} }
else if (m_commandLoopState == 3) { else if (m_commandLoopState == StateStartProgramming) {
// Start programming! // Start programming!
// Open programming process // Open programming process
@ -270,15 +278,15 @@ void FPGASocket::commandLoop() {
m_logMessages.append(TQString("The system was unable to execute '%1'\nPlease contact your system administrator with this information").arg(programmingScript)); m_logMessages.append(TQString("The system was unable to execute '%1'\nPlease contact your system administrator with this information").arg(programmingScript));
m_progErrorFlag = true; m_progErrorFlag = true;
transferred_data = true; transferred_data = true;
m_commandLoopState = 0; m_commandLoopState = StateIdle;
} }
else { else {
m_progpipefd = fileno(m_progpipe); m_progpipefd = fileno(m_progpipe);
fcntl(m_progpipefd, F_SETFL, O_NONBLOCK); fcntl(m_progpipefd, F_SETFL, O_NONBLOCK);
} }
m_commandLoopState = 4; m_commandLoopState = StateCheckProgrammingStatus;
} }
else if (m_commandLoopState == 4) { else if (m_commandLoopState == StateCheckProgrammingStatus) {
// Check programming status // Check programming status
TQCString buf; TQCString buf;
buf.resize(8192); buf.resize(8192);
@ -293,10 +301,10 @@ void FPGASocket::commandLoop() {
} }
else { else {
// Process terminated // Process terminated
m_commandLoopState = 5; m_commandLoopState = StateProgammingFinished;
} }
} }
else if (m_commandLoopState == 5) { else if (m_commandLoopState == StateProgammingFinished) {
// Programming process terminated; get exit code and clean up // Programming process terminated; get exit code and clean up
if (m_progpipe) { if (m_progpipe) {
m_progRetCode = pclose(m_progpipe); m_progRetCode = pclose(m_progpipe);
@ -308,7 +316,7 @@ void FPGASocket::commandLoop() {
m_progpipefd = -1; m_progpipefd = -1;
m_progDoneFlag = true; m_progDoneFlag = true;
m_commandLoopState = 0; m_commandLoopState = StateIdle;
} }
} }
m_criticalSection--; m_criticalSection--;
@ -327,7 +335,7 @@ void FPGASocket::commandLoop() {
} }
int FPGASocket::enterCommandLoop() { int FPGASocket::enterCommandLoop() {
m_commandLoopState = 0; m_commandLoopState = StateIdle;
if (!m_loopTimer) { if (!m_loopTimer) {
m_loopTimer = new TQTimer(); m_loopTimer = new TQTimer();
connect(m_loopTimer, SIGNAL(timeout()), this, SLOT(commandLoop())); connect(m_loopTimer, SIGNAL(timeout()), this, SLOT(commandLoop()));

Loading…
Cancel
Save