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
20#include "sw/device/lib/dif/autogen/dif_usbdev_autogen.h"
21
22#ifdef __cplusplus
23extern "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
39typedef 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;
52} dif_usbdev_endpoint_id_t;
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 */
63typedef struct dif_usbdev_buffer_pool {
64 uint8_t buffers[USBDEV_NUM_BUFFERS];
65 int8_t top;
67
68/**
69 * Buffer types.
70 */
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 */
101typedef 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 */
124typedef 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 */
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 */
512dif_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 */
528dif_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 */
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 */
604dif_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 */
614dif_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 */
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
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. */
826 /** Whether the USB became non-Idle whilst the AON wake module was active. */
828} dif_usbdev_wake_status_t;
829
830/**
831 * Get the status of the AON wake module.
832 *
833 * Note that the conditions triggering exit from suspended state must be read
834 * before disabling the AON wake module. Once the AON wake module is
835 * deactivated, that status information is lost.
836 *
837 * Also note that the ordinary resume condition does not report to the usbdev
838 * module. Instead, it should be obtained from the module monitoring wakeup
839 * sources.
840 *
841 * @param usbdev A USB device.
842 * @param[out] status The status of the module.
843 * @return The result of the operation.
844 */
847 dif_usbdev_wake_status_t *status);
848
849/**
850 * Force the link state machine to resume to an active state.
851 *
852 * This is used when waking from a low-power suspended state to resume to an
853 * active state. It moves the usbdev out of the Powered state (from the USB
854 * device state machine in the spec) without receiving a bus reset. Without help
855 * from software, the usbdev module cannot determine on its own when a bus reset
856 * is required.
857 *
858 * @param usbdev A USB device.
859 * @return The result of the operation.
860 */
863
865 /** USB D+ input. */
866 bool rx_dp : 1;
867 /** USB D- input. */
868 bool rx_dn : 1;
869 /** USB data input from an external differential receiver, if available. */
870 bool rx_d : 1;
871 /** USB transmit D+ output. */
872 bool tx_dp : 1;
873 /** USB transmit D- output. */
874 bool tx_dn : 1;
875 /** USB transmit data value output. */
876 bool tx_d : 1;
877 /** USB single-ended zero output. */
878 bool tx_se0 : 1;
879 /** USB output enable for D+ / D-. */
881 /** USB VBUS sense pin. */
882 bool vbus_sense : 1;
883} dif_usbdev_phy_pins_sense_t;
884
885/**
886 * Get the current state of the USB PHY pins.
887 *
888 * @param usbdev A USB device.
889 * @param[out] status The current state of the pins.
890 * @return The result of the operation.
891 */
894 const dif_usbdev_t *usbdev, dif_usbdev_phy_pins_sense_t *status);
895
897 /** USB D+ output, for use with dn. */
898 bool dp : 1;
899 /** USB D- output. for use with dp. */
900 bool dn : 1;
901 /** USB data output, encoding K and J when se0 is 0. */
902 bool data : 1;
903 /** USB single-ended zero output. */
904 bool se0 : 1;
905 /** USB output enable for D+ / D-. */
907 /** Enable control pin for the differential receiver. */
909 /** Controls whether to pull up the D+ pin. */
910 bool dp_pullup_en : 1;
911 /** Controls whether to pull up the D- pin. */
912 bool dn_pullup_en : 1;
913} dif_usbdev_phy_pins_drive_t;
914
915/**
916 * Control whether to override the USB PHY and drive pins as GPIOs.
917 *
918 * @param usbdev A USB device.
919 * @param override_enable Enable / disable the GPIO-like overrides.
920 * @param overrides The values to set the pins to.
921 * @return The result of the operation.
922 */
925 const dif_usbdev_t *usbdev, dif_toggle_t override_enable,
926 dif_usbdev_phy_pins_drive_t overrides);
927
928/**
929 * Raw data transfer directly to the packet buffer memory. This is a faster
930 * implementation of the generic `mmio_memcpy_to_mmio32` that is specialized for
931 * the USB device and gives a significant performance improvement.
932 *
933 * @param usbdev A USB device.
934 * @param id Buffer number.
935 * @param src Source data.
936 * @param src_len Number of bytes to transfer.
937 * @return The result of the operation.
938 */
941 const uint8_t *src, size_t src_len);
942
943/**
944 * Raw data transfer directly from the packet buffer memory. This is a faster
945 * implementation of the generic `mmio_memcpy_from_mmio32` that is specialized
946 * for the USB device and gives a significant performance improvemenet.
947 *
948 * @param usbdev A USB device.
949 * @param id Buffer number.
950 * @param dst Destination buffer.
951 * @param dst_len Number of bytes to transfer.
952 * @return The result of the operation.
953 */
956 uint8_t *dst, size_t dst_len);
957
958#ifdef __cplusplus
959} // extern "C"
960#endif // __cplusplus
961
962#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_USBDEV_H_