Mistake on this page?
Report an issue in GitHub or email us
USBPhy.h
1 /*
2  * Copyright (c) 2018-2019, Arm Limited and affiliates.
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef USBPHY_H
19 #define USBPHY_H
20 
21 #include "USBPhyTypes.h"
22 #include "USBPhyEvents.h"
23 
24 /** Abstract interface to physical USB hardware
25  *
26  * # Defined behavior
27  * * You can use any endpoint configurations that fit in the parameters
28  * of the table returned by USBPhy::endpoint_table.
29  * * You can use all endpoints in any valid endpoint configuration concurrently.
30  * * The device supports use of at least one control, bulk, interrupt and
31  * isochronous in each direction at the same time - at least 8 endpoints.
32  * * USBPhy supports all standard endpoint sizes (wMaxPacketSize).
33  * * USBPhy can handle an interrupt latency of at least 100ms if the host PC
34  * is not performing a reset or setting the device's address.
35  * * USBPhy only sends USBPhyEvents when it is in the initialized state.
36  * * When unpowered, USBPhy only sends the USBPhyEvents::power event.
37  * * On USB reset, all endpoints are removed except for endpoint 0.
38  * * A call to USBPhy::ep0_write results in the call of USBPhyEvents::in when
39  * the PC reads the data unless a power loss, reset, or a call to
40  * USBPhy::disconnect occurs first.
41  * * A call to USBPhy::endpoint_write results in the call of USBPhyEvents::in
42  * when the pc reads the data unless a power loss, reset, or a call to
43  * USBPhy::endpoint_abort occurs first.
44  * * A call to USBPhy::endpoint_read results in the call of USBPhyEvents::out
45  * when the pc sends data unless a power loss, reset, or a call to
46  * USBPhy::endpoint_abort occurs first.
47  * * Endpoint 0 naks all transactions aside from setup packets until
48  * higher-level code calls one of USBPhy::ep0_read, USBPhy::ep0_write or
49  * USBPhy::ep0_stall.
50  * * Endpoint 0 stall automatically clears on reception of a setup packet.
51  *
52  * # Undefined behavior
53  * * Calling USBPhy::endpoint_add or USBPhy::endpoint_remove outside of the
54  * control requests SetInterface or SetConfiguration.
55  * * Calling USBPhy::endpoint_remove on an endpoint that has an ongoing read
56  * or write operation. To avoid undefined behavior, you must abort ongoing
57  * operations with USBPhy::endpoint_abort.
58  * * Devices behavior is undefined if latency is greater than 2ms when address
59  * is being set - see USB spec 9.2.6.3.
60  * * Devices behavior is undefined if latency is greater than 10ms when a
61  * reset occurs - see USB spec 7.1.7.5.
62  * * Calling any of the USBPhy::endpoint_* functions on endpoint 0.
63  *
64  * # Notes
65  * * Make sure USBPhy sends USBPhyEvents in the correct order when multiple
66  * packets are present. USBPhy must send IN endpoint events before OUT
67  * endpoint events if both are pending.
68  * * A host PC may resend setup packets to a USB device if there is noise on
69  * the USB line. The USBPhy should be able to handle this scenario and
70  * respond to the setup packet with an ACK.
71  * * Bidirectional protocols making use of alternating IN and OUT phases
72  * should not rely on the last ACK an IN transfer to indicate that the
73  * OUT phase should start. Instead, the OUT phase should be started at
74  * the same time the last IN transfer is started. This is because the ACK
75  * to the last in transfer may be dropped if there is noise on the USB
76  * line. If dropped, it will only be resent on the next IN phase. You can
77  * find more information on this in section 8.5.3.3 of the USB
78  * specification.
79  *
80  * @ingroup usb_device_core
81  */
82 class USBPhy {
83 public:
84  USBPhy() {};
85  virtual ~USBPhy() {};
86 
87  /**
88  * Initialize this USBPhy instance
89  *
90  * This function must be called before calling
91  * any other functions of this class, unless specifically
92  * noted.
93  *
94  * @param events Callback class to handle USB events
95  */
96  virtual void init(USBPhyEvents *events) = 0;
97 
98  /**
99  * Power down this USBPhy instance
100  *
101  * Disable interrupts and stop sending events.
102  */
103  virtual void deinit() = 0;
104 
105  /**
106  * Check if USB power is present
107  *
108  * Devices which don't support checking the USB power state
109  * must always return true.
110  *
111  * @return true if USB power is present, false otherwise
112  */
113  virtual bool powered() = 0;
114 
115  /**
116  * Make the USB phy visible to the USB host
117  *
118  * Enable either the D+ or D- pullup so the host can detect
119  * the presence of this device.
120  */
121  virtual void connect() = 0;
122 
123  /**
124  * Detach the USB phy
125  *
126  * Disable the D+ and D- pullup and stop responding to
127  * USB traffic.
128  */
129  virtual void disconnect() = 0;
130 
131  /**
132  * Set this device to the configured state
133  *
134  * Enable added endpoints if they are not enabled
135  * already.
136  */
137  virtual void configure() = 0;
138 
139  /**
140  * Leave the configured state
141  *
142  * This is a notification to the USBPhy indicating that the device
143  * is leaving the configured state. The USBPhy can disable all
144  * endpoints other than endpoint 0.
145  *
146  */
147  virtual void unconfigure() = 0;
148 
149  /**
150  * Enable the start of frame interrupt
151  *
152  * Call USBPhyEvents::sof on every frame.
153  */
154  virtual void sof_enable() = 0;
155 
156  /**
157  * Disable the start of frame interrupt
158  *
159  * Stop calling USBPhyEvents::sof.
160  */
161  virtual void sof_disable() = 0;
162 
163  /**
164  * Set the USBPhy's address
165  *
166  * @param address This device's USB address
167  */
168  virtual void set_address(uint8_t address) = 0;
169 
170  /**
171  * Wake upstream devices
172  */
173  virtual void remote_wakeup() = 0;
174 
175  /**
176  * Get the endpoint table
177  *
178  * This function returns a table which describes the endpoints
179  * can be used, the functionality of those endpoints and the
180  * resource cost.
181  */
182  virtual const usb_ep_table_t *endpoint_table() = 0;
183 
184  /**
185  * Set wMaxPacketSize of endpoint 0
186  *
187  * @param max_packet The wMaxPacketSize value for endpoint 0
188  * @return The actual size of endpoint 0
189  */
190  virtual uint32_t ep0_set_max_packet(uint32_t max_packet) = 0;
191 
192  /**
193  * Read the contents of the SETUP packet
194  *
195  * @param buffer Buffer to fill with data
196  * @param size Size of buffer passed in
197  */
198  virtual void ep0_setup_read_result(uint8_t *buffer, uint32_t size) = 0;
199 
200  /**
201  * Start receiving a packet of up to wMaxPacketSize on endpoint 0
202  *
203  * @param data Buffer to fill with the data read
204  * @param size Size of buffer
205  */
206  virtual void ep0_read(uint8_t *data, uint32_t size) = 0;
207 
208  /**
209  * Read the contents of a received packet
210  *
211  * @return Size of data read
212  */
213  virtual uint32_t ep0_read_result() = 0;
214 
215  /**
216  * Write a packet on endpoint 0
217  *
218  * @param buffer Buffer fill with data to send
219  * @param size Size of data to send
220  */
221  virtual void ep0_write(uint8_t *buffer, uint32_t size) = 0;
222 
223  /**
224  * Protocol stall on endpoint 0
225  *
226  * Stall all IN and OUT packets on endpoint 0 until a setup packet
227  * is received.
228  * @note The stall is cleared automatically when a setup packet is received
229  */
230  virtual void ep0_stall() = 0;
231 
232  /**
233  * Configure and enable an endpoint
234  *
235  * @param endpoint Endpoint to configure and enable
236  * @param max_packet The maximum packet size that can be sent or received
237  * @param type The type of endpoint this should be configured as -
238  * USB_EP_TYPE_BULK, USB_EP_TYPE_INT or USB_EP_TYPE_ISO
239  * @note This function cannot be used to configure endpoint 0. That must be done
240  * with ep0_set_max_packet
241  */
242  virtual bool endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type) = 0;
243 
244  /**
245  * Disable an endpoint
246  *
247  * @param endpoint Endpoint to disable
248  */
249  virtual void endpoint_remove(usb_ep_t endpoint) = 0;
250 
251  /**
252  * Perform a functional stall on the given endpoint
253  *
254  * Set the HALT feature for this endpoint so that all further
255  * communication is aborted.
256  *
257  * @param endpoint Endpoint to stall
258  */
259  virtual void endpoint_stall(usb_ep_t endpoint) = 0;
260 
261  /**
262  * Unstall the endpoint
263  *
264  * Clear the HALT feature on this endpoint so communication can
265  * resume.
266  *
267  * @param endpoint Endpoint to stall
268  */
269  virtual void endpoint_unstall(usb_ep_t endpoint) = 0;
270 
271  /**
272  * Start a read on the given endpoint
273  *
274  * @param endpoint Endpoint to start the read on
275  * @param data Buffer to fill with data
276  * @param size Size of the read buffer. This must be at least
277  * the max packet size for this endpoint.
278  * @return true if the read was successfully started, false otherwise
279  */
280  virtual bool endpoint_read(usb_ep_t endpoint, uint8_t *data, uint32_t size) = 0;
281 
282  /**
283  * Finish a read on the given endpoint
284  *
285  * @param endpoint Endpoint to check
286  * @return The number of bytes received
287  */
288  virtual uint32_t endpoint_read_result(usb_ep_t endpoint) = 0;
289 
290  /**
291  * Start a write on the given endpoint
292  *
293  * @param endpoint Endpoint to write to
294  * @param data Buffer to write
295  * @param size Size of data to write
296  * @return true if the data was prepared for transmit, false otherwise
297  */
298  virtual bool endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size) = 0;
299 
300  /**
301  * Abort the current transfer if it has not yet been sent
302  *
303  * @param endpoint Endpoint to abort the transfer on. It is implementation defined
304  * if this function has an effect on receive endpoints.
305  */
306  virtual void endpoint_abort(usb_ep_t endpoint) = 0;
307 
308  /**
309  * Callback used for performing USB processing
310  *
311  * USBPhy processing should be triggered by calling USBPhyEvents::start_process
312  * and done inside process. All USBPhyEvents callbacks aside from
313  * USBPhyEvents::start_process must be called in the context of process
314  */
315  virtual void process() = 0;
316 };
317 
318 #endif
virtual void sof_disable()=0
Disable the start of frame interrupt.
virtual void ep0_setup_read_result(uint8_t *buffer, uint32_t size)=0
Read the contents of the SETUP packet.
virtual uint32_t ep0_read_result()=0
Read the contents of a received packet.
virtual void connect()=0
Make the USB phy visible to the USB host.
virtual uint32_t endpoint_read_result(usb_ep_t endpoint)=0
Finish a read on the given endpoint.
virtual void process()=0
Callback used for performing USB processing.
virtual void endpoint_stall(usb_ep_t endpoint)=0
Perform a functional stall on the given endpoint.
virtual void remote_wakeup()=0
Wake upstream devices.
virtual bool endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size)=0
Start a write on the given endpoint.
virtual void ep0_write(uint8_t *buffer, uint32_t size)=0
Write a packet on endpoint 0.
virtual bool endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type)=0
Configure and enable an endpoint.
Abstract interface to physical USB hardware.
Definition: USBPhy.h:82
virtual const usb_ep_table_t * endpoint_table()=0
Get the endpoint table.
virtual void disconnect()=0
Detach the USB phy.
virtual void sof_enable()=0
Enable the start of frame interrupt.
virtual void configure()=0
Set this device to the configured state.
virtual void init(USBPhyEvents *events)=0
Initialize this USBPhy instance.
virtual void ep0_stall()=0
Protocol stall on endpoint 0.
virtual void endpoint_unstall(usb_ep_t endpoint)=0
Unstall the endpoint.
virtual void ep0_read(uint8_t *data, uint32_t size)=0
Start receiving a packet of up to wMaxPacketSize on endpoint 0.
virtual void endpoint_remove(usb_ep_t endpoint)=0
Disable an endpoint.
virtual void deinit()=0
Power down this USBPhy instance.
virtual void endpoint_abort(usb_ep_t endpoint)=0
Abort the current transfer if it has not yet been sent.
virtual bool powered()=0
Check if USB power is present.
virtual uint32_t ep0_set_max_packet(uint32_t max_packet)=0
Set wMaxPacketSize of endpoint 0.
virtual void unconfigure()=0
Leave the configured state.
Event handler for USBPhy.
Definition: USBPhyEvents.h:31
virtual void set_address(uint8_t address)=0
Set the USBPhy's address.
virtual bool endpoint_read(usb_ep_t endpoint, uint8_t *data, uint32_t size)=0
Start a read on the given endpoint.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.