DeviceStandardReq.c 10.2 KB
Newer Older
1
2
3
/*
             LUFA Library
     Copyright (C) Dean Camera, 2010.
4

5
6
7
8
9
10
11
  dean [at] fourwalledcubicle [dot] com
      www.fourwalledcubicle.com
*/

/*
  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)

12
  Permission to use, copy, modify, distribute, and sell this
13
  software and its documentation for any purpose is hereby granted
14
  without fee, provided that the above copyright notice appear in
15
  all copies and that both that the copyright notice and this
16
17
18
  permission notice and warranty disclaimer appear in supporting
  documentation, and that the name of the author not be used in
  advertising or publicity pertaining to distribution of the
19
20
21
22
23
24
25
26
27
28
29
30
31
  software without specific, written prior permission.

  The author disclaim all warranties with regard to this
  software, including all implied warranties of merchantability
  and fitness.  In no event shall the author be liable for any
  special, indirect or consequential damages or any damages
  whatsoever resulting from loss of use, data or profits, whether
  in an action of contract, negligence or other tortious action,
  arising out of or in connection with the use or performance of
  this software.
*/

#define  __INCLUDE_FROM_USB_DRIVER
32
#include "USBMode.h"
33
34
35

#if defined(USB_CAN_BE_DEVICE)

36
37
#define  __INCLUDE_FROM_DEVICESTDREQ_C
#include "DeviceStandardReq.h"
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

uint8_t USB_ConfigurationNumber;

#if !defined(NO_DEVICE_SELF_POWER)
bool    USB_CurrentlySelfPowered;
#endif

#if !defined(NO_DEVICE_REMOTE_WAKEUP)
bool    USB_RemoteWakeupEnabled;
#endif

void USB_Device_ProcessControlRequest(void)
{
	bool     RequestHandled = false;
	uint8_t* RequestHeader  = (uint8_t*)&USB_ControlRequest;
53

54
55
	for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)
	  *(RequestHeader++) = Endpoint_Read_Byte();
56

57
	uint8_t bmRequestType = USB_ControlRequest.bmRequestType;
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
	switch (USB_ControlRequest.bRequest)
	{
		case REQ_GetStatus:
			if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
			    (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
			{
				USB_Device_GetStatus();
				RequestHandled = true;
			}

			break;
		case REQ_ClearFeature:
		case REQ_SetFeature:
			if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||
			    (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))
			{
				USB_Device_ClearSetFeature();
				RequestHandled = true;
			}

			break;
		case REQ_SetAddress:
			if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
			{
				USB_Device_SetAddress();
				RequestHandled = true;
			}

			break;
		case REQ_GetDescriptor:
			if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
			    (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
			{
				USB_Device_GetDescriptor();
				RequestHandled = true;
			}
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
			break;
		case REQ_GetConfiguration:
			if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
			{
				USB_Device_GetConfiguration();
				RequestHandled = true;
			}

			break;
		case REQ_SetConfiguration:
			if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
			{
				USB_Device_SetConfiguration();
				RequestHandled = true;
			}

			break;
	}

	if (!(RequestHandled))
	  EVENT_USB_Device_UnhandledControlRequest();
117

118
119
120
	if (Endpoint_IsSETUPReceived())
	{
		Endpoint_StallTransaction();
121
		Endpoint_ClearSETUP();
122
123
124
125
126
127
128
	}
}

static void USB_Device_SetAddress(void)
{
	uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);

129
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
130
	{
131
		Endpoint_ClearSETUP();
132

133
		Endpoint_ClearStatusStage();
134

135
		while (!(Endpoint_IsINReady()));
136

137
		USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
138

139
140
		USB_Device_SetDeviceAddress(DeviceAddress);
	}
141
142
143
144
}

static void USB_Device_SetConfiguration(void)
{
145
	#if defined(FIXED_NUM_CONFIGURATIONS)
146
147
	if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
	  return;
148
149
150
	#else
	USB_Descriptor_Device_t* DevDescriptorPtr;

151
152
153
154
155
156
157
158
159
	#if defined(USE_FLASH_DESCRIPTORS)
		#define MemoryAddressSpace  MEMSPACE_FLASH
	#elif defined(USE_EEPROM_DESCRIPTORS)
		#define MemoryAddressSpace  MEMSPACE_EEPROM
	#elif defined(USE_SRAM_DESCRIPTORS)
		#define MemoryAddressSpace  MEMSPACE_SRAM
	#else
		uint8_t MemoryAddressSpace;
	#endif
160

161
162
163
164
165
166
167
168
	if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
	                               , &MemoryAddressSpace
	#endif
	                               ) == NO_DESCRIPTOR)
	{
		return;
	}
169

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
	if (MemoryAddressSpace == MEMSPACE_FLASH)
	{
		if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
		  return;
	}
	else if (MemoryAddressSpace == MEMSPACE_EEPROM)
	{
		if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
		  return;
	}
	else
	{
		if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
		  return;
	}
185
	#endif
186

187
188
189
190
191
192
	Endpoint_ClearSETUP();

	USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;

	Endpoint_ClearStatusStage();

193
194
195
196
	if (USB_ConfigurationNumber)
	  USB_DeviceState = DEVICE_STATE_Configured;
	else
	  USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
197
198
199
200

	EVENT_USB_Device_ConfigurationChanged();
}

201
static void USB_Device_GetConfiguration(void)
202
203
204
205
206
207
208
209
210
{
	Endpoint_ClearSETUP();

	Endpoint_Write_Byte(USB_ConfigurationNumber);
	Endpoint_ClearIN();

	Endpoint_ClearStatusStage();
}

211
#if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
212
213
static char USB_Device_NibbleToASCII(uint8_t Nibble)
{
214
215
	Nibble &= 0x0F;
	return (Nibble >= 10) ? (('A' - 10) + Nibble) : ('0' + Nibble);
216
217
218
219
220
221
222
}

static void USB_Device_GetInternalSerialDescriptor(void)
{
	struct
	{
		USB_Descriptor_Header_t Header;
223
		wchar_t                 UnicodeString[20];
224
225
226
227
	} SignatureDescriptor;

	SignatureDescriptor.Header.Type = DTYPE_String;
	SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor);
228

229
230
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
	{
231
232
		uint8_t SigReadAddress = 0x0E;

233
234
235
		for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
		{
			uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
236

237
238
239
240
241
			if (SerialCharNum & 0x01)
			{
				SerialByte >>= 4;
				SigReadAddress++;
			}
242

243
244
245
			SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);
		}
	}
246

247
248
249
250
251
252
253
254
255
256
	Endpoint_ClearSETUP();

	Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));

	Endpoint_ClearOUT();
}
#endif

static void USB_Device_GetDescriptor(void)
{
257
258
	const void* DescriptorPointer;
	uint16_t    DescriptorSize;
259

260
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
261
	uint8_t DescriptorAddressSpace;
262
	#endif
263

264
	#if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
265
266
267
268
269
270
	if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
	{
		USB_Device_GetInternalSerialDescriptor();
		return;
	}
	#endif
271

272
273
274
275
276
277
278
279
280
	if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
	                                                 &DescriptorPointer
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
	                                                 , &DescriptorAddressSpace
	#endif
													 )) == NO_DESCRIPTOR)
	{
		return;
	}
281

282
283
284
285
286
287
288
	Endpoint_ClearSETUP();

	#if defined(USE_RAM_DESCRIPTORS)
	Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
	#elif defined(USE_EEPROM_DESCRIPTORS)
	Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
	#elif defined(USE_FLASH_DESCRIPTORS)
289
	Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
290
291
	#else
	if (DescriptorAddressSpace == MEMSPACE_FLASH)
292
	  Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
293
294
295
	else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
	  Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
	else
296
	  Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
297
298
299
300
301
302
303
304
305
306
307
	#endif

	Endpoint_ClearOUT();
}

static void USB_Device_GetStatus(void)
{
	uint8_t CurrentStatus = 0;

	switch (USB_ControlRequest.bmRequestType)
	{
308
		#if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
309
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
310
			#if !defined(NO_DEVICE_SELF_POWER)
311
312
			if (USB_CurrentlySelfPowered)
			  CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
313
			#endif
314

315
			#if !defined(NO_DEVICE_REMOTE_WAKEUP)
316
317
			if (USB_RemoteWakeupEnabled)
			  CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
318
			#endif
319
			break;
320
321
		#endif
		#if !defined(CONTROL_ONLY_DEVICE)
322
323
324
325
326
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
			Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);

			CurrentStatus = Endpoint_IsStalled();

327
			Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
328
329

			break;
330
		#endif
331
332
333
334
335
336
337
338
		default:
			return;
	}

	Endpoint_ClearSETUP();

	Endpoint_Write_Word_LE(CurrentStatus);
	Endpoint_ClearIN();
339

340
341
342
343
344
345
346
	Endpoint_ClearStatusStage();
}

static void USB_Device_ClearSetFeature(void)
{
	switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
	{
347
		#if !defined(NO_DEVICE_REMOTE_WAKEUP)
348
349
350
351
352
		case REQREC_DEVICE:
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
			  USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
			else
			  return;
353
354

			break;
355
356
		#endif
		#if !defined(CONTROL_ONLY_DEVICE)
357
358
359
360
		case REQREC_ENDPOINT:
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
			{
				uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
361

362
363
364
365
366
				if (EndpointIndex == ENDPOINT_CONTROLEP)
				  return;

				Endpoint_SelectEndpoint(EndpointIndex);

367
				if (Endpoint_IsEnabled())
368
				{
369
370
371
372
373
374
375
376
377
					if (USB_ControlRequest.bRequest == REQ_SetFeature)
					{
						Endpoint_StallTransaction();
					}
					else
					{
						Endpoint_ClearStall();
						Endpoint_ResetFIFO(EndpointIndex);
						Endpoint_ResetDataToggle();
378
					}
379
380
				}
			}
381

382
			break;
383
		#endif
384
385
386
387
388
389
390
391
392
393
394
395
		default:
			return;
	}

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

	Endpoint_ClearSETUP();

	Endpoint_ClearStatusStage();
}

#endif
396