00001
00002
00003
00004
00005
00006
00007
00008
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>></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