3 Copyright (C) Dean Camera, 2009.
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
12 Permission to use, copy, modify, and distribute this software
13 and its documentation for any purpose and without fee is hereby
14 granted, provided that the above copyright notice appear in all
15 copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
31 #include "../HighLevel/USBMode.h"
33 #if defined(USB_CAN_BE_DEVICE)
35 #define INCLUDE_FROM_DEVCHAPTER9_C
36 #include "DevChapter9.h"
38 uint8_t USB_ConfigurationNumber
;
40 #if !defined(NO_DEVICE_SELF_POWER)
41 bool USB_CurrentlySelfPowered
;
44 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
45 bool USB_RemoteWakeupEnabled
;
48 void USB_Device_ProcessControlRequest(void)
50 bool RequestHandled
= false;
51 uint8_t* RequestHeader
= (uint8_t*)&USB_ControlRequest
;
53 for (uint8_t RequestHeaderByte
= 0; RequestHeaderByte
< sizeof(USB_Request_Header_t
); RequestHeaderByte
++)
54 *(RequestHeader
++) = Endpoint_Read_Byte();
56 uint8_t bmRequestType
= USB_ControlRequest
.bmRequestType
;
58 switch (USB_ControlRequest
.bRequest
)
61 if ((bmRequestType
== (REQDIR_DEVICETOHOST
| REQTYPE_STANDARD
| REQREC_DEVICE
)) ||
62 (bmRequestType
== (REQDIR_DEVICETOHOST
| REQTYPE_STANDARD
| REQREC_ENDPOINT
)))
64 USB_Device_GetStatus();
65 RequestHandled
= true;
69 case REQ_ClearFeature
:
71 if ((bmRequestType
== (REQDIR_HOSTTODEVICE
| REQTYPE_STANDARD
| REQREC_DEVICE
)) ||
72 (bmRequestType
== (REQDIR_HOSTTODEVICE
| REQTYPE_STANDARD
| REQREC_ENDPOINT
)))
74 USB_Device_ClearSetFeature();
75 RequestHandled
= true;
80 if (bmRequestType
== (REQDIR_HOSTTODEVICE
| REQTYPE_STANDARD
| REQREC_DEVICE
))
82 USB_Device_SetAddress();
83 RequestHandled
= true;
87 case REQ_GetDescriptor
:
88 if ((bmRequestType
== (REQDIR_DEVICETOHOST
| REQTYPE_STANDARD
| REQREC_DEVICE
)) ||
89 (bmRequestType
== (REQDIR_DEVICETOHOST
| REQTYPE_STANDARD
| REQREC_INTERFACE
)))
91 USB_Device_GetDescriptor();
92 RequestHandled
= true;
96 case REQ_GetConfiguration
:
97 if (bmRequestType
== (REQDIR_DEVICETOHOST
| REQTYPE_STANDARD
| REQREC_DEVICE
))
99 USB_Device_GetConfiguration();
100 RequestHandled
= true;
104 case REQ_SetConfiguration
:
105 if (bmRequestType
== (REQDIR_HOSTTODEVICE
| REQTYPE_STANDARD
| REQREC_DEVICE
))
107 USB_Device_SetConfiguration();
108 RequestHandled
= true;
114 if (!(RequestHandled
))
115 EVENT_USB_Device_UnhandledControlRequest();
117 if (Endpoint_IsSETUPReceived())
119 Endpoint_StallTransaction();
120 Endpoint_ClearSETUP();
124 static void USB_Device_SetAddress(void)
126 uint8_t DeviceAddress
= (USB_ControlRequest
.wValue
& 0x7F);
128 Endpoint_ClearSETUP();
130 Endpoint_ClearStatusStage();
132 while (!(Endpoint_IsINReady()))
134 if (USB_DeviceState
== DEVICE_STATE_Unattached
)
139 USB_DeviceState
= DEVICE_STATE_Addressed
;
141 UDADDR
= ((1 << ADDEN
) | DeviceAddress
);
146 static void USB_Device_SetConfiguration(void)
148 #if defined(FIXED_NUM_CONFIGURATIONS)
149 if ((uint8_t)USB_ControlRequest
.wValue
> FIXED_NUM_CONFIGURATIONS
)
152 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
153 uint8_t MemoryAddressSpace
;
156 USB_Descriptor_Device_t
* DevDescriptorPtr
;
158 if (CALLBACK_USB_GetDescriptor((DTYPE_Device
<< 8), 0, (void*)&DevDescriptorPtr
159 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
160 , &MemoryAddressSpace
167 #if defined(USE_RAM_DESCRIPTORS)
168 if ((uint8_t)USB_ControlRequest
.wValue
> DevDescriptorPtr
->NumberOfConfigurations
)
170 #elif defined (USE_EEPROM_DESCRIPTORS)
171 if ((uint8_t)USB_ControlRequest
.wValue
> eeprom_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))
173 #elif defined (USE_FLASH_DESCRIPTORS)
174 if ((uint8_t)USB_ControlRequest
.wValue
> pgm_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
))
177 if (MemoryAddressSpace
== MEMSPACE_FLASH
)
179 if (((uint8_t)USB_ControlRequest
.wValue
> pgm_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
)))
182 else if (MemoryAddressSpace
== MEMSPACE_EEPROM
)
184 if (((uint8_t)USB_ControlRequest
.wValue
> eeprom_read_byte(&DevDescriptorPtr
->NumberOfConfigurations
)))
189 if ((uint8_t)USB_ControlRequest
.wValue
> DevDescriptorPtr
->NumberOfConfigurations
)
195 Endpoint_ClearSETUP();
197 USB_ConfigurationNumber
= (uint8_t)USB_ControlRequest
.wValue
;
199 Endpoint_ClearStatusStage();
201 USB_DeviceState
= (USB_ConfigurationNumber
) ? DEVICE_STATE_Configured
: DEVICE_STATE_Addressed
;
203 EVENT_USB_Device_ConfigurationChanged();
206 void USB_Device_GetConfiguration(void)
208 Endpoint_ClearSETUP();
210 Endpoint_Write_Byte(USB_ConfigurationNumber
);
213 Endpoint_ClearStatusStage();
216 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
217 static char USB_Device_NibbleToASCII(uint8_t Nibble
)
219 Nibble
= ((Nibble
& 0x0F) + '0');
220 return (Nibble
> '9') ?
(Nibble
+ ('A' - '9' - 1)) : Nibble
;
223 static void USB_Device_GetInternalSerialDescriptor(void)
227 USB_Descriptor_Header_t Header
;
228 int16_t UnicodeString
[20];
229 } SignatureDescriptor
;
231 SignatureDescriptor
.Header
.Type
= DTYPE_String
;
232 SignatureDescriptor
.Header
.Size
= sizeof(SignatureDescriptor
);
234 uint8_t SigReadAddress
= 0x0E;
236 for (uint8_t SerialCharNum
= 0; SerialCharNum
< 20; SerialCharNum
++)
238 uint8_t SerialByte
= boot_signature_byte_get(SigReadAddress
);
240 if (SerialCharNum
& 0x01)
246 SignatureDescriptor
.UnicodeString
[SerialCharNum
] = USB_Device_NibbleToASCII(SerialByte
);
249 Endpoint_ClearSETUP();
251 Endpoint_Write_Control_Stream_LE(&SignatureDescriptor
, sizeof(SignatureDescriptor
));
257 static void USB_Device_GetDescriptor(void)
259 void* DescriptorPointer
;
260 uint16_t DescriptorSize
;
262 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
263 uint8_t DescriptorAddressSpace
;
266 #if !defined(NO_INTERNAL_SERIAL) && (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR))
267 if (USB_ControlRequest
.wValue
== ((DTYPE_String
<< 8) | USE_INTERNAL_SERIAL
))
269 USB_Device_GetInternalSerialDescriptor();
274 if ((DescriptorSize
= CALLBACK_USB_GetDescriptor(USB_ControlRequest
.wValue
, USB_ControlRequest
.wIndex
,
276 #if !defined(USE_FLASH_DESCRIPTORS) && !defined(USE_EEPROM_DESCRIPTORS) && !defined(USE_RAM_DESCRIPTORS)
277 , &DescriptorAddressSpace
284 Endpoint_ClearSETUP();
286 #if defined(USE_RAM_DESCRIPTORS)
287 Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
);
288 #elif defined(USE_EEPROM_DESCRIPTORS)
289 Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
);
290 #elif defined(USE_FLASH_DESCRIPTORS)
291 Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
);
293 if (DescriptorAddressSpace
== MEMSPACE_FLASH
)
294 Endpoint_Write_Control_PStream_LE(DescriptorPointer
, DescriptorSize
);
295 else if (DescriptorAddressSpace
== MEMSPACE_EEPROM
)
296 Endpoint_Write_Control_EStream_LE(DescriptorPointer
, DescriptorSize
);
298 Endpoint_Write_Control_Stream_LE(DescriptorPointer
, DescriptorSize
);
304 static void USB_Device_GetStatus(void)
306 uint8_t CurrentStatus
= 0;
308 switch (USB_ControlRequest
.bmRequestType
)
310 case (REQDIR_DEVICETOHOST
| REQTYPE_STANDARD
| REQREC_DEVICE
):
311 #if !defined(NO_DEVICE_SELF_POWER)
312 if (USB_CurrentlySelfPowered
)
313 CurrentStatus
|= FEATURE_SELFPOWERED_ENABLED
;
316 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
317 if (USB_RemoteWakeupEnabled
)
318 CurrentStatus
|= FEATURE_REMOTE_WAKEUP_ENABLED
;
322 #if !defined(CONTROL_ONLY_DEVICE)
323 case (REQDIR_DEVICETOHOST
| REQTYPE_STANDARD
| REQREC_ENDPOINT
):
324 Endpoint_SelectEndpoint(USB_ControlRequest
.wIndex
& 0xFF);
326 CurrentStatus
= Endpoint_IsStalled();
328 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
);
336 Endpoint_ClearSETUP();
338 Endpoint_Write_Word_LE(CurrentStatus
);
341 Endpoint_ClearStatusStage();
344 static void USB_Device_ClearSetFeature(void)
346 switch (USB_ControlRequest
.bmRequestType
& CONTROL_REQTYPE_RECIPIENT
)
349 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
350 if ((uint8_t)USB_ControlRequest
.wValue
== FEATURE_REMOTE_WAKEUP
)
351 USB_RemoteWakeupEnabled
= (USB_ControlRequest
.bRequest
== REQ_SetFeature
);
357 #if !defined(CONTROL_ONLY_DEVICE)
358 case REQREC_ENDPOINT
:
359 if ((uint8_t)USB_ControlRequest
.wValue
== FEATURE_ENDPOINT_HALT
)
361 uint8_t EndpointIndex
= ((uint8_t)USB_ControlRequest
.wIndex
& ENDPOINT_EPNUM_MASK
);
363 if (EndpointIndex
== ENDPOINT_CONTROLEP
)
366 Endpoint_SelectEndpoint(EndpointIndex
);
368 if (Endpoint_IsEnabled())
370 if (USB_ControlRequest
.bRequest
== REQ_SetFeature
)
372 Endpoint_StallTransaction();
376 Endpoint_ClearStall();
377 Endpoint_ResetFIFO(EndpointIndex
);
378 Endpoint_ResetDataToggle();
387 Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP
);
389 Endpoint_ClearSETUP();
391 Endpoint_ClearStatusStage();