1 /*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_device_config.h"
10 #include "usb.h"
11
12 #include "usb_device.h"
13 #include "usb_device_dci.h"
14 #include "usb_device_class.h"
15 #include "usb_device_ch9.h"
16 #if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U))
17 /*******************************************************************************
18 * Definitions
19 ******************************************************************************/
20
21 /*!
22 * @brief Standard request callback function typedef.
23 *
24 * This function is used to handle the standard request.
25 *
26 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
27 * @param setup The pointer of the setup packet.
28 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
29 * @param length It is an out parameter, the data length.
30 *
31 * @return A USB error code or kStatus_USB_Success.
32 */
33 typedef usb_status_t (*usb_standard_request_callback_t)(usb_device_common_class_struct_t *classHandle,
34 usb_setup_struct_t *setup,
35 uint8_t **buffer,
36 uint32_t *length);
37
38 /*******************************************************************************
39 * Prototypes
40 ******************************************************************************/
41
42 static usb_status_t USB_DeviceCh9GetStatus(usb_device_common_class_struct_t *classHandle,
43 usb_setup_struct_t *setup,
44 uint8_t **buffer,
45 uint32_t *length);
46 static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle,
47 usb_setup_struct_t *setup,
48 uint8_t **buffer,
49 uint32_t *length);
50
51 static usb_status_t USB_DeviceCh9SetAddress(usb_device_common_class_struct_t *classHandle,
52 usb_setup_struct_t *setup,
53 uint8_t **buffer,
54 uint32_t *length);
55 static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t *classHandle,
56 usb_setup_struct_t *setup,
57 uint8_t **buffer,
58 uint32_t *length);
59 static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t *classHandle,
60 usb_setup_struct_t *setup,
61 uint8_t **buffer,
62 uint32_t *length);
63 static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t *classHandle,
64 usb_setup_struct_t *setup,
65 uint8_t **buffer,
66 uint32_t *length);
67 static usb_status_t USB_DeviceCh9GetInterface(usb_device_common_class_struct_t *classHandle,
68 usb_setup_struct_t *setup,
69 uint8_t **buffer,
70 uint32_t *length);
71 static usb_status_t USB_DeviceCh9SetInterface(usb_device_common_class_struct_t *classHandle,
72 usb_setup_struct_t *setup,
73 uint8_t **buffer,
74 uint32_t *length);
75 static usb_status_t USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t *classHandle,
76 usb_setup_struct_t *setup,
77 uint8_t **buffer,
78 uint32_t *length);
79
80 /*******************************************************************************
81 * Variables
82 ******************************************************************************/
83
84 /* The function list to handle the standard request. */
85 static const usb_standard_request_callback_t s_UsbDeviceStandardRequest[] = {
86 USB_DeviceCh9GetStatus,
87 USB_DeviceCh9SetClearFeature,
88 (usb_standard_request_callback_t)NULL,
89 USB_DeviceCh9SetClearFeature,
90 (usb_standard_request_callback_t)NULL,
91 USB_DeviceCh9SetAddress,
92 USB_DeviceCh9GetDescriptor,
93 (usb_standard_request_callback_t)NULL,
94 USB_DeviceCh9GetConfiguration,
95 USB_DeviceCh9SetConfiguration,
96 USB_DeviceCh9GetInterface,
97 USB_DeviceCh9SetInterface,
98 USB_DeviceCh9SynchFrame,
99 };
100
101 /*******************************************************************************
102 * Code
103 ******************************************************************************/
104
105 /*!
106 * @brief Handle get status request.
107 *
108 * This function is used to handle get status request.
109 *
110 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
111 * @param setup The pointer of the setup packet.
112 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
113 * @param length It is an out parameter, the data length.
114 *
115 * @retval kStatus_USB_Success The request is handled successfully.
116 * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
117 * or, the request is unsupported.
118 */
USB_DeviceCh9GetStatus(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)119 static usb_status_t USB_DeviceCh9GetStatus(usb_device_common_class_struct_t *classHandle,
120 usb_setup_struct_t *setup,
121 uint8_t **buffer,
122 uint32_t *length)
123 {
124 usb_status_t error = kStatus_USB_InvalidRequest;
125 uint8_t state = 0U;
126
127 if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_IN) || (setup->wValue != 0U) ||
128 (setup->wLength != 2U))
129 {
130 return error;
131 }
132 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
133 if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
134 {
135 return kStatus_USB_Error;
136 }
137 #else
138 (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
139 #endif
140
141 if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state))
142 {
143 return error;
144 }
145
146 if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE)
147 {
148 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
149 if (setup->wIndex == USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR)
150 {
151 error =
152 USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusOtg, &classHandle->standardTranscationBuffer);
153 classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
154 /* The device status length must be USB_DEVICE_STATUS_SIZE. */
155 *length = 1;
156 }
157 else /* Get the device status */
158 {
159 #endif
160 error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDevice,
161 &classHandle->standardTranscationBuffer);
162 classHandle->standardTranscationBuffer =
163 classHandle->standardTranscationBuffer & USB_GET_STATUS_DEVICE_MASK;
164 classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
165 /* The device status length must be USB_DEVICE_STATUS_SIZE. */
166 *length = USB_DEVICE_STATUS_SIZE;
167 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
168 }
169 #endif
170 }
171 else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
172 {
173 #if ((defined(USB_DEVICE_CONFIG_ROOT2_TEST)) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
174 if (((uint8_t)kUSB_DeviceStateAddress == state) ||
175 (((uint8_t)kUSB_DeviceStateConfigured == state) && (0U == setup->wIndex)))
176 {
177 /* In valid address state, device must stall the status stage for get status (interface) request.
178 In configured state, device must stall the status stage for get status (interface 0) request */
179 return error;
180 }
181 #endif
182 /* Get the interface status */
183 error = kStatus_USB_Success;
184 classHandle->standardTranscationBuffer = 0U;
185 /* The interface status length must be USB_INTERFACE_STATUS_SIZE. */
186 *length = USB_INTERFACE_STATUS_SIZE;
187 }
188 else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT)
189 {
190 #if ((defined(USB_DEVICE_CONFIG_ROOT2_TEST)) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
191 if ((USB_CONTROL_ENDPOINT != (setup->wIndex & USB_ENDPOINT_NUMBER_MASK)) &&
192 ((uint8_t)kUSB_DeviceStateAddress == state))
193 {
194 /* In valid address, device must stall the status stage for get status (EP) request for no-control endpoint
195 */
196 return error;
197 }
198 #endif
199 /* Get the endpoint status */
200 usb_device_endpoint_status_struct_t endpointStatus;
201 endpointStatus.endpointAddress = (uint8_t)setup->wIndex;
202 endpointStatus.endpointStatus = (uint16_t)kUSB_DeviceEndpointStateIdle;
203 error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusEndpoint, &endpointStatus);
204 classHandle->standardTranscationBuffer = endpointStatus.endpointStatus & USB_GET_STATUS_ENDPOINT_MASK;
205 classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
206 /* The endpoint status length must be USB_INTERFACE_STATUS_SIZE. */
207 *length = USB_ENDPOINT_STATUS_SIZE;
208 }
209 else
210 {
211 /*no action*/
212 }
213 *buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
214
215 return error;
216 }
217
218 /*!
219 * @brief Handle set or clear device feature request.
220 *
221 * This function is used to handle set or clear device feature request.
222 *
223 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
224 * @param setup The pointer of the setup packet.
225 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
226 * @param length It is an out parameter, the data length.
227 *
228 * @retval kStatus_USB_Success The request is handled successfully.
229 * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
230 * or, the request is unsupported.
231 */
USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)232 static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle,
233 usb_setup_struct_t *setup,
234 uint8_t **buffer,
235 uint32_t *length)
236 {
237 usb_status_t error = kStatus_USB_InvalidRequest;
238 uint8_t state = 0U;
239 uint8_t isSet = 0U;
240
241 if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_OUT) || (setup->wLength != 0U))
242 {
243 return error;
244 }
245 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
246 if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
247 {
248 return kStatus_USB_Error;
249 }
250 #else
251 (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
252 #endif
253
254 if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state))
255 {
256 return error;
257 }
258
259 /* Identify the request is set or clear the feature. */
260 if (USB_REQUEST_STANDARD_SET_FEATURE == setup->bRequest)
261 {
262 isSet = 1U;
263 }
264
265 if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE)
266 {
267 /* Set or Clear the device feature. */
268 if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP == setup->wValue)
269 {
270 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
271 USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusRemoteWakeup, &isSet);
272 #endif
273 /* Set or Clear the device remote wakeup feature. */
274 error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventSetRemoteWakeup, &isSet);
275 }
276 #if ((defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
277 (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \
278 (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
279 else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE == setup->wValue)
280 {
281 state = kUSB_DeviceStateTestMode;
282 error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
283 }
284 #endif
285 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
286 else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_B_HNP_ENABLE == setup->wValue)
287 {
288 error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetBHNPEnable, &isSet);
289 }
290 #endif
291 else
292 {
293 }
294 }
295 else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT)
296 {
297 /* Set or Clear the endpoint feature. */
298 if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT == setup->wValue)
299 {
300 #if ((defined(USB_DEVICE_CONFIG_ROOT2_TEST)) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
301 if ((USB_CONTROL_ENDPOINT != (setup->wIndex & USB_ENDPOINT_NUMBER_MASK)) &&
302 (kUSB_DeviceStateConfigured != state))
303 {
304 /* In no-configured state, device must stall the status stage for clear/set feature halt requests for
305 * no-control endpoint */
306 return error;
307 }
308 else
309 {
310 /* In configured state, device must stall the status stage for clear/set feature halt for no-initialized
311 EP. For contol EP, device must accept status stage of Set Feature Halt (Endpoint 80) in Addressed
312 State */
313 usb_device_endpoint_status_struct_t endpointStatus;
314 endpointStatus.endpointAddress = (uint8_t)setup->wIndex;
315 error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusEndpoint, &endpointStatus);
316 if (kStatus_USB_Success != error)
317 {
318 return error;
319 }
320 }
321 #else
322 if (USB_CONTROL_ENDPOINT == (setup->wIndex & USB_ENDPOINT_NUMBER_MASK))
323 {
324 /* Set or Clear the control endpoint status(halt or not). */
325 if (0U != isSet)
326 {
327 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
328 if (kStatus_USB_Success != USB_DeviceStallEndpoint(classHandle->handle, (uint8_t)setup->wIndex))
329 {
330 return kStatus_USB_Error;
331 }
332 #else
333 (void)USB_DeviceStallEndpoint(classHandle->handle, (uint8_t)setup->wIndex);
334 #endif
335 }
336 else
337 {
338 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
339 if (kStatus_USB_Success != USB_DeviceUnstallEndpoint(classHandle->handle, (uint8_t)setup->wIndex))
340 {
341 return kStatus_USB_Error;
342 }
343 #else
344 (void)USB_DeviceUnstallEndpoint(classHandle->handle, (uint8_t)setup->wIndex);
345 #endif
346 }
347 }
348 #endif
349 /* Set or Clear the endpoint status feature. */
350 if (0U != isSet)
351 {
352 error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetEndpointHalt, &setup->wIndex);
353 }
354 else
355 {
356 error =
357 USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventClearEndpointHalt, &setup->wIndex);
358 }
359 }
360 else
361 {
362 /*no action*/
363 }
364 }
365 else
366 {
367 /*no action*/
368 }
369
370 return error;
371 }
372
373 /*!
374 * @brief Handle set address request.
375 *
376 * This function is used to handle set address request.
377 *
378 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
379 * @param setup The pointer of the setup packet.
380 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
381 * @param length It is an out parameter, the data length.
382 *
383 * @retval kStatus_USB_Success The request is handled successfully.
384 * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state.
385 */
USB_DeviceCh9SetAddress(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)386 static usb_status_t USB_DeviceCh9SetAddress(usb_device_common_class_struct_t *classHandle,
387 usb_setup_struct_t *setup,
388 uint8_t **buffer,
389 uint32_t *length)
390 {
391 usb_status_t error = kStatus_USB_InvalidRequest;
392 uint8_t state = 0U;
393
394 if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_OUT) ||
395 ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_DEVICE) ||
396 (setup->wIndex != 0U) || (setup->wLength != 0U))
397 {
398 return error;
399 }
400
401 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
402 if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
403 {
404 return kStatus_USB_Error;
405 }
406 #else
407 (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
408 #endif
409
410 if (((uint8_t)kUSB_DeviceStateAddressing != state) && ((uint8_t)kUSB_DeviceStateAddress != state) &&
411 ((uint8_t)kUSB_DeviceStateDefault != state)
412 #if ((defined(USB_DEVICE_CONFIG_ROOT2_TEST)) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
413 #else
414 && ((uint8_t)kUSB_DeviceStateConfigured != state)
415 #endif
416 )
417 {
418 return error;
419 }
420
421 if ((uint8_t)kUSB_DeviceStateAddressing != state)
422 {
423 /* If the device address is not setting, pass the address and the device state will change to
424 * kUSB_DeviceStateAddressing internally. */
425 state = (uint8_t)(setup->wValue & 0xFFU);
426 #if ((defined(USB_DEVICE_CONFIG_ROOT2_TEST)) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
427 /* Setting the address to 128 or above should not be allowed. */
428 if (state >= 0x80U)
429 {
430 return error;
431 }
432 #endif
433 error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusAddress, &state);
434 }
435 else
436 {
437 /* If the device address is setting, set device address and the address will be write into the controller
438 * internally. */
439 error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusAddress, NULL);
440 /* And then change the device state to kUSB_DeviceStateAddress. */
441 if (kStatus_USB_Success == error)
442 {
443 state = (uint8_t)kUSB_DeviceStateAddress;
444 error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
445 }
446 }
447
448 return error;
449 }
450
451 /*!
452 * @brief Handle get descriptor request.
453 *
454 * This function is used to handle get descriptor request.
455 *
456 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
457 * @param setup The pointer of the setup packet.
458 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
459 * @param length It is an out parameter, the data length.
460 *
461 * @retval kStatus_USB_Success The request is handled successfully.
462 * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
463 * or, the request is unsupported.
464 */
USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)465 static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t *classHandle,
466 usb_setup_struct_t *setup,
467 uint8_t **buffer,
468 uint32_t *length)
469 {
470 usb_device_get_descriptor_common_union_t commonDescriptor;
471 usb_status_t error = kStatus_USB_InvalidRequest;
472 uint8_t state = 0U;
473 uint8_t descriptorType = (uint8_t)((setup->wValue & 0xFF00U) >> 8U);
474 uint8_t descriptorIndex = (uint8_t)((setup->wValue & 0x00FFU));
475
476 if ((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_IN)
477 {
478 return error;
479 }
480
481 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
482 if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
483 {
484 return kStatus_USB_Error;
485 }
486 #else
487 (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
488 #endif
489
490 if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state) &&
491 ((uint8_t)kUSB_DeviceStateDefault != state))
492 {
493 return error;
494 }
495 commonDescriptor.commonDescriptor.length = setup->wLength;
496 if (USB_DESCRIPTOR_TYPE_DEVICE == descriptorType)
497 {
498 /* Get the device descriptor */
499 if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) &&
500 (descriptorIndex == 0U) && (setup->wIndex == 0U))
501 {
502 error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetDeviceDescriptor,
503 &commonDescriptor.deviceDescriptor);
504 }
505 }
506 else if (USB_DESCRIPTOR_TYPE_CONFIGURE == descriptorType)
507 {
508 /* Get the configuration descriptor */
509 if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) &&
510 (setup->wIndex == 0U))
511 {
512 commonDescriptor.configurationDescriptor.configuration = descriptorIndex;
513 error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetConfigurationDescriptor,
514 &commonDescriptor.configurationDescriptor);
515 }
516 }
517 else if (USB_DESCRIPTOR_TYPE_STRING == descriptorType)
518 {
519 /* Get the string descriptor */
520 if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE)
521 {
522 commonDescriptor.stringDescriptor.stringIndex = descriptorIndex;
523 commonDescriptor.stringDescriptor.languageId = setup->wIndex;
524 error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetStringDescriptor,
525 &commonDescriptor.stringDescriptor);
526 }
527 }
528 #if (defined(USB_DEVICE_CONFIG_HID) && (USB_DEVICE_CONFIG_HID > 0U))
529 else if (USB_DESCRIPTOR_TYPE_HID == descriptorType)
530 {
531 /* Get the hid descriptor */
532 if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE) &&
533 (descriptorIndex == 0U))
534 {
535 commonDescriptor.hidDescriptor.interfaceNumber = (uint8_t)setup->wIndex;
536 error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetHidDescriptor,
537 &commonDescriptor.hidDescriptor);
538 }
539 }
540 else if (USB_DESCRIPTOR_TYPE_HID_REPORT == descriptorType)
541 {
542 /* Get the hid report descriptor */
543 if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE) &&
544 (descriptorIndex == 0U))
545 {
546 commonDescriptor.hidReportDescriptor.interfaceNumber = (uint8_t)setup->wIndex;
547 error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetHidReportDescriptor,
548 &commonDescriptor.hidReportDescriptor);
549 }
550 }
551 else if (USB_DESCRIPTOR_TYPE_HID_PHYSICAL == descriptorType)
552 {
553 /* Get the hid physical descriptor */
554 if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
555 {
556 commonDescriptor.hidPhysicalDescriptor.index = descriptorIndex;
557 commonDescriptor.hidPhysicalDescriptor.interfaceNumber = (uint8_t)setup->wIndex;
558 error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetHidPhysicalDescriptor,
559 &commonDescriptor.hidPhysicalDescriptor);
560 }
561 }
562 #endif
563 #if (defined(USB_DEVICE_CONFIG_CV_TEST) && (USB_DEVICE_CONFIG_CV_TEST > 0U))
564 else if (USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER == descriptorType)
565 {
566 /* Get the device descriptor */
567 if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) &&
568 (descriptorIndex == 0U) && (setup->wIndex == 0U))
569 {
570 error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetDeviceQualifierDescriptor,
571 &commonDescriptor.deviceDescriptor);
572 }
573 }
574 #endif
575 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
576 else if (USB_DESCRIPTOR_TYPE_BOS == descriptorType)
577 {
578 /* Get the configuration descriptor */
579 if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) &&
580 (setup->wIndex == 0U))
581 {
582 commonDescriptor.configurationDescriptor.configuration = descriptorIndex;
583 error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetBOSDescriptor,
584 &commonDescriptor.configurationDescriptor);
585 }
586 }
587 #endif
588 else
589 {
590 }
591 *buffer = commonDescriptor.commonDescriptor.buffer;
592 *length = commonDescriptor.commonDescriptor.length;
593 return error;
594 }
595
596 /*!
597 * @brief Handle get current configuration request.
598 *
599 * This function is used to handle get current configuration request.
600 *
601 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
602 * @param setup The pointer of the setup packet.
603 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
604 * @param length It is an out parameter, the data length.
605 *
606 * @retval kStatus_USB_Success The request is handled successfully.
607 * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
608 * or, the request is unsupported.
609 */
USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)610 static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t *classHandle,
611 usb_setup_struct_t *setup,
612 uint8_t **buffer,
613 uint32_t *length)
614 {
615 uint8_t state = 0U;
616
617 if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_IN) ||
618 ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_DEVICE) ||
619 (setup->wValue != 0U) || (setup->wIndex != 0U) || (setup->wLength != 1U))
620 {
621 return kStatus_USB_InvalidRequest;
622 }
623
624 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
625 if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
626 {
627 return kStatus_USB_Error;
628 }
629 #else
630 (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
631 #endif
632
633 if (((uint8_t)kUSB_DeviceStateAddress != state) && (((uint8_t)kUSB_DeviceStateConfigured != state)))
634 {
635 return kStatus_USB_InvalidRequest;
636 }
637
638 *length = USB_CONFIGURE_SIZE;
639 *buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
640 return USB_DeviceClassCallback(classHandle->handle, (uint8_t)kUSB_DeviceEventGetConfiguration,
641 &classHandle->standardTranscationBuffer);
642 }
643
644 /*!
645 * @brief Handle set current configuration request.
646 *
647 * This function is used to handle set current configuration request.
648 *
649 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
650 * @param setup The pointer of the setup packet.
651 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
652 * @param length It is an out parameter, the data length.
653 *
654 * @retval kStatus_USB_Success The request is handled successfully.
655 * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
656 * or, the request is unsupported.
657 */
USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)658 static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t *classHandle,
659 usb_setup_struct_t *setup,
660 uint8_t **buffer,
661 uint32_t *length)
662 {
663 uint8_t state = 0U;
664 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
665 usb_status_t error = kStatus_USB_InvalidRequest;
666 #endif
667
668 if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_OUT) ||
669 ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_DEVICE) ||
670 (setup->wIndex != 0U) || (setup->wLength != 0U))
671 {
672 return kStatus_USB_InvalidRequest;
673 }
674
675 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
676 if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
677 {
678 return kStatus_USB_Error;
679 }
680 #else
681 (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
682 #endif
683
684 if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state))
685 {
686 return kStatus_USB_InvalidRequest;
687 }
688
689 /* The device state is changed to kUSB_DeviceStateConfigured */
690 state = (uint8_t)kUSB_DeviceStateConfigured;
691 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
692 if (kStatus_USB_Success != USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
693 {
694 return kStatus_USB_Error;
695 }
696 #else
697 (void)USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
698 #endif
699 if (0U == setup->wValue)
700 {
701 /* If the new configuration is zero, the device state is changed to kUSB_DeviceStateAddress */
702 state = (uint8_t)kUSB_DeviceStateAddress;
703 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
704 if (kStatus_USB_Success != USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
705 {
706 return kStatus_USB_Error;
707 }
708 #else
709 (void)USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
710 #endif
711 }
712
713 /* Notify the class layer the configuration is changed */
714 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
715 error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetConfiguration, &setup->wValue);
716 if (kStatus_USB_Success != error)
717 {
718 return error;
719 }
720 #else
721 (void)USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetConfiguration, &setup->wValue);
722 #endif
723 /* Notify the application the configuration is changed */
724 return USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventSetConfiguration, &setup->wValue);
725 }
726
727 /*!
728 * @brief Handle get the alternate setting of a interface request.
729 *
730 * This function is used to handle get the alternate setting of a interface request.
731 *
732 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
733 * @param setup The pointer of the setup packet.
734 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
735 * @param length It is an out parameter, the data length.
736 *
737 * @retval kStatus_USB_Success The request is handled successfully.
738 * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
739 * or, the request is unsupported.
740 */
USB_DeviceCh9GetInterface(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)741 static usb_status_t USB_DeviceCh9GetInterface(usb_device_common_class_struct_t *classHandle,
742 usb_setup_struct_t *setup,
743 uint8_t **buffer,
744 uint32_t *length)
745 {
746 usb_status_t error = kStatus_USB_InvalidRequest;
747 uint8_t state = 0U;
748
749 if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_IN) ||
750 ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_INTERFACE) ||
751 (setup->wValue != 0U) || (setup->wLength != 1U))
752 {
753 return error;
754 }
755
756 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
757 if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
758 {
759 return kStatus_USB_Error;
760 }
761 #else
762 (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
763 #endif
764
765 if (state != (uint8_t)kUSB_DeviceStateConfigured)
766 {
767 return error;
768 }
769 *length = USB_INTERFACE_SIZE;
770 *buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
771 classHandle->standardTranscationBuffer = (uint16_t)(((uint32_t)setup->wIndex & 0xFFU) << 8U);
772 /* The Bit[15~8] is used to save the interface index, and the alternate setting will be saved in Bit[7~0] by
773 * application. */
774 error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetInterface,
775 &classHandle->standardTranscationBuffer);
776 classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
777 return error;
778 }
779
780 /*!
781 * @brief Handle set the alternate setting of a interface request.
782 *
783 * This function is used to handle set the alternate setting of a interface request.
784 *
785 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
786 * @param setup The pointer of the setup packet.
787 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
788 * @param length It is an out parameter, the data length.
789 *
790 * @retval kStatus_USB_Success The request is handled successfully.
791 * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
792 * or, the request is unsupported.
793 */
USB_DeviceCh9SetInterface(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)794 static usb_status_t USB_DeviceCh9SetInterface(usb_device_common_class_struct_t *classHandle,
795 usb_setup_struct_t *setup,
796 uint8_t **buffer,
797 uint32_t *length)
798 {
799 uint8_t state = 0U;
800 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
801 usb_status_t error = kStatus_USB_InvalidRequest;
802 #endif
803
804 if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_OUT) ||
805 ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_INTERFACE) ||
806 (setup->wLength != 0U))
807 {
808 return kStatus_USB_InvalidRequest;
809 }
810
811 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
812 if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
813 {
814 return kStatus_USB_Error;
815 }
816 #else
817 (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
818 #endif
819
820 if (state != (uint8_t)kUSB_DeviceStateConfigured)
821 {
822 return kStatus_USB_InvalidRequest;
823 }
824 classHandle->standardTranscationBuffer = ((setup->wIndex & 0xFFU) << 8U) | (setup->wValue & 0xFFU);
825 /* Notify the class driver the alternate setting of the interface is changed. */
826 /* The Bit[15~8] is used to save the interface index, and the alternate setting is saved in Bit[7~0]. */
827 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
828 error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetInterface,
829 &classHandle->standardTranscationBuffer);
830 if (kStatus_USB_Success != error)
831 {
832 return error;
833 }
834 #else
835 (void)USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetInterface,
836 &classHandle->standardTranscationBuffer);
837 #endif
838 /* Notify the application the alternate setting of the interface is changed. */
839 /* The Bit[15~8] is used to save the interface index, and the alternate setting will is saved in Bit[7~0]. */
840 return USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventSetInterface,
841 &classHandle->standardTranscationBuffer);
842 }
843
844 /*!
845 * @brief Handle get sync frame request.
846 *
847 * This function is used to handle get sync frame request.
848 *
849 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
850 * @param setup The pointer of the setup packet.
851 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
852 * @param length It is an out parameter, the data length.
853 *
854 * @retval kStatus_USB_Success The request is handled successfully.
855 * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state,
856 * or, the request is unsupported.
857 */
USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)858 static usb_status_t USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t *classHandle,
859 usb_setup_struct_t *setup,
860 uint8_t **buffer,
861 uint32_t *length)
862 {
863 usb_status_t error = kStatus_USB_InvalidRequest;
864 uint8_t state = 0U;
865
866 if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_IN) ||
867 ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) ||
868 (setup->wValue != 0U) || (setup->wLength != 2U))
869 {
870 return error;
871 }
872
873 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
874 if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
875 {
876 return kStatus_USB_Error;
877 }
878 #else
879 (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
880 #endif
881
882 if (state != (uint8_t)kUSB_DeviceStateConfigured)
883 {
884 return error;
885 }
886 /* Synch frame is not implemented by any MS devices. Expected response from device will be STALL until a device
887 exists that supports this command. At that time this script will need to be updated to support a
888 response other than STALL */
889 #if (defined(USB_DEVICE_CONFIG_ROOT2_TEST) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
890 return error;
891 #else
892 classHandle->standardTranscationBuffer = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex);
893 /* Get the sync frame value */
894 error =
895 USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusSynchFrame, &classHandle->standardTranscationBuffer);
896 *buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
897 *length = sizeof(classHandle->standardTranscationBuffer);
898 return error;
899 #endif
900 }
901
902 /*!
903 * @brief Send the response to the host.
904 *
905 * This function is used to send the response to the host.
906 *
907 * There are two cases this function will be called.
908 * Case one when a setup packet is received in control endpoint callback function:
909 * 1. If there is not data phase in the setup transfer, the function will prime an IN transfer with the data
910 * length is zero for status phase.
911 * 2. If there is an IN data phase, the function will prime an OUT transfer with the actual length to need to
912 * send for data phase. And then prime an IN transfer with the data length is zero for status phase.
913 * 3. If there is an OUT data phase, the function will prime an IN transfer with the actual length to want to
914 * receive for data phase.
915 *
916 * Case two when is not a setup packet received in control endpoint callback function:
917 * 1. The function will prime an IN transfer with data length is zero for status phase.
918 *
919 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
920 * @param setup The pointer of the setup packet.
921 * @param error The error code returned from the standard request function.
922 * @param stage The stage of the control transfer.
923 * @param buffer It is an out parameter, is used to save the buffer address to response the host's request.
924 * @param length It is an out parameter, the data length.
925 *
926 * @return A USB error code or kStatus_USB_Success.
927 */
USB_DeviceControlCallbackFeedback(usb_device_handle handle,usb_setup_struct_t * setup,usb_status_t error,usb_device_control_read_write_sequence_t stage,uint8_t ** buffer,uint32_t * length)928 static usb_status_t USB_DeviceControlCallbackFeedback(usb_device_handle handle,
929 usb_setup_struct_t *setup,
930 usb_status_t error,
931 usb_device_control_read_write_sequence_t stage,
932 uint8_t **buffer,
933 uint32_t *length)
934 {
935 usb_status_t status;
936
937 if (kStatus_USB_InvalidRequest == error)
938 {
939 /* Stall the control pipe when the request is unsupported. */
940 status = USB_DeviceStallEndpoint(handle, (uint8_t)USB_CONTROL_ENDPOINT);
941 }
942 else
943 {
944 if (*length > setup->wLength)
945 {
946 *length = setup->wLength;
947 }
948
949 if (kStatus_USB_Success == error)
950 {
951 status = USB_DeviceSendRequest(handle, (USB_CONTROL_ENDPOINT), *buffer, *length);
952 }
953 else
954 {
955 status = USB_DeviceSendRequest(handle, (USB_CONTROL_ENDPOINT), (uint8_t *)NULL, 0U);
956 }
957
958 if ((kStatus_USB_Success == status) &&
959 (USB_REQUEST_TYPE_DIR_IN == (setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK)))
960 {
961 status = USB_DeviceRecvRequest(handle, (USB_CONTROL_ENDPOINT), (uint8_t *)NULL, 0U);
962 }
963 }
964
965 return status;
966 }
967
968 /*!
969 * @brief Control endpoint callback function.
970 *
971 * This callback function is used to notify uplayer the transfser result of a transfer.
972 * This callback pointer is passed when a specified endpoint initialized by calling API USB_DeviceInitEndpoint.
973 *
974 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
975 * @param message The result of a transfer, includes transfer buffer, transfer length and whether is in setup
976 * phase for control pipe.
977 * @param callbackParam The parameter for this callback. It is same with
978 * usb_device_endpoint_callback_struct_t::callbackParam.
979 *
980 * @return A USB error code or kStatus_USB_Success.
981 */
USB_DeviceControlCallback(usb_device_handle handle,usb_device_endpoint_callback_message_struct_t * message,void * callbackParam)982 static usb_status_t USB_DeviceControlCallback(usb_device_handle handle,
983 usb_device_endpoint_callback_message_struct_t *message,
984 void *callbackParam)
985 {
986 usb_setup_struct_t *deviceSetup, *setup;
987 usb_device_common_class_struct_t *classHandle;
988 uint8_t *buffer = (uint8_t *)NULL;
989 uint32_t length = 0U;
990 void *temp;
991 usb_status_t status = kStatus_USB_InvalidRequest;
992 uint8_t state = 0U;
993
994 /* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */
995 if (USB_CANCELLED_TRANSFER_LENGTH == message->length)
996 {
997 return kStatus_USB_Success;
998 }
999
1000 if (NULL == callbackParam)
1001 {
1002 return status;
1003 }
1004
1005 classHandle = (usb_device_common_class_struct_t *)callbackParam;
1006 temp = (void *)&classHandle->setupBuffer[0];
1007 deviceSetup = (usb_setup_struct_t *)temp;
1008 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1009 if (kStatus_USB_Success != USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state))
1010 {
1011 return kStatus_USB_Error;
1012 }
1013 #else
1014 (void)USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
1015 #endif
1016
1017 if (0U != message->isSetup)
1018 {
1019 if ((USB_SETUP_PACKET_SIZE != message->length) || (NULL == message->buffer))
1020 {
1021 /* If a invalid setup is received, the control pipes should be de-init and init again.
1022 * Due to the IP can not meet this require, it is reserved for feature.
1023 */
1024 /*
1025 USB_DeviceDeinitEndpoint(handle,
1026 USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
1027 USB_DeviceDeinitEndpoint(handle,
1028 USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
1029 USB_DeviceControlPipeInit(handle, callbackParam);
1030 */
1031 return status;
1032 }
1033 /* Receive a setup request */
1034 temp = (void *)(message->buffer);
1035 setup = (usb_setup_struct_t *)temp;
1036
1037 /* Copy the setup packet to the application buffer */
1038 deviceSetup->wValue = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wValue);
1039 deviceSetup->wIndex = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex);
1040 deviceSetup->wLength = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wLength);
1041 deviceSetup->bRequest = setup->bRequest;
1042 deviceSetup->bmRequestType = setup->bmRequestType;
1043
1044 /* Check the invalid value */
1045 if ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) > USB_REQUEST_TYPE_RECIPIENT_OTHER)
1046 {
1047 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1048 status = USB_DeviceControlCallbackFeedback(handle, deviceSetup, kStatus_USB_InvalidRequest,
1049 kUSB_DeviceControlPipeSetupStage, NULL, NULL);
1050 return kStatus_USB_InvalidRequest;
1051 #else
1052 (void)USB_DeviceControlCallbackFeedback(handle, deviceSetup, kStatus_USB_InvalidRequest,
1053 kUSB_DeviceControlPipeSetupStage, NULL, NULL);
1054 return status;
1055 #endif
1056 }
1057
1058 if ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_STANDARD)
1059 {
1060 /* Handle the standard request, only handle the request in request array. */
1061 if (deviceSetup->bRequest <
1062 ((sizeof(s_UsbDeviceStandardRequest)) / (sizeof(usb_standard_request_callback_t))))
1063 {
1064 if (s_UsbDeviceStandardRequest[deviceSetup->bRequest] != (usb_standard_request_callback_t)NULL)
1065 {
1066 status =
1067 s_UsbDeviceStandardRequest[deviceSetup->bRequest](classHandle, deviceSetup, &buffer, &length);
1068 }
1069 }
1070 }
1071 else
1072 {
1073 if ((0U != deviceSetup->wLength) &&
1074 ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT))
1075 {
1076 /* Class or vendor request with the OUT data phase. */
1077 if ((0U != deviceSetup->wLength) &&
1078 ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_CLASS))
1079 {
1080 /* Get data buffer to receive the data from the host. */
1081 usb_device_control_request_struct_t controlRequest;
1082 controlRequest.buffer = (uint8_t *)NULL;
1083 controlRequest.isSetup = 1U;
1084 controlRequest.setup = deviceSetup;
1085 controlRequest.length = deviceSetup->wLength;
1086 status = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest);
1087 length = controlRequest.length;
1088 buffer = controlRequest.buffer;
1089 }
1090 else if ((0U != deviceSetup->wLength) &&
1091 ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_VENDOR))
1092 {
1093 /* Get data buffer to receive the data from the host. */
1094 usb_device_control_request_struct_t controlRequest;
1095 controlRequest.buffer = (uint8_t *)NULL;
1096 controlRequest.isSetup = 1U;
1097 controlRequest.setup = deviceSetup;
1098 controlRequest.length = deviceSetup->wLength;
1099 status = USB_DeviceClassCallback(handle, (uint32_t)kUSB_DeviceEventVendorRequest, &controlRequest);
1100 length = controlRequest.length;
1101 buffer = controlRequest.buffer;
1102 }
1103 else
1104 {
1105 /*no action*/
1106 }
1107 if (kStatus_USB_Success == status)
1108 {
1109 /* Prime an OUT transfer */
1110 if (length > deviceSetup->wLength)
1111 {
1112 length = deviceSetup->wLength;
1113 }
1114 status = USB_DeviceRecvRequest(handle, USB_CONTROL_ENDPOINT, buffer, length);
1115 return status;
1116 }
1117 else
1118 {
1119 /* Other error codes, will stall control endpoint */
1120 status = kStatus_USB_InvalidRequest;
1121 }
1122 }
1123 else
1124 {
1125 /* Class or vendor request with the IN data phase. */
1126 if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_CLASS))
1127 {
1128 /* Get data buffer to response the host. */
1129 usb_device_control_request_struct_t controlRequest;
1130 controlRequest.buffer = (uint8_t *)NULL;
1131 controlRequest.isSetup = 1U;
1132 controlRequest.setup = deviceSetup;
1133 controlRequest.length = deviceSetup->wLength;
1134 status = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest);
1135 length = controlRequest.length;
1136 buffer = controlRequest.buffer;
1137 }
1138 else if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_VENDOR))
1139 {
1140 /* Get data buffer to response the host. */
1141 usb_device_control_request_struct_t controlRequest;
1142 controlRequest.buffer = (uint8_t *)NULL;
1143 controlRequest.isSetup = 1U;
1144 controlRequest.setup = deviceSetup;
1145 controlRequest.length = deviceSetup->wLength;
1146 status = USB_DeviceClassCallback(handle, (uint32_t)kUSB_DeviceEventVendorRequest, &controlRequest);
1147 length = controlRequest.length;
1148 buffer = controlRequest.buffer;
1149 }
1150 else
1151 {
1152 /*no action*/
1153 }
1154 }
1155 }
1156 /* Buffer that is equal to NULL means the application or classs driver does not prepare a buffer for
1157 sending or receiving the data, so control endpoint will be stalled here. */
1158 if ((0U != length) && (NULL == buffer))
1159 {
1160 status = kStatus_USB_InvalidRequest;
1161 }
1162 /* Send the response to the host. */
1163 status = USB_DeviceControlCallbackFeedback(handle, deviceSetup, status, kUSB_DeviceControlPipeSetupStage,
1164 &buffer, &length);
1165 }
1166 else if ((uint8_t)kUSB_DeviceStateAddressing == state)
1167 {
1168 if (USB_REQUEST_STANDARD_SET_ADDRESS == deviceSetup->bRequest)
1169 {
1170 /* Set the device address to controller. */
1171 status = s_UsbDeviceStandardRequest[deviceSetup->bRequest](classHandle, deviceSetup, &buffer, &length);
1172 }
1173 }
1174 #if ((defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \
1175 (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \
1176 (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
1177 else if ((uint8_t)kUSB_DeviceStateTestMode == state)
1178 {
1179 uint8_t portTestControl = (uint8_t)(deviceSetup->wIndex >> 8);
1180 /* Set the controller.into test mode. */
1181 status = USB_DeviceSetStatus(handle, kUSB_DeviceStatusTestMode, &portTestControl);
1182 }
1183 #endif
1184 else if ((0U != message->length) && (0U != deviceSetup->wLength) &&
1185 ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT))
1186 {
1187 if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_CLASS))
1188 {
1189 /* Data received in OUT phase, and notify the class driver. */
1190 usb_device_control_request_struct_t controlRequest;
1191 controlRequest.buffer = message->buffer;
1192 controlRequest.isSetup = 0U;
1193 controlRequest.setup = deviceSetup;
1194 controlRequest.length = message->length;
1195 status = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest);
1196 }
1197 else if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_VENDOR))
1198 {
1199 /* Data received in OUT phase, and notify the application. */
1200 usb_device_control_request_struct_t controlRequest;
1201 controlRequest.buffer = message->buffer;
1202 controlRequest.isSetup = 0U;
1203 controlRequest.setup = deviceSetup;
1204 controlRequest.length = message->length;
1205 status = USB_DeviceClassCallback(handle, (uint32_t)kUSB_DeviceEventVendorRequest, &controlRequest);
1206 }
1207 else
1208 {
1209 /*no action*/
1210 }
1211 /* Send the response to the host. */
1212 status = USB_DeviceControlCallbackFeedback(handle, deviceSetup, status, kUSB_DeviceControlPipeDataStage,
1213 &buffer, &length);
1214 }
1215 else
1216 {
1217 /*no action*/
1218 }
1219 return status;
1220 }
1221
1222 /*!
1223 * @brief Control endpoint initialization function.
1224 *
1225 * This callback function is used to initialize the control pipes.
1226 *
1227 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
1228 * @param param The up layer handle.
1229 *
1230 * @return A USB error code or kStatus_USB_Success.
1231 */
USB_DeviceControlPipeInit(usb_device_handle handle,void * param)1232 usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle, void *param)
1233 {
1234 usb_device_endpoint_init_struct_t epInitStruct;
1235 usb_device_endpoint_callback_struct_t epCallback;
1236 usb_status_t status;
1237
1238 epCallback.callbackFn = USB_DeviceControlCallback;
1239 epCallback.callbackParam = param;
1240
1241 epInitStruct.zlt = 1U;
1242 epInitStruct.transferType = USB_ENDPOINT_CONTROL;
1243 epInitStruct.interval = 0;
1244 epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
1245 epInitStruct.maxPacketSize = USB_CONTROL_MAX_PACKET_SIZE;
1246 /* Initialize the control IN pipe */
1247 status = USB_DeviceInitEndpoint(handle, &epInitStruct, &epCallback);
1248
1249 if (kStatus_USB_Success != status)
1250 {
1251 return status;
1252 }
1253 epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
1254 /* Initialize the control OUT pipe */
1255 status = USB_DeviceInitEndpoint(handle, &epInitStruct, &epCallback);
1256
1257 if (kStatus_USB_Success != status)
1258 {
1259 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1260 if (kStatus_USB_Success !=
1261 USB_DeviceDeinitEndpoint(
1262 handle, USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)))
1263 {
1264 return kStatus_USB_Error;
1265 }
1266 #else
1267 (void)USB_DeviceDeinitEndpoint(
1268 handle, USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
1269 #endif
1270 return status;
1271 }
1272
1273 return kStatus_USB_Success;
1274 }
1275 #endif /* USB_DEVICE_CONFIG_NUM */
1276