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 | ---------------------------------------------------------------------------
-- The AVR-Ada Library is free software; you can redistribute it and/or --
-- modify it under terms of the GNU General Public License as published --
-- by the Free Software Foundation; either version 2, or (at your --
-- option) any later version. The AVR-Ada Library is distributed in the --
-- hope that it will be useful, but WITHOUT ANY WARRANTY; without even --
-- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR --
-- PURPOSE. See the GNU General Public License for more details. --
-- --
-- As a special exception, if other files instantiate generics from this --
-- unit, or you link this unit with other files to produce an --
-- executable this unit does not by itself cause the resulting --
-- executable to be covered by the GNU General Public License. This --
-- exception does not however invalidate any other reasons why the --
-- executable file might be covered by the GNU Public License. --
---------------------------------------------------------------------------
-- Make the program wait for the specified amount of time. This can only
-- work, if the routines are properly inlined avoiding the call overhead.
-- As these routines do a busy wait, any interupt will add to the delay.
-- For delays of more than a few milliseconds (and even there) a timer
-- triggerd delay is preferable.
with System.Machine_Code; use System.Machine_Code;
with Interfaces; use Interfaces;
package body AVR.Wait is
procedure Wait_3_Cycles (Count : Unsigned_8) is
Dummy : Unsigned_8;
begin
if Count > 0 then
Asm ("1: dec %0" & ASCII.LF &
"brne 1b",
Outputs => Unsigned_8'Asm_Output ("=r", Dummy),
Inputs => Unsigned_8'Asm_Input ("0", Count),
Volatile => True);
end if;
end Wait_3_Cycles;
procedure Wait_4_Cycles (Count : Unsigned_16) is
Dummy : Unsigned_16;
begin
if Count > 0 then
Asm ("1: sbiw %0,1" & ASCII.LF &
"brne 1b",
Outputs => Unsigned_16'Asm_Output ("=w", Dummy),
Inputs => Unsigned_16'Asm_Input ("0", Count),
Volatile => True);
end if;
end Wait_4_Cycles;
procedure Generic_Wait_USecs is
-- time for four cycles measured in pico seconds
Cycle_Length : constant Long_Long_Integer :=
1_000_000_000_000 / Crystal_Hertz;
Cycles_To_Wait : constant Unsigned_32
:= Unsigned_32 ((Micro_Seconds * 1_000_000) / Cycle_Length);
begin
Wait_Cycles (Cycles_To_Wait);
end Generic_Wait_USecs;
procedure Generic_Wait_NSecs is
-- time for one cycle measured in pico seconds
Cycle_Length : constant Long_Long_Integer :=
1_000_000_000_000 / Crystal_Hertz;
Cycles_To_Wait : constant Unsigned_32
:= Unsigned_32 ((Nano_Seconds * 1_000) / Cycle_Length);
begin
Wait_Cycles (Cycles_To_Wait);
end Generic_Wait_NSecs;
procedure Generic_Busy_Wait_Milliseconds (Wait : Unsigned_16)
is
procedure Wait_1ms is new Generic_Wait_USecs
(Crystal_Hertz => Crystal_Hertz,
Micro_Seconds => 1000);
begin
for I in 1 .. Wait loop
Wait_1ms;
end loop;
end Generic_Busy_Wait_Milliseconds;
procedure Generic_Busy_Wait_Seconds (Wait : Unsigned_16)
is
procedure Wait_1sec is new Generic_Busy_Wait_Milliseconds
(Crystal_Hertz => Crystal_Hertz);
begin
for I in 1 .. Wait loop
Wait_1sec (1000);
end loop;
end Generic_Busy_Wait_Seconds;
end AVR.Wait;
|