From 74298f8ca11dc8d3b0359d1d4e124d6494c3eeac Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Fri, 10 Apr 2009 01:15:42 +0200 Subject: * digital/avr/modules/usb: - imported LUFA. --- .../lufa/LUFA/Drivers/USB/LowLevel/DevChapter9.c | 313 +++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 digital/avr/modules/usb/lufa/LUFA/Drivers/USB/LowLevel/DevChapter9.c (limited to 'digital/avr/modules/usb/lufa/LUFA/Drivers/USB/LowLevel/DevChapter9.c') diff --git a/digital/avr/modules/usb/lufa/LUFA/Drivers/USB/LowLevel/DevChapter9.c b/digital/avr/modules/usb/lufa/LUFA/Drivers/USB/LowLevel/DevChapter9.c new file mode 100644 index 00000000..9ea3f417 --- /dev/null +++ b/digital/avr/modules/usb/lufa/LUFA/Drivers/USB/LowLevel/DevChapter9.c @@ -0,0 +1,313 @@ +/* + 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. +*/ + +#include "USBMode.h" +#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) +{ + uint8_t bmRequestType = Endpoint_Read_Byte(); + uint8_t bRequest = Endpoint_Read_Byte(); + bool RequestHandled = false; + + switch (bRequest) + { + case REQ_GetStatus: + if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || + (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT))) + { + USB_Device_GetStatus(bmRequestType); + RequestHandled = true; + } + + break; +#if !defined(NO_CLEARSET_FEATURE_REQUEST) + case REQ_ClearFeature: + case REQ_SetFeature: + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)) + { + USB_Device_ClearSetFeature(bRequest, bmRequestType); + RequestHandled = true; + } + + break; +#endif + case REQ_SetAddress: + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) + { + USB_Device_SetAddress(); + RequestHandled = true; + } + + break; + case REQ_GetDescriptor: + if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || + (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE))) + { + USB_Device_GetDescriptor(); + RequestHandled = true; + } + + break; + case REQ_GetConfiguration: + if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) + { + USB_Device_GetConfiguration(); + RequestHandled = true; + } + + break; + case REQ_SetConfiguration: + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) + { + USB_Device_SetConfiguration(); + RequestHandled = true; + } + + break; + } + + if (!(RequestHandled)) + RAISE_EVENT(USB_UnhandledControlPacket, bRequest, bmRequestType); + + if (Endpoint_IsSetupReceived()) + { + Endpoint_StallTransaction(); + Endpoint_ClearSetupReceived(); + } +} + +static void USB_Device_SetAddress(void) +{ + uint8_t wValue_LSB = Endpoint_Read_Byte(); + + Endpoint_ClearSetupReceived(); + + while (!(Endpoint_IsSetupINReady())); + + Endpoint_ClearSetupIN(); + + while (!(Endpoint_IsSetupINReady())); + + UDADDR = ((1 << ADDEN) | (wValue_LSB & 0x7F)); + + return; +} + +static void USB_Device_SetConfiguration(void) +{ + uint8_t wValue_LSB = Endpoint_Read_Byte(); + bool AlreadyConfigured = (USB_ConfigurationNumber != 0); + +#if defined(USE_SINGLE_DEVICE_CONFIGURATION) + if (wValue_LSB > 1) +#else + USB_Descriptor_Device_t* DevDescriptorPtr; + + if ((USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr) == NO_DESCRIPTOR) || + #if defined(USE_RAM_DESCRIPTORS) + (wValue_LSB > DevDescriptorPtr->NumberOfConfigurations)) + #elif defined (USE_EEPROM_DESCRIPTORS) + (wValue_LSB > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations))) + #else + (wValue_LSB > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations))) + #endif +#endif + { + return; + } + + Endpoint_ClearSetupReceived(); + + USB_ConfigurationNumber = wValue_LSB; + + Endpoint_ClearSetupIN(); + + if (!(AlreadyConfigured) && USB_ConfigurationNumber) + RAISE_EVENT(USB_DeviceEnumerationComplete); + + RAISE_EVENT(USB_ConfigurationChanged); +} + +void USB_Device_GetConfiguration(void) +{ + Endpoint_ClearSetupReceived(); + + Endpoint_Write_Byte(USB_ConfigurationNumber); + + Endpoint_ClearSetupIN(); + + while (!(Endpoint_IsSetupOUTReceived())); + Endpoint_ClearSetupOUT(); +} + +static void USB_Device_GetDescriptor(void) +{ + uint16_t wValue = Endpoint_Read_Word_LE(); + uint16_t wIndex = Endpoint_Read_Word_LE(); + uint16_t wLength = Endpoint_Read_Word_LE(); + + void* DescriptorPointer; + uint16_t DescriptorSize; + + bool SendZLP; + + if ((DescriptorSize = USB_GetDescriptor(wValue, wIndex, &DescriptorPointer)) == NO_DESCRIPTOR) + return; + + Endpoint_ClearSetupReceived(); + + if (wLength > DescriptorSize) + wLength = DescriptorSize; + + while (wLength) + { + while (!(Endpoint_IsSetupINReady())) + { + if (Endpoint_IsSetupOUTReceived()) + { + Endpoint_ClearSetupOUT(); + return; + } + } + + while (wLength && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize)) + { + #if defined(USE_RAM_DESCRIPTORS) + Endpoint_Write_Byte(*((uint8_t*)DescriptorPointer++)); + #elif defined (USE_EEPROM_DESCRIPTORS) + Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer++)); + #else + Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer++)); + #endif + + wLength--; + } + + SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize); + Endpoint_ClearSetupIN(); + } + + if (SendZLP) + { + while (!(Endpoint_IsSetupINReady())); + Endpoint_ClearSetupIN(); + } + + while (!(Endpoint_IsSetupOUTReceived())); + Endpoint_ClearSetupOUT(); +} + +static void USB_Device_GetStatus(const uint8_t bmRequestType) +{ + uint8_t CurrentStatus = 0; + + Endpoint_Discard_Word(); + + uint8_t wIndex_LSB = Endpoint_Read_Byte(); + + switch (bmRequestType) + { + case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE): + if (USB_CurrentlySelfPowered) + CurrentStatus |= FEATURE_SELFPOWERED_ENABLED; + + if (USB_RemoteWakeupEnabled) + CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; + + break; + case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT): + Endpoint_SelectEndpoint(wIndex_LSB); + + CurrentStatus = Endpoint_IsStalled(); + + break; + } + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + Endpoint_ClearSetupReceived(); + Endpoint_Write_Word_LE(CurrentStatus); + + Endpoint_ClearSetupIN(); + + while (!(Endpoint_IsSetupOUTReceived())); + Endpoint_ClearSetupOUT(); +} + +#if !defined(NO_CLEARSET_FEATURE_REQUEST) +static void USB_Device_ClearSetFeature(const uint8_t bRequest, const uint8_t bmRequestType) +{ + uint16_t wValue = Endpoint_Read_Word_LE(); + uint16_t wIndex = Endpoint_Read_Word_LE(); + + switch (bmRequestType & CONTROL_REQTYPE_RECIPIENT) + { + case REQREC_ENDPOINT: + if (wValue == FEATURE_ENDPOINT_HALT) + { + uint8_t EndpointIndex = (wIndex & ENDPOINT_EPNUM_MASK); + + if (EndpointIndex != ENDPOINT_CONTROLEP) + { + Endpoint_SelectEndpoint(EndpointIndex); + + if (Endpoint_IsEnabled()) + { + if (bRequest == REQ_ClearFeature) + { + Endpoint_ClearStall(); + Endpoint_ResetFIFO(EndpointIndex); + Endpoint_ResetDataToggle(); + } + else + { + Endpoint_StallTransaction(); + } + } + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + Endpoint_ClearSetupReceived(); + Endpoint_ClearSetupIN(); + } + } + + break; + } +} +#endif + +#endif -- cgit v1.2.3