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

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

/*
  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

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)
{
	uint8_t* RequestHeader  = (uint8_t*)&USB_ControlRequest;
52

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

56
	EVENT_USB_Device_ControlRequest();
57

58
	if (Endpoint_IsSETUPReceived())
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
95
96
97
98
99
100
101
102
103
104
		uint8_t bmRequestType = USB_ControlRequest.bmRequestType;

		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();
				}

				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();
				}

				break;
			case REQ_SetAddress:
				if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
				  USB_Device_SetAddress();

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

				break;
			case REQ_GetConfiguration:
				if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
				  USB_Device_GetConfiguration();

				break;
			case REQ_SetConfiguration:
				if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
				  USB_Device_SetConfiguration();

				break;
		}
105
106
107
108
109
	}

	if (Endpoint_IsSETUPReceived())
	{
		Endpoint_StallTransaction();
110
		Endpoint_ClearSETUP();
111
112
113
114
115
116
117
	}
}

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

118
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
119
	{
120
		Endpoint_ClearSETUP();
121

122
		Endpoint_ClearStatusStage();
123

124
		while (!(Endpoint_IsINReady()));
125

126
		USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
127

128
129
		USB_Device_SetDeviceAddress(DeviceAddress);
	}
130
131
132
133
}

static void USB_Device_SetConfiguration(void)
{
134
	#if defined(FIXED_NUM_CONFIGURATIONS)
135
136
	if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
	  return;
137
138
139
	#else
	USB_Descriptor_Device_t* DevDescriptorPtr;

140
141
142
143
144
145
146
147
148
	#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
149

150
151
152
153
154
155
156
157
	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;
	}
158

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
	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;
	}
174
	#endif
175

176
177
178
179
180
181
	Endpoint_ClearSETUP();

	USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;

	Endpoint_ClearStatusStage();

182
183
184
185
	if (USB_ConfigurationNumber)
	  USB_DeviceState = DEVICE_STATE_Configured;
	else
	  USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
186
187
188
189

	EVENT_USB_Device_ConfigurationChanged();
}

190
static void USB_Device_GetConfiguration(void)
191
192
193
194
195
196
197
198
199
{
	Endpoint_ClearSETUP();

	Endpoint_Write_Byte(USB_ConfigurationNumber);
	Endpoint_ClearIN();

	Endpoint_ClearStatusStage();
}

200
#if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
201
202
203
204
205
static void USB_Device_GetInternalSerialDescriptor(void)
{
	struct
	{
		USB_Descriptor_Header_t Header;
206
		wchar_t                 UnicodeString[20];
207
208
209
210
	} SignatureDescriptor;

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

212
213
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
	{
214
215
		uint8_t SigReadAddress = 0x0E;

216
217
218
		for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
		{
			uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
219

220
221
222
223
224
			if (SerialCharNum & 0x01)
			{
				SerialByte >>= 4;
				SigReadAddress++;
			}
225

226
227
228
229
			SerialByte &= 0x0F;

			SignatureDescriptor.UnicodeString[SerialCharNum] = (SerialByte >= 10) ?
			                                                   (('A' - 10) + SerialByte) : ('0' + SerialByte);
230
231
		}
	}
232

233
234
235
236
237
238
239
240
241
242
	Endpoint_ClearSETUP();

	Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));

	Endpoint_ClearOUT();
}
#endif

static void USB_Device_GetDescriptor(void)
{
243
244
	const void* DescriptorPointer;
	uint16_t    DescriptorSize;
245

246
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
247
	uint8_t DescriptorAddressSpace;
248
	#endif
249

250
	#if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
251
252
253
254
255
256
	if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
	{
		USB_Device_GetInternalSerialDescriptor();
		return;
	}
	#endif
257

258
259
260
261
262
263
264
265
266
	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;
	}
267

268
269
270
271
272
273
274
	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)
275
	Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
276
277
	#else
	if (DescriptorAddressSpace == MEMSPACE_FLASH)
278
	  Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
279
280
281
	else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
	  Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
	else
282
	  Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
283
284
285
286
287
288
289
290
291
292
293
	#endif

	Endpoint_ClearOUT();
}

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

	switch (USB_ControlRequest.bmRequestType)
	{
294
		#if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
295
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
296
			#if !defined(NO_DEVICE_SELF_POWER)
297
298
			if (USB_CurrentlySelfPowered)
			  CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
299
			#endif
300

301
			#if !defined(NO_DEVICE_REMOTE_WAKEUP)
302
303
			if (USB_RemoteWakeupEnabled)
			  CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
304
			#endif
305
			break;
306
307
		#endif
		#if !defined(CONTROL_ONLY_DEVICE)
308
309
310
311
312
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
			Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);

			CurrentStatus = Endpoint_IsStalled();

313
			Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
314
315

			break;
316
		#endif
317
318
319
320
321
322
323
324
		default:
			return;
	}

	Endpoint_ClearSETUP();

	Endpoint_Write_Word_LE(CurrentStatus);
	Endpoint_ClearIN();
325

326
327
328
329
330
331
332
	Endpoint_ClearStatusStage();
}

static void USB_Device_ClearSetFeature(void)
{
	switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
	{
333
		#if !defined(NO_DEVICE_REMOTE_WAKEUP)
334
		case REQREC_DEVICE:
335
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)
336
337
338
			  USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
			else
			  return;
339
340

			break;
341
342
		#endif
		#if !defined(CONTROL_ONLY_DEVICE)
343
		case REQREC_ENDPOINT:
344
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt)
345
346
			{
				uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
347

348
349
350
351
352
				if (EndpointIndex == ENDPOINT_CONTROLEP)
				  return;

				Endpoint_SelectEndpoint(EndpointIndex);

353
				if (Endpoint_IsEnabled())
354
				{
355
356
357
358
359
360
361
362
363
					if (USB_ControlRequest.bRequest == REQ_SetFeature)
					{
						Endpoint_StallTransaction();
					}
					else
					{
						Endpoint_ClearStall();
						Endpoint_ResetFIFO(EndpointIndex);
						Endpoint_ResetDataToggle();
364
					}
365
366
				}
			}
367

368
			break;
369
		#endif
370
371
372
373
374
375
376
377
378
379
380
381
		default:
			return;
	}

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

	Endpoint_ClearSETUP();

	Endpoint_ClearStatusStage();
}

#endif
382