|  | // Copyright lowRISC contributors. | 
|  | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | // SPDX-License-Identifier: Apache-2.0 | 
|  |  | 
|  | #ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_USB_TESTUTILS_H_ | 
|  | #define OPENTITAN_SW_DEVICE_LIB_TESTING_USB_TESTUTILS_H_ | 
|  |  | 
|  | #include <stdbool.h> | 
|  | #include <stddef.h> | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include "sw/device/lib/dif/dif_usbdev.h" | 
|  | #include "usb_testutils_diags.h" | 
|  |  | 
|  | typedef struct usb_testutils_ctx usb_testutils_ctx_t; | 
|  |  | 
|  | struct usb_testutils_ctx { | 
|  | dif_usbdev_t *dev; | 
|  | dif_usbdev_buffer_pool_t *buffer_pool; | 
|  | int flushed; | 
|  | /** | 
|  | * Have we received an indication of USB activity? | 
|  | */ | 
|  | bool got_frame; | 
|  | /** | 
|  | * Most recent bus frame number received from host | 
|  | */ | 
|  | uint16_t frame; | 
|  | void *ep_ctx[USBDEV_NUM_ENDPOINTS]; | 
|  | void (*tx_done_callback[USBDEV_NUM_ENDPOINTS])(void *); | 
|  | void (*rx_callback[USBDEV_NUM_ENDPOINTS])(void *, dif_usbdev_rx_packet_info_t, | 
|  | dif_usbdev_buffer_t); | 
|  | void (*flush[USBDEV_NUM_ENDPOINTS])(void *); | 
|  | void (*reset[USBDEV_NUM_ENDPOINTS])(void *); | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * Call regularly to poll the usbdev interface | 
|  | * | 
|  | * @param ctx usbdev context pointer | 
|  | */ | 
|  | void usb_testutils_poll(usb_testutils_ctx_t *ctx); | 
|  |  | 
|  | typedef enum usb_testutils_out_transfer_mode { | 
|  | /** | 
|  | * The endpoint does not support OUT transactions. | 
|  | */ | 
|  | kUsbdevOutDisabled = 0, | 
|  | /** | 
|  | * Software does NOT need to call usb_testutils_clear_out_nak() after every | 
|  | * received transaction. If software takes no action, usbdev will allow an | 
|  | * endpoint's transactions to proceed as long as a buffer is available. | 
|  | */ | 
|  | kUsbdevOutStream = 1, | 
|  | /** | 
|  | * Software must call usb_testutils_clear_out_nak() after every received | 
|  | * transaction to re-enable packet reception. This gives software time to | 
|  | * respond with the appropriate handshake when it's ready. | 
|  | */ | 
|  | kUsbdevOutMessage = 2, | 
|  | } usb_testutils_out_transfer_mode_t; | 
|  |  | 
|  | /** | 
|  | * Call to set up endpoints. | 
|  | * | 
|  | * Note that this library currently only supports setting up both the IN and OUT | 
|  | * endpoints in the same call, using the same `ep_ctx` for their callbacks. | 
|  | * | 
|  | * @param ctx usbdev context pointer | 
|  | * @param ep endpoint number | 
|  | * @param out_mode the transfer mode for OUT transactions | 
|  | * @param ep_ctx context pointer for callee | 
|  | * @param tx_done(void *ep_ctx) callback once send has been Acked | 
|  | * @param rx(void *ep_ctx, usbbufid_t buf, int size, int setup) | 
|  | called when a packet is received | 
|  | * @param flush(void *ep_ctx) called every 16ms based USB host timebase | 
|  | * @param reset(void *ep_ctx) called when an USB link reset is detected | 
|  | */ | 
|  | void usb_testutils_endpoint_setup(usb_testutils_ctx_t *ctx, int ep, | 
|  | usb_testutils_out_transfer_mode_t out_mode, | 
|  | void *ep_ctx, void (*tx_done)(void *), | 
|  | void (*rx)(void *, | 
|  | dif_usbdev_rx_packet_info_t, | 
|  | dif_usbdev_buffer_t), | 
|  | void (*flush)(void *), void (*reset)(void *)); | 
|  |  | 
|  | /** | 
|  | * Returns an indication of whether an endpoint is currently halted because | 
|  | * of the occurrence of an error. | 
|  | * | 
|  | * @param ctx usbdev context pointer | 
|  | * @param ep endpoint number | 
|  | * @return true iff the endpoint is halted as a result of an error condition | 
|  | */ | 
|  | inline bool usb_testutils_endpoint_halted(usb_testutils_ctx_t *ctx, | 
|  | dif_usbdev_endpoint_id_t endpoint); | 
|  |  | 
|  | /** | 
|  | * Initialize the usbdev interface | 
|  | * | 
|  | * Does not connect the device, since the default endpoint is not yet enabled. | 
|  | * See usb_testutils_connect(). | 
|  | * | 
|  | * @param ctx uninitialized usbdev context pointer | 
|  | * @param pinflip boolean to indicate if PHY should be configured for D+/D- flip | 
|  | * @param en_diff_rcvr boolean to indicate if PHY should enable an external | 
|  | *                     differential receiver, activating the single-ended D | 
|  | *                     input | 
|  | * @param tx_use_d_se0 boolean to indicate if PHY uses D/SE0 for TX instead of | 
|  | *                     Dp/Dn | 
|  | */ | 
|  | void usb_testutils_init(usb_testutils_ctx_t *ctx, bool pinflip, | 
|  | bool en_diff_rcvr, bool tx_use_d_se0); | 
|  |  | 
|  | #endif  // OPENTITAN_SW_DEVICE_LIB_TESTING_USB_TESTUTILS_H_ |