Software APIs
dif_usbdev.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_USBDEV_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_USBDEV_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/usbdev/doc/">USB Device</a> Device Interface Functions
11  */
12 
13 #include <stddef.h>
14 #include <stdint.h>
15 
19 
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif // __cplusplus
25 
26 /**
27  * Hardware constants.
28  */
29 #define USBDEV_NUM_ENDPOINTS 12
30 #define USBDEV_MAX_PACKET_SIZE 64
31 // Internal constant that should not be used by clients. Defined here because
32 // it is used in the definition of `dif_usbdev_buffer_pool` below.
33 #define USBDEV_NUM_BUFFERS 32
34 
35 // Constants used for the `dif_usbdev_endpoint_id` direction field.
36 #define USBDEV_ENDPOINT_DIR_IN 1
37 #define USBDEV_ENDPOINT_DIR_OUT 0
38 
39 typedef struct dif_usbdev_endpoint_id {
40  /**
41  * Endpoint number.
42  */
43  unsigned int number : 4;
44  /**
45  * Reserved. Should be zero.
46  */
47  unsigned int reserved : 3;
48  /**
49  * Endpoint direction. 1 = IN endpoint, 0 = OUT endpoint
50  */
51  unsigned int direction : 1;
53 
54 /**
55  * Free buffer pool.
56  *
57  * A USB device has a fixed number of buffers that are used for storing incoming
58  * and outgoing packets and the software is responsible for keeping track of
59  * free buffers. The pool is implemented as a stack for constant-time add and
60  * remove. `top` points to the last free buffer added to the pool. The pool is
61  * full when `top == USBDEV_NUM_BUFFERS - 1` and empty when `top == -1`.
62  */
63 typedef struct dif_usbdev_buffer_pool {
64  uint8_t buffers[USBDEV_NUM_BUFFERS];
65  int8_t top;
67 
68 /**
69  * Buffer types.
70  */
71 typedef enum dif_usbdev_buffer_type {
72  /**
73  * For reading payloads of incoming packets.
74  */
76  /**
77  * For writing payloads of outgoing packets.
78  */
80  /**
81  * Clients must not use a buffer after it is handed over to hardware or
82  * returned to the free buffer pool. This type exists to protect against such
83  * cases.
84  */
87 
88 /**
89  * A USB device buffer.
90  *
91  * This struct represents a USB device buffer that has been provided to a client
92  * in response to a buffer request. Clients should treat instances of this
93  * struct as opaque objects and should pass them to the appropriate functions of
94  * this library to read and write payloads of incoming and outgoing packets,
95  * respectively.
96  *
97  * See also: `dif_usbdev_recv`, `dif_usbdev_buffer_read`,
98  * `dif_usbdev_buffer_request`, `dif_usbdev_buffer_write`,
99  * `dif_usbdev_send`, `dif_usbdev_buffer_return`.
100  */
101 typedef struct dif_usbdev_buffer {
102  /**
103  * Hardware buffer id.
104  */
105  uint8_t id;
106  /**
107  * Byte offset for the next read or write operation.
108  */
109  uint8_t offset;
110  /**
111  * For read buffers: remaining number of bytes to read.
112  * For write buffers: remaining number of bytes that can be written.
113  */
115  /**
116  * Type of this buffer.
117  */
120 
121 /**
122  * Configuration for initializing a USB device.
123  */
124 typedef struct dif_usbdev_config {
125  /**
126  * Activate the single-ended D signal for detecting K and J symbols, for use
127  * with a differential receiver.
128  */
130  /**
131  * Use the TX interface with D and SE0 signals instead of Dp/Dn, for use with
132  * certain transceivers.
133  */
135  /*
136  * Recognize a single SE0 bit as end of packet instead of requiring
137  * two bits.
138  */
139  dif_toggle_t single_bit_eop;
140  /**
141  * Flip the D+/D- pins.
142  */
144  /**
145  * Reference signal generation for clock synchronization.
146  */
149 
150 /**
151  * Configures a USB device with runtime information.
152  *
153  * This function should need to be called once for the lifetime of `handle`.
154  *
155  * @param usbdev A USB device.
156  * @param buffer_pool A USB device buffer pool.
157  * @param config Runtime configuration parameters for a USB device.
158  * @return The result of the operation.
159  */
162  dif_usbdev_buffer_pool_t *buffer_pool,
163  dif_usbdev_config_t config);
164 
165 /**
166  * Fill the available buffer FIFO of a USB device.
167  *
168  * The USB device has a small FIFO (AV FIFO) that stores free buffers for
169  * incoming packets. It is the responsibility of the software to ensure that the
170  * AV FIFO is never empty. If the host tries to send a packet when the AV FIFO
171  * is empty, the USB device will respond with a NAK. While this will typically
172  * cause the host to retry transmission for regular data packets, there are
173  * transactions in the USB protocol during which the USB device is not allowed
174  * to send a NAK. Thus, the software must make sure that the AV FIFO is never
175  * empty by calling this function periodically.
176  *
177  * @param usbdev A USB device.
178  * @param buffer_pool A USB device buffer pool.
179  * @return The result of the operation.
180  */
183  const dif_usbdev_t *usbdev, dif_usbdev_buffer_pool_t *buffer_pool);
184 
185 /**
186  * Enable or disable reception of SETUP packets for an endpoint.
187  *
188  * This controls whether the pair of IN and OUT endpoints with the specified
189  * endpoint number are control endpoints.
190  *
191  * @param usbdev A USB device.
192  * @param endpoint An endpoint number.
193  * @param new_state New SETUP packet reception state.
194  * @return The result of the operation.
195  */
198  uint8_t endpoint,
199  dif_toggle_t new_state);
200 
201 /**
202  * Enable or disable reception of OUT packets for an active endpoint.
203  *
204  * When disabling reception of OUT packets, what the endpoint will do depends
205  * on other factors. If the endpoint is currently configured as a control
206  * endpoint (receives SETUP packets) or it is configured as an isochronous
207  * endpoint, disabling reception of OUT packets will cause them to be ignored.
208  *
209  * If the endpoint is neither a control nor isochronous endpoint, then its
210  * behavior depends on whether it is configured to respond with STALL. If the
211  * STALL response is not active, then disabling reception will cause usbdev to
212  * NAK the packet. Otherwise, the STALL response takes priority, regardless of
213  * the setting here.
214  *
215  * @param usbdev A USB device.
216  * @param endpoint An OUT endpoint number.
217  * @param new_state New OUT packet reception state.
218  * @return The result of the operation.
219  */
222  uint8_t endpoint,
223  dif_toggle_t new_state);
224 
225 /**
226  * Enable or disable clearing the out_enable bit after completion of an OUT
227  * transaction to an endpoint.
228  *
229  * If set_nak_out is enabled, an OUT endpoint will disable reception of OUT
230  * packets after each successful OUT transaction to that endpoint, requiring a
231  * call to `dif_usbdev_endpoint_out_enable()` to enable reception again.
232  *
233  * @param usbdev A USB device.
234  * @param endpoint An OUT endpoint number.
235  * @param new_state New set_nak_on_out state.
236  * @return The result of the operation.
237  */
240  uint8_t endpoint,
241  dif_toggle_t new_state);
242 
243 /**
244  * Enable or disable STALL for an endpoint.
245  *
246  * @param usbdev A USB device.
247  * @param endpoint An endpoint ID.
248  * @param new_state New STALL state.
249  * @return The result of the operation.
250  */
253  dif_usbdev_endpoint_id_t endpoint,
254  dif_toggle_t new_state);
255 
256 /**
257  * Get STALL state of an endpoint.
258  *
259  * @param usbdev A USB device.
260  * @param endpoint An endpoint ID.
261  * @param[out] state Current STALL state.
262  * @return The result of the operation.
263  */
266  dif_usbdev_endpoint_id_t endpoint,
267  bool *state);
268 
269 /**
270  * Enable or disable isochronous mode for an endpoint.
271  *
272  * Isochronous endpoints transfer data periodically. Since isochronous transfers
273  * do not have a handshaking stage, isochronous endpoints cannot report errors
274  * or STALL conditions.
275  *
276  * @param usbdev A USB device.
277  * @param endpoint An endpoint.
278  * @param new_state New isochronous state.
279  * @return The result of the operation.
280  */
283  dif_usbdev_endpoint_id_t endpoint,
284  dif_toggle_t new_state);
285 
286 /**
287  * Enable or disable an endpoint.
288  *
289  * An enabled endpoint responds to packets from the host. A disabled endpoint
290  * ignores them.
291  *
292  * @param usbdev A USB device.
293  * @param endpoint An endpoint.
294  * @param new_state New endpoint state.
295  * @return The result of the operation.
296  */
299  dif_usbdev_endpoint_id_t endpoint,
300  dif_toggle_t new_state);
301 
302 /**
303  * Enable the USB interface of a USB device.
304  *
305  * Calling this function causes the USB device to assert the full-speed pull-up
306  * signal to indicate its presence to the host. Ensure the default endpoint is
307  * set up before enabling the interface.
308  *
309  * @param usbdev A USB device.
310  * @param new_state New interface state.
311  * @return The result of the operation.
312  */
315  dif_toggle_t new_state);
316 
317 /**
318  * Information about a received packet.
319  */
321  /**
322  * Endpoint of the packet.
323  */
324  uint8_t endpoint;
325  /**
326  * Payload length in bytes.
327  */
328  uint8_t length;
329  /**
330  * Indicates if the packet is a SETUP packet.
331  */
332  bool is_setup;
334 
335 /**
336  * Get the packet at the front of RX FIFO.
337  *
338  * The USB device has a small FIFO (RX FIFO) that stores received packets until
339  * the software has a chance to process them. It is the responsibility of the
340  * software to ensure that the RX FIFO is never full. If the host tries to send
341  * a packet when the RX FIFO is full, the USB device will respond with a NAK.
342  * While this will typically cause the host to retry transmission for regular
343  * data packets, there are transactions in the USB protocol during which the USB
344  * device is not allowed to send a NAK. Thus, the software must read received
345  * packets as soon as possible.
346  *
347  * Reading received packets involves two main steps:
348  * - Calling this function, i.e. `dif_usbdev_recv`, and
349  * - Calling `dif_usbdev_buffer_read` until the entire packet payload
350  * is read.
351  *
352  * In order to read an incoming packet, clients should first call this function
353  * to get information about the packet and the buffer that holds the packet
354  * payload. Then, clients should call `dif_usbdev_buffer_read` with this buffer
355  * one or more times (depending on the sizes of their internal buffers) until
356  * the entire packet payload is read. Once the entire payload is read, the
357  * buffer is returned to the free buffer pool. If the clients want to ignore the
358  * payload of a packet, e.g. for an unsupported or a zero-length packet, they
359  * can call `dif_usbdev_buffer_return` to immediately return the buffer to the
360  * free buffer pool.
361  *
362  * @param usbdev A USB device.
363  * @param[out] packet_info Packet information.
364  * @param[out] buffer Buffer that holds the packet payload.
365  * @return The result of the operation.
366  */
369  dif_usbdev_rx_packet_info_t *packet_info,
370  dif_usbdev_buffer_t *buffer);
371 
372 /**
373  * Read incoming packet payload.
374  *
375  * Clients should call this function with a buffer provided by `dif_usbdev_recv`
376  * to read the payload of an incoming packet. This function copies the smaller
377  * of `dst_len` and remaining number of bytes in the buffer to `dst`. The buffer
378  * that holds the packet payload is returned to the free buffer pool when the
379  * entire packet payload is read.
380  *
381  * See also: `dif_usbdev_recv`.
382  *
383  * @param usbdev A USB device.
384  * @param buffer_pool A USB device buffer pool.
385  * @param buffer A buffer provided by `dif_usbdev_recv`.
386  * @param[out] dst Destination buffer.
387  * @param dst_len Length of the destination buffer.
388  * @param[out] bytes_written Number of bytes written to destination buffer.
389  * @return The result of the operation.
390  */
393  dif_usbdev_buffer_pool_t *buffer_pool,
394  dif_usbdev_buffer_t *buffer, uint8_t *dst,
395  size_t dst_len, size_t *bytes_written);
396 
397 /**
398  * Return a buffer to the free buffer pool.
399  *
400  * This function immediately returns the given buffer to the free buffer pool.
401  * Since `dif_usbdev_buffer_read` and `dif_usbdev_get_tx_status` return the
402  * buffers that they work on to the free buffer pool automatically, this
403  * function should only be called to discard the payload of a received
404  * packet or a packet that was being prepared for transmission before it is
405  * queued for transmission from an endpoint.
406  *
407  * See also: `dif_usbdev_recv`, `dif_usbdev_buffer_request`.
408  *
409  * @param usbdev A USB device.
410  * @param buffer_pool A USB device buffer pool.
411  * @param buffer A buffer provided by `dif_usbdev_recv` or
412  * `dif_usbdev_buffer_request`.
413  * @return The result of the operation.
414  */
417  dif_usbdev_buffer_pool_t *buffer_pool,
418  dif_usbdev_buffer_t *buffer);
419 
420 /**
421  * Request a buffer for outgoing packet payload.
422  *
423  * Clients should call this function to request a buffer to write the payload of
424  * an outgoing packet. Sending a packet from a particular endpoint to the host
425  * involves four main steps:
426  * - Calling this function, i.e. `dif_usbdev_buffer_request`,
427  * - Calling `dif_usbdev_buffer_write`,
428  * - Calling `dif_usbdev_send`, and
429  * - Calling `dif_usbdev_get_tx_status`.
430  *
431  * In order to send a packet, clients should first call this function to obtain
432  * a buffer for the packet payload. Clients should then call
433  * `dif_usbdev_buffer_write` (one or more times depending on the sizes of their
434  * internal buffers) to write the packet payload to this buffer. After writing
435  * the packet payload, clients should call `dif_usbdev_send` to mark the packet
436  * as ready for transmission from a particular endpoint. Then, clients should
437  * call `dif_usbdev_get_tx_status` to check the status of the transmission.
438  * `dif_usbdev_get_tx_status` returns the buffer that holds the packet payload
439  * to the free buffer pool once the packet is either successfully transmitted or
440  * canceled due to an incoming SETUP packet or a link reset. If the packet
441  * should no longer be sent, clients can call `dif_usbdev_buffer_return` to
442  * return the buffer to the free buffer pool as long as `dif_usbdev_send` is not
443  * called yet.
444  *
445  * See also: `dif_usbdev_buffer_write`, `dif_usbdev_send`,
446  * `dif_usbdev_get_tx_status`, `dif_usbdev_buffer_return`.
447  *
448  * @param usbdev A USB device.
449  * @param buffer_pool A USB device buffer pool.
450  * @param[out] buffer A buffer for writing outgoing packet payload.
451  * @return The result of the operation.
452  */
455  dif_usbdev_buffer_pool_t *buffer_pool,
456  dif_usbdev_buffer_t *buffer);
457 
458 /**
459  * Write outgoing packet payload.
460  *
461  * Clients should call this function with a buffer provided by
462  * `dif_usbdev_buffer_request` to write the payload of an outgoing packet. This
463  * function copies the smaller of `src_len` and remaining number of bytes in the
464  * buffer to the buffer. Clients should then call `dif_usbdev_send` to queue the
465  * packet for transmission from a particular endpoint.
466  *
467  * See also: `dif_usbdev_buffer_request`, `dif_usbdev_send`,
468  * `dif_usbdev_get_tx_status`, `dif_usbdev_buffer_return`.
469  *
470  * @param usbdev A USB device.
471  * @param buffer A buffer provided by `dif_usbdev_buffer_request`.
472  * @param src Source buffer.
473  * @param src_len Length of the source buffer.
474  * @param[out] bytes_written Number of bytes written to the USB device buffer.
475  * @return The result of the operation.
476  */
479  dif_usbdev_buffer_t *buffer,
480  const uint8_t *src, size_t src_len,
481  size_t *bytes_written);
482 
483 /**
484  * Mark a packet ready for transmission from an endpoint.
485  *
486  * The USB device has 12 endpoints, each of which can be used to send packets to
487  * the host. Since a packet is not actually transmitted to the host until the
488  * host sends an IN token, clients must write the packet payload to a device
489  * buffer and mark it as ready for transmission from a particular endpoint. A
490  * packet queued for transmission from a particular endpoint is transmitted once
491  * the host sends an IN token for that endpoint.
492  *
493  * After a packet is queued for transmission, clients should check its status by
494  * calling `dif_usbdev_get_tx_status`. While the USB device handles transmission
495  * errors automatically by retrying transmission, transmission of a packet may
496  * be canceled if the endpoint receives a SETUP packet or the link is reset
497  * before the queued packet is transmitted. In these cases, clients should
498  * handle the SETUP packet or the link reset first and then optionally send the
499  * same packet again. Clients must also make sure that the given endpoint does
500  * not already have a packet pending for transmission before calling this
501  * function.
502  *
503  * See also: `dif_usbdev_buffer_request`, `dif_usbdev_buffer_write`,
504  * `dif_usbdev_get_tx_status`, `dif_usbdev_buffer_return`.
505  *
506  * @param usbdev A USB device.
507  * @param endpoint An OUT endpoint number.
508  * @param buffer A buffer provided by `dif_usbdev_buffer_request`.
509  * @return The result of the operation.
510  */
512 dif_result_t dif_usbdev_send(const dif_usbdev_t *usbdev, uint8_t endpoint,
513  dif_usbdev_buffer_t *buffer);
514 
515 /**
516  * Get which IN endpoints have sent packets.
517  *
518  * This function provides which endpoints have buffers that have successfully
519  * completed transmission to the host. It may be used to guide calls to
520  * `dif_usbdev_clear_tx_status` to return the used buffer to the pool and clear
521  * the state for the next transaction.
522  *
523  * @param usbdev A USB device.
524  * @param[out] sent A bitmap of which endpoints have sent packets.
525  * @return The result of the operation.
526  */
528 dif_result_t dif_usbdev_get_tx_sent(const dif_usbdev_t *usbdev, uint16_t *sent);
529 
530 /**
531  * Clear the TX state of the provided endpoint and restore its associated buffer
532  * to the pool.
533  *
534  * Note that this function should only be called when an endpoint has been
535  * provided a buffer. Without it, the buffer pool will become corrupted, as this
536  * function does not check the status.
537  *
538  * In addition, if the endpoint has not yet completed or canceled the
539  * transaction, the user must not call this function while the device is in an
540  * active state. Otherwise, the user risks corrupting an ongoing transaction.
541  *
542  * @param usbdev A USB device.
543  * @param buffer_pool A USB device buffer pool.
544  * @param endpoint An IN endpoint number.
545  * @return The result of the operation.
546  */
549  dif_usbdev_buffer_pool_t *buffer_pool,
550  uint8_t endpoint);
551 
552 /**
553  * Status of an outgoing packet.
554  */
555 typedef enum dif_usbdev_tx_status {
556  /**
557  * There is no packet for the given OUT endpoint.
558  */
560  /**
561  * Packet is pending transmission.
562  */
564  /**
565  * Packet was sent successfully.
566  */
568  /**
569  * Transmission was canceled due to an incoming SETUP packet.
570  */
573 
574 /**
575  * Get the status of a packet that has been queued to be sent from an endpoint.
576  *
577  * While the USB device handles transmission errors automatically by retrying
578  * transmission, transmission of a packet may be canceled if the endpoint
579  * receives a SETUP packet or the link is reset before the queued packet is
580  * transmitted. In these cases, clients should handle the SETUP packet or the
581  * link reset first and then optionally send the same packet again.
582  *
583  * This function does not modify any device state. `dif_usbdev_clear_tx_status`
584  * can be used to clear the status and return the buffer to the pool.
585  *
586  * @param usbdev A USB device.
587  * @param endpoint An IN endpoint number.
588  * @param[out] status Status of the packet.
589  * @return The result of the operation.
590  */
593  uint8_t endpoint,
595 
596 /**
597  * Set the address of a USB device.
598  *
599  * @param usbdev A USB device.
600  * @param addr New address. Only the last 7 bits are significant.
601  * @return The result of the operation.
602  */
604 dif_result_t dif_usbdev_address_set(const dif_usbdev_t *usbdev, uint8_t addr);
605 
606 /**
607  * Get the address of a USB device.
608  *
609  * @param usbdev A USB device.
610  * @param[out] addr Current address.
611  * @return The result of the operation.
612  */
614 dif_result_t dif_usbdev_address_get(const dif_usbdev_t *usbdev, uint8_t *addr);
615 
616 /**
617  * Read the data toggle bits of the OUT endpoints.
618  *
619  * @param usbdev A USB device.
620  * @param[out]toggles Current state of OUT data toggle bits.
621  * @return The result of the operation.
622  */
625  uint16_t *toggles);
626 
627 /**
628  * Read the data toggle bits of the IN endpoints.
629  *
630  * @param usbdev A USB device.
631  * @param[out]toggles Current state of IN data toggle bits.
632  * @return The result of the operation.
633  */
636  uint16_t *toggles);
637 
638 /**
639  * Write to the data toggle bits of a subset of the OUT endpoints.
640  * Set 1 in `mask` to change the data toggle bit of an OUT endpoint to the value
641  * of the corresponding bit in `state`.
642  *
643  * @param usbdev A USB device.
644  * @param mask Mask of OUT endpoint data toggles to be changed.
645  * @param state New states of that OUT endpoint data toggles being changed.
646  * @return The result of the operation.
647  */
650  uint16_t mask, uint16_t state);
651 
652 /**
653  * Write to the data toggle bits of a subset of the IN endpoints.
654  * Set 1 in `mask` to change the data toggle bit of an IN endpoint to the value
655  * of the corresponding bit in `state`.
656  *
657  * @param usbdev A USB device.
658  * @param mask Mask of IN endpoint data toggles to be changed.
659  * @param state New states of that IN endpoint data toggles being changed.
660  * @return The result of the operation.
661  */
664  uint16_t mask, uint16_t state);
665 
666 /**
667  * Clear the data toggle bits for the selected endpoint.
668  *
669  * @param usbdev A USB device.
670  * @param endpoint An endpoint number.
671  * @return The result of the operation.
672  */
675  uint8_t endpoint);
676 
677 /**
678  * Get USB frame index.
679  *
680  * @param usbdev A USB device.
681  * @param[out] frame_index USB frame index.
682  * @return The result of the operation.
683  */
686  uint16_t *frame_index);
687 
688 /**
689  * Check if the host is lost.
690  *
691  * The host is lost if the link is still active but a start of frame packet has
692  * not been received in the last 4.096ms.
693  *
694  * @param usbdev A USB device.
695  * @param[out] host_lost Status of the host. `true` if the host is lost, `false`
696  * otherwise.
697  * @return The result of the operation.
698  */
701  bool *host_lost);
702 
703 /**
704  * USB link state.
705  */
706 typedef enum dif_usbdev_link_state {
707  kDifUsbdevLinkStateDisconnected,
708  kDifUsbdevLinkStatePowered,
709  kDifUsbdevLinkStatePoweredSuspended,
710  kDifUsbdevLinkStateActive,
711  kDifUsbdevLinkStateSuspended,
712  kDifUsbdevLinkStateActiveNoSof,
713  kDifUsbdevLinkStateResuming,
715 
716 /**
717  * Get USB link state.
718  *
719  * @param usbdev A USB device.
720  * @param[out] link_state USB link state.
721  * @return The result of the operation.
722  */
725  const dif_usbdev_t *usbdev, dif_usbdev_link_state_t *link_state);
726 
727 /**
728  * Get the state of the sense pin.
729  *
730  * @param usbdev A USB device.
731  * @param[out] sense State of the sense pin. `true` if the host is providing
732  * VBUS, `false` otherwise.
733  * @return The result of the operation.
734  */
737  bool *sense);
738 
739 /**
740  * Get the depths of the AV OUT and AV SETUP FIFOs.
741  *
742  * See also: `dif_usbdev_fill_available_fifos`.
743  *
744  * @param usbdev A USB device.
745  * @param[out] setup_depth Depth of the AV SETUP FIFO.
746  * @param[out] out_depth Depth of the AV OUT FIFO.
747  * @return The result of the operation.
748  */
751  const dif_usbdev_t *usbdev, uint8_t *setup_depth, uint8_t *out_depth);
752 /**
753  * Check if AV OUT and AV SETUP FIFOs are full.
754  *
755  * See also: `dif_usbdev_fill_available_fifos`.
756  *
757  * @param usbdev A USB device.
758  * @param[out] setup_is_full State of the AV SETUP FIFO. `true` if full, false
759  * otherwise.
760  * @param[out] out_is_full State of the AV OUT FIFO. `true` if full, false
761  * otherwise.
762  * @return The result of the operation.
763  */
766  const dif_usbdev_t *usbdev, bool *setup_is_full, bool *out_is_full);
767 /**
768  * Get the depth of the RX FIFO.
769  *
770  * See also: `dif_usbdev_recv`.
771  *
772  * @param usbdev A USB device.
773  * @param[out] depth Depth of the RX FIFO.
774  * @return The result of the operation.
775  */
778  uint8_t *depth);
779 
780 /**
781  * Check if the RX FIFO is empty.
782  *
783  * See also: `dif_usbdev_recv`.
784  *
785  * @param usbdev A USB device.
786  * @param[out] is_empty State of the RX FIFO. `true` if empty, `false`
787  * otherwise.
788  * @return The result of the operation.
789  */
792  bool *is_empty);
793 
794 /**
795  * Control whether oscillator test mode is enabled.
796  *
797  * In oscillator test mode, usbdev transmits a continuous 0101 pattern for
798  * evaluating the reference clock's quality.
799  *
800  * @param usbdev A USB device.
801  * @param enable Whether the test mode should be enabled.
802  * @return The result of the operation.
803  */
806  dif_toggle_t enable);
807 
808 /**
809  * Control whether the AON wake module is active.
810  *
811  * @param usbdev A USB device.
812  * @param enable Whether the AON wake module is enabled.
813  * @return The result of the operation.
814  */
817  dif_toggle_t enable);
818 
819 typedef struct dif_usbdev_wake_status {
820  /** Whether the AON wake module is active. */
821  bool active;
822  /** Whether the USB disconnected while the AON wake module was active. */
824  /** Whether the USB was reset while the AON wake module was active. */
825  bool bus_reset;
827 
828 /**
829  * Get the status of the AON wake module.
830  *
831  * Note that the conditions triggering exit from suspended state must be read
832  * before disabling the AON wake module. Once the AON wake module is
833  * deactivated, that status information is lost.
834  *
835  * Also note that the ordinary resume condition does not report to the usbdev
836  * module. Instead, it should be obtained from the module monitoring wakeup
837  * sources.
838  *
839  * @param usbdev A USB device.
840  * @param[out] status The status of the module.
841  * @return The result of the operation.
842  */
846 
847 /**
848  * Force the link state machine to resume to an active state.
849  *
850  * This is used when waking from a low-power suspended state to resume to an
851  * active state. It moves the usbdev out of the Powered state (from the USB
852  * device state machine in the spec) without receiving a bus reset. Without help
853  * from software, the usbdev module cannot determine on its own when a bus reset
854  * is required.
855  *
856  * @param usbdev A USB device.
857  * @return The result of the operation.
858  */
861 
863  /** USB D+ input. */
864  bool rx_dp : 1;
865  /** USB D- input. */
866  bool rx_dn : 1;
867  /** USB data input from an external differential receiver, if available. */
868  bool rx_d : 1;
869  /** USB transmit D+ output. */
870  bool tx_dp : 1;
871  /** USB transmit D- output. */
872  bool tx_dn : 1;
873  /** USB transmit data value output. */
874  bool tx_d : 1;
875  /** USB single-ended zero output. */
876  bool tx_se0 : 1;
877  /** USB output enable for D+ / D-. */
878  bool output_enable : 1;
879  /** USB VBUS sense pin. */
880  bool vbus_sense : 1;
882 
883 /**
884  * Get the current state of the USB PHY pins.
885  *
886  * @param usbdev A USB device.
887  * @param[out] status The current state of the pins.
888  * @return The result of the operation.
889  */
893 
895  /** USB D+ output, for use with dn. */
896  bool dp : 1;
897  /** USB D- output. for use with dp. */
898  bool dn : 1;
899  /** USB data output, encoding K and J when se0 is 0. */
900  bool data : 1;
901  /** USB single-ended zero output. */
902  bool se0 : 1;
903  /** USB output enable for D+ / D-. */
904  bool output_enable : 1;
905  /** Enable control pin for the differential receiver. */
907  /** Controls whether to pull up the D+ pin. */
908  bool dp_pullup_en : 1;
909  /** Controls whether to pull up the D- pin. */
910  bool dn_pullup_en : 1;
912 
913 /**
914  * Control whether to override the USB PHY and drive pins as GPIOs.
915  *
916  * @param usbdev A USB device.
917  * @param override_enable Enable / disable the GPIO-like overrides.
918  * @param overrides The values to set the pins to.
919  * @return The result of the operation.
920  */
923  const dif_usbdev_t *usbdev, dif_toggle_t override_enable,
924  dif_usbdev_phy_pins_drive_t overrides);
925 
926 /**
927  * Raw data transfer directly to the packet buffer memory. This is a faster
928  * implementation of the generic `mmio_memcpy_to_mmio32` that is specialized for
929  * the USB device and gives a significant performance improvement.
930  *
931  * @param usbdev A USB device.
932  * @param id Buffer number.
933  * @param src Source data.
934  * @param src_len Number of bytes to transfer.
935  * @return The result of the operation.
936  */
938 dif_result_t dif_usbdev_buffer_raw_write(const dif_usbdev_t *usbdev, uint8_t id,
939  const uint8_t *src, size_t src_len);
940 
941 /**
942  * Raw data transfer directly from the packet buffer memory. This is a faster
943  * implementation of the generic `mmio_memcpy_from_mmio32` that is specialized
944  * for the USB device and gives a significant performance improvemenet.
945  *
946  * @param usbdev A USB device.
947  * @param id Buffer number.
948  * @param dst Destination buffer.
949  * @param dst_len Number of bytes to transfer.
950  * @return The result of the operation.
951  */
953 dif_result_t dif_usbdev_buffer_raw_read(const dif_usbdev_t *usbdev, uint8_t id,
954  uint8_t *dst, size_t dst_len);
955 
956 #ifdef __cplusplus
957 } // extern "C"
958 #endif // __cplusplus
959 
960 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_USBDEV_H_