FastArduino  v1.7
C++ library to build fast but small Arduino/AVR projects
time.h
Go to the documentation of this file.
1 // Copyright 2016-2021 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 
32 namespace 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 
76  RTTTime& operator=(const RTTTime& that)
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;
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  {
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  }
448  ~auto_delay() INLINE
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 */
503 
time::RTTTime::RTTTime
RTTTime(uint32_t micros=0UL)
Construct a new RTTTime value.
Definition: time.h:56
time::auto_delay::auto_delay
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
time::MILLIS_PTR
uint32_t(*)() MILLIS_PTR
Function pointer type used for time::millis global variable.
Definition: time.h:305
time::RTTTime::millis
uint32_t millis() const
Number of elapsed milliseconds.
Definition: time.h:125
time::operator>
bool operator>(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:148
time::RTTTime::micros
uint16_t micros() const
Number of elapsed microseconds (0..999).
Definition: time.h:131
time::delay
DELAY_PTR delay
Delay program execution for the given amount of milliseconds.
Definition: time.cpp:19
time::operator-
RTTTime operator-(const RTTTime &a, const RTTTime &b)
Subtract 2 RTTTime instances.
Definition: time.h:245
time::operator==
bool operator==(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:204
time::DELAY_PTR
void(*)(uint32_t ms) DELAY_PTR
Function pointer type used for time::delay global variable.
Definition: time.h:285
time::delta
RTTTime delta(const RTTTime &time1, const RTTTime &time2)
Compute the time delta from time1 and time2.
Definition: time.cpp:27
time::yield
void yield()
Utility method used by many FastArduino API in order to "yield" some processor time; concretely it ju...
Definition: time.cpp:22
time::RTTTime::total_micros
uint32_t total_micros() const
Return current elapsed time in microseconds only.
Definition: time.h:119
time::RTTTime::RTTTime
RTTTime(uint32_t millis, uint16_t micros)
Construct a new RTTTime value.
Definition: time.h:63
time::RTTTime::operator+=
RTTTime & operator+=(uint32_t microseconds)
Add microseconds to this RTTTime instance.
Definition: time.h:91
time::auto_millis::auto_millis
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
time::set_clock
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
time::RTTTime::RTTTime
RTTTime(const RTTTime &that)
Construct a copy of that.
Definition: time.h:69
time::delay_us
void delay_us(uint16_t us) INLINE
Delay program execution for the given amount of microseconds.
Definition: time.h:334
time::since
uint32_t since(uint32_t start_ms)
Compute the time elapsed, in milliseconds, since start_ms.
Definition: time.cpp:41
time::millis
MILLIS_PTR millis
Count number of milliseconds elapsed since some time base reference (generally since MCU startup).
Definition: time.cpp:20
time
Defines simple API to handle time and delays.
Definition: time.h:33
time::RTTTime::operator=
RTTTime & operator=(const RTTTime &that)
Assign this RTTTime instance from that.
Definition: time.h:76
utilities.h
General utilities API that have broad application in programs.
time::RTTTime
Structure used to hold a time value with microsecond precision.
Definition: time.h:50
time::auto_delay
Set a new time::delay function for the duration of the current scope; when the scope is left,...
Definition: time.h:433
time::operator<
bool operator<(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:176
time::default_delay
void default_delay(uint32_t ms)
Delay program execution for the given amount of milliseconds.
Definition: time.cpp:47
time::operator!=
bool operator!=(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:216
time::operator>=
bool operator>=(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:162
time::RTTTime::operator-=
RTTTime & operator-=(uint32_t microseconds)
Remove microseconds from this RTTTime instance.
Definition: time.h:111
time::operator<=
bool operator<=(const RTTTime &a, const RTTTime &b)
Compare 2 RTTTime instances.
Definition: time.h:190
time::delay_ms
void delay_ms(uint16_t ms) INLINE
Delay program execution for the given amount of milliseconds.
Definition: time.h:346
time::auto_millis
Set a new time::millis function for the duration of the current scope; when the scope is left,...
Definition: time.h:477
time::operator+
RTTTime operator+(const RTTTime &a, const RTTTime &b)
Add 2 RTTTime instances.
Definition: time.h:227
INLINE
#define INLINE
Specific GCC attribute to force the compiler to always inline code of a given function.
Definition: defines.h:57