File indexing completed on 2024-05-05 05:46:03

0001 /***************************************************************************
0002  *   Copyright (C) 2003-2005 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "binarycounter.h"
0012 
0013 #include <KLocalizedString>
0014 #include <cstdlib>
0015 
0016 #include "libraryitem.h"
0017 #include "logic.h"
0018 
0019 Item *BinaryCounter::construct(ItemDocument *itemDocument, bool newItem, const char *id)
0020 {
0021     return new BinaryCounter(static_cast<ICNDocument *>(itemDocument), newItem, id);
0022 }
0023 
0024 LibraryItem *BinaryCounter::libraryItem()
0025 {
0026     QStringList ids;
0027     ids << "ec/binary_counter"
0028         << "ec/4_bit_binary_counter";
0029     return new LibraryItem(ids, i18n("Binary Counter"), i18n("Integrated Circuits"), "ic1.png", LibraryItem::lit_component, BinaryCounter::construct);
0030 }
0031 
0032 void BinaryCounter_inStateChanged(void *objV, bool state) { // Input
0033     BinaryCounter *objT = static_cast<BinaryCounter*>(objV);
0034     objT->inStateChanged(state);
0035 }
0036 void BinaryCounter_rStateChanged(void *objV, bool state) {  // Reset
0037     BinaryCounter *objT = static_cast<BinaryCounter*>(objV);
0038     objT->rStateChanged(state);
0039 }
0040 void BinaryCounter_enStateChanged(void *objV, bool state) { // Enable
0041     BinaryCounter *objT = static_cast<BinaryCounter*>(objV);
0042     objT->enStateChanged(state);
0043 }
0044 void BinaryCounter_udStateChanged(void *objV, bool state) { // Up/Down
0045     BinaryCounter *objT = static_cast<BinaryCounter*>(objV);
0046     objT->udStateChanged(state);
0047 }
0048 
0049 BinaryCounter::BinaryCounter(ICNDocument *icnDocument, bool newItem, const char *id)
0050     : Component(icnDocument, newItem, id ? id : "binary_counter")
0051 {
0052     m_name = i18n("Binary Counter");
0053 
0054     enLogic = inLogic = rLogic = udLogic = nullptr;
0055 
0056     b_reset = false;
0057     b_triggerHigh = true;
0058     b_oldIn = false;
0059     m_value = 0;
0060     b_en = false;
0061     b_ud = false;
0062     m_numBits = 0;
0063     m_maxValue = false;
0064     m_bDoneLogicIn = false;
0065 
0066     createProperty("trig", Variant::Type::Select);
0067     property("trig")->setCaption(i18n("Trigger Edge"));
0068     QStringMap allowed;
0069     allowed["Rising"] = i18n("Rising");
0070     allowed["Falling"] = i18n("Falling");
0071     property("trig")->setAllowed(allowed);
0072     property("trig")->setValue("Falling");
0073 
0074     createProperty("bitcount", Variant::Type::Int);
0075     property("bitcount")->setCaption(i18n("Bit Count"));
0076     property("bitcount")->setMinValue(1);
0077     property("bitcount")->setMaxValue(26);
0078     property("bitcount")->setValue(4);
0079 }
0080 
0081 BinaryCounter::~BinaryCounter()
0082 {
0083 }
0084 
0085 void BinaryCounter::dataChanged()
0086 {
0087     initPins(dataInt("bitcount"));
0088 
0089     b_triggerHigh = dataString("trig") == "Rising";
0090     setDisplayText(">", b_triggerHigh ? "^>" : "_>");
0091 }
0092 
0093 void BinaryCounter::initPins(unsigned numBits)
0094 {
0095     if (m_numBits == numBits)
0096         return;
0097 
0098     QStringList pins;
0099     pins << "en"
0100          << ">"
0101          << "u/d"
0102          << "r";
0103 
0104     {
0105         int np = abs(4 - int(numBits));
0106         for (int i = 0; i < np; i++)
0107             pins << " ";
0108     }
0109 
0110     for (int i = numBits - 1; i >= 0; i--)
0111         pins << QChar('A' + i);
0112 
0113     initDIPSymbol(pins, 64);
0114     initDIP(pins);
0115 
0116     if (m_numBits < numBits) {
0117         for (unsigned i = m_numBits; i < numBits; i++)
0118             m_pLogicOut[i] = createLogicOut(ecNodeWithID(QChar('A' + i)), false);
0119     } else {
0120         for (unsigned i = numBits; i < m_numBits; i++) {
0121             QString id = QChar('A' + i);
0122             removeElement(m_pLogicOut[i], false);
0123             removeDisplayText(id);
0124             removeNode(id);
0125         }
0126     }
0127 
0128     m_numBits = numBits;
0129     m_maxValue = (1 << m_numBits) - 1;
0130 
0131     if (!m_bDoneLogicIn) {
0132         enLogic = createLogicIn(ecNodeWithID("en"));
0133         inLogic = createLogicIn(ecNodeWithID(">"));
0134         rLogic = createLogicIn(ecNodeWithID("r"));
0135         udLogic = createLogicIn(ecNodeWithID("u/d"));
0136 
0137         //enLogic->setCallback(this, (CallbackPtr)(&BinaryCounter::enStateChanged));
0138         enLogic->setCallback2(BinaryCounter_enStateChanged,this);
0139         //inLogic->setCallback(this, (CallbackPtr)(&BinaryCounter::inStateChanged));
0140         inLogic->setCallback2(BinaryCounter_inStateChanged, this);
0141         //rLogic->setCallback(this, (CallbackPtr)(&BinaryCounter::rStateChanged));
0142         rLogic->setCallback2(BinaryCounter_rStateChanged, this);
0143         //udLogic->setCallback(this, (CallbackPtr)(&BinaryCounter::udStateChanged));
0144         udLogic->setCallback2(BinaryCounter_udStateChanged, this);
0145 
0146         m_bDoneLogicIn = true;
0147     }
0148 
0149     outputValue();
0150 }
0151 
0152 void BinaryCounter::inStateChanged(bool state)
0153 {
0154     if ((state != b_oldIn) && b_en && !b_reset && state == b_triggerHigh) {
0155         m_value += (b_ud) ? 1 : -1;
0156 
0157         if (m_value < 0)
0158             m_value = m_maxValue;
0159 
0160         else if (m_value > m_maxValue)
0161             m_value = 0;
0162 
0163         outputValue();
0164     }
0165 
0166     b_oldIn = state;
0167 }
0168 
0169 void BinaryCounter::rStateChanged(bool state)
0170 {
0171     b_reset = state;
0172     if (b_reset) {
0173         m_value = 0;
0174         outputValue();
0175     }
0176 }
0177 
0178 void BinaryCounter::enStateChanged(bool state)
0179 {
0180     b_en = state;
0181 }
0182 
0183 void BinaryCounter::udStateChanged(bool state)
0184 {
0185     b_ud = state;
0186 }
0187 
0188 void BinaryCounter::outputValue()
0189 {
0190     for (unsigned i = 0; i < m_numBits; i++)
0191         m_pLogicOut[i]->setHigh(m_value & (1 << i));
0192 }