Skip to content

Commit 21e9f11

Browse files
committed
gpio wip
1 parent 80d939c commit 21e9f11

File tree

5 files changed

+459
-1
lines changed

5 files changed

+459
-1
lines changed

src/devices/RP2040/rp-clock.adb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ package body RP.Clock is
102102
end record;
103103

104104
CLOCKS : CLOCKS_Peripheral
105-
with Import, Address => System'To_Address (16#4001_0000#);
105+
with Import, Address => System'To_Address (16#4000_8000#);
106106

107107
procedure Set_Divider
108108
(GP : GP_Output;

src/devices/RP2040/rp-gpio.adb

Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
--
2+
-- Copyright 2021-2026 (C) Jeremy Grosser
3+
--
4+
-- SPDX-License-Identifier: BSD-3-Clause
5+
--
6+
with System;
7+
with HAL; use HAL;
8+
9+
package body RP.GPIO is
10+
11+
type IO_Register is record
12+
STATUS : UInt32 := 0;
13+
CTRL : UInt32 := 16#0000_001F#;
14+
end record
15+
with Volatile, Object_Size => 64;
16+
for IO_Register use record
17+
STATUS at 0 range 0 .. 31;
18+
CTRL at 4 range 0 .. 31;
19+
end record;
20+
21+
type IO_Array is array (GPIO_Pin) of IO_Register
22+
with Volatile, Component_Size => 64;
23+
24+
type IO_BANK_Peripheral is record
25+
GPIO : IO_Array;
26+
end record
27+
with Volatile;
28+
for IO_BANK_Peripheral use record
29+
GPIO at 0 range 0 .. 1919;
30+
end record;
31+
32+
type PAD_Register is record
33+
OD : Boolean := False;
34+
IE : Boolean := False;
35+
DRIVE : UInt2 := 1;
36+
PUE : Boolean := False;
37+
PDE : Boolean := True;
38+
SCHMITT : Boolean := True;
39+
SLEWFAST : Boolean := False;
40+
end record
41+
with Volatile_Full_Access,
42+
Effective_Writes,
43+
Async_Readers,
44+
Object_Size => 32;
45+
for PAD_Register use record
46+
OD at 0 range 7 .. 7;
47+
IE at 0 range 6 .. 6;
48+
DRIVE at 0 range 4 .. 5;
49+
PUE at 0 range 3 .. 3;
50+
PDE at 0 range 2 .. 2;
51+
SCHMITT at 0 range 1 .. 1;
52+
SLEWFAST at 0 range 0 .. 0;
53+
end record;
54+
55+
type PAD_Array is array (GPIO_Pin) of PAD_Register
56+
with Volatile, Component_Size => 32;
57+
58+
type PADS_BANK_Peripheral is record
59+
VOLTAGE_SELECT : UInt32 := 0;
60+
GPIO : PAD_Array;
61+
end record
62+
with Volatile;
63+
for PADS_BANK_Peripheral use record
64+
VOLTAGE_SELECT at 0 range 0 .. 31;
65+
GPIO at 4 range 0 .. 959;
66+
end record;
67+
68+
type SIO_Array is array (GPIO_Pin) of Boolean
69+
with Volatile,
70+
Component_Size => 1,
71+
Object_Size => 32;
72+
73+
type SIO_Peripheral is record
74+
GPIO_IN : SIO_Array;
75+
GPIO_OUT : SIO_Array;
76+
GPIO_OUT_SET : SIO_Array;
77+
GPIO_OUT_CLR : SIO_Array;
78+
GPIO_OUT_XOR : SIO_Array;
79+
GPIO_OE : SIO_Array;
80+
GPIO_OE_SET : SIO_Array;
81+
GPIO_OE_CLR : SIO_Array;
82+
GPIO_OE_XOR : SIO_Array;
83+
end record
84+
with Volatile;
85+
for SIO_Peripheral use record
86+
GPIO_IN at 16#004# range 0 .. 31;
87+
GPIO_OUT at 16#010# range 0 .. 31;
88+
GPIO_OUT_SET at 16#014# range 0 .. 31;
89+
GPIO_OUT_CLR at 16#018# range 0 .. 31;
90+
GPIO_OUT_XOR at 16#01C# range 0 .. 31;
91+
GPIO_OE at 16#020# range 0 .. 31;
92+
GPIO_OE_SET at 16#024# range 0 .. 31;
93+
GPIO_OE_CLR at 16#028# range 0 .. 31;
94+
GPIO_OE_XOR at 16#02C# range 0 .. 31;
95+
end record;
96+
97+
IO_BANK : IO_BANK_Peripheral
98+
with Import, Address => System'To_Address (16#4001_4000#);
99+
PADS_BANK : PADS_BANK_Peripheral
100+
with Import, Address => System'To_Address (16#4001_C000#);
101+
SIO_BANK : SIO_Peripheral
102+
with Import, Address => System'To_Address (16#D000_0000#);
103+
104+
procedure Drive
105+
(Pin : GPIO_Pin;
106+
Current : GPIO_Drive := 1)
107+
is
108+
begin
109+
if Current = 0 then
110+
PADS_BANK.GPIO (Pin).OD := True;
111+
else
112+
PADS_BANK.GPIO (Pin).DRIVE := UInt2 (Current - 1);
113+
PADS_BANK.GPIO (Pin).OD := False;
114+
end if;
115+
end Drive;
116+
117+
procedure Func
118+
(Pin : GPIO_Pin;
119+
Func : GPIO_Function)
120+
is
121+
begin
122+
IO_BANK.GPIO (Pin).CTRL := UInt32 (Func);
123+
end Func;
124+
125+
procedure Pull
126+
(Pin : GPIO_Pin;
127+
Up : Boolean := False;
128+
Down : Boolean := False)
129+
is
130+
begin
131+
PADS_BANK.GPIO (Pin).PUE := Up;
132+
PADS_BANK.GPIO (Pin).PDE := Down;
133+
end Pull;
134+
135+
procedure Output_Enable
136+
(Pin : GPIO_Pin;
137+
Enable : Boolean := True)
138+
is
139+
begin
140+
if Enable then
141+
SIO_BANK.GPIO_OE_SET (Pin) := True;
142+
else
143+
SIO_BANK.GPIO_OE_CLR (Pin) := True;
144+
end if;
145+
end Output_Enable;
146+
147+
procedure Set
148+
(Pin : GPIO_Pin;
149+
High : Boolean := True)
150+
is
151+
begin
152+
if High then
153+
SIO_BANK.GPIO_OUT_SET (Pin) := True;
154+
else
155+
SIO_BANK.GPIO_OUT_CLR (Pin) := True;
156+
end if;
157+
end Set;
158+
159+
procedure Input_Enable
160+
(Pin : GPIO_Pin;
161+
Enable : Boolean := True)
162+
is
163+
begin
164+
PADS_BANK.GPIO (Pin).IE := Enable;
165+
end Input_Enable;
166+
167+
procedure Get
168+
(Pin : GPIO_Pin;
169+
High : out Boolean)
170+
is
171+
begin
172+
High := SIO_BANK.GPIO_IN (Pin);
173+
end Get;
174+
175+
procedure Configure
176+
(This : GPIO_Point;
177+
Mode : GPIO_Config_Mode;
178+
Pull : GPIO_Pull_Mode := Floating;
179+
Func : GPIO_Function := SIO;
180+
Schmitt : Boolean := False;
181+
Slew_Fast : Boolean := False;
182+
Drive : GPIO_Drive := Drive_2mA)
183+
is
184+
begin
185+
case Mode is
186+
when Output =>
187+
SIO_BANK.GPIO_OE_SET (This.Pin) := True;
188+
IO_BANK.GPIO (This.Pin).CTRL := UInt32 (Func);
189+
PADS_BANK.GPIO (This.Pin) :=
190+
(OD => False,
191+
IE => False,
192+
DRIVE => UInt2 (Drive - 1),
193+
PUE => (Pull = Pull_Up or else Pull = Pull_Both),
194+
PDE => (Pull = Pull_Down or else Pull = Pull_Both),
195+
SCHMITT => Schmitt,
196+
SLEWFAST => Slew_Fast);
197+
when Input =>
198+
SIO_BANK.GPIO_OE_CLR (This.Pin) := True;
199+
IO_BANK.GPIO (This.Pin).CTRL := UInt32 (Func);
200+
PADS_BANK.GPIO (This.Pin) :=
201+
(OD => False,
202+
IE => True,
203+
DRIVE => 0,
204+
PUE => (Pull = Pull_Up or else Pull = Pull_Both),
205+
PDE => (Pull = Pull_Down or else Pull = Pull_Both),
206+
SCHMITT => Schmitt,
207+
SLEWFAST => Slew_Fast);
208+
when Analog =>
209+
SIO_BANK.GPIO_OE_CLR (This.Pin) := True;
210+
IO_BANK.GPIO (This.Pin).CTRL := 0;
211+
PADS_BANK.GPIO (This.Pin) :=
212+
(OD => True,
213+
IE => False,
214+
DRIVE => 0,
215+
PUE => False,
216+
PDE => False,
217+
SCHMITT => False,
218+
SLEWFAST => False);
219+
end case;
220+
end Configure;
221+
222+
overriding
223+
function Support
224+
(This : GPIO_Point;
225+
Capa : HAL.GPIO.Capability)
226+
return Boolean
227+
is (True);
228+
229+
overriding
230+
function Mode
231+
(This : GPIO_Point)
232+
return HAL.GPIO.GPIO_Mode
233+
is
234+
begin
235+
if IO_BANK.GPIO (This.Pin).CTRL /= UInt32 (SIO) then
236+
return HAL.GPIO.Unknown_Mode;
237+
end if;
238+
239+
if SIO_BANK.GPIO_OE (This.Pin) then
240+
return HAL.GPIO.Output;
241+
else
242+
return HAL.GPIO.Input;
243+
end if;
244+
end Mode;
245+
246+
overriding
247+
procedure Set_Mode
248+
(This : in out GPIO_Point;
249+
Mode : HAL.GPIO.GPIO_Config_Mode)
250+
is
251+
use type HAL.GPIO.GPIO_Config_Mode;
252+
begin
253+
IO_BANK.GPIO (This.Pin).CTRL := UInt32 (SIO);
254+
PADS_BANK.GPIO (This.Pin).OD := Mode = HAL.GPIO.Input;
255+
PADS_BANK.GPIO (This.Pin).IE := Mode = HAL.GPIO.Input;
256+
SIO_BANK.GPIO_OE (This.Pin) := Mode = HAL.GPIO.Output;
257+
end Set_Mode;
258+
259+
overriding
260+
function Pull_Resistor
261+
(This : GPIO_Point)
262+
return HAL.GPIO.GPIO_Pull_Resistor
263+
is
264+
Pad : constant PAD_Register := PADS_BANK.GPIO (This.Pin);
265+
begin
266+
if Pad.PUE then
267+
return HAL.GPIO.Pull_Up;
268+
elsif Pad.PDE then
269+
return HAL.GPIO.Pull_Down;
270+
else
271+
return HAL.GPIO.Floating;
272+
end if;
273+
end Pull_Resistor;
274+
275+
overriding
276+
procedure Set_Pull_Resistor
277+
(This : in out GPIO_Point;
278+
Pull : HAL.GPIO.GPIO_Pull_Resistor)
279+
is
280+
use type HAL.GPIO.GPIO_Pull_Resistor;
281+
begin
282+
PADS_BANK.GPIO (This.Pin).PUE := (Pull = HAL.GPIO.Pull_Up);
283+
PADS_BANK.GPIO (This.Pin).PDE := (Pull = HAL.GPIO.Pull_Down);
284+
end Set_Pull_Resistor;
285+
286+
overriding
287+
function Set
288+
(This : GPIO_Point)
289+
return Boolean
290+
is (SIO_BANK.GPIO_IN (This.Pin));
291+
292+
overriding
293+
procedure Set
294+
(This : in out GPIO_Point)
295+
is
296+
begin
297+
SIO_BANK.GPIO_OUT_SET (This.Pin) := True;
298+
end Set;
299+
300+
overriding
301+
procedure Clear
302+
(This : in out GPIO_Point)
303+
is
304+
begin
305+
SIO_BANK.GPIO_OUT_CLR (This.Pin) := True;
306+
end Clear;
307+
308+
overriding
309+
procedure Toggle
310+
(This : in out GPIO_Point)
311+
is
312+
begin
313+
SIO_BANK.GPIO_OUT_XOR (This.Pin) := True;
314+
end Toggle;
315+
316+
end RP.GPIO;

0 commit comments

Comments
 (0)