1////////////////////////////////////////////////////////////////////////////////
2// //
3// This software is supplied under the terms of a license agreement or //
4// nondisclosure agreement with Mitov Software and may not be copied //
5// or disclosed except in accordance with the terms of that agreement. //
6// Copyright(c) 2002-2016 Mitov Software. All Rights Reserved. //
7// //
8////////////////////////////////////////////////////////////////////////////////
9
10#ifndef _MITOV_TIMING_h
11#define _MITOV_TIMING_h
12
13#include <Mitov.h>
14
15namespace Mitov
16{
17 class ClockGenerator : public Mitov::CommonGenerator
18 {
19 protected:
20 virtual void Clock()
21 {
22 OutputPin.Notify( NULL );
23 }
24
25 };
26//---------------------------------------------------------------------------
27 class Timer : public Mitov::CommonEnableSource
28 {
29 typedef Mitov::CommonEnableSource inherited;
30
31 public:
32 OpenWire::SinkPin StartInputPin;
33 OpenWire::SinkPin ResetInputPin;
34
35 public:
36 uint32_t Interval = 1000000;
37 bool AutoRepeat : 1;
38 bool CanRestart : 1;
39
40 protected:
41 bool FValue : 1;
42
43 uint32_t FStartTime;
44
45 protected:
46 virtual void SystemStart()
47 {
48 inherited::SystemStart();
49 OutputPin.SendValue( FValue );
50 }
51
52 virtual void SystemLoopBegin( unsigned long currentMicros )
53 {
54 if( ! AutoRepeat )
55 if( ! FValue )
56 {
57 inherited::SystemLoopBegin( currentMicros );
58 return;
59 }
60
61 if( FValue )
62 if( ! Enabled )
63 {
64 FValue = false;
65 OutputPin.SendValue( FValue );
66 inherited::SystemLoopBegin( currentMicros );
67 return;
68 }
69
70 currentMicros = micros(); // Use micros(); to make sure the DoReceiveStart is not from the same clock event!
71 if( currentMicros - FStartTime >= Interval )
72 {
73 FValue = !FValue;
74 OutputPin.SendValue( FValue );
75 if( AutoRepeat )
76 FStartTime += Interval;
77 }
78
79 inherited::SystemLoopBegin( currentMicros );
80 }
81
82 protected:
83 virtual void DoReceiveStart( void *_Data )
84 {
85 if( ! Enabled )
86 return;
87
88 if( !CanRestart )
89 if( FValue )
90 return;
91
92 FStartTime = micros();
93 if( FValue )
94 return;
95
96 FValue = true;
97 OutputPin.SendValue( FValue );
98 }
99
100 void DoReceiveClear( void *_Data )
101 {
102 if( FValue )
103 {
104 FValue = false;
105 OutputPin.SendValue( FValue );
106
107 if( AutoRepeat )
108 FStartTime = micros();
109 }
110 }
111
112 public:
113 Timer() :
114 AutoRepeat( false ),
115 CanRestart( true ),
116 FValue( false )
117 {
118 StartInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&Timer::DoReceiveStart );
119 ResetInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&Timer::DoReceiveClear );
120 }
121 };
122//---------------------------------------------------------------------------
123 class Delay : public Mitov::CommonEnableSource
124 {
125 typedef Mitov::CommonEnableSource inherited;
126
127 public:
128 OpenWire::SinkPin StartInputPin;
129 OpenWire::SinkPin ResetInputPin;
130
131 public:
132 unsigned long Interval = 1000000;
133 bool CanRestart : 1;
134
135 protected:
136 bool FValue : 1;
137 unsigned long FStartTime;
138
139 protected:
140 virtual void SystemLoopBegin( unsigned long currentMicros )
141 {
142 if( FValue )
143 {
144 if( ! Enabled )
145 FValue = false;
146
147 else
148 {
149 unsigned long ACurrentMicros = micros(); // Use micros(); to make sure the DoReceiveStart is not from the same clock event!
150 if( ACurrentMicros - FStartTime >= Interval )
151 {
152 FValue = false;
153 OutputPin.Notify( NULL );
154 }
155 }
156 }
157
158 inherited::SystemLoopBegin( currentMicros );
159 }
160
161 protected:
162 virtual void DoReceiveStart( void *_Data )
163 {
164 if( ! Enabled )
165 return;
166
167 if( !CanRestart )
168 if( FValue )
169 return;
170
171 FStartTime = micros();
172 if( FValue )
173 return;
174
175 FValue = true;
176 }
177
178 void DoReceiveClear( void *_Data )
179 {
180 FValue = false;
181 }
182
183 public:
184 Delay() :
185 CanRestart( true ),
186 FValue( false )
187 {
188 StartInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&Delay::DoReceiveStart );
189 ResetInputPin.SetCallback( this, (OpenWire::TOnPinReceive)&Delay::DoReceiveClear );
190 }
191 };
192//---------------------------------------------------------------------------
193 class DetectEdge : public Mitov::CommonEnableFilter
194 {
195 public:
196 bool Rising : 1;
197
198 protected:
199 bool FLastValue : 1;
200
201 protected:
202 virtual void DoReceive( void *_Data ) override
203 {
204 bool AValue = *(bool *)_Data;
205 if( AValue == FLastValue )
206 return;
207
208 FLastValue = AValue;
209 if( Rising == AValue )
210 OutputPin.Notify( NULL );
211
212 }
213
214 public:
215 DetectEdge() :
216 FLastValue( false ),
217 Rising( true )
218 {
219 }
220
221 };
222
223//---------------------------------------------------------------------------
224}
225
226#endif