summaryrefslogtreecommitdiffstats
path: root/src/electronics/components/parallelportcomponent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/electronics/components/parallelportcomponent.cpp')
-rw-r--r--src/electronics/components/parallelportcomponent.cpp241
1 files changed, 241 insertions, 0 deletions
diff --git a/src/electronics/components/parallelportcomponent.cpp b/src/electronics/components/parallelportcomponent.cpp
new file mode 100644
index 0000000..9bc17b4
--- /dev/null
+++ b/src/electronics/components/parallelportcomponent.cpp
@@ -0,0 +1,241 @@
+/***************************************************************************
+ * Copyright (C) 2005 by David Saxton *
+ * david@bluehaze.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "port.h"
+#include "parallelportcomponent.h"
+
+#include "ecnode.h"
+#include "itemdocument.h"
+#include "libraryitem.h"
+#include "pin.h"
+#include "resistance.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <qpainter.h>
+
+#include <cmath>
+#include <termios.h>
+
+Item* ParallelPortComponent::construct( ItemDocument *itemDocument, bool newItem, const char *id )
+{
+ return new ParallelPortComponent( (ICNDocument*)itemDocument, newItem, id );
+}
+
+LibraryItem* ParallelPortComponent::libraryItem()
+{
+ return new LibraryItem(
+ "ec/parallel_port",
+ i18n("Parallel Port"),
+ i18n("Connections"),
+ "ic1.png",
+ LibraryItem::lit_component,
+ ParallelPortComponent::construct
+ );
+}
+
+ParallelPortComponent::ParallelPortComponent( ICNDocument *icnDocument, bool newItem, const char *id )
+ : Component( icnDocument, newItem, id ? id : "parallel_port" )
+{
+ m_name = i18n("Parallel Port");
+ m_desc = i18n("The pins are divided into 3 registers.<br><br>"
+ "<b>Data Pins</b><br><br>"
+ "The data pins can be configured as either all input or all output. They are:"
+ "<ul>"
+ "<li><b>D<i>[0..7]</i></b></li>"
+ "</ul><br>"
+ "<b>Status Pins</b><br><br>"
+ "The status pins are read-only. They area:"
+ "<ul>"
+ "<li><b>ERR</b> - Error</li>"
+ "<li><b>ON</b> - Online</li>"
+ "<li><b>PE</b> - Paper End</li>"
+ "<li><b>ACK</b> - Acknowledge</li>"
+ "<li><b>BUSY</b> - Busy</li>"
+ "</ul><br>"
+ "<b>Control Pins</b>"
+ "<ul>"
+ "<li><b>STR</b> - Strobe</li>"
+ "<li><b>AUT</b> - Auto Feed</li>"
+ "<li><b>INIT</b> - Init</li>"
+ "<li><b>SEL</b> - Select</li>"
+ "</ul><br>"
+ "The remaining pins are all ground."
+ );
+
+ QPointArray pa( 4 );
+ pa[0] = QPoint( -32, -112 );
+ pa[1] = QPoint( 32, -104 );
+ pa[2] = QPoint( 32, 104 );
+ pa[3] = QPoint( -32, 112 );
+ setItemPoints( pa );
+
+ m_pParallelPort = new ParallelPort();
+
+ for ( unsigned i = 0; i < 24; ++i )
+ m_pLogic[i] = 0;
+
+ ECNode * pin = 0;
+
+ //BEGIN Data register
+ for ( int i = 0; i < 8; ++i )
+ {
+ QString id = QString("D%1").arg(i);
+ QString name = id;
+
+ pin = createPin( -40, -80 + 16*i, 0, id );
+ addDisplayText( id, QRect( -28, -88 + 16*i, 28, 16 ), name, true, Qt::AlignLeft | Qt::AlignVCenter );
+
+ m_pLogic[i] = createLogicOut( pin, false );
+ m_pLogic[i]->setCallback( this, (CallbackPtr)(&ParallelPortComponent::dataCallback) );
+ }
+ //END Data register
+
+
+ //BEGIN Status register
+ QString statusNames[] = { "ERR", "ON", "PE", "ACK", "BUSY" };
+
+ // The statusIDs are referenced in the save file and must not change
+ QString statusIDs[] = { "ERROR", "ONLINE", "PE", "ACK", "BUSY" };
+
+ // Bits 0...2 in the Status register are not used
+ for ( int i = 3; i < 8; ++i )
+ {
+ QString id = statusIDs[i-3];
+ QString name = statusNames[i-3];
+
+ // Bit 3 (pin 15) doesn't not follow the same positioning pattern as
+ // the other pins in the Status register.
+ if ( i == 3 )
+ {
+ pin = createPin( 40, -72, 180, id );
+ addDisplayText( id, QRect( 0, -80, 28, 16 ), name, true, Qt::AlignRight | Qt::AlignVCenter );
+ }
+ else
+ {
+ pin = createPin( -40, -16 + 16*i, 0, id );
+ addDisplayText( id, QRect( -28, -24 + 16*i, 28, 16 ), name, true, Qt::AlignLeft | Qt::AlignVCenter );
+ }
+
+ m_pLogic[i+8] = createLogicOut( pin, false );
+ }
+ //END Status register
+
+
+ //BEGIN Control register
+ QString controlNames[] = { "STR", "AUT", "INIT", "SEL" };
+
+ // The controlIDs are referenced in the save file and must not change
+ QString controlIDs[] = { "STROBE", "AUTO", "INIT", "SELECT" };
+
+ // Bits 4..7 are not used (well; bit 5 is, but not as a pin)
+ for ( int i = 0; i < 4; ++i )
+ {
+ QString id = controlIDs[i];
+ QString name = controlNames[i];
+
+ if ( i == 0 )
+ {
+ pin = createPin( -40, -96, 0, id );
+ addDisplayText( id, QRect( -28, -104, 28, 16 ), name, true, Qt::AlignLeft | Qt::AlignVCenter );
+ }
+ else if ( i == 1 )
+ {
+ pin = createPin( 40, -88, 180, id );
+ addDisplayText( id, QRect( 0, -96, 28, 16 ), name, true, Qt::AlignRight | Qt::AlignVCenter );
+ }
+ else
+ {
+ pin = createPin( 40, -88 + i*16, 180, id );
+ addDisplayText( id, QRect( 0, -96 + i*16, 28, 16 ), name, true, Qt::AlignRight | Qt::AlignVCenter );
+ }
+
+ m_pLogic[i+16] = createLogicOut( pin, false );
+ m_pLogic[i+16]->setCallback( this, (CallbackPtr)(&ParallelPortComponent::controlCallback) );
+ }
+ //END Control register
+
+
+#if 0
+ // And make the rest of the pins ground
+ for ( int i = 0; i < 8; ++i )
+ {
+ pin = createPin( 40, -24 + i*16, 180, QString("GND%1").arg( i ) );
+ pin->pin()->setGroundType( Pin::gt_always );
+ }
+#endif
+
+ Variant * v = createProperty( "port", Variant::Type::Combo );
+ v->setAllowed( ParallelPort::ports( Port::ExistsAndRW ) );
+ v->setCaption( i18n("Port") );
+}
+
+
+ParallelPortComponent::~ParallelPortComponent()
+{
+ delete m_pParallelPort;
+}
+
+
+void ParallelPortComponent::dataChanged()
+{
+ initPort( dataString("port") );
+}
+
+
+void ParallelPortComponent::initPort( const QString & port )
+{
+ if ( port.isEmpty() )
+ {
+ m_pParallelPort->closePort();
+ return;
+ }
+
+ if ( ! m_pParallelPort->openPort( port ) )
+ {
+ p_itemDocument->canvas()->setMessage( i18n("Could not open port %1").arg( port ) );
+ return;
+ }
+}
+
+
+void ParallelPortComponent::dataCallback( bool )
+{
+ uchar value = 0;
+ for ( unsigned i = 0; i < 8; ++ i )
+ value |= m_pLogic[ i + 0 ]->isHigh() ? 0 : (1 << i);
+
+ m_pParallelPort->writeToData( value );
+}
+
+
+void ParallelPortComponent::controlCallback( bool )
+{
+ uchar value = 0;
+ for ( unsigned i = 0; i < 4; ++ i )
+ value |= m_pLogic[ i + 16 ]->isHigh() ? 0 : (1 << i);
+
+ m_pParallelPort->writeToControl( value );
+}
+
+
+void ParallelPortComponent::stepNonLogic()
+{
+ uchar status = m_pParallelPort->readFromRegister( ParallelPort::Status );
+ // Bits 0...2 in the Status register are not used
+ for ( int i = 3; i < 8; ++i )
+ m_pLogic[i + 8]->setHigh( status | (1 << i) );
+}
+
+
+void ParallelPortComponent::drawShape( QPainter & p )
+{
+ drawPortShape( p );
+}