aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Demos/Device/ClassDriver/AudioInput/AudioInput.c74
-rw-r--r--Demos/Device/ClassDriver/AudioInput/Descriptors.c17
-rw-r--r--Demos/Device/ClassDriver/AudioInput/Descriptors.h5
-rw-r--r--Demos/Device/ClassDriver/AudioOutput/AudioOutput.c74
-rw-r--r--Demos/Device/ClassDriver/AudioOutput/Descriptors.c16
-rw-r--r--Demos/Device/ClassDriver/AudioOutput/Descriptors.h5
-rw-r--r--Demos/Device/LowLevel/AudioInput/Descriptors.c4
-rw-r--r--Demos/Device/LowLevel/AudioOutput/Descriptors.c4
-rw-r--r--Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c8
-rw-r--r--Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c8
-rw-r--r--Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c8
-rw-r--r--Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c8
-rw-r--r--LUFA/Drivers/USB/Class/Common/Audio.h45
-rw-r--r--LUFA/Drivers/USB/Class/Device/Audio.c63
-rw-r--r--LUFA/Drivers/USB/Class/Device/Audio.h29
-rw-r--r--LUFA/Drivers/USB/Core/StdRequestType.h4
-rw-r--r--LUFA/ManPages/ChangeLog.txt4
-rw-r--r--LUFA/ManPages/FutureChanges.txt3
-rw-r--r--LUFA/ManPages/VIDAndPIDValues.txt4
-rw-r--r--Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c4
20 files changed, 336 insertions, 51 deletions
diff --git a/Demos/Device/ClassDriver/AudioInput/AudioInput.c b/Demos/Device/ClassDriver/AudioInput/AudioInput.c
index b197588a8..58a3668e8 100644
--- a/Demos/Device/ClassDriver/AudioInput/AudioInput.c
+++ b/Demos/Device/ClassDriver/AudioInput/AudioInput.c
@@ -51,6 +51,9 @@ USB_ClassInfo_Audio_Device_t Microphone_Audio_Interface =
},
};
+/** Current audio sampling frequency of the streaming audio endpoint. */
+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.
@@ -133,7 +136,7 @@ void EVENT_USB_Device_Connect(void)
/* 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
}
@@ -163,3 +166,72 @@ void EVENT_USB_Device_ControlRequest(void)
Audio_Device_ProcessControlRequest(&Microphone_Audio_Interface);
}
+/** 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 retreived 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 Audio_ClassRequests_t.
+ * \param[in] EndpointIndex Index of the streaming endpoint whose property is being referenced.
+ * \param[in] EndpointControl Parameter of the endpoint to get or set, a value from 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 true if the property get/set was successful, false otherwise
+ */
+bool CALLBACK_Audio_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
+ const uint8_t EndpointProperty,
+ const uint8_t EndpointIndex,
+ const uint8_t EndpointControl,
+ uint16_t* const DataLength,
+ uint8_t* Data)
+{
+ /* Check the requested endpoint to see if a supported endpoint is being manipulated */
+ if (EndpointIndex == Microphone_Audio_Interface.Config.DataINEndpointNumber)
+ {
+ /* Check the requested control to see if a supported control is being manipulated */
+ if (EndpointControl == AUDIO_EPCONTROL_SamplingFreq)
+ {
+ /* Check the requested property to see if a supported property is being manipulated */
+ if (EndpointProperty == AUDIO_REQ_SetCurrent)
+ {
+ /* Check if we are just testing for a valid property, or actually adjusting it */
+ if (DataLength != NULL)
+ {
+ /* Set the new sampling frequency to the value given by the host */
+ CurrentAudioSampleFrequency = (((uint32_t)Data[2] << 16) | ((uint32_t)Data[1] << 8) | (uint32_t)Data[0]);
+
+ /* Adjust sample reload timer to the new frequency */
+ OCR0A = ((F_CPU / 8 / CurrentAudioSampleFrequency) - 1);
+ }
+
+ return true;
+ }
+ else if (EndpointProperty == AUDIO_REQ_GetCurrent)
+ {
+ /* Check if we are just testing for a valid property, or actually reading it */
+ if (DataLength != NULL)
+ {
+ *DataLength = 3;
+
+ Data[2] = (CurrentAudioSampleFrequency >> 16);
+ Data[1] = (CurrentAudioSampleFrequency >> 8);
+ Data[0] = (CurrentAudioSampleFrequency & 0xFF);
+ }
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/Demos/Device/ClassDriver/AudioInput/Descriptors.c b/Demos/Device/ClassDriver/AudioInput/Descriptors.c
index bd31bdb0e..6fffd05d4 100644
--- a/Demos/Device/ClassDriver/AudioInput/Descriptors.c
+++ b/Demos/Device/ClassDriver/AudioInput/Descriptors.c
@@ -54,7 +54,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB,
- .ProductID = 0x2047,
+ .ProductID = 0x206B,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.Audio_AudioFormat =
{
- .Header = {.Size = sizeof(USB_Audio_Descriptor_Format_t), .Type = DTYPE_CSInterface},
+ .Header = {.Size = sizeof(USB_Audio_Descriptor_Format_t) +
+ sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates),
+ .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_FormatType,
.FormatType = 0x01,
@@ -199,12 +201,17 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.SubFrameSize = 0x02,
.BitResolution = 16,
- .TotalDiscreteSampleRates = 1,
+
+ .TotalDiscreteSampleRates = (sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates) / sizeof(USB_Audio_SampleFreq_t))
},
.Audio_AudioFormatSampleRates =
{
- AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)
+ AUDIO_SAMPLE_FREQ(8000),
+ AUDIO_SAMPLE_FREQ(11025),
+ AUDIO_SAMPLE_FREQ(22050),
+ AUDIO_SAMPLE_FREQ(44100),
+ AUDIO_SAMPLE_FREQ(48000),
},
.Audio_StreamEndpoint =
@@ -228,7 +235,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Spc_t), .Type = DTYPE_CSEndpoint},
.Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
- .Attributes = AUDIO_EP_ACCEPTS_SMALL_PACKETS,
+ .Attributes = (AUDIO_EP_ACCEPTS_SMALL_PACKETS | AUDIO_EP_SAMPLE_FREQ_CONTROL),
.LockDelayUnits = 0x00,
.LockDelay = 0x0000
diff --git a/Demos/Device/ClassDriver/AudioInput/Descriptors.h b/Demos/Device/ClassDriver/AudioInput/Descriptors.h
index 82dbd517f..05d1fee36 100644
--- a/Demos/Device/ClassDriver/AudioInput/Descriptors.h
+++ b/Demos/Device/ClassDriver/AudioInput/Descriptors.h
@@ -51,9 +51,6 @@
*/
#define AUDIO_STREAM_EPSIZE ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
- /** Sample frequency of the data being transmitted through the streaming endpoint. */
- #define AUDIO_SAMPLE_FREQUENCY 48000
-
/* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
@@ -70,7 +67,7 @@
USB_Descriptor_Interface_t Audio_StreamInterface_Alt1;
USB_Audio_Descriptor_Interface_AS_t Audio_StreamInterface_SPC;
USB_Audio_Descriptor_Format_t Audio_AudioFormat;
- USB_Audio_SampleFreq_t Audio_AudioFormatSampleRates[1];
+ USB_Audio_SampleFreq_t Audio_AudioFormatSampleRates[5];
USB_Audio_Descriptor_StreamEndpoint_Std_t Audio_StreamEndpoint;
USB_Audio_Descriptor_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
} USB_Descriptor_Configuration_t;
diff --git a/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c b/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c
index dbfd10b8b..43267b2a7 100644
--- a/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c
+++ b/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c
@@ -51,6 +51,9 @@ USB_ClassInfo_Audio_Device_t Speaker_Audio_Interface =
},
};
+/** Current audio sampling frequency of the streaming audio endpoint. */
+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.
@@ -135,7 +138,7 @@ void EVENT_USB_Device_Connect(void)
/* 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
@@ -199,3 +202,72 @@ void EVENT_USB_Device_ControlRequest(void)
Audio_Device_ProcessControlRequest(&Speaker_Audio_Interface);
}
+/** 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 retreived 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 Audio_ClassRequests_t.
+ * \param[in] EndpointIndex Index of the streaming endpoint whose property is being referenced.
+ * \param[in] EndpointControl Parameter of the endpoint to get or set, a value from 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 true if the property get/set was successful, false otherwise
+ */
+bool CALLBACK_Audio_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
+ const uint8_t EndpointProperty,
+ const uint8_t EndpointIndex,
+ const uint8_t EndpointControl,
+ uint16_t* const DataLength,
+ uint8_t* Data)
+{
+ /* Check the requested endpoint to see if a supported endpoint is being manipulated */
+ if (EndpointIndex == Speaker_Audio_Interface.Config.DataOUTEndpointNumber)
+ {
+ /* Check the requested control to see if a supported control is being manipulated */
+ if (EndpointControl == AUDIO_EPCONTROL_SamplingFreq)
+ {
+ /* Check the requested property to see if a supported property is being manipulated */
+ if (EndpointProperty == AUDIO_REQ_SetCurrent)
+ {
+ /* Check if we are just testing for a valid property, or actually adjusting it */
+ if (DataLength != NULL)
+ {
+ /* Set the new sampling frequency to the value given by the host */
+ CurrentAudioSampleFrequency = (((uint32_t)Data[2] << 16) | ((uint32_t)Data[1] << 8) | (uint32_t)Data[0]);
+
+ /* Adjust sample reload timer to the new frequency */
+ OCR0A = ((F_CPU / 8 / CurrentAudioSampleFrequency) - 1);
+ }
+
+ return true;
+ }
+ else if (EndpointProperty == AUDIO_REQ_GetCurrent)
+ {
+ /* Check if we are just testing for a valid property, or actually reading it */
+ if (DataLength != NULL)
+ {
+ *DataLength = 3;
+
+ Data[2] = (CurrentAudioSampleFrequency >> 16);
+ Data[1] = (CurrentAudioSampleFrequency >> 8);
+ Data[0] = (CurrentAudioSampleFrequency & 0xFF);
+ }
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/Demos/Device/ClassDriver/AudioOutput/Descriptors.c b/Demos/Device/ClassDriver/AudioOutput/Descriptors.c
index e46c3c023..5bb0e9f11 100644
--- a/Demos/Device/ClassDriver/AudioOutput/Descriptors.c
+++ b/Demos/Device/ClassDriver/AudioOutput/Descriptors.c
@@ -54,7 +54,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = 0x03EB,
- .ProductID = 0x2046,
+ .ProductID = 0x206C,
.ReleaseNumber = VERSION_BCD(00.01),
.ManufacturerStrIndex = 0x01,
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.Audio_AudioFormat =
{
- .Header = {.Size = sizeof(USB_Audio_Descriptor_Format_t), .Type = DTYPE_CSInterface},
+ .Header = {.Size = sizeof(USB_Audio_Descriptor_Format_t) +
+ sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates),
+ .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_FormatType,
.FormatType = 0x01,
@@ -200,12 +202,16 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.SubFrameSize = 0x02,
.BitResolution = 16,
- .TotalDiscreteSampleRates = 1,
+ .TotalDiscreteSampleRates = (sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates) / sizeof(USB_Audio_SampleFreq_t)),
},
.Audio_AudioFormatSampleRates =
{
- AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)
+ AUDIO_SAMPLE_FREQ(8000),
+ AUDIO_SAMPLE_FREQ(11025),
+ AUDIO_SAMPLE_FREQ(22050),
+ AUDIO_SAMPLE_FREQ(44100),
+ AUDIO_SAMPLE_FREQ(48000),
},
.Audio_StreamEndpoint =
@@ -229,7 +235,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Spc_t), .Type = DTYPE_CSEndpoint},
.Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
- .Attributes = AUDIO_EP_ACCEPTS_SMALL_PACKETS,
+ .Attributes = (AUDIO_EP_ACCEPTS_SMALL_PACKETS | AUDIO_EP_SAMPLE_FREQ_CONTROL),
.LockDelayUnits = 0x00,
.LockDelay = 0x0000
diff --git a/Demos/Device/ClassDriver/AudioOutput/Descriptors.h b/Demos/Device/ClassDriver/AudioOutput/Descriptors.h
index b4b8db6a4..ca5c87386 100644
--- a/Demos/Device/ClassDriver/AudioOutput/Descriptors.h
+++ b/Demos/Device/ClassDriver/AudioOutput/Descriptors.h
@@ -51,9 +51,6 @@
*/
#define AUDIO_STREAM_EPSIZE ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
- /** Sample frequency of the data being transmitted through the streaming endpoint. */
- #define AUDIO_SAMPLE_FREQUENCY 48000
-
/* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
@@ -70,7 +67,7 @@
USB_Descriptor_Interface_t Audio_StreamInterface_Alt1;
USB_Audio_Descriptor_Interface_AS_t Audio_StreamInterface_SPC;
USB_Audio_Descriptor_Format_t Audio_AudioFormat;
- USB_Audio_SampleFreq_t Audio_AudioFormatSampleRates[1];
+ USB_Audio_SampleFreq_t Audio_AudioFormatSampleRates[5];
USB_Audio_Descriptor_StreamEndpoint_Std_t Audio_StreamEndpoint;
USB_Audio_Descriptor_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
} USB_Descriptor_Configuration_t;
diff --git a/Demos/Device/LowLevel/AudioInput/Descriptors.c b/Demos/Device/LowLevel/AudioInput/Descriptors.c
index 6c8323c56..8a63d7736 100644
--- a/Demos/Device/LowLevel/AudioInput/Descriptors.c
+++ b/Demos/Device/LowLevel/AudioInput/Descriptors.c
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.Audio_AudioFormat =
{
- .Header = {.Size = sizeof(USB_Audio_Descriptor_Format_t), .Type = DTYPE_CSInterface},
+ .Header = {.Size = sizeof(USB_Audio_Descriptor_Format_t) +
+ sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates),
+ .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_FormatType,
.FormatType = 0x01,
diff --git a/Demos/Device/LowLevel/AudioOutput/Descriptors.c b/Demos/Device/LowLevel/AudioOutput/Descriptors.c
index 9c57a421f..59e3af1dd 100644
--- a/Demos/Device/LowLevel/AudioOutput/Descriptors.c
+++ b/Demos/Device/LowLevel/AudioOutput/Descriptors.c
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.Audio_AudioFormat =
{
- .Header = {.Size = sizeof(USB_Audio_Descriptor_Format_t), .Type = DTYPE_CSInterface},
+ .Header = {.Size = sizeof(USB_Audio_Descriptor_Format_t) +
+ sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates),
+ .Type = DTYPE_CSInterface},
.Subtype = AUDIO_DSUBTYPE_CSInterface_FormatType,
.FormatType = 0x01,
diff --git a/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c b/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c
index 9b6125e6c..38af3a7c5 100644
--- a/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c
+++ b/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c
@@ -137,9 +137,13 @@ int main(void)
PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
}
else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
- (KeyCode <= HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
+ (KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
{
- PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '0';
+ PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
+ }
+ else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
+ {
+ PressedKey = '0';
}
else if (KeyCode == HID_KEYBOARD_SC_SPACE)
{
diff --git a/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c b/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c
index abb391cee..d7df58f07 100644
--- a/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c
+++ b/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c
@@ -157,9 +157,13 @@ int main(void)
PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
}
else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
- (KeyCode <= HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
+ (KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
{
- PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '0';
+ PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
+ }
+ else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
+ {
+ PressedKey = '0';
}
else if (KeyCode == HID_KEYBOARD_SC_SPACE)
{
diff --git a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
index 84e6145fb..6df052d72 100644
--- a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
+++ b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
@@ -173,9 +173,13 @@ void ReadNextReport(void)
PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
}
else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
- (KeyCode <= HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
+ (KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
{
- PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '0';
+ PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
+ }
+ else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
+ {
+ PressedKey = '0';
}
else if (KeyCode == HID_KEYBOARD_SC_SPACE)
{
diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
index 512cc1ae2..6ef7a9677 100644
--- a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
+++ b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
@@ -287,9 +287,13 @@ void ProcessKeyboardReport(uint8_t* KeyboardReport)
PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
}
else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
- (KeyCode <= HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
+ (KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
{
- PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '0';
+ PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
+ }
+ else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
+ {
+ PressedKey = '0';
}
else if (KeyCode == HID_KEYBOARD_SC_SPACE)
{
diff --git a/LUFA/Drivers/USB/Class/Common/Audio.h b/LUFA/Drivers/USB/Class/Common/Audio.h
index cc6e8e52d..fd9a3a92b 100644
--- a/LUFA/Drivers/USB/Class/Common/Audio.h
+++ b/LUFA/Drivers/USB/Class/Common/Audio.h
@@ -197,7 +197,7 @@
*
* \param[in] freq Required audio sampling frequency in HZ
*/
- #define AUDIO_SAMPLE_FREQ(freq) {.Byte1 = ((uint32_t)freq & 0x0000FF), .Byte2 = (((uint32_t)freq >> 8) & 0xFF), .Byte3 = (((uint32_t)freq >> 16) & 0xFF)}
+ #define AUDIO_SAMPLE_FREQ(freq) {.Byte1 = ((uint32_t)freq & 0xFF), .Byte2 = (((uint32_t)freq >> 8) & 0xFF), .Byte3 = (((uint32_t)freq >> 16) & 0xFF)}
/** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
* accepts only filled endpoint packets of audio samples.
@@ -208,6 +208,16 @@
* will accept partially filled endpoint packets of audio samples.
*/
#define AUDIO_EP_ACCEPTS_SMALL_PACKETS (0 << 7)
+
+ /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
+ * allows for sampling frequency adjustments to be made via control requests directed at the endpoint.
+ */
+ #define AUDIO_EP_SAMPLE_FREQ_CONTROL (1 << 0)
+
+ /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
+ * allows for pitch adjustments to be made via control requests directed at the endpoint.
+ */
+ #define AUDIO_EP_PITCH_CONTROL (1 << 1)
/* Enums: */
/** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Audio
@@ -277,6 +287,15 @@
AUDIO_REQ_GetMemory = 0x85, /**< Audio class-specific request to get the memory value of a parameter within the device. */
AUDIO_REQ_GetStatus = 0xFF, /**< Audio class-specific request to get the device status. */
};
+
+ /** Enum for Audio class specific Endpoint control modifiers which can be set and retrieved by a USB host, if the corresponding
+ * endpoint control is indicated to be supported in the Endpoint's Audio-class specific endpoint descriptor.
+ */
+ enum Audio_EndpointControls_t
+ {
+ AUDIO_EPCONTROL_SamplingFreq = 0x01, /**< Sampling frequency adjustment of the endpoint. */
+ AUDIO_EPCONTROL_Pitch = 0x02, /**< Pitch adjustment of the endpoint. */
+ };
/* Type Defines: */
/** \brief Audio class-specific Input Terminal Descriptor (LUFA naming conventions).
@@ -538,18 +557,6 @@
uint16_t wFormatTag; /**< Format of the audio stream, see Audio Device Formats specification. */
} ATTR_PACKED USB_Audio_StdDescriptor_Interface_AS_t;
- /** \brief 24-Bit Audio Frequency Structure.
- *
- * Type define for a 24bit audio sample frequency structure. GCC does not contain a built in 24bit datatype,
- * this this structure is used to build up the value instead. Fill this structure with the \ref AUDIO_SAMPLE_FREQ() macro.
- */
- typedef struct
- {
- uint8_t Byte1; /**< Lowest 8 bits of the 24-bit value. */
- uint8_t Byte2; /**< Middle 8 bits of the 24-bit value. */
- uint8_t Byte3; /**< Upper 8 bits of the 24-bit value. */
- } ATTR_PACKED USB_Audio_SampleFreq_t;
-
/** \brief Audio class-specific Format Descriptor (LUFA naming conventions).
*
* Type define for an Audio class-specific audio format descriptor. This is used to give the host full details
@@ -581,6 +588,18 @@
*/
} ATTR_PACKED USB_Audio_Descriptor_Format_t;
+ /** \brief 24-Bit Audio Frequency Structure.
+ *
+ * Type define for a 24bit audio sample frequency structure. As GCC does not contain a built in 24-bit datatype,
+ * this this structure is used to build up the value instead. Fill this structure with the \ref AUDIO_SAMPLE_FREQ() macro.
+ */
+ typedef struct
+ {
+ uint8_t Byte1; /**< Lowest 8 bits of the 24-bit value. */
+ uint8_t Byte2; /**< Middle 8 bits of the 24-bit value. */
+ uint8_t Byte3; /**< Upper 8 bits of the 24-bit value. */
+ } ATTR_PACKED USB_Audio_SampleFreq_t;
+
/** \brief Audio class-specific Format Descriptor (USB-IF naming conventions).
*
* Type define for an Audio class-specific audio format descriptor. This is used to give the host full details
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.c b/LUFA/Drivers/USB/Class/Device/Audio.c
index 8c5c9960d..f183fdedd 100644
--- a/LUFA/Drivers/USB/Class/Device/Audio.c
+++ b/LUFA/Drivers/USB/Class/Device/Audio.c
@@ -45,6 +45,22 @@ void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const Audi
if (USB_ControlRequest.wIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber)
return;
+ 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)
+ {
+ if (!((AudioInterfaceInfo->Config.DataINEndpointNumber &&
+ (USB_ControlRequest.wIndex == AudioInterfaceInfo->Config.DataINEndpointNumber)) ||
+ (AudioInterfaceInfo->Config.DataOUTEndpointNumber &&
+ (USB_ControlRequest.wIndex == AudioInterfaceInfo->Config.DataOUTEndpointNumber))))
+ {
+ return;
+ }
+ }
+
switch (USB_ControlRequest.bRequest)
{
case REQ_SetInterface:
@@ -64,6 +80,53 @@ void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const Audi
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 == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT))
+ {
+ uint8_t EndpointProperty = USB_ControlRequest.bRequest;
+ uint8_t EndpointIndex = (uint8_t)USB_ControlRequest.wIndex;
+ uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8);
+
+ if (CALLBACK_Audio_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointIndex, 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_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointIndex, EndpointControl, &ValueLength, Value);
+ }
+ }
+
+ 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;
+ uint8_t EndpointIndex = (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_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointIndex, EndpointControl, &ValueLength, Value))
+ {
+ Endpoint_ClearSETUP();
+ Endpoint_Write_Control_Stream_LE(Value, ValueLength);
+ Endpoint_ClearOUT();
+ }
+ }
+
+ break;
}
}
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.h b/LUFA/Drivers/USB/Class/Device/Audio.h
index a50bd97cc..a09076341 100644
--- a/LUFA/Drivers/USB/Class/Device/Audio.h
+++ b/LUFA/Drivers/USB/Class/Device/Audio.h
@@ -130,6 +130,35 @@
* \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 retreived 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] EndpointIndex Index 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 true if the property get/set was successful, false otherwise
+ */
+ bool CALLBACK_Audio_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
+ const uint8_t EndpointProperty,
+ const uint8_t EndpointIndex,
+ const uint8_t EndpointControl,
+ uint16_t* const DataLength,
+ uint8_t* Data);
/* Inline Functions: */
/** General management task for a given Audio class interface, required for the correct operation of the interface. This should
diff --git a/LUFA/Drivers/USB/Core/StdRequestType.h b/LUFA/Drivers/USB/Core/StdRequestType.h
index e3e30f95f..83f59afc6 100644
--- a/LUFA/Drivers/USB/Core/StdRequestType.h
+++ b/LUFA/Drivers/USB/Core/StdRequestType.h
@@ -74,8 +74,8 @@
*/
#define CONTROL_REQTYPE_TYPE 0x60
- /** Mask for the request type parameter, to indicate the recipient of the request (Standard, Class
- * or Vendor Specific). The result of this mask should then be compared to the request recipient
+ /** Mask for the request type parameter, to indicate the recipient of the request (Device, Interface
+ * Endpoint or Other). The result of this mask should then be compared to the request recipient
* masks.
*
* \see REQREC_* macros for masks indicating the request recipient.
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 27a25e75f..f0683039b 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -13,6 +13,7 @@
* tokens as an alternative to tokens defined in the project makefile
* - Added new USB_Host_SetInterfaceAltSetting() convenience function for the selection of an interface's alternative setting
* - Added Audio class control request definitions
+ * - Added new callback to the Audio Class driver to allow for endpoint control manipulations such as data sample rates
* - Library Applications:
* - Added RNDIS device mode to the Webserver project
* - Added new MediaControl project
@@ -27,13 +28,14 @@
* the supported audio sampling rates, to allow for multiple audio interfaces with different numbers of supported rates and/or
* continuous sample rates
* - Library Applications:
- * - <i>None</i>
+ * - Modified the Class Driver AudioInput and AudioOutput demos to support multiple sample rates
*
* <b>Fixed:</b>
* - Core:
* - <i>None</i>
* - Library Applications:
* - Fixed incorrect signature in the CDC and DFU class bootloaders for the ATMEGA8U2
+ * - Fixed KeyboardHost and KeyboardHostWithParser demos displaying incorrect values when numerical keys were pressed
*
* \section Sec_ChangeLog110528 Version 110528
* <b>New:</b>
diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt
index 4016bf52b..75dd9e729 100644
--- a/LUFA/ManPages/FutureChanges.txt
+++ b/LUFA/ManPages/FutureChanges.txt
@@ -28,10 +28,11 @@
* -# Write LUFA tutorials
* - Demos/Projects
* -# Device/Host USB bridge
- * -# Alternative (USB-IF endorsed) USB-CDC Ethernet Class
* -# Finish incomplete demos and projects
* -# Add class driver support for Audio Host class
* -# Add class driver support for Test and Measurement class
+ * -# Add class driver support for EEM class
+ * -# Add class driver support for ECM class
* -# Fix up Audio class support - add support for mixers, etc., add support for GET/SET commands
* - Ports
* -# Complete AVR32 port for existing devices, add UC3C support
diff --git a/LUFA/ManPages/VIDAndPIDValues.txt b/LUFA/ManPages/VIDAndPIDValues.txt
index 17d9e1782..d05334d9a 100644
--- a/LUFA/ManPages/VIDAndPIDValues.txt
+++ b/LUFA/ManPages/VIDAndPIDValues.txt
@@ -361,7 +361,7 @@
* 0x206B
* </td>
* <td>
- * <i>Currently Unallocated</i>
+ * Class Driver Audio Input Demo (Multiple Sample Rates)
* </td>
* </tr>
*
@@ -373,7 +373,7 @@
* 0x206C
* </td>
* <td>
- * <i>Currently Unallocated</i>
+ * Class Driver Audio Output Demo (Multiple Sample Rates)
* </td>
* </tr>
*
diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
index 42e436cdf..e9e92f99a 100644
--- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
+++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
@@ -236,12 +236,12 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
/* EEPROM just increments the address each byte, flash needs to increment on each word and
* also check to ensure that a LOAD EXTENDED ADDRESS command is issued each time the extended
- * address boundary has been crossed */
+ * address boundary has been crossed during FLASH memory programming */
if ((CurrentByte & 0x01) || (V2Command == CMD_PROGRAM_EEPROM_ISP))
{
CurrentAddress++;
- if ((V2Command != CMD_PROGRAM_EEPROM_ISP) && !(CurrentAddress & 0xFFFF))
+ if ((V2Command == CMD_PROGRAM_FLASH_ISP) && !(CurrentAddress & 0xFFFF))
MustLoadExtendedAddress = true;
}
}