-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathGPIO.pas
160 lines (134 loc) · 3.88 KB
/
GPIO.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
(*
说明:全志A20的GPIO底层操作封装类。分为两个部分:
1.TGPIOGROUP类,可对寄存器直接操作,单例;
2.TGPIO类,对具体的Pin实现了一些功能的简化。
作者:tjCFeng
更新日期:2014.12.06
*)
unit GPIO;
{$mode objfpc}{$H+}
interface
uses A20, Clock;
type
TPort = (PA, PB, PC, PD, PE, PF, PG, PH, PI); //PS:DRAM
TFun = (Fun0, Fun1, Fun2, Fun3, Fun4, Fun5, Fun6, Fun7); //Fun0:Input; Fun1:Output
TDrv = (Level0, Level1, Level2, Level3);
TPull = (PULL_OFF, PULL_UP, PULL_DOWN);
TGPIOGROUP = class
private
FPort: TPort;
FGPIO_BASE: ^LongWord;
protected
FGPIO_CFG: TGROUP4_REG;
FGPIO_DAT: TGROUP1_REG;
FGPIO_DRV: TGROUP2_REG;
FGPIO_PUL: TGROUP2_REG;
public
constructor Create(Port: TPort);
destructor Destroy; override;
public
property GPIO_CFG: TGROUP4_REG read FGPIO_CFG;
property GPIO_DAT: TGROUP1_REG read FGPIO_DAT;
property GPIO_DRV: TGROUP2_REG read FGPIO_DRV;
property GPIO_PUL: TGROUP2_REG read FGPIO_PUL;
end;
TGPIO = class(TGPIOGROUP)
private
FPin: Byte;
FPinBit: LongWord;
FPIN_CFG: ^LongWord;
FPIN_DAT: ^LongWord;
FPIN_DRV: ^LongWord;
FPIN_PUL: ^LongWord;
protected
procedure SetFun(Fun: TFun);
procedure SetDrv(Drv: TDrv);
procedure SetPull(Pull: TPull);
procedure SetData(Level: Boolean);
function GetData: Boolean;
public
constructor Create(Port: TPort; Pin: Byte);
procedure Reverse;
public
property Fun: TFun write SetFun;
property Drv: TDrv write SetDrv;
property Pull: TPull write SetPull;
property Data: Boolean read GetData write SetData;
end;
implementation
const
PIO_BASE = $01C20800;
(*GPIO Group*******************************************************************)
constructor TGPIOGROUP.Create(Port: TPort);
var Base: LongWord;
begin
inherited Create;
FPort:= Port;
FGPIO_BASE:= TA20.Instance.GetMMap(PIO_BASE);
Base:= LongWord(FGPIO_BASE) + TA20.Instance.BaseOffset(PIO_BASE) + (Ord(FPort) * $24);
FGPIO_CFG[0]:= Pointer(Base + $00);
FGPIO_CFG[1]:= Pointer(Base + $04);
FGPIO_CFG[2]:= Pointer(Base + $08);
FGPIO_CFG[3]:= Pointer(Base + $0C);
FGPIO_DAT:= Pointer(Base + $10);
FGPIO_DRV[0]:= Pointer(Base + $14);
FGPIO_DRV[1]:= Pointer(Base + $18);
FGPIO_PUL[0]:= Pointer(Base + $1C);
FGPIO_PUL[1]:= Pointer(Base + $20);
TCCU.Instance.CLK_SetGPIO(True);
end;
destructor TGPIOGROUP.Destroy;
begin
TA20.Instance.FreeMMap(FGPIO_BASE);
inherited Destroy;
end;
(*GPIO Pin*********************************************************************)
constructor TGPIO.Create(Port: TPort; Pin: Byte);
begin
inherited Create(Port);
FPort:= Port;
FPin:= Pin;
FPinBit:= ($1 shl FPin);
FPIN_CFG:= FGPIO_CFG[FPin div 8];
FPIN_DAT:= FGPIO_DAT;
FPIN_DRV:= FGPIO_DRV[FPin div 16];
FPIN_PUL:= FGPIO_PUL[FPin div 16];
end;
procedure TGPIO.SetFun(Fun: TFun);
var PinN: Byte;
begin
PinN:= (FPin mod 8) * 4;
FPIN_CFG^:= FPIN_CFG^ and not ($7 shl PinN);
FPIN_CFG^:= FPIN_CFG^ or (Ord(Fun) shl PinN);
end;
procedure TGPIO.SetDrv(Drv: TDrv);
var PinN: Byte;
begin
PinN:= (FPin mod 16) * 2;
FPIN_DRV^:= FPIN_DRV^ and not ($3 shl PinN);
FPIN_DRV^:= FPIN_DRV^ or (Ord(Drv) shl PinN);
end;
procedure TGPIO.SetPull(Pull: TPull);
var PinN: Byte;
begin
PinN:= (FPin mod 16) * 2;
FPIN_PUL^:= FPIN_PUL^ and not ($3 shl PinN);
FPIN_PUL^:= FPIN_PUL^ or (Ord(Pull) shl PinN);
end;
procedure TGPIO.SetData(Level: Boolean);
begin
case Level of
False: FPIN_DAT^:= FPIN_DAT^ and not FPinBit;
True: FPIN_DAT^:= FPIN_DAT^ or FPinBit;
end;
end;
function TGPIO.GetData: Boolean;
begin
Result:= ((FPIN_DAT^ and FPinBit) = FPinBit);
end;
procedure TGPIO.Reverse;
begin
FPIN_DAT^:= FPIN_DAT^ xor FPinBit;
end;
end.