-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclock_examples.cpp
More file actions
142 lines (116 loc) · 4.22 KB
/
clock_examples.cpp
File metadata and controls
142 lines (116 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#define F_CPU 8000000
#include <util/delay.h>
#include "clock.h"
#include "ports.h"
using namespace clock;
typedef PIN_C2 Led;
typedef PIN_C3 WarnLed;
typedef PIN_D3 Led1;
typedef PIN_D4 Led2;
int main(void) {
Led::DDR = ports::DataDirection::Output; // Put Led pin into output mode.
WarnLed::DDR = ports::DataDirection::Output;
Led1::DDR = ports::DataDirection::Output;
Led2::DDR = ports::DataDirection::Output;
{
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
// «CLOCK_DIFF[^ ,]»
uint8_t prev = Clock;
_delay_ms(2);
uint8_t now = Clock;
uint8_t diff = now - prev;
// Try to avoid the following line.
uint8_t shouldBe2 = units_to_ms(diff);
// Try not to use units_to_ms for variable values.
// If possible convert a const value:
uint8_t expected = ms_to_units<2>();
/*¤*/
# pragma GCC diagnostic pop
// make gcc happy
if (shouldBe2 != 2) {
Led::PORT = 1;
}
if (expected != diff) {
Led::PORT = 1;
}
}
// «CLOCK_BASIC[^ ,]»
uint16_t previous = Clock;
while(!duration_passed(previous, ms_to_units<5000>()));
/*¤*/
// don't give the compiler a chance to optimize this away.
uint8_t userMs = 8 + Led::PIN;
uint8_t userUs = 8 + WarnLed::PIN;
// «CLOCK_CONVERSION[^ ,]»
// If the type is too small the compiler will warn us.
const uint16_t durationInUnits = ms_to_units<300>();
const uint8_t duration2InUnits = us_to_units<1500>();
const uint8_t durationConvToMs = units_to_ms<50>();
const uint32_t durationConvToUs = units_to_us<10000>();
uint16_t clockStart = Clock;
// Do something we want to measure.
uint16_t clockEnd = Clock;
auto measured = clockEnd - clockStart;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
uint8_t measuredTimeInMs = units_to_ms(measured);
uint8_t measuredTimeInUs = units_to_us(measured);
// userMs and userUs might come from rs232.
// If code size and calculation speed doesn't matter to you
// using the deprecated function is perfectly fine.
uint32_t userMsToUnits = ms_to_units(userMs); // userMs might come from rs232
uint32_t userUsToUnits = us_to_units(userUs); // userUs might come from rs232
#pragma GCC diagnostic pop
/*¤*/
static_assert(duration2InUnits < durationInUnits, "1.5 ms should be smaller than 300ms");
static_assert(durationConvToMs < durationConvToUs, "10000 units in µs must be > than 50 units in ms");
if (measuredTimeInMs > 3) {
// Operation took longer than 3 ms.
Led::PORT = 1;
}
auto diff = measuredTimeInMs * 1000 - measuredTimeInUs;
if (diff > 1000) {
// The calculated difference is bigger than 1ms.
WarnLed::PORT = 1;
}
// Wait the user entered ms:
previous = Clock;
while(!duration_passed(previous, userMsToUnits));
// Wait the user entered us:
previous = Clock;
while(!duration_passed(previous, userUsToUnits));
// «CLOCK_REACHED1[^ ,]»
uint16_t now = Clock;
uint16_t target_clock = now + ms_to_units<1000>();
while (!clock_reached(target_clock)) {}
/*¤*/
// «CLOCK_REACHED2[^ ,]»
uint16_t previous_clock = Clock;
uint16_t next_clock = previous_clock + ms_to_units<3000>();
while (!clock_reached((uint16_t) Clock, previous_clock, next_clock)) {}
/*¤*/
/*«CLOCK_REACHED_UINT16»*/uint16_t target = (uint16_t) Clock + ms_to_units<1800>();/*¤*/
// use target
if (target == std::numeric_limits<uint16_t>::max()) target = 0;
// «CLOCK_DURATION[^ ,]»
previous = Clock;
while(!duration_passed(previous, ms_to_units<5000>()));
// The simpler version above is equivalent to
// duration_passed(previous, Clock, ...);
previous = Clock;
for (;;) {
uint16_t now = Clock;
if (duration_passed(previous, now, ms_to_units<150>())) Led1::PORT = 1;
if (duration_passed(previous, now, ms_to_units<220>())) Led2::PORT = 1;
if (duration_passed(previous, now, ms_to_units<270>())) {
Led1::PORT = 0; // Led1 has been on for 270-150 = 120ms
Led2::PORT = 0; // Led2 has been on for 270-220 = 50ms
// Start again: Led1 will turn on again in 150ms; Led2 in 220ms.
previous = Clock;
}
}
/*¤*/
return 0;
}
#include REGISTER_IRQS