| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
DeviceStandardReq.c
Go to the documentation of this file.
1 /*
2 * @brief USB device standard request management
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * Copyright(C) Dean Camera, 2011, 2012
7 * All rights reserved.
8 *
9 * @par
10 * Software that is described herein is for illustrative purposes only
11 * which provides customers with programming information regarding the
12 * LPC products. This software is supplied "AS IS" without any warranties of
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
14 * all warranties, express or implied, including all implied warranties of
15 * merchantability, fitness for a particular purpose and non-infringement of
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
17 * or liability for the use of the software, conveys no license or rights under any
18 * patent, copyright, mask work right, or any other intellectual property rights in
19 * or to any products. NXP Semiconductors reserves the right to make changes
20 * in the software without notification. NXP Semiconductors also makes no
21 * representation or warranty that such application will be suitable for the
22 * specified use without further testing or modification.
23 *
24 * @par
25 * Permission to use, copy, modify, and distribute this software and its
26 * documentation is hereby granted, under NXP Semiconductors' and its
27 * licensor's relevant copyrights in the software, without fee, provided that it
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
29 * copyright, permission, and disclaimer notice must appear in all copies of
30 * this code.
31 */
32
33
34 #define __INCLUDE_FROM_USB_DRIVER
35 #include "USBMode.h"
36
37 #if defined(USB_CAN_BE_DEVICE)
38
39 #define __INCLUDE_FROM_DEVICESTDREQ_C
40 #include "DeviceStandardReq.h"
41
42 uint8_t USB_Device_ConfigurationNumber;
43
44 #if !defined(NO_DEVICE_SELF_POWER)
45 bool USB_Device_CurrentlySelfPowered;
46 #endif
47
48 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
49 bool USB_Device_RemoteWakeupEnabled;
50 #endif
51
52 void USB_Device_ProcessControlRequest(uint8_t corenum)
53 {
54 // USB_ControlRequest.bmRequestType = Endpoint_Read_8();
55 // USB_ControlRequest.bRequest = Endpoint_Read_8();
56 // USB_ControlRequest.wValue = Endpoint_Read_16_LE();
57 // USB_ControlRequest.wIndex = Endpoint_Read_16_LE();
58 // USB_ControlRequest.wLength = Endpoint_Read_16_LE();
59
60 Endpoint_GetSetupPackage(corenum, (uint8_t*) &USB_ControlRequest);
61
62 EVENT_USB_Device_ControlRequest();
63
64 if (Endpoint_IsSETUPReceived(corenum))
65 {
66 uint8_t bmRequestType = USB_ControlRequest.bmRequestType;
67
68 switch (USB_ControlRequest.bRequest)
69 {
70 case REQ_GetStatus:
71 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
72 (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
73 {
74 USB_Device_GetStatus(corenum);
75 }
76
77 break;
78 case REQ_ClearFeature:
79 case REQ_SetFeature:
80 if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||
81 (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))
82 {
83 USB_Device_ClearSetFeature(corenum);
84 }
85
86 break;
87 case REQ_SetAddress:
88 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
89 USB_Device_SetAddress(corenum);
90
91 break;
92 case REQ_GetDescriptor:
93 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
94 (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
95 {
96 USB_Device_GetDescriptor(corenum);
97 }
98
99 break;
100 case REQ_GetConfiguration:
101 if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
102 USB_Device_GetConfiguration(corenum);
103
104 break;
105 case REQ_SetConfiguration:
106 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
107 USB_Device_SetConfiguration(corenum);
108
109 break;
110 }
111 }
112
113 if (Endpoint_IsSETUPReceived(corenum))
114 {
115 Endpoint_ClearSETUP(corenum);
116 Endpoint_StallTransaction(corenum);
117 }
118 }
119
120 static void USB_Device_SetAddress(uint8_t corenum)
121 {
122 uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);
123 uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
124 GlobalInterruptDisable();
125
126 Endpoint_ClearSETUP(corenum);
127
128 Endpoint_ClearStatusStage(corenum);
129
130 while (!(Endpoint_IsINReady(corenum)));
131
132 USB_Device_SetDeviceAddress(corenum, DeviceAddress);
133 USB_DeviceState[corenum] = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
134
135 SetGlobalInterruptMask(CurrentGlobalInt);
136 }
137
138 static void USB_Device_SetConfiguration(uint8_t corenum)
139 {
140 #if defined(FIXED_NUM_CONFIGURATIONS)
141 if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
142 return;
143 #else
144 USB_Descriptor_Device_t* DevDescriptorPtr;
145
146 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
147 #if defined(USE_FLASH_DESCRIPTORS)
148 #define MemoryAddressSpace MEMSPACE_FLASH
149 #elif defined(USE_EEPROM_DESCRIPTORS)
150 #define MemoryAddressSpace MEMSPACE_EEPROM
151 #elif defined(USE_RAM_DESCRIPTORS)
152 #define MemoryAddressSpace MEMSPACE_SRAM
153 #else
154 uint8_t MemoryAddressSpace;
155 #endif
156 #endif
157
158 if (CALLBACK_USB_GetDescriptor(corenum, (DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
159 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
160 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
161 , &MemoryAddressSpace
162 #endif
163 ) == NO_DESCRIPTOR)
164 {
165 return;
166 }
167
168 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
169 if (MemoryAddressSpace == MEMSPACE_FLASH)
170 {
171 if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
172 return;
173 }
174 else if (MemoryAddressSpace == MEMSPACE_EEPROM)
175 {
176 if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
177 return;
178 }
179 else
180 {
181 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
182 return;
183 }
184 #else
185 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
186 return;
187 #endif
188 #endif
189
190 Endpoint_ClearSETUP(corenum);
191
192 USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
193
194 Endpoint_ClearStatusStage(corenum);
195
196 if (USB_Device_ConfigurationNumber)
197 USB_DeviceState[corenum] = DEVICE_STATE_Configured;
198 else
199 USB_DeviceState[corenum] = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
200
201 EVENT_USB_Device_ConfigurationChanged();
202 }
203
204 static void USB_Device_GetConfiguration(uint8_t corenum)
205 {
206 Endpoint_ClearSETUP(corenum);
207
208 Endpoint_Write_8(corenum, USB_Device_ConfigurationNumber);
209 Endpoint_ClearIN(corenum);
210
211 Endpoint_ClearStatusStage(corenum);
212 }
213
214 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
215 static void USB_Device_GetInternalSerialDescriptor(uint8_t corenum)
216 {
217 struct
218 {
219 USB_Descriptor_Header_t Header;
220 uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];
221 } SignatureDescriptor;
222
223 SignatureDescriptor.Header.Type = DTYPE_String;
224 SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4);
225
226 USB_Device_GetSerialString(SignatureDescriptor.UnicodeString);
227
228 Endpoint_ClearSETUP(corenum);
229
230 Endpoint_Write_Control_Stream_LE(corenum, &SignatureDescriptor, sizeof(SignatureDescriptor));
231 Endpoint_ClearOUT(corenum);
232 }
233 #endif
234
235 static void USB_Device_GetDescriptor(uint8_t corenum)
236 {
237 const void* DescriptorPointer;
238 uint16_t DescriptorSize;
239
240 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
241 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
242 uint8_t DescriptorAddressSpace;
243 #endif
244
245 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
246 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
247 {
248 USB_Device_GetInternalSerialDescriptor(corenum);
249 return;
250 }
251 #endif
252
253 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(corenum, USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
254 &DescriptorPointer
255 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
256 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
257 , &DescriptorAddressSpace
258 #endif
259 )) == NO_DESCRIPTOR)
260 {
261 return;
262 }
263
264 Endpoint_ClearSETUP(corenum);
265
266 #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
267 Endpoint_Write_Control_Stream_LE(corenum, DescriptorPointer, DescriptorSize);
268 #elif defined(USE_EEPROM_DESCRIPTORS)
269 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
270 #elif defined(USE_FLASH_DESCRIPTORS)
271 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
272 #else
273 if (DescriptorAddressSpace == MEMSPACE_FLASH)
274 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
275 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
276 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
277 else
278 Endpoint_Write_Control_Stream_LE(corenum, DescriptorPointer, DescriptorSize);
279 #endif
280
281 Endpoint_ClearOUT(corenum);
282 }
283
284 static void USB_Device_GetStatus(uint8_t corenum)
285 {
286 uint8_t CurrentStatus = 0;
287
288 switch (USB_ControlRequest.bmRequestType)
289 {
290 #if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
291 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
292 #if !defined(NO_DEVICE_SELF_POWER)
293 if (USB_Device_CurrentlySelfPowered)
294 CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
295 #endif
296
297 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
298 if (USB_Device_RemoteWakeupEnabled)
299 CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
300 #endif
301 break;
302 #endif
303 #if !defined(CONTROL_ONLY_DEVICE)
304 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
305 Endpoint_SelectEndpoint(corenum, (uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
306
307 CurrentStatus = Endpoint_IsStalled(corenum);
308
309 Endpoint_SelectEndpoint(corenum, ENDPOINT_CONTROLEP);
310
311 break;
312 #endif
313 default:
314 return;
315 }
316
317 Endpoint_ClearSETUP(corenum);
318
319 Endpoint_Write_16_LE(corenum, CurrentStatus);
320 Endpoint_ClearIN(corenum);
321
322 Endpoint_ClearStatusStage(corenum);
323 }
324
325 static void USB_Device_ClearSetFeature(uint8_t corenum)
326 {
327 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
328 {
329 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
330 case REQREC_DEVICE:
331 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)
332 USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
333 else
334 return;
335
336 break;
337 #endif
338 #if !defined(CONTROL_ONLY_DEVICE)
339 case REQREC_ENDPOINT:
340 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt)
341 {
342 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
343
344 if (EndpointIndex == ENDPOINT_CONTROLEP)
345 return;
346
347 Endpoint_SelectEndpoint(corenum, EndpointIndex);
348
349 if (Endpoint_IsEnabled())
350 {
351 if (USB_ControlRequest.bRequest == REQ_SetFeature)
352 {
353 Endpoint_StallTransaction(corenum);
354 }
355 else
356 {
357 Endpoint_ClearStall(corenum);
358 Endpoint_ResetEndpoint(EndpointIndex);
359 Endpoint_ResetDataToggle(corenum);
360 }
361 }
362 }
363
364 break;
365 #endif
366 default:
367 return;
368 }
369
370 Endpoint_SelectEndpoint(corenum, ENDPOINT_CONTROLEP);
371
372 Endpoint_ClearSETUP(corenum);
373
374 Endpoint_ClearStatusStage(corenum);
375 }
376
377 #endif
378