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 }