/*************************************************************************** * Copyright (C) 2003-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 "binarycounter.h" #include "logic.h" #include "libraryitem.h" #include #include Item* BinaryCounter::construct( ItemDocument *itemDocument, bool newItem, const char *id ) { return new BinaryCounter( (ICNDocument*)itemDocument, newItem, id ); } LibraryItem* BinaryCounter::libraryItem() { QStringList ids; ids << "ec/binary_counter" << "ec/4_bit_binary_counter"; return new LibraryItem( ids, i18n("Binary Counter"), i18n("Integrated Circuits"), "ic1.png", LibraryItem::lit_component, BinaryCounter::construct ); } BinaryCounter::BinaryCounter( ICNDocument *icnDocument, bool newItem, const char *id ) : Component( icnDocument, newItem, id ? id : "binary_counter" ) { m_name = i18n("Binary Counter"); m_desc = i18n("Holds an internal count, which changes when the clock input > pin is pulsed.

" "Normal operation: en (Enable) and u/d (Up/Down) are held high, r (Reset) is low."); enLogic = inLogic = rLogic = udLogic = 0L; b_reset = false; b_triggerHigh = true; b_oldIn = false; m_value = 0; b_en = false; b_ud = false; m_numBits = 0; m_maxValue = false; m_bDoneLogicIn = false; createProperty( "trig", Variant::Type::Select ); property("trig")->setCaption( i18n("Trigger Edge") ); property("trig")->setAllowed( QStringList::split( ',', "Rising,Falling" ) ); property("trig")->setValue("Rising"); createProperty( "bitcount", Variant::Type::Int ); property("bitcount")->setCaption( i18n("Bit Count") ); property("bitcount")->setMinValue(1); property("bitcount")->setMaxValue(26); property("bitcount")->setValue(4); } BinaryCounter::~BinaryCounter() { } void BinaryCounter::dataChanged() { initPins( dataInt("bitcount") ); b_triggerHigh = dataString("trig") == "Rising"; setDisplayText( ">", b_triggerHigh ? "^>" : "_>" ); } void BinaryCounter::initPins( unsigned numBits ) { if ( m_numBits == numBits ) return; QStringList pins; pins << "en" << ">" << "u/d" << "r"; for ( int i = 0; i < QABS(4-int(numBits)); i++ ) pins << ""; for ( int i = numBits-1; i >= 0; i-- ) pins << QChar('A'+i); initDIPSymbol( pins, 64 ); initDIP(pins); if ( m_numBits < numBits ) { for ( unsigned i = m_numBits; i < numBits; i++ ) m_pLogicOut[i] = createLogicOut( ecNodeWithID( QChar('A'+i) ), false ); } else { for ( unsigned i = numBits; i < m_numBits; i++ ) { QString id = QChar('A'+i); removeElement( m_pLogicOut[i], false ); removeDisplayText(id); removeNode(id); } } m_numBits = numBits; m_maxValue = (1<") ); rLogic = createLogicIn( ecNodeWithID("r") ); udLogic = createLogicIn( ecNodeWithID("u/d") ); enLogic->setCallback( this, (CallbackPtr)(&BinaryCounter::enStateChanged) ); inLogic->setCallback( this, (CallbackPtr)(&BinaryCounter::inStateChanged) ); rLogic->setCallback( this, (CallbackPtr)(&BinaryCounter::rStateChanged) ); udLogic->setCallback( this, (CallbackPtr)(&BinaryCounter::udStateChanged) ); m_bDoneLogicIn = true; } outputValue(); } void BinaryCounter::inStateChanged( bool state ) { if ( (state != b_oldIn) && b_en && !b_reset && state == b_triggerHigh ) { m_value += (b_ud) ? 1 : -1; if ( m_value < 0 ) m_value = m_maxValue; else if ( m_value > m_maxValue ) m_value = 0; outputValue(); } b_oldIn = state; } void BinaryCounter::rStateChanged( bool state ) { b_reset = state; if (b_reset) { m_value = 0; outputValue(); } } void BinaryCounter::enStateChanged( bool state ) { b_en = state; } void BinaryCounter::udStateChanged( bool state ) { b_ud = state; } void BinaryCounter::outputValue() { for ( unsigned i = 0; i < m_numBits; i++ ) m_pLogicOut[i]->setHigh( m_value & (1 << i) ); }