You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
282 lines
5.7 KiB
282 lines
5.7 KiB
/***************************************************************************
|
|
* Copyright (C) 2005 by David Saxton *
|
|
* david@bluehaze.org *
|
|
* *
|
|
* 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 <tdelocale.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;
|
|
|
|
TQStringList 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 += TQString::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( TQString::number(i) );
|
|
m_logic[i] = createLogicOut( node, false );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( int i=numBits; i<m_numBits; ++i )
|
|
{
|
|
TQString id = TQString::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;
|
|
|
|
TQStringList pins;
|
|
|
|
for ( int i=0; i<numBits; ++i )
|
|
pins += TQString::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( TQString::number(i) );
|
|
m_logic[i] = createLogicIn(node);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( int i=numBits; i<m_numBits; ++i )
|
|
{
|
|
TQString id = TQString::number(i);
|
|
removeDisplayText(id);
|
|
removeElement( m_logic[i], false );
|
|
removeNode(id);
|
|
m_logic[i] = 0l;
|
|
}
|
|
}
|
|
|
|
m_numBits = numBits;
|
|
}
|
|
//END class DAC
|
|
|