Added new callback to the Audio Class driver to allow for endpoint control manipulati...
authorDean Camera <dean@fourwalledcubicle.com>
Fri, 3 Jun 2011 07:56:12 +0000 (07:56 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Fri, 3 Jun 2011 07:56:12 +0000 (07:56 +0000)
Modified the Class Driver AudioInput and AudioOutput demos to support multiple sample rates.

Fixed KeyboardHost and KeyboardHostWithParser demos displaying incorrect values when numerical keys were pressed.

Fix broken LowLevel audio demo descriptors.

Minor documentation fixes.

20 files changed:
Demos/Device/ClassDriver/AudioInput/AudioInput.c
Demos/Device/ClassDriver/AudioInput/Descriptors.c
Demos/Device/ClassDriver/AudioInput/Descriptors.h
Demos/Device/ClassDriver/AudioOutput/AudioOutput.c
Demos/Device/ClassDriver/AudioOutput/Descriptors.c
Demos/Device/ClassDriver/AudioOutput/Descriptors.h
Demos/Device/LowLevel/AudioInput/Descriptors.c
Demos/Device/LowLevel/AudioOutput/Descriptors.c
Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c
Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c
Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
LUFA/Drivers/USB/Class/Common/Audio.h
LUFA/Drivers/USB/Class/Device/Audio.c
LUFA/Drivers/USB/Class/Device/Audio.h
LUFA/Drivers/USB/Core/StdRequestType.h
LUFA/ManPages/ChangeLog.txt
LUFA/ManPages/FutureChanges.txt
LUFA/ManPages/VIDAndPIDValues.txt
Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c

index b197588..58a3668 100644 (file)
@@ -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.
 
 /** 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);
 
        /* 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
 }
        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_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;
+}
index bd31bdb..6fffd05 100644 (file)
@@ -54,7 +54,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
        .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
 
        .VendorID               = 0x03EB,
        .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
 
        .VendorID               = 0x03EB,
-       .ProductID              = 0x2047,
+       .ProductID              = 0x206B,
        .ReleaseNumber          = VERSION_BCD(00.01),
 
        .ManufacturerStrIndex   = 0x01,
        .ReleaseNumber          = VERSION_BCD(00.01),
 
        .ManufacturerStrIndex   = 0x01,
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 
        .Audio_AudioFormat =
                {
 
        .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,
                        .Subtype                  = AUDIO_DSUBTYPE_CSInterface_FormatType,
 
                        .FormatType               = 0x01,
@@ -199,12 +201,17 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 
                        .SubFrameSize             = 0x02,
                        .BitResolution            = 16,
 
                        .SubFrameSize             = 0x02,
                        .BitResolution            = 16,
-                       .TotalDiscreteSampleRates = 1,
+
+                       .TotalDiscreteSampleRates = (sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates) / sizeof(USB_Audio_SampleFreq_t))
                },
        
        .Audio_AudioFormatSampleRates =
                {
                },
        
        .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 =
                },
 
        .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,
 
                        .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
 
                        .LockDelayUnits           = 0x00,
                        .LockDelay                = 0x0000
index 82dbd51..05d1fee 100644 (file)
@@ -51,9 +51,6 @@
                 */
                #define AUDIO_STREAM_EPSIZE          ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
 
                 */
                #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
        /* 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_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;
                        USB_Audio_Descriptor_StreamEndpoint_Std_t Audio_StreamEndpoint;
                        USB_Audio_Descriptor_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
                } USB_Descriptor_Configuration_t;
index dbfd10b..43267b2 100644 (file)
@@ -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.
 
 /** 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);
 
        /* 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
 
        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_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;
+}
index e46c3c0..5bb0e9f 100644 (file)
@@ -54,7 +54,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
        .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
 
        .VendorID               = 0x03EB,
        .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
 
        .VendorID               = 0x03EB,
-       .ProductID              = 0x2046,
+       .ProductID              = 0x206C,
        .ReleaseNumber          = VERSION_BCD(00.01),
 
        .ManufacturerStrIndex   = 0x01,
        .ReleaseNumber          = VERSION_BCD(00.01),
 
        .ManufacturerStrIndex   = 0x01,
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 
        .Audio_AudioFormat =
                {
 
        .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,
                        .Subtype                  = AUDIO_DSUBTYPE_CSInterface_FormatType,
 
                        .FormatType               = 0x01,
@@ -200,12 +202,16 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
                        .SubFrameSize             = 0x02,
                        .BitResolution            = 16,
 
                        .SubFrameSize             = 0x02,
                        .BitResolution            = 16,
 
-                       .TotalDiscreteSampleRates = 1,
+                       .TotalDiscreteSampleRates = (sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates) / sizeof(USB_Audio_SampleFreq_t)),
                },
        
        .Audio_AudioFormatSampleRates =
                {
                },
        
        .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 =
                },
 
        .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,
 
                        .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
 
                        .LockDelayUnits           = 0x00,
                        .LockDelay                = 0x0000
index b4b8db6..ca5c873 100644 (file)
@@ -51,9 +51,6 @@
                 */
                #define AUDIO_STREAM_EPSIZE          ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
 
                 */
                #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
        /* 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_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;
                        USB_Audio_Descriptor_StreamEndpoint_Std_t Audio_StreamEndpoint;
                        USB_Audio_Descriptor_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
                } USB_Descriptor_Configuration_t;
index 6c8323c..8a63d77 100644 (file)
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 
        .Audio_AudioFormat =
                {
 
        .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,
                        .Subtype                  = AUDIO_DSUBTYPE_CSInterface_FormatType,
 
                        .FormatType               = 0x01,
index 9c57a42..59e3af1 100644 (file)
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 
        .Audio_AudioFormat =
                {
 
        .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,
                        .Subtype                  = AUDIO_DSUBTYPE_CSInterface_FormatType,
 
                        .FormatType               = 0x01,
index 9b6125e..38af3a7 100644 (file)
@@ -137,9 +137,13 @@ int main(void)
                                                        PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
                                                }
                                                else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
                                                        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)
                                                {
                                                }
                                                else if (KeyCode == HID_KEYBOARD_SC_SPACE)
                                                {
index abb391c..d7df58f 100644 (file)
@@ -157,9 +157,13 @@ int main(void)
                                                                        PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
                                                                }
                                                                else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
                                                                        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)
                                                                {
                                                                }
                                                                else if (KeyCode == HID_KEYBOARD_SC_SPACE)
                                                                {
index 84e6145..6df052d 100644 (file)
@@ -173,9 +173,13 @@ void ReadNextReport(void)
                                PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
                        }
                        else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
                                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)
                        {
                        }
                        else if (KeyCode == HID_KEYBOARD_SC_SPACE)
                        {
index 512cc1a..6ef7a96 100644 (file)
@@ -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) &
                                        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)
                                {
                                }
                                else if (KeyCode == HID_KEYBOARD_SC_SPACE)
                                {
index cc6e8e5..fd9a3a9 100644 (file)
                 *
                 *  \param[in] freq  Required audio sampling frequency in HZ
                 */
                 *
                 *  \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.
 
                /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
                 *  accepts only filled endpoint packets of audio samples.
                 *  will accept partially filled endpoint packets of audio samples.
                 */
                #define AUDIO_EP_ACCEPTS_SMALL_PACKETS    (0 << 7)
                 *  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
                
        /* Enums: */
                /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Audio
                        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. */
                };
                        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).
 
        /* Type Defines: */
                /** \brief Audio class-specific Input Terminal Descriptor (LUFA naming conventions).
                        uint16_t wFormatTag; /**< Format of the audio stream, see Audio Device Formats specification. */
                } ATTR_PACKED USB_Audio_StdDescriptor_Interface_AS_t;
 
                        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
                /** \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
                                                                           */
                } ATTR_PACKED USB_Audio_Descriptor_Format_t;
 
                                                                           */
                } 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
                /** \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
index 8c5c996..f183fde 100644 (file)
@@ -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.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:
        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();
                        }
                                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;
        }
 }
 
        }
 }
 
index a50bd97..a090763 100644 (file)
                         *  \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);
                         *  \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
 
                /* Inline Functions: */
                        /** General management task for a given Audio class interface, required for the correct operation of the interface. This should
index e3e30f9..83f59af 100644 (file)
@@ -74,8 +74,8 @@
                         */
                        #define CONTROL_REQTYPE_TYPE       0x60
 
                         */
                        #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.
                         *  masks.
                         *
                         *  \see REQREC_* macros for masks indicating the request recipient.
index 27a25e7..f068303 100644 (file)
@@ -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
   *     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
   *  - Library Applications:
   *   - Added RNDIS device mode to the Webserver project
   *   - Added new MediaControl project
   *     the supported audio sampling rates, to allow for multiple audio interfaces with different numbers of supported rates and/or
   *     continuous sample rates
   *  - Library Applications:
   *     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
   *
   *  <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>
   *
   *  \section Sec_ChangeLog110528 Version 110528
   *  <b>New:</b>
index 4016bf5..75dd9e7 100644 (file)
   *      -# Write LUFA tutorials
   *  - Demos/Projects
   *      -# Device/Host USB bridge
   *      -# 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
   *      -# 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
   *      -# 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
index 17d9e17..d05334d 100644 (file)
  *     0x206B
  *    </td>
  *    <td>
  *     0x206B
  *    </td>
  *    <td>
- *     <i>Currently Unallocated</i>
+ *     Class Driver Audio Input Demo (Multiple Sample Rates)
  *    </td>
  *   </tr>
  *
  *    </td>
  *   </tr>
  *
  *     0x206C
  *    </td>
  *    <td>
  *     0x206C
  *    </td>
  *    <td>
- *     <i>Currently Unallocated</i>
+ *     Class Driver Audio Output Demo (Multiple Sample Rates)
  *    </td>
  *   </tr>
  *
  *    </td>
  *   </tr>
  *
index 42e436c..e9e92f9 100644 (file)
@@ -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
                
                /* 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 ((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;
                }
        }
                          MustLoadExtendedAddress = true;
                }
        }