File indexing completed on 2024-05-05 05:46:11
0001 /*************************************************************************** 0002 * Copyright (C) 2003-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 #ifndef LOGIC_H 0012 #define LOGIC_H 0013 0014 #include "element.h" 0015 0016 #include <QList> 0017 #include <QPointer> 0018 0019 class Component; 0020 class Pin; 0021 class Simulator; 0022 0023 typedef QList<QPointer<Pin>> PinList; 0024 0025 class LogicConfig 0026 { 0027 public: 0028 LogicConfig(); 0029 0030 float risingTrigger; ///< Trigger on rising edge 0031 float fallingTrigger; ///< Trigger on falling edge 0032 float output; ///< Output voltage 0033 float highImpedance; ///< Output impedance when high 0034 float lowImpedance; ///< Output impedance when low 0035 }; 0036 0037 class CallbackClass 0038 { 0039 }; 0040 typedef void (CallbackClass::*CallbackPtr)(bool isHigh); 0041 0042 // BEGIN Callback2Ptr 0043 0044 typedef void * Callback2Obj; 0045 typedef void (*Callback2Ptr)(Callback2Obj objV, bool isHigh); 0046 0047 // END Callback2Ptr 0048 0049 /** 0050 Use this class for Logic Inputs - this will have infinite impedance. 0051 Use isHigh() will return whether the voltage level at the pin 0052 is high than the predetermined voltage threshold, and setHigh() will make the 0053 output high/low, also according to the predetermined logic type / voltages. 0054 0055 @short Boolean Logic input 0056 */ 0057 class LogicIn : public Element 0058 { 0059 public: 0060 LogicIn(LogicConfig config); 0061 ~LogicIn() override; 0062 0063 Type type() const override 0064 { 0065 return Element_LogicIn; 0066 } 0067 void setElementSet(ElementSet *c) override; 0068 0069 /** 0070 * Set logic values from the LogicConfig. 0071 */ 0072 virtual void setLogic(LogicConfig config); 0073 /** 0074 * Check if the input state has changed, to see if we need to callback. 0075 */ 0076 void check(); 0077 /** 0078 * Returns whether the pin is 'high', as defined for the logic type 0079 * Note: this is defined as the voltage on the pin, as opposed to what the 0080 * state was set to (the two are not necessarily the same). 0081 */ 0082 bool isHigh() const 0083 { 0084 return m_bLastState; 0085 } 0086 /** 0087 * When the logic state on this LogicIn changes, the function passed in this 0088 * function will be called. At most one Callback can be added per LogicIn. 0089 */ 0090 // void setCallback(CallbackClass *object, CallbackPtr func); 0091 0092 void setCallback2(Callback2Ptr fun, Callback2Obj obj); 0093 0094 /** 0095 * Reads the LogicConfig values in from KTLConfig, and returns them in a 0096 * nice object form. 0097 */ 0098 static LogicConfig getConfig(); 0099 /** 0100 * If this belongs to a logic chain, then this will be called from the chain. 0101 */ 0102 void setLastState(bool state) 0103 { 0104 m_bLastState = state; 0105 } 0106 /** 0107 * Returns a pointer to the next LogicIn in the chain. 0108 */ 0109 LogicIn *nextLogic() const 0110 { 0111 return m_pNextLogic; 0112 } 0113 /** 0114 * Sets the next LogicIn in the chain. 0115 */ 0116 void setNextLogic(LogicIn *next) 0117 { 0118 m_pNextLogic = next; 0119 } 0120 /** 0121 * Calls the callback function, if there is one. 0122 */ 0123 void callCallback() 0124 { 0125 // if (m_pCallbackFunction) 0126 // (m_pCallbackObject->*m_pCallbackFunction)(m_bLastState); 0127 if (m_pCallback2Func) 0128 m_pCallback2Func(m_pCallback2Obj, m_bLastState); 0129 } 0130 0131 protected: 0132 void updateCurrents() override; 0133 void add_initial_dc() override; 0134 0135 // 2022.06.13 - fix this crap NO FUNCTION POINTERS 0136 // v1 callbacks, deprecated 0137 // CallbackPtr m_pCallbackFunction; 0138 // CallbackClass *m_pCallbackObject; 0139 // v2 callbacks, a bit less hacky than v1 0140 Callback2Ptr m_pCallback2Func; 0141 Callback2Obj m_pCallback2Obj; 0142 0143 bool m_bLastState; 0144 LogicIn *m_pNextLogic; 0145 LogicConfig m_config; 0146 }; 0147 0148 /** 0149 @short Logic output/input 0150 */ 0151 class LogicOut : public LogicIn 0152 { 0153 public: 0154 LogicOut(LogicConfig config, bool _high); 0155 ~LogicOut() override; 0156 0157 void setLogic(LogicConfig config) override; 0158 void setElementSet(ElementSet *c) override; 0159 Type type() const override 0160 { 0161 return Element_LogicOut; 0162 } 0163 0164 /** 0165 * Call this function to override the logic-high output impedance as set by 0166 * the user. Once set, the impedance will not be changed by the user 0167 * updating the config; only by subsequent calls to this function. 0168 */ 0169 void setOutputHighConductance(double g); 0170 /** 0171 * Call this function to override the logic-low output impedance as set by 0172 * the user. Once set, the impedance will not be changed by the user 0173 * updating the config; only by subsequent calls to this function. 0174 */ 0175 void setOutputLowConductance(double g); 0176 /** 0177 * Call this function to override the logic out voltage as set by the 0178 * user. Once set, the impedance will not be changed by the user 0179 * updating the config; only by subsequent calls to this function. 0180 */ 0181 void setOutputHighVoltage(double v); 0182 /** 0183 * Returns the voltage that this will output when high. 0184 */ 0185 double outputHighVoltage() const 0186 { 0187 return m_vHigh; 0188 } 0189 /** 0190 * Sets the pin to be high/low 0191 */ 0192 void setHigh(bool high); 0193 /** 0194 * @returns the state that this is outputting (regardless of voltage level on logic) 0195 */ 0196 bool outputState() const 0197 { 0198 return b_state; 0199 } 0200 /** 0201 * Set whether or not this LogicOut is the head of a LogicChain (controls 0202 * itself and a bunch of LogicIns). 0203 */ 0204 void setUseLogicChain(bool use); 0205 /** 0206 * When a LogicOut configured as the start of a LogicChain changes start, it 0207 * appends a pointer to itself to the list of change LogicOut, starting from 0208 * the Simulator. This functions enables appending the next changed LogicOut 0209 * to this one. 0210 */ 0211 void setNextChanged(LogicOut *logicOut, unsigned char chain) 0212 { 0213 m_pNextChanged[chain] = logicOut; 0214 } 0215 /** 0216 * To avoid a pointer to this LogicOut being added twice in one 0217 * iteration due to the state changing twice, this LogicOut sets an 0218 * added flag to true after adding it to the list of changed. The flag 0219 * must be reset to false with this function (done by Simulator). 0220 */ 0221 void setCanAddChanged(bool canAdd) 0222 { 0223 m_bCanAddChanged = canAdd; 0224 } 0225 /** 0226 * Returns the next LogicOut that has changed, when configured as the start 0227 * of a LogicChain. 0228 * @see setNextChanged 0229 */ 0230 LogicOut *nextChanged(unsigned char chain) const 0231 { 0232 return m_pNextChanged[chain]; 0233 } 0234 PinList pinList; 0235 PinList::iterator pinListBegin; 0236 PinList::iterator pinListEnd; 0237 0238 protected: 0239 void configChanged(); 0240 void updateCurrents() override; 0241 void add_initial_dc() override; 0242 0243 // Pre-initalized levels from config 0244 double m_gHigh; 0245 double m_gLow; 0246 double m_vHigh; 0247 0248 // Whether to use the user-defined logic values 0249 bool m_bOutputHighConductanceConst; 0250 bool m_bOutputLowConductanceConst; 0251 bool m_bOutputHighVoltageConst; 0252 0253 double m_g_out; 0254 double m_v_out; 0255 double m_old_g_out; 0256 double m_old_v_out; 0257 bool b_state; 0258 bool m_bCanAddChanged; 0259 LogicOut *m_pNextChanged[2]; 0260 Simulator *m_pSimulator; 0261 bool m_bUseLogicChain; 0262 }; 0263 0264 #endif