Software APIs
usb_testutils_controlep.h
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_TESTING_USB_TESTUTILS_CONTROLEP_H_
6 #define OPENTITAN_SW_DEVICE_LIB_TESTING_USB_TESTUTILS_CONTROLEP_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include "sw/device/lib/base/status.h"
12 #include "sw/device/lib/testing/usb_testutils.h"
13 
14 // DPI test numbers
15 typedef enum usb_testutils_test_number {
16  kUsbTestNumberSmoke = 0,
17  kUsbTestNumberStreams,
18  kUsbTestNumberIso,
19  kUsbTestNumberMixed,
20  kUsbTestNumberSuspend,
21  kUsbTestNumberExc,
22  kUsbTestNumberPinCfg,
23 } usb_testutils_test_number_t;
24 
25 typedef enum usb_testutils_ctstate {
26  kUsbTestutilsCtIdle,
27  kUsbTestutilsCtWaitIn, // Queued IN data stage, waiting ack
28  kUsbTestutilsCtStatOut, // Waiting for OUT status stage
29  kUsbTestutilsCtAddrStatIn, // Queued Status stage of SET_ADDRESS; awaiting
30  // host acknowledgement, after which the device
31  // address will be set.
32  kUsbTestutilsCtCfgStatIn, // Queued Status stage of SET_CONFIGURATION;
33  // awaiting acknowledgement from host, after which
34  // the new Configuration will be selected.
35  kUsbTestutilsCtStatIn, // Queued status stage, waiting ack
36  kUsbTestutilsCtError // Something bad
37 } usb_testutils_ctstate_t;
38 
39 typedef enum usb_testutils_device_state {
40  kUsbTestutilsDeviceAttached,
41  kUsbTestutilsDevicePowered,
42  kUsbTestutilsDeviceDefault,
43  kUsbTestutilsDeviceAddressed,
44  kUsbTestutilsDeviceConfigured,
45  kUsbTestutilsDeviceSuspended,
46 } usb_testutils_device_state_t;
47 
50  uint8_t ep;
51  usb_testutils_ctstate_t ctrlstate;
52  usb_testutils_device_state_t device_state;
53  /**
54  * New Device Address, to be set upon successful Status stage
55  */
56  uint8_t new_dev;
57  /**
58  * New Device Configuration, to be set upon successful Status stage
59  */
60  uint8_t new_config;
61  /**
62  * Current Device Configuration
63  */
64  uint8_t usb_config;
65  /**
66  * USB configuration descriptor
67  */
68  const uint8_t *cfg_dscr;
69  size_t cfg_dscr_len;
70  /**
71  * Optional test descriptor, or NULL
72  */
73  const uint8_t *test_dscr;
74  size_t test_dscr_len;
76 
77 /**
78  * Initialize control endpoint
79  *
80  * @param ctctx uninitialized context for this instance
81  * @param ctx initialized context for usbdev driver
82  * @param ep endpoint (if this is other than 0 make sure you know why)
83  * @param cfg_dscr configuration descriptor for the device
84  * @param cfg_dscr_len length of cfg_dscr
85  * @param test_dscr optional test descriptor, or NULL
86  * @param test_dscr_len length of test_dscr
87  * @return The result of the operation
88  */
90 status_t usb_testutils_controlep_init(usb_testutils_controlep_ctx_t *ctctx,
91  usb_testutils_ctx_t *ctx, uint8_t ep,
92  const uint8_t *cfg_dscr,
93  size_t cfg_dscr_len,
94  const uint8_t *test_dscr,
95  size_t test_dscr_len);
96 
97 /**
98  * Wait until the device configuration has been set by the host.
99  *
100  * @param ctctx uninitialized context for this instance.
101  * @param ctx initialized context for usbdev driver.
102  * @return The result of the operation.
103  */
105 status_t usb_testutils_controlep_config_wait(
107 
108 /***********************************************************************/
109 /* Below this point are macros used to construct the USB configuration */
110 /* descriptor. Use them to initialize a uint8_t array for cfg_dscr */
111 
112 #define USB_CFG_DSCR_LEN 9
113 #define USB_CFG_DSCR_HEAD(total_len, nint) \
114  /* This is the actual configuration descriptor */ \
115  USB_CFG_DSCR_LEN, /* bLength */ \
116  2, /* bDescriptorType */ \
117  (total_len)&0xff, /* wTotalLength[0] */ \
118  (total_len) >> 8, /* wTotalLength[1] */ \
119  (nint), /* bNumInterfaces */ \
120  1, /* bConfigurationValue */ \
121  0, /* iConfiguration */ \
122  0xC0, /* bmAttributes: must-be-one, self-powered */ \
123  50 /* bMaxPower */ /* MUST be followed \
124  by (nint) \
125  Interface + \
126  Endpoint \
127  Descriptors */
128 
129 // KEEP BLANK LINE ABOVE, it is in the macro!
130 
131 #define USB_INTERFACE_DSCR_LEN 9
132 #define VEND_INTERFACE_DSCR(inum, nep, subclass, protocol) \
133  /* interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 */ \
134  USB_INTERFACE_DSCR_LEN, /* bLength */ \
135  4, /* bDescriptorType */ \
136  (inum), /* bInterfaceNumber */ \
137  0, /* bAlternateSetting */ \
138  (nep), /* bNumEndpoints */ \
139  0xff, /* bInterfaceClass (Vendor Specific) */ \
140  (subclass), /* bInterfaceSubClass */ \
141  (protocol), /* bInterfaceProtocol */ \
142  0 /* iInterface */ /* MUST be followed by \
143  (nep) Endpoint \
144  Descriptors */
145 
146 // KEEP BLANK LINE ABOVE, it is in the macro!
147 
148 #define USB_EP_DSCR_LEN 7
149 #define USB_EP_DSCR(in, ep, attr, maxsize, interval) \
150  /* endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 */ \
151  USB_EP_DSCR_LEN, /* bLength */ \
152  5, /* bDescriptorType */ \
153  (ep) | (((in) << 7) & 0x80), /* bEndpointAddress, top bit set for IN */ \
154  attr, /* bmAttributes */ \
155  (maxsize)&0xff, /* wMaxPacketSize[0] */ \
156  (maxsize) >> 8, /* wMaxPacketSize[1] */ \
157  (interval) /* bInterval */
158 
159 // KEEP BLANK LINE ABOVE, it is in the macro!
160 #define USB_BULK_EP_DSCR(in, ep, maxsize, interval) \
161  /* endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 */ \
162  USB_EP_DSCR_LEN, /* bLength */ \
163  5, /* bDescriptorType */ \
164  (ep) | (((in) << 7) & 0x80), /* bEndpointAddress, top bit set for IN */ \
165  kUsbTransferTypeBulk, /* bmAttributes (0x02=bulk, data) */ \
166  (maxsize)&0xff, /* wMaxPacketSize[0] */ \
167  (maxsize) >> 8, /* wMaxPacketSize[1] */ \
168  (interval) /* bInterval */
169 
170 // KEEP BLANK LINE ABOVE, it is in the macro!
171 
172 /***********************************************************************/
173 /* Below this point are macros used to construct the test descriptor */
174 /* Use them to initialize a uint8_t array for test_dscr */
175 #define USB_TESTUTILS_TEST_DSCR_LEN 0x10u
176 #define USB_TESTUTILS_TEST_DSCR(num, arg0, arg1, arg2, arg3) \
177  0x7e, 0x57, 0xc0, 0xf1u, /* Header signature */ \
178  (USB_TESTUTILS_TEST_DSCR_LEN)&0xff, /* Descriptor length[0] */ \
179  (USB_TESTUTILS_TEST_DSCR_LEN) >> 8, /* Descriptor length[1] */ \
180  (num)&0xff, /* Test number[0] */ \
181  (num) >> 8, /* Test number[1] */ \
182  (arg0), (arg1), (arg2), (arg3), /* Test-specific arugments */ \
183  0x1fu, 0x0cu, 0x75, 0xe7u /* Tail signature */
184 
185 // KEEP BLANK LINE ABOVE, it is in the macro!
186 
187 #endif // OPENTITAN_SW_DEVICE_LIB_TESTING_USB_TESTUTILS_CONTROLEP_H_