FastArduino v1.10
C++ library to build fast but small Arduino/AVR projects
Loading...
Searching...
No Matches
time.h
Go to the documentation of this file.
1// Copyright 2016-2023 Jean-Francois Poilpret
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
16
21#ifndef TIME_HH
22#define TIME_HH
23
24#include <stdint.h>
25#include "boards/io.h"
26#include <util/delay_basic.h>
27#include "utilities.h"
28
32namespace time
33{
34 // Forward declaration to avoid compilation error
35 class RTTTime;
36 inline RTTTime operator-(const RTTTime& a, const RTTTime& b);
37
49 class RTTTime
50 {
51 public:
56 explicit RTTTime(uint32_t micros = 0UL) : millis_(micros / ONE_MILLI_32), micros_(micros % ONE_MILLI_32) {}
57
63 RTTTime(uint32_t millis, uint16_t micros) : millis_(millis), micros_(micros) {}
64
69 RTTTime(const RTTTime& that) : millis_{that.millis_}, micros_{that.micros_} {}
70
77 {
78 if (this != &that)
79 {
80 millis_ = that.millis_;
81 micros_ = that.micros_;
82 }
83 return *this;
84 }
85
91 RTTTime& operator+=(uint32_t microseconds)
92 {
93 uint32_t extra_millis = microseconds / ONE_MILLI_32;
94 uint16_t extra_micros = microseconds % ONE_MILLI_32;
95 millis_ += extra_millis;
96 micros_ += extra_micros;
97 if (micros_ >= ONE_MILLI_16)
98 {
99 ++millis_;
100 micros_ -= ONE_MILLI_16;
101 }
102 return *this;
103 }
104
111 RTTTime& operator-=(uint32_t microseconds)
112 {
113 return *this = (*this - RTTTime{microseconds});
114 }
115
119 uint32_t total_micros() const
120 {
121 return millis_ * ONE_MILLI_32 + micros_;
122 }
123
125 uint32_t millis() const
126 {
127 return millis_;
128 }
129
131 uint16_t micros() const
132 {
133 return micros_;
134 }
135
136 private:
137 uint32_t millis_;
138 uint16_t micros_;
139 };
140
148 inline bool operator>(const RTTTime& a, const RTTTime& b)
149 {
150 if (a.millis() > b.millis()) return true;
151 if (a.millis() < b.millis()) return false;
152 return a.micros() > b.micros();
153 }
154
162 inline bool operator>=(const RTTTime& a, const RTTTime& b)
163 {
164 if (a.millis() > b.millis()) return true;
165 if (a.millis() < b.millis()) return false;
166 return a.micros() >= b.micros();
167 }
168
176 inline bool operator<(const RTTTime& a, const RTTTime& b)
177 {
178 if (a.millis() < b.millis()) return true;
179 if (a.millis() > b.millis()) return false;
180 return a.micros() < b.micros();
181 }
182
190 inline bool operator<=(const RTTTime& a, const RTTTime& b)
191 {
192 if (a.millis() < b.millis()) return true;
193 if (a.millis() > b.millis()) return false;
194 return a.micros() <= b.micros();
195 }
196
204 inline bool operator==(const RTTTime& a, const RTTTime& b)
205 {
206 return (a.millis() == b.millis()) && (a.micros() == b.micros());
207 }
208
216 inline bool operator!=(const RTTTime& a, const RTTTime& b)
217 {
218 return (a.millis() != b.millis()) || (a.micros() != b.micros());
219 }
220
227 inline RTTTime operator+(const RTTTime& a, const RTTTime& b)
228 {
229 uint32_t millis = a.millis() + b.millis();
230 uint16_t micros = a.micros() + b.micros();
231 if (micros >= ONE_MILLI_16)
232 {
233 ++millis;
234 micros -= ONE_MILLI_16;
235 }
236 return RTTTime{millis, micros};
237 }
238
245 inline RTTTime operator-(const RTTTime& a, const RTTTime& b)
246 {
247 if (a <= b) return RTTTime{0, 0};
248 uint32_t millis = a.millis() - b.millis();
249 if (a.micros() >= b.micros()) return RTTTime{millis, a.micros() - b.micros()};
250 return RTTTime{millis - 1, ONE_MILLI_16 + a.micros() - b.micros()};
251 }
252
259 void yield();
260
269 RTTTime delta(const RTTTime& time1, const RTTTime& time2);
270
280 uint32_t since(uint32_t start_ms);
281
285 using DELAY_PTR = void (*)(uint32_t ms);
286
300 extern DELAY_PTR delay;
301
305 using MILLIS_PTR = uint32_t (*)();
306
325 extern MILLIS_PTR millis;
326
333 inline void delay_us(uint16_t us) INLINE;
334 inline void delay_us(uint16_t us)
335 {
336 _delay_loop_2(us * INST_PER_US / 4UL);
337 }
338
345 inline void delay_ms(uint16_t ms) INLINE;
346 inline void delay_ms(uint16_t ms)
347 {
348 while (ms--) delay_us(ONE_MILLI_16);
349 }
350
359 void default_delay(uint32_t ms);
360
362 template<typename CLOCK> class ClockDelegate
363 {
364 using TYPE = ClockDelegate<CLOCK>;
365
366 public:
367 ClockDelegate() = delete;
368
369 static void set_clock(const CLOCK& clock)
370 {
371 clock_ = &clock;
372 time::delay = TYPE::delay;
373 time::millis = TYPE::millis;
374 }
375
376 static void delay(uint32_t ms)
377 {
378 clock_->delay(ms);
379 }
380
381 static uint32_t millis()
382 {
383 return clock_->millis();
384 }
385
386 private:
387 static const CLOCK* clock_;
388 };
389
390 template<typename CLOCK> const CLOCK* ClockDelegate<CLOCK>::clock_ = nullptr;
392
408 template<typename CLOCK> void set_clock(const CLOCK& clock)
409 {
410 time::ClockDelegate<CLOCK>::set_clock(clock);
411 }
412
433 {
434 public:
435 auto_delay(const auto_delay&) = delete;
436 auto_delay& operator=(const auto_delay&) = delete;
437
443 explicit auto_delay(DELAY_PTR new_delay) INLINE
444 {
445 delay = new_delay;
446 }
449 {
450 delay = old_delay_;
451 }
453 private:
454 const DELAY_PTR old_delay_ = delay;
455 };
456
477 {
478 public:
479 auto_millis(const auto_millis&) = delete;
480 auto_millis& operator=(const auto_millis&) = delete;
481
487 explicit auto_millis(MILLIS_PTR new_millis) INLINE
488 {
489 millis = new_millis;
490 }
493 {
494 millis = old_millis_;
495 }
497 private:
498 const MILLIS_PTR old_millis_ = millis;
499 };
500};
501
502#endif /* TIME_HH */
Structure used to hold a time value with microsecond precision.
Definition: time.h:50
RTTTime(uint32_t millis, uint16_t micros)
Construct a new RTTTime value.
Definition: time.h:63
RTTTime(uint32_t micros=0UL)
Construct a new RTTTime value.
Definition: time.h:56
RTTTime(const RTTTime &that)
Construct a copy of that.
Definition: time.h:69
uint32_t total_micros() const
Return current elapsed time in microseconds only.
Definition: time.h:119
uint16_t micros() const
Number of elapsed microseconds (0..999).
Definition: time.h:131
RTTTime & operator-=(uint32_t microseconds)
Remove microseconds from this RTTTime instance.
Definition: time.h:111
uint32_t millis() const
Number of elapsed milliseconds.
Definition: time.h:125
RTTTime & operator+=(uint32_t microseconds)
Add microseconds to this RTTTime instance.
Definition: time.h:91
RTTTime & operator=(const RTTTime &that)
Assign this RTTTime instance from that.
Definition: time.h:76
Set a new time::delay function for the duration of the current scope; when the scope is left,...
Definition: time.h:433
auto_delay(DELAY_PTR new_delay) INLINE
Set new time::delay to new_delay after storing current function for later restore.
Definition: time.h:443
Set a new time::millis function for the duration of the current scope; when the scope is left,...
Definition: time.h:477
auto_millis(MILLIS_PTR new_millis) INLINE
Set new time::millis to new_millis after storing current function for later restore.
Definition: time.h:487
#define INLINE
Specific GCC attribute to force the compiler to always inline code of a given function.
Definition: defines.h:57
Defines simple API to handle time and delays.
Definition: time.h:33
void(*)(uint32_t ms) DELAY_PTR
Function pointer type used for time::delay global variable.
Definition: time.h:285
MILLIS_PTR millis
Count number of milliseconds elapsed since some time base reference (generally since MCU startup).
Definition: time.cpp:20
bool operator<=(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:190
void delay_us(uint16_t us) INLINE
Delay program execution for the given amount of microseconds.
Definition: time.h:334
void default_delay(uint32_t ms)
Delay program execution for the given amount of milliseconds.
Definition: time.cpp:47
bool operator>(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:148
void yield()
Utility method used by many FastArduino API in order to "yield" some processor time; concretely it ju...
Definition: time.cpp:22
RTTTime delta(const RTTTime &time1, const RTTTime &time2)
Compute the time delta from time1 and time2.
Definition: time.cpp:27
uint32_t(*)() MILLIS_PTR
Function pointer type used for time::millis global variable.
Definition: time.h:305
bool operator==(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:204
RTTTime operator-(const RTTTime &a, const RTTTime &b)
Subtract 2 RTTTime instances.
Definition: time.h:245
RTTTime operator+(const RTTTime &a, const RTTTime &b)
Add 2 RTTTime instances.
Definition: time.h:227
bool operator<(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:176
void set_clock(const CLOCK &clock)
Utility method to transform millis() and delay() methods of a clock instance of any CLOCK class into ...
Definition: time.h:408
uint32_t since(uint32_t start_ms)
Compute the time elapsed, in milliseconds, since start_ms.
Definition: time.cpp:41
bool operator!=(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:216
bool operator>=(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:162
void delay_ms(uint16_t ms) INLINE
Delay program execution for the given amount of milliseconds.
Definition: time.h:346
DELAY_PTR delay
Delay program execution for the given amount of milliseconds.
Definition: time.cpp:19
General utilities API that have broad application in programs.