1 /*
2    Copyright (C) 2015	Roy R Rankin
3 
4 This file is part of the libgpsim library of gpsim
5 
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10 
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 Lesser General Public License for more details.
15 
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, see
18 <http://www.gnu.org/licenses/lgpl-2.1.html>.
19 */
20 
21 #ifndef __CTMU_H__
22 #define __CTMU_H__
23 
24 #include "trace.h"
25 
26 
27 class CTMU;
28 
29 
30 class CTMUCONH : public sfr_register
31 {
32 public:
33     CTMUCONH(Processor *pCpu, const char *pName, const char *pDesc=0, CTMU *_ctmu=0);
34 
35     enum
36     {
37 	CTTRIG   = 1<<0,	// CTMU Special Event Trigger Control Bit
38 	IDISSEN  = 1<<1,	// Analog Current Source Control bit
39 	EDGSEQEN = 1<<2,	// Edge Sequence Enable bit
40 	EDGEN    = 1<<3,	// Edge Enable bit
41 	TGEN     = 1<<4,	// Time Generation Enable bit
42 	CTMUSIDL = 1<<5,	// Stop in Idle Mode bit
43 	CTMUEN   = 1<<7		// CTMU Enable bit
44     };
45 
46 
47     void put(unsigned int new_value);
48 
49     CTMU *ctmu;
50 
51 };
52 
53 class CTMUCONL : public sfr_register
54 {
55 public:
56 
57     CTMUCONL(Processor *pCpu, const char *pName, const char *pDesc=0, CTMU *_ctmu=0);
58     enum
59     {
60 	EDG1STAT = 1<<0,	// Edge 1 Status bit
61 	EDG2STAT = 1<<1,	// Edge 2 Status bit
62 	EDG1SEL0 = 1<<2,	// Edge 1 Source Select bit 0
63 	EDG1SEL1 = 1<<3,	// Edge 1 Source Select bit 1
64 	EDG1POL  = 1<<4,	// Edge 1 Polarity Select bit
65 	EDG2SEL0 = 1<<5,	// Edge 2 Source Select bit 0
66 	EDG2SEL1 = 1<<6,	// Edge 2 Source Select bit 1
67 	EDG2POL  = 1<<7		// Edge 2 Polarity Select bit
68     };
69 
70     void put(unsigned int new_value);
71 
72     CTMU *ctmu;
73 };
74 
75 class CTMUICON : public sfr_register
76 {
77 public:
78 
79     CTMUICON(Processor *pCpu, const char *pName, const char *pDesc=0, CTMU *_ctmu=0);
80 
81     void put(unsigned int new_value);
82     enum
83     {
84 	IRNG0    = 1<<0,	// Current Source Range Select bit 0
85 	IRNG1    = 1<<1,	// Current Source Range Select bit 1
86 	ITRIM0   = 1<<2,	// Current Source Trim bit 0
87 	ITRIM1   = 1<<3,	// Current Source Trim bit 1
88 	ITRIM2   = 1<<4,	// Current Source Trim bit 2
89 	ITRIM3   = 1<<5,	// Current Source Trim bit 3
90 	ITRIM4   = 1<<6,	// Current Source Trim bit 4
91 	ITRIM5   = 1<<7  	// Current Source Trim bit 5
92     };
93     CTMU *ctmu;
94 };
95 class ctmu_stimulus : public stimulus
96 {
97 public:
98 
99   ctmu_stimulus(Processor *pCpu, const char *n=0, double _Vth=5.0,
stimulus(n,_Vth,_Zth)100 	double _Zth=1e3) : stimulus(n, _Vth, _Zth), cpu(pCpu)
101   {
102   }
103 
104   /* A current source is simulated by using a 200 V source so
105      between 0-5 V the current should change < 2%.
106      The maximum voltage to a pin is clamped to be below Vdd-0.5 volts.
107      Thus when the node voltage >= Vdd-0.6 we drop the drive voltage
108      is reduced to Vdd-0.6. This can cause an overshoot to the node voltage.
109   */
get_Vth()110   virtual double get_Vth()
111   {
112         double max_volt = cpu->get_Vdd() - 0.6;
113         if (get_nodeVoltage() >= max_volt)
114 	    return max_volt;
115 	return Vth;
116   }
117 private:
118   Processor *cpu;
119 };
120 
121 #define Vsrc 200.
122 class CTMU_SignalSink;
123 
124 class CTMU
125 {
126 public:
127 
128     CTMU(Processor *pCpu);
129     void new_current(double I);
130     void enable(unsigned int value);
131     void disable();
132     void current_off();
133     void stat_change();
134     void idissen(bool ground);
set_eepas(ECCPAS * _e1,ECCPAS * _e2)135     void set_eepas(ECCPAS *_e1, ECCPAS *_e2) { m_eccpas1 = _e1; m_eccpas2=_e2;}
set_IOpins(PinModule * _pm1,PinModule * _pm2,PinModule * _pout)136     void set_IOpins(PinModule *_pm1, PinModule *_pm2, PinModule *_pout)
137 	{m_cted1 = _pm1; m_cted2 = _pm2; m_ctpls = _pout;}
138     void new_edge();
139     void tgen_on();
140     void tgen_off();
141     void syncC2out(bool high);
142 
143 
144 
145     double      current = 0.0;
146     double      resistance = 0.0;
147     bool        cted1_state = false;
148     bool        cted2_state = false;
149     ctmu_stimulus	*ctmu_stim = nullptr;
150     PinModule	*m_cted1 = nullptr;
151     PinModule	*m_cted2 = nullptr;
152     PinModule   *m_ctpls = nullptr;
153     ECCPAS	*m_eccpas1 = nullptr;
154     ECCPAS	*m_eccpas2 = nullptr;
155     CTMU_SignalSink *ctmu_cted1_sink = nullptr;
156     CTMU_SignalSink *ctmu_cted2_sink = nullptr;
157     PeripheralSignalSource *ctpls_source = nullptr;
158 
159     CTMUCONH 	*ctmuconh = nullptr;
160     CTMUCONL 	*ctmuconl = nullptr;
161     CTMUICON 	*ctmuicon = nullptr;
162     ADCON0_V2   *adcon0 = nullptr;
163     ADCON1_2B   *adcon1 = nullptr;
164     CM2CON1_V2  *cm2con1 = nullptr;
165     Processor   *cpu;
166 
167 };
168 #endif // __CTMU_H__
169