44
55/*
66 PolledTimeout.h - Encapsulation of a polled Timeout
7-
7+
88 Copyright (c) 2018 Daniel Salazar. All rights reserved.
99 This file is part of the esp8266 core for Arduino environment.
1010
2323 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2424 */
2525
26- #include < limits>
27-
28- #include < Arduino.h>
26+ #include < c_types.h> // IRAM_ATTR
27+ #include < limits> // std::numeric_limits
28+ #include < type_traits> // std::is_unsigned
29+ #include < core_esp8266_features.h>
2930
3031namespace esp8266
3132{
@@ -70,13 +71,13 @@ struct TimeSourceMillis
7071
7172struct TimeSourceCycles
7273{
73- // time policy based on ESP.getCycleCount ()
74+ // time policy based on esp_get_cycle_count ()
7475 // this particular time measurement is intended to be called very often
7576 // (every loop, every yield)
7677
77- using timeType = decltype (ESP.getCycleCount ());
78- static timeType time () {return ESP. getCycleCount ();}
79- static constexpr timeType ticksPerSecond = ESP.getCpuFreqMHz () * 1000000UL ; // 80'000'000 or 160'000'000 Hz
78+ using timeType = decltype (esp_get_cycle_count ());
79+ static timeType time () {return esp_get_cycle_count ();}
80+ static constexpr timeType ticksPerSecond = esp_get_cpu_freq_mhz () * 1000000UL ; // 80'000'000 or 160'000'000 Hz
8081 static constexpr timeType ticksPerSecondMax = 160000000 ; // 160MHz
8182};
8283
@@ -161,13 +162,13 @@ class timeoutTemplate
161162 return expiredRetrigger ();
162163 return expiredOneShot ();
163164 }
164-
165+
165166 IRAM_ATTR // fast
166167 operator bool ()
167168 {
168- return expired ();
169+ return expired ();
169170 }
170-
171+
171172 bool canExpire () const
172173 {
173174 return !_neverExpires;
@@ -178,6 +179,7 @@ class timeoutTemplate
178179 return _timeout != alwaysExpired;
179180 }
180181
182+ // Resets, will trigger after this new timeout.
181183 IRAM_ATTR // called from ISR
182184 void reset (const timeType newUserTimeout)
183185 {
@@ -186,12 +188,30 @@ class timeoutTemplate
186188 _neverExpires = (newUserTimeout < 0 ) || (newUserTimeout > timeMax ());
187189 }
188190
191+ // Resets, will trigger after the timeout previously set.
189192 IRAM_ATTR // called from ISR
190193 void reset ()
191194 {
192195 _start = TimePolicyT::time ();
193196 }
194197
198+ // Resets to just expired so that on next poll the check will immediately trigger for the user,
199+ // also change timeout (after next immediate trigger).
200+ IRAM_ATTR // called from ISR
201+ void resetAndSetExpired (const timeType newUserTimeout)
202+ {
203+ reset (newUserTimeout);
204+ _start -= _timeout;
205+ }
206+
207+ // Resets to just expired so that on next poll the check will immediately trigger for the user.
208+ IRAM_ATTR // called from ISR
209+ void resetAndSetExpired ()
210+ {
211+ reset ();
212+ _start -= _timeout;
213+ }
214+
195215 void resetToNeverExpires ()
196216 {
197217 _timeout = alwaysExpired + 1 ; // because canWait() has precedence
@@ -202,7 +222,7 @@ class timeoutTemplate
202222 {
203223 return TimePolicyT::toUserUnit (_timeout);
204224 }
205-
225+
206226 static constexpr timeType timeMax ()
207227 {
208228 return TimePolicyT::timeMax;
@@ -235,14 +255,14 @@ class timeoutTemplate
235255 }
236256 return false ;
237257 }
238-
258+
239259 IRAM_ATTR // fast
240260 bool expiredOneShot () const
241261 {
242262 // returns "always expired" or "has expired"
243263 return !canWait () || checkExpired (TimePolicyT::time ());
244264 }
245-
265+
246266 timeType _timeout;
247267 timeType _start;
248268 bool _neverExpires;
@@ -259,14 +279,14 @@ using periodic = polledTimeout::timeoutTemplate<true> /*__attribute__((deprecate
259279using oneShotMs = polledTimeout::timeoutTemplate<false >;
260280using periodicMs = polledTimeout::timeoutTemplate<true >;
261281
262- // Time policy based on ESP.getCycleCount (), and intended to be called very often:
282+ // Time policy based on esp_get_cycle_count (), and intended to be called very often:
263283// "Fast" versions sacrifices time range for improved precision and reduced execution time (by 86%)
264- // (cpu cycles for ::expired(): 372 (millis()) vs 52 (ESP.getCycleCount ()))
284+ // (cpu cycles for ::expired(): 372 (millis()) vs 52 (esp_get_cycle_count ()))
265285// timeMax() values:
266286// Ms: max is 26843 ms (26.8 s)
267287// Us: max is 26843545 us (26.8 s)
268288// Ns: max is 1073741823 ns ( 1.07 s)
269- // (time policy based on ESP.getCycleCount () is intended to be called very often)
289+ // (time policy based on esp_get_cycle_count () is intended to be called very often)
270290
271291using oneShotFastMs = polledTimeout::timeoutTemplate<false , YieldPolicy::DoNothing, TimePolicy::TimeFastMillis>;
272292using periodicFastMs = polledTimeout::timeoutTemplate<true , YieldPolicy::DoNothing, TimePolicy::TimeFastMillis>;
0 commit comments