diff options
Diffstat (limited to 'clients/tde')
-rw-r--r-- | clients/tde/src/part/fpgaview/layout.ui | 210 | ||||
-rw-r--r-- | clients/tde/src/part/fpgaview/part.cpp | 679 | ||||
-rw-r--r-- | clients/tde/src/part/fpgaview/part.h | 51 |
3 files changed, 898 insertions, 42 deletions
diff --git a/clients/tde/src/part/fpgaview/layout.ui b/clients/tde/src/part/fpgaview/layout.ui index a2619eb..966e640 100644 --- a/clients/tde/src/part/fpgaview/layout.ui +++ b/clients/tde/src/part/fpgaview/layout.ui @@ -14,7 +14,7 @@ </property> <grid> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_grid</cstring> </property> <widget class="TQTabWidget" row="0" column="0"> <property name="name"> @@ -32,7 +32,7 @@ </attribute> <grid> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_grid</cstring> </property> <widget class="TQGroupBox" row="0" column="0"> <property name="name"> @@ -43,7 +43,7 @@ </property> <grid> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_grid</cstring> </property> <widget class="TQGroupBox" row="0" column="0"> <property name="name"> @@ -54,7 +54,7 @@ </property> <grid> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_grid</cstring> </property> <widget class="FPGALed" row="0" column="0"> <property name="name"> @@ -112,7 +112,7 @@ </property> <grid> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_grid</cstring> </property> <widget class="FPGALed" row="0" column="0"> <property name="name"> @@ -170,11 +170,11 @@ </property> <grid> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_grid</cstring> </property> <widget class="TQLabel" row="0" column="0"> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_label</cstring> </property> <property name="text"> <cstring>Input:</cstring> @@ -202,7 +202,7 @@ </widget> <widget class="TQLabel" row="0" column="2"> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_label</cstring> </property> <property name="text"> <cstring>Output:</cstring> @@ -227,15 +227,15 @@ </property> <grid> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_grid</cstring> </property> <widget class="TQLayoutWidget" row="0" column="1" colspan="2"> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_layout</cstring> </property> <grid> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_grid</cstring> </property> <spacer row="0" column="0"> <property name="name"> @@ -290,11 +290,11 @@ </widget> <widget class="TQLayoutWidget" row="3" column="1" colspan="2"> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_layout</cstring> </property> <grid> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_grid</cstring> </property> <spacer row="0" column="0"> <property name="name"> @@ -379,7 +379,7 @@ </widget> <widget class="TQLayoutWidget" row="0" column="2" rowspan="3"> <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_layout</cstring> </property> <grid> <widget class="TQGroupBox" row="0" column="0"> @@ -391,10 +391,7 @@ </property> <grid> <property name="name"> - <cstring>unnamed</cstring> - </property> - <property name="name"> - <cstring>unnamed</cstring> + <cstring>unnamed_grid</cstring> </property> <widget class="TQLabel" row="0" column="0"> <property name="name"> @@ -434,6 +431,183 @@ </spacer> </grid> </widget> + <widget class="TQLayoutWidget" row="0" column="3" rowspan="3"> + <property name="name"> + <cstring>unnamed_layout</cstring> + </property> + <grid> + <widget class="TQGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupLEDDisplay</cstring> + </property> + <property name="title"> + <string>LED Display:</string> + </property> + <property name="margin"> + <number>0</number> + </property> + <grid> + <widget class="TQFrame" row="0" column="0"> + <property name="name"> + <cstring>frameLEDDisplay</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <grid> + <property name="name"> + <cstring>unnamed_grid</cstring> + </property> + <property name="margin"> + <number>2</number> + </property> + <widget class="FPGA7Segment" row="0" column="0"> + <property name="name"> + <cstring>LEDOutputDisplayDigit0</cstring> + </property> + <property name="minimumSize"> + <size> + <width>30</width> + <height>40</height> + </size> + </property> + </widget> + <widget class="FPGA7Segment" row="0" column="1"> + <property name="name"> + <cstring>LEDOutputDisplayDigit1</cstring> + </property> + <property name="minimumSize"> + <size> + <width>30</width> + <height>40</height> + </size> + </property> + </widget> + <widget class="FPGA7Segment" row="0" column="2"> + <property name="name"> + <cstring>LEDOutputDisplayDigit2</cstring> + </property> + <property name="minimumSize"> + <size> + <width>30</width> + <height>40</height> + </size> + </property> + </widget> + <widget class="FPGA7Segment" row="0" column="3"> + <property name="name"> + <cstring>LEDOutputDisplayDigit3</cstring> + </property> + <property name="minimumSize"> + <size> + <width>30</width> + <height>40</height> + </size> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>unnamed_spacer</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="TQGroupBox" row="4" column="0" colspan="4"> + <property name="name"> + <cstring>groupBatchTest</cstring> + </property> + <property name="title"> + <string>Batch Test:</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed_grid</cstring> + </property> + <widget class="TQLabel" row="0" column="0"> + <property name="name"> + <cstring>unnamed_label</cstring> + </property> + <property name="text"> + <cstring>Input File Name:</cstring> + </property> + </widget> + <widget class="KURLRequester" row="1" column="0"> + <property name="name"> + <cstring>batchTestInputFile</cstring> + </property> + <property name="mode"> + <number>25</number> + </property> + <property name="filter"> + <cstring>*.txt|Text Files (*.txt)</cstring> + </property> + </widget> + <widget class="TQLabel" row="0" column="1"> + <property name="name"> + <cstring>unnamed_label</cstring> + </property> + <property name="text"> + <cstring>Output File Name:</cstring> + </property> + </widget> + <widget class="KURLRequester" row="1" column="1"> + <property name="name"> + <cstring>batchTestOutputFile</cstring> + </property> + <property name="mode"> + <number>25</number> + </property> + <property name="filter"> + <cstring>*.txt|Text Files (*.txt)</cstring> + </property> + </widget> + <widget class="TQPushButton" row="1" column="2"> + <property name="name"> + <cstring>batchTestRunButton</cstring> + </property> + <property name="text"> + <cstring>Run Batch Test</cstring> + </property> + </widget> + <widget class="TQProgressBar" row="2" column="0" colspan="3"> + <property name="name"> + <cstring>batchTestProgressBar</cstring> + </property> + </widget> + <widget class="TQCheckBox" row="3" column="0"> + <property name="name"> + <cstring>batchTest16BitCheckBox</cstring> + </property> + <property name="text"> + <cstring>Test using 16 bit interface</cstring> + </property> + </widget> + <widget class="TQLabel" row="3" column="1" colspan="2"> + <property name="name"> + <cstring>batchTestStatusLabel</cstring> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </grid> + </widget> </grid> </widget> </grid> diff --git a/clients/tde/src/part/fpgaview/part.cpp b/clients/tde/src/part/fpgaview/part.cpp index 8876e44..e97272f 100644 --- a/clients/tde/src/part/fpgaview/part.cpp +++ b/clients/tde/src/part/fpgaview/part.cpp @@ -42,11 +42,17 @@ #include <unistd.h> //access() #include <stdint.h> +#include <tqpainter.h> + #include "tracewidget.h" #include "floatspinbox.h" #include "layout.h" -#define SERVER_TIMEOUT_MS 10000 +// RAJA UNCOMMENT ME +//#define SERVER_TIMEOUT_MS 10000 +// RAJA DEBUG ONLY +#define SERVER_TIMEOUT_MS 100000 +#define FPGA_COMM_TIMEOUT_MS 500 FPGALed::FPGALed(TQWidget *parent, const char *name) : KLed(parent, name), m_clickable(true) @@ -117,6 +123,430 @@ void FPGAPushButton::leaveEvent(TQEvent *e) { } } +FPGA7Segment::FPGA7Segment( TQWidget *parent, const char *name ) + : TQFrame( parent, name ) +{ + init(); +} + +FPGA7Segment::~FPGA7Segment() { + free(m_prevSegments); + free(m_currentSegments); +} + +void FPGA7Segment::init() { + setFrameStyle(TQFrame::Box | TQFrame::Raised); + val = 0; + smallPoint = TRUE; + setSegmentStyle(Flat); + m_prevSegments = (char*)malloc(sizeof(char)*9); + m_currentSegments = (char*)malloc(sizeof(char)*9); + m_prevSegments[0] = 99; + m_currentSegments[0] = 99; + d = 0; + setSizePolicy(TQSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum)); +} + +void FPGA7Segment::setLitSegments(unsigned int segs) { + // This produces an array of up to 10 chars, with each char being the number of a lit segment, and the list being terminated with the number 99 + // The bit input in segs is active high + // The bit sequence, MSB to LSB, is dp a b c d e f g + // Segment letters are taken from ug130.pdf + // 0: a + // 1: f + // 2: d + // 3: g + // 4: e + // 5: c + // 6: b + // 7: dp + + int i = 0; + if (segs & 0x80) { m_currentSegments[i] = 7; i++; } + if (segs & 0x40) { m_currentSegments[i] = 0; i++; } + if (segs & 0x20) { m_currentSegments[i] = 6; i++; } + if (segs & 0x10) { m_currentSegments[i] = 5; i++; } + if (segs & 0x08) { m_currentSegments[i] = 2; i++; } + if (segs & 0x04) { m_currentSegments[i] = 4; i++; } + if (segs & 0x02) { m_currentSegments[i] = 1; i++; } + if (segs & 0x01) { m_currentSegments[i] = 3; i++; } + m_currentSegments[i] = 99; +} + +void FPGA7Segment::drawContents( TQPainter *p ) +{ + // Draw all segments + TQPoint pos; + int digitSpace = smallPoint ? 2 : 1; + int xSegLen = width()*5/(1*(5 + digitSpace) + digitSpace); + int ySegLen = height()*5/12; + int segLen = ySegLen > xSegLen ? xSegLen : ySegLen; + int xAdvance = segLen*( 5 + 1 )/5; + int xOffset = ( width() - xAdvance + segLen/5 )/2; + int yOffset = ( height() - segLen*2 )/2; + + pos = TQPoint(xOffset, yOffset); + drawDigit(pos, *p, segLen, m_currentSegments); +} + +TQSize FPGA7Segment::sizeHint() const { + return TQSize(10 + 9 * (1 + (smallPoint ? 0 : 1)), 23); +} + +void FPGA7Segment::setSegmentStyle( SegmentStyle s ) { + fill = (s == Flat || s == Filled); + shadow = (s == Outline || s == Filled); + update(); +} + +FPGA7Segment::SegmentStyle FPGA7Segment::segmentStyle() const { + Q_ASSERT(fill || shadow); + if (!fill && shadow) { + return Outline; + } + if (fill && shadow) { + return Filled; + } + return Flat; +} + +static void addPoint( TQPointArray &a, const TQPoint &p ) { + uint n = a.size(); + a.resize(n + 1); + a.setPoint(n, p); +} + +void FPGA7Segment::drawDigit(const TQPoint &pos, TQPainter &p, int segLen, const char *newSegs) { + char updates[20][2]; // Can hold 2 times number of segments, only + // first 10 used if segment table is correct + int nErases; + int nUpdates; + const char *segs; + int i,j; + + const char erase = 0; + const char draw = 1; + const char leaveAlone = 2; + + segs = m_prevSegments; + for ( nErases=0; segs[nErases] != 99; nErases++ ) { + updates[nErases][0] = erase; // Get segments to erase to + updates[nErases][1] = segs[nErases]; // remove old char + } + nUpdates = nErases; + segs = newSegs; + for(i = 0 ; segs[i] != 99 ; i++) { + for ( j=0; j<nErases; j++ ) { + if ( segs[i] == updates[j][1] ) { // Same segment ? + updates[j][0] = leaveAlone; // yes, already on screen + break; + } + } + if ( j == nErases ) { // If not already on screen + updates[nUpdates][0] = draw; + updates[nUpdates][1] = segs[i]; + nUpdates++; + } + } + for ( i=0; i<nUpdates; i++ ) { + if ( updates[i][0] == draw ) { + drawSegment( pos, updates[i][1], p, segLen ); + } + if (updates[i][0] == erase) { + drawSegment( pos, updates[i][1], p, segLen, TRUE ); + } + } + + memcpy(m_prevSegments, newSegs, sizeof(char)*9); +} + +void FPGA7Segment::drawSegment(const TQPoint &pos, char segmentNo, TQPainter &p, int segLen, bool erase) { + TQPoint pt = pos; + int width = segLen/5; + + const TQColorGroup & g = colorGroup(); + TQColor lightColor,darkColor,fgColor; + if (erase) { + lightColor = backgroundColor(); + darkColor = lightColor; + fgColor = lightColor; + } + else { + lightColor = g.light(); + darkColor = g.dark(); + fgColor = g.foreground(); + } + +#define LINETO(X,Y) addPoint( a, TQPoint(pt.x() + (X),pt.y() + (Y))) +#define LIGHT +#define DARK + + if ( fill ) { + TQPointArray a(0); + + //The following is an exact copy of the switch below. + //don't make any changes here + switch ( segmentNo ) { + case 0 : + p.moveTo(pt); + LIGHT; + LINETO(segLen - 1,0); + DARK; + LINETO(segLen - width - 1,width); + LINETO(width,width); + LINETO(0,0); + break; + case 1 : + pt += TQPoint(0 , 1); + p.moveTo(pt); + LIGHT; + LINETO(width,width); + DARK; + LINETO(width,segLen - width/2 - 2); + LINETO(0,segLen - 2); + LIGHT; + LINETO(0,0); + break; + case 2 : + pt += TQPoint(segLen - 1 , 1); + p.moveTo(pt); + DARK; + LINETO(0,segLen - 2); + LINETO(-width,segLen - width/2 - 2); + LIGHT; + LINETO(-width,width); + LINETO(0,0); + break; + case 3 : + pt += TQPoint(0 , segLen); + p.moveTo(pt); + LIGHT; + LINETO(width,-width/2); + LINETO(segLen - width - 1,-width/2); + LINETO(segLen - 1,0); + DARK; + if (width & 1) { // adjust for integer division error + LINETO(segLen - width - 3,width/2 + 1); + LINETO(width + 2,width/2 + 1); + } else { + LINETO(segLen - width - 1,width/2); + LINETO(width,width/2); + } + LINETO(0,0); + break; + case 4 : + pt += TQPoint(0 , segLen + 1); + p.moveTo(pt); + LIGHT; + LINETO(width,width/2); + DARK; + LINETO(width,segLen - width - 2); + LINETO(0,segLen - 2); + LIGHT; + LINETO(0,0); + break; + case 5 : + pt += TQPoint(segLen - 1 , segLen + 1); + p.moveTo(pt); + DARK; + LINETO(0,segLen - 2); + LINETO(-width,segLen - width - 2); + LIGHT; + LINETO(-width,width/2); + LINETO(0,0); + break; + case 6 : + pt += TQPoint(0 , segLen*2); + p.moveTo(pt); + LIGHT; + LINETO(width,-width); + LINETO(segLen - width - 1,-width); + LINETO(segLen - 1,0); + DARK; + LINETO(0,0); + break; + case 7 : + if ( smallPoint ) // if smallpoint place'.' between other digits + pt += TQPoint(segLen + width/2 , segLen*2); + else + pt += TQPoint(segLen/2 , segLen*2); + p.moveTo(pt); + DARK; + LINETO(width,0); + LINETO(width,-width); + LIGHT; + LINETO(0,-width); + LINETO(0,0); + break; + case 8 : + pt += TQPoint(segLen/2 - width/2 + 1 , segLen/2 + width); + p.moveTo(pt); + DARK; + LINETO(width,0); + LINETO(width,-width); + LIGHT; + LINETO(0,-width); + LINETO(0,0); + break; + case 9 : + pt += TQPoint(segLen/2 - width/2 + 1 , 3*segLen/2 + width); + p.moveTo(pt); + DARK; + LINETO(width,0); + LINETO(width,-width); + LIGHT; + LINETO(0,-width); + LINETO(0,0); + break; +#if defined(QT_CHECK_RANGE) + default : + tqWarning( "FPGA7Segment::drawSegment: (%s) Internal error." + " Illegal segment id: %d\n", + name( "unnamed" ), segmentNo ); +#endif + } + // End exact copy + p.setPen( fgColor ); + p.setBrush( fgColor ); + p.drawPolygon( a ); + p.setBrush( NoBrush ); + + pt = pos; + } +#undef LINETO +#undef LIGHT +#undef DARK + +#define LINETO(X,Y) p.lineTo(TQPoint(pt.x() + (X),pt.y() + (Y))) +#define LIGHT p.setPen(lightColor) +#define DARK p.setPen(darkColor) + if ( shadow ) { + switch ( segmentNo ) { + case 0 : + p.moveTo(pt); + LIGHT; + LINETO(segLen - 1,0); + DARK; + LINETO(segLen - width - 1,width); + LINETO(width,width); + LINETO(0,0); + break; + case 1 : + pt += TQPoint(0,1); + p.moveTo(pt); + LIGHT; + LINETO(width,width); + DARK; + LINETO(width,segLen - width/2 - 2); + LINETO(0,segLen - 2); + LIGHT; + LINETO(0,0); + break; + case 2 : + pt += TQPoint(segLen - 1 , 1); + p.moveTo(pt); + DARK; + LINETO(0,segLen - 2); + LINETO(-width,segLen - width/2 - 2); + LIGHT; + LINETO(-width,width); + LINETO(0,0); + break; + case 3 : + pt += TQPoint(0 , segLen); + p.moveTo(pt); + LIGHT; + LINETO(width,-width/2); + LINETO(segLen - width - 1,-width/2); + LINETO(segLen - 1,0); + DARK; + if (width & 1) { // adjust for integer division error + LINETO(segLen - width - 3,width/2 + 1); + LINETO(width + 2,width/2 + 1); + } else { + LINETO(segLen - width - 1,width/2); + LINETO(width,width/2); + } + LINETO(0,0); + break; + case 4 : + pt += TQPoint(0 , segLen + 1); + p.moveTo(pt); + LIGHT; + LINETO(width,width/2); + DARK; + LINETO(width,segLen - width - 2); + LINETO(0,segLen - 2); + LIGHT; + LINETO(0,0); + break; + case 5 : + pt += TQPoint(segLen - 1 , segLen + 1); + p.moveTo(pt); + DARK; + LINETO(0,segLen - 2); + LINETO(-width,segLen - width - 2); + LIGHT; + LINETO(-width,width/2); + LINETO(0,0); + break; + case 6 : + pt += TQPoint(0 , segLen*2); + p.moveTo(pt); + LIGHT; + LINETO(width,-width); + LINETO(segLen - width - 1,-width); + LINETO(segLen - 1,0); + DARK; + LINETO(0,0); + break; + case 7 : + if ( smallPoint ) // if smallpoint place'.' between other digits + pt += TQPoint(segLen + width/2 , segLen*2); + else + pt += TQPoint(segLen/2 , segLen*2); + p.moveTo(pt); + DARK; + LINETO(width,0); + LINETO(width,-width); + LIGHT; + LINETO(0,-width); + LINETO(0,0); + break; + case 8 : + pt += TQPoint(segLen/2 - width/2 + 1 , segLen/2 + width); + p.moveTo(pt); + DARK; + LINETO(width,0); + LINETO(width,-width); + LIGHT; + LINETO(0,-width); + LINETO(0,0); + break; + case 9 : + pt += TQPoint(segLen/2 - width/2 + 1 , 3*segLen/2 + width); + p.moveTo(pt); + DARK; + LINETO(width,0); + LINETO(width,-width); + LIGHT; + LINETO(0,-width); + LINETO(0,0); + break; +#if defined(QT_CHECK_RANGE) + default : + tqWarning( "FPGA7Segment::drawSegment: (%s) Internal error." + " Illegal segment id: %d\n", + name( "unnamed" ), segmentNo ); +#endif + } + } + +#undef LINETO +#undef LIGHT +#undef DARK +} + namespace RemoteLab { typedef KParts::GenericFactory<RemoteLab::FPGAViewPart> Factory; @@ -128,7 +558,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), - remoteInputModeEnabled(false), m_4bitInputValue(0), m_4bitOutputValue(0), m_8bitInputValue(0), m_8bitOutputValue(0), m_16bitInputValue(0), m_16bitOutputValue(0) + 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) { // Initialize mutex m_connectionMutex = new TQMutex(false); @@ -229,6 +660,32 @@ FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObj connect(m_base->group16BitInputValue, SIGNAL(valueChanged(int)), this, SLOT(process16BitInputChanges())); + m_base->LEDOutputDisplayDigit0->setBackgroundColor(TQt::black); + m_base->LEDOutputDisplayDigit1->setBackgroundColor(TQt::black); + m_base->LEDOutputDisplayDigit2->setBackgroundColor(TQt::black); + m_base->LEDOutputDisplayDigit3->setBackgroundColor(TQt::black); + m_base->LEDOutputDisplayDigit0->setPaletteForegroundColor(TQColor(0, 255, 64)); + m_base->LEDOutputDisplayDigit1->setPaletteForegroundColor(TQColor(0, 255, 64)); + m_base->LEDOutputDisplayDigit2->setPaletteForegroundColor(TQColor(0, 255, 64)); + m_base->LEDOutputDisplayDigit3->setPaletteForegroundColor(TQColor(0, 255, 64)); + // The LED display can work one of two ways +#if 0 + // Separated segments + m_base->LEDOutputDisplayDigit0->setFrameStyle(TQFrame::Box | TQFrame::Raised); + m_base->LEDOutputDisplayDigit1->setFrameStyle(TQFrame::Box | TQFrame::Raised); + m_base->LEDOutputDisplayDigit2->setFrameStyle(TQFrame::Box | TQFrame::Raised); + m_base->LEDOutputDisplayDigit3->setFrameStyle(TQFrame::Box | TQFrame::Raised); + m_base->frameLEDDisplay->setFrameStyle(TQFrame::NoFrame); +#else + // Combined segments + m_base->frameLEDDisplay->setBackgroundColor(TQt::black); + m_base->LEDOutputDisplayDigit0->setFrameStyle(TQFrame::NoFrame); + m_base->LEDOutputDisplayDigit1->setFrameStyle(TQFrame::NoFrame); + m_base->LEDOutputDisplayDigit2->setFrameStyle(TQFrame::NoFrame); + m_base->LEDOutputDisplayDigit3->setFrameStyle(TQFrame::NoFrame); + m_base->frameLEDDisplay->setFrameStyle(TQFrame::Box | TQFrame::Raised); +#endif + processAllGraphicsUpdates(); TQTimer::singleShot(0, this, TQT_SLOT(postInit())); @@ -255,6 +712,7 @@ void FPGAViewPart::processAllGraphicsUpdates() { process16BitOutputChanges(); processLCDOutputChanges(); + process7SegmentLEDOutputChanges(); processLockouts(); } @@ -276,20 +734,51 @@ void FPGAViewPart::process4BitOutputChanges() { } void FPGAViewPart::process8BitInputChanges() { - // Read LED status into m_8bitInputValue - m_8bitInputValue = 0; - if (m_base->group8BitInputLED7->state() == KLed::On) m_8bitInputValue |= 0x80; - if (m_base->group8BitInputLED6->state() == KLed::On) m_8bitInputValue |= 0x40; - if (m_base->group8BitInputLED5->state() == KLed::On) m_8bitInputValue |= 0x20; - if (m_base->group8BitInputLED4->state() == KLed::On) m_8bitInputValue |= 0x10; - if (m_base->group8BitInputLED3->state() == KLed::On) m_8bitInputValue |= 0x08; - if (m_base->group8BitInputLED2->state() == KLed::On) m_8bitInputValue |= 0x04; - if (m_base->group8BitInputLED1->state() == KLed::On) m_8bitInputValue |= 0x02; - if (m_base->group8BitInputLED0->state() == KLed::On) m_8bitInputValue |= 0x01; + if (m_remoteInputModeEnabled) { + // Read LED status into m_8bitInputValue + m_8bitInputValue = 0; + if (m_base->group8BitInputLED7->state() == KLed::On) m_8bitInputValue |= 0x80; + if (m_base->group8BitInputLED6->state() == KLed::On) m_8bitInputValue |= 0x40; + if (m_base->group8BitInputLED5->state() == KLed::On) m_8bitInputValue |= 0x20; + if (m_base->group8BitInputLED4->state() == KLed::On) m_8bitInputValue |= 0x10; + if (m_base->group8BitInputLED3->state() == KLed::On) m_8bitInputValue |= 0x08; + if (m_base->group8BitInputLED2->state() == KLed::On) m_8bitInputValue |= 0x04; + if (m_base->group8BitInputLED1->state() == KLed::On) m_8bitInputValue |= 0x02; + if (m_base->group8BitInputLED0->state() == KLed::On) m_8bitInputValue |= 0x01; + + m_base->group8BitInputLED7->setClickable(true); + m_base->group8BitInputLED6->setClickable(true); + m_base->group8BitInputLED5->setClickable(true); + m_base->group8BitInputLED4->setClickable(true); + m_base->group8BitInputLED3->setClickable(true); + m_base->group8BitInputLED2->setClickable(true); + m_base->group8BitInputLED1->setClickable(true); + m_base->group8BitInputLED0->setClickable(true); + } + 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->group8BitInputLED7->setClickable(false); + m_base->group8BitInputLED6->setClickable(false); + m_base->group8BitInputLED5->setClickable(false); + m_base->group8BitInputLED4->setClickable(false); + m_base->group8BitInputLED3->setClickable(false); + m_base->group8BitInputLED2->setClickable(false); + m_base->group8BitInputLED1->setClickable(false); + m_base->group8BitInputLED0->setClickable(false); + } m_base->group8BitInputValueText->setText(TQString("0x%1").arg(m_8bitInputValue, 0, 16)); - if (remoteInputModeEnabled) { + if (m_remoteInputModeEnabled) { m_base->group8BitInput->setTitle(i18n("8-Bit Input Values") + " [" + i18n("Remote Input Mode") + "]"); } else { @@ -299,14 +788,14 @@ void FPGAViewPart::process8BitInputChanges() { void FPGAViewPart::process8BitOutputChanges() { // Write m_8bitOutputValue to LEDs - m_base->group8BitOutputLED7->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off); - m_base->group8BitOutputLED6->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off); - m_base->group8BitOutputLED5->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off); - m_base->group8BitOutputLED4->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off); - m_base->group8BitOutputLED3->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off); - m_base->group8BitOutputLED2->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off); - m_base->group8BitOutputLED1->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off); - m_base->group8BitOutputLED0->setState((m_8bitInputValue & 0x80)?KLed::On:KLed::Off); + 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->group8BitOutputValueText->setText(TQString("0x%1").arg(m_8bitOutputValue, 0, 16)); } @@ -330,6 +819,15 @@ void FPGAViewPart::processLCDOutputChanges() { m_base->LCDOutputLabel->setText(topLine + "\n" + bottomLine); } +void FPGAViewPart::process7SegmentLEDOutputChanges() { + // Write LED digits to 7 segment displays + // Note that the information stored in the data structures is bitwise inverted + m_base->LEDOutputDisplayDigit0->setLitSegments(~m_7segDigit0OutputValue); + m_base->LEDOutputDisplayDigit1->setLitSegments(~m_7segDigit1OutputValue); + m_base->LEDOutputDisplayDigit2->setLitSegments(~m_7segDigit2OutputValue); + m_base->LEDOutputDisplayDigit3->setLitSegments(~m_7segDigit3OutputValue); +} + void FPGAViewPart::processLockouts() { TQWidget* mainWidget = widget(); if (mainWidget) { @@ -477,6 +975,9 @@ printf("[RAJA DEBUG 400.0] Got '%s' from the server\n\r", response.ascii()); ffl if (response == "OK") { connToServerState = 3; connToServerConnecting = false; + connect(m_socket, SIGNAL(readyRead()), m_socket, SLOT(processPendingData())); + connect(m_socket, SIGNAL(newDataReceived()), this, SLOT(updateDisplay())); + m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE); processLockouts(); return; } @@ -543,9 +1044,141 @@ TQPtrList<KAction> FPGAViewPart::menuActionList() { return m_menuActionList; } +#define UPDATEDISPLAY_TIMEOUT m_connectionActiveAndValid = false; \ + m_tickerState = 0; \ + m_commHandlerState = 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); \ + return; + void FPGAViewPart::updateDisplay() { - // RAJA FIXME - // setStatusMessage(i18n("Debug interface timeout, still waiting for data. Please verify that the FPGA is properly configured.")); // or setStatusMessage(i18n("Running")+"... \|/-" + m_updateTimer->stop(); + + 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: + // Get all data + if (m_socket->bytesAvailable() >= 41) { + // 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; + } + 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(); + + 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 { + m_commHandlerState = 0; + } } KAboutData* FPGAViewPart::createAboutData() { diff --git a/clients/tde/src/part/fpgaview/part.h b/clients/tde/src/part/fpgaview/part.h index c46ad6b..4b9c071 100644 --- a/clients/tde/src/part/fpgaview/part.h +++ b/clients/tde/src/part/fpgaview/part.h @@ -26,6 +26,7 @@ #include <tdekrbclientsocket.h> #include <tqcstring.h> +#include <tqframe.h> #include <kparts/browserextension.h> #include <kparts/statusbarextension.h> @@ -83,6 +84,46 @@ class FPGAPushButton : public KLed bool mouseDown; }; +class FPGA7SegmentPrivate; + +class Q_EXPORT FPGA7Segment : public TQFrame +{ + Q_OBJECT + Q_ENUMS(SegmentStyle) + Q_PROPERTY(bool smallDecimalPoint READ smallDecimalPoint WRITE setSmallDecimalPoint) + Q_PROPERTY(SegmentStyle segmentStyle READ segmentStyle WRITE setSegmentStyle) + + public: + FPGA7Segment(TQWidget* parent=0, const char* name=0); + ~FPGA7Segment(); + + enum SegmentStyle { Outline, Filled, Flat }; + + SegmentStyle segmentStyle() const; + virtual void setSegmentStyle(SegmentStyle); + + void setLitSegments(unsigned int); + + TQSize sizeHint() const; + + protected: + void drawContents(TQPainter *); + + private: + void init(); + void drawSegment(const TQPoint &, char, TQPainter &, int, bool = FALSE); + void drawDigit(const TQPoint &, TQPainter &, int, const char *); + + char* m_prevSegments; + char* m_currentSegments; + + double val; + uint smallPoint : 1; + uint fill : 1; + uint shadow : 1; + FPGA7SegmentPrivate *d; +}; + namespace RemoteLab { class FPGAViewPart : public KParts::RemoteInstrumentPart @@ -128,6 +169,7 @@ namespace RemoteLab void process16BitInputChanges(); void process16BitOutputChanges(); void processLCDOutputChanges(); + void process7SegmentLEDOutputChanges(); private: TDEKerberosClientSocket* m_socket; @@ -147,7 +189,10 @@ namespace RemoteLab InterfaceMode m_interfaceMode; - bool remoteInputModeEnabled; + int m_commHandlerState; + bool m_connectionActiveAndValid; + unsigned char m_tickerState; + bool m_remoteInputModeEnabled; unsigned char m_4bitInputValue; unsigned char m_4bitOutputValue; unsigned char m_8bitInputValue; @@ -155,6 +200,10 @@ namespace RemoteLab unsigned int m_16bitInputValue; unsigned int m_16bitOutputValue; TQCString m_LCDOutputValue; + unsigned int m_7segDigit3OutputValue; + unsigned int m_7segDigit2OutputValue; + unsigned int m_7segDigit1OutputValue; + unsigned int m_7segDigit0OutputValue; }; } |