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

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

	return;
}

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

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

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

154
	USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
155

156
	Endpoint_ClearIN();
157
158
159
160
161
162
163
164
165

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

	RAISE_EVENT(USB_ConfigurationChanged);
}

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

	Endpoint_Write_Byte(USB_ConfigurationNumber);
	
170
	Endpoint_ClearIN();
171

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

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

226
	while (!(Endpoint_IsOUTReceived()));
227
228
	#endif
	
229
	Endpoint_ClearOUT();
230
231
}

232
static void USB_Device_GetStatus(void)
233
234
235
{
	uint8_t CurrentStatus = 0;

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

			CurrentStatus = Endpoint_IsStalled();

252
253
			Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);			  

254
			break;
255
#endif
256
	}
257

258
	Endpoint_ClearSETUP();
259

260
261
	Endpoint_Write_Word_LE(CurrentStatus);

262
	Endpoint_ClearIN();
263
	
264
	while (!(Endpoint_IsOUTReceived()));
265
	Endpoint_ClearOUT();
266
267
}

268
269
270
static void USB_Device_ClearSetFeature(void)
{	
	switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
271
	{
272
273
274
		case REQREC_DEVICE:
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
			  USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
275
276
			else
			  return;
277
278
279
			
			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
291
292
293
294
295
296
297
298
299
				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
					{
300
						Endpoint_StallTransaction();
301
302
303
304
305
					}
				}
			}
			
			break;
306
#endif
307
	}
308
309
310
311
312
313

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

	Endpoint_ClearSETUP();

	Endpoint_ClearIN();
314
315
316
}

#endif