Work around data transfer problems in FTDI serial converters

Fix glitches in FPGA viewer part
master
Timothy Pearson 11 years ago
parent 40c129a8eb
commit fda60e9d28

@ -494,6 +494,7 @@ void RemoteMDI::configKeys() {
void RemoteMDI::setServerHost(TQString server) {
m_serverHost = server;
connectToServer();
}
void RemoteMDI::openNewWindow(KMdiChildView *view) {

@ -55,7 +55,7 @@
#include "floatspinbox.h"
#include "layout.h"
#define NETWORK_COMM_TIMEOUT_MS 2500
#define NETWORK_COMM_TIMEOUT_MS 15000
enum connectionModes {
ModeIdle = 0,
@ -205,6 +205,7 @@ void FPGAProgramPart::connectionStatusChangedCallback() {
void FPGAProgramPart::programRunButtonClicked() {
m_commHandlerState = ModeProgramming_StateReadFile;
m_commHandlerMode = ModeProgramming;
m_forcedUpdateTimer->start(0, TRUE);
processLockouts();
}
@ -496,6 +497,9 @@ void FPGAProgramPart::mainEventLoop() {
m_socket->clearFrameTail();
ds << TQString("STATUS");
m_socket->writeEndOfFrame();
m_base->programmingProgressBar->reset();
KMessageBox::error(0, i18n("<qt>Timeout</qt>"), i18n("Program Failed"));
processLockouts();
}
}
else {

@ -712,7 +712,24 @@
<property name="name">
<cstring>unnamed_grid</cstring>
</property>
<widget class="TQLabel" row="0" column="0">
<spacer row="0" column="0">
<property name="name">
<cstring>unnamed_spacer</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>ImageInputLabel</cstring>
</property>
@ -726,6 +743,23 @@
</size>
</property>
</widget>
<spacer row="0" column="2">
<property name="name">
<cstring>unnamed_spacer</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</grid>
</widget>
<widget class="TQGroupBox" row="2" column="0">
@ -739,7 +773,24 @@
<property name="name">
<cstring>unnamed_grid</cstring>
</property>
<widget class="TQLabel" row="0" column="0">
<spacer row="0" column="0">
<property name="name">
<cstring>unnamed_spacer</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>ImageOutputLabel</cstring>
</property>
@ -753,6 +804,23 @@
</size>
</property>
</widget>
<spacer row="0" column="2">
<property name="name">
<cstring>unnamed_spacer</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</grid>
</widget>
<spacer row="0" column="0">

@ -54,9 +54,9 @@
#include "floatspinbox.h"
#include "layout.h"
#define SERVER_TIMEOUT_MS 10000
#define FPGA_COMM_TIMEOUT_MS 500
#define FPGA_DATA_PROCESSING_TIMEOUT_MS 2500
#define SERVER_TIMEOUT_MS 20000
#define FPGA_COMM_TIMEOUT_MS 2000
#define FPGA_DATA_PROCESSING_TIMEOUT_MS 19000
FPGALed::FPGALed(TQWidget *parent, const char *name)
: KLed(parent, name), m_clickable(true)
@ -556,6 +556,7 @@ ImageViewerWindow::ImageViewerWindow(TQString caption, TQWidget *parent, const c
{
TQGridLayout* layout = new TQGridLayout(this);
m_label = new TQLabel(this);
m_label->setScaledContents(true);
layout->addWidget(m_label, 0, 0);
}
@ -563,6 +564,10 @@ ImageViewerWindow::~ImageViewerWindow() {
//
}
void ImageViewerWindow::resizeEvent(TQResizeEvent *) {
//
}
void ImageViewerWindow::setPixmap(TQPixmap pixmap) {
m_label->setPixmap(pixmap);
}
@ -578,7 +583,7 @@ 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_base(NULL), m_interfaceMode(BasicInterfaceMode),
m_commHandlerState(0), m_commHandlerMode(0), m_connectionActiveAndValid(false), m_tickerState(0), m_remoteInputModeEnabled(false), m_4bitInputValue(0), m_4bitOutputValue(0),
m_commHandlerState(0), m_commHandlerMode(0), m_commHandlerNextState(0), m_commHandlerNextMode(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_batchOutputFile(NULL), m_dataOutputFile(NULL),
@ -717,6 +722,10 @@ FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObj
m_base->frameLCDDisplay->setBackgroundColor(TQColor(192, 192, 192));
m_base->LCDOutputLabel->setBackgroundColor(TQColor(192, 192, 192));
m_base->LCDOutputLabel->setPaletteForegroundColor(TQColor(0, 0, 0));
TQFontMetrics lcdmetrics(m_base->LCDOutputLabel->font());
int lcdwidth = lcdmetrics.width("0000000000000000");
int lcdheight = lcdmetrics.height()*2;
m_base->LCDOutputLabel->setFixedSize(lcdwidth, lcdheight);
m_base->frameLCDDisplay->setFrameStyle(TQFrame::Box | TQFrame::Raised);
connect(m_base->batchTestRunButton, SIGNAL(clicked()), this, SLOT(batchTestRunButtonClicked()));
@ -782,7 +791,7 @@ void FPGAViewPart::process4BitInputChanges() {
void FPGAViewPart::process4BitOutputChanges() {
// Write m_4bitOutputValue to label
m_base->group4BitOutputValueText->setText(TQString("0x%1").arg(m_16bitOutputValue, 0, 16));
m_base->group4BitOutputValueText->setText(TQString("0x%1").arg(m_4bitOutputValue, 0, 16));
}
void FPGAViewPart::process8BitInputChanges() {
@ -810,13 +819,13 @@ void FPGAViewPart::process8BitInputChanges() {
else {
// Write m_8bitInputValue to LEDs
m_base->group8BitInputLED7->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitInputLED6->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitInputLED5->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitInputLED4->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitInputLED3->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitInputLED2->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitInputLED1->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitInputLED0->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitInputLED6->setState((m_8bitInputValue & 0x40)?KLed::On:KLed::Off);
m_base->group8BitInputLED5->setState((m_8bitInputValue & 0x20)?KLed::On:KLed::Off);
m_base->group8BitInputLED4->setState((m_8bitInputValue & 0x10)?KLed::On:KLed::Off);
m_base->group8BitInputLED3->setState((m_8bitInputValue & 0x08)?KLed::On:KLed::Off);
m_base->group8BitInputLED2->setState((m_8bitInputValue & 0x04)?KLed::On:KLed::Off);
m_base->group8BitInputLED1->setState((m_8bitInputValue & 0x02)?KLed::On:KLed::Off);
m_base->group8BitInputLED0->setState((m_8bitInputValue & 0x01)?KLed::On:KLed::Off);
m_base->group8BitInputLED7->setClickable(false);
m_base->group8BitInputLED6->setClickable(false);
@ -838,16 +847,28 @@ void FPGAViewPart::process8BitInputChanges() {
}
}
void FPGAViewPart::update8BitInputLEDs() {
// Write m_8bitInputValue to LEDs
m_base->group8BitInputLED7->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitInputLED6->setState((m_8bitInputValue & 0x40)?KLed::On:KLed::Off);
m_base->group8BitInputLED5->setState((m_8bitInputValue & 0x20)?KLed::On:KLed::Off);
m_base->group8BitInputLED4->setState((m_8bitInputValue & 0x10)?KLed::On:KLed::Off);
m_base->group8BitInputLED3->setState((m_8bitInputValue & 0x08)?KLed::On:KLed::Off);
m_base->group8BitInputLED2->setState((m_8bitInputValue & 0x04)?KLed::On:KLed::Off);
m_base->group8BitInputLED1->setState((m_8bitInputValue & 0x02)?KLed::On:KLed::Off);
m_base->group8BitInputLED0->setState((m_8bitInputValue & 0x01)?KLed::On:KLed::Off);
}
void FPGAViewPart::process8BitOutputChanges() {
// Write m_8bitOutputValue to LEDs
m_base->group8BitOutputLED7->setState((m_8bitOutputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitOutputLED6->setState((m_8bitOutputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitOutputLED5->setState((m_8bitOutputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitOutputLED4->setState((m_8bitOutputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitOutputLED3->setState((m_8bitOutputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitOutputLED2->setState((m_8bitOutputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitOutputLED1->setState((m_8bitOutputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitOutputLED0->setState((m_8bitOutputValue & 0x80)?KLed::On:KLed::Off);
m_base->group8BitOutputLED6->setState((m_8bitOutputValue & 0x40)?KLed::On:KLed::Off);
m_base->group8BitOutputLED5->setState((m_8bitOutputValue & 0x20)?KLed::On:KLed::Off);
m_base->group8BitOutputLED4->setState((m_8bitOutputValue & 0x10)?KLed::On:KLed::Off);
m_base->group8BitOutputLED3->setState((m_8bitOutputValue & 0x08)?KLed::On:KLed::Off);
m_base->group8BitOutputLED2->setState((m_8bitOutputValue & 0x04)?KLed::On:KLed::Off);
m_base->group8BitOutputLED1->setState((m_8bitOutputValue & 0x02)?KLed::On:KLed::Off);
m_base->group8BitOutputLED0->setState((m_8bitOutputValue & 0x01)?KLed::On:KLed::Off);
m_base->group8BitOutputValueText->setText(TQString("0x%1").arg(m_8bitOutputValue, 0, 16));
}
@ -864,11 +885,7 @@ void FPGAViewPart::process16BitOutputChanges() {
void FPGAViewPart::processLCDOutputChanges() {
// Write m_LCDOutputValue to label
TQString topLine = m_LCDOutputValue;
TQString bottomLine = m_LCDOutputValue;
topLine.truncate(16);
bottomLine.remove(0,8);
m_base->LCDOutputLabel->setText(topLine + "\n" + bottomLine);
m_base->LCDOutputLabel->setText(m_LCDOutputValue);
}
void FPGAViewPart::process7SegmentLEDOutputChanges() {
@ -969,6 +986,7 @@ void FPGAViewPart::processLockouts() {
m_base->batchTestInputFile->setEnabled(false);
m_base->batchTestOutputFile->setEnabled(false);
m_base->batchTest16BitCheckBox->setEnabled(false);
m_base->batchTestRunButton->setEnabled(false);
}
else {
m_base->batchTestInputFile->setEnabled(true);
@ -991,6 +1009,7 @@ void FPGAViewPart::processLockouts() {
m_base->dataProcessingInputFile->setEnabled(false);
m_base->dataProcessingOutputFile->setEnabled(false);
m_base->dataProcessingGenerateValidationString->setEnabled(false);
m_base->dataProcessingRunButton->setEnabled(false);
}
else {
m_base->dataProcessingInputFile->setEnabled(true);
@ -1061,7 +1080,9 @@ void FPGAViewPart::connectionFinishedCallback() {
m_tickerState = 0;
m_commHandlerState = 0;
m_commHandlerMode = 0;
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE);
m_commHandlerNextState = 0;
m_commHandlerNextMode = 0;
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, TRUE);
processLockouts();
updateDisplay();
return;
@ -1076,15 +1097,15 @@ TQPtrList<TDEAction> FPGAViewPart::menuActionList() {
}
void FPGAViewPart::batchTestRunButtonClicked() {
m_commHandlerState = 0;
m_commHandlerMode = 1;
m_commHandlerNextState = 0;
m_commHandlerNextMode = 1;
m_batchUsing16Bit = m_base->batchTest16BitCheckBox->isChecked();
processLockouts();
}
void FPGAViewPart::dataProcessingRunButtonClicked() {
m_commHandlerState = 0;
m_commHandlerMode = 2;
m_commHandlerNextState = 0;
m_commHandlerNextMode = 2;
m_dataGenerateValidationString = m_base->dataProcessingGenerateValidationString->isChecked();
processLockouts();
}
@ -1111,9 +1132,11 @@ void FPGAViewPart::sendInputStatesToRemoteFPGA() {
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);
data[11] = '\r';
data[12] = m_16bitInputValue&0xff;
data[13] = '\r';
m_socket->writeBlock(data, 14);
m_socket->writeBufferedData();
}
}
@ -1128,7 +1151,7 @@ void FPGAViewPart::receiveInputStatesFromRemoteFPGA() {
line[16] = '\n';
memcpy(line+17, data+16, 16);
line[33] = 0;
m_base->LCDOutputLabel->setText(line);
m_LCDOutputValue = line;
// Remote/Local input mode
m_socket->readBlock(data, 1);
@ -1174,16 +1197,18 @@ void FPGAViewPart::receiveInputStatesFromRemoteFPGA() {
m_tickerState = 0; \
m_commHandlerState = 0; \
m_commHandlerMode = 0; \
m_commHandlerNextState = 0; \
m_commHandlerNextMode = 0; \
while (m_socket->bytesAvailable() > 0) { \
m_socket->readBlock(data, 64); \
} \
setStatusMessage(i18n("Debug interface timeout, still waiting for data. Please verify that the FPGA is properly configured.")); \
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE); \
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, TRUE); \
return;
void FPGAViewPart::updateDisplay() {
m_updateTimer->stop();
#define POLL_FOR_DATA_IMMEDIATE TQTimer::singleShot(50, this, TQT_SLOT(updateDisplay()));
void FPGAViewPart::updateDisplay() {
if (m_socket) {
char data[64];
@ -1194,56 +1219,77 @@ void FPGAViewPart::updateDisplay() {
// Send current input states to remote system
sendInputStatesToRemoteFPGA();
// Clear input buffer to ensure proper sync
m_socket->clearIncomingData();
// Send request for all output states
m_socket->writeLine("L\r");
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE);
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, TRUE);
m_commHandlerState = 1;
POLL_FOR_DATA_IMMEDIATE
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;
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, TRUE);
m_commHandlerState = m_commHandlerNextState;
m_commHandlerMode = m_commHandlerNextMode;
m_commHandlerNextState = 0;
m_commHandlerNextMode = 0;
POLL_FOR_DATA_IMMEDIATE
}
setStatusMessage(i18n("Running") + TQString("... %1").arg(tickerChar));
m_tickerState++;
if (m_tickerState > 3) {
m_tickerState = 0;
else {
// Invalid data packet
// State likely lost in remote debug module (e.g. FPGA reprogrammed)
// Clear input buffers and allow timeout to occur in order to force resync
m_socket->clearIncomingData();
}
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE);
m_commHandlerState = 0;
}
else {
if (!m_updateTimer->isActive()) {
UPDATEDISPLAY_TIMEOUT
}
else {
POLL_FOR_DATA_IMMEDIATE
}
}
break;
}
processLockouts();
}
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) {
processLockouts();
m_base->batchTestStatusLabel->setText(i18n("Reading input data") + "...");
m_batchInputValueList.clear();
TQFile file(m_base->batchTestInputFile->url());
@ -1259,9 +1305,10 @@ void FPGAViewPart::updateDisplay() {
m_base->batchTestProgressBar->setTotalSteps(m_batchInputValueList.count());
m_batchOutputFile = new TQFile(m_base->batchTestOutputFile->url());
if (m_batchOutputFile->open(IO_ReadWrite)) {
if (m_batchOutputFile->open(IO_ReadWrite | IO_Truncate)) {
m_batchCurrentValueIndex = 0;
m_commHandlerState = 1;
POLL_FOR_DATA_IMMEDIATE
}
else {
delete m_batchOutputFile;
@ -1300,39 +1347,53 @@ void FPGAViewPart::updateDisplay() {
}
else {
m_8bitInputValue = m_batchInputValueList[m_batchCurrentValueIndex];
update8BitInputLEDs();
}
sendInputStatesToRemoteFPGA();
// Clear input buffer to ensure proper sync
m_socket->clearIncomingData();
// Send request for all output states
m_socket->writeLine("L\r");
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE);
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, TRUE);
m_commHandlerState = 2;
POLL_FOR_DATA_IMMEDIATE
}
}
else if (m_commHandlerState == 2) {
// Get all data
if (m_socket->bytesAvailable() >= 41) {
TQString line;
// Process the received data packet
receiveInputStatesFromRemoteFPGA();
// Write received data to batch output file
if (m_batchUsing16Bit) {
line = TQString("%1\n").arg(m_16bitOutputValue);
if (m_socket->bytesAvailable() == 41) {
TQString line;
// Process the received data packet
receiveInputStatesFromRemoteFPGA();
// Write received data to batch output file
if (m_batchUsing16Bit) {
line = TQString("%1\n").arg(m_16bitOutputValue);
}
else {
line = TQString("%1\n").arg(m_8bitOutputValue);
}
m_batchOutputFile->writeBlock(line.ascii(), line.length());
m_base->batchTestProgressBar->setProgress(m_batchCurrentValueIndex);
m_batchCurrentValueIndex++;
m_connectionActiveAndValid = true;
setStatusMessage(i18n("Running batch test") + "...");
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, TRUE);
m_commHandlerState = 1;
POLL_FOR_DATA_IMMEDIATE
}
else {
line = TQString("%1\n").arg(m_8bitOutputValue);
// Invalid data packet
// State likely lost in remote debug module (e.g. FPGA reprogrammed)
// Clear input buffers and allow timeout to occur in order to force resync
m_socket->clearIncomingData();
}
m_batchOutputFile->writeBlock(line.ascii(), line.length());
m_base->batchTestProgressBar->setProgress(m_batchCurrentValueIndex);
m_batchCurrentValueIndex++;
m_connectionActiveAndValid = true;
setStatusMessage(i18n("Running batch test") + "...");
m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE);
m_commHandlerState = 1;
}
else {
if (!m_updateTimer->isActive()) {
@ -1355,18 +1416,20 @@ void FPGAViewPart::updateDisplay() {
int i;
if (m_commHandlerState == 0) {
m_base->batchTestStatusLabel->setText(i18n("Reading input data") + "...");
m_updateTimer->stop();
processLockouts();
m_base->dataProcessingStatusLabel->setText(i18n("Reading input data") + "...");
m_batchInputValueList.clear();
TQFile file(m_base->batchTestInputFile->url());
TQFile file(m_base->dataProcessingInputFile->url());
if (file.open(IO_ReadOnly)) {
// Is it an image?
m_dataIsImage = m_dataInputImage.load(m_base->batchTestInputFile->url());
m_dataIsImage = m_dataInputImage.load(m_base->dataProcessingInputFile->url());
if ((file.size() <= 16384) || ((m_dataIsImage) && ((m_dataInputImage.height()*m_dataInputImage.width()) <= 16384))) {
m_base->dataProcessingProgressBar->setTotalSteps(0);
m_base->dataProcessingProgressBar->setProgress(0);
m_dataOutputFile = new TQFile(m_base->batchTestOutputFile->url());
m_dataOutputFile = new TQFile(m_base->dataProcessingOutputFile->url());
if (m_dataOutputFile->open(IO_ReadWrite)) {
if (!m_dataIsImage) {
m_dataByteArray = file.readAll();
@ -1391,24 +1454,32 @@ void FPGAViewPart::updateDisplay() {
m_base->dataProcessingStatusLabel->setText(i18n("Transmitting data to FPGA") + "...");
// Transmit m_dataByteArray to FPGA
m_socket->writeLine("M\r");
m_socket->writeBlock("M\r", 2);
m_socket->writeBufferedData();
int len = m_dataByteArray.size();
if (len >= 16384) {
len = 16384;
}
TQByteArray dataToSend(16384*2);
for (i=0; i<(len*2); i++) {
for (i=0; i<len; i++) {
dataToSend[(i*2)+0] = m_dataByteArray[i];
dataToSend[(i+2)+1] = '\r';
dataToSend[(i*2)+1] = '\r';
}
m_base->dataProcessingProgressBar->setTotalSteps(len*4);
m_base->dataProcessingProgressBar->setProgress(0);
int offset = 0;
while (offset < (len*2)) {
m_socket->writeBlock(dataToSend.data()+offset, 1024);
m_socket->writeBufferedData();
offset = offset + 1024;
m_base->dataProcessingProgressBar->setProgress(offset);
}
m_socket->writeBlock(dataToSend, len*2);
m_base->dataProcessingStatusLabel->setText(i18n("Waiting for data from FPGA") + "...");
m_updateTimer->start(FPGA_DATA_PROCESSING_TIMEOUT_MS, FALSE);
m_updateTimer->start(FPGA_DATA_PROCESSING_TIMEOUT_MS, TRUE);
m_batchCurrentValueIndex = 0;
m_commHandlerState = 1;
POLL_FOR_DATA_IMMEDIATE
}
else {
KMessageBox::error(0, i18n("<qt>Unable to open selected data output file</qt>"), i18n("Data Processing Failed"));
@ -1435,9 +1506,41 @@ void FPGAViewPart::updateDisplay() {
}
}
else if (m_commHandlerState == 1) {
if (m_socket->bytesAvailable() >= 1) {
TQByteArray recData(1);
m_socket->readBlock(recData.data(), 1);
m_base->dataProcessingStatusLabel->setText(i18n("Waiting for data from FPGA") + "...");
m_updateTimer->start(FPGA_DATA_PROCESSING_TIMEOUT_MS, TRUE);
m_commHandlerState = 2;
POLL_FOR_DATA_IMMEDIATE
}
else {
if (!m_updateTimer->isActive()) {
m_dataOutputFile->flush();
m_dataOutputFile->close();
delete m_dataOutputFile;
m_dataOutputFile = NULL;
m_base->dataProcessingProgressBar->reset();
m_commHandlerMode = 0;
m_commHandlerState = 0;
KMessageBox::error(0, i18n("<qt>Timeout occurred while attempting to transmit data to FPGA</qt>"), i18n("Data Processing Failed"));
processLockouts();
UPDATEDISPLAY_TIMEOUT
}
}
}
else if (m_commHandlerState == 2) {
if (m_socket->bytesAvailable() >= 16384) {
TQByteArray recData(16384);
m_socket->readBlock(recData.data(), recData.size());
int offset = 0;
while (offset < 16384) {
m_socket->readBlock(recData.data()+offset, 1024);
offset = offset + 1024;
m_base->dataProcessingProgressBar->setProgress((16384*2) + offset);
}
m_base->dataProcessingStatusLabel->setText(i18n("Writing data to file") + "...");
if (!m_dataIsImage) {
@ -1451,11 +1554,13 @@ void FPGAViewPart::updateDisplay() {
TQImage outputImage(m_dataInputImage.width(), m_dataInputImage.height(), m_dataInputImage.depth());
int x;
int y;
unsigned char grey;
int imageWidth = outputImage.width();
m_dataByteArray.resize(outputImage.height()*imageWidth);
for (y=0; y<outputImage.height(); y++) {
for (x=0; x<outputImage.width(); x++) {
outputImage.setPixel(x, y, recData[(y*imageWidth)+x]);
grey = recData[(y*imageWidth)+x];
outputImage.setPixel(x, y, tqRgb(grey, grey, grey));
}
}
TQPixmap outputImagePixmap(outputImage);
@ -1471,12 +1576,12 @@ void FPGAViewPart::updateDisplay() {
TQByteArray writtenFile = m_dataOutputFile->readAll();
KMD5 writtenMD5(writtenFile);
TQFile verificationFile(m_base->batchTestOutputFile->url() + ".vrf");
TQFile verificationFile(m_base->dataProcessingOutputFile->url() + ".vrf");
if (verificationFile.open(IO_ReadWrite)) {
TQCString datastring = writtenMD5.hexDigest();
datastring.prepend("md5=");
verificationFile.writeBlock(datastring);
datastring = (TQString("datetime=").arg(TQDateTime::currentDateTime().toString())).ascii();
datastring = (TQString("datetime=%1").arg(TQDateTime::currentDateTime().toString())).ascii();
verificationFile.writeBlock(datastring);
}
@ -1487,6 +1592,7 @@ void FPGAViewPart::updateDisplay() {
m_commHandlerMode = 0;
m_commHandlerState = 0;
processLockouts();
POLL_FOR_DATA_IMMEDIATE
}
else {
if (!m_updateTimer->isActive()) {
@ -1497,6 +1603,7 @@ void FPGAViewPart::updateDisplay() {
m_base->dataProcessingProgressBar->reset();
m_commHandlerMode = 0;
m_commHandlerState = 0;
KMessageBox::error(0, i18n("<qt>Timeout occurred while attempting to receive data from FPGA</qt>"), i18n("Data Processing Failed"));
processLockouts();
UPDATEDISPLAY_TIMEOUT
}

@ -138,6 +138,9 @@ class ImageViewerWindow : public KMdiChildView
public:
void setPixmap(TQPixmap);
protected:
void resizeEvent(TQResizeEvent *);
private:
TQLabel* m_label;
};
@ -182,6 +185,7 @@ namespace RemoteLab
void switchToIntermediateMode();
void switchToAdvancedMode();
void processAllGraphicsUpdates();
void update8BitInputLEDs();
void process4BitInputChanges();
void process4BitOutputChanges();
@ -214,6 +218,8 @@ namespace RemoteLab
int m_commHandlerState;
int m_commHandlerMode;
int m_commHandlerNextState;
int m_commHandlerNextMode;
bool m_connectionActiveAndValid;
unsigned char m_tickerState;
bool m_remoteInputModeEnabled;

@ -29,10 +29,12 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <tqtimer.h>
@ -40,6 +42,10 @@
#include "fpga_conn.h"
#define FLUSH_IN 0
#define FLUSH_OUT 1
#define FLUSH_BOTH 2
#define ABORT_SOCKET(s) s->close(); \
s->disconnect(); \
delete s; \
@ -195,14 +201,15 @@ int FPGASocket::setupSerial() {
void FPGASocket::commandLoop() {
int cc;
char buffer[10000];
int ret;
char buffer[1024];
bool transferred_data;
m_criticalSection++;
try {
transferred_data = false;
if (state() == TQSocket::Connected) {
cc = read(m_fd_tty, buffer, 10000);
cc = read(m_fd_tty, buffer, 1024);
if (cc > 0) {
writeBlock(buffer, cc);
flush();
@ -210,11 +217,26 @@ void FPGASocket::commandLoop() {
printf("[DEBUG] Got %d bytes from the serial port\n\r", cc); fflush(stdout);
}
if (canReadData()) {
cc = readBlock(buffer, 10000);
cc = readBlock(buffer, 1024);
if (cc > 0) {
if (write(m_fd_tty, buffer, cc) < 0) {
ret = write(m_fd_tty, buffer, cc);
// HACK
// This works around a buffer overflow on FTDI serial devices
// It may not be sufficient for baudrates less than 115200!
if (cc > 128) {
usleep(100000);
}
while ((ret < 0) && (errno == EAGAIN)) {
usleep(1000);
ret = write(m_fd_tty, buffer, cc);
}
if (ret < 0) {
// ERROR
printf("[ERROR] Failed to transmit data to serial port (%s, code %d)! Continuing, but data was likely lost\n\r", strerror(errno), errno); fflush(stdout);
}
ioctl(m_fd_tty, TCFLSH, FLUSH_OUT);
transferred_data = true;
printf("[DEBUG] Got %d bytes from the network interface\n\r", cc); fflush(stdout);
}
@ -280,4 +302,4 @@ void FPGAServer::newConnection(int socket) {
void FPGAServer::remoteConnectionClosed() {
m_numberOfConnections--;
}
}

Loading…
Cancel
Save