diff options
Diffstat (limited to 'Demos/Host/Incomplete/AudioInputHost/ConfigDescriptor.c')
| -rw-r--r-- | Demos/Host/Incomplete/AudioInputHost/ConfigDescriptor.c | 183 | 
1 files changed, 183 insertions, 0 deletions
| diff --git a/Demos/Host/Incomplete/AudioInputHost/ConfigDescriptor.c b/Demos/Host/Incomplete/AudioInputHost/ConfigDescriptor.c new file mode 100644 index 000000000..d0ca91a08 --- /dev/null +++ b/Demos/Host/Incomplete/AudioInputHost/ConfigDescriptor.c @@ -0,0 +1,183 @@ +/*
 +             LUFA Library
 +     Copyright (C) Dean Camera, 2011.
 +
 +  dean [at] fourwalledcubicle [dot] com
 +           www.lufa-lib.org
 +*/
 +
 +/*
 +  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 +
 +  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
 +  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.
 +*/
 +
 +/** \file
 + *
 + *  USB Device Configuration Descriptor processing routines, to determine the correct pipe configurations
 + *  needed to communication with an attached USB device. Descriptors are special  computer-readable structures
 + *  which the host requests upon device enumeration, to determine the device's capabilities and functions.
 + */
 +
 +#include "ConfigDescriptor.h"
 +
 +uint8_t StreamingInterfaceIndex      = 0;
 +uint8_t StreamingInterfaceAltSetting = 0;
 +uint8_t StreamingEndpointAddress     = 0;
 +
 +uint8_t ProcessConfigurationDescriptor(void)
 +{
 +	uint8_t  ConfigDescriptorData[512];
 +	void*    CurrConfigLocation = ConfigDescriptorData;
 +	uint16_t CurrConfigBytesRem;
 +
 +	USB_Descriptor_Interface_t* AudioControlInterface   = NULL;
 +	USB_Descriptor_Interface_t* AudioStreamingInterface = NULL;
 +	USB_Descriptor_Endpoint_t*  DataINEndpoint          = NULL;
 +
 +	/* Retrieve the entire configuration descriptor into the allocated buffer */
 +	switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
 +	{
 +		case HOST_GETCONFIG_Successful:
 +			break;
 +		case HOST_GETCONFIG_InvalidData:
 +			return InvalidConfigDataReturned;
 +		case HOST_GETCONFIG_BuffOverflow:
 +			return DescriptorTooLarge;
 +		default:
 +			return ControlError;
 +	}
 +
 +	while (!(DataINEndpoint))
 +	{
 +		if (!(AudioControlInterface) ||
 +		    USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 +		                              DComp_NextAudioInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
 +		{
 +			if (!(AudioControlInterface))
 +			{
 +				if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 +											  DComp_NextAudioControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 +				{
 +					/* Descriptor not found, error out */
 +					return NoCompatibleInterfaceFound;
 +				}
 +
 +				/* Save the interface in case we need to refer back to it later */
 +				AudioControlInterface = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t);			
 +			}
 +		
 +			if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 +										  DComp_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 +			{
 +				if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 +											  DComp_NextAudioControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 +				{
 +					/* Descriptor not found, error out */
 +					return NoCompatibleInterfaceFound;
 +				}
 +
 +				/* Save the interface in case we need to refer back to it later */
 +				AudioControlInterface = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t);
 +			}
 +
 +			/* Save the interface in case we need to refer back to it later */
 +			AudioStreamingInterface = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t);
 +
 +			/* Skip the remainder of the loop as we have not found an endpoint yet */
 +			continue;
 +		}
 +
 +		/* Retrieve the endpoint address from the endpoint descriptor */
 +		USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t);
 +
 +		/* If the endpoint is a IN type endpoint */
 +		if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
 +		  DataINEndpoint = EndpointData;
 +	}
 +
 +	StreamingInterfaceIndex      = AudioStreamingInterface->InterfaceNumber;
 +	StreamingInterfaceAltSetting = AudioStreamingInterface->AlternateSetting;
 +	StreamingEndpointAddress     = DataINEndpoint->EndpointAddress;
 +
 +	/* Configure the HID data IN pipe */
 +	Pipe_ConfigurePipe(AUDIO_DATA_IN_PIPE, EP_TYPE_ISOCHRONOUS, PIPE_TOKEN_IN,
 +	                   DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_DOUBLE);
 +
 +	/* Valid data found, return success */
 +	return SuccessfulConfigRead;
 +}
 +
 +uint8_t DComp_NextAudioControlInterface(void* CurrentDescriptor)
 +{
 +	USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
 +
 +	if (Header->Type == DTYPE_Interface)
 +	{
 +		USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
 +
 +		if ((Interface->Class    == AUDIO_CSCP_AudioClass) &&
 +		    (Interface->SubClass == AUDIO_CSCP_ControlSubclass) &&
 +		    (Interface->Protocol == AUDIO_CSCP_ControlProtocol))
 +		{
 +			return DESCRIPTOR_SEARCH_Found;
 +		}
 +	}
 +
 +	return DESCRIPTOR_SEARCH_NotFound;
 +}
 +
 +uint8_t DComp_NextAudioStreamInterface(void* CurrentDescriptor)
 +{
 +	USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
 +
 +	if (Header->Type == DTYPE_Interface)
 +	{
 +		USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
 +
 +		if ((Interface->Class    == AUDIO_CSCP_AudioClass) &&
 +		    (Interface->SubClass == AUDIO_CSCP_AudioStreamingSubclass) &&
 +		    (Interface->Protocol == AUDIO_CSCP_StreamingProtocol))
 +		{
 +			return DESCRIPTOR_SEARCH_Found;
 +		}
 +	}
 +
 +	return DESCRIPTOR_SEARCH_NotFound;
 +}
 +
 +uint8_t DComp_NextAudioInterfaceDataEndpoint(void* CurrentDescriptor)
 +{
 +	USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
 +
 +	if (Header->Type == DTYPE_Endpoint)
 +	{
 +		USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
 +
 +		if ((Endpoint->Attributes & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS)
 +		  return DESCRIPTOR_SEARCH_Found;
 +	}
 +	else if (Header->Type == DTYPE_Interface)
 +	{
 +		return DESCRIPTOR_SEARCH_Fail;
 +	}
 +
 +	return DESCRIPTOR_SEARCH_NotFound;
 +}
 +
 | 
