summaryrefslogtreecommitdiffstats
path: root/src/electronics/simulation/logic.h
blob: be8374f0263d94b7ded5d7f4fcb56f38babb11d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/***************************************************************************
 *   Copyright (C) 2003-2005 by David Saxton                               *
 *   [email protected]                                                    *
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/

#ifndef LOGIC_H
#define LOGIC_H

#include "element.h"

#include <qguardedptr.h>
#include <qvaluelist.h>

class Component;
class Pin;
class Simulator;

typedef QValueList<QGuardedPtr<Pin> > PinList;

typedef struct
{
	float risingTrigger; // Trigger on rising edge
	float fallingTrigger; // Trigger on falling edge
	float output; // Output voltage
	float highImpedance; // Output impedance when high
	float lowImpedance; // Output impedance when low
} LogicConfig;

class CallbackClass {};
typedef void(CallbackClass::*CallbackPtr)( bool isHigh );

/**
Use this class for Logic Inputs - this will have infinite impedance.
Use isHigh() will return whether the voltage level at the pin
is high than the predetermined voltage threshold, and setHigh() will make the
output high/low, also according to the predetermined logic type / voltages.

@short Boolean Logic input
*/
class LogicIn : public Element
{
	public:
		LogicIn( LogicConfig config );
		virtual ~LogicIn();
	
		virtual Type type() const { return Element_LogicIn; }
		virtual void setElementSet( ElementSet *c );
	
		/**
		 * Set logic values from the LogicConfig.
		 */
		virtual void setLogic( LogicConfig config );
		/**
		 * Check if the input state has changed, to see if we need to callback.
		 */
		void check();
		/**
		 * Returns whether the pin is 'high', as defined for the logic type
		 * Note: this is defined as the voltage on the pin, as opposed to what the 
		 * state was set to (the two are not necessarily the same).
		 */
		bool isHigh() const { return m_bLastState; }
		/**
		 * When the logic state on this LogicIn changes, the function passed in this
		 * function will be called. At most one Callback can be added per LogicIn.
		 */
		void setCallback( CallbackClass * object, CallbackPtr func );
		/**
		 * Reads the LogicConfig values in from KTLConfig, and returns them in a
		 * nice object form.
		 */
		static LogicConfig getConfig();
		/**
		 * If this belongs to a logic chain, then this will be called from the chain.
		 */
		void setLastState( bool state ) { m_bLastState = state; }
		/**
		 * Returns a pointer to the next LogicIn in the chain.
		 */
		LogicIn * nextLogic() const { return m_pNextLogic; }
		/**
		 * Sets the next LogicIn in the chain.
		 */
		void setNextLogic( LogicIn * next ) { m_pNextLogic = next; }
		/**
		 * Calls the callback function, if there is one.
		 */
		void callCallback()
		{
			if (m_pCallbackFunction)
				(m_pCallbackObject->*m_pCallbackFunction)(m_bLastState);
		}
	
	protected:
		virtual void updateCurrents();
		virtual void add_initial_dc();
	
		CallbackPtr m_pCallbackFunction;
		CallbackClass * m_pCallbackObject;
		bool m_bLastState;
		LogicIn * m_pNextLogic;
		LogicConfig m_config;
};


/**
@short Logic output/input
*/
class LogicOut : public LogicIn
{
	public:
		LogicOut( LogicConfig config, bool _high );
		virtual ~LogicOut();
	
		virtual void setLogic( LogicConfig config );
		virtual void setElementSet( ElementSet *c );
		virtual void add_map();
		virtual Type type() const { return Element_LogicOut; }
	
		/**
		 * Call this function to override the logic-high output impedance as set by
		 * the user. Once set, the impedance will not be changed by the user
		 * updating the config; only by subsequent calls to this function.
		 */
		void setOutputHighConductance( double g );
		/**
		 * Call this function to override the logic-low output impedance as set by
		 * the user. Once set, the impedance will not be changed by the user
		 * updating the config; only by subsequent calls to this function.
		 */
		void setOutputLowConductance( double g );
		/**
		 * Call this function to override the logic out voltage as set by the
		 * user. Once set, the impedance will not be changed by the user
		 * updating the config; only by subsequent calls to this function.
		 */
		void setOutputHighVoltage( double v );
		/**
		 * Returns the voltage that this will output when high.
		 */
		double outputHighVoltage() const { return m_vHigh; }
		/**
		 * Sets the pin to be high/low
		 */
		void setHigh( bool high );
		/**
		 * @returns the state that this is outputting (regardless of voltage level on logic)
		 */
		bool outputState() const { return b_state; }
		/**
		 * Set whether or not this LogicOut is the head of a LogicChain (controls
		 * itself and a bunch of LogicIns).
		 */
		void setUseLogicChain( bool use );
		/**
		 * When a LogicOut configured as the start of a LogicChain changes start, it
		 * appends a pointer to itself to the list of change LogicOut, starting from
		 * the Simulator. This functions enables appending the next changed LogicOut
		 * to this one.
		 */
		void setNextChanged( LogicOut * logicOut, unsigned char chain ) { m_pNextChanged[chain] = logicOut; }
		/**
		 * To avoid a pointer to this LogicOut being added twice in one
		 * iteration due to the state changing twice, this LogicOut sets an
		 * added flag to true after adding it to the list of changed. The flag
		 * must be reset to false with this function (done by Simulator).
		 */
		void setCanAddChanged( bool canAdd ) { m_bCanAddChanged = canAdd; }
		/**
		 * Returns the next LogicOut that has changed, when configured as the start
		 * of a LogicChain.
		 * @see setNextChanged
		 */
		LogicOut * nextChanged( unsigned char chain ) const { return m_pNextChanged[chain]; }
		PinList pinList;
		PinList::iterator pinListBegin;
		PinList::iterator pinListEnd;
	
	protected:
		void configChanged();
		virtual void updateCurrents();
		virtual void add_initial_dc();
	
		// Pre-initalized levels from config
		double m_gHigh;
		double m_gLow;
		double m_vHigh;
		
		// Whether to use the user-defined logic values
		bool m_bOutputHighConductanceConst;
		bool m_bOutputLowConductanceConst;
		bool m_bOutputHighVoltageConst;
	
		double m_g_out;
		double m_v_out;
		double m_old_g_out;
		double m_old_v_out;
		bool b_state;
		bool m_bCanAddChanged;
		LogicOut * m_pNextChanged[2];
		Simulator * m_pSimulator;
		bool m_bUseLogicChain;
};

#endif