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
#if defined(FIXED_NUM_CONFIGURATIONS)
	if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
146
	  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
#if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
230
231
232
233
234
235
static char USB_Device_NibbleToASCII(uint8_t Nibble)
{
	Nibble = ((Nibble & 0x0F) + '0');
	return (Nibble > '9') ? (Nibble + ('A' - '9' - 1)) : Nibble;
}

236
static void USB_Device_GetInternalSerialDescriptor(void)
237
{
238
239
240
	struct
	{
		USB_Descriptor_Header_t Header;
241
		int16_t                 UnicodeString[20];
242
243
244
245
246
247
248
249
250
251
	} SignatureDescriptor;

	#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

252
253
	uint8_t  SigReadAddress     = 0x0E;

254
	for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
255
	{
256
		uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
257
		
258
		if (SerialCharNum & 0x01)
259
		{
260
261
262
			SerialByte >>= 4;
			SigReadAddress++;
		}
263
		
264
		SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);
265
266
267
268
269
270
271
272
273
274
275
276
277
	}
	
	Endpoint_ClearSETUP();
	Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
	Endpoint_ClearOUT();
}
#endif

static void USB_Device_GetDescriptor(void)
{
	void*    DescriptorPointer;
	uint16_t DescriptorSize;
	
278
279
280
281
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
	uint8_t  DescriptorAddressSpace;
	#endif
	
282
283
284
285
	#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();
286
287
288
289
		return;
	}
	#endif
	
290
	if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
291
292
293
294
295
	                                                 &DescriptorPointer
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
	                                                 , &DescriptorAddressSpace
	#endif
													 )) == NO_DESCRIPTOR)
296
297
298
	{
		return;
	}
299
	
300
	Endpoint_ClearSETUP();
301

302
303
	#if defined(USE_RAM_DESCRIPTORS)
	Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
304
305
	#elif defined(USE_EEPROM_DESCRIPTORS)
	Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
306
	#elif defined(USE_FLASH_DESCRIPTORS)
307
	Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);	
308
309
310
311
312
313
314
	#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);	
315
	#endif
316

317
	Endpoint_ClearOUT();
318
319
}

320
static void USB_Device_GetStatus(void)
321
322
323
{
	uint8_t CurrentStatus = 0;

324
	switch (USB_ControlRequest.bmRequestType)
325
326
327
328
329
330
331
332
333
	{
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
			if (USB_CurrentlySelfPowered)
			  CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
			
			if (USB_RemoteWakeupEnabled)
			  CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
			
			break;
334
#if !defined(CONTROL_ONLY_DEVICE)
335
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
336
			Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex);
337
338
339

			CurrentStatus = Endpoint_IsStalled();

340
341
			Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);			  

342
			break;
343
#endif
344
	}
345

346
	Endpoint_ClearSETUP();
347

348
349
	Endpoint_Write_Word_LE(CurrentStatus);

350
	Endpoint_ClearIN();
351
	
352
353
354
355
356
357
	while (!(Endpoint_IsOUTReceived()))
	{
		if (USB_DeviceState == DEVICE_STATE_Unattached)
		  return;	
	}
	
358
	Endpoint_ClearOUT();
359
360
}

361
362
363
static void USB_Device_ClearSetFeature(void)
{	
	switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
364
	{
365
366
367
		case REQREC_DEVICE:
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
			  USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
368
369
			else
			  return;
370
371
372
			
			break;			
#if !defined(CONTROL_ONLY_DEVICE)
373
		case REQREC_ENDPOINT:
374
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
375
			{
376
				uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
377
				
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
				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
					{
393
						Endpoint_StallTransaction();
394
395
396
397
398
					}
				}
			}
			
			break;
399
#endif
400
	}
401
402
403
404
405
406

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

	Endpoint_ClearSETUP();

	Endpoint_ClearIN();
407
408
409
}

#endif