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_host_config.h"
10 #include "usb_host.h"
11 #include "usb_host_hci.h"
12 #include "usb_host_devices.h"
13 #include "usb_host_framework.h"
14 /*******************************************************************************
15 * Definitions
16 ******************************************************************************/
17
18 /* Component ID definition, used by tools. */
19 #ifndef FSL_COMPONENT_ID
20 #define FSL_COMPONENT_ID "middleware.usb.host.fatfs_usb_stack"
21 #endif
22
23 /*******************************************************************************
24 * Prototypes
25 ******************************************************************************/
26
27 /*******************************************************************************
28 * Variables
29 ******************************************************************************/
30
31 /*******************************************************************************
32 * Code
33 ******************************************************************************/
34
USB_HostCh9RequestCommon(usb_host_device_instance_t * deviceInstance,usb_host_transfer_t * transfer,uint8_t * buffer,uint32_t bufferLen)35 usb_status_t USB_HostCh9RequestCommon(usb_host_device_instance_t *deviceInstance,
36 usb_host_transfer_t *transfer,
37 uint8_t *buffer,
38 uint32_t bufferLen)
39 {
40 /* initialize transfer */
41 transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN((uint16_t)bufferLen);
42 transfer->transferBuffer = buffer;
43 transfer->transferLength = bufferLen;
44
45 if (USB_HostSendSetup(deviceInstance->hostHandle, deviceInstance->controlPipe, transfer) !=
46 kStatus_USB_Success) /* send setup transfer */
47 {
48 #ifdef HOST_ECHO
49 usb_echo("failed for USB_HostSendSetup\r\n");
50 #endif
51 (void)USB_HostFreeTransfer(deviceInstance->hostHandle, transfer);
52 return kStatus_USB_Error;
53 }
54 return kStatus_USB_Success;
55 }
56
USB_HostStandardGetStatus(usb_host_device_instance_t * deviceInstance,usb_host_transfer_t * transfer,void * param)57 usb_status_t USB_HostStandardGetStatus(usb_host_device_instance_t *deviceInstance,
58 usb_host_transfer_t *transfer,
59 void *param)
60 {
61 usb_host_get_status_param_t *statusParam;
62 uint8_t length;
63
64 /* initialize transfer */
65 statusParam = (usb_host_get_status_param_t *)param;
66 transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_STANDARD;
67 if (statusParam->requestType == (uint8_t)kRequestDevice)
68 {
69 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_DEVICE;
70 }
71 else if (statusParam->requestType == (uint8_t)kRequestInterface)
72 {
73 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
74 }
75 else
76 {
77 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
78 }
79 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(statusParam->statusSelector);
80
81 length = 2;
82 if (statusParam->statusSelector == USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR)
83 {
84 length = 1;
85 }
86 return USB_HostCh9RequestCommon(deviceInstance, transfer, statusParam->statusBuffer, length);
87 }
88
USB_HostStandardSetClearFeature(usb_host_device_instance_t * deviceInstance,usb_host_transfer_t * transfer,void * param)89 usb_status_t USB_HostStandardSetClearFeature(usb_host_device_instance_t *deviceInstance,
90 usb_host_transfer_t *transfer,
91 void *param)
92 {
93 usb_host_process_feature_param_t *featureParam;
94
95 /* initialize transfer */
96 featureParam = (usb_host_process_feature_param_t *)param;
97 if (featureParam->requestType == (uint8_t)kRequestDevice)
98 {
99 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_DEVICE;
100 }
101 else if (featureParam->requestType == (uint8_t)kRequestInterface)
102 {
103 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
104 }
105 else
106 {
107 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
108 }
109 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(featureParam->featureSelector);
110 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(featureParam->interfaceOrEndpoint);
111
112 return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
113 }
114
USB_HostStandardSetAddress(usb_host_device_instance_t * deviceInstance,usb_host_transfer_t * transfer,void * param)115 usb_status_t USB_HostStandardSetAddress(usb_host_device_instance_t *deviceInstance,
116 usb_host_transfer_t *transfer,
117 void *param)
118 {
119 uint8_t address;
120
121 /* initialize transfer */
122 address = *(uint8_t *)param;
123 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(address);
124
125 return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
126 }
127
USB_HostStandardSetGetDescriptor(usb_host_device_instance_t * deviceInstance,usb_host_transfer_t * transfer,void * param)128 usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
129 usb_host_transfer_t *transfer,
130 void *param)
131 {
132 usb_host_process_descriptor_param_t *descriptorParam;
133
134 /* initialize transfer */
135 descriptorParam = (usb_host_process_descriptor_param_t *)param;
136 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(
137 (uint16_t)((uint16_t)descriptorParam->descriptorType << 8) | descriptorParam->descriptorIndex);
138 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(descriptorParam->languageId);
139 return USB_HostCh9RequestCommon(deviceInstance, transfer, descriptorParam->descriptorBuffer,
140 descriptorParam->descriptorLength);
141 }
142
USB_HostStandardGetInterface(usb_host_device_instance_t * deviceInstance,usb_host_transfer_t * transfer,void * param)143 usb_status_t USB_HostStandardGetInterface(usb_host_device_instance_t *deviceInstance,
144 usb_host_transfer_t *transfer,
145 void *param)
146 {
147 usb_host_get_interface_param_t *interfaceParam;
148
149 /* initialize transfer */
150 interfaceParam = (usb_host_get_interface_param_t *)param;
151 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
152 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
153 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(interfaceParam->interface);
154
155 return USB_HostCh9RequestCommon(deviceInstance, transfer, interfaceParam->alternateInterfaceBuffer, 1);
156 }
157
USB_HostStandardSetInterface(usb_host_device_instance_t * deviceInstance,usb_host_transfer_t * transfer,void * param)158 usb_status_t USB_HostStandardSetInterface(usb_host_device_instance_t *deviceInstance,
159 usb_host_transfer_t *transfer,
160 void *param)
161 {
162 usb_host_set_interface_param_t *setParam;
163
164 /* initialize transfer */
165 setParam = (usb_host_set_interface_param_t *)param;
166 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
167 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(setParam->interface);
168 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(setParam->alternateSetting);
169
170 return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
171 }
172
USB_HostStandardSyncFrame(usb_host_device_instance_t * deviceInstance,usb_host_transfer_t * transfer,void * param)173 usb_status_t USB_HostStandardSyncFrame(usb_host_device_instance_t *deviceInstance,
174 usb_host_transfer_t *transfer,
175 void *param)
176 {
177 usb_host_synch_frame_param_t *frameParam;
178
179 /* initialize transfer */
180 frameParam = (usb_host_synch_frame_param_t *)param;
181 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
182 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
183 transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(frameParam->endpoint);
184
185 return USB_HostCh9RequestCommon(deviceInstance, transfer, frameParam->frameNumberBuffer, 2);
186 }
187
USB_HostRequestControl(usb_device_handle deviceHandle,uint8_t usbRequest,usb_host_transfer_t * transfer,void * param)188 usb_status_t USB_HostRequestControl(usb_device_handle deviceHandle,
189 uint8_t usbRequest,
190 usb_host_transfer_t *transfer,
191 void *param)
192 {
193 usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
194 usb_status_t status = kStatus_USB_Error;
195
196 if (deviceHandle == NULL)
197 {
198 return kStatus_USB_InvalidHandle;
199 }
200
201 /* reset transfer fields */
202 transfer->setupPacket->bmRequestType = 0x00;
203 transfer->setupPacket->bRequest = usbRequest;
204 transfer->setupPacket->wIndex = 0;
205 transfer->setupPacket->wLength = 0;
206 transfer->setupPacket->wValue = 0;
207
208 switch (usbRequest)
209 {
210 case USB_REQUEST_STANDARD_GET_STATUS: /* standard get status request */
211 status = USB_HostStandardGetStatus(deviceInstance, transfer, param);
212 break;
213
214 case USB_REQUEST_STANDARD_CLEAR_FEATURE: /* standard clear status request */
215 case USB_REQUEST_STANDARD_SET_FEATURE: /* standard set feature request */
216 status = USB_HostStandardSetClearFeature(deviceInstance, transfer, param);
217 break;
218
219 case USB_REQUEST_STANDARD_SET_ADDRESS: /* standard set address request */
220 status = USB_HostStandardSetAddress(deviceInstance, transfer, param);
221 break;
222
223 case USB_REQUEST_STANDARD_GET_DESCRIPTOR: /* standard get descriptor request */
224 case USB_REQUEST_STANDARD_SET_DESCRIPTOR: /* standard set descriptor request */
225 if (usbRequest == USB_REQUEST_STANDARD_GET_DESCRIPTOR)
226 {
227 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
228 }
229 status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, param);
230 break;
231
232 case USB_REQUEST_STANDARD_GET_CONFIGURATION: /* standard get configuration descriptor request */
233 transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
234 status =
235 USB_HostCh9RequestCommon((usb_host_device_instance_t *)deviceHandle, transfer, (uint8_t *)param, 1);
236 break;
237
238 case USB_REQUEST_STANDARD_SET_CONFIGURATION: /* standard set configuration request */
239 transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(*((uint8_t *)param));
240 status = USB_HostCh9RequestCommon((usb_host_device_instance_t *)deviceHandle, transfer, NULL, 0);
241 break;
242
243 case USB_REQUEST_STANDARD_GET_INTERFACE: /* standard get interface request */
244 status = USB_HostStandardGetInterface(deviceInstance, transfer, param);
245 break;
246
247 case USB_REQUEST_STANDARD_SET_INTERFACE: /* standard set interface request */
248 status = USB_HostStandardSetInterface(deviceInstance, transfer, param);
249 break;
250
251 case USB_REQUEST_STANDARD_SYNCH_FRAME: /* standard synch frame request */
252 status = USB_HostStandardSyncFrame(deviceInstance, transfer, param);
253 break;
254
255 default:
256 /*no action*/
257 break;
258 }
259
260 return status;
261 }
262