DevChapter9.c 11 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
             LUFA Library
     Copyright (C) Dean Camera, 2009.
              
  dean [at] fourwalledcubicle [dot] com
      www.fourwalledcubicle.com
*/

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

  Permission to use, copy, modify, and distribute this software
  and its documentation for any purpose and without fee is hereby
  granted, provided that the above copyright notice appear in all
  copies and that both that the copyright notice and this
  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
  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.
*/

31
32
#include "../HighLevel/USBMode.h"

33
34
35
36
37
38
39
40
41
42
43
#if defined(USB_CAN_BE_DEVICE)

#define  INCLUDE_FROM_DEVCHAPTER9_C
#include "DevChapter9.h"

uint8_t USB_ConfigurationNumber;
bool    USB_RemoteWakeupEnabled;
bool    USB_CurrentlySelfPowered;

void USB_Device_ProcessControlPacket(void)
{
44
45
	bool     RequestHandled = false;
	uint8_t* RequestHeader  = (uint8_t*)&USB_ControlRequest;
46
	
47
48
	for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)
	  *(RequestHeader++) = Endpoint_Read_Byte();
49
50
	  
	uint8_t bmRequestType = USB_ControlRequest.bmRequestType;
51
52
	
	switch (USB_ControlRequest.bRequest)
53
54
	{
		case REQ_GetStatus:
55
56
			if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
			    (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
57
			{
58
				USB_Device_GetStatus();
59
60
61
62
63
64
				RequestHandled = true;
			}

			break;
		case REQ_ClearFeature:
		case REQ_SetFeature:
65
66
			if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||
			    (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))
67
			{
68
				USB_Device_ClearSetFeature();
69
70
71
72
73
				RequestHandled = true;
			}

			break;
		case REQ_SetAddress:
74
			if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
75
76
77
78
79
80
81
			{
				USB_Device_SetAddress();
				RequestHandled = true;
			}

			break;
		case REQ_GetDescriptor:
82
83
			if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
			    (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
84
85
86
87
88
89
90
			{
				USB_Device_GetDescriptor();
				RequestHandled = true;
			}
			
			break;
		case REQ_GetConfiguration:
91
			if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
92
93
94
95
96
97
98
			{
				USB_Device_GetConfiguration();
				RequestHandled = true;
			}

			break;
		case REQ_SetConfiguration:
99
			if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
100
101
102
103
104
105
106
107
108
			{
				USB_Device_SetConfiguration();
				RequestHandled = true;
			}

			break;
	}

	if (!(RequestHandled))
109
	  EVENT_USB_UnhandledControlPacket();
110
	  
111
	if (Endpoint_IsSETUPReceived())
112
113
	{
		Endpoint_StallTransaction();
114
		Endpoint_ClearSETUP();		
115
116
117
118
119
	}
}

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

122
	Endpoint_ClearSETUP();
123
	
124
	Endpoint_ClearIN();
125
	
126
127
128
129
130
131
132
	while (!(Endpoint_IsINReady()))
	{
		if (USB_DeviceState == DEVICE_STATE_Unattached)
		  return;
	}

	UDADDR = ((1 << ADDEN) | DeviceAddress);
133

134
135
	if (DeviceAddress)
	  USB_DeviceState = DEVICE_STATE_Addressed;
136
137
138
139
140
141

	return;
}

static void USB_Device_SetConfiguration(void)
{
142
	bool AlreadyConfigured = (USB_ConfigurationNumber != 0);
143

144
145
146
#if defined(TOTAL_NUM_CONFIGURATIONS)
	if ((uint8_t)USB_ControlRequest.wValue > TOTAL_NUM_CONFIGURATIONS)
	  return;
147
#else
148
149
150
151
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
	uint8_t MemoryAddressSpace;
	#endif
	
152
153
	USB_Descriptor_Device_t* DevDescriptorPtr;

154
155
	if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
156
	                               , &MemoryAddressSpace
157
	#endif
158
	                               ) == NO_DESCRIPTOR)
159
160
161
162
	{
		return;
	}
	
163
	#if defined(USE_RAM_DESCRIPTORS)
164
165
	if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
	  return;
166
	#elif defined (USE_EEPROM_DESCRIPTORS)
167
168
169
170
171
	if ((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations))
	  return;
	#elif defined (USE_FLASH_DESCRIPTORS)
	if ((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations))
	  return;
172
	#else
173
	if (MemoryAddressSpace == MEMSPACE_FLASH)
174
	{
175
176
		if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
		  return;
177
	}
178
179
180
181
182
183
184
185
186
187
188
189
	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;
	}
	#endif
#endif
190
	
191
	Endpoint_ClearSETUP();
192

193
	USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
194

195
	Endpoint_ClearIN();
196

197
198
199
200
201
202
203
204
205
206
207
	if (USB_ConfigurationNumber)
	{
		USB_DeviceState = DEVICE_STATE_Configured;

		if (!(AlreadyConfigured))
		  EVENT_USB_DeviceEnumerationComplete();
	}
	else
	{
		USB_DeviceState = DEVICE_STATE_Addressed;
	}
208

209
	EVENT_USB_ConfigurationChanged();
210
211
212
213
}

void USB_Device_GetConfiguration(void)
{
214
	Endpoint_ClearSETUP();
215
216
217

	Endpoint_Write_Byte(USB_ConfigurationNumber);
	
218
	Endpoint_ClearIN();
219

220
221
222
223
224
225
	while (!(Endpoint_IsOUTReceived()))
	{
		if (USB_DeviceState == DEVICE_STATE_Unattached)
		  return;	
	}

226
	Endpoint_ClearOUT();
227
228
}

229
230
#if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
static void USB_Device_GetInternalSerialDescriptor(void)
231
{
232
233
234
	struct
	{
		USB_Descriptor_Header_t Header;
235
		int16_t                 UnicodeString[20];
236
	} SignatureDescriptor;
237
	
238
	uint8_t SigReadAddress  = 0x0E;
239
240
241
242
243
244
245
246
247
248
	bool    OddNibbleRead   = false;

	#if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)
		SignatureDescriptor.Header.Size            = sizeof(SignatureDescriptor);
		SignatureDescriptor.Header.Type            = DTYPE_String;
	#else
		SignatureDescriptor.Header.bLength         = sizeof(SignatureDescriptor);
		SignatureDescriptor.Header.bDescriptorType = DTYPE_String;
	#endif

249
	for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
250
	{
251
		uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
252
		
253
		if (OddNibbleRead)
254
		{
255
256
257
258
259
260
			SerialByte >>= 4;
			SigReadAddress++;
		}
		else
		{
			SerialByte &= 0x0F;
261
262
		}
		
263
		OddNibbleRead = !(OddNibbleRead);
264

265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
		if (SerialByte < 0x0A)
		  SerialByte += '0';
		else
		  SerialByte += ('A' - 0x0A);

		SignatureDescriptor.UnicodeString[SerialCharNum] = SerialByte;
	}
	
	Endpoint_ClearSETUP();
	Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
	Endpoint_ClearOUT();
}
#endif

static void USB_Device_GetDescriptor(void)
{
	void*    DescriptorPointer;
	uint16_t DescriptorSize;
	
284
285
286
287
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
	uint8_t  DescriptorAddressSpace;
	#endif
	
288
289
290
291
	#if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
	if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
	{
		USB_Device_GetInternalSerialDescriptor();
292
293
294
295
		return;
	}
	#endif
	
296
	if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
297
298
299
300
301
	                                                 &DescriptorPointer
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
	                                                 , &DescriptorAddressSpace
	#endif
													 )) == NO_DESCRIPTOR)
302
303
304
	{
		return;
	}
305
	
306
	Endpoint_ClearSETUP();
307

308
309
	#if defined(USE_RAM_DESCRIPTORS)
	Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
310
311
	#elif defined(USE_EEPROM_DESCRIPTORS)
	Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
312
	#elif defined(USE_FLASH_DESCRIPTORS)
313
	Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);	
314
315
316
317
318
319
320
	#else
	if (DescriptorAddressSpace == MEMSPACE_FLASH)
	  Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);	
	else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
	  Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
	else
	  Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);	
321
	#endif
322

323
	Endpoint_ClearOUT();
324
325
}

326
static void USB_Device_GetStatus(void)
327
328
329
{
	uint8_t CurrentStatus = 0;

330
	switch (USB_ControlRequest.bmRequestType)
331
332
333
334
335
336
337
338
339
	{
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
			if (USB_CurrentlySelfPowered)
			  CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
			
			if (USB_RemoteWakeupEnabled)
			  CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
			
			break;
340
#if !defined(CONTROL_ONLY_DEVICE)
341
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
342
			Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex);
343
344
345

			CurrentStatus = Endpoint_IsStalled();

346
347
			Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);			  

348
			break;
349
#endif
350
	}
351

352
	Endpoint_ClearSETUP();
353

354
355
	Endpoint_Write_Word_LE(CurrentStatus);

356
	Endpoint_ClearIN();
357
	
358
359
360
361
362
363
	while (!(Endpoint_IsOUTReceived()))
	{
		if (USB_DeviceState == DEVICE_STATE_Unattached)
		  return;	
	}
	
364
	Endpoint_ClearOUT();
365
366
}

367
368
369
static void USB_Device_ClearSetFeature(void)
{	
	switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
370
	{
371
372
373
		case REQREC_DEVICE:
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
			  USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
374
375
			else
			  return;
376
377
378
			
			break;			
#if !defined(CONTROL_ONLY_DEVICE)
379
		case REQREC_ENDPOINT:
380
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
381
			{
382
				uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
383
				
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
				if (EndpointIndex == ENDPOINT_CONTROLEP)
				  return;

				Endpoint_SelectEndpoint(EndpointIndex);

				if (Endpoint_IsEnabled())
				{				
					if (USB_ControlRequest.bRequest == REQ_ClearFeature)
					{
						Endpoint_ClearStall();
						Endpoint_ResetFIFO(EndpointIndex);
						Endpoint_ResetDataToggle();
					}
					else
					{
399
						Endpoint_StallTransaction();
400
401
402
403
404
					}
				}
			}
			
			break;
405
#endif
406
	}
407
408
409
410
411
412

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

	Endpoint_ClearSETUP();

	Endpoint_ClearIN();
413
414
415
}

#endif