parallelportcomponent.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by David Saxton                                    *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #include "port.h"
00012 #include "parallelportcomponent.h"
00013 
00014 #include "ecnode.h"
00015 #include "itemdocument.h"
00016 #include "libraryitem.h"
00017 #include "pin.h"
00018 #include "resistance.h"
00019 
00020 #include <kdebug.h>
00021 #include <klocale.h>
00022 #include <qpainter.h>
00023 
00024 #include <cmath>
00025 #include <termios.h>
00026 
00027 Item* ParallelPortComponent::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00028 {
00029         return new ParallelPortComponent( (ICNDocument*)itemDocument, newItem, id );
00030 }
00031 
00032 LibraryItem* ParallelPortComponent::libraryItem()
00033 {
00034         return new LibraryItem(
00035                         "ec/parallel_port",
00036         i18n("Parallel Port"),
00037         i18n("Connections"),
00038         "ic1.png",
00039         LibraryItem::lit_component,
00040         ParallelPortComponent::construct
00041                                                   );
00042 }
00043 
00044 ParallelPortComponent::ParallelPortComponent( ICNDocument *icnDocument, bool newItem, const char *id )
00045         : Component( icnDocument, newItem, id ? id : "parallel_port" )
00046 {
00047         m_name = i18n("Parallel Port");
00048         m_desc = i18n("The pins are divided into 3 registers.<br><br>"
00049                         "<b>Data Pins</b><br><br>"
00050                         "The data pins can be configured as either all input or all output. They are:"
00051                         "<ul>"
00052                         "<li><b>D<i>[0..7]</i></b></li>"
00053                         "</ul><br>"
00054                         "<b>Status Pins</b><br><br>"
00055                         "The status pins are read-only. They area:"
00056                         "<ul>"
00057                         "<li><b>ERR</b> - Error</li>"
00058                         "<li><b>ON</b> - Online</li>"
00059                         "<li><b>PE</b> - Paper End</li>"
00060                         "<li><b>ACK</b> - Acknowledge</li>"
00061                         "<li><b>BUSY</b> - Busy</li>"
00062                         "</ul><br>"
00063                         "<b>Control Pins</b>"
00064                         "<ul>"
00065                         "<li><b>STR</b> - Strobe</li>"
00066                         "<li><b>AUT</b> - Auto Feed</li>"
00067                         "<li><b>INIT</b> - Init</li>"
00068                         "<li><b>SEL</b> - Select</li>"
00069                         "</ul><br>"
00070                         "The remaining pins are all ground."
00071                                  );
00072         
00073         QPointArray pa( 4 );
00074         pa[0] = QPoint( -32, -112 );
00075         pa[1] = QPoint( 32, -104 );
00076         pa[2] = QPoint( 32, 104 );
00077         pa[3] = QPoint( -32, 112 );
00078         setItemPoints( pa );
00079         
00080         m_pParallelPort = new ParallelPort();
00081         
00082         for ( unsigned i = 0; i < 24; ++i )
00083                 m_pLogic[i] = 0;
00084         
00085         ECNode * pin = 0;
00086         
00087         //BEGIN Data register
00088         for ( int i = 0; i < 8; ++i )
00089         {
00090                 QString id = QString("D%1").arg(i);
00091                 QString name = id;
00092                 
00093                 pin = createPin( -40, -80 + 16*i, 0, id );
00094                 addDisplayText( id, QRect( -28, -88 + 16*i, 28, 16 ), name, true, Qt::AlignLeft | Qt::AlignVCenter );
00095                 
00096                 m_pLogic[i] = createLogicOut( pin, false );
00097                 m_pLogic[i]->setCallback( this, (CallbackPtr)(&ParallelPortComponent::dataCallback) );
00098         }
00099         //END Data register
00100         
00101         
00102         //BEGIN Status register
00103         QString statusNames[] = { "ERR", "ON", "PE", "ACK", "BUSY" };
00104         
00105         // The statusIDs are referenced in the save file and must not change
00106         QString statusIDs[] = { "ERROR", "ONLINE", "PE", "ACK", "BUSY" };
00107         
00108         // Bits 0...2 in the Status register are not used
00109         for ( int i = 3; i < 8; ++i )
00110         {
00111                 QString id = statusIDs[i-3];
00112                 QString name = statusNames[i-3];
00113                 
00114                 // Bit 3 (pin 15) doesn't not follow the same positioning pattern as
00115                 // the other pins in the Status register.
00116                 if ( i == 3 )
00117                 {
00118                         pin = createPin( 40, -72, 180, id );
00119                         addDisplayText( id, QRect( 0, -80, 28, 16 ), name, true, Qt::AlignRight | Qt::AlignVCenter );
00120                 }
00121                 else
00122                 {
00123                         pin = createPin( -40, -16 + 16*i, 0, id );
00124                         addDisplayText( id, QRect( -28, -24 + 16*i, 28, 16 ), name, true, Qt::AlignLeft | Qt::AlignVCenter );
00125                 }
00126                 
00127                 m_pLogic[i+8] = createLogicOut( pin, false );
00128         }
00129         //END Status register
00130         
00131         
00132         //BEGIN Control register
00133         QString controlNames[] = { "STR", "AUT", "INIT", "SEL" };
00134         
00135         // The controlIDs are referenced in the save file and must not change
00136         QString controlIDs[] = { "STROBE", "AUTO", "INIT", "SELECT" };
00137         
00138         // Bits 4..7 are not used (well; bit 5 is, but not as a pin)
00139         for ( int i = 0; i < 4; ++i )
00140         {
00141                 QString id = controlIDs[i];
00142                 QString name = controlNames[i];
00143                 
00144                 if ( i == 0 )
00145                 {
00146                         pin = createPin( -40, -96, 0, id );
00147                         addDisplayText( id, QRect( -28, -104, 28, 16 ), name, true, Qt::AlignLeft | Qt::AlignVCenter );
00148                 }
00149                 else if ( i == 1 )
00150                 {
00151                         pin = createPin( 40, -88, 180, id );
00152                         addDisplayText( id, QRect( 0, -96, 28, 16 ), name, true, Qt::AlignRight | Qt::AlignVCenter );
00153                 }
00154                 else
00155                 {
00156                         pin = createPin( 40, -88 + i*16, 180, id );
00157                         addDisplayText( id, QRect( 0, -96 + i*16, 28, 16 ), name, true, Qt::AlignRight | Qt::AlignVCenter );
00158                 }
00159                 
00160                 m_pLogic[i+16] = createLogicOut( pin, false );
00161                 m_pLogic[i+16]->setCallback( this, (CallbackPtr)(&ParallelPortComponent::controlCallback) );
00162         }
00163         //END Control register
00164         
00165         
00166 #if 0
00167         // And make the rest of the pins ground
00168         for ( int i = 0; i < 8; ++i )
00169         {
00170                 pin = createPin( 40, -24 + i*16, 180, QString("GND%1").arg( i ) );
00171                 pin->pin()->setGroundType( Pin::gt_always );
00172         }
00173 #endif
00174         
00175         Variant * v = createProperty( "port", Variant::Type::Combo );
00176         v->setAllowed( ParallelPort::ports( Port::ExistsAndRW ) );
00177         v->setCaption( i18n("Port") );
00178 }
00179 
00180 
00181 ParallelPortComponent::~ParallelPortComponent()
00182 {
00183         delete m_pParallelPort;
00184 }
00185 
00186 
00187 void ParallelPortComponent::dataChanged()
00188 {
00189         initPort( dataString("port") );
00190 }
00191 
00192 
00193 void ParallelPortComponent::initPort( const QString & port )
00194 {
00195         if ( port.isEmpty() )
00196         {
00197                 m_pParallelPort->closePort();
00198                 return;
00199         }
00200         
00201         if ( ! m_pParallelPort->openPort( port ) )
00202         {
00203                 p_itemDocument->canvas()->setMessage( i18n("Could not open port %1").arg( port ) );
00204                 return;
00205         }
00206 }
00207 
00208 
00209 void ParallelPortComponent::dataCallback( bool )
00210 {
00211         uchar value = 0;
00212         for ( unsigned i = 0; i < 8; ++ i )
00213                 value |= m_pLogic[ i + 0 ]->isHigh() ? 0 : (1 << i);
00214         
00215         m_pParallelPort->writeToData( value );
00216 }
00217 
00218 
00219 void ParallelPortComponent::controlCallback( bool )
00220 {
00221         uchar value = 0;
00222         for ( unsigned i = 0; i < 4; ++ i )
00223                 value |= m_pLogic[ i + 16 ]->isHigh() ? 0 : (1 << i);
00224         
00225         m_pParallelPort->writeToControl( value );
00226 }
00227 
00228 
00229 void ParallelPortComponent::stepNonLogic()
00230 {
00231         uchar status = m_pParallelPort->readFromRegister( ParallelPort::Status );
00232         // Bits 0...2 in the Status register are not used
00233         for ( int i = 3; i < 8; ++i )
00234                 m_pLogic[i + 8]->setHigh( status | (1 << i) );
00235 }
00236 
00237 
00238 void ParallelPortComponent::drawShape( QPainter & p )
00239 {
00240         drawPortShape( p );
00241 }

Generated on Tue May 8 17:05:31 2007 for KTechLab by  doxygen 1.5.1