-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
88 lines (73 loc) · 2.53 KB
/
main.c
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
#include "sm/main_sm.c"
#include "sm/write_sm.c"
#include "sm/read_sm.c"
#include "sm/display_sm.c"
#include "drivers/keyboard.c"
#include "drivers/display.c"
#include "lib/scheduler.h"
#include "lib/timer.h"
int main() {
DDRA = 0xFF; PORTA = 0x00; // Display control lines.
DDRC = 0xFF; PORTC = 0x00; // Display data lines.
DDRD = 0x00; PORTD = 0xFF; // Keyboard and button overrides.
// Synchronous state machine setup:
unsigned long main_tick_length = 100;
unsigned long write_tick_length = 25;
unsigned long read_tick_length = 25;
unsigned long display_tick_length = 200;
// Get GCD:
unsigned long tmp_GCD = 1;
tmp_GCD = findGCD(tmp_GCD, main_tick_length);
tmp_GCD = findGCD(tmp_GCD, write_tick_length);
tmp_GCD = findGCD(tmp_GCD, read_tick_length);
tmp_GCD = findGCD(tmp_GCD, display_tick_length);
unsigned long GCD = tmp_GCD;
// Calculate period:
unsigned long main_period = main_tick_length / GCD;
unsigned long write_period = write_tick_length / GCD;
unsigned long read_period = read_tick_length / GCD;
unsigned long display_period = display_tick_length / GCD;
// Setup list of tasks.
static task m_task, w_task, r_task, d_task;
task *tasks[] = { &m_task, &w_task, &r_task, &d_task };
const unsigned char num_tasks = sizeof(tasks) / sizeof(task*);
// Main tick
m_task.state = main_start;
m_task.period = main_period;
m_task.elapsedTime = main_period;
m_task.TickFct = &main_tick;
// Write tick
w_task.state = write_start;
w_task.period = write_period;
w_task.elapsedTime = write_period;
w_task.TickFct = &write_tick;
// Read tick
r_task.state = read_start;
r_task.period = read_period;
r_task.elapsedTime = read_period;
r_task.TickFct = &read_tick;
// Display tick
d_task.state = display_start;
d_task.period = display_period;
d_task.elapsedTime = display_period;
d_task.TickFct = &display_tick;
LCD_init();
KB_init();
TimerSet(GCD);
TimerOn();
while(1) {
for (unsigned char i = 0; i < num_tasks; i++ ) {
// Task is ready to tick
if ( tasks[i]->elapsedTime == tasks[i]->period ) {
// Setting next state for task
tasks[i]->state = tasks[i]->TickFct(tasks[i]->state);
// Reset the elapsed time for next tick.
tasks[i]->elapsedTime = 0;
}
tasks[i]->elapsedTime += 1;
}
while(!TimerFlag);
TimerFlag = 0;
}
return 0;
}