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 | --
-- Copyright (C) 2021 Jeremy Grosser <jeremy@synack.me>
--
-- SPDX-License-Identifier: BSD-3-Clause
--
with System.Storage_Elements;
with System;
with HAL; use HAL;
with USB.HAL.Device;
with USB;
package RP.USB_Device is
type USB_Device_Controller is new USB.HAL.Device.USB_Device_Controller with private;
overriding
procedure Initialize
(This : in out USB_Device_Controller);
overriding
procedure Start
(This : in out USB_Device_Controller);
overriding
function Poll
(This : in out USB_Device_Controller)
return USB.HAL.Device.UDC_Event;
overriding
procedure Reset
(This : in out USB_Device_Controller);
overriding
function Request_Buffer
(This : in out USB_Device_Controller;
Ep : USB.EP_Addr;
Len : USB.Packet_Size)
return System.Address;
overriding
function Valid_EP_Id
(This : in out USB_Device_Controller;
Ep : USB.EP_Id)
return Boolean;
overriding
procedure EP_Send_Packet
(This : in out USB_Device_Controller;
Ep : USB.EP_Id;
Len : USB.Packet_Size);
overriding
procedure EP_Setup
(This : in out USB_Device_Controller;
Ep : USB.EP_Addr;
Typ : USB.EP_Type);
overriding
procedure EP_Ready_For_Data
(This : in out USB_Device_Controller;
Ep : USB.EP_Id;
Max_Len : USB.Packet_Size;
Ready : Boolean := True);
overriding
procedure EP_Stall
(This : in out USB_Device_Controller;
Ep : USB.EP_Addr;
Set : Boolean := True);
overriding
procedure Set_Address
(This : in out USB_Device_Controller;
Addr : UInt7);
overriding
function Early_Address
(This : USB_Device_Controller)
return Boolean;
private
-- The first 0x100 bytes of DPRAM are control registers. 0x100-0x180 is EP0
-- buffers. The remainder of the 4k DPRAM is allocated to endpoints as needed.
subtype DPRAM_Offset is System.Storage_Elements.Storage_Offset range 16#100# .. 16#FFF#;
type Endpoint_Status is record
Addr : System.Address := System.Null_Address;
Next_PID : Boolean := False;
Buffer_Address : DPRAM_Offset := DPRAM_Offset'Last;
Max_Len : USB.Packet_Size := USB.Packet_Size'First;
end record;
type Endpoint_Status_Array is array (USB.EP_Id, USB.EP_Dir) of Endpoint_Status;
type USB_Device_Controller is new USB.HAL.Device.USB_Device_Controller with record
Next_Buffer : DPRAM_Offset := 16#180#; -- EP0 buffers cannot be allocated, start at EP1
EP_Status : Endpoint_Status_Array := (others => (others => <>));
end record;
use type System.Storage_Elements.Storage_Offset;
function Allocate_Buffer
(This : in out USB_Device_Controller;
Size : Natural)
return DPRAM_Offset
with Pre => Size <= 1024,
Post => Allocate_Buffer'Result >= 16#180#
and (Natural (Allocate_Buffer'Result) + Size) <= Natural (DPRAM_Offset'Last)
and (Natural (Allocate_Buffer'Result) mod 64) = 0;
function Endpoint_Buffer_Address
(Ep : USB.EP_Addr)
return System.Address;
-- See Errata RP2040-E5
procedure Enumeration_Fix
(This : in out USB_Device_Controller);
type Line_States is (SE0, J, K, SE1)
with Size => 2;
function Line_State
(This : in out USB_Device_Controller)
return Line_States;
function Find_First_Set
(A : UInt32)
return Natural;
end RP.USB_Device;
|