AudioClassDevice.c 5.96 KB
Newer Older
1 2
/*
             LUFA Library
3
     Copyright (C) Dean Camera, 2011.
4

5
  dean [at] fourwalledcubicle [dot] com
6
           www.lufa-lib.org
7 8 9
*/

/*
10
  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11

12
  Permission to use, copy, modify, distribute, and sell this
13
  software and its documentation for any purpose is hereby granted
14
  without fee, provided that the above copyright notice appear in
15
  all copies and that both that the copyright notice and this
16 17 18
  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
19 20 21 22 23 24 25 26 27 28 29 30 31
  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
32 33
#include "../../Core/USBMode.h"

34 35 36
#if defined(USB_CAN_BE_DEVICE)

#define  __INCLUDE_FROM_AUDIO_DRIVER
37
#define  __INCLUDE_FROM_AUDIO_DEVICE_C
38
#include "AudioClassDevice.h"
39 40 41 42 43

void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
{
	if (!(Endpoint_IsSETUPReceived()))
	  return;
44

45 46 47 48 49 50 51
	if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
	{
		if (USB_ControlRequest.wIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber)
		  return;
	}
	else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
	{
52 53 54
		bool EndpointFilterMatch = false;
	
		EndpointFilterMatch |= (AudioInterfaceInfo->Config.DataINEndpointNumber &&
55
		                        ((uint8_t)USB_ControlRequest.wIndex == (ENDPOINT_DIR_IN  | AudioInterfaceInfo->Config.DataINEndpointNumber)));
56 57
	
		EndpointFilterMatch |= (AudioInterfaceInfo->Config.DataOUTEndpointNumber &&
58
		                        ((uint8_t)USB_ControlRequest.wIndex == (ENDPOINT_DIR_OUT | AudioInterfaceInfo->Config.DataOUTEndpointNumber)));
59 60 61

		if (!(EndpointFilterMatch))
		  return;
62 63
	}	

64 65 66 67 68 69 70
	switch (USB_ControlRequest.bRequest)
	{
		case REQ_SetInterface:
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
			{
				Endpoint_ClearSETUP();
				Endpoint_ClearStatusStage();
71 72

				AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0);
73
				EVENT_Audio_Device_StreamStartStop(AudioInterfaceInfo);
74 75 76
			}

			break;
77 78 79 80 81 82 83
		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();
			}
84 85 86 87 88 89 90 91 92

			break;
		case AUDIO_REQ_SetCurrent:
		case AUDIO_REQ_SetMinimum:
		case AUDIO_REQ_SetMaximum:
		case AUDIO_REQ_SetResolution:
			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT))
			{
				uint8_t EndpointProperty = USB_ControlRequest.bRequest;
93
				uint8_t EndpointAddress  = (uint8_t)USB_ControlRequest.wIndex;
94 95
				uint8_t EndpointControl  = (USB_ControlRequest.wValue >> 8);
			
96 97
				if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
				                                                 EndpointControl, NULL, NULL))
98 99 100 101 102 103 104 105
				{
					uint16_t ValueLength = USB_ControlRequest.wLength;
					uint8_t  Value[ValueLength];
					
					Endpoint_ClearSETUP();
					Endpoint_Read_Control_Stream_LE(Value, ValueLength);
					Endpoint_ClearIN();					

106 107
					CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
					                                             EndpointControl, &ValueLength, Value);
108 109 110 111 112 113 114 115 116 117 118
				}				
			}

			break;
		case AUDIO_REQ_GetCurrent:
		case AUDIO_REQ_GetMinimum:
		case AUDIO_REQ_GetMaximum:
		case AUDIO_REQ_GetResolution:
			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))
			{
				uint8_t  EndpointProperty = USB_ControlRequest.bRequest;
119
				uint8_t  EndpointAddress  = (uint8_t)USB_ControlRequest.wIndex;
120 121 122 123
				uint8_t  EndpointControl  = (USB_ControlRequest.wValue >> 8);
				uint16_t ValueLength      = USB_ControlRequest.wLength;
				uint8_t  Value[ValueLength];

124 125
				if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress,
				                                                 EndpointControl, &ValueLength, Value))
126 127 128 129 130 131 132 133
				{
					Endpoint_ClearSETUP();
					Endpoint_Write_Control_Stream_LE(Value, ValueLength);
					Endpoint_ClearOUT();					
				}
			}

			break;
134 135 136
	}
}

137
bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo)
138 139 140
{
	memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));

141
	for (uint8_t EndpointNum = 1; EndpointNum < ENDPOINT_TOTAL_ENDPOINTS; EndpointNum++)
142
	{
143 144 145
		uint16_t Size;
		uint8_t  Type;
		uint8_t  Direction;
146
		bool     DoubleBanked;
147 148

		if (EndpointNum == AudioInterfaceInfo->Config.DataINEndpointNumber)
149
		{
150 151 152
			Size         = AudioInterfaceInfo->Config.DataINEndpointSize;
			Direction    = ENDPOINT_DIR_IN;
			Type         = EP_TYPE_ISOCHRONOUS;
153
			DoubleBanked = true;
154
		}
155 156 157 158 159
		else if (EndpointNum == AudioInterfaceInfo->Config.DataOUTEndpointNumber)
		{
			Size         = AudioInterfaceInfo->Config.DataOUTEndpointSize;
			Direction    = ENDPOINT_DIR_OUT;
			Type         = EP_TYPE_ISOCHRONOUS;
160
			DoubleBanked = true;
161 162 163 164 165
		}
		else
		{
			continue;
		}
166

167 168 169 170 171
		if (!(Endpoint_ConfigureEndpoint(EndpointNum, Type, Direction, Size,
		                                 DoubleBanked ? ENDPOINT_BANK_DOUBLE : ENDPOINT_BANK_SINGLE)))
		{
			return false;
		}
172
	}
173

174 175 176
	return true;
}

177 178 179 180 181
void Audio_Device_Event_Stub(void)
{

}

182
#endif