addac.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by David Saxton                                    *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
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 //BEGIN class ADDAC
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 //END class ADDAC
00076 
00077 
00078 //BEGIN class ADC
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 //END class ADC
00156 
00157 
00158 //BEGIN class DAC
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 //      double valueAsDouble = double(value);
00182 //      double powChange = std::pow(double(m_numBits), 2)-1.;
00183 //      m_voltagePoint->setVoltage(m_range * valueAsDouble / powChange);
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 //END class DAC
00232 

Generated on Tue May 8 17:05:27 2007 for KTechLab by  doxygen 1.5.1