/*
LUFA Library
- Copyright (C) Dean Camera, 2011.
+ Copyright (C) Dean Camera, 2012.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
- Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+ 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
/** Flag to indicate if the streaming audio alternative interface has been selected by the host. */
static bool StreamingAudioInterfaceSelected = false;
+/** Current audio sampling frequency of the streaming audio endpoint. */
+static uint32_t CurrentAudioSampleFrequency = 48000;
+
/** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop.
/* Sample reload timer initialization */
TIMSK0 = (1 << OCIE0A);
- OCR0A = ((F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1);
+ OCR0A = ((F_CPU / 8 / CurrentAudioSampleFrequency) - 1);
TCCR0A = (1 << WGM01); // CTC mode
TCCR0B = (1 << CS01); // Fcpu/8 speed
bool ConfigSuccess = true;
/* Setup Audio Stream Endpoint */
- ConfigSuccess &= Endpoint_ConfigureEndpoint(AUDIO_STREAM_EPNUM, EP_TYPE_ISOCHRONOUS, ENDPOINT_DIR_OUT,
- AUDIO_STREAM_EPSIZE, ENDPOINT_BANK_DOUBLE);
+ ConfigSuccess &= Endpoint_ConfigureEndpoint(AUDIO_STREAM_EPADDR, EP_TYPE_ISOCHRONOUS, AUDIO_STREAM_EPSIZE, 2);
/* Indicate endpoint configuration success or failure */
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
}
+
+ break;
+ case AUDIO_REQ_SetCurrent:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT))
+ {
+ /* Extract out the relevant request information to get the target Endpoint address and control being set */
+ uint8_t EndpointAddress = (uint8_t)USB_ControlRequest.wIndex;
+ uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8);
+
+ /* Only handle SET CURRENT requests to the audio endpoint's sample frequency property */
+ if ((EndpointAddress == AUDIO_STREAM_EPADDR) && (EndpointControl == AUDIO_EPCONTROL_SamplingFreq))
+ {
+ uint8_t SampleRate[3];
+
+ Endpoint_ClearSETUP();
+ Endpoint_Read_Control_Stream_LE(SampleRate, sizeof(SampleRate));
+ Endpoint_ClearOUT();
+
+ /* Set the new sampling frequency to the value given by the host */
+ CurrentAudioSampleFrequency = (((uint32_t)SampleRate[2] << 16) | ((uint32_t)SampleRate[1] << 8) | (uint32_t)SampleRate[0]);
+
+ /* Adjust sample reload timer to the new frequency */
+ OCR0A = ((F_CPU / 8 / CurrentAudioSampleFrequency) - 1);
+ }
+ }
+
+ break;
+ case AUDIO_REQ_GetCurrent:
+ if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT))
+ {
+ /* Extract out the relevant request information to get the target Endpoint address and control being retrieved */
+ uint8_t EndpointAddress = (uint8_t)USB_ControlRequest.wIndex;
+ uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8);
+
+ /* Only handle GET CURRENT requests to the audio endpoint's sample frequency property */
+ if ((EndpointAddress == AUDIO_STREAM_EPADDR) && (EndpointControl == AUDIO_EPCONTROL_SamplingFreq))
+ {
+ uint8_t SampleRate[3];
+
+ /* Convert the sampling rate value into the 24-bit format the host expects for the property */
+ SampleRate[2] = (CurrentAudioSampleFrequency >> 16);
+ SampleRate[1] = (CurrentAudioSampleFrequency >> 8);
+ SampleRate[0] = (CurrentAudioSampleFrequency & 0xFF);
+
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Control_Stream_LE(SampleRate, sizeof(SampleRate));
+ Endpoint_ClearOUT();
+ }
+ }
+
+ break;
}
}
uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint();
/* Select the audio stream endpoint */
- Endpoint_SelectEndpoint(AUDIO_STREAM_EPNUM);
+ Endpoint_SelectEndpoint(AUDIO_STREAM_EPADDR);
/* Check if the current endpoint can be read from (contains a packet) and the host is sending data */
if (Endpoint_IsOUTReceived() && StreamingAudioInterfaceSelected)
LEDs_SetAllLEDs(LEDMask);
}
-
+
Endpoint_SelectEndpoint(PrevEndpoint);
}