blob: 20170b9a140a8775fb449681309a10a18aa978e8 [file] [log] [blame]
// 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_