DevChapter9.c 10.7 KB
Newer Older
1
2
/*
             LUFA Library
Dean Camera's avatar
Dean Camera committed
3
     Copyright (C) Dean Camera, 2010.
4
5
6
7
8
9
              
  dean [at] fourwalledcubicle [dot] com
      www.fourwalledcubicle.com
*/

/*
Dean Camera's avatar
Dean Camera committed
10
  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11

12
13
14
15
16
17
18
  Permission to use, copy, modify, distribute, and sell this 
  software and its documentation for any purpose is hereby granted
  without fee, 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 
19
20
21
22
23
24
25
26
27
28
29
30
  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
#define  __INCLUDE_FROM_USB_DRIVER
32
33
#include "../HighLevel/USBMode.h"

34
35
#if defined(USB_CAN_BE_DEVICE)

36
#define  __INCLUDE_FROM_DEVCHAPTER9_C
37
38
39
#include "DevChapter9.h"

uint8_t USB_ConfigurationNumber;
40
41

#if !defined(NO_DEVICE_SELF_POWER)
42
bool    USB_CurrentlySelfPowered;
43
44
45
46
47
#endif

#if !defined(NO_DEVICE_REMOTE_WAKEUP)
bool    USB_RemoteWakeupEnabled;
#endif
48

49
void USB_Device_ProcessControlRequest(void)
50
{
51
52
	bool     RequestHandled = false;
	uint8_t* RequestHeader  = (uint8_t*)&USB_ControlRequest;
53
	
54
55
	for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)
	  *(RequestHeader++) = Endpoint_Read_Byte();
56
57
	  
	uint8_t bmRequestType = USB_ControlRequest.bmRequestType;
58
59
	
	switch (USB_ControlRequest.bRequest)
60
61
	{
		case REQ_GetStatus:
62
63
			if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
			    (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
64
			{
65
				USB_Device_GetStatus();
66
67
68
69
70
71
				RequestHandled = true;
			}

			break;
		case REQ_ClearFeature:
		case REQ_SetFeature:
72
73
			if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||
			    (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))
74
			{
75
				USB_Device_ClearSetFeature();
76
77
78
79
80
				RequestHandled = true;
			}

			break;
		case REQ_SetAddress:
81
			if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
82
83
84
85
86
87
88
			{
				USB_Device_SetAddress();
				RequestHandled = true;
			}

			break;
		case REQ_GetDescriptor:
89
90
			if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
			    (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
91
92
93
94
95
96
97
			{
				USB_Device_GetDescriptor();
				RequestHandled = true;
			}
			
			break;
		case REQ_GetConfiguration:
98
			if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
99
100
101
102
103
104
105
			{
				USB_Device_GetConfiguration();
				RequestHandled = true;
			}

			break;
		case REQ_SetConfiguration:
106
			if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
107
108
109
110
111
112
113
114
115
			{
				USB_Device_SetConfiguration();
				RequestHandled = true;
			}

			break;
	}

	if (!(RequestHandled))
116
	  EVENT_USB_Device_UnhandledControlRequest();
117
	  
118
	if (Endpoint_IsSETUPReceived())
119
120
	{
		Endpoint_StallTransaction();
121
		Endpoint_ClearSETUP();		
122
123
124
125
126
	}
}

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

129
	Endpoint_ClearSETUP();
130
	
131
	Endpoint_ClearStatusStage();
132
	
133
134
135
136
137
138
	while (!(Endpoint_IsINReady()))
	{
		if (USB_DeviceState == DEVICE_STATE_Unattached)
		  return;
	}

139
	USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
140

141
	UDADDR = ((1 << ADDEN) | DeviceAddress);
Dean Camera's avatar
Dean Camera committed
142

143
144
145
146
147
	return;
}

static void USB_Device_SetConfiguration(void)
{
148
149
150
	if (USB_DeviceState != DEVICE_STATE_Addressed)
	  return;
	
151
152
#if defined(FIXED_NUM_CONFIGURATIONS)
	if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
153
	  return;
154
#else
155
156
157
158
159
160
161
162
	#if defined(USE_FLASH_DESCRIPTORS)
		#define MemoryAddressSpace  MEMSPACE_FLASH
	#elif defined(USE_EEPROM_DESCRIPTORS)
		#define MemoryAddressSpace  MEMSPACE_EEPROM
	#elif defined(USE_SRAM_DESCRIPTORS)
		#define MemoryAddressSpace  MEMSPACE_SRAM
	#else
		uint8_t MemoryAddressSpace;
163
164
	#endif
	
165
166
	USB_Descriptor_Device_t* DevDescriptorPtr;

167
168
	if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
169
	                               , &MemoryAddressSpace
170
	#endif
171
	                               ) == NO_DESCRIPTOR)
172
173
174
175
176
	{
		return;
	}
	
	if (MemoryAddressSpace == MEMSPACE_FLASH)
177
	{
178
179
		if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
		  return;
180
	}
181
182
183
184
185
186
187
188
189
190
191
	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
192
	
193
	Endpoint_ClearSETUP();
194

195
	USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
196

197
	Endpoint_ClearStatusStage();
198

Dean Camera's avatar
Dean Camera committed
199
	USB_DeviceState = (USB_ConfigurationNumber) ? DEVICE_STATE_Configured : DEVICE_STATE_Addressed;
200

201
	EVENT_USB_Device_ConfigurationChanged();
202
203
204
205
}

void USB_Device_GetConfiguration(void)
{
206
	Endpoint_ClearSETUP();
207
208

	Endpoint_Write_Byte(USB_ConfigurationNumber);
209
	Endpoint_ClearIN();
210

211
	Endpoint_ClearStatusStage();
212
213
}

214
#if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
215
216
217
218
219
220
static char USB_Device_NibbleToASCII(uint8_t Nibble)
{
	Nibble = ((Nibble & 0x0F) + '0');
	return (Nibble > '9') ? (Nibble + ('A' - '9' - 1)) : Nibble;
}

221
static void USB_Device_GetInternalSerialDescriptor(void)
222
{
223
224
225
	struct
	{
		USB_Descriptor_Header_t Header;
226
		int16_t                 UnicodeString[20];
227
228
	} SignatureDescriptor;

Dean Camera's avatar
Dean Camera committed
229
230
	SignatureDescriptor.Header.Type = DTYPE_String;
	SignatureDescriptor.Header.Size = sizeof(SignatureDescriptor);
231
	
Dean Camera's avatar
Dean Camera committed
232
	uint8_t SigReadAddress = 0x0E;
233

234
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
235
	{
236
		for (uint8_t SerialCharNum = 0; SerialCharNum < 20; SerialCharNum++)
237
		{
238
239
240
241
242
243
244
245
246
			uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
			
			if (SerialCharNum & 0x01)
			{
				SerialByte >>= 4;
				SigReadAddress++;
			}
			
			SignatureDescriptor.UnicodeString[SerialCharNum] = USB_Device_NibbleToASCII(SerialByte);
247
248
249
250
		}
	}
	
	Endpoint_ClearSETUP();
251

252
	Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
253

254
255
256
257
258
259
260
261
262
	Endpoint_ClearOUT();
}
#endif

static void USB_Device_GetDescriptor(void)
{
	void*    DescriptorPointer;
	uint16_t DescriptorSize;
	
263
264
265
266
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
	uint8_t  DescriptorAddressSpace;
	#endif
	
267
268
269
270
	#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();
271
272
273
274
		return;
	}
	#endif
	
275
	if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
276
277
278
279
280
	                                                 &DescriptorPointer
	#if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
	                                                 , &DescriptorAddressSpace
	#endif
													 )) == NO_DESCRIPTOR)
281
282
283
	{
		return;
	}
284
	
285
	Endpoint_ClearSETUP();
286

287
288
	#if defined(USE_RAM_DESCRIPTORS)
	Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
289
290
	#elif defined(USE_EEPROM_DESCRIPTORS)
	Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
291
	#elif defined(USE_FLASH_DESCRIPTORS)
292
	Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);	
293
294
295
296
297
298
299
	#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);	
300
	#endif
301

302
	Endpoint_ClearOUT();
303
304
}

305
static void USB_Device_GetStatus(void)
306
307
308
{
	uint8_t CurrentStatus = 0;

309
	switch (USB_ControlRequest.bmRequestType)
310
	{
311
#if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)	
312
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
313
	#if !defined(NO_DEVICE_SELF_POWER)
314
315
			if (USB_CurrentlySelfPowered)
			  CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
316
	#endif
317

318
	#if !defined(NO_DEVICE_REMOTE_WAKEUP)			
319
320
			if (USB_RemoteWakeupEnabled)
			  CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
321
	#endif
322
			break;
323
#endif
324
#if !defined(CONTROL_ONLY_DEVICE)
325
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
326
			Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
327
328
329

			CurrentStatus = Endpoint_IsStalled();

330
331
			Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);			  

332
			break;
333
#endif
334
335
		default:
			return;
336
	}
337

338
	Endpoint_ClearSETUP();
339

340
	Endpoint_Write_Word_LE(CurrentStatus);
341
	Endpoint_ClearIN();
342
	
343
	Endpoint_ClearStatusStage();
344
345
}

346
static void USB_Device_ClearSetFeature(void)
347
{
348
	switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
349
	{
350
#if !defined(NO_DEVICE_REMOTE_WAKEUP)			
351
		case REQREC_DEVICE:
352
353
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_REMOTE_WAKEUP)
			  USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
354
355
			else
			  return;
356
357
			
			break;			
358
#endif
359
#if !defined(CONTROL_ONLY_DEVICE)
360
		case REQREC_ENDPOINT:
361
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
362
			{
363
				uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
364
				
365
366
367
368
369
				if (EndpointIndex == ENDPOINT_CONTROLEP)
				  return;

				Endpoint_SelectEndpoint(EndpointIndex);

370
371
372
373
374
375
376
377
378
379
380
381
				if (!(Endpoint_IsEnabled()))
				  return;

				if (USB_ControlRequest.bRequest == REQ_SetFeature)
				{
					Endpoint_StallTransaction();
				}
				else
				{
					Endpoint_ClearStall();
					Endpoint_ResetFIFO(EndpointIndex);
					Endpoint_ResetDataToggle();
382
383
384
385
				}
			}
			
			break;
386
#endif
387
388
		default:
			return;
389
	}
390
391
392
393
394

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

	Endpoint_ClearSETUP();

395
	Endpoint_ClearStatusStage();
396
397
398
}

#endif