File indexing completed on 2024-05-05 05:46:08

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 "config.h"
0012 #ifndef NO_GPSIM
0013 
0014 #include "micropackage.h"
0015 #include "piccomponent.h"
0016 #include "piccomponentpin.h"
0017 
0018 #include <ktechlab_debug.h>
0019 
0020 void PICComponentPin_logicCallback(void *objV, bool state) {
0021     PICComponentPin *objT = static_cast<PICComponentPin*>(objV);
0022     objT->logicCallback(state);
0023 }
0024 
0025 PICComponentPin::PICComponentPin(PICComponent *picComponent, PicPin picPin)
0026     : m_id(picPin.pinID)
0027 {
0028     m_gOutHigh = 0.0;
0029     m_gOutLow = 0.0;
0030     m_picPin = picPin;
0031     m_pPICComponent = picComponent;
0032     m_pLogicOut = nullptr;
0033     m_pLogicIn = nullptr;
0034     m_pIOPIN = nullptr;
0035     m_pStimulusNode = nullptr;
0036     Zth = 0.0;
0037     Vth = 0.0;
0038 
0039     switch (picPin.type) {
0040     case PicPin::type_input: {
0041         m_pLogicIn = picComponent->createLogicIn(picComponent->ecNodeWithID(picPin.pinID));
0042         break;
0043     }
0044     case PicPin::type_bidir: {
0045         m_pLogicOut = picComponent->createLogicOut(picComponent->ecNodeWithID(picPin.pinID), false);
0046         m_gOutHigh = 0.004;
0047         m_gOutLow = 0.004;
0048         break;
0049     }
0050     case PicPin::type_open: {
0051         m_pLogicOut = picComponent->createLogicOut(picComponent->ecNodeWithID(picPin.pinID), false);
0052         m_pLogicOut->setOutputHighVoltage(0.0);
0053         m_pLogicOut->setOutputHighConductance(0.0);
0054         m_gOutHigh = 0.0;
0055         m_gOutLow = 0.004;
0056         break;
0057     }
0058     case PicPin::type_vss:
0059     case PicPin::type_vdd:
0060     case PicPin::type_mclr:
0061     case PicPin::type_osc:
0062     default:
0063         break;
0064     }
0065 
0066     if (m_pLogicIn) {
0067         //m_pLogicIn->setCallback(this, (CallbackPtr)(&PICComponentPin::logicCallback));
0068         m_pLogicIn->setCallback2(PICComponentPin_logicCallback, this);
0069     }
0070     if (m_pLogicOut) {
0071         //m_pLogicOut->setCallback(this, (CallbackPtr)(&PICComponentPin::logicCallback));
0072         m_pLogicOut->setCallback2(PICComponentPin_logicCallback, this);
0073     }
0074 }
0075 
0076 PICComponentPin::~PICComponentPin()
0077 {
0078     if (m_pLogicIn) {
0079         //m_pLogicIn->setCallback(nullptr, (CallbackPtr) nullptr);
0080         m_pLogicIn->setCallback2(nullptr, nullptr);
0081     }
0082     if (m_pLogicOut) {
0083         //m_pLogicOut->setCallback(nullptr, (CallbackPtr) nullptr);
0084         m_pLogicOut->setCallback2(nullptr, nullptr);
0085     }
0086 
0087     delete m_pStimulusNode;
0088 }
0089 
0090 void PICComponentPin::attach(IOPIN *iopin)
0091 {
0092     if (!iopin) {
0093         qCWarning(KTL_LOG) << " iopin is nullptr";
0094         return;
0095     }
0096 
0097     if (m_pStimulusNode) {
0098         qCWarning(KTL_LOG) << " Already have a node stimulus";
0099         return;
0100     }
0101 
0102     if (m_pIOPIN) {
0103         qCWarning(KTL_LOG) << " Already have an iopin";
0104         return;
0105     }
0106 
0107     m_pIOPIN = iopin;
0108     m_pStimulusNode = new Stimulus_Node(m_id.toLatin1());
0109     m_pStimulusNode->attach_stimulus(iopin);
0110     m_pStimulusNode->attach_stimulus(this);
0111 
0112     // We need to tell the iopin whether or not we are high
0113     if (m_pLogicOut)
0114         logicCallback(m_pLogicOut->isHigh());
0115     else if (m_pLogicIn)
0116         logicCallback(m_pLogicIn->isHigh());
0117 }
0118 
0119 double PICComponentPin::get_Vth()
0120 {
0121     if (!m_pIOPIN)
0122         return 0.0;
0123 
0124     if (m_pIOPIN->get_direction() == IOPIN::DIR_INPUT)
0125         return Vth;
0126     else
0127         return m_pIOPIN->get_Vth();
0128 }
0129 
0130 void PICComponentPin::set_nodeVoltage(double v)
0131 {
0132     Q_UNUSED(v);
0133 
0134     if (!m_pLogicOut || !m_pIOPIN)
0135         return;
0136 
0137     if (m_pIOPIN->get_direction() == IOPIN::DIR_INPUT) {
0138         m_pLogicOut->setOutputHighConductance(0.0);
0139         m_pLogicOut->setOutputLowConductance(0.0);
0140     } else {
0141         m_pLogicOut->setHigh(m_pIOPIN->getDrivingState());
0142         m_pLogicOut->setOutputHighConductance(m_gOutHigh);
0143         m_pLogicOut->setOutputLowConductance(m_gOutLow);
0144     }
0145 }
0146 
0147 void PICComponentPin::logicCallback(bool state)
0148 {
0149     if (!m_pIOPIN)
0150         return;
0151 
0152     Vth = state ? 5e10 : 0;
0153     bDrivingState = state;
0154 
0155     if (m_pIOPIN->get_direction() == IOPIN::DIR_INPUT) {
0156         Zth = 1e5;
0157 
0158         m_pIOPIN->setDrivenState(state);
0159         if (m_pStimulusNode)
0160             m_pStimulusNode->update();
0161     } else
0162         Zth = 0;
0163 }
0164 
0165 void PICComponentPin::resetOutput()
0166 {
0167     if (m_pLogicOut)
0168         m_pLogicOut->setHigh(false);
0169 }
0170 
0171 #endif