DeviceStandardReq.c 10.2 KB
Newer Older
1 2
/*
             LUFA Library
3
     Copyright (C) Dean Camera, 2011.
4

5
  dean [at] fourwalledcubicle [dot] com
6
           www.lufa-lib.org
7 8 9
*/

/*
10
  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11

12
  Permission to use, copy, modify, distribute, and sell this
13
  software and its documentation for any purpose is hereby granted
14
  without fee, provided that the above copyright notice appear in
15
  all copies and that both that the copyright notice and this
16 17 18
  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 31
  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.
*/

#define  __INCLUDE_FROM_USB_DRIVER
32
#include "USBMode.h"
33 34 35

#if defined(USB_CAN_BE_DEVICE)

36 37
#define  __INCLUDE_FROM_DEVICESTDREQ_C
#include "DeviceStandardReq.h"
38 39 40 41 42 43 44 45 46 47 48 49 50

uint8_t USB_ConfigurationNumber;

#if !defined(NO_DEVICE_SELF_POWER)
bool    USB_CurrentlySelfPowered;
#endif

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

void USB_Device_ProcessControlRequest(void)
{
51 52 53 54 55
	USB_ControlRequest.bmRequestType = Endpoint_Read_8();
	USB_ControlRequest.bRequest      = Endpoint_Read_8();
	USB_ControlRequest.wValue        = Endpoint_Read_16_LE();
	USB_ControlRequest.wIndex        = Endpoint_Read_16_LE();
	USB_ControlRequest.wLength       = Endpoint_Read_16_LE();
56

57
	EVENT_USB_Device_ControlRequest();
58

59
	if (Endpoint_IsSETUPReceived())
60
	{
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
		uint8_t bmRequestType = USB_ControlRequest.bmRequestType;

		switch (USB_ControlRequest.bRequest)
		{
			case REQ_GetStatus:
				if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
					(bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
				{
					USB_Device_GetStatus();
				}

				break;
			case REQ_ClearFeature:
			case REQ_SetFeature:
				if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||
					(bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))
				{
					USB_Device_ClearSetFeature();
				}

				break;
			case REQ_SetAddress:
				if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
				  USB_Device_SetAddress();

				break;
			case REQ_GetDescriptor:
				if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
					(bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
				{
					USB_Device_GetDescriptor();
				}

				break;
			case REQ_GetConfiguration:
				if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
				  USB_Device_GetConfiguration();

				break;
			case REQ_SetConfiguration:
				if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
				  USB_Device_SetConfiguration();

				break;
		}
106 107 108 109 110
	}

	if (Endpoint_IsSETUPReceived())
	{
		Endpoint_StallTransaction();
111
		Endpoint_ClearSETUP();
112 113 114 115 116
	}
}

static void USB_Device_SetAddress(void)
{
117
	uint8_t DeviceAddress       = (USB_ControlRequest.wValue & 0x7F);
118 119
	uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
	GlobalInterruptDisable();
120 121
				
	Endpoint_ClearSETUP();
122

123
	Endpoint_ClearStatusStage();
124

125
	while (!(Endpoint_IsINReady()));
126

127
	USB_Device_SetDeviceAddress(DeviceAddress);
128
	USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
129
	
130
	SetGlobalInterruptMask(CurrentGlobalInt);
131 132 133 134
}

static void USB_Device_SetConfiguration(void)
{
135
	#if defined(FIXED_NUM_CONFIGURATIONS)
136 137
	if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
	  return;
138 139 140
	#else
	USB_Descriptor_Device_t* DevDescriptorPtr;

141 142 143 144 145 146 147 148 149 150
	#if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
		#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;
		#endif
151
	#endif
152
	
153
	if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
154 155
	#if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
	    !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
156 157 158 159 160 161
	                               , &MemoryAddressSpace
	#endif
	                               ) == NO_DESCRIPTOR)
	{
		return;
	}
162

163
	#if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
	if (MemoryAddressSpace == MEMSPACE_FLASH)
	{
		if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
		  return;
	}
	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;
	}
179 180 181 182
	#else
	if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
	  return;	
	#endif
183
	#endif
184

185 186 187 188 189 190
	Endpoint_ClearSETUP();

	USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;

	Endpoint_ClearStatusStage();

191 192 193 194
	if (USB_ConfigurationNumber)
	  USB_DeviceState = DEVICE_STATE_Configured;
	else
	  USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
195 196 197 198

	EVENT_USB_Device_ConfigurationChanged();
}

199
static void USB_Device_GetConfiguration(void)
200 201 202
{
	Endpoint_ClearSETUP();

203
	Endpoint_Write_8(USB_ConfigurationNumber);
204 205 206 207 208
	Endpoint_ClearIN();

	Endpoint_ClearStatusStage();
}

209
#if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
210 211 212 213 214
static void USB_Device_GetInternalSerialDescriptor(void)
{
	struct
	{
		USB_Descriptor_Header_t Header;
215
		uint16_t                UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];
216 217 218
	} SignatureDescriptor;

	SignatureDescriptor.Header.Type = DTYPE_String;
219 220 221
	SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4);
	
	USB_Device_GetSerialString(SignatureDescriptor.UnicodeString);
222

223 224 225 226 227 228 229 230 231
	Endpoint_ClearSETUP();

	Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
	Endpoint_ClearOUT();
}
#endif

static void USB_Device_GetDescriptor(void)
{
232 233
	const void* DescriptorPointer;
	uint16_t    DescriptorSize;
234

235 236
	#if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
	    !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
237
	uint8_t DescriptorAddressSpace;
238
	#endif
239

240
	#if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
241 242 243 244 245 246
	if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
	{
		USB_Device_GetInternalSerialDescriptor();
		return;
	}
	#endif
247

248 249
	if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
	                                                 &DescriptorPointer
250 251
	#if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
	    !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
252 253 254 255 256 257
	                                                 , &DescriptorAddressSpace
	#endif
													 )) == NO_DESCRIPTOR)
	{
		return;
	}
258

259 260
	Endpoint_ClearSETUP();

261
	#if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
262 263 264 265
	Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
	#elif defined(USE_EEPROM_DESCRIPTORS)
	Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
	#elif defined(USE_FLASH_DESCRIPTORS)
266
	Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
267 268
	#else
	if (DescriptorAddressSpace == MEMSPACE_FLASH)
269
	  Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
270 271 272
	else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
	  Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
	else
273
	  Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
274 275 276 277 278 279 280 281 282 283 284
	#endif

	Endpoint_ClearOUT();
}

static void USB_Device_GetStatus(void)
{
	uint8_t CurrentStatus = 0;

	switch (USB_ControlRequest.bmRequestType)
	{
285
		#if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
286
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
287
			#if !defined(NO_DEVICE_SELF_POWER)
288 289
			if (USB_CurrentlySelfPowered)
			  CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
290
			#endif
291

292
			#if !defined(NO_DEVICE_REMOTE_WAKEUP)
293 294
			if (USB_RemoteWakeupEnabled)
			  CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
295
			#endif
296
			break;
297 298
		#endif
		#if !defined(CONTROL_ONLY_DEVICE)
299 300 301 302 303
		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
			Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);

			CurrentStatus = Endpoint_IsStalled();

304
			Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
305 306

			break;
307
		#endif
308 309 310 311 312 313
		default:
			return;
	}

	Endpoint_ClearSETUP();

314
	Endpoint_Write_16_LE(CurrentStatus);
315
	Endpoint_ClearIN();
316

317 318 319 320 321 322 323
	Endpoint_ClearStatusStage();
}

static void USB_Device_ClearSetFeature(void)
{
	switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
	{
324
		#if !defined(NO_DEVICE_REMOTE_WAKEUP)
325
		case REQREC_DEVICE:
326
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)
327 328 329
			  USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
			else
			  return;
330 331

			break;
332 333
		#endif
		#if !defined(CONTROL_ONLY_DEVICE)
334
		case REQREC_ENDPOINT:
335
			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt)
336 337
			{
				uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
338

339 340 341 342 343
				if (EndpointIndex == ENDPOINT_CONTROLEP)
				  return;

				Endpoint_SelectEndpoint(EndpointIndex);

344
				if (Endpoint_IsEnabled())
345
				{
346 347 348 349 350 351 352
					if (USB_ControlRequest.bRequest == REQ_SetFeature)
					{
						Endpoint_StallTransaction();
					}
					else
					{
						Endpoint_ClearStall();
353
						Endpoint_ResetEndpoint(EndpointIndex);
354
						Endpoint_ResetDataToggle();
355
					}
356 357
				}
			}
358

359
			break;
360
		#endif
361 362 363 364 365 366 367 368 369 370 371 372
		default:
			return;
	}

	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);

	Endpoint_ClearSETUP();

	Endpoint_ClearStatusStage();
}

#endif
373