binarycounter.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2003-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 "binarycounter.h"
00012 
00013 #include "logic.h"
00014 #include "libraryitem.h"
00015 
00016 #include <kiconloader.h>
00017 #include <klocale.h>
00018 
00019 Item* BinaryCounter::construct( ItemDocument *itemDocument, bool newItem, const char *id )
00020 {
00021         return new BinaryCounter( (ICNDocument*)itemDocument, newItem, id );
00022 }
00023 
00024 LibraryItem* BinaryCounter::libraryItem()
00025 {
00026         QStringList ids;
00027         ids << "ec/binary_counter" << "ec/4_bit_binary_counter";
00028         return new LibraryItem(
00029                 ids,
00030                 i18n("Binary Counter"),
00031                 i18n("Integrated Circuits"),
00032                 "ic1.png",
00033                 LibraryItem::lit_component,
00034                 BinaryCounter::construct
00035                         );
00036 }
00037 
00038 BinaryCounter::BinaryCounter( ICNDocument *icnDocument, bool newItem, const char *id )
00039         : Component( icnDocument, newItem, id ? id : "binary_counter" )
00040 {
00041         m_name = i18n("Binary Counter");
00042         m_desc = i18n("Holds an internal count, which changes when the clock input <i>&gt;</i> pin is pulsed.<br><br>"
00043                                   "Normal operation: <i>en</i> (Enable) and <i>u/d</i> (Up/Down) are held high, <i>r</i> (Reset) is low.");
00044 
00045         enLogic = inLogic = rLogic = udLogic = 0;
00046         
00047         b_reset = false;
00048         b_triggerHigh = true;
00049         b_oldIn = false;
00050         m_value = 0;
00051         b_en = false;
00052         b_ud = false;
00053         m_numBits = 0;
00054         m_maxValue = false;
00055         m_bDoneLogicIn = false;
00056         
00057         createProperty( "trig", Variant::Type::Select );
00058         property("trig")->setCaption( i18n("Trigger Edge") );
00059         property("trig")->setAllowed( QStringList::split( ',', "Rising,Falling" ) );
00060         property("trig")->setValue("Rising");
00061         
00062         createProperty( "bitcount", Variant::Type::Int );
00063         property("bitcount")->setCaption( i18n("Bit Count") );
00064         property("bitcount")->setMinValue(1);
00065         property("bitcount")->setMaxValue(26);
00066         property("bitcount")->setValue(4);
00067 }
00068 
00069 
00070 BinaryCounter::~BinaryCounter()
00071 {
00072 }
00073 
00074 
00075 void BinaryCounter::dataChanged()
00076 {
00077         initPins( dataInt("bitcount") );
00078         
00079         b_triggerHigh = dataString("trig") == "Rising";
00080         setDisplayText( ">", b_triggerHigh ? "^>" : "_>" );
00081 }
00082 
00083 
00084 void BinaryCounter::initPins( unsigned numBits )
00085 {
00086         if ( m_numBits == numBits )
00087                 return;
00088         
00089         QStringList pins;
00090         pins << "en" << ">" << "u/d" << "r";
00091         
00092         for ( int i = 0; i < QABS(4-int(numBits)); i++ )
00093                 pins << "";
00094         
00095         for ( int i = numBits-1; i >= 0; i-- )
00096                 pins << QChar('A'+i);
00097         
00098         initDIPSymbol( pins, 64 );
00099         initDIP(pins);
00100         
00101         if ( m_numBits < numBits ) {
00102                 for ( unsigned i = m_numBits; i < numBits; i++ )
00103                         m_pLogicOut[i] = createLogicOut( ecNodeWithID( QChar('A'+i) ), false );
00104         } else {
00105                 for ( unsigned i = numBits; i < m_numBits; i++ ) {
00106                         QString id = QChar('A'+i);
00107                         removeElement( m_pLogicOut[i], false );
00108                         removeDisplayText(id);
00109                         removeNode(id);
00110                 }
00111         }
00112 
00113         m_numBits = numBits;
00114         m_maxValue = (1<<m_numBits)-1;
00115 
00116         if (!m_bDoneLogicIn) {
00117                 enLogic = createLogicIn( ecNodeWithID("en") );
00118                 inLogic = createLogicIn( ecNodeWithID(">") );
00119                 rLogic = createLogicIn( ecNodeWithID("r") );
00120                 udLogic = createLogicIn( ecNodeWithID("u/d") );
00121 
00122                 enLogic->setCallback( this, (CallbackPtr)(&BinaryCounter::enStateChanged) );
00123                 inLogic->setCallback( this, (CallbackPtr)(&BinaryCounter::inStateChanged) );
00124                 rLogic->setCallback( this, (CallbackPtr)(&BinaryCounter::rStateChanged) );
00125                 udLogic->setCallback( this, (CallbackPtr)(&BinaryCounter::udStateChanged) );
00126 
00127                 m_bDoneLogicIn = true;
00128         }
00129 
00130         outputValue();
00131 }
00132 
00133 void BinaryCounter::inStateChanged( bool state )
00134 {
00135         if ( (state != b_oldIn) && b_en && !b_reset && state == b_triggerHigh )
00136         {
00137                 m_value += (b_ud) ? 1 : -1;
00138                 
00139                 if ( m_value < 0 ) m_value = m_maxValue;
00140                 else if ( m_value > m_maxValue ) m_value = 0;
00141 
00142                 outputValue();
00143         }
00144         
00145         b_oldIn = state;
00146 }
00147 
00148 void BinaryCounter::rStateChanged( bool state )
00149 {
00150         b_reset = state;
00151         if (b_reset) {
00152                 m_value = 0;
00153                 outputValue();
00154         }
00155 }
00156 
00157 void BinaryCounter::enStateChanged( bool state )
00158 {
00159         b_en = state;
00160 }
00161 
00162 void BinaryCounter::udStateChanged( bool state )
00163 {
00164         b_ud = state;
00165 }
00166 
00167 void BinaryCounter::outputValue()
00168 {
00169         for ( unsigned i = 0; i < m_numBits; i++ )
00170                 m_pLogicOut[i]->setHigh( m_value & (1 << i) );
00171 }
00172 

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