blob: 9cbd378281cc29336102049e4d86d47074a6a556 [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_CONTROLEP_H_
#define OPENTITAN_SW_DEVICE_LIB_TESTING_USB_TESTUTILS_CONTROLEP_H_
#include <stddef.h>
#include <stdint.h>
#include "sw/device/lib/testing/usb_testutils.h"
typedef enum usb_testutils_ctstate {
kUsbTestutilsCtIdle,
kUsbTestutilsCtWaitIn, // Queued IN data stage, waiting ack
kUsbTestutilsCtStatOut, // Waiting for OUT status stage
kUsbTestutilsCtAddrStatIn, // Queued status stage, waiting ack.
// After which, set dev_addr
kUsbTestutilsCtStatIn, // Queued status stage, waiting ack
kUsbTestutilsCtError // Something bad
} usb_testutils_ctstate_t;
typedef enum usb_testutils_device_state {
kUsbTestutilsDeviceAttached,
kUsbTestutilsDevicePowered,
kUsbTestutilsDeviceDefault,
kUsbTestutilsDeviceAddressed,
kUsbTestutilsDeviceConfigured,
kUsbTestutilsDeviceSuspended,
} usb_testutils_device_state_t;
typedef struct usb_testutils_controlep_ctx {
usb_testutils_ctx_t *ctx;
int ep;
usb_testutils_ctstate_t ctrlstate;
usb_testutils_device_state_t device_state;
uint32_t new_dev;
uint8_t usb_config;
/**
* USB configuration descriptor
*/
const uint8_t *cfg_dscr;
size_t cfg_dscr_len;
/**
* Optional test descriptor, or NULL
*/
const uint8_t *test_dscr;
size_t test_dscr_len;
} usb_testutils_controlep_ctx_t;
/**
* Initialize control endpoint
*
* @param ctctx uninitialized context for this instance
* @param ctx initialized context for usbdev driver
* @param ep endpoint (if this is other than 0 make sure you know why)
* @param cfg_dscr configuration descriptor for the device
* @param cfg_dscr_len length of cfg_dscr
* @param test_dscr optional test descriptor, or NULL
* @param test_dscr_len length of test_dscr
*/
void usb_testutils_controlep_init(usb_testutils_controlep_ctx_t *ctctx,
usb_testutils_ctx_t *ctx, int ep,
const uint8_t *cfg_dscr, size_t cfg_dscr_len,
const uint8_t *test_dscr,
size_t test_dscr_len);
/***********************************************************************/
/* Below this point are macros used to construct the USB configuration */
/* descriptor. Use them to initialize a uint8_t array for cfg_dscr */
#define USB_CFG_DSCR_LEN 9
#define USB_CFG_DSCR_HEAD(total_len, nint) \
/* This is the actual configuration descriptor */ \
USB_CFG_DSCR_LEN, /* bLength */ \
2, /* bDescriptorType */ \
(total_len)&0xff, /* wTotalLength[0] */ \
(total_len) >> 8, /* wTotalLength[1] */ \
(nint), /* bNumInterfaces */ \
1, /* bConfigurationValue */ \
0, /* iConfiguration */ \
0xC0, /* bmAttributes: must-be-one, self-powered */ \
50 /* bMaxPower */ /* MUST be followed \
by (nint) \
Interface + \
Endpoint \
Descriptors */
// KEEP BLANK LINE ABOVE, it is in the macro!
#define USB_INTERFACE_DSCR_LEN 9
#define VEND_INTERFACE_DSCR(inum, nep, subclass, protocol) \
/* interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 */ \
USB_INTERFACE_DSCR_LEN, /* bLength */ \
4, /* bDescriptorType */ \
(inum), /* bInterfaceNumber */ \
0, /* bAlternateSetting */ \
(nep), /* bNumEndpoints */ \
0xff, /* bInterfaceClass (Vendor Specific) */ \
(subclass), /* bInterfaceSubClass */ \
(protocol), /* bInterfaceProtocol */ \
0 /* iInterface */ /* MUST be followed by \
(nep) Endpoint \
Descriptors */
// KEEP BLANK LINE ABOVE, it is in the macro!
#define USB_EP_DSCR_LEN 7
#define USB_EP_DSCR(in, ep, attr, maxsize, interval) \
/* endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 */ \
USB_EP_DSCR_LEN, /* bLength */ \
5, /* bDescriptorType */ \
(ep) | (((in) << 7) & 0x80), /* bEndpointAddress, top bit set for IN */ \
attr, /* bmAttributes */ \
(maxsize)&0xff, /* wMaxPacketSize[0] */ \
(maxsize) >> 8, /* wMaxPacketSize[1] */ \
(interval) /* bInterval */
// KEEP BLANK LINE ABOVE, it is in the macro!
#define USB_BULK_EP_DSCR(in, ep, maxsize, interval) \
/* endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 */ \
USB_EP_DSCR_LEN, /* bLength */ \
5, /* bDescriptorType */ \
(ep) | (((in) << 7) & 0x80), /* bEndpointAddress, top bit set for IN */ \
0x02, /* bmAttributes (0x02=bulk, data) */ \
(maxsize)&0xff, /* wMaxPacketSize[0] */ \
(maxsize) >> 8, /* wMaxPacketSize[1] */ \
(interval) /* bInterval */
// KEEP BLANK LINE ABOVE, it is in the macro!
/***********************************************************************/
/* Below this point are macros used to construct the test descriptor */
/* Use them to initialize a uint8_t array for test_dscr */
#define USB_TESTUTILS_TEST_DSCR_LEN 0x10u
#define USB_TESTUTILS_TEST_DSCR(num, arg0, arg1, arg2, arg3) \
0x7e, 0x57, 0xc0, 0xf1u, /* Header signature */ \
(USB_TESTUTILS_TEST_DSCR_LEN)&0xff, /* Descriptor length[0] */ \
(USB_TESTUTILS_TEST_DSCR_LEN) >> 8, /* Descriptor length[1] */ \
(num)&0xff, /* Test number[0] */ \
(num) >> 8, /* Test number[1] */ \
(arg0), (arg1), (arg2), (arg3), /* Test-specific arugments */ \
0x1fu, 0x0cu, 0x75, 0xe7u /* Tail signature */
// KEEP BLANK LINE ABOVE, it is in the macro!
#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_USB_TESTUTILS_CONTROLEP_H_