DevChapter9.c 8.04 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
			if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT))
66
			{
67
				USB_Device_ClearSetFeature();
68
69
70
71
72
				RequestHandled = true;
			}

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

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

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

			break;
	}

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

static void USB_Device_SetAddress(void)
{
119
	Endpoint_ClearSETUP();
120
	
121
	while (!(Endpoint_IsINReady()));
122
	
123
	Endpoint_ClearIN();
124
	
125
	while (!(Endpoint_IsINReady()));
126

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

	return;
}

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

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

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

156
	USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
157

158
	Endpoint_ClearIN();
159
160
161
162
163
164
165
166
167

	if (!(AlreadyConfigured) && USB_ConfigurationNumber)
	  RAISE_EVENT(USB_DeviceEnumerationComplete);

	RAISE_EVENT(USB_ConfigurationChanged);
}

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

	Endpoint_Write_Byte(USB_ConfigurationNumber);
	
172
	Endpoint_ClearIN();
173

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

static void USB_Device_GetDescriptor(void)
{
	void*    DescriptorPointer;
	uint16_t DescriptorSize;
	
183
	if ((DescriptorSize = USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex, &DescriptorPointer)) == NO_DESCRIPTOR)
184
185
	  return;
	
186
187
188
189
190
191
	Endpoint_ClearSETUP();
	
	#if defined(USE_RAM_DESCRIPTORS)
	Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
	#else
	bool     SendZLP;
192
	
193
194
	if (USB_ControlRequest.wLength > DescriptorSize)
	  USB_ControlRequest.wLength = DescriptorSize;
195
	
196
	while (USB_ControlRequest.wLength)
197
	{
198
		while (!(Endpoint_IsINReady()))
199
		{
200
			if (Endpoint_IsOUTReceived())
201
			{
202
				Endpoint_ClearOUT();
203
204
205
206
				return;
			}		
		}
		
207
		while (USB_ControlRequest.wLength && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
208
		{
209
			#if defined (USE_EEPROM_DESCRIPTORS)
210
211
212
213
214
			Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer++));			
			#else
			Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer++));
			#endif
			
215
			USB_ControlRequest.wLength--;
216
217
218
		}
		
		SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
219
		Endpoint_ClearIN();
220
221
222
223
	}
	
	if (SendZLP)
	{
224
		while (!(Endpoint_IsINReady()));
225
		Endpoint_ClearIN();
226
227
	}

228
	while (!(Endpoint_IsOUTReceived()));
229
230
	#endif
	
231
	Endpoint_ClearOUT();
232
233
}

234
static void USB_Device_GetStatus(void)
235
236
237
{
	uint8_t CurrentStatus = 0;

238
	switch (USB_ControlRequest.bmRequestType)
239
240
241
242
243
244
245
246
247
	{
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
			if (USB_CurrentlySelfPowered)
			  CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
			
			if (USB_RemoteWakeupEnabled)
			  CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
			
			break;
248
#if !defined(CONTROL_ONLY_DEVICE)
249
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
250
			Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex);
251
252
253

			CurrentStatus = Endpoint_IsStalled();

254
255
			Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);			  

256
			break;
257
#endif
258
	}
259

260
	Endpoint_ClearSETUP();
261

262
263
	Endpoint_Write_Word_LE(CurrentStatus);

264
	Endpoint_ClearIN();
265
	
266
	while (!(Endpoint_IsOUTReceived()));
267
	Endpoint_ClearOUT();
268
269
}

270
271
272
static void USB_Device_ClearSetFeature(void)
{	
	switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
273
	{
274
275
276
277
278
279
		case REQREC_DEVICE:
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
			  USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
			
			break;			
#if !defined(CONTROL_ONLY_DEVICE)
280
		case REQREC_ENDPOINT:
281
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
282
			{
283
				uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
284
285
286
287
288
289
290
				
				if (EndpointIndex != ENDPOINT_CONTROLEP)
				{
					Endpoint_SelectEndpoint(EndpointIndex);

					if (Endpoint_IsEnabled())
					{				
291
						if (USB_ControlRequest.bRequest == REQ_ClearFeature)
292
293
294
295
296
297
298
299
300
301
302
303
						{
							Endpoint_ClearStall();
							Endpoint_ResetFIFO(EndpointIndex);
							Endpoint_ResetDataToggle();
						}
						else
						{
							Endpoint_StallTransaction();						
						}
					}

					Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
304
305
					Endpoint_ClearSETUP();
					Endpoint_ClearIN();
306
307
308
309
				}
			}
			
			break;
310
#endif
311
312
313
314
	}
}

#endif