File indexing completed on 2024-05-19 09:39:02
0001 /*************************************************************************** 0002 * Copyright (C) 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 "addac.h" 0012 #include "ecnode.h" 0013 #include "libraryitem.h" 0014 #include "logic.h" 0015 #include "pin.h" 0016 #include "voltagepoint.h" 0017 0018 #include <KLocalizedString> 0019 #include <cmath> 0020 0021 Item *ADC::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0022 { 0023 return new ADC(static_cast<ICNDocument *>(itemDocument), newItem, id); 0024 } 0025 0026 Item *DAC::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0027 { 0028 return new DAC(static_cast<ICNDocument *>(itemDocument), newItem, id); 0029 } 0030 0031 LibraryItem *ADC::libraryItem() 0032 { 0033 return new LibraryItem(QStringList(QString("ec/adc")), i18n("Analog-Digital"), i18n("Integrated Circuits"), "ic1.png", LibraryItem::lit_component, ADC::construct); 0034 } 0035 0036 LibraryItem *DAC::libraryItem() 0037 { 0038 return new LibraryItem(QStringList(QString("ec/dac")), i18n("Digital-Analog"), i18n("Integrated Circuits"), "ic1.png", LibraryItem::lit_component, DAC::construct); 0039 } 0040 0041 // BEGIN class ADDAC 0042 ADDAC::ADDAC(ICNDocument *icnDocument, bool newItem, const char *id) 0043 : Component(icnDocument, newItem, id) 0044 { 0045 m_numBits = 0; 0046 m_range = 0; 0047 0048 createProperty("numBits", Variant::Type::Int); 0049 property("numBits")->setCaption(i18n("Number Bits")); 0050 property("numBits")->setMinValue(2); 0051 property("numBits")->setMaxValue(max_ADDAC_bits); 0052 property("numBits")->setValue(2); 0053 0054 createProperty("range", Variant::Type::Double); 0055 property("range")->setCaption(i18n("Input Range")); 0056 property("range")->setUnit("V"); 0057 property("range")->setMinValue(-1e12); 0058 property("range")->setMaxValue(1e12); 0059 property("range")->setValue(5); 0060 } 0061 0062 ADDAC::~ADDAC() 0063 { 0064 } 0065 0066 void ADDAC::dataChanged() 0067 { 0068 m_range = dataDouble("range"); 0069 initPins(); 0070 } 0071 0072 // END class ADDAC 0073 0074 // BEGIN class ADC 0075 ADC::ADC(ICNDocument *icnDocument, bool newItem, const char *id) 0076 : ADDAC(icnDocument, newItem, id ? id : "adc") 0077 { 0078 m_name = i18n("ADC"); 0079 0080 for (int i = 0; i < max_ADDAC_bits; ++i) 0081 m_logic[i] = nullptr; 0082 0083 m_realNode = nullptr; 0084 } 0085 0086 ADC::~ADC() 0087 { 0088 } 0089 0090 void ADC::stepNonLogic() 0091 { 0092 double floatBitValue = m_realNode->pin()->voltage() * (std::pow(2, double(m_numBits)) - 1.) / m_range; 0093 double roundBitValue = std::floor(floatBitValue + 0.5); 0094 0095 if (roundBitValue < 0) { 0096 for (int i = 0; i < m_numBits; ++i) 0097 m_logic[i]->setHigh(false); 0098 return; 0099 } 0100 0101 uint roundedBitValue = uint(roundBitValue); 0102 for (int i = 0; i < m_numBits; ++i) 0103 m_logic[i]->setHigh(roundedBitValue & (1 << i)); 0104 } 0105 0106 void ADC::initPins() 0107 { 0108 int numBits = dataInt("numBits"); 0109 0110 if (numBits < 2) 0111 numBits = 2; 0112 else if (numBits > max_ADDAC_bits) 0113 numBits = max_ADDAC_bits; 0114 0115 if (numBits == m_numBits) 0116 return; 0117 0118 QStringList pins; 0119 0120 int inPos = (numBits - 1 + (numBits % 2)) / 2; 0121 for (int i = 0; i < inPos; ++i) 0122 pins += ""; 0123 0124 pins += "In"; 0125 0126 for (int i = inPos + 1; i < numBits; ++i) 0127 pins += ""; 0128 0129 for (int i = numBits - 1; i >= 0; --i) 0130 pins += QString::number(i); 0131 0132 initDIPSymbol(pins, 64); 0133 initDIP(pins); 0134 0135 if (!m_realNode) 0136 m_realNode = ecNodeWithID("In"); 0137 0138 if (numBits > m_numBits) { 0139 for (int i = m_numBits; i < numBits; ++i) { 0140 ECNode *node = ecNodeWithID(QString::number(i)); 0141 m_logic[i] = createLogicOut(node, false); 0142 } 0143 } else { 0144 for (int i = numBits; i < m_numBits; ++i) { 0145 QString id = QString::number(i); 0146 removeDisplayText(id); 0147 removeElement(m_logic[i], false); 0148 removeNode(id); 0149 m_logic[i] = nullptr; 0150 } 0151 } 0152 0153 m_numBits = numBits; 0154 } 0155 // END class ADC 0156 0157 // BEGIN class DAC 0158 DAC::DAC(ICNDocument *icnDocument, bool newItem, const char *id) 0159 : ADDAC(icnDocument, newItem, id ? id : "dac") 0160 { 0161 m_name = i18n("DAC"); 0162 0163 for (int i = 0; i < max_ADDAC_bits; ++i) 0164 m_logic[i] = nullptr; 0165 0166 m_voltagePoint = nullptr; 0167 } 0168 0169 DAC::~DAC() 0170 { 0171 } 0172 0173 void DAC::stepNonLogic() 0174 { 0175 uint value = 0; 0176 for (int i = 0; i < m_numBits; ++i) 0177 value |= (m_logic[i]->isHigh() ? 1 : 0) << i; 0178 0179 // double valueAsDouble = double(value); 0180 // double powChange = std::pow( double(m_numBits), 2 )-1.; 0181 // m_voltagePoint->setVoltage( m_range * valueAsDouble / powChange ); 0182 m_voltagePoint->setVoltage(m_range * double(value) / (std::pow(2, double(m_numBits)) - 1.)); 0183 } 0184 0185 void DAC::initPins() 0186 { 0187 int numBits = dataInt("numBits"); 0188 0189 if (numBits < 2) 0190 numBits = 2; 0191 else if (numBits > max_ADDAC_bits) 0192 numBits = max_ADDAC_bits; 0193 0194 if (numBits == m_numBits) 0195 return; 0196 0197 QStringList pins; 0198 0199 for (int i = 0; i < numBits; ++i) 0200 pins += QString::number(i); 0201 0202 int inPos = (numBits + 1 + (numBits % 2)) / 2; 0203 for (int i = numBits - 1; i >= inPos; --i) 0204 pins += ""; 0205 0206 pins += "Out"; 0207 0208 for (int i = inPos - 2; i >= 0; --i) 0209 pins += ""; 0210 0211 initDIPSymbol(pins, 64); 0212 initDIP(pins); 0213 0214 if (!m_voltagePoint) 0215 m_voltagePoint = createVoltagePoint(ecNodeWithID("Out"), 0.); 0216 0217 if (numBits > m_numBits) { 0218 for (int i = m_numBits; i < numBits; ++i) { 0219 ECNode *node = ecNodeWithID(QString::number(i)); 0220 m_logic[i] = createLogicIn(node); 0221 } 0222 } else { 0223 for (int i = numBits; i < m_numBits; ++i) { 0224 QString id = QString::number(i); 0225 removeDisplayText(id); 0226 removeElement(m_logic[i], false); 0227 removeNode(id); 0228 m_logic[i] = nullptr; 0229 } 0230 } 0231 0232 m_numBits = numBits; 0233 } 0234 // END class DAC