Now includes LUFA-120730 in repository
This commit is contained in:
		
							parent
							
								
									e9e4c0edc5
								
							
						
					
					
						commit
						8215634175
					
				
					 306 changed files with 64019 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -0,0 +1,198 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_USB_DRIVER
 | 
			
		||||
#include "../../Core/USBMode.h"
 | 
			
		||||
 | 
			
		||||
#if defined(USB_CAN_BE_DEVICE)
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_AUDIO_DRIVER
 | 
			
		||||
#define  __INCLUDE_FROM_AUDIO_DEVICE_C
 | 
			
		||||
#include "AudioClassDevice.h"
 | 
			
		||||
 | 
			
		||||
void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if (!(Endpoint_IsSETUPReceived()))
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
 | 
			
		||||
	{
 | 
			
		||||
		uint8_t InterfaceIndex = (USB_ControlRequest.wIndex & 0xFF);
 | 
			
		||||
	
 | 
			
		||||
		if ((InterfaceIndex != AudioInterfaceInfo->Config.ControlInterfaceNumber) &&
 | 
			
		||||
		    (InterfaceIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber))
 | 
			
		||||
		{
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
 | 
			
		||||
	{
 | 
			
		||||
		uint8_t EndpointAddress = (USB_ControlRequest.wIndex & 0xFF);
 | 
			
		||||
	
 | 
			
		||||
		if ((EndpointAddress != AudioInterfaceInfo->Config.DataINEndpoint.Address) &&
 | 
			
		||||
		    (EndpointAddress != AudioInterfaceInfo->Config.DataOUTEndpoint.Address))
 | 
			
		||||
		{
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch (USB_ControlRequest.bRequest)
 | 
			
		||||
	{
 | 
			
		||||
		case REQ_SetInterface:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
 | 
			
		||||
				AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0);
 | 
			
		||||
				EVENT_Audio_Device_StreamStartStop(AudioInterfaceInfo);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case AUDIO_REQ_GetStatus:
 | 
			
		||||
			if ((USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) ||
 | 
			
		||||
			    (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT)))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case AUDIO_REQ_SetCurrent:
 | 
			
		||||
		case AUDIO_REQ_SetMinimum:
 | 
			
		||||
		case AUDIO_REQ_SetMaximum:
 | 
			
		||||
		case AUDIO_REQ_SetResolution:
 | 
			
		||||
			if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
 | 
			
		||||
			{
 | 
			
		||||
				uint8_t EndpointProperty = USB_ControlRequest.bRequest;
 | 
			
		||||
				uint8_t EndpointAddress  = (uint8_t)USB_ControlRequest.wIndex;
 | 
			
		||||
				uint8_t EndpointControl  = (USB_ControlRequest.wValue >> 8);
 | 
			
		||||
 | 
			
		||||
				if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
 | 
			
		||||
				                                                 EndpointControl, NULL, NULL))
 | 
			
		||||
				{
 | 
			
		||||
					uint16_t ValueLength = USB_ControlRequest.wLength;
 | 
			
		||||
					uint8_t  Value[ValueLength];
 | 
			
		||||
 | 
			
		||||
					Endpoint_ClearSETUP();
 | 
			
		||||
					Endpoint_Read_Control_Stream_LE(Value, ValueLength);
 | 
			
		||||
					Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
					CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
 | 
			
		||||
					                                             EndpointControl, &ValueLength, Value);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
 | 
			
		||||
			{
 | 
			
		||||
				uint8_t  Property  = USB_ControlRequest.bRequest;
 | 
			
		||||
				uint8_t  Entity    = (USB_ControlRequest.wIndex >> 8);
 | 
			
		||||
				uint16_t Parameter = USB_ControlRequest.wValue;
 | 
			
		||||
 | 
			
		||||
				if (CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity,
 | 
			
		||||
				                                                  Parameter, NULL, NULL))
 | 
			
		||||
				{
 | 
			
		||||
					uint16_t ValueLength = USB_ControlRequest.wLength;
 | 
			
		||||
					uint8_t  Value[ValueLength];
 | 
			
		||||
 | 
			
		||||
					Endpoint_ClearSETUP();
 | 
			
		||||
					Endpoint_Read_Control_Stream_LE(Value, ValueLength);
 | 
			
		||||
					Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
					CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity,
 | 
			
		||||
				                                                  Parameter, &ValueLength, Value);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case AUDIO_REQ_GetCurrent:
 | 
			
		||||
		case AUDIO_REQ_GetMinimum:
 | 
			
		||||
		case AUDIO_REQ_GetMaximum:
 | 
			
		||||
		case AUDIO_REQ_GetResolution:
 | 
			
		||||
			if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
 | 
			
		||||
			{
 | 
			
		||||
				uint8_t  EndpointProperty = USB_ControlRequest.bRequest;
 | 
			
		||||
				uint8_t  EndpointAddress  = (uint8_t)USB_ControlRequest.wIndex;
 | 
			
		||||
				uint8_t  EndpointControl  = (USB_ControlRequest.wValue >> 8);
 | 
			
		||||
				uint16_t ValueLength      = USB_ControlRequest.wLength;
 | 
			
		||||
				uint8_t  Value[ValueLength];
 | 
			
		||||
 | 
			
		||||
				if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
 | 
			
		||||
				                                                 EndpointControl, &ValueLength, Value))
 | 
			
		||||
				{
 | 
			
		||||
					Endpoint_ClearSETUP();
 | 
			
		||||
					Endpoint_Write_Control_Stream_LE(Value, ValueLength);
 | 
			
		||||
					Endpoint_ClearOUT();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
 | 
			
		||||
			{
 | 
			
		||||
				uint8_t  Property    = USB_ControlRequest.bRequest;
 | 
			
		||||
				uint8_t  Entity      = (USB_ControlRequest.wIndex >> 8);
 | 
			
		||||
				uint16_t Parameter   = USB_ControlRequest.wValue;
 | 
			
		||||
				uint16_t ValueLength = USB_ControlRequest.wLength;
 | 
			
		||||
				uint8_t  Value[ValueLength];
 | 
			
		||||
 | 
			
		||||
				if (CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity,
 | 
			
		||||
				                                                  Parameter, &ValueLength, Value))
 | 
			
		||||
				{
 | 
			
		||||
					Endpoint_ClearSETUP();
 | 
			
		||||
					Endpoint_Write_Control_Stream_LE(Value, ValueLength);
 | 
			
		||||
					Endpoint_ClearOUT();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));
 | 
			
		||||
	
 | 
			
		||||
	AudioInterfaceInfo->Config.DataINEndpoint.Type  = EP_TYPE_ISOCHRONOUS;
 | 
			
		||||
	AudioInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_ISOCHRONOUS;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&AudioInterfaceInfo->Config.DataINEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&AudioInterfaceInfo->Config.DataOUTEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// cppcheck-suppress unusedFunction
 | 
			
		||||
void Audio_Device_Event_Stub(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,396 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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
 | 
			
		||||
 *  \brief Device mode driver for the library USB Audio 1.0 Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  Device mode driver for the library USB Audio 1.0 Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  \note This file should not be included directly. It is automatically included as needed by the USB module driver
 | 
			
		||||
 *        dispatch header located in LUFA/Drivers/USB.h.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** \ingroup Group_USBClassAudio
 | 
			
		||||
 *  \defgroup Group_USBClassAudioDevice Audio 1.0 Class Device Mode Driver
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_Dependencies Module Source Dependencies
 | 
			
		||||
 *  The following files must be built with any user project that uses this module:
 | 
			
		||||
 *    - LUFA/Drivers/USB/Class/Device/AudioClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_ModDescription Module Description
 | 
			
		||||
 *  Device Mode USB Class driver framework interface, for the Audio 1.0 USB Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _AUDIO_CLASS_DEVICE_H_
 | 
			
		||||
#define _AUDIO_CLASS_DEVICE_H_
 | 
			
		||||
 | 
			
		||||
	/* Includes: */
 | 
			
		||||
		#include "../../USB.h"
 | 
			
		||||
		#include "../Common/AudioClassCommon.h"
 | 
			
		||||
 | 
			
		||||
	/* Enable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			extern "C" {
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Preprocessor Checks: */
 | 
			
		||||
		#if !defined(__INCLUDE_FROM_AUDIO_DRIVER)
 | 
			
		||||
			#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Public Interface - May be used in end-application: */
 | 
			
		||||
		/* Type Defines: */
 | 
			
		||||
			/** \brief Audio Class Device Mode Configuration and State Structure.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  Class state structure. An instance of this structure should be made for each Audio interface
 | 
			
		||||
			 *  within the user application, and passed to each of the Audio class driver functions as the
 | 
			
		||||
			 *  \c AudioInterfaceInfo parameter. This stores each Audio interface's configuration and state information.
 | 
			
		||||
			 */
 | 
			
		||||
			typedef struct
 | 
			
		||||
			{
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					uint8_t  ControlInterfaceNumber; /**< Index of the Audio Control interface within the device this
 | 
			
		||||
					                                  *   structure controls.
 | 
			
		||||
					                                  */
 | 
			
		||||
					uint8_t  StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this
 | 
			
		||||
														*   structure controls.
 | 
			
		||||
														*/
 | 
			
		||||
 | 
			
		||||
					USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
 | 
			
		||||
					USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
 | 
			
		||||
				} Config; /**< Config data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				           *   <b>must</b> be set or the interface will fail to enumerate and operate correctly.
 | 
			
		||||
				           */
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					bool InterfaceEnabled; /**< Set and cleared by the class driver to indicate if the host has enabled the streaming endpoints
 | 
			
		||||
					                        *   of the Audio Streaming interface.
 | 
			
		||||
					                        */
 | 
			
		||||
				} State; /**< State data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				          *   are reset to their defaults when the interface is enumerated.
 | 
			
		||||
				          */
 | 
			
		||||
			} USB_ClassInfo_Audio_Device_t;
 | 
			
		||||
 | 
			
		||||
		/* Function Prototypes: */
 | 
			
		||||
			/** Configures the endpoints of a given Audio interface, ready for use. This should be linked to the library
 | 
			
		||||
			 *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the
 | 
			
		||||
			 *  given Audio interface is selected.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Processes incoming control requests from the host, that are directed to the given Audio class interface. This should be
 | 
			
		||||
			 *  linked to the library \ref EVENT_USB_Device_ControlRequest() event.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Audio class driver callback for the setting and retrieval of streaming endpoint properties. This callback must be implemented
 | 
			
		||||
			 *  in the user application to handle property manipulations on streaming audio endpoints.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for
 | 
			
		||||
			 *  the given endpoint index, and should return as fast as possible. When non-NULL, this value may be altered for GET operations
 | 
			
		||||
			 *  to indicate the size of the retrieved data.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value
 | 
			
		||||
			 *        of the \c DataLength parameter.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *  \param[in]     EndpointProperty    Property of the endpoint to get or set, a value from \ref Audio_ClassRequests_t.
 | 
			
		||||
			 *  \param[in]     EndpointAddress     Address of the streaming endpoint whose property is being referenced.
 | 
			
		||||
			 *  \param[in]     EndpointControl     Parameter of the endpoint to get or set, a value from \ref Audio_EndpointControls_t.
 | 
			
		||||
			 *  \param[in,out] DataLength          For SET operations, the length of the parameter data to set. For GET operations, the maximum
 | 
			
		||||
			 *                                     length of the retrieved data. When NULL, the function should return whether the given property
 | 
			
		||||
			 *                                     and parameter is valid for the requested endpoint without reading or modifying the Data buffer.
 | 
			
		||||
			 *  \param[in,out] Data                Pointer to a location where the parameter data is stored for SET operations, or where
 | 
			
		||||
			 *                                     the retrieved data is to be stored for GET operations.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the property GET/SET was successful, \c false otherwise
 | 
			
		||||
			 */
 | 
			
		||||
			bool CALLBACK_Audio_Device_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
 | 
			
		||||
			                                                  const uint8_t EndpointProperty,
 | 
			
		||||
			                                                  const uint8_t EndpointAddress,
 | 
			
		||||
			                                                  const uint8_t EndpointControl,
 | 
			
		||||
			                                                  uint16_t* const DataLength,
 | 
			
		||||
			                                                  uint8_t* Data) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Audio class driver callback for the setting and retrieval of streaming interface properties. This callback must be implemented
 | 
			
		||||
			 *  in the user application to handle property manipulations on streaming audio interfaces.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for
 | 
			
		||||
			 *  the given entity and should return as fast as possible. When non-NULL, this value may be altered for GET operations
 | 
			
		||||
			 *  to indicate the size of the retrieved data.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value
 | 
			
		||||
			 *        of the \c DataLength parameter.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *  \param[in]     Property            Property of the interface to get or set, a value from \ref Audio_ClassRequests_t.
 | 
			
		||||
			 *  \param[in]     EntityAddress       Address of the audio entity whose property is being referenced.
 | 
			
		||||
			 *  \param[in]     Parameter           Parameter of the entity to get or set, specific to each type of entity (see USB Audio specification).
 | 
			
		||||
			 *  \param[in,out] DataLength          For SET operations, the length of the parameter data to set. For GET operations, the maximum
 | 
			
		||||
			 *                                     length of the retrieved data. When NULL, the function should return whether the given property
 | 
			
		||||
			 *                                     and parameter is valid for the requested endpoint without reading or modifying the Data buffer.
 | 
			
		||||
			 *  \param[in,out] Data                Pointer to a location where the parameter data is stored for SET operations, or where
 | 
			
		||||
			 *                                     the retrieved data is to be stored for GET operations.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the property GET/SET was successful, \c false otherwise
 | 
			
		||||
			 */
 | 
			
		||||
			bool CALLBACK_Audio_Device_GetSetInterfaceProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
 | 
			
		||||
			                                                   const uint8_t Property,
 | 
			
		||||
			                                                   const uint8_t EntityAddress,
 | 
			
		||||
			                                                   const uint16_t Parameter,
 | 
			
		||||
			                                                   uint16_t* const DataLength,
 | 
			
		||||
			                                                   uint8_t* Data) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Audio class driver event for an Audio Stream start/stop change. This event fires each time the device receives a stream enable or
 | 
			
		||||
			 *  disable control request from the host, to start and stop the audio stream. The current state of the stream can be determined by the
 | 
			
		||||
			 *  State.InterfaceEnabled value inside the Audio interface structure passed as a parameter.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void EVENT_Audio_Device_StreamStartStop(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo);
 | 
			
		||||
 | 
			
		||||
		/* Inline Functions: */
 | 
			
		||||
			/** General management task for a given Audio class interface, required for the correct operation of the interface. This should
 | 
			
		||||
			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			                                        ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
 | 
			
		||||
			static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			{
 | 
			
		||||
				(void)AudioInterfaceInfo;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming
 | 
			
		||||
			 *  OUT endpoint ready for reading.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 | 
			
		||||
			 *       the call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the given Audio interface has a sample to be read, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			                                                 ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
 | 
			
		||||
			static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			{
 | 
			
		||||
				if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
 | 
			
		||||
				  return false;
 | 
			
		||||
 | 
			
		||||
				Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
				return Endpoint_IsOUTReceived();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects
 | 
			
		||||
			 *  the streaming IN endpoint ready for writing.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 | 
			
		||||
			 *       the call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the given Audio interface is ready to accept the next sample, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			                                                     ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
 | 
			
		||||
			static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			{
 | 
			
		||||
				if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled))
 | 
			
		||||
				  return false;
 | 
			
		||||
 | 
			
		||||
				Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
				return Endpoint_IsINReady();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/** Reads the next 8-bit audio sample from the current audio interface.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
 | 
			
		||||
			 *       that the correct endpoint is selected and ready for data.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return  Signed 8-bit audio sample from the audio interface.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			                                              ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
 | 
			
		||||
			static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			{
 | 
			
		||||
				int8_t Sample;
 | 
			
		||||
 | 
			
		||||
				(void)AudioInterfaceInfo;
 | 
			
		||||
 | 
			
		||||
				Sample = Endpoint_Read_8();
 | 
			
		||||
 | 
			
		||||
				if (!(Endpoint_BytesInEndpoint()))
 | 
			
		||||
				  Endpoint_ClearOUT();
 | 
			
		||||
 | 
			
		||||
				return Sample;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/** Reads the next 16-bit audio sample from the current audio interface.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
 | 
			
		||||
			 *       that the correct endpoint is selected and ready for data.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return  Signed 16-bit audio sample from the audio interface.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			                                                ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
 | 
			
		||||
			static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			{
 | 
			
		||||
				int16_t Sample;
 | 
			
		||||
 | 
			
		||||
				(void)AudioInterfaceInfo;
 | 
			
		||||
 | 
			
		||||
				Sample = (int16_t)Endpoint_Read_16_LE();
 | 
			
		||||
 | 
			
		||||
				if (!(Endpoint_BytesInEndpoint()))
 | 
			
		||||
				  Endpoint_ClearOUT();
 | 
			
		||||
 | 
			
		||||
				return Sample;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/** Reads the next 24-bit audio sample from the current audio interface.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure
 | 
			
		||||
			 *       that the correct endpoint is selected and ready for data.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Signed 24-bit audio sample from the audio interface.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			                                                ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
 | 
			
		||||
			static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
			{
 | 
			
		||||
				int32_t Sample;
 | 
			
		||||
 | 
			
		||||
				(void)AudioInterfaceInfo;
 | 
			
		||||
 | 
			
		||||
				Sample = (((uint32_t)Endpoint_Read_8() << 16) | Endpoint_Read_16_LE());
 | 
			
		||||
 | 
			
		||||
				if (!(Endpoint_BytesInEndpoint()))
 | 
			
		||||
				  Endpoint_ClearOUT();
 | 
			
		||||
 | 
			
		||||
				return Sample;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/** Writes the next 8-bit audio sample to the current audio interface.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
 | 
			
		||||
			 *       ensure that the correct endpoint is selected and ready for data.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *  \param[in]     Sample              Signed 8-bit audio sample.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
 | 
			
		||||
			                                             const int8_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
 | 
			
		||||
			static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
 | 
			
		||||
			                                             const int8_t Sample)
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_Write_8(Sample);
 | 
			
		||||
 | 
			
		||||
				if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size)
 | 
			
		||||
				  Endpoint_ClearIN();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/** Writes the next 16-bit audio sample to the current audio interface.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
 | 
			
		||||
			 *       ensure that the correct endpoint is selected and ready for data.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *  \param[in]     Sample              Signed 16-bit audio sample.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
 | 
			
		||||
			                                              const int16_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
 | 
			
		||||
			static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
 | 
			
		||||
			                                              const int16_t Sample)
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_Write_16_LE(Sample);
 | 
			
		||||
 | 
			
		||||
				if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size)
 | 
			
		||||
				  Endpoint_ClearIN();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/** Writes the next 24-bit audio sample to the current audio interface.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to
 | 
			
		||||
			 *       ensure that the correct endpoint is selected and ready for data.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 | 
			
		||||
			 *  \param[in]     Sample              Signed 24-bit audio sample.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
 | 
			
		||||
			                                              const int32_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
 | 
			
		||||
			static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
 | 
			
		||||
			                                              const int32_t Sample)
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_Write_16_LE(Sample);
 | 
			
		||||
				Endpoint_Write_8(Sample >> 16);
 | 
			
		||||
 | 
			
		||||
				if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size)
 | 
			
		||||
				  Endpoint_ClearIN();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
	/* Private Interface - For use in library only: */
 | 
			
		||||
	#if !defined(__DOXYGEN__)
 | 
			
		||||
		/* Function Prototypes: */
 | 
			
		||||
			#if defined(__INCLUDE_FROM_AUDIO_DEVICE_C)
 | 
			
		||||
				void Audio_Device_Event_Stub(void) ATTR_CONST;
 | 
			
		||||
 | 
			
		||||
				void EVENT_Audio_Device_StreamStartStop(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
 | 
			
		||||
				                                        ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(Audio_Device_Event_Stub);
 | 
			
		||||
			#endif
 | 
			
		||||
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	/* Disable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			}
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,339 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_USB_DRIVER
 | 
			
		||||
#include "../../Core/USBMode.h"
 | 
			
		||||
 | 
			
		||||
#if defined(USB_CAN_BE_DEVICE)
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_CDC_DRIVER
 | 
			
		||||
#define  __INCLUDE_FROM_CDC_DEVICE_C
 | 
			
		||||
#include "CDCClassDevice.h"
 | 
			
		||||
 | 
			
		||||
void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if (!(Endpoint_IsSETUPReceived()))
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber)
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	switch (USB_ControlRequest.bRequest)
 | 
			
		||||
	{
 | 
			
		||||
		case CDC_REQ_GetLineEncoding:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
 | 
			
		||||
				while (!(Endpoint_IsINReady()));
 | 
			
		||||
 | 
			
		||||
				Endpoint_Write_32_LE(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
 | 
			
		||||
				Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat);
 | 
			
		||||
				Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType);
 | 
			
		||||
				Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits);
 | 
			
		||||
 | 
			
		||||
				Endpoint_ClearIN();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case CDC_REQ_SetLineEncoding:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
 | 
			
		||||
				while (!(Endpoint_IsOUTReceived()))
 | 
			
		||||
				{
 | 
			
		||||
					if (USB_DeviceState == DEVICE_STATE_Unattached)
 | 
			
		||||
					  return;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE();
 | 
			
		||||
				CDCInterfaceInfo->State.LineEncoding.CharFormat  = Endpoint_Read_8();
 | 
			
		||||
				CDCInterfaceInfo->State.LineEncoding.ParityType  = Endpoint_Read_8();
 | 
			
		||||
				CDCInterfaceInfo->State.LineEncoding.DataBits    = Endpoint_Read_8();
 | 
			
		||||
 | 
			
		||||
				Endpoint_ClearOUT();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
 | 
			
		||||
				EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case CDC_REQ_SetControlLineState:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
 | 
			
		||||
				CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue;
 | 
			
		||||
 | 
			
		||||
				EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case CDC_REQ_SendBreak:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
 | 
			
		||||
				EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State));
 | 
			
		||||
 | 
			
		||||
	CDCInterfaceInfo->Config.DataINEndpoint.Type       = EP_TYPE_BULK;
 | 
			
		||||
	CDCInterfaceInfo->Config.DataOUTEndpoint.Type      = EP_TYPE_BULK;
 | 
			
		||||
	CDCInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataINEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataOUTEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.NotificationEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
 | 
			
		||||
	CDC_Device_Flush(CDCInterfaceInfo);
 | 
			
		||||
	#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
                              const char* const String)
 | 
			
		||||
{
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
 | 
			
		||||
	  return ENDPOINT_RWSTREAM_DeviceDisconnected;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
	return Endpoint_Write_Stream_LE(String, strlen(String), NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
                            const char* const Buffer,
 | 
			
		||||
                            const uint16_t Length)
 | 
			
		||||
{
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
 | 
			
		||||
	  return ENDPOINT_RWSTREAM_DeviceDisconnected;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
	return Endpoint_Write_Stream_LE(Buffer, Length, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
                            const uint8_t Data)
 | 
			
		||||
{
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
 | 
			
		||||
	  return ENDPOINT_RWSTREAM_DeviceDisconnected;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_IsReadWriteAllowed()))
 | 
			
		||||
	{
 | 
			
		||||
		Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
		uint8_t ErrorCode;
 | 
			
		||||
 | 
			
		||||
		if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
 | 
			
		||||
		  return ErrorCode;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Endpoint_Write_8(Data);
 | 
			
		||||
	return ENDPOINT_READYWAIT_NoError;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
 | 
			
		||||
	  return ENDPOINT_RWSTREAM_DeviceDisconnected;
 | 
			
		||||
 | 
			
		||||
	uint8_t ErrorCode;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_BytesInEndpoint()))
 | 
			
		||||
	  return ENDPOINT_READYWAIT_NoError;
 | 
			
		||||
 | 
			
		||||
	bool BankFull = !(Endpoint_IsReadWriteAllowed());
 | 
			
		||||
 | 
			
		||||
	Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
	if (BankFull)
 | 
			
		||||
	{
 | 
			
		||||
		if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
 | 
			
		||||
		  return ErrorCode;
 | 
			
		||||
 | 
			
		||||
		Endpoint_ClearIN();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ENDPOINT_READYWAIT_NoError;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
 | 
			
		||||
	  return 0;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if (Endpoint_IsOUTReceived())
 | 
			
		||||
	{
 | 
			
		||||
		if (!(Endpoint_BytesInEndpoint()))
 | 
			
		||||
		{
 | 
			
		||||
			Endpoint_ClearOUT();
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			return Endpoint_BytesInEndpoint();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
 | 
			
		||||
	  return -1;
 | 
			
		||||
 | 
			
		||||
	int16_t ReceivedByte = -1;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if (Endpoint_IsOUTReceived())
 | 
			
		||||
	{
 | 
			
		||||
		if (Endpoint_BytesInEndpoint())
 | 
			
		||||
		  ReceivedByte = Endpoint_Read_8();
 | 
			
		||||
 | 
			
		||||
		if (!(Endpoint_BytesInEndpoint()))
 | 
			
		||||
		  Endpoint_ClearOUT();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ReceivedByte;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	USB_Request_Header_t Notification = (USB_Request_Header_t)
 | 
			
		||||
		{
 | 
			
		||||
			.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
 | 
			
		||||
			.bRequest      = CDC_NOTIF_SerialState,
 | 
			
		||||
			.wValue        = CPU_TO_LE16(0),
 | 
			
		||||
			.wIndex        = CPU_TO_LE16(0),
 | 
			
		||||
			.wLength       = CPU_TO_LE16(sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost)),
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
	Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL);
 | 
			
		||||
	Endpoint_Write_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost,
 | 
			
		||||
	                         sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost),
 | 
			
		||||
	                         NULL);
 | 
			
		||||
	Endpoint_ClearIN();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(FDEV_SETUP_STREAM)
 | 
			
		||||
void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
                             FILE* const Stream)
 | 
			
		||||
{
 | 
			
		||||
	*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW);
 | 
			
		||||
	fdev_set_udata(Stream, CDCInterfaceInfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
                                     FILE* const Stream)
 | 
			
		||||
{
 | 
			
		||||
	*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW);
 | 
			
		||||
	fdev_set_udata(Stream, CDCInterfaceInfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CDC_Device_putchar(char c,
 | 
			
		||||
                              FILE* Stream)
 | 
			
		||||
{
 | 
			
		||||
	return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CDC_Device_getchar(FILE* Stream)
 | 
			
		||||
{
 | 
			
		||||
	int16_t ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
 | 
			
		||||
 | 
			
		||||
	if (ReceivedByte < 0)
 | 
			
		||||
	  return _FDEV_EOF;
 | 
			
		||||
 | 
			
		||||
	return ReceivedByte;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int CDC_Device_getchar_Blocking(FILE* Stream)
 | 
			
		||||
{
 | 
			
		||||
	int16_t ReceivedByte;
 | 
			
		||||
 | 
			
		||||
	while ((ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))) < 0)
 | 
			
		||||
	{
 | 
			
		||||
		if (USB_DeviceState == DEVICE_STATE_Unattached)
 | 
			
		||||
		  return _FDEV_EOF;
 | 
			
		||||
 | 
			
		||||
		CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
 | 
			
		||||
		USB_USBTask();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ReceivedByte;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// cppcheck-suppress unusedFunction
 | 
			
		||||
void CDC_Device_Event_Stub(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,352 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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
 | 
			
		||||
 *  \brief Device mode driver for the library USB CDC Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  Device mode driver for the library USB CDC Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  \note This file should not be included directly. It is automatically included as needed by the USB module driver
 | 
			
		||||
 *        dispatch header located in LUFA/Drivers/USB.h.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** \ingroup Group_USBClassCDC
 | 
			
		||||
 *  \defgroup Group_USBClassCDCDevice CDC Class Device Mode Driver
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_Dependencies Module Source Dependencies
 | 
			
		||||
 *  The following files must be built with any user project that uses this module:
 | 
			
		||||
 *    - LUFA/Drivers/USB/Class/Device/CDCClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_ModDescription Module Description
 | 
			
		||||
 *  Device Mode USB Class driver framework interface, for the CDC USB Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  \note There are several major drawbacks to the CDC-ACM standard USB class, however
 | 
			
		||||
 *        it is very standardized and thus usually available as a built-in driver on
 | 
			
		||||
 *        most platforms, and so is a better choice than a proprietary serial class.
 | 
			
		||||
 *
 | 
			
		||||
 *        One major issue with CDC-ACM is that it requires two Interface descriptors,
 | 
			
		||||
 *        which will upset most hosts when part of a multi-function "Composite" USB
 | 
			
		||||
 *        device. This is because each interface will be loaded into a separate driver
 | 
			
		||||
 *        instance, causing the two interfaces be become unlinked. To prevent this, you
 | 
			
		||||
 *        should use the "Interface Association Descriptor" addendum to the USB 2.0 standard
 | 
			
		||||
 *        which is available on most OSes when creating Composite devices.
 | 
			
		||||
 *
 | 
			
		||||
 *        Another major oversight is that there is no mechanism for the host to notify the
 | 
			
		||||
 *        device that there is a data sink on the host side ready to accept data. This
 | 
			
		||||
 *        means that the device may try to send data while the host isn't listening, causing
 | 
			
		||||
 *        lengthy blocking timeouts in the transmission routines. It is thus highly recommended
 | 
			
		||||
 *        that the virtual serial line DTR (Data Terminal Ready) signal be used where possible
 | 
			
		||||
 *        to determine if a host application is ready for data.
 | 
			
		||||
 *
 | 
			
		||||
 *  @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _CDC_CLASS_DEVICE_H_
 | 
			
		||||
#define _CDC_CLASS_DEVICE_H_
 | 
			
		||||
 | 
			
		||||
	/* Includes: */
 | 
			
		||||
		#include "../../USB.h"
 | 
			
		||||
		#include "../Common/CDCClassCommon.h"
 | 
			
		||||
 | 
			
		||||
		#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
	/* Enable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			extern "C" {
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Preprocessor Checks: */
 | 
			
		||||
		#if !defined(__INCLUDE_FROM_CDC_DRIVER)
 | 
			
		||||
			#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Public Interface - May be used in end-application: */
 | 
			
		||||
		/* Type Defines: */
 | 
			
		||||
			/** \brief CDC Class Device Mode Configuration and State Structure.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  Class state structure. An instance of this structure should be made for each CDC interface
 | 
			
		||||
			 *  within the user application, and passed to each of the CDC class driver functions as the
 | 
			
		||||
			 *  CDCInterfaceInfo parameter. This stores each CDC interface's configuration and state information.
 | 
			
		||||
			 */
 | 
			
		||||
			typedef struct
 | 
			
		||||
			{
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device. */
 | 
			
		||||
					
 | 
			
		||||
					USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
 | 
			
		||||
					USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
 | 
			
		||||
					USB_Endpoint_Table_t NotificationEndpoint; /**< Notification IN Endpoint configuration table. */
 | 
			
		||||
				} Config; /**< Config data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				           *   <b>must</b> be set or the interface will fail to enumerate and operate correctly.
 | 
			
		||||
				           */
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					struct
 | 
			
		||||
					{
 | 
			
		||||
						uint16_t HostToDevice; /**< Control line states from the host to device, as a set of \c CDC_CONTROL_LINE_OUT_*
 | 
			
		||||
											    *   masks. This value is updated each time \ref CDC_Device_USBTask() is called.
 | 
			
		||||
											    */
 | 
			
		||||
						uint16_t DeviceToHost; /**< Control line states from the device to host, as a set of \c CDC_CONTROL_LINE_IN_*
 | 
			
		||||
											    *   masks - to notify the host of changes to these values, call the
 | 
			
		||||
											    *   \ref CDC_Device_SendControlLineStateChange() function.
 | 
			
		||||
											    */
 | 
			
		||||
					} ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */
 | 
			
		||||
 | 
			
		||||
					CDC_LineEncoding_t LineEncoding; /** Line encoding used in the virtual serial port, for the device's information.
 | 
			
		||||
					                                  *  This is generally only used if the virtual serial port data is to be
 | 
			
		||||
					                                  *  reconstructed on a physical UART.
 | 
			
		||||
					                                  */
 | 
			
		||||
				} State; /**< State data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				          *   are reset to their defaults when the interface is enumerated.
 | 
			
		||||
				          */
 | 
			
		||||
			} USB_ClassInfo_CDC_Device_t;
 | 
			
		||||
 | 
			
		||||
		/* Function Prototypes: */
 | 
			
		||||
			/** Configures the endpoints of a given CDC interface, ready for use. This should be linked to the library
 | 
			
		||||
			 *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing
 | 
			
		||||
			 *  the given CDC interface is selected.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Processes incoming control requests from the host, that are directed to the given CDC class interface. This should be
 | 
			
		||||
			 *  linked to the library \ref EVENT_USB_Device_ControlRequest() event.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** General management task for a given CDC class interface, required for the correct operation of the interface. This should
 | 
			
		||||
			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a
 | 
			
		||||
			 *  line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the
 | 
			
		||||
			 *  user program by declaring a handler function with the same name and parameters listed here. The new line encoding
 | 
			
		||||
			 *  settings are available in the LineEncoding structure inside the CDC interface structure passed as a parameter.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a
 | 
			
		||||
			 *  control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the
 | 
			
		||||
			 *  user program by declaring a handler function with the same name and parameters listed here. The new control line states
 | 
			
		||||
			 *  are available in the \c ControlLineStates.HostToDevice value inside the CDC interface structure passed as a parameter, set as
 | 
			
		||||
			 *  a mask of \c CDC_CONTROL_LINE_OUT_* masks.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** CDC class driver event for a send break request sent to the device from the host. This is generally used to separate
 | 
			
		||||
			 *  data or to indicate a special condition to the receiving device.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 *  \param[in]     Duration          Duration of the break that has been sent by the host, in milliseconds.
 | 
			
		||||
			 */
 | 
			
		||||
			void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
			                                const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is
 | 
			
		||||
			 *  called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank
 | 
			
		||||
			 *  becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
 | 
			
		||||
			 *  for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 | 
			
		||||
			 *       the call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 *  \param[in]     Buffer            Pointer to a buffer containing the data to send to the device.
 | 
			
		||||
			 *  \param[in]     Length            Length of the data to send to the host.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
 | 
			
		||||
			 */
 | 
			
		||||
			uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
			                            const char* const Buffer,
 | 
			
		||||
			                            const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
 | 
			
		||||
 | 
			
		||||
			/** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when
 | 
			
		||||
			 *  the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
 | 
			
		||||
			 *  the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to
 | 
			
		||||
			 *  the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 | 
			
		||||
			 *       the call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 *  \param[in]     String            Pointer to the null terminated string to send to the host.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
 | 
			
		||||
			 */
 | 
			
		||||
			uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
			                              const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
 | 
			
		||||
 | 
			
		||||
			/** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
 | 
			
		||||
			 *  byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
 | 
			
		||||
			 *  \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be
 | 
			
		||||
			 *  packed into a single endpoint packet, increasing data throughput.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 | 
			
		||||
			 *       the call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 *  \param[in]     Data              Byte of data to send to the host.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
 | 
			
		||||
			 */
 | 
			
		||||
			uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
			                            const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Determines the number of bytes received by the CDC interface from the host, waiting to be read. This indicates the number
 | 
			
		||||
			 *  of bytes in the OUT endpoint bank only, and thus the number of calls to \ref CDC_Device_ReceiveByte() which are guaranteed to
 | 
			
		||||
			 *  succeed immediately. If multiple bytes are to be received, they should be buffered by the user application, as the endpoint
 | 
			
		||||
			 *  bank will not be released back to the USB controller until all bytes are read.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 | 
			
		||||
			 *       the call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Total number of buffered bytes received from the host.
 | 
			
		||||
			 */
 | 
			
		||||
			uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function
 | 
			
		||||
			 *  returns a negative value. The \ref CDC_Device_BytesReceived() function may be queried in advance to determine how many
 | 
			
		||||
			 *  bytes are currently buffered in the CDC interface's data receive endpoint bank, and thus how many repeated calls to this
 | 
			
		||||
			 *  function which are guaranteed to succeed.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 | 
			
		||||
			 *       the call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Next received byte from the host, or a negative value if no data received.
 | 
			
		||||
			 */
 | 
			
		||||
			int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Flushes any data waiting to be sent, ensuring that the send buffer is cleared.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 | 
			
		||||
			 *       the call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
 | 
			
		||||
			 */
 | 
			
		||||
			uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial
 | 
			
		||||
			 *  control lines (DCD, DSR, etc.) have changed states, or to give BREAK notifications to the host. Line states persist
 | 
			
		||||
			 *  until they are cleared via a second notification. This should be called each time the CDC class driver's
 | 
			
		||||
			 *  \c ControlLineStates.DeviceToHost value is updated to push the new states to the USB host.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
 | 
			
		||||
			 *       the call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			#if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__)
 | 
			
		||||
			/** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular
 | 
			
		||||
			 *  functions in the standard <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf()). The created
 | 
			
		||||
			 *  stream is bidirectional and can be used for both input and output functions.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
 | 
			
		||||
			 *  fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
 | 
			
		||||
			 *  be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own
 | 
			
		||||
			 *  line buffering.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \note The created stream can be given as \c stdout if desired to direct the standard output from all <stdio.h> functions
 | 
			
		||||
			 *        to the given CDC interface.
 | 
			
		||||
			 *        \n\n
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \note This function is not available on all microcontroller architectures.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 *  \param[in,out] Stream            Pointer to a FILE structure where the created stream should be placed.
 | 
			
		||||
			 */
 | 
			
		||||
			void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
			                             FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
 | 
			
		||||
 | 
			
		||||
			/** Identical to \ref CDC_Device_CreateStream(), except that reads are blocking until the calling stream function terminates
 | 
			
		||||
			 *  the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \note This function is not available on all microcontroller architectures.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 | 
			
		||||
			 *  \param[in,out] Stream            Pointer to a FILE structure where the created stream should be placed.
 | 
			
		||||
			 */
 | 
			
		||||
			void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
			                                     FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
 | 
			
		||||
			#endif
 | 
			
		||||
			
 | 
			
		||||
	/* Private Interface - For use in library only: */
 | 
			
		||||
	#if !defined(__DOXYGEN__)
 | 
			
		||||
		/* Function Prototypes: */
 | 
			
		||||
			#if defined(__INCLUDE_FROM_CDC_DEVICE_C)
 | 
			
		||||
				#if defined(FDEV_SETUP_STREAM)
 | 
			
		||||
				static int CDC_Device_putchar(char c,
 | 
			
		||||
				                              FILE* Stream) ATTR_NON_NULL_PTR_ARG(2);
 | 
			
		||||
				static int CDC_Device_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
				static int CDC_Device_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
				#endif
 | 
			
		||||
 | 
			
		||||
				void CDC_Device_Event_Stub(void) ATTR_CONST;
 | 
			
		||||
 | 
			
		||||
				void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
 | 
			
		||||
				                                          ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
 | 
			
		||||
				void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
 | 
			
		||||
				                                             ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub);
 | 
			
		||||
				void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
 | 
			
		||||
				                                const uint8_t Duration) ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1)
 | 
			
		||||
				                                ATTR_ALIAS(CDC_Device_Event_Stub);
 | 
			
		||||
			#endif
 | 
			
		||||
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	/* Disable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			}
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,200 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_USB_DRIVER
 | 
			
		||||
#include "../../Core/USBMode.h"
 | 
			
		||||
 | 
			
		||||
#if defined(USB_CAN_BE_DEVICE)
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_HID_DRIVER
 | 
			
		||||
#define  __INCLUDE_FROM_HID_DEVICE_C
 | 
			
		||||
#include "HIDClassDevice.h"
 | 
			
		||||
 | 
			
		||||
void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if (!(Endpoint_IsSETUPReceived()))
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber)
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	switch (USB_ControlRequest.bRequest)
 | 
			
		||||
	{
 | 
			
		||||
		case HID_REQ_GetReport:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				uint16_t ReportSize = 0;
 | 
			
		||||
				uint8_t  ReportID   = (USB_ControlRequest.wValue & 0xFF);
 | 
			
		||||
				uint8_t  ReportType = (USB_ControlRequest.wValue >> 8) - 1;
 | 
			
		||||
				uint8_t  ReportData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
 | 
			
		||||
 | 
			
		||||
				memset(ReportData, 0, sizeof(ReportData));
 | 
			
		||||
 | 
			
		||||
				CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportType, ReportData, &ReportSize);
 | 
			
		||||
 | 
			
		||||
				if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
 | 
			
		||||
				{
 | 
			
		||||
					memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportData,
 | 
			
		||||
					       HIDInterfaceInfo->Config.PrevReportINBufferSize);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
 | 
			
		||||
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
 | 
			
		||||
				Endpoint_ClearOUT();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case HID_REQ_SetReport:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				uint16_t ReportSize = USB_ControlRequest.wLength;
 | 
			
		||||
				uint8_t  ReportID   = (USB_ControlRequest.wValue & 0xFF);
 | 
			
		||||
				uint8_t  ReportType = (USB_ControlRequest.wValue >> 8) - 1;
 | 
			
		||||
				uint8_t  ReportData[ReportSize];
 | 
			
		||||
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_Read_Control_Stream_LE(ReportData, ReportSize);
 | 
			
		||||
				Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
				CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType,
 | 
			
		||||
				                                     &ReportData[ReportID ? 1 : 0], ReportSize - (ReportID ? 1 : 0));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case HID_REQ_GetProtocol:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				while (!(Endpoint_IsINReady()));
 | 
			
		||||
				Endpoint_Write_8(HIDInterfaceInfo->State.UsingReportProtocol);
 | 
			
		||||
				Endpoint_ClearIN();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case HID_REQ_SetProtocol:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
 | 
			
		||||
				HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case HID_REQ_SetIdle:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
 | 
			
		||||
				HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case HID_REQ_GetIdle:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				while (!(Endpoint_IsINReady()));
 | 
			
		||||
				Endpoint_Write_8(HIDInterfaceInfo->State.IdleCount >> 2);
 | 
			
		||||
				Endpoint_ClearIN();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State));
 | 
			
		||||
	HIDInterfaceInfo->State.UsingReportProtocol = true;
 | 
			
		||||
	HIDInterfaceInfo->State.IdleCount           = 500;
 | 
			
		||||
 | 
			
		||||
	HIDInterfaceInfo->Config.ReportINEndpoint.Type = EP_TYPE_INTERRUPT;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&HIDInterfaceInfo->Config.ReportINEndpoint, 1)))
 | 
			
		||||
	  return false;	
 | 
			
		||||
	
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if (USB_DeviceState != DEVICE_STATE_Configured)
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	if (HIDInterfaceInfo->State.PrevFrameNum == USB_Device_GetFrameNumber())
 | 
			
		||||
	  return;
 | 
			
		||||
	  
 | 
			
		||||
	Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if (Endpoint_IsReadWriteAllowed())
 | 
			
		||||
	{
 | 
			
		||||
		uint8_t  ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize];
 | 
			
		||||
		uint8_t  ReportID     = 0;
 | 
			
		||||
		uint16_t ReportINSize = 0;
 | 
			
		||||
 | 
			
		||||
		memset(ReportINData, 0, sizeof(ReportINData));
 | 
			
		||||
 | 
			
		||||
		bool ForceSend         = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, HID_REPORT_ITEM_In,
 | 
			
		||||
		                                                             ReportINData, &ReportINSize);
 | 
			
		||||
		bool StatesChanged     = false;
 | 
			
		||||
		bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining));
 | 
			
		||||
 | 
			
		||||
		if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
 | 
			
		||||
		{
 | 
			
		||||
			StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0);
 | 
			
		||||
			memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed))
 | 
			
		||||
		{
 | 
			
		||||
			HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount;
 | 
			
		||||
 | 
			
		||||
			Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
			if (ReportID)
 | 
			
		||||
			  Endpoint_Write_8(ReportID);
 | 
			
		||||
 | 
			
		||||
			Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NULL);
 | 
			
		||||
 | 
			
		||||
			Endpoint_ClearIN();
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		HIDInterfaceInfo->State.PrevFrameNum = USB_Device_GetFrameNumber();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,210 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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
 | 
			
		||||
 *  \brief Device mode driver for the library USB HID Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  Device mode driver for the library USB HID Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  \note This file should not be included directly. It is automatically included as needed by the USB module driver
 | 
			
		||||
 *        dispatch header located in LUFA/Drivers/USB.h.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** \ingroup Group_USBClassHID
 | 
			
		||||
 *  \defgroup Group_USBClassHIDDevice HID Class Device Mode Driver
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_Dependencies Module Source Dependencies
 | 
			
		||||
 *  The following files must be built with any user project that uses this module:
 | 
			
		||||
 *    - LUFA/Drivers/USB/Class/Device/HIDClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_ModDescription Module Description
 | 
			
		||||
 *  Device Mode USB Class driver framework interface, for the HID USB Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _HID_CLASS_DEVICE_H_
 | 
			
		||||
#define _HID_CLASS_DEVICE_H_
 | 
			
		||||
 | 
			
		||||
	/* Includes: */
 | 
			
		||||
		#include "../../USB.h"
 | 
			
		||||
		#include "../Common/HIDClassCommon.h"
 | 
			
		||||
 | 
			
		||||
	/* Enable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			extern "C" {
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Preprocessor Checks: */
 | 
			
		||||
		#if !defined(__INCLUDE_FROM_HID_DRIVER)
 | 
			
		||||
			#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Public Interface - May be used in end-application: */
 | 
			
		||||
		/* Type Defines: */
 | 
			
		||||
			/** \brief HID Class Device Mode Configuration and State Structure.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  Class state structure. An instance of this structure should be made for each HID interface
 | 
			
		||||
			 *  within the user application, and passed to each of the HID class driver functions as the
 | 
			
		||||
			 *  \c HIDInterfaceInfo parameter. This stores each HID interface's configuration and state information.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \note Due to technical limitations, the HID device class driver does not utilize a separate OUT
 | 
			
		||||
			 *        endpoint for host->device communications. Instead, the host->device data (if any) is sent to
 | 
			
		||||
			 *        the device via the control endpoint.
 | 
			
		||||
			 */
 | 
			
		||||
			typedef struct
 | 
			
		||||
			{
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					uint8_t  InterfaceNumber; /**< Interface number of the HID interface within the device. */
 | 
			
		||||
 | 
			
		||||
					USB_Endpoint_Table_t ReportINEndpoint; /**< Data IN HID report endpoint configuration table. */
 | 
			
		||||
 | 
			
		||||
					void*    PrevReportINBuffer; /**< Pointer to a buffer where the previously created HID input report can be
 | 
			
		||||
					                              *  stored by the driver, for comparison purposes to detect report changes that
 | 
			
		||||
					                              *  must be sent immediately to the host. This should point to a buffer big enough
 | 
			
		||||
					                              *  to hold the largest HID input report sent from the HID interface. If this is set
 | 
			
		||||
												  *  to \c NULL, it is up to the user to force transfers when needed in the
 | 
			
		||||
												  *  \ref CALLBACK_HID_Device_CreateHIDReport() callback function.
 | 
			
		||||
												  *
 | 
			
		||||
												  *  \note Due to the single buffer, the internal driver can only correctly compare
 | 
			
		||||
												  *        subsequent reports with identical report IDs. In multiple report devices,
 | 
			
		||||
												  *        this buffer should be set to \c NULL and the decision to send reports made
 | 
			
		||||
												  *        by the user application instead.
 | 
			
		||||
					                              */
 | 
			
		||||
					uint8_t  PrevReportINBufferSize; /**< Size in bytes of the given input report buffer. This is used to create a
 | 
			
		||||
					                                  *  second buffer of the same size within the driver so that subsequent reports
 | 
			
		||||
					                                  *  can be compared. If the user app is to determine when reports are to be sent
 | 
			
		||||
					                                  *  exclusively (i.e. \ref PrevReportINBuffer is \c NULL) this value must still be
 | 
			
		||||
													  *  set to the size of the largest report the device can issue to the host.
 | 
			
		||||
					                                  */
 | 
			
		||||
				} Config; /**< Config data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				           *   <b>must</b> be set or the interface will fail to enumerate and operate correctly.
 | 
			
		||||
				           */
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					bool     UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode. */
 | 
			
		||||
					uint16_t PrevFrameNum; /**< Frame number of the previous HID report packet opportunity. */
 | 
			
		||||
					uint16_t IdleCount; /**< Report idle period, in milliseconds, set by the host. */
 | 
			
		||||
					uint16_t IdleMSRemaining; /**< Total number of milliseconds remaining before the idle period elapsed - this
 | 
			
		||||
											   *   should be decremented by the user application if non-zero each millisecond. */
 | 
			
		||||
				} State; /**< State data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				          *   are reset to their defaults when the interface is enumerated.
 | 
			
		||||
				          */
 | 
			
		||||
			} USB_ClassInfo_HID_Device_t;
 | 
			
		||||
 | 
			
		||||
		/* Function Prototypes: */
 | 
			
		||||
			/** Configures the endpoints of a given HID interface, ready for use. This should be linked to the library
 | 
			
		||||
			 *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
 | 
			
		||||
			 *  containing the given HID interface is selected.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Processes incoming control requests from the host, that are directed to the given HID class interface. This should be
 | 
			
		||||
			 *  linked to the library \ref EVENT_USB_Device_ControlRequest() event.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** General management task for a given HID class interface, required for the correct operation of the interface. This should
 | 
			
		||||
			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** HID class driver callback for the user creation of a HID IN report. This callback may fire in response to either
 | 
			
		||||
			 *  HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the
 | 
			
		||||
			 *  user is responsible for the creation of the next HID input report to be sent to the host.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
 | 
			
		||||
			 *  \param[in,out] ReportID          If preset to a non-zero value, this is the report ID being requested by the host. If zero,
 | 
			
		||||
			 *                                   this should be set to the report ID of the generated HID input report (if any). If multiple
 | 
			
		||||
			 *                                   reports are not sent via the given HID interface, this parameter should be ignored.
 | 
			
		||||
			 *  \param[in]     ReportType        Type of HID report to generate, either \ref HID_REPORT_ITEM_In or \ref HID_REPORT_ITEM_Feature.
 | 
			
		||||
			 *  \param[out]    ReportData        Pointer to a buffer where the generated HID report should be stored.
 | 
			
		||||
			 *  \param[out]    ReportSize        Number of bytes in the generated input report, or zero if no report is to be sent.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true to force the sending of the report even if it is identical to the previous report and still within
 | 
			
		||||
			 *          the idle period (useful for devices which report relative movement), \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
 | 
			
		||||
			                                         uint8_t* const ReportID,
 | 
			
		||||
			                                         const uint8_t ReportType,
 | 
			
		||||
			                                         void* ReportData,
 | 
			
		||||
			                                         uint16_t* const ReportSize) ATTR_NON_NULL_PTR_ARG(1)
 | 
			
		||||
			                                         ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(4) ATTR_NON_NULL_PTR_ARG(5);
 | 
			
		||||
 | 
			
		||||
			/** HID class driver callback for the user processing of a received HID OUT report. This callback may fire in response to
 | 
			
		||||
			 *  either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback
 | 
			
		||||
			 *  the user is responsible for the processing of the received HID output report from the host.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
 | 
			
		||||
			 *  \param[in]     ReportID          Report ID of the received output report. If multiple reports are not received via the given HID
 | 
			
		||||
			 *                                   interface, this parameter should be ignored.
 | 
			
		||||
			 *  \param[in]     ReportType        Type of received HID report, either \ref HID_REPORT_ITEM_Out or \ref HID_REPORT_ITEM_Feature.
 | 
			
		||||
			 *  \param[in]     ReportData        Pointer to a buffer where the received HID report is stored.
 | 
			
		||||
			 *  \param[in]     ReportSize        Size in bytes of the received report from the host.
 | 
			
		||||
			 */
 | 
			
		||||
			void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
 | 
			
		||||
			                                          const uint8_t ReportID,
 | 
			
		||||
			                                          const uint8_t ReportType,
 | 
			
		||||
			                                          const void* ReportData,
 | 
			
		||||
			                                          const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(4);
 | 
			
		||||
 | 
			
		||||
		/* Inline Functions: */
 | 
			
		||||
			/** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be
 | 
			
		||||
			 *  decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended
 | 
			
		||||
			 *  that this be called by the \ref EVENT_USB_Device_StartOfFrame() event, once SOF events have been enabled via
 | 
			
		||||
			 *  \ref USB_Device_EnableSOFEvents().
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_ALWAYS_INLINE ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
			static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
 | 
			
		||||
			{
 | 
			
		||||
				if (HIDInterfaceInfo->State.IdleMSRemaining)
 | 
			
		||||
				  HIDInterfaceInfo->State.IdleMSRemaining--;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
	/* Disable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			}
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,125 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_USB_DRIVER
 | 
			
		||||
#include "../../Core/USBMode.h"
 | 
			
		||||
 | 
			
		||||
#if defined(USB_CAN_BE_DEVICE)
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_MIDI_DRIVER
 | 
			
		||||
#define  __INCLUDE_FROM_MIDI_DEVICE_C
 | 
			
		||||
#include "MIDIClassDevice.h"
 | 
			
		||||
 | 
			
		||||
bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State));
 | 
			
		||||
 | 
			
		||||
	MIDIInterfaceInfo->Config.DataINEndpoint.Type  = EP_TYPE_BULK;
 | 
			
		||||
	MIDIInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&MIDIInterfaceInfo->Config.DataINEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&MIDIInterfaceInfo->Config.DataOUTEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if (USB_DeviceState != DEVICE_STATE_Configured)
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
 | 
			
		||||
	MIDI_Device_Flush(MIDIInterfaceInfo);
 | 
			
		||||
	#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
 | 
			
		||||
                                    const MIDI_EventPacket_t* const Event)
 | 
			
		||||
{
 | 
			
		||||
	if (USB_DeviceState != DEVICE_STATE_Configured)
 | 
			
		||||
	  return ENDPOINT_RWSTREAM_DeviceDisconnected;
 | 
			
		||||
 | 
			
		||||
	uint8_t ErrorCode;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if ((ErrorCode = Endpoint_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL)) != ENDPOINT_RWSTREAM_NoError)
 | 
			
		||||
	  return ErrorCode;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_IsReadWriteAllowed()))
 | 
			
		||||
	  Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
	return ENDPOINT_RWSTREAM_NoError;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if (USB_DeviceState != DEVICE_STATE_Configured)
 | 
			
		||||
	  return ENDPOINT_RWSTREAM_DeviceDisconnected;
 | 
			
		||||
 | 
			
		||||
	uint8_t ErrorCode;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if (Endpoint_BytesInEndpoint())
 | 
			
		||||
	{
 | 
			
		||||
		Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
		if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
 | 
			
		||||
		  return ErrorCode;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ENDPOINT_READYWAIT_NoError;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
 | 
			
		||||
                                    MIDI_EventPacket_t* const Event)
 | 
			
		||||
{
 | 
			
		||||
	if (USB_DeviceState != DEVICE_STATE_Configured)
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_IsReadWriteAllowed()))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	Endpoint_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL);
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_IsReadWriteAllowed()))
 | 
			
		||||
	  Endpoint_ClearOUT();
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,175 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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
 | 
			
		||||
 *  \brief Device mode driver for the library USB MIDI Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  Device mode driver for the library USB MIDI Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  \note This file should not be included directly. It is automatically included as needed by the USB module driver
 | 
			
		||||
 *        dispatch header located in LUFA/Drivers/USB.h.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** \ingroup Group_USBClassMIDI
 | 
			
		||||
 *  \defgroup Group_USBClassMIDIDevice MIDI Class Device Mode Driver
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_Dependencies Module Source Dependencies
 | 
			
		||||
 *  The following files must be built with any user project that uses this module:
 | 
			
		||||
 *    - LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_ModDescription Module Description
 | 
			
		||||
 *  Device Mode USB Class driver framework interface, for the MIDI USB Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _MIDI_CLASS_DEVICE_H_
 | 
			
		||||
#define _MIDI_CLASS_DEVICE_H_
 | 
			
		||||
 | 
			
		||||
	/* Includes: */
 | 
			
		||||
		#include "../../USB.h"
 | 
			
		||||
		#include "../Common/MIDIClassCommon.h"
 | 
			
		||||
 | 
			
		||||
	/* Enable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			extern "C" {
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Preprocessor Checks: */
 | 
			
		||||
		#if !defined(__INCLUDE_FROM_MIDI_DRIVER)
 | 
			
		||||
			#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Public Interface - May be used in end-application: */
 | 
			
		||||
		/* Type Define: */
 | 
			
		||||
			/** \brief MIDI Class Device Mode Configuration and State Structure.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  Class state structure. An instance of this structure should be made for each MIDI interface
 | 
			
		||||
			 *  within the user application, and passed to each of the MIDI class driver functions as the
 | 
			
		||||
			 *  \c MIDIInterfaceInfo parameter. This stores each MIDI interface's configuration and state information.
 | 
			
		||||
			 */
 | 
			
		||||
			typedef struct
 | 
			
		||||
			{
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					uint8_t  StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls. */
 | 
			
		||||
 | 
			
		||||
					USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
 | 
			
		||||
					USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
 | 
			
		||||
				} Config; /**< Config data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				           *   <b>must</b> be set or the interface will fail to enumerate and operate correctly.
 | 
			
		||||
				           */
 | 
			
		||||
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					uint8_t RESERVED; // No state information for this class
 | 
			
		||||
				} State; /**< State data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				          *   are reset to their defaults when the interface is enumerated.
 | 
			
		||||
				          */
 | 
			
		||||
			} USB_ClassInfo_MIDI_Device_t;
 | 
			
		||||
 | 
			
		||||
		/* Function Prototypes: */
 | 
			
		||||
			/** Configures the endpoints of a given MIDI interface, ready for use. This should be linked to the library
 | 
			
		||||
			 *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
 | 
			
		||||
			 *  containing the given MIDI interface is selected.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] MIDIInterfaceInfo  Pointer to a structure containing a MIDI Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** General management task for a given MIDI class interface, required for the correct operation of the interface. This should
 | 
			
		||||
			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] MIDIInterfaceInfo  Pointer to a structure containing a MIDI Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded. Events are queued into the
 | 
			
		||||
			 *  endpoint bank until either the endpoint bank is full, or \ref MIDI_Device_Flush() is called. This allows for multiple
 | 
			
		||||
			 *  MIDI events to be packed into a single endpoint packet, increasing data throughput.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
 | 
			
		||||
			 *       call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] MIDIInterfaceInfo  Pointer to a structure containing a MIDI Class configuration and state.
 | 
			
		||||
			 *  \param[in]     Event              Pointer to a populated \ref MIDI_EventPacket_t structure containing the MIDI event to send.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
 | 
			
		||||
			 */
 | 
			
		||||
			uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
 | 
			
		||||
			                                    const MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			/** Flushes the MIDI send buffer, sending any queued MIDI events to the host. This should be called to override the
 | 
			
		||||
			 *  \ref MIDI_Device_SendEventPacket() function's packing behavior, to flush queued events.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] MIDIInterfaceInfo  Pointer to a structure containing a MIDI Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
 | 
			
		||||
			 */
 | 
			
		||||
			uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Receives a MIDI event packet from the host. Events are unpacked from the endpoint, thus if the endpoint bank contains
 | 
			
		||||
			 *  multiple MIDI events from the host in the one packet, multiple calls to this function will return each individual event.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
 | 
			
		||||
			 *       call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] MIDIInterfaceInfo  Pointer to a structure containing a MIDI Class configuration and state.
 | 
			
		||||
			 *  \param[out]    Event              Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if a MIDI event packet was received, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
 | 
			
		||||
			                                    MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
 | 
			
		||||
 | 
			
		||||
		/* Inline Functions: */
 | 
			
		||||
			/** Processes incoming control requests from the host, that are directed to the given MIDI class interface. This should be
 | 
			
		||||
			 *  linked to the library \ref EVENT_USB_Device_ControlRequest() event.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] MIDIInterfaceInfo  Pointer to a structure containing a MIDI Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
			static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
 | 
			
		||||
			{
 | 
			
		||||
				(void)MIDIInterfaceInfo;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
	/* Disable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			}
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,215 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_USB_DRIVER
 | 
			
		||||
#include "../../Core/USBMode.h"
 | 
			
		||||
 | 
			
		||||
#if defined(USB_CAN_BE_DEVICE)
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_MS_DRIVER
 | 
			
		||||
#define  __INCLUDE_FROM_MASSSTORAGE_DEVICE_C
 | 
			
		||||
#include "MassStorageClassDevice.h"
 | 
			
		||||
 | 
			
		||||
void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if (!(Endpoint_IsSETUPReceived()))
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	if (USB_ControlRequest.wIndex != MSInterfaceInfo->Config.InterfaceNumber)
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	switch (USB_ControlRequest.bRequest)
 | 
			
		||||
	{
 | 
			
		||||
		case MS_REQ_MassStorageReset:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
 | 
			
		||||
				MSInterfaceInfo->State.IsMassStoreReset = true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case MS_REQ_GetMaxLUN:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				while (!(Endpoint_IsINReady()));
 | 
			
		||||
				Endpoint_Write_8(MSInterfaceInfo->Config.TotalLUNs - 1);
 | 
			
		||||
				Endpoint_ClearIN();
 | 
			
		||||
				Endpoint_ClearStatusStage();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State));
 | 
			
		||||
 | 
			
		||||
	MSInterfaceInfo->Config.DataINEndpoint.Type  = EP_TYPE_BULK;
 | 
			
		||||
	MSInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&MSInterfaceInfo->Config.DataINEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&MSInterfaceInfo->Config.DataOUTEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if (USB_DeviceState != DEVICE_STATE_Configured)
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if (Endpoint_IsOUTReceived())
 | 
			
		||||
	{
 | 
			
		||||
		if (MS_Device_ReadInCommandBlock(MSInterfaceInfo))
 | 
			
		||||
		{
 | 
			
		||||
			if (MSInterfaceInfo->State.CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN)
 | 
			
		||||
			  Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
			bool SCSICommandResult = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo);
 | 
			
		||||
 | 
			
		||||
			MSInterfaceInfo->State.CommandStatus.Status              = (SCSICommandResult) ? MS_SCSI_COMMAND_Pass : MS_SCSI_COMMAND_Fail;
 | 
			
		||||
			MSInterfaceInfo->State.CommandStatus.Signature           = CPU_TO_LE32(MS_CSW_SIGNATURE);
 | 
			
		||||
			MSInterfaceInfo->State.CommandStatus.Tag                 = MSInterfaceInfo->State.CommandBlock.Tag;
 | 
			
		||||
			MSInterfaceInfo->State.CommandStatus.DataTransferResidue = MSInterfaceInfo->State.CommandBlock.DataTransferLength;
 | 
			
		||||
 | 
			
		||||
			if (!(SCSICommandResult) && (le32_to_cpu(MSInterfaceInfo->State.CommandStatus.DataTransferResidue)))
 | 
			
		||||
			  Endpoint_StallTransaction();
 | 
			
		||||
 | 
			
		||||
			MS_Device_ReturnCommandStatus(MSInterfaceInfo);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (MSInterfaceInfo->State.IsMassStoreReset)
 | 
			
		||||
	{
 | 
			
		||||
		Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
		Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
		Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
		Endpoint_ClearStall();
 | 
			
		||||
		Endpoint_ResetDataToggle();
 | 
			
		||||
		Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
		Endpoint_ClearStall();
 | 
			
		||||
		Endpoint_ResetDataToggle();
 | 
			
		||||
 | 
			
		||||
		MSInterfaceInfo->State.IsMassStoreReset = false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	uint16_t BytesProcessed;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
	
 | 
			
		||||
	BytesProcessed = 0;
 | 
			
		||||
	while (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock,
 | 
			
		||||
	                               (sizeof(MS_CommandBlockWrapper_t) - 16), &BytesProcessed) ==
 | 
			
		||||
	                               ENDPOINT_RWSTREAM_IncompleteTransfer)
 | 
			
		||||
	{
 | 
			
		||||
		if (MSInterfaceInfo->State.IsMassStoreReset)
 | 
			
		||||
		  return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((MSInterfaceInfo->State.CommandBlock.Signature         != CPU_TO_LE32(MS_CBW_SIGNATURE))     ||
 | 
			
		||||
	    (MSInterfaceInfo->State.CommandBlock.LUN               >= MSInterfaceInfo->Config.TotalLUNs) ||
 | 
			
		||||
		(MSInterfaceInfo->State.CommandBlock.Flags              & 0x1F)                              ||
 | 
			
		||||
		(MSInterfaceInfo->State.CommandBlock.SCSICommandLength == 0)                                 ||
 | 
			
		||||
		(MSInterfaceInfo->State.CommandBlock.SCSICommandLength >  16))
 | 
			
		||||
	{		
 | 
			
		||||
		Endpoint_StallTransaction();
 | 
			
		||||
		Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
		Endpoint_StallTransaction();
 | 
			
		||||
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BytesProcessed = 0;
 | 
			
		||||
	while (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock.SCSICommandData,
 | 
			
		||||
	                                MSInterfaceInfo->State.CommandBlock.SCSICommandLength, &BytesProcessed) ==
 | 
			
		||||
	                                ENDPOINT_RWSTREAM_IncompleteTransfer)
 | 
			
		||||
	{
 | 
			
		||||
		if (MSInterfaceInfo->State.IsMassStoreReset)
 | 
			
		||||
		  return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Endpoint_ClearOUT();
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	while (Endpoint_IsStalled())
 | 
			
		||||
	{
 | 
			
		||||
		#if !defined(INTERRUPT_CONTROL_ENDPOINT)
 | 
			
		||||
		USB_USBTask();
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
		if (MSInterfaceInfo->State.IsMassStoreReset)
 | 
			
		||||
		  return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	while (Endpoint_IsStalled())
 | 
			
		||||
	{
 | 
			
		||||
		#if !defined(INTERRUPT_CONTROL_ENDPOINT)
 | 
			
		||||
		USB_USBTask();
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
		if (MSInterfaceInfo->State.IsMassStoreReset)
 | 
			
		||||
		  return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	uint16_t BytesProcessed = 0;
 | 
			
		||||
	while (Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus,
 | 
			
		||||
	                                sizeof(MS_CommandStatusWrapper_t), &BytesProcessed) ==
 | 
			
		||||
	                                ENDPOINT_RWSTREAM_IncompleteTransfer)
 | 
			
		||||
	{
 | 
			
		||||
		if (MSInterfaceInfo->State.IsMassStoreReset)
 | 
			
		||||
		  return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Endpoint_ClearIN();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,161 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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
 | 
			
		||||
 *  \brief Device mode driver for the library USB Mass Storage Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  Device mode driver for the library USB Mass Storage Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  \note This file should not be included directly. It is automatically included as needed by the USB module driver
 | 
			
		||||
 *        dispatch header located in LUFA/Drivers/USB.h.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** \ingroup Group_USBClassMS
 | 
			
		||||
 *  \defgroup Group_USBClassMSDevice Mass Storage Class Device Mode Driver
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_Dependencies Module Source Dependencies
 | 
			
		||||
 *  The following files must be built with any user project that uses this module:
 | 
			
		||||
 *    - LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_ModDescription Module Description
 | 
			
		||||
 *  Device Mode USB Class driver framework interface, for the Mass Storage USB Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _MS_CLASS_DEVICE_H_
 | 
			
		||||
#define _MS_CLASS_DEVICE_H_
 | 
			
		||||
 | 
			
		||||
	/* Includes: */
 | 
			
		||||
		#include "../../USB.h"
 | 
			
		||||
		#include "../Common/MassStorageClassCommon.h"
 | 
			
		||||
 | 
			
		||||
	/* Enable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			extern "C" {
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Preprocessor Checks: */
 | 
			
		||||
		#if !defined(__INCLUDE_FROM_MS_DRIVER)
 | 
			
		||||
			#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Public Interface - May be used in end-application: */
 | 
			
		||||
		/* Type Defines: */
 | 
			
		||||
			/** \brief Mass Storage Class Device Mode Configuration and State Structure.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  Class state structure. An instance of this structure should be made for each Mass Storage interface
 | 
			
		||||
			 *  within the user application, and passed to each of the Mass Storage class driver functions as the
 | 
			
		||||
			 *  \c MSInterfaceInfo parameter. This stores each Mass Storage interface's configuration and state information.
 | 
			
		||||
			 */
 | 
			
		||||
			typedef struct
 | 
			
		||||
			{
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					uint8_t  InterfaceNumber; /**< Interface number of the Mass Storage interface within the device. */
 | 
			
		||||
 | 
			
		||||
					USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
 | 
			
		||||
					USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
 | 
			
		||||
 | 
			
		||||
					uint8_t  TotalLUNs; /**< Total number of logical drives in the Mass Storage interface. */
 | 
			
		||||
				} Config; /**< Config data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				           *   <b>must</b> be set or the interface will fail to enumerate and operate correctly.
 | 
			
		||||
				           */
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					MS_CommandBlockWrapper_t  CommandBlock; /**< Mass Storage class command block structure, stores the received SCSI
 | 
			
		||||
															 *   command from the host which is to be processed.
 | 
			
		||||
															 */
 | 
			
		||||
					MS_CommandStatusWrapper_t CommandStatus; /**< Mass Storage class command status structure, set elements to indicate
 | 
			
		||||
															  *   the issued command's success or failure to the host.
 | 
			
		||||
															  */
 | 
			
		||||
					volatile bool IsMassStoreReset; /**< Flag indicating that the host has requested that the Mass Storage interface be reset
 | 
			
		||||
											         *   and that all current Mass Storage operations should immediately abort.
 | 
			
		||||
											         */
 | 
			
		||||
				} State; /**< State data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				          *   are reset to their defaults when the interface is enumerated.
 | 
			
		||||
				          */
 | 
			
		||||
			} USB_ClassInfo_MS_Device_t;
 | 
			
		||||
 | 
			
		||||
		/* Function Prototypes: */
 | 
			
		||||
			/** Configures the endpoints of a given Mass Storage interface, ready for use. This should be linked to the library
 | 
			
		||||
			 *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
 | 
			
		||||
			 *  containing the given Mass Storage interface is selected.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] MSInterfaceInfo  Pointer to a structure containing a Mass Storage Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Processes incoming control requests from the host, that are directed to the given Mass Storage class interface. This should be
 | 
			
		||||
			 *  linked to the library \ref EVENT_USB_Device_ControlRequest() event.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] MSInterfaceInfo  Pointer to a structure containing a Mass Storage Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** General management task for a given Mass Storage class interface, required for the correct operation of the interface. This should
 | 
			
		||||
			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] MSInterfaceInfo  Pointer to a structure containing a Mass Storage configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Mass Storage class driver callback for the user processing of a received SCSI command. This callback will fire each time the
 | 
			
		||||
			 *  host sends a SCSI command which requires processing by the user application. Inside this callback the user is responsible
 | 
			
		||||
			 *  for the processing of the received SCSI command from the host. The SCSI command is available in the CommandBlock structure
 | 
			
		||||
			 *  inside the Mass Storage class state structure passed as a parameter to the callback function.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] MSInterfaceInfo  Pointer to a structure containing a Mass Storage Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the SCSI command was successfully processed, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
	/* Private Interface - For use in library only: */
 | 
			
		||||
	#if !defined(__DOXYGEN__)
 | 
			
		||||
		/* Function Prototypes: */
 | 
			
		||||
			#if defined(__INCLUDE_FROM_MASSSTORAGE_DEVICE_C)
 | 
			
		||||
				static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
				static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
			#endif
 | 
			
		||||
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	/* Disable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			}
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,502 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_USB_DRIVER
 | 
			
		||||
#include "../../Core/USBMode.h"
 | 
			
		||||
 | 
			
		||||
#if defined(USB_CAN_BE_DEVICE)
 | 
			
		||||
 | 
			
		||||
#define  __INCLUDE_FROM_RNDIS_DRIVER
 | 
			
		||||
#define  __INCLUDE_FROM_RNDIS_DEVICE_C
 | 
			
		||||
#include "RNDISClassDevice.h"
 | 
			
		||||
 | 
			
		||||
static const uint32_t PROGMEM AdapterSupportedOIDList[]  =
 | 
			
		||||
	{
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_SUPPORTED_LIST),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_PHYSICAL_MEDIUM),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_HARDWARE_STATUS),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_MEDIA_SUPPORTED),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_MEDIA_IN_USE),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_MAXIMUM_FRAME_SIZE),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_LINK_SPEED),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_TRANSMIT_BLOCK_SIZE),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_RECEIVE_BLOCK_SIZE),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_VENDOR_ID),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_VENDOR_DESCRIPTION),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_CURRENT_PACKET_FILTER),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_MEDIA_CONNECT_STATUS),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_XMIT_OK),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_RCV_OK),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_XMIT_ERROR),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_RCV_ERROR),
 | 
			
		||||
		CPU_TO_LE32(OID_GEN_RCV_NO_BUFFER),
 | 
			
		||||
		CPU_TO_LE32(OID_802_3_PERMANENT_ADDRESS),
 | 
			
		||||
		CPU_TO_LE32(OID_802_3_CURRENT_ADDRESS),
 | 
			
		||||
		CPU_TO_LE32(OID_802_3_MULTICAST_LIST),
 | 
			
		||||
		CPU_TO_LE32(OID_802_3_MAXIMUM_LIST_SIZE),
 | 
			
		||||
		CPU_TO_LE32(OID_802_3_RCV_ERROR_ALIGNMENT),
 | 
			
		||||
		CPU_TO_LE32(OID_802_3_XMIT_ONE_COLLISION),
 | 
			
		||||
		CPU_TO_LE32(OID_802_3_XMIT_MORE_COLLISIONS),
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if (!(Endpoint_IsSETUPReceived()))
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->Config.ControlInterfaceNumber)
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	switch (USB_ControlRequest.bRequest)
 | 
			
		||||
	{
 | 
			
		||||
		case RNDIS_REQ_SendEncapsulatedCommand:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength);
 | 
			
		||||
				Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
				RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case RNDIS_REQ_GetEncapsulatedResponse:
 | 
			
		||||
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
 | 
			
		||||
			{
 | 
			
		||||
				RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
 | 
			
		||||
				if (!(MessageHeader->MessageLength))
 | 
			
		||||
				{
 | 
			
		||||
					RNDISInterfaceInfo->State.RNDISMessageBuffer[0] = 0;
 | 
			
		||||
					MessageHeader->MessageLength                    = CPU_TO_LE32(1);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Endpoint_ClearSETUP();
 | 
			
		||||
				Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, le32_to_cpu(MessageHeader->MessageLength));
 | 
			
		||||
				Endpoint_ClearOUT();
 | 
			
		||||
 | 
			
		||||
				MessageHeader->MessageLength = CPU_TO_LE32(0);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State));
 | 
			
		||||
 | 
			
		||||
	RNDISInterfaceInfo->Config.DataINEndpoint.Type       = EP_TYPE_BULK;
 | 
			
		||||
	RNDISInterfaceInfo->Config.DataOUTEndpoint.Type      = EP_TYPE_BULK;
 | 
			
		||||
	RNDISInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataINEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataOUTEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.NotificationEndpoint, 1)))
 | 
			
		||||
	  return false;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if (USB_DeviceState != DEVICE_STATE_Configured)
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady)
 | 
			
		||||
	{
 | 
			
		||||
		USB_Request_Header_t Notification = (USB_Request_Header_t)
 | 
			
		||||
			{
 | 
			
		||||
				.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
 | 
			
		||||
				.bRequest      = RNDIS_NOTIF_ResponseAvailable,
 | 
			
		||||
				.wValue        = CPU_TO_LE16(0),
 | 
			
		||||
				.wIndex        = CPU_TO_LE16(0),
 | 
			
		||||
				.wLength       = CPU_TO_LE16(0),
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
		Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL);
 | 
			
		||||
 | 
			
		||||
		Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
		RNDISInterfaceInfo->State.ResponseReady = false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
 | 
			
		||||
	         this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
 | 
			
		||||
 | 
			
		||||
	RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
 | 
			
		||||
	switch (le32_to_cpu(MessageHeader->MessageType))
 | 
			
		||||
	{
 | 
			
		||||
		case REMOTE_NDIS_INITIALIZE_MSG:
 | 
			
		||||
			RNDISInterfaceInfo->State.ResponseReady     = true;
 | 
			
		||||
 | 
			
		||||
			RNDIS_Initialize_Message_t*  INITIALIZE_Message  =
 | 
			
		||||
			               (RNDIS_Initialize_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
			RNDIS_Initialize_Complete_t* INITIALIZE_Response =
 | 
			
		||||
			               (RNDIS_Initialize_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
 | 
			
		||||
			INITIALIZE_Response->MessageType            = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT);
 | 
			
		||||
			INITIALIZE_Response->MessageLength          = CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t));
 | 
			
		||||
			INITIALIZE_Response->RequestId              = INITIALIZE_Message->RequestId;
 | 
			
		||||
			INITIALIZE_Response->Status                 = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
 | 
			
		||||
 | 
			
		||||
			INITIALIZE_Response->MajorVersion           = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR);
 | 
			
		||||
			INITIALIZE_Response->MinorVersion           = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR);
 | 
			
		||||
			INITIALIZE_Response->DeviceFlags            = CPU_TO_LE32(REMOTE_NDIS_DF_CONNECTIONLESS);
 | 
			
		||||
			INITIALIZE_Response->Medium                 = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3);
 | 
			
		||||
			INITIALIZE_Response->MaxPacketsPerTransfer  = CPU_TO_LE32(1);
 | 
			
		||||
			INITIALIZE_Response->MaxTransferSize        = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX);
 | 
			
		||||
			INITIALIZE_Response->PacketAlignmentFactor  = CPU_TO_LE32(0);
 | 
			
		||||
			INITIALIZE_Response->AFListOffset           = CPU_TO_LE32(0);
 | 
			
		||||
			INITIALIZE_Response->AFListSize             = CPU_TO_LE32(0);
 | 
			
		||||
 | 
			
		||||
			RNDISInterfaceInfo->State.CurrRNDISState    = RNDIS_Initialized;
 | 
			
		||||
			break;
 | 
			
		||||
		case REMOTE_NDIS_HALT_MSG:
 | 
			
		||||
			RNDISInterfaceInfo->State.ResponseReady     = false;
 | 
			
		||||
 | 
			
		||||
			MessageHeader->MessageLength                = CPU_TO_LE32(0);
 | 
			
		||||
 | 
			
		||||
			RNDISInterfaceInfo->State.CurrRNDISState    = RNDIS_Uninitialized;
 | 
			
		||||
			break;
 | 
			
		||||
		case REMOTE_NDIS_QUERY_MSG:
 | 
			
		||||
			RNDISInterfaceInfo->State.ResponseReady     = true;
 | 
			
		||||
 | 
			
		||||
			RNDIS_Query_Message_t*  QUERY_Message       = (RNDIS_Query_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
			RNDIS_Query_Complete_t* QUERY_Response      = (RNDIS_Query_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
			uint32_t                Query_Oid           = CPU_TO_LE32(QUERY_Message->Oid);
 | 
			
		||||
 | 
			
		||||
			void*    QueryData    = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
 | 
			
		||||
			                                                                      le32_to_cpu(QUERY_Message->InformationBufferOffset)];
 | 
			
		||||
			void*    ResponseData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Query_Complete_t)];
 | 
			
		||||
			uint16_t ResponseSize;
 | 
			
		||||
 | 
			
		||||
			QUERY_Response->MessageType                 = CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT);
 | 
			
		||||
 | 
			
		||||
			if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, le32_to_cpu(QUERY_Message->InformationBufferLength),
 | 
			
		||||
			                                  ResponseData, &ResponseSize))
 | 
			
		||||
			{
 | 
			
		||||
				QUERY_Response->Status                  = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
 | 
			
		||||
				QUERY_Response->MessageLength           = cpu_to_le32(sizeof(RNDIS_Query_Complete_t) + ResponseSize);
 | 
			
		||||
 | 
			
		||||
				QUERY_Response->InformationBufferLength = CPU_TO_LE32(ResponseSize);
 | 
			
		||||
				QUERY_Response->InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t));
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				QUERY_Response->Status                  = CPU_TO_LE32(REMOTE_NDIS_STATUS_NOT_SUPPORTED);
 | 
			
		||||
				QUERY_Response->MessageLength           = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t));
 | 
			
		||||
 | 
			
		||||
				QUERY_Response->InformationBufferLength = CPU_TO_LE32(0);
 | 
			
		||||
				QUERY_Response->InformationBufferOffset = CPU_TO_LE32(0);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case REMOTE_NDIS_SET_MSG:
 | 
			
		||||
			RNDISInterfaceInfo->State.ResponseReady     = true;
 | 
			
		||||
 | 
			
		||||
			RNDIS_Set_Message_t*  SET_Message           = (RNDIS_Set_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
			RNDIS_Set_Complete_t* SET_Response          = (RNDIS_Set_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
			uint32_t              SET_Oid               = le32_to_cpu(SET_Message->Oid);
 | 
			
		||||
 | 
			
		||||
			SET_Response->MessageType                   = CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT);
 | 
			
		||||
			SET_Response->MessageLength                 = CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t));
 | 
			
		||||
			SET_Response->RequestId                     = SET_Message->RequestId;
 | 
			
		||||
 | 
			
		||||
			void* SetData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
 | 
			
		||||
			                                                              le32_to_cpu(SET_Message->InformationBufferOffset)];
 | 
			
		||||
 | 
			
		||||
			SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData,
 | 
			
		||||
			                                                   le32_to_cpu(SET_Message->InformationBufferLength)) ?
 | 
			
		||||
			                                                   REMOTE_NDIS_STATUS_SUCCESS : REMOTE_NDIS_STATUS_NOT_SUPPORTED;
 | 
			
		||||
			break;
 | 
			
		||||
		case REMOTE_NDIS_RESET_MSG:
 | 
			
		||||
			RNDISInterfaceInfo->State.ResponseReady     = true;
 | 
			
		||||
 | 
			
		||||
			RNDIS_Reset_Complete_t* RESET_Response      = (RNDIS_Reset_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
 | 
			
		||||
			RESET_Response->MessageType                 = CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT);
 | 
			
		||||
			RESET_Response->MessageLength               = CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t));
 | 
			
		||||
			RESET_Response->Status                      = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
 | 
			
		||||
			RESET_Response->AddressingReset             = CPU_TO_LE32(0);
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		case REMOTE_NDIS_KEEPALIVE_MSG:
 | 
			
		||||
			RNDISInterfaceInfo->State.ResponseReady     = true;
 | 
			
		||||
 | 
			
		||||
			RNDIS_KeepAlive_Message_t*  KEEPALIVE_Message  =
 | 
			
		||||
			                (RNDIS_KeepAlive_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
			RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response =
 | 
			
		||||
			                (RNDIS_KeepAlive_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
 | 
			
		||||
 | 
			
		||||
			KEEPALIVE_Response->MessageType             = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT);
 | 
			
		||||
			KEEPALIVE_Response->MessageLength           = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t));
 | 
			
		||||
			KEEPALIVE_Response->RequestId               = KEEPALIVE_Message->RequestId;
 | 
			
		||||
			KEEPALIVE_Response->Status                  = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS);
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
 | 
			
		||||
                                          const uint32_t OId,
 | 
			
		||||
                                          void* const QueryData,
 | 
			
		||||
                                          const uint16_t QuerySize,
 | 
			
		||||
                                          void* ResponseData,
 | 
			
		||||
                                          uint16_t* const ResponseSize)
 | 
			
		||||
{
 | 
			
		||||
	(void)QueryData;
 | 
			
		||||
	(void)QuerySize;
 | 
			
		||||
 | 
			
		||||
	switch (OId)
 | 
			
		||||
	{
 | 
			
		||||
		case OID_GEN_SUPPORTED_LIST:
 | 
			
		||||
			*ResponseSize = sizeof(AdapterSupportedOIDList);
 | 
			
		||||
 | 
			
		||||
			memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_PHYSICAL_MEDIUM:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			/* Indicate that the device is a true ethernet link */
 | 
			
		||||
			*((uint32_t*)ResponseData) = CPU_TO_LE32(0);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_HARDWARE_STATUS:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			*((uint32_t*)ResponseData) = CPU_TO_LE32(NDIS_HardwareStatus_Ready);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_MEDIA_SUPPORTED:
 | 
			
		||||
		case OID_GEN_MEDIA_IN_USE:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			*((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_VENDOR_ID:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			/* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
 | 
			
		||||
			*((uint32_t*)ResponseData) = CPU_TO_LE32(0x00FFFFFF);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_MAXIMUM_FRAME_SIZE:
 | 
			
		||||
		case OID_GEN_TRANSMIT_BLOCK_SIZE:
 | 
			
		||||
		case OID_GEN_RECEIVE_BLOCK_SIZE:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			*((uint32_t*)ResponseData) = CPU_TO_LE32(ETHERNET_FRAME_SIZE_MAX);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_VENDOR_DESCRIPTION:
 | 
			
		||||
			*ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1);
 | 
			
		||||
 | 
			
		||||
			memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_MEDIA_CONNECT_STATUS:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			*((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIA_STATE_CONNECTED);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_LINK_SPEED:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			/* Indicate 10Mb/s link speed */
 | 
			
		||||
			*((uint32_t*)ResponseData) = CPU_TO_LE32(100000);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_802_3_PERMANENT_ADDRESS:
 | 
			
		||||
		case OID_802_3_CURRENT_ADDRESS:
 | 
			
		||||
			*ResponseSize = sizeof(MAC_Address_t);
 | 
			
		||||
 | 
			
		||||
			memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t));
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_802_3_MAXIMUM_LIST_SIZE:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			/* Indicate only one multicast address supported */
 | 
			
		||||
			*((uint32_t*)ResponseData) = CPU_TO_LE32(1);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_CURRENT_PACKET_FILTER:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			*((uint32_t*)ResponseData) = cpu_to_le32(RNDISInterfaceInfo->State.CurrPacketFilter);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_XMIT_OK:
 | 
			
		||||
		case OID_GEN_RCV_OK:
 | 
			
		||||
		case OID_GEN_XMIT_ERROR:
 | 
			
		||||
		case OID_GEN_RCV_ERROR:
 | 
			
		||||
		case OID_GEN_RCV_NO_BUFFER:
 | 
			
		||||
		case OID_802_3_RCV_ERROR_ALIGNMENT:
 | 
			
		||||
		case OID_802_3_XMIT_ONE_COLLISION:
 | 
			
		||||
		case OID_802_3_XMIT_MORE_COLLISIONS:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			/* Unused statistic OIDs - always return 0 for each */
 | 
			
		||||
			*((uint32_t*)ResponseData) = CPU_TO_LE32(0);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_GEN_MAXIMUM_TOTAL_SIZE:
 | 
			
		||||
			*ResponseSize = sizeof(uint32_t);
 | 
			
		||||
 | 
			
		||||
			/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
 | 
			
		||||
			*((uint32_t*)ResponseData) = CPU_TO_LE32(RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		default:
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
 | 
			
		||||
                                        const uint32_t OId,
 | 
			
		||||
                                        const void* SetData,
 | 
			
		||||
                                        const uint16_t SetSize)
 | 
			
		||||
{
 | 
			
		||||
	(void)SetSize;
 | 
			
		||||
 | 
			
		||||
	switch (OId)
 | 
			
		||||
	{
 | 
			
		||||
		case OID_GEN_CURRENT_PACKET_FILTER:
 | 
			
		||||
			RNDISInterfaceInfo->State.CurrPacketFilter = le32_to_cpu(*((uint32_t*)SetData));
 | 
			
		||||
			RNDISInterfaceInfo->State.CurrRNDISState   = (RNDISInterfaceInfo->State.CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Initialized;
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		case OID_802_3_MULTICAST_LIST:
 | 
			
		||||
			/* Do nothing - throw away the value from the host as it is unused */
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		default:
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
 | 
			
		||||
{
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) ||
 | 
			
		||||
	    (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
 | 
			
		||||
	{
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
	return Endpoint_IsOUTReceived();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
 | 
			
		||||
                                void* Buffer,
 | 
			
		||||
                                uint16_t* const PacketLength)
 | 
			
		||||
{
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) ||
 | 
			
		||||
	    (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
 | 
			
		||||
	{
 | 
			
		||||
		return ENDPOINT_RWSTREAM_DeviceDisconnected;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	*PacketLength = 0;
 | 
			
		||||
 | 
			
		||||
	if (!(Endpoint_IsOUTReceived()))
 | 
			
		||||
		return ENDPOINT_RWSTREAM_NoError;
 | 
			
		||||
 | 
			
		||||
	RNDIS_Packet_Message_t RNDISPacketHeader;
 | 
			
		||||
	Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL);
 | 
			
		||||
 | 
			
		||||
	if (le32_to_cpu(RNDISPacketHeader.DataLength) > ETHERNET_FRAME_SIZE_MAX)
 | 
			
		||||
	{
 | 
			
		||||
		Endpoint_StallTransaction();
 | 
			
		||||
 | 
			
		||||
		return RNDIS_ERROR_LOGICAL_CMD_FAILED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*PacketLength = (uint16_t)le32_to_cpu(RNDISPacketHeader.DataLength);
 | 
			
		||||
 | 
			
		||||
	Endpoint_Read_Stream_LE(Buffer, *PacketLength, NULL);
 | 
			
		||||
	Endpoint_ClearOUT();
 | 
			
		||||
 | 
			
		||||
	return ENDPOINT_RWSTREAM_NoError;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
 | 
			
		||||
                                void* Buffer,
 | 
			
		||||
                                const uint16_t PacketLength)
 | 
			
		||||
{
 | 
			
		||||
	uint8_t ErrorCode;
 | 
			
		||||
 | 
			
		||||
	if ((USB_DeviceState != DEVICE_STATE_Configured) ||
 | 
			
		||||
	    (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized))
 | 
			
		||||
	{
 | 
			
		||||
		return ENDPOINT_RWSTREAM_DeviceDisconnected;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpoint.Address);
 | 
			
		||||
 | 
			
		||||
	if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
 | 
			
		||||
	  return ErrorCode;
 | 
			
		||||
 | 
			
		||||
	RNDIS_Packet_Message_t RNDISPacketHeader;
 | 
			
		||||
 | 
			
		||||
	memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t));
 | 
			
		||||
 | 
			
		||||
	RNDISPacketHeader.MessageType   = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG);
 | 
			
		||||
	RNDISPacketHeader.MessageLength = cpu_to_le32(sizeof(RNDIS_Packet_Message_t) + PacketLength);
 | 
			
		||||
	RNDISPacketHeader.DataOffset    = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t));
 | 
			
		||||
	RNDISPacketHeader.DataLength    = cpu_to_le32(PacketLength);
 | 
			
		||||
 | 
			
		||||
	Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL);
 | 
			
		||||
	Endpoint_Write_Stream_LE(Buffer, PacketLength, NULL);
 | 
			
		||||
	Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
	return ENDPOINT_RWSTREAM_NoError;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,203 @@
 | 
			
		|||
/*
 | 
			
		||||
             LUFA Library
 | 
			
		||||
     Copyright (C) Dean Camera, 2012.
 | 
			
		||||
 | 
			
		||||
  dean [at] fourwalledcubicle [dot] com
 | 
			
		||||
           www.lufa-lib.org
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Copyright 2012  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
 | 
			
		||||
 *  \brief Device mode driver for the library USB RNDIS Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  Device mode driver for the library USB RNDIS Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  \note This file should not be included directly. It is automatically included as needed by the USB module driver
 | 
			
		||||
 *        dispatch header located in LUFA/Drivers/USB.h.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** \ingroup Group_USBClassRNDIS
 | 
			
		||||
 *  \defgroup Group_USBClassRNDISDevice RNDIS Class Device Mode Driver
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_Dependencies Module Source Dependencies
 | 
			
		||||
 *  The following files must be built with any user project that uses this module:
 | 
			
		||||
 *    - LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c <i>(Makefile source module name: LUFA_SRC_USBCLASS)</i>
 | 
			
		||||
 *
 | 
			
		||||
 *  \section Sec_ModDescription Module Description
 | 
			
		||||
 *  Device Mode USB Class driver framework interface, for the RNDIS USB Class driver.
 | 
			
		||||
 *
 | 
			
		||||
 *  @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _RNDIS_CLASS_DEVICE_H_
 | 
			
		||||
#define _RNDIS_CLASS_DEVICE_H_
 | 
			
		||||
 | 
			
		||||
	/* Includes: */
 | 
			
		||||
		#include "../../USB.h"
 | 
			
		||||
		#include "../Common/RNDISClassCommon.h"
 | 
			
		||||
 | 
			
		||||
	/* Enable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			extern "C" {
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Preprocessor Checks: */
 | 
			
		||||
		#if !defined(__INCLUDE_FROM_RNDIS_DRIVER)
 | 
			
		||||
			#error Do not include this file directly. Include LUFA/Drivers/USB.h instead.
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	/* Public Interface - May be used in end-application: */
 | 
			
		||||
		/* Type Defines: */
 | 
			
		||||
			/** \brief RNDIS Class Device Mode Configuration and State Structure.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  Class state structure. An instance of this structure should be made for each RNDIS interface
 | 
			
		||||
			 *  within the user application, and passed to each of the RNDIS class driver functions as the
 | 
			
		||||
			 *  \c RNDISInterfaceInfo parameter. This stores each RNDIS interface's configuration and state information.
 | 
			
		||||
			 */
 | 
			
		||||
			typedef struct
 | 
			
		||||
			{
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					uint8_t  ControlInterfaceNumber; /**< Interface number of the RNDIS control interface within the device. */
 | 
			
		||||
 | 
			
		||||
					USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */
 | 
			
		||||
					USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */
 | 
			
		||||
					USB_Endpoint_Table_t NotificationEndpoint; /**< Notification IN Endpoint configuration table. */
 | 
			
		||||
 | 
			
		||||
					char*         AdapterVendorDescription; /**< String description of the adapter vendor. */
 | 
			
		||||
					MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter. */
 | 
			
		||||
				} Config; /**< Config data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				           *   <b>must</b> be set or the interface will fail to enumerate and operate correctly.
 | 
			
		||||
				           */
 | 
			
		||||
				struct
 | 
			
		||||
				{
 | 
			
		||||
					uint8_t  RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE]; /**< Buffer to hold RNDIS messages to and from the host,
 | 
			
		||||
																			 *   managed by the class driver.
 | 
			
		||||
																			 */
 | 
			
		||||
					bool     ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host. */
 | 
			
		||||
					uint8_t  CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the \ref RNDIS_States_t enum. */
 | 
			
		||||
					uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver. */
 | 
			
		||||
				} State; /**< State data for the USB class interface within the device. All elements in this section
 | 
			
		||||
				          *   are reset to their defaults when the interface is enumerated.
 | 
			
		||||
				          */
 | 
			
		||||
			} USB_ClassInfo_RNDIS_Device_t;
 | 
			
		||||
 | 
			
		||||
		/* Function Prototypes: */
 | 
			
		||||
			/** Configures the endpoints of a given RNDIS interface, ready for use. This should be linked to the library
 | 
			
		||||
			 *  \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration
 | 
			
		||||
			 *  containing the given RNDIS interface is selected.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] RNDISInterfaceInfo  Pointer to a structure containing a RNDIS Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if the endpoints were successfully configured, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Processes incoming control requests from the host, that are directed to the given RNDIS class interface. This should be
 | 
			
		||||
			 *  linked to the library \ref EVENT_USB_Device_ControlRequest() event.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] RNDISInterfaceInfo  Pointer to a structure containing a RNDIS Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** General management task for a given RNDIS class interface, required for the correct operation of the interface. This should
 | 
			
		||||
			 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] RNDISInterfaceInfo  Pointer to a structure containing a RNDIS Class configuration and state.
 | 
			
		||||
			 */
 | 
			
		||||
			void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
 | 
			
		||||
			/** Determines if a packet is currently waiting for the device to read in and process.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the
 | 
			
		||||
			 *       call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] RNDISInterfaceInfo  Pointer to a structure containing an RNDIS Class configuration and state.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return Boolean \c true if a packet is waiting to be read in by the host, \c false otherwise.
 | 
			
		||||
			 */
 | 
			
		||||
			bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo);
 | 
			
		||||
 | 
			
		||||
			/** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave
 | 
			
		||||
			 *  only the packet contents for processing by the device in the nominated buffer.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the
 | 
			
		||||
			 *       call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] RNDISInterfaceInfo  Pointer to a structure containing an RNDIS Class configuration and state.
 | 
			
		||||
			 *  \param[out]    Buffer              Pointer to a buffer where the packer data is to be written to.
 | 
			
		||||
			 *  \param[out]    PacketLength        Pointer to where the length in bytes of the read packet is to be stored.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
 | 
			
		||||
			 */
 | 
			
		||||
			uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
 | 
			
		||||
											void* Buffer,
 | 
			
		||||
											uint16_t* const PacketLength);
 | 
			
		||||
 | 
			
		||||
			/** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the
 | 
			
		||||
			 *       call will fail.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \param[in,out] RNDISInterfaceInfo  Pointer to a structure containing an RNDIS Class configuration and state.
 | 
			
		||||
			 *  \param[in]     Buffer              Pointer to a buffer where the packer data is to be read from.
 | 
			
		||||
			 *  \param[in]     PacketLength        Length in bytes of the packet to send.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
 | 
			
		||||
			 */
 | 
			
		||||
			uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
 | 
			
		||||
											void* Buffer,
 | 
			
		||||
											const uint16_t PacketLength);
 | 
			
		||||
 | 
			
		||||
	/* Private Interface - For use in library only: */
 | 
			
		||||
	#if !defined(__DOXYGEN__)
 | 
			
		||||
		/* Function Prototypes: */
 | 
			
		||||
		#if defined(__INCLUDE_FROM_RNDIS_DEVICE_C)
 | 
			
		||||
			static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
 | 
			
		||||
			                                                    ATTR_NON_NULL_PTR_ARG(1);
 | 
			
		||||
			static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
 | 
			
		||||
			                                          const uint32_t OId,
 | 
			
		||||
                                                      void* const QueryData,
 | 
			
		||||
                                                      const uint16_t QuerySize,
 | 
			
		||||
										              void* ResponseData,
 | 
			
		||||
                                                      uint16_t* const ResponseSize) ATTR_NON_NULL_PTR_ARG(1)
 | 
			
		||||
			                                          ATTR_NON_NULL_PTR_ARG(5) ATTR_NON_NULL_PTR_ARG(6);
 | 
			
		||||
			static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo,
 | 
			
		||||
                                                    const uint32_t OId,
 | 
			
		||||
			                                        const void* SetData,
 | 
			
		||||
                                                    const uint16_t SetSize) ATTR_NON_NULL_PTR_ARG(1)
 | 
			
		||||
			                                        ATTR_NON_NULL_PTR_ARG(3);
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	/* Disable C linkage for C++ Compilers: */
 | 
			
		||||
		#if defined(__cplusplus)
 | 
			
		||||
			}
 | 
			
		||||
		#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue