DevChapter9.c 8.97 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
	Endpoint_ClearSETUP();
121
	
122
	Endpoint_ClearIN();
123
	
124
	while (!(Endpoint_IsINReady()));
125

126
	UDADDR = ((1 << ADDEN) | ((uint8_t)USB_ControlRequest.wValue & 0x7F));
127
128
129
130
131
132

	return;
}

static void USB_Device_SetConfiguration(void)
{
133
	bool AlreadyConfigured = (USB_ConfigurationNumber != 0);
134
135

#if defined(USE_SINGLE_DEVICE_CONFIGURATION)
136
	if ((uint8_t)USB_ControlRequest.wValue > 1)
137
138
139
#else
	USB_Descriptor_Device_t* DevDescriptorPtr;

140
	if ((CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr) == NO_DESCRIPTOR) ||
141
	#if defined(USE_RAM_DESCRIPTORS)
142
	    ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations))
143
	#elif defined (USE_EEPROM_DESCRIPTORS)
144
	    ((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
145
	#else
146
	    ((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
147
148
149
150
151
152
	#endif
#endif
	{
		return;
	}
	
153
	Endpoint_ClearSETUP();
154

155
	USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
156

157
	Endpoint_ClearIN();
158
159

	if (!(AlreadyConfigured) && USB_ConfigurationNumber)
160
	  EVENT_USB_DeviceEnumerationComplete();
161

162
	EVENT_USB_ConfigurationChanged();
163
164
165
166
}

void USB_Device_GetConfiguration(void)
{
167
	Endpoint_ClearSETUP();
168
169
170

	Endpoint_Write_Byte(USB_ConfigurationNumber);
	
171
	Endpoint_ClearIN();
172

173
	while (!(Endpoint_IsOUTReceived()));
174
	Endpoint_ClearOUT();
175
176
177
178
179
180
181
}

static void USB_Device_GetDescriptor(void)
{
	void*    DescriptorPointer;
	uint16_t DescriptorSize;
	
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
	#if defined(USE_INTERNAL_SERIAL)
	if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
	{
		uint8_t SignatureDescriptor[2 + (sizeof(int16_t) * 20)];

		SignatureDescriptor[0] = sizeof(SignatureDescriptor);
		SignatureDescriptor[1] = DTYPE_String;
		
		uint16_t* SigUnicodeChars = (uint16_t*)&SignatureDescriptor[2];

		for (uint8_t SerialByteNum = 0; SerialByteNum < 10; SerialByteNum++)
		{
			char ConvSigString[3];

			itoa(boot_signature_byte_get(0x0E + SerialByteNum), ConvSigString, 16);
			
			SigUnicodeChars[0] = toupper(ConvSigString[0]);
			SigUnicodeChars[1] = toupper(ConvSigString[1]);
			
			SigUnicodeChars += 2;
		}
		
		Endpoint_ClearSETUP();
		Endpoint_Write_Control_Stream_LE(SignatureDescriptor, sizeof(SignatureDescriptor));
		Endpoint_ClearOUT();

		return;
	}
	#endif
	
212
213
	if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
	                                                 &DescriptorPointer)) == NO_DESCRIPTOR)
214
215
216
	{
		return;
	}
217
	
218
	Endpoint_ClearSETUP();
219

220
221
222
	#if defined(USE_RAM_DESCRIPTORS)
	Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
	#else
223
	bool SendZLP;
224
	
225
226
	if (USB_ControlRequest.wLength > DescriptorSize)
	  USB_ControlRequest.wLength = DescriptorSize;
227
	
228
	while (USB_ControlRequest.wLength)
229
	{
230
		while (!(Endpoint_IsINReady()))
231
		{
232
			if (Endpoint_IsOUTReceived())
233
			{
234
				Endpoint_ClearOUT();
235
236
237
238
				return;
			}		
		}
		
239
		while (USB_ControlRequest.wLength && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
240
		{
241
			#if defined (USE_EEPROM_DESCRIPTORS)
242
			Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer++));		
243
244
245
246
			#else
			Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer++));
			#endif
			
247
			USB_ControlRequest.wLength--;
248
249
250
		}
		
		SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
251
		Endpoint_ClearIN();
252
253
254
255
	}
	
	if (SendZLP)
	{
256
		while (!(Endpoint_IsINReady()));
257
		Endpoint_ClearIN();
258
259
	}

260
	while (!(Endpoint_IsOUTReceived()));
261
262
	#endif
	
263
	Endpoint_ClearOUT();
264
265
}

266
static void USB_Device_GetStatus(void)
267
268
269
{
	uint8_t CurrentStatus = 0;

270
	switch (USB_ControlRequest.bmRequestType)
271
272
273
274
275
276
277
278
279
	{
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
			if (USB_CurrentlySelfPowered)
			  CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
			
			if (USB_RemoteWakeupEnabled)
			  CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
			
			break;
280
#if !defined(CONTROL_ONLY_DEVICE)
281
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
282
			Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex);
283
284
285

			CurrentStatus = Endpoint_IsStalled();

286
287
			Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);			  

288
			break;
289
#endif
290
	}
291

292
	Endpoint_ClearSETUP();
293

294
295
	Endpoint_Write_Word_LE(CurrentStatus);

296
	Endpoint_ClearIN();
297
	
298
	while (!(Endpoint_IsOUTReceived()));
299
	Endpoint_ClearOUT();
300
301
}

302
303
304
static void USB_Device_ClearSetFeature(void)
{	
	switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
305
	{
306
307
308
		case REQREC_DEVICE:
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
			  USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
309
310
			else
			  return;
311
312
313
			
			break;			
#if !defined(CONTROL_ONLY_DEVICE)
314
		case REQREC_ENDPOINT:
315
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
316
			{
317
				uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
318
				
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
				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
					{
334
						Endpoint_StallTransaction();
335
336
337
338
339
					}
				}
			}
			
			break;
340
#endif
341
	}
342
343
344
345
346
347

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

	Endpoint_ClearSETUP();

	Endpoint_ClearIN();
348
349
350
}

#endif