summaryrefslogtreecommitdiffstats
path: root/src/electronics/components/addac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/electronics/components/addac.cpp')
-rw-r--r--src/electronics/components/addac.cpp281
1 files changed, 281 insertions, 0 deletions
diff --git a/src/electronics/components/addac.cpp b/src/electronics/components/addac.cpp
new file mode 100644
index 0000000..a58e2d8
--- /dev/null
+++ b/src/electronics/components/addac.cpp
@@ -0,0 +1,281 @@
+/***************************************************************************
+ * Copyright (C) 2005 by David Saxton *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "addac.h"
+#include "ecnode.h"
+#include "logic.h"
+#include "libraryitem.h"
+#include "pin.h"
+#include "voltagepoint.h"
+
+#include <cmath>
+#include <kiconloader.h>
+#include <klocale.h>
+
+
+Item* ADC::construct( ItemDocument *itemDocument, bool newItem, const char *id )
+{
+ return new ADC( (ICNDocument*)itemDocument, newItem, id );
+}
+
+
+Item* DAC::construct( ItemDocument *itemDocument, bool newItem, const char *id )
+{
+ return new DAC( (ICNDocument*)itemDocument, newItem, id );
+}
+
+
+LibraryItem* ADC::libraryItem()
+{
+ return new LibraryItem(
+ "ec/adc",
+ i18n("Analog-Digital"),
+ i18n("Integrated Circuits"),
+ "ic1.png",
+ LibraryItem::lit_component,
+ ADC::construct
+ );
+}
+
+
+LibraryItem* DAC::libraryItem()
+{
+ return new LibraryItem(
+ "ec/dac",
+ i18n("Digital-Analog"),
+ i18n("Integrated Circuits"),
+ "ic1.png",
+ LibraryItem::lit_component,
+ DAC::construct
+ );
+}
+
+
+//BEGIN class ADDAC
+ADDAC::ADDAC( ICNDocument *icnDocument, bool newItem, const char *id )
+ : Component( icnDocument, newItem, id )
+{
+ m_numBits = 0;
+ m_range = 0;
+
+ createProperty( "numBits", Variant::Type::Int );
+ property("numBits")->setCaption( i18n("Number Bits") );
+ property("numBits")->setMinValue(2);
+ property("numBits")->setMaxValue(max_ADDAC_bits);
+ property("numBits")->setValue(2);
+
+ createProperty( "range", Variant::Type::Double );
+ property("range")->setCaption( i18n("Input Range") );
+ property("range")->setUnit("V");
+ property("range")->setMinValue(-1e12);
+ property("range")->setMaxValue(1e12);
+ property("range")->setValue(5);
+}
+
+ADDAC::~ADDAC()
+{
+}
+
+
+void ADDAC::dataChanged()
+{
+ m_range = dataDouble("range");
+ initPins();
+}
+
+//END class ADDAC
+
+
+
+
+//BEGIN class ADC
+ADC::ADC( ICNDocument *icnDocument, bool newItem, const char *id )
+ : ADDAC( icnDocument, newItem, (id) ? id : "adc" )
+{
+ m_name = i18n("ADC");
+ m_desc = i18n("Converts an analog signal into a digital output.");
+
+ for ( int i=0; i<max_ADDAC_bits; ++i )
+ m_logic[i] = 0l;
+
+ m_realNode = 0l;
+}
+
+ADC::~ADC()
+{
+}
+
+
+void ADC::stepNonLogic()
+{
+ double floatBitValue = m_realNode->pin()->voltage() * (std::pow( 2, double(m_numBits) )-1.) / m_range;
+ double roundBitValue = std::floor( floatBitValue+0.5 );
+
+ if ( roundBitValue < 0 )
+ {
+ for ( int i = 0; i<m_numBits; ++i )
+ m_logic[i]->setHigh(false);
+ return;
+ }
+
+ uint roundedBitValue = uint(roundBitValue);
+ for ( int i = 0; i<m_numBits; ++i )
+ m_logic[i]->setHigh( roundedBitValue & ( 1 << i ) );
+}
+
+
+void ADC::initPins()
+{
+ int numBits = dataInt("numBits");
+
+ if ( numBits < 2 )
+ numBits = 2;
+ else if ( numBits > max_ADDAC_bits )
+ numBits = max_ADDAC_bits;
+
+ if ( numBits == m_numBits )
+ return;
+
+ QStringList pins;
+
+ int inPos = (numBits-1+(numBits%2))/2;
+ for ( int i=0; i<inPos; ++i )
+ pins += "";
+
+ pins += "In";
+
+ for ( int i=inPos+1; i<numBits; ++i )
+ pins += "";
+
+ for ( int i=numBits-1; i>=0; --i )
+ pins += QString::number(i);
+
+ initDIPSymbol( pins, 64 );
+ initDIP(pins);
+
+ if (!m_realNode)
+ m_realNode = ecNodeWithID("In");
+
+
+ if ( numBits > m_numBits )
+ {
+ for ( int i=m_numBits; i<numBits; ++i )
+ {
+ ECNode *node = ecNodeWithID( QString::number(i) );
+ m_logic[i] = createLogicOut( node, false );
+ }
+ }
+ else
+ {
+ for ( int i=numBits; i<m_numBits; ++i )
+ {
+ QString id = QString::number(i);
+ removeDisplayText(id);
+ removeElement( m_logic[i], false );
+ removeNode(id);
+ m_logic[i] = 0l;
+ }
+ }
+
+ m_numBits = numBits;
+}
+//END class ADC
+
+
+
+
+//BEGIN class DAC
+DAC::DAC( ICNDocument *icnDocument, bool newItem, const char *id )
+ : ADDAC( icnDocument, newItem, (id) ? id : "dac" )
+{
+ m_name = i18n("DAC");
+ m_desc = i18n("Converts a digital input to an analog output signal.");
+
+ for ( int i=0; i<max_ADDAC_bits; ++i )
+ m_logic[i] = 0l;
+
+ m_voltagePoint = 0l;
+}
+
+
+DAC::~DAC()
+{
+}
+
+
+void DAC::stepNonLogic()
+{
+ uint value = 0;
+ for ( int i=0; i<m_numBits; ++i )
+ value |= ( m_logic[i]->isHigh() ? 1 : 0 ) << i;
+
+// double valueAsDouble = double(value);
+// double powChange = std::pow( double(m_numBits), 2 )-1.;
+// m_voltagePoint->setVoltage( m_range * valueAsDouble / powChange );
+ m_voltagePoint->setVoltage( m_range * double(value) / (std::pow( 2, double(m_numBits) )-1.) );
+}
+
+
+void DAC::initPins()
+{
+ int numBits = dataInt("numBits");
+
+ if ( numBits < 2 )
+ numBits = 2;
+ else if ( numBits > max_ADDAC_bits )
+ numBits = max_ADDAC_bits;
+
+ if ( numBits == m_numBits )
+ return;
+
+ QStringList pins;
+
+ for ( int i=0; i<numBits; ++i )
+ pins += QString::number(i);
+
+ int inPos = (numBits+1+(numBits%2))/2;
+ for ( int i=numBits-1; i>=inPos; --i )
+ pins += "";
+
+ pins += "Out";
+
+ for ( int i=inPos-2; i>=0; --i )
+ pins += "";
+
+ initDIPSymbol( pins, 64 );
+ initDIP(pins);
+
+ if (!m_voltagePoint)
+ m_voltagePoint = createVoltagePoint( ecNodeWithID("Out"), 0. );
+
+ if ( numBits > m_numBits )
+ {
+ for ( int i=m_numBits; i<numBits; ++i )
+ {
+ ECNode *node = ecNodeWithID( QString::number(i) );
+ m_logic[i] = createLogicIn(node);
+ }
+ }
+ else
+ {
+ for ( int i=numBits; i<m_numBits; ++i )
+ {
+ QString id = QString::number(i);
+ removeDisplayText(id);
+ removeElement( m_logic[i], false );
+ removeNode(id);
+ m_logic[i] = 0l;
+ }
+ }
+
+ m_numBits = numBits;
+}
+//END class DAC
+