-
Notifications
You must be signed in to change notification settings - Fork 0
/
dial.cpp
117 lines (95 loc) · 2.51 KB
/
dial.cpp
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
#include <Arduino.h>
#include "dial.h"
char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
// The global dial_state
Dial_State dial_state;
Dial_Output dial_output;
Dial_Input dial_input;
void Dial_state_transition(Dial_State new_state) {
// execute exit of old state
dial_state(EXIT);
dial_state = new_state;
// and entry of the new state
dial_state(ENTRY);
}
struct DialVars {
uint32_t state_presence = 0;
char number[20];
uint8_t number_idx = 0;
uint8_t pulse_counter = 0;
} dial_vars;
void Dial_waiting_for_number(Event e) {
switch(e) {
case ENTRY:
memset(dial_vars.number, 0, sizeof(dial_vars.number));
dial_vars.number_idx = 0;
dial_vars.pulse_counter = 0;
dial_vars.state_presence = 0;
break;
case EXIT:
break;
case PERIODIC:
if (dial_input.dial_pin == LOW) {
Dial_state_transition(&Dial_low);
}
break;
}
}
void Dial_low(Event e) {
switch(e) {
case ENTRY:
dial_vars.state_presence = 1;
break;
case EXIT:
break;
case PERIODIC:
dial_vars.state_presence++;
if (dial_input.dial_pin == HIGH && dial_vars.state_presence >= 3 && dial_vars.state_presence < 50) {
dial_vars.pulse_counter++;
Dial_state_transition(&Dial_high);
}
break;
}
}
void Dial_high(Event e) {
switch(e) {
case ENTRY:
dial_vars.state_presence = 1;
break;
case EXIT:
break;
case PERIODIC:
dial_vars.state_presence++;
if (dial_input.dial_pin == LOW && dial_vars.state_presence >= 2 && dial_vars.state_presence < 20) {
Dial_state_transition(&Dial_low);
}
if (dial_vars.state_presence >= 20) {
// digit ready
dial_vars.number[dial_vars.number_idx++] = digits[dial_vars.pulse_counter % 10];
Dial_state_transition(&Dial_wait_next_digit);
}
break;
}
}
void Dial_wait_next_digit(Event e) {
switch(e) {
case ENTRY:
dial_vars.pulse_counter = 0;
dial_vars.state_presence = 0;
break;
case EXIT:
break;
case PERIODIC:
if (dial_input.dial_pin == LOW) {
Dial_state_transition(&Dial_low);
}
dial_vars.state_presence++;
if (dial_vars.state_presence >= 200) {
// number ready
memcpy(dial_output.number, dial_vars.number, sizeof(dial_vars.number));
dial_output.ready = true;
Dial_state_transition(&Dial_waiting_for_number);
}
break;
}
}