3 Copyright (C) Dean Camera, 2012.
\r
5 dean [at] fourwalledcubicle [dot] com
\r
10 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
\r
12 Permission to use, copy, modify, distribute, and sell this
\r
13 software and its documentation for any purpose is hereby granted
\r
14 without fee, provided that the above copyright notice appear in
\r
15 all copies and that both that the copyright notice and this
\r
16 permission notice and warranty disclaimer appear in supporting
\r
17 documentation, and that the name of the author not be used in
\r
18 advertising or publicity pertaining to distribution of the
\r
19 software without specific, written prior permission.
\r
21 The author disclaim all warranties with regard to this
\r
22 software, including all implied warranties of merchantability
\r
23 and fitness. In no event shall the author be liable for any
\r
24 special, indirect or consequential damages or any damages
\r
25 whatsoever resulting from loss of use, data or profits, whether
\r
26 in an action of contract, negligence or other tortious action,
\r
27 arising out of or in connection with the use or performance of
\r
31 #define __INCLUDE_FROM_USB_DRIVER
\r
32 #include "USBMode.h"
\r
34 #if defined(USB_CAN_BE_DEVICE)
\r
36 #define __INCLUDE_FROM_DEVICESTDREQ_C
\r
37 #include "DeviceStandardReq.h"
\r
39 uint8_t USB_Device_ConfigurationNumber;
\r
41 #if !defined(NO_DEVICE_SELF_POWER)
\r
42 bool USB_Device_CurrentlySelfPowered;
\r
45 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
\r
46 bool USB_Device_RemoteWakeupEnabled;
\r
49 void USB_Device_ProcessControlRequest(void)
\r
51 #if defined(ARCH_BIG_ENDIAN)
\r
52 USB_ControlRequest.bmRequestType = Endpoint_Read_8();
\r
53 USB_ControlRequest.bRequest = Endpoint_Read_8();
\r
54 USB_ControlRequest.wValue = Endpoint_Read_16_LE();
\r
55 USB_ControlRequest.wIndex = Endpoint_Read_16_LE();
\r
56 USB_ControlRequest.wLength = Endpoint_Read_16_LE();
\r
58 uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest;
\r
60 for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)
\r
61 *(RequestHeader++) = Endpoint_Read_8();
\r
64 EVENT_USB_Device_ControlRequest();
\r
66 if (Endpoint_IsSETUPReceived())
\r
68 uint8_t bmRequestType = USB_ControlRequest.bmRequestType;
\r
70 switch (USB_ControlRequest.bRequest)
\r
73 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
\r
74 (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
\r
76 USB_Device_GetStatus();
\r
80 case REQ_ClearFeature:
\r
81 case REQ_SetFeature:
\r
82 if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) ||
\r
83 (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)))
\r
85 USB_Device_ClearSetFeature();
\r
89 case REQ_SetAddress:
\r
90 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
\r
91 USB_Device_SetAddress();
\r
94 case REQ_GetDescriptor:
\r
95 if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
\r
96 (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
\r
98 USB_Device_GetDescriptor();
\r
102 case REQ_GetConfiguration:
\r
103 if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
\r
104 USB_Device_GetConfiguration();
\r
107 case REQ_SetConfiguration:
\r
108 if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
\r
109 USB_Device_SetConfiguration();
\r
115 if (Endpoint_IsSETUPReceived())
\r
117 Endpoint_StallTransaction();
\r
118 Endpoint_ClearSETUP();
\r
122 static void USB_Device_SetAddress(void)
\r
124 uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);
\r
125 uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
\r
126 GlobalInterruptDisable();
\r
128 Endpoint_ClearSETUP();
\r
130 Endpoint_ClearStatusStage();
\r
132 while (!(Endpoint_IsINReady()));
\r
134 USB_Device_SetDeviceAddress(DeviceAddress);
\r
135 USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default;
\r
137 SetGlobalInterruptMask(CurrentGlobalInt);
\r
140 static void USB_Device_SetConfiguration(void)
\r
142 #if defined(FIXED_NUM_CONFIGURATIONS)
\r
143 if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS)
\r
146 USB_Descriptor_Device_t* DevDescriptorPtr;
\r
148 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
\r
149 #if defined(USE_FLASH_DESCRIPTORS)
\r
150 #define MemoryAddressSpace MEMSPACE_FLASH
\r
151 #elif defined(USE_EEPROM_DESCRIPTORS)
\r
152 #define MemoryAddressSpace MEMSPACE_EEPROM
\r
153 #elif defined(USE_SRAM_DESCRIPTORS)
\r
154 #define MemoryAddressSpace MEMSPACE_SRAM
\r
156 uint8_t MemoryAddressSpace;
\r
160 if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr
\r
161 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
\r
162 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
\r
163 , &MemoryAddressSpace
\r
165 ) == NO_DESCRIPTOR)
\r
170 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
\r
171 if (MemoryAddressSpace == MEMSPACE_FLASH)
\r
173 if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
\r
176 else if (MemoryAddressSpace == MEMSPACE_EEPROM)
\r
178 if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
\r
183 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
\r
187 if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations)
\r
192 Endpoint_ClearSETUP();
\r
194 USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
\r
196 Endpoint_ClearStatusStage();
\r
198 if (USB_Device_ConfigurationNumber)
\r
199 USB_DeviceState = DEVICE_STATE_Configured;
\r
201 USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
\r
203 EVENT_USB_Device_ConfigurationChanged();
\r
206 static void USB_Device_GetConfiguration(void)
\r
208 Endpoint_ClearSETUP();
\r
210 Endpoint_Write_8(USB_Device_ConfigurationNumber);
\r
211 Endpoint_ClearIN();
\r
213 Endpoint_ClearStatusStage();
\r
216 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
\r
217 static void USB_Device_GetInternalSerialDescriptor(void)
\r
221 USB_Descriptor_Header_t Header;
\r
222 uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4];
\r
223 } SignatureDescriptor;
\r
225 SignatureDescriptor.Header.Type = DTYPE_String;
\r
226 SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4);
\r
228 USB_Device_GetSerialString(SignatureDescriptor.UnicodeString);
\r
230 Endpoint_ClearSETUP();
\r
232 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor));
\r
233 Endpoint_ClearOUT();
\r
237 static void USB_Device_GetDescriptor(void)
\r
239 const void* DescriptorPointer;
\r
240 uint16_t DescriptorSize;
\r
242 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
\r
243 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
\r
244 uint8_t DescriptorAddressSpace;
\r
247 #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR)
\r
248 if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL))
\r
250 USB_Device_GetInternalSerialDescriptor();
\r
255 if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex,
\r
257 #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \
\r
258 !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS))
\r
259 , &DescriptorAddressSpace
\r
261 )) == NO_DESCRIPTOR)
\r
266 Endpoint_ClearSETUP();
\r
268 #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE)
\r
269 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
\r
270 #elif defined(USE_EEPROM_DESCRIPTORS)
\r
271 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
\r
272 #elif defined(USE_FLASH_DESCRIPTORS)
\r
273 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
\r
275 if (DescriptorAddressSpace == MEMSPACE_FLASH)
\r
276 Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize);
\r
277 else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
\r
278 Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize);
\r
280 Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
\r
283 Endpoint_ClearOUT();
\r
286 static void USB_Device_GetStatus(void)
\r
288 uint8_t CurrentStatus = 0;
\r
290 switch (USB_ControlRequest.bmRequestType)
\r
292 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
\r
293 #if !defined(NO_DEVICE_SELF_POWER)
\r
294 if (USB_Device_CurrentlySelfPowered)
\r
295 CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
\r
298 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
\r
299 if (USB_Device_RemoteWakeupEnabled)
\r
300 CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
\r
303 case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
\r
304 #if !defined(CONTROL_ONLY_DEVICE)
\r
305 Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
\r
307 CurrentStatus = Endpoint_IsStalled();
\r
309 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
\r
317 Endpoint_ClearSETUP();
\r
319 Endpoint_Write_16_LE(CurrentStatus);
\r
320 Endpoint_ClearIN();
\r
322 Endpoint_ClearStatusStage();
\r
325 static void USB_Device_ClearSetFeature(void)
\r
327 switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
\r
329 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
\r
330 case REQREC_DEVICE:
\r
331 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)
\r
332 USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
\r
338 #if !defined(CONTROL_ONLY_DEVICE)
\r
339 case REQREC_ENDPOINT:
\r
340 if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt)
\r
342 uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
\r
344 if (EndpointIndex == ENDPOINT_CONTROLEP)
\r
347 Endpoint_SelectEndpoint(EndpointIndex);
\r
349 if (Endpoint_IsEnabled())
\r
351 if (USB_ControlRequest.bRequest == REQ_SetFeature)
\r
353 Endpoint_StallTransaction();
\r
357 Endpoint_ClearStall();
\r
358 Endpoint_ResetEndpoint(EndpointIndex);
\r
359 Endpoint_ResetDataToggle();
\r
370 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
\r
372 Endpoint_ClearSETUP();
\r
374 Endpoint_ClearStatusStage();
\r