1 /* Copyright (C) 2012 Eduard Timotei Budulea
2 Copyright (C) 2013 Roy R. Rankin
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include "config.h"
18 #include "bit1w.h"
19
20 bool debug = false;
21
LowLevel1W(const char * name,const char * desc)22 LowLevel1W::LowLevel1W(const char *name, const char *desc):
23 Module(name, desc), cicluReper(0), lastValue(true),
24 lastTimeout(false),
25 state(&LowLevel1W::idle), ignoreCallback(false), bit_break(0)
26 {
27 pin = new Pin1W("pin", *this);
28 addSymbol(pin);
29 create_pkg(1);
30 assign_pin(1, pin);
31 pin->putState(false);
32 pin->update_direction(IOPIN::DIR_INPUT, true);
33 change(true);
34 }
~LowLevel1W()35 LowLevel1W::~LowLevel1W()
36 {
37 removeSymbol(pin);
38 }
39
callback()40 void LowLevel1W::callback() {
41 change(false);
42 }
43
change(bool pinChange)44 void LowLevel1W::change(bool pinChange) {
45 if (ignoreCallback) return;
46 guint64 ciclu = get_cycles().get();
47 bool bitValue = false;
48 switch(pin->getBitChar()) {
49 case 'Z':
50 case '1':
51 case 'x':
52 case 'W':
53 bitValue = true;
54 }
55 bool isTimeout = ciclu >= cicluReper;
56
57
58 if ((lastValue != bitValue || lastTimeout != isTimeout) && debug) {
59 cout << name() <<" +++change state: line = " << bitValue << ", timeout = " << isTimeout << "; time = " << hex << ciclu << ", reper = " << cicluReper << endl;
60 }
61 lastValue = bitValue;
62 lastTimeout = isTimeout;
63 ignoreCallback = true;
64 (this->*state)(bitValue, isTimeout);
65 ignoreCallback = false;
66 if (cicluReper > ciclu) {
67 if (!pinChange && bit_break >= ciclu) {
68 get_cycles().clear_break(bit_break);
69 }
70 if(cicluReper != bit_break)
71 get_cycles().set_break(cicluReper, this);
72 if(debug)
73 printf("%s now %" PRINTF_GINT64_MODIFIER "x next break %" PRINTF_GINT64_MODIFIER "x last break %" PRINTF_GINT64_MODIFIER "x delta(usec) %.1f\n", name().c_str(), ciclu, cicluReper, bit_break, (cicluReper-ciclu)*4./20.);
74 bit_break = cicluReper;
75 }
76 }
77
idle(bool input,bool isTimeout)78 void LowLevel1W::idle(bool input, bool isTimeout) {
79 if(debug && !isTimeout)
80 cout <<name() << " idle input="<<input <<" timout="<<isTimeout<<endl;
81 if (input) return;
82 switch(gotBitStart()) {
83 case WRITE1:
84 if(verbose) cout << name() << " ===write1" << endl;
85 state = &LowLevel1W::inWritting1;
86 cicluReper = get_cycles().get(0.000045);
87 return;
88
89 case WRITE0:
90 if (verbose) cout << name() << " ===write0" << endl;
91 state = &LowLevel1W::inWritting0;
92 cicluReper = get_cycles().get(0.000040);
93 pin->update_direction(IOPIN::DIR_OUTPUT, true);
94 return;
95
96 case READ:
97 if(verbose) cout << name() << " ===read" << endl;
98 state = &LowLevel1W::inReading;
99 cicluReper = get_cycles().get(0.000030);
100 return;
101
102 case RESET:
103 if(verbose) cout << name() <<" ===expect reset" << endl;
104 state = &LowLevel1W::inResetPulse;
105 cicluReper = get_cycles().get(0.000440);
106 return;
107
108 case IDLE:
109 state = &LowLevel1W::idle;
110 return;
111 }
112 }
113
inResetPulse(bool input,bool isTimeout)114 void LowLevel1W::inResetPulse(bool input, bool isTimeout) {
115 if(debug)
116 cout <<name() << " inResetPulse input="<<input <<" timout="<<isTimeout<<endl;
117 if (input) {
118 state = &LowLevel1W::idle;
119 return;
120 }
121 if (!isTimeout) return;
122 state = &LowLevel1W::endResetPulse;
123 }
124
endResetPulse(bool input,bool isTimeout)125 void LowLevel1W::endResetPulse(bool input, bool isTimeout) {
126 if(debug)
127 cout << name() << " "<<__FUNCTION__ << " input="<<input <<" timout="<<isTimeout<<endl;
128 if (!input) return;
129 gotReset();
130 state = &LowLevel1W::inPresencePulse;
131 cicluReper = get_cycles().get(0.00005);
132 }
133
inPresencePulse(bool input,bool isTimeout)134 void LowLevel1W::inPresencePulse(bool input, bool isTimeout) {
135 if(debug)
136 cout << name() << " "<< __FUNCTION__ << " input="<<input <<" timout="<<isTimeout<<endl;
137 if (!isTimeout) return;
138 state = &LowLevel1W::endPresencePulse;
139 pin->update_direction(IOPIN::DIR_OUTPUT, true);
140 cicluReper = get_cycles().get(0.0002);
141 }
142
endPresencePulse(bool input,bool isTimeout)143 void LowLevel1W::endPresencePulse(bool input, bool isTimeout) {
144 if(debug)
145 cout << name() << " " << __FUNCTION__ << " input="<<input <<" timout="<<isTimeout<<endl;
146 if (!isTimeout) return;
147 pin->update_direction(IOPIN::DIR_INPUT, true);
148 state = &LowLevel1W::waitIdle;
149 cicluReper = get_cycles().get(0.00002);
150 }
151
waitIdle(bool input,bool isTimeout)152 void LowLevel1W::waitIdle(bool input, bool isTimeout) {
153 if(debug)
154 cout << name() << "waitIdle input=" <<input <<" timeout="<<isTimeout<<endl;
155 if (!input) return;
156 state = &LowLevel1W::idle;
157 }
158
inWritting0(bool input,bool isTimeout)159 void LowLevel1W::inWritting0(bool input, bool isTimeout) {
160 if(debug)
161 cout << name() << " " << __FUNCTION__ << " input="<<input <<" timout="<<isTimeout<<endl;
162 if (!isTimeout) return;
163 state = &LowLevel1W::finalizeBit;
164 pin->update_direction(IOPIN::DIR_INPUT, true);
165 //cicluReper = get_cycles().get(0.00006);
166 cicluReper = get_cycles().get(0.0000050);
167 }
168
inWritting1(bool input,bool isTimeout)169 void LowLevel1W::inWritting1(bool input, bool isTimeout) {
170 if(debug)
171 cout <<name() << " " << __FUNCTION__ << " input="<<input <<" timout="<<isTimeout<<endl;
172 if (!isTimeout) return;
173 if(!input) // OOPS either a reset or bus collision
174 {
175 state = &LowLevel1W::inResetPulse;
176 cicluReper = get_cycles().get(0.000440);
177 return;
178 }
179 state = &LowLevel1W::idle;
180 if (bit_remaining() == 0) gotBitStart();
181 //state = &LowLevel1W::finalizeBit;
182 }
183
inReading(bool input,bool isTimeout)184 void LowLevel1W::inReading(bool input, bool isTimeout) {
185 if(debug)
186 cout << name() << " " << __FUNCTION__ << " input="<<input <<" timout="<<isTimeout<<endl;
187 if (input) {
188 readBit(true);
189 state = &LowLevel1W::idle;
190 if (bit_remaining() == 0) gotBitStart();
191 return;
192 }
193 if (!isTimeout) return;
194 readBit(false);
195 state = &LowLevel1W::finalizeBit;
196 // assume read < 120 us (30 + 90)
197 cicluReper = get_cycles().get(0.000090);
198 }
199
200 // Wait for a 1 then go to idle
finalizeBit(bool input,bool isTimeout)201 void LowLevel1W::finalizeBit(bool input, bool isTimeout) {
202 if(debug)
203 cout << name() << " " <<__FUNCTION__ << " input="<<input <<" timout="<<isTimeout<<endl;
204 if (input) {
205 state = &LowLevel1W::idle;
206 if (bit_remaining() == 0) gotBitStart();
207 return;
208 }
209 if (!isTimeout) return;
210 state = &LowLevel1W::inResetPulse;
211 cicluReper = get_cycles().get(0.000320);
212 }
213
214