00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "addac.h"
00012 #include "ecnode.h"
00013 #include "logic.h"
00014 #include "libraryitem.h"
00015 #include "pin.h"
00016 #include "voltagepoint.h"
00017
00018 #include <cmath>
00019 #include <kiconloader.h>
00020 #include <klocale.h>
00021
00022 Item* ADC::construct(ItemDocument *itemDocument, bool newItem, const char *id)
00023 {
00024 return new ADC((ICNDocument*)itemDocument, newItem, id);
00025 }
00026
00027
00028 Item* DAC::construct(ItemDocument *itemDocument, bool newItem, const char *id)
00029 {
00030 return new DAC((ICNDocument*)itemDocument, newItem, id);
00031 }
00032
00033
00034 LibraryItem* ADC::libraryItem()
00035 {
00036 return new LibraryItem("ec/adc", i18n("Analog-Digital"), i18n("Integrated Circuits"), "ic1.png", LibraryItem::lit_component, ADC::construct
00037 );
00038 }
00039
00040 LibraryItem* DAC::libraryItem()
00041 {
00042 return new LibraryItem( "ec/dac", i18n("Digital-Analog"), i18n("Integrated Circuits"), "ic1.png", LibraryItem::lit_component, DAC::construct );
00043 }
00044
00045
00046 ADDAC::ADDAC(ICNDocument *icnDocument, bool newItem, const char *id)
00047 : Component(icnDocument, newItem, id)
00048 {
00049 m_numBits = 0;
00050 m_range = 0;
00051
00052 createProperty("numBits", Variant::Type::Int);
00053 property("numBits")->setCaption(i18n("Number Bits"));
00054 property("numBits")->setMinValue(2);
00055 property("numBits")->setMaxValue(max_ADDAC_bits);
00056 property("numBits")->setValue(2);
00057
00058 createProperty("range", Variant::Type::Double);
00059 property("range")->setCaption(i18n("Input Range"));
00060 property("range")->setUnit("V");
00061 property("range")->setMinValue(-1e12);
00062 property("range")->setMaxValue(1e12);
00063 property("range")->setValue(5);
00064 }
00065
00066 ADDAC::~ADDAC()
00067 {
00068 }
00069
00070 void ADDAC::dataChanged()
00071 {
00072 m_range = dataDouble("range");
00073 initPins();
00074 }
00075
00076
00077
00078
00079 ADC::ADC(ICNDocument *icnDocument, bool newItem, const char *id)
00080 : ADDAC(icnDocument, newItem, (id) ? id : "adc")
00081 {
00082 m_name = i18n("ADC");
00083 m_desc = i18n("Converts an analog signal into a digital output.");
00084
00085 for(int i=0; i<max_ADDAC_bits; ++i) m_logic[i] = 0;
00086
00087 m_realNode = 0;
00088 }
00089
00090 ADC::~ADC()
00091 {
00092 }
00093
00094 void ADC::stepNonLogic()
00095 {
00096 double floatBitValue = m_realNode->pin()->voltage() * (std::pow(2, double(m_numBits))-1.) / m_range;
00097 double roundBitValue = std::floor(floatBitValue+0.5);
00098
00099 if(roundBitValue < 0) {
00100 for(int i = 0; i<m_numBits; ++i) m_logic[i]->setHigh(false);
00101 return;
00102 }
00103
00104 uint roundedBitValue = uint(roundBitValue);
00105 for(int i = 0; i<m_numBits; ++i)
00106 m_logic[i]->setHigh(roundedBitValue & (1 << i));
00107 }
00108
00109 void ADC::initPins()
00110 {
00111 int numBits = dataInt("numBits");
00112
00113 if(numBits < 2) numBits = 2;
00114 else if(numBits > max_ADDAC_bits) numBits = max_ADDAC_bits;
00115
00116 if(numBits == m_numBits) return;
00117
00118 QStringList pins;
00119
00120 int inPos = (numBits-1+(numBits%2))/2;
00121
00122 for(int i=0; i<inPos; ++i) pins += " ";
00123
00124 pins += "In";
00125
00126 for(int i=inPos+1; i<numBits; ++i) pins += " ";
00127
00128 for(int i=numBits-1; i>=0; --i) pins += QString::number(i);
00129
00130 initDIPSymbol(pins, 64);
00131 initDIP(pins);
00132
00133 if(!m_realNode) m_realNode = ecNodeWithID("In");
00134
00135 if(numBits > m_numBits)
00136 {
00137 for(int i=m_numBits; i<numBits; ++i)
00138 {
00139 ECNode *node = ecNodeWithID(QString::number(i));
00140 m_logic[i] = createLogicOut(node, false);
00141 }
00142 } else {
00143 for(int i=numBits; i<m_numBits; ++i)
00144 {
00145 QString id = QString::number(i);
00146 removeDisplayText(id);
00147 removeElement(m_logic[i], false);
00148 removeNode(id);
00149 m_logic[i] = 0;
00150 }
00151 }
00152
00153 m_numBits = numBits;
00154 }
00155
00156
00157
00158
00159
00160 DAC::DAC(ICNDocument *icnDocument, bool newItem, const char *id)
00161 : ADDAC(icnDocument, newItem, (id) ? id : "dac")
00162 {
00163 m_name = i18n("DAC");
00164 m_desc = i18n("Converts a digital input to an analog output signal.");
00165
00166 for(int i=0; i<max_ADDAC_bits; ++i) m_logic[i] = 0;
00167
00168 m_voltagePoint = 0;
00169 }
00170
00171 DAC::~DAC()
00172 {
00173 }
00174
00175 void DAC::stepNonLogic()
00176 {
00177 uint value = 0;
00178 for(int i=0; i<m_numBits; ++i)
00179 value |= (m_logic[i]->isHigh() ? 1 : 0) << i;
00180
00181
00182
00183
00184 m_voltagePoint->setVoltage(m_range * double(value) / (std::pow(2, double(m_numBits))-1.));
00185 }
00186
00187 void DAC::initPins()
00188 {
00189 int numBits = dataInt("numBits");
00190
00191 if(numBits < 2) numBits = 2;
00192 else if(numBits > max_ADDAC_bits) numBits = max_ADDAC_bits;
00193
00194 if(numBits == m_numBits) return;
00195
00196 QStringList pins;
00197
00198 for(int i=0; i<numBits; ++i) pins += QString::number(i);
00199
00200 int inPos = (numBits+1+(numBits%2))/2;
00201 for(int i=numBits-1; i>=inPos; --i) pins += "";
00202
00203 pins += "Out";
00204
00205 for(int i=inPos-2; i>=0; --i) pins += "";
00206
00207 initDIPSymbol(pins, 64);
00208 initDIP(pins);
00209
00210 if(!m_voltagePoint) m_voltagePoint = createVoltagePoint(ecNodeWithID("Out"), 0.);
00211
00212 if(numBits > m_numBits) {
00213 for(int i=m_numBits; i<numBits; ++i)
00214 {
00215 ECNode *node = ecNodeWithID(QString::number(i));
00216 m_logic[i] = createLogicIn(node);
00217 }
00218 } else {
00219 for(int i=numBits; i<m_numBits; ++i)
00220 {
00221 QString id = QString::number(i);
00222 removeDisplayText(id);
00223 removeElement(m_logic[i], false);
00224 removeNode(id);
00225 m_logic[i] = 0;
00226 }
00227 }
00228
00229 m_numBits = numBits;
00230 }
00231
00232