-
Notifications
You must be signed in to change notification settings - Fork 0
/
wclock.ceu
71 lines (56 loc) · 2.33 KB
/
wclock.ceu
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
///////////////////////////////////////////////////////////////////////////////
// EXTERNAL INTERFACE
///////////////////////////////////////////////////////////////////////////////
// Language wall-clock timer (e.g., `await 1s`)
code/call WCLOCK_Now (none) -> u32 do
escape { ceu_wclock_now() };
end
code/call WCLOCK_Freeze (var u32 us) -> none do
_delayMicroseconds(us);
end
///////////////////////////////////////////////////////////////////////////////
// INTERNAL INTERFACE
///////////////////////////////////////////////////////////////////////////////
#ifndef CEU_WCLOCK_IRQ_N
#error missing `CEU_WCLOCK_IRQ_N`
#endif
#ifndef CEU_WCLOCK_PRESCALER
#error missing `CEU_WCLOCK_PRESCALER`
#endif
native/pre do
##define __WCLOCK_CEU__
void ceu_wclock_init (void);
//void ceu_wclock (bool v); // TODO: ???
void ceu_wclock_request (s32 us, bool was_active);
void ceu_wclock_done (void);
s32 ceu_wclock_dt (void);
u32 ceu_wclock_now (void);
end
///////////////////////////////////////////////////////////////////////////////
// INITIALIZATION
///////////////////////////////////////////////////////////////////////////////
#define CEU_WCLOCK_US_TO_INCS(us) ((s32)(((double)(us))*F_CPU/CEU_WCLOCK_PRESCALER/1000000L))
#define CEU_WCLOCK_US_TO_OVERFLOW(us) (65536 - CEU_WCLOCK_US_TO_INCS(us) - 1) // -1: sleep one more tick to compensate math rounds
#define CEU_WCLOCK_INCS_TO_US(incs) ((s32)(((double)(incs))*1000000L*CEU_WCLOCK_PRESCALER/F_CPU)+1) // +1: add one more us to compensate math round
native/pos do
static bool ceu_wclock_is_active = 0;
void ceu_arduino_callback_wclock_min (s32 dt) {
ceu_wclock_request(dt, ceu_wclock_is_active);
ceu_wclock_is_active = (dt != CEU_WCLOCK_INACTIVE);
ceu_pm_set(CEU_PM_WCLOCK, ceu_wclock_is_active);
}
s32 ceu_arduino_callback_wclock_dt (void) {
return (ceu_wclock_is_active) ? ceu_wclock_dt() : CEU_WCLOCK_INACTIVE;
}
end
{
ceu_wclock_init();
}
///////////////////////////////////////////////////////////////////////////////
// INPUT / OUTPUT
///////////////////////////////////////////////////////////////////////////////
input none CEU_WCLOCK;
spawn async/isr [CEU_WCLOCK_IRQ_N, 0] do
{ceu_wclock_done();}
emit CEU_WCLOCK; // dummy emit to trigger `ceu_input` in env.ino
end