forked from tjCFeng/ClassA20
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LRADC.pas
182 lines (150 loc) · 4.34 KB
/
LRADC.pas
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
(*
说明:全志A20的LRADC底层操作封装类。分为两个部分:
1.TLRADCGROUP类,可对寄存器直接操作,单例;
2.TLRADC类,对具体的LRADC通道实现了一些功能的简化。
作者:tjCFeng
更新日期:2014.12.06
*)
unit LRADC;
{$mode objfpc}{$H+}
interface
uses SysUtils, A20;
type
TChannel = (LRADC_0, LRADC_1);
TLRADCINT = (ADCDATA, KEYDOWN, HOLD, ALRDYHOLD, KEYUP);
TLRADCINTs = set of TLRADCINT;
TLRADCGROUP = class
private
class var FInstance: TLRADCGROUP;
class function GetInstance: TLRADCGROUP; static;
public
class procedure Release;
class property Instance: TLRADCGROUP read GetInstance;
private
FLRADC_BASE: ^LongWord;
FLRADC_CTRL: TGROUP1_REG;
FLRADC_INTC: TGROUP1_REG;
FLRADC_INTS: TGROUP1_REG;
FLRADC_DATA: TGROUP2_REG;
constructor Create;
destructor Destroy; override;
public
procedure Start;
procedure Stop;
procedure ClearAllPending;
public
property LRADC_CTRL: TGROUP1_REG read FLRADC_CTRL;
property LRADC_INTC: TGROUP1_REG read FLRADC_INTC;
property LRADC_INTS: TGROUP1_REG read FLRADC_INTS;
property LRADC_DATA: TGROUP2_REG read FLRADC_DATA;
end;
TLRADC = class
private
FChannel: TChannel;
FINTs: TLRADCINTs;
FLRADC_DATA: ^LongWord;
private
procedure SetINTs(INTs: TLRADCINTs);
function GetDATA: Byte;
public
constructor Create(Channel: TChannel);
function GetStatus(INT: TLRADCINT): Boolean;
procedure ClearPendings(INTs: TLRADCINTs);
public
property Channel: TChannel read FChannel;
property INTs: TLRADCINTs read FINTs write SetINTs default [];
property Data: Byte read GetDATA;
end;
implementation
const
LRADC_BASE = $01C22800;
(*LRADC Group******************************************************************)
class function TLRADCGROUP.GetInstance: TLRADCGROUP;
begin
if FInstance = nil then FInstance:= TLRADCGROUP.Create;
Result:= FInstance;
end;
class procedure TLRADCGROUP.Release;
begin
FreeAndNil(FInstance);
end;
constructor TLRADCGROUP.Create;
var Base: LongWord;
begin
inherited Create;
FLRADC_BASE:= TA20.Instance.GetMMap(LRADC_BASE);
Base:= LongWord(FLRADC_BASE) + TA20.Instance.BaseOffset(LRADC_BASE);
FLRADC_CTRL:= Pointer(Base + $00);
FLRADC_INTC:= Pointer(Base + $04);
FLRADC_INTS:= Pointer(Base + $08);
FLRADC_DATA[0]:= Pointer(Base + $0C);
FLRADC_DATA[1]:= Pointer(Base + $10);
end;
destructor TLRADCGROUP.Destroy;
begin
TA20.Instance.FreeMMap(FLRADC_BASE);
inherited Destroy;
end;
procedure TLRADCGROUP.Start;
begin
FLRADC_CTRL^:= FLRADC_CTRL^ or ($1 shl 0);
end;
procedure TLRADCGROUP.Stop;
begin
FLRADC_CTRL^:= FLRADC_CTRL^ and not ($1 shl 0);
end;
procedure TLRADCGROUP.ClearAllPending;
begin
FLRADC_INTS^:= $00001F1F;
end;
(*LRADC Channel****************************************************************)
constructor TLRADC.Create(Channel: TChannel);
begin
inherited Create;
FChannel:= Channel;
FLRADC_DATA:= TLRADCGROUP.Instance.LRADC_DATA[Ord(FChannel)];
end;
function TLRADC.GetDATA: Byte;
begin
Result:= Byte(FLRADC_DATA^);
end;
function TLRADC.GetStatus(INT: TLRADCINT): Boolean;
var INTBIT: LongWord;
begin
INTBIT:= Ord(FChannel) * 8 + Ord(INT);
Result:= (TLRADCGROUP.Instance.LRADC_INTS^ and INTBIT) = INTBIT;
end;
procedure TLRADC.SetINTs(INTs: TLRADCINTs);
procedure SetINT(IndexINT: Byte; ED: Boolean);
begin
with TLRADCGROUP.Instance do
if ED then
LRADC_INTC^:= LRADC_INTC^ or ($1 shl (Ord(FChannel) * 8) + IndexINT)
else
LRADC_INTC^:= LRADC_INTC^ and not ($1 shl (Ord(FChannel) * 8) + IndexINT);
end;
begin
FINTs:= INTs;
SetINT(Ord(ADCDATA), ADCDATA in INTs);
SetINT(Ord(KEYDOWN), KEYDOWN in INTs);
SetINT(Ord(HOLD), HOLD in INTs);
SetINT(Ord(ALRDYHOLD), ALRDYHOLD in INTs);
SetINT(Ord(KEYUP), KEYUP in INTs);
end;
procedure TLRADC.ClearPendings(INTs: TLRADCINTs);
procedure ClearPending(IndexINT: Byte);
begin
with TLRADCGROUP.Instance do
LRADC_INTS^:= LRADC_INTS^ or ($1 shl Ord(FChannel) * 8 + IndexINT);
end;
begin
if (ADCDATA in INTs) then ClearPending(Ord(DATA));
if (KEYDOWN in INTs) then ClearPending(Ord(KEYDOWN));
if (HOLD in INTs) then ClearPending(Ord(HOLD));
if (ALRDYHOLD in INTs) then ClearPending(Ord(ALRDYHOLD));
if (KEYUP in INTs) then ClearPending(Ord(KEYUP));
end;
finalization
TLRADCGROUP.Instance.Release;
end.