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