diff --git a/.gitignore b/.gitignore
index 0af1cba..7ef5dd5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,8 +51,6 @@ Module.symvers
Mkfile.old
dkms.conf
-USBD_Test/
-Test/
Files/
Debug/
debug/
diff --git a/I-CUBE-USBD-COMPOSITE/AL94.I-CUBE-USBD-COMPOSITE.1.0.3.pack b/I-CUBE-USBD-COMPOSITE/AL94.I-CUBE-USBD-COMPOSITE.1.0.3.pack
index 4776688..1d74922 100644
Binary files a/I-CUBE-USBD-COMPOSITE/AL94.I-CUBE-USBD-COMPOSITE.1.0.3.pack and b/I-CUBE-USBD-COMPOSITE/AL94.I-CUBE-USBD-COMPOSITE.1.0.3.pack differ
diff --git a/USBD_Test/Composite/AL94.I-CUBE-USBD-COMPOSITE_conf.h b/USBD_Test/Composite/AL94.I-CUBE-USBD-COMPOSITE_conf.h
new file mode 100644
index 0000000..03dd3a2
--- /dev/null
+++ b/USBD_Test/Composite/AL94.I-CUBE-USBD-COMPOSITE_conf.h
@@ -0,0 +1,87 @@
+/**
+ ******************************************************************************
+ * File Name : AL94.I-CUBE-USBD-COMPOSITE_conf.h
+ * Description : This file provides code for the configuration
+ * of the AL94.I-CUBE-USBD-COMPOSITE_conf.h instances.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2022 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __AL94__I_CUBE_USBD_COMPOSITE_CONF__H__
+#define __AL94__I_CUBE_USBD_COMPOSITE_CONF__H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+
+/**
+ MiddleWare name : AL94.I-CUBE-USBD-COMPOSITE.1.0.3
+ MiddleWare fileName : AL94.I-CUBE-USBD-COMPOSITE_conf.h
+ MiddleWare version :
+*/
+/*---------- _USBD_USE_HS -----------*/
+#define _USBD_USE_HS true
+
+/*---------- _USBD_USE_CDC_ACM -----------*/
+#define _USBD_USE_CDC_ACM true
+
+/*---------- _USBD_CDC_ACM_COUNT -----------*/
+#define _USBD_CDC_ACM_COUNT 1
+
+/*---------- _USBD_USE_CDC_RNDIS -----------*/
+#define _USBD_USE_CDC_RNDIS true
+
+/*---------- _USBD_USE_CDC_ECM -----------*/
+#define _USBD_USE_CDC_ECM true
+
+/*---------- _USBD_USE_HID_MOUSE -----------*/
+#define _USBD_USE_HID_MOUSE true
+
+/*---------- _USBD_USE_HID_KEYBOARD -----------*/
+#define _USBD_USE_HID_KEYBOARD true
+
+/*---------- _USBD_USE_HID_CUSTOM -----------*/
+#define _USBD_USE_HID_CUSTOM true
+
+/*---------- _USBD_USE_UAC_MIC -----------*/
+#define _USBD_USE_UAC_MIC true
+
+/*---------- _USBD_USE_UAC_SPKR -----------*/
+#define _USBD_USE_UAC_SPKR true
+
+/*---------- _USBD_USE_UVC -----------*/
+#define _USBD_USE_UVC true
+
+/*---------- _USBD_USE_MSC -----------*/
+#define _USBD_USE_MSC true
+
+/*---------- _USBD_USE_DFU -----------*/
+#define _USBD_USE_DFU true
+
+/*---------- _USBD_USE_PRNTR -----------*/
+#define _USBD_USE_PRNTR true
+
+/*---------- _STM32F1_DEVICE -----------*/
+#define _STM32F1_DEVICE false
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__ AL94__I_CUBE_USBD_COMPOSITE_CONF__H_H */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Drivers/CMSIS/Device/ST/STM32H7xx/LICENSE.txt b/USBD_Test/Drivers/CMSIS/Device/ST/STM32H7xx/LICENSE.txt
new file mode 100644
index 0000000..872e82b
--- /dev/null
+++ b/USBD_Test/Drivers/CMSIS/Device/ST/STM32H7xx/LICENSE.txt
@@ -0,0 +1,6 @@
+This software component is provided to you as part of a software package and
+applicable license terms are in the Package_license file. If you received this
+software component outside of a package or without applicable license terms,
+the terms of the Apache-2.0 license shall apply.
+You may obtain a copy of the Apache-2.0 at:
+https://opensource.org/licenses/Apache-2.0
diff --git a/USBD_Test/Drivers/CMSIS/Device/ST/STM32H7xx/License.md b/USBD_Test/Drivers/CMSIS/Device/ST/STM32H7xx/License.md
new file mode 100644
index 0000000..008472d
--- /dev/null
+++ b/USBD_Test/Drivers/CMSIS/Device/ST/STM32H7xx/License.md
@@ -0,0 +1 @@
+License.md file kept for legacy purpose
\ No newline at end of file
diff --git a/USBD_Test/Drivers/CMSIS/LICENSE.txt b/USBD_Test/Drivers/CMSIS/LICENSE.txt
new file mode 100644
index 0000000..8dada3e
--- /dev/null
+++ b/USBD_Test/Drivers/CMSIS/LICENSE.txt
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/USBD_Test/Drivers/STM32H7xx_HAL_Driver/LICENSE.txt b/USBD_Test/Drivers/STM32H7xx_HAL_Driver/LICENSE.txt
new file mode 100644
index 0000000..3edc4d1
--- /dev/null
+++ b/USBD_Test/Drivers/STM32H7xx_HAL_Driver/LICENSE.txt
@@ -0,0 +1,6 @@
+This software component is provided to you as part of a software package and
+applicable license terms are in the Package_license file. If you received this
+software component outside of a package or without applicable license terms,
+the terms of the BSD-3-Clause license shall apply.
+You may obtain a copy of the BSD-3-Clause at:
+https://opensource.org/licenses/BSD-3-Clause
diff --git a/USBD_Test/Drivers/STM32H7xx_HAL_Driver/License.md b/USBD_Test/Drivers/STM32H7xx_HAL_Driver/License.md
new file mode 100644
index 0000000..008472d
--- /dev/null
+++ b/USBD_Test/Drivers/STM32H7xx_HAL_Driver/License.md
@@ -0,0 +1 @@
+License.md file kept for legacy purpose
\ No newline at end of file
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_mic_if.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_mic_if.c
new file mode 100644
index 0000000..f94fd86
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_mic_if.c
@@ -0,0 +1,174 @@
+/**
+ ******************************************************************************
+ * @file usbd_audio_if.c
+ * @author SRA - Central Labs
+ * @version v1.1.0
+ * @date 03-Apr-2020
+ * @brief USB Device Audio interface file.
+ ******************************************************************************
+ * @attention
+ *
+ *
© Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_audio_mic_if.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+static int8_t Audio_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+static int8_t Audio_DeInit(uint32_t options);
+static int8_t Audio_Record(void);
+static int8_t Audio_VolumeCtl(int16_t Volume);
+static int8_t Audio_MuteCtl(uint8_t cmd);
+static int8_t Audio_Stop(void);
+static int8_t Audio_Pause(void);
+static int8_t Audio_Resume(void);
+static int8_t Audio_CommandMgr(uint8_t cmd);
+
+/* Private variables ---------------------------------------------------------*/
+extern USBD_HandleTypeDef hUsbDeviceFS;
+
+USBD_AUDIO_MIC_ItfTypeDef USBD_AUDIO_MIC_fops_FS = {
+ Audio_Init,
+ Audio_DeInit,
+ Audio_Record,
+ Audio_VolumeCtl,
+ Audio_MuteCtl,
+ Audio_Stop,
+ Audio_Pause,
+ Audio_Resume,
+ Audio_CommandMgr,
+};
+
+/* Private functions ---------------------------------------------------------*/
+/* This table maps the audio device class setting in 1/256 dB to a
+* linear 0-64 scaling used in pdm_filter.c. It is computed as
+* 256*20*log10(index/64). */
+const int16_t vol_table[65] =
+{ 0x8000, 0xDBE0, 0xE1E6, 0xE56B, 0xE7EB, 0xE9DB, 0xEB70, 0xECC7,
+0xEDF0, 0xEEF6, 0xEFE0, 0xF0B4, 0xF176, 0xF228, 0xF2CD, 0xF366,
+0xF3F5, 0xF47C, 0xF4FB, 0xF574, 0xF5E6, 0xF652, 0xF6BA, 0xF71C,
+0xF778, 0xF7D6, 0xF82D, 0xF881, 0xF8D2, 0xF920, 0xF96B, 0xF9B4,
+0xF9FB, 0xFA3F, 0xFA82, 0xFAC2, 0xFB01, 0xFB3E, 0xFB79, 0xFBB3,
+0xFBEB, 0xFC22, 0xFC57, 0xFC8C, 0xFCBF, 0xFCF1, 0xFD22, 0xFD51,
+0xFD80, 0xFDAE, 0xFDDB, 0xFE07, 0xFE32, 0xFE5D, 0xFE86, 0xFEAF,
+0xFED7, 0xFF00, 0xFF25, 0xFF4B, 0xFF70, 0xFF95, 0xFFB9, 0xFFD0,
+0x0000 };
+
+
+/**
+* @brief Initializes the AUDIO media low layer.
+* @param AudioFreq: Audio frequency used to play the audio stream.
+* @param BitRes: desired bit resolution
+* @param ChnlNbr: number of channel to be configured
+* @retval BSP_ERROR_NONE in case of success, AUDIO_ERROR otherwise
+*/
+static int8_t Audio_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
+{
+ return USBD_OK;
+}
+
+/**
+* @brief De-Initializes the AUDIO media low layer.
+* @param options: Reserved for future use
+* @retval BSP_ERROR_NONE in case of success, AUDIO_ERROR otherwise
+*/
+static int8_t Audio_DeInit(uint32_t options)
+{
+ return USBD_OK;
+}
+
+/**
+* @brief Start audio recording engine
+* @retval BSP_ERROR_NONE in case of success, AUDIO_ERROR otherwise
+*/
+static int8_t Audio_Record(void)
+{
+ return USBD_OK;
+}
+
+/**
+* @brief Controls AUDIO Volume.
+* @param vol: Volume level
+* @retval BSP_ERROR_NONE in case of success, AUDIO_ERROR otherwise
+*/
+static int8_t Audio_VolumeCtl(int16_t Volume)
+{
+ /* Call low layer volume setting function */
+ uint32_t j = 0;
+
+ /* Find the setting nearest to the desired setting */
+ while(j<64 && abs(Volume-vol_table[j]) > abs(Volume-vol_table[j+1]))
+ {
+ j++;
+ }
+ /** TODO */
+ return USBD_OK;
+}
+
+/**
+* @brief Controls AUDIO Mute.
+* @param cmd: Command opcode
+* @retval BSP_ERROR_NONE in case of success, AUDIO_ERROR otherwise
+*/
+static int8_t Audio_MuteCtl(uint8_t cmd)
+{
+ return USBD_OK;
+}
+
+
+/**
+* @brief Stops audio acquisition
+* @param none
+* @retval BSP_ERROR_NONE in case of success, AUDIO_ERROR otherwise
+*/
+static int8_t Audio_Stop(void)
+{
+ return USBD_OK;
+}
+
+/**
+* @brief Pauses audio acquisition
+* @param none
+* @retval BSP_ERROR_NONE in case of success, AUDIO_ERROR otherwise
+*/
+
+static int8_t Audio_Pause(void)
+{
+ return USBD_OK;
+}
+
+
+/**
+* @brief Resumes audio acquisition
+* @param none
+* @retval BSP_ERROR_NONE in case of success, AUDIO_ERROR otherwise
+*/
+static int8_t Audio_Resume(void)
+{
+ return USBD_OK;
+}
+
+/**
+* @brief Manages command from usb
+* @param None
+* @retval BSP_ERROR_NONE in case of success, AUDIO_ERROR otherwise
+*/
+
+static int8_t Audio_CommandMgr(uint8_t cmd)
+{
+ return USBD_OK;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_mic_if.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_mic_if.h
new file mode 100644
index 0000000..18ac72d
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_mic_if.h
@@ -0,0 +1,37 @@
+/**
+ ******************************************************************************
+ * @file usbd_audio_if.h
+ * @author SRA - Central Labs
+ * @version v1.1.0
+ * @date 03-Apr-2020
+ * @brief Header for usbd_audio_if.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_AUDIO_IF_H
+#define __USBD_AUDIO_IF_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_audio_mic.h"
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+extern USBD_AUDIO_MIC_ItfTypeDef USBD_AUDIO_MIC_fops_FS;
+
+#endif /* __USBD_AUDIO_IF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_spkr_if.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_spkr_if.c
new file mode 100644
index 0000000..a601744
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_spkr_if.c
@@ -0,0 +1,290 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : usbd_audio_if.c
+ * @version : v1.0_Cube
+ * @brief : Generic media access layer.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+ /* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_audio_spkr_if.h"
+
+/* USER CODE BEGIN INCLUDE */
+//#include "cs43l22.h"
+/* USER CODE END INCLUDE */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+/* Private variables ---------------------------------------------------------*/
+
+/* USER CODE END PV */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @brief Usb device library.
+ * @{
+ */
+
+/** @addtogroup USBD_AUDIO_IF
+ * @{
+ */
+
+/** @defgroup USBD_AUDIO_IF_Private_TypesDefinitions USBD_AUDIO_IF_Private_TypesDefinitions
+ * @brief Private types.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_TYPES */
+
+/* USER CODE END PRIVATE_TYPES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_IF_Private_Defines USBD_AUDIO_IF_Private_Defines
+ * @brief Private defines.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_DEFINES */
+
+/* USER CODE END PRIVATE_DEFINES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_IF_Private_Macros USBD_AUDIO_IF_Private_Macros
+ * @brief Private macros.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_MACRO */
+
+/* USER CODE END PRIVATE_MACRO */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_IF_Private_Variables USBD_AUDIO_IF_Private_Variables
+ * @brief Private variables.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_VARIABLES */
+
+/* USER CODE END PRIVATE_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_IF_Exported_Variables USBD_AUDIO_IF_Exported_Variables
+ * @brief Public variables.
+ * @{
+ */
+
+extern USBD_HandleTypeDef hUsbDevice;
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_IF_Private_FunctionPrototypes USBD_AUDIO_IF_Private_FunctionPrototypes
+ * @brief Private functions declaration.
+ * @{
+ */
+
+static int8_t AUDIO_Init(uint32_t AudioFreq, uint32_t Volume, uint32_t options);
+static int8_t AUDIO_DeInit(uint32_t options);
+static int8_t AUDIO_AudioCmd(uint8_t* pbuf, uint32_t size, uint8_t cmd);
+static int8_t AUDIO_VolumeCtl(uint8_t vol);
+static int8_t AUDIO_MuteCtl(uint8_t cmd);
+static int8_t AUDIO_PeriodicTC(uint8_t *pbuf, uint32_t size, uint8_t cmd);
+static int8_t AUDIO_GetState(void);
+
+/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
+
+/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
+
+/**
+ * @}
+ */
+
+USBD_AUDIO_SPKR_ItfTypeDef USBD_AUDIO_SPKR_fops =
+{
+ AUDIO_Init,
+ AUDIO_DeInit,
+ AUDIO_AudioCmd,
+ AUDIO_VolumeCtl,
+ AUDIO_MuteCtl,
+ AUDIO_PeriodicTC,
+ AUDIO_GetState,
+};
+
+/* Private functions ---------------------------------------------------------*/
+/**
+ * @brief Initializes the AUDIO media low layer over USB FS IP
+ * @param AudioFreq: Audio frequency used to play the audio stream.
+ * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
+ * @param options: Reserved for future use
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t AUDIO_Init(uint32_t AudioFreq, uint32_t Volume, uint32_t options)
+{
+ /* USER CODE BEGIN 0 */
+ UNUSED(AudioFreq);
+ UNUSED(Volume);
+ UNUSED(options);
+ return (USBD_OK);
+ /* USER CODE END 0 */
+}
+
+/**
+ * @brief De-Initializes the AUDIO media low layer
+ * @param options: Reserved for future use
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t AUDIO_DeInit(uint32_t options)
+{
+ /* USER CODE BEGIN 1 */
+ UNUSED(options);
+ return (USBD_OK);
+ /* USER CODE END 1 */
+}
+
+/**
+ * @brief Handles AUDIO command.
+ * @param pbuf: Pointer to buffer of data to be sent
+ * @param size: Number of data to be sent (in bytes)
+ * @param cmd: Command opcode
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t AUDIO_AudioCmd(uint8_t* pbuf, uint32_t size, uint8_t cmd)
+{
+ /* USER CODE BEGIN 2 */
+ switch(cmd)
+ {
+ case AUDIO_CMD_START:
+ break;
+
+ case AUDIO_CMD_PLAY:
+ break;
+ }
+ UNUSED(pbuf);
+ UNUSED(size);
+ UNUSED(cmd);
+ return (USBD_OK);
+ /* USER CODE END 2 */
+}
+
+/**
+ * @brief Controls AUDIO Volume.
+ * @param vol: volume level (0..100)
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t AUDIO_VolumeCtl(uint8_t vol)
+{
+ /* USER CODE BEGIN 3 */
+ UNUSED(vol);
+ //cs43l22_SetVolume(CS43L22_I2C_ADDRESS, vol);
+ return (USBD_OK);
+ /* USER CODE END 3 */
+}
+
+/**
+ * @brief Controls AUDIO Mute.
+ * @param cmd: command opcode
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t AUDIO_MuteCtl(uint8_t cmd)
+{
+ /* USER CODE BEGIN 4 */
+ UNUSED(cmd);
+ //cs43l22_SetMute(CS43L22_I2C_ADDRESS, cmd);
+ return (USBD_OK);
+ /* USER CODE END 4 */
+}
+
+/**
+ * @brief AUDIO_PeriodicT
+ * @param cmd: Command opcode
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t AUDIO_PeriodicTC(uint8_t *pbuf, uint32_t size, uint8_t cmd)
+{
+ /* USER CODE BEGIN 5 */
+ UNUSED(pbuf);
+ UNUSED(size);
+ UNUSED(cmd);
+ return (USBD_OK);
+ /* USER CODE END 5 */
+}
+
+/**
+ * @brief Gets AUDIO State.
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t AUDIO_GetState(void)
+{
+ /* USER CODE BEGIN 6 */
+ return (USBD_OK);
+ /* USER CODE END 6 */
+}
+
+/**
+ * @brief Manages the DMA full transfer complete event.
+ * @retval None
+ */
+void TransferComplete_CallBack(void)
+{
+ /* USER CODE BEGIN 7 */
+ USBD_AUDIO_SPKR_Sync(&hUsbDevice, AUDIO_OFFSET_FULL);
+ /* USER CODE END 7 */
+}
+
+/**
+ * @brief Manages the DMA Half transfer complete event.
+ * @retval None
+ */
+void HalfTransfer_CallBack(void)
+{
+ /* USER CODE BEGIN 8 */
+ USBD_AUDIO_SPKR_Sync(&hUsbDevice, AUDIO_OFFSET_HALF);
+ /* USER CODE END 8 */
+}
+
+/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
+
+/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_spkr_if.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_spkr_if.h
new file mode 100644
index 0000000..12fab9c
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_audio_spkr_if.h
@@ -0,0 +1,140 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : usbd_audio_if.h
+ * @version : v1.0_Cube
+ * @brief : Header for usbd_audio_if.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_AUDIO_SPKR_IF_H__
+#define __USBD_AUDIO_SPKR_IF_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_audio_spkr.h"
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @brief For Usb device.
+ * @{
+ */
+
+/** @defgroup USBD_AUDIO_IF USBD_AUDIO_IF
+ * @brief Usb audio interface device module.
+ * @{
+ */
+
+/** @defgroup USBD_AUDIO_IF_Exported_Defines USBD_AUDIO_IF_Exported_Defines
+ * @brief Defines.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_DEFINES */
+
+/* USER CODE END EXPORTED_DEFINES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_IF_Exported_Types USBD_AUDIO_IF_Exported_Types
+ * @brief Types.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_TYPES */
+
+/* USER CODE END EXPORTED_TYPES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_IF_Exported_Macros USBD_AUDIO_IF_Exported_Macros
+ * @brief Aliases.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_MACRO */
+
+/* USER CODE END EXPORTED_MACRO */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_IF_Exported_Variables USBD_AUDIO_IF_Exported_Variables
+ * @brief Public variables.
+ * @{
+ */
+
+/** AUDIO_IF Interface callback. */
+extern USBD_AUDIO_SPKR_ItfTypeDef USBD_AUDIO_SPKR_fops;
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_IF_Exported_FunctionsPrototype USBD_AUDIO_IF_Exported_FunctionsPrototype
+ * @brief Public functions declaration.
+ * @{
+ */
+
+/**
+ * @brief Manages the DMA full transfer complete event.
+ * @retval None
+ */
+void TransferComplete_CallBack_FS(void);
+
+/**
+ * @brief Manages the DMA half transfer complete event.
+ * @retval None
+ */
+void HalfTransfer_CallBack_FS(void);
+
+/* USER CODE BEGIN EXPORTED_FUNCTIONS */
+
+/* USER CODE END EXPORTED_FUNCTIONS */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_AUDIO_SPKR_IF_H__ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_acm_if.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_acm_if.c
new file mode 100644
index 0000000..ea7121c
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_acm_if.c
@@ -0,0 +1,544 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : usbd_cdc_if.c
+ * @version : v2.0_Cube
+ * @brief : Usb device for Virtual Com Port.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc_acm_if.h"
+
+/* USER CODE BEGIN INCLUDE */
+//#include "usart.h"
+//#include "tim.h"
+/* USER CODE END INCLUDE */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+/* Private variables ---------------------------------------------------------*/
+
+/* USER CODE END PV */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @brief Usb device library.
+ * @{
+ */
+
+/** @addtogroup USBD_CDC_IF
+ * @{
+ */
+
+/** @defgroup USBD_CDC_IF_Private_TypesDefinitions USBD_CDC_IF_Private_TypesDefinitions
+ * @brief Private types.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_TYPES */
+
+/* USER CODE END PRIVATE_TYPES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_IF_Private_Defines USBD_CDC_IF_Private_Defines
+ * @brief Private defines.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_DEFINES */
+/* USER CODE END PRIVATE_DEFINES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_IF_Private_Macros USBD_CDC_IF_Private_Macros
+ * @brief Private macros.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_MACRO */
+
+/* USER CODE END PRIVATE_MACRO */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables
+ * @brief Private variables.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_VARIABLES */
+
+#define APP_RX_DATA_SIZE 128
+#define APP_TX_DATA_SIZE 128
+
+/** RX buffer for USB */
+uint8_t RX_Buffer[NUMBER_OF_CDC][APP_RX_DATA_SIZE];
+
+/** TX buffer for USB, RX buffer for UART */
+uint8_t TX_Buffer[NUMBER_OF_CDC][APP_TX_DATA_SIZE];
+
+USBD_CDC_ACM_LineCodingTypeDef Line_Coding[NUMBER_OF_CDC];
+
+uint32_t Write_Index[NUMBER_OF_CDC]; /* keep track of received data over UART */
+uint32_t Read_Index[NUMBER_OF_CDC]; /* keep track of sent data to USB */
+
+/* USER CODE END PRIVATE_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
+ * @brief Public variables.
+ * @{
+ */
+
+extern USBD_HandleTypeDef hUsbDevice;
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes
+ * @brief Private functions declaration.
+ * @{
+ */
+
+static int8_t CDC_Init(uint8_t cdc_ch);
+static int8_t CDC_DeInit(uint8_t cdc_ch);
+static int8_t CDC_Control(uint8_t cdc_ch, uint8_t cmd, uint8_t *pbuf, uint16_t length);
+static int8_t CDC_Receive(uint8_t cdc_ch, uint8_t *pbuf, uint32_t *Len);
+static int8_t CDC_TransmitCplt(uint8_t cdc_ch, uint8_t *Buf, uint32_t *Len, uint8_t epnum);
+
+/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
+//UART_HandleTypeDef *CDC_CH_To_UART_Handle(uint8_t cdc_ch)
+//{
+// UART_HandleTypeDef *handle = NULL;
+//
+// if (cdc_ch == 0)
+// {
+// handle = &huart1;
+// }
+//#if (0)
+// else if (cdc_ch == 1)
+// {
+// handle = &huart2;
+// }
+// else if (cdc_ch == 2)
+// {
+// handle = &huart3;
+// }
+//#endif
+// return handle;
+//}
+//
+//uint8_t UART_Handle_TO_CDC_CH(UART_HandleTypeDef *handle)
+//{
+// uint8_t cdc_ch = 0;
+//
+// if (handle == &huart1)
+// {
+// cdc_ch = 0;
+// }
+//#if (0)
+// else if (handle == &huart2)
+// {
+// cdc_ch = 1;
+// }
+// else if (handle == &huart3)
+// {
+// cdc_ch = 2;
+// }
+//#endif
+// return cdc_ch;
+//}
+//
+//void Change_UART_Setting(uint8_t cdc_ch)
+//{
+// UART_HandleTypeDef *handle = CDC_CH_To_UART_Handle(cdc_ch);
+//
+// if (HAL_UART_DeInit(handle) != HAL_OK)
+// {
+// /* Initialization Error */
+// Error_Handler();
+// }
+// /* set the Stop bit */
+// switch (Line_Coding[cdc_ch].format)
+// {
+// case 0:
+// handle->Init.StopBits = UART_STOPBITS_1;
+// break;
+// case 2:
+// handle->Init.StopBits = UART_STOPBITS_2;
+// break;
+// default:
+// handle->Init.StopBits = UART_STOPBITS_1;
+// break;
+// }
+//
+// /* set the parity bit*/
+// switch (Line_Coding[cdc_ch].paritytype)
+// {
+// case 0:
+// handle->Init.Parity = UART_PARITY_NONE;
+// break;
+// case 1:
+// handle->Init.Parity = UART_PARITY_ODD;
+// break;
+// case 2:
+// handle->Init.Parity = UART_PARITY_EVEN;
+// break;
+// default:
+// handle->Init.Parity = UART_PARITY_NONE;
+// break;
+// }
+//
+// /*set the data type : only 8bits and 9bits is supported */
+// switch (Line_Coding[cdc_ch].datatype)
+// {
+// case 0x07:
+// /* With this configuration a parity (Even or Odd) must be set */
+// handle->Init.WordLength = UART_WORDLENGTH_8B;
+// break;
+// case 0x08:
+// if (handle->Init.Parity == UART_PARITY_NONE)
+// {
+// handle->Init.WordLength = UART_WORDLENGTH_8B;
+// }
+// else
+// {
+// handle->Init.WordLength = UART_WORDLENGTH_9B;
+// }
+//
+// break;
+// default:
+// handle->Init.WordLength = UART_WORDLENGTH_8B;
+// break;
+// }
+//
+// if (Line_Coding[cdc_ch].bitrate == 0)
+// {
+// Line_Coding[cdc_ch].bitrate = 115200;
+// }
+//
+// handle->Init.BaudRate = Line_Coding[cdc_ch].bitrate;
+// handle->Init.HwFlowCtl = UART_HWCONTROL_NONE;
+// handle->Init.Mode = UART_MODE_TX_RX;
+// handle->Init.OverSampling = UART_OVERSAMPLING_16;
+//
+// if (HAL_UART_Init(handle) != HAL_OK)
+// {
+// /* Initialization Error */
+// Error_Handler();
+// }
+//
+// /** rx for uart and tx buffer of usb */
+// if (HAL_UART_Receive_IT(handle, TX_Buffer[cdc_ch], 1) != HAL_OK)
+// {
+// /* Transfer error in reception process */
+// Error_Handler();
+// }
+//}
+/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
+
+/**
+ * @}
+ */
+
+USBD_CDC_ACM_ItfTypeDef USBD_CDC_ACM_fops = {CDC_Init,
+ CDC_DeInit,
+ CDC_Control,
+ CDC_Receive,
+ CDC_TransmitCplt};
+
+/* Private functions ---------------------------------------------------------*/
+/**
+ * @brief Initializes the CDC media low layer over the FS USB IP
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_Init(uint8_t cdc_ch)
+{
+ /* USER CODE BEGIN 3 */
+
+ /* ##-1- Set Application Buffers */
+ USBD_CDC_SetRxBuffer(cdc_ch, &hUsbDevice, RX_Buffer[cdc_ch]);
+
+ // /*##-2- Start the TIM Base generation in interrupt mode ####################*/
+ // /* Start Channel1 */
+ // if (HAL_TIM_Base_Start_IT(&htim4) != HAL_OK)
+ // {
+ // /* Starting Error */
+ // Error_Handler();
+ // }
+
+ return (USBD_OK);
+ /* USER CODE END 3 */
+}
+
+/**
+ * @brief DeInitializes the CDC media low layer
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_DeInit(uint8_t cdc_ch)
+{
+ /* USER CODE BEGIN 4 */
+ /* DeInitialize the UART peripheral */
+ // if (HAL_UART_DeInit(CDC_CH_To_UART_Handle(cdc_ch)) != HAL_OK)
+ // {
+ // /* Initialization Error */
+ // Error_Handler();
+ // }
+ return (USBD_OK);
+ /* USER CODE END 4 */
+}
+
+/**
+ * @brief Manage the CDC class requests
+ * @param cmd: Command code
+ * @param pbuf: Buffer containing command data (request parameters)
+ * @param length: Number of data to be sent (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_Control(uint8_t cdc_ch, uint8_t cmd, uint8_t *pbuf, uint16_t length)
+{
+ /* USER CODE BEGIN 5 */
+ switch (cmd)
+ {
+ case CDC_SEND_ENCAPSULATED_COMMAND:
+
+ break;
+
+ case CDC_GET_ENCAPSULATED_RESPONSE:
+
+ break;
+
+ case CDC_SET_COMM_FEATURE:
+
+ break;
+
+ case CDC_GET_COMM_FEATURE:
+
+ break;
+
+ case CDC_CLEAR_COMM_FEATURE:
+
+ break;
+
+ /*******************************************************************************/
+ /* Line Coding Structure */
+ /*-----------------------------------------------------------------------------*/
+ /* Offset | Field | Size | Value | Description */
+ /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
+ /* 4 | bCharFormat | 1 | Number | Stop bits */
+ /* 0 - 1 Stop bit */
+ /* 1 - 1.5 Stop bits */
+ /* 2 - 2 Stop bits */
+ /* 5 | bParityType | 1 | Number | Parity */
+ /* 0 - None */
+ /* 1 - Odd */
+ /* 2 - Even */
+ /* 3 - Mark */
+ /* 4 - Space */
+ /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
+ /*******************************************************************************/
+ case CDC_SET_LINE_CODING:
+ Line_Coding[cdc_ch].bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) |
+ (pbuf[2] << 16) | (pbuf[3] << 24));
+ Line_Coding[cdc_ch].format = pbuf[4];
+ Line_Coding[cdc_ch].paritytype = pbuf[5];
+ Line_Coding[cdc_ch].datatype = pbuf[6];
+
+ //Change_UART_Setting(cdc_ch);
+ break;
+
+ case CDC_GET_LINE_CODING:
+ pbuf[0] = (uint8_t)(Line_Coding[cdc_ch].bitrate);
+ pbuf[1] = (uint8_t)(Line_Coding[cdc_ch].bitrate >> 8);
+ pbuf[2] = (uint8_t)(Line_Coding[cdc_ch].bitrate >> 16);
+ pbuf[3] = (uint8_t)(Line_Coding[cdc_ch].bitrate >> 24);
+ pbuf[4] = Line_Coding[cdc_ch].format;
+ pbuf[5] = Line_Coding[cdc_ch].paritytype;
+ pbuf[6] = Line_Coding[cdc_ch].datatype;
+ break;
+
+ case CDC_SET_CONTROL_LINE_STATE:
+
+ break;
+
+ case CDC_SEND_BREAK:
+
+ break;
+
+ default:
+ break;
+ }
+
+ return (USBD_OK);
+ /* USER CODE END 5 */
+}
+
+/**
+ * @brief Data received over USB OUT endpoint are sent over CDC interface
+ * through this function.
+ *
+ * @note
+ * This function will issue a NAK packet on any OUT packet received on
+ * USB endpoint until exiting this function. If you exit this function
+ * before transfer is complete on CDC interface (ie. using DMA controller)
+ * it will result in receiving more data while previous ones are still
+ * not sent.
+ *
+ * @param Buf: Buffer of data to be received
+ * @param Len: Number of data received (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_Receive(uint8_t cdc_ch, uint8_t *Buf, uint32_t *Len)
+{
+ /* USER CODE BEGIN 6 */
+ //HAL_UART_Transmit_DMA(CDC_CH_To_UART_Handle(cdc_ch), Buf, *Len);
+ CDC_Transmit(cdc_ch, Buf, *Len); // echo back on same channel
+
+ USBD_CDC_SetRxBuffer(cdc_ch, &hUsbDevice, &Buf[0]);
+ USBD_CDC_ReceivePacket(cdc_ch, &hUsbDevice);
+ return (USBD_OK);
+ /* USER CODE END 6 */
+}
+
+/**
+ * @brief CDC_TransmitCplt_FS
+ * Data transmited callback
+ *
+ * @note
+ * This function is IN transfer complete callback used to inform user that
+ * the submitted Data is successfully sent over USB.
+ *
+ * @param Buf: Buffer of data to be received
+ * @param Len: Number of data received (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_TransmitCplt(uint8_t cdc_ch, uint8_t *Buf, uint32_t *Len, uint8_t epnum)
+{
+ return (USBD_OK);
+}
+
+/**
+ * @brief CDC_Transmit
+ * Data to send over USB IN endpoint are sent over CDC interface
+ * through this function.
+ * @note
+ *
+ *
+ * @param Buf: Buffer of data to be sent
+ * @param Len: Number of data to be sent (in bytes)
+ * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
+ */
+uint8_t CDC_Transmit(uint8_t ch, uint8_t *Buf, uint16_t Len)
+{
+ uint8_t result = USBD_OK;
+ /* USER CODE BEGIN 7 */
+ extern USBD_CDC_ACM_HandleTypeDef CDC_ACM_Class_Data[];
+ USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
+ hcdc = &CDC_ACM_Class_Data[ch];
+ if (hcdc->TxState != 0)
+ {
+ return USBD_BUSY;
+ }
+ USBD_CDC_SetTxBuffer(ch, &hUsbDevice, Buf, Len);
+ result = USBD_CDC_TransmitPacket(ch, &hUsbDevice);
+ /* USER CODE END 7 */
+ return result;
+}
+
+/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
+//void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
+//{
+// /* Initiate next USB packet transfer once UART completes transfer (transmitting data over Tx line) */
+// //USBD_CDC_ReceivePacket(UART_Handle_TO_CDC_CH(huart), &hUsbDevice);
+//}
+
+//void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
+//{
+// for (uint8_t i = 0; i < NUMBER_OF_CDC; i++)
+// {
+// uint32_t buffptr;
+// uint32_t buffsize;
+//
+// if (Read_Index[i] != Write_Index[i])
+// {
+// if (Read_Index[i] > Write_Index[i]) /* Rollback */
+// {
+// buffsize = APP_TX_DATA_SIZE - Read_Index[i];
+// }
+// else
+// {
+// buffsize = Write_Index[i] - Read_Index[i];
+// }
+//
+// buffptr = Read_Index[i];
+//
+// USBD_CDC_SetTxBuffer(i, &hUsbDevice, &TX_Buffer[i][buffptr], buffsize);
+//
+// if (USBD_CDC_TransmitPacket(i, &hUsbDevice) == USBD_OK)
+// {
+// Read_Index[i] += buffsize;
+// if (Read_Index[i] == APP_RX_DATA_SIZE)
+// {
+// Read_Index[i] = 0;
+// }
+// }
+// }
+// }
+//}
+
+//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+//{
+// uint8_t cdc_ch = UART_Handle_TO_CDC_CH(huart);
+// /* Increment Index for buffer writing */
+// Write_Index[cdc_ch]++;
+//
+// /* To avoid buffer overflow */
+// if (Write_Index[cdc_ch] == APP_RX_DATA_SIZE)
+// {
+// Write_Index[cdc_ch] = 0;
+// }
+//
+// /* Start another reception: provide the buffer pointer with offset and the buffer size */
+// HAL_UART_Receive_IT(huart, (TX_Buffer[cdc_ch] + Write_Index[cdc_ch]), 1);
+//}
+/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_acm_if.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_acm_if.h
new file mode 100644
index 0000000..0558650
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_acm_if.h
@@ -0,0 +1,130 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : usbd_cdc_acm_if.h
+ * @version : v2.0_Cube
+ * @brief : Header for usbd_cdc_if.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CDC_ACM_IF_H__
+#define __USBD_CDC_ACM_IF_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc_acm.h"
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @brief For Usb device.
+ * @{
+ */
+
+/** @defgroup USBD_CDC_IF USBD_CDC_IF
+ * @brief Usb VCP device module
+ * @{
+ */
+
+/** @defgroup USBD_CDC_IF_Exported_Defines USBD_CDC_IF_Exported_Defines
+ * @brief Defines.
+ * @{
+ */
+/* USER CODE BEGIN EXPORTED_DEFINES */
+
+/* USER CODE END EXPORTED_DEFINES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_IF_Exported_Types USBD_CDC_IF_Exported_Types
+ * @brief Types.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_TYPES */
+
+/* USER CODE END EXPORTED_TYPES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_IF_Exported_Macros USBD_CDC_IF_Exported_Macros
+ * @brief Aliases.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_MACRO */
+
+/* USER CODE END EXPORTED_MACRO */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
+ * @brief Public variables.
+ * @{
+ */
+
+/** CDC Interface callback. */
+extern USBD_CDC_ACM_ItfTypeDef USBD_CDC_ACM_fops;
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_IF_Exported_FunctionsPrototype USBD_CDC_IF_Exported_FunctionsPrototype
+ * @brief Public functions declaration.
+ * @{
+ */
+
+uint8_t CDC_Transmit(uint8_t ch, uint8_t* Buf, uint16_t Len);
+
+/* USER CODE BEGIN EXPORTED_FUNCTIONS */
+
+/* USER CODE END EXPORTED_FUNCTIONS */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_CDC_ACM_IF_TEMPLATE_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_ecm_if.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_ecm_if.c
new file mode 100644
index 0000000..c0db019
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_ecm_if.c
@@ -0,0 +1,245 @@
+/**
+ ******************************************************************************
+ * @file Src/usbd_cdc_ecm_if_template.c
+ * @author MCD Application Team
+ * @brief Source file for USBD CDC_ECM interface
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "usbd_cdc_ecm_if.h"
+
+extern USBD_HandleTypeDef hUsbDevice;
+
+/*
+ Include here LwIP files if used
+*/
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma data_alignment=4
+#endif
+__ALIGN_BEGIN static uint8_t UserRxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; /* Received Data over USB are stored in this buffer */
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma data_alignment=4
+#endif
+__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; /* Received Data over CDC_ECM (CDC_ECM interface) are stored in this buffer */
+
+static uint8_t CDC_ECMInitialized = 0U;
+
+/* Private function prototypes -----------------------------------------------*/
+static int8_t CDC_ECM_Itf_Init(void);
+static int8_t CDC_ECM_Itf_DeInit(void);
+static int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length);
+static int8_t CDC_ECM_Itf_Receive(uint8_t *pbuf, uint32_t *Len);
+static int8_t CDC_ECM_Itf_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
+static int8_t CDC_ECM_Itf_Process(USBD_HandleTypeDef *pdev);
+
+USBD_CDC_ECM_ItfTypeDef USBD_CDC_ECM_fops =
+{
+ CDC_ECM_Itf_Init,
+ CDC_ECM_Itf_DeInit,
+ CDC_ECM_Itf_Control,
+ CDC_ECM_Itf_Receive,
+ CDC_ECM_Itf_TransmitCplt,
+ CDC_ECM_Itf_Process,
+ (uint8_t *)CDC_ECM_MAC_STR_DESC,
+};
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief CDC_ECM_Itf_Init
+ * Initializes the CDC_ECM media low layer
+ * @param None
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_ECM_Itf_Init(void)
+{
+ if (CDC_ECMInitialized == 0U)
+ {
+ /*
+ Initialize the TCP/IP stack here
+ */
+
+ CDC_ECMInitialized = 1U;
+ }
+
+ /* Set Application Buffers */
+ (void)USBD_CDC_ECM_SetTxBuffer(&hUsbDevice, UserTxBuffer, 0U);
+ (void)USBD_CDC_ECM_SetRxBuffer(&hUsbDevice, UserRxBuffer);
+
+ return (0);
+}
+
+/**
+ * @brief CDC_ECM_Itf_DeInit
+ * DeInitializes the CDC_ECM media low layer
+ * @param None
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_ECM_Itf_DeInit(void)
+{
+ USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(hUsbDevice.pClassData_CDC_ECM);
+
+ /* Notify application layer that link is down */
+ hcdc_cdc_ecm->LinkStatus = 0U;
+
+ return (0);
+}
+
+/**
+ * @brief CDC_ECM_Itf_Control
+ * Manage the CDC_ECM class requests
+ * @param Cmd: Command code
+ * @param Buf: Buffer containing command data (request parameters)
+ * @param Len: Number of data to be sent (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
+{
+ USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(hUsbDevice.pClassData_CDC_ECM);
+
+ switch (cmd)
+ {
+ case CDC_ECM_SEND_ENCAPSULATED_COMMAND:
+ /* Add your code here */
+ break;
+
+ case CDC_ECM_GET_ENCAPSULATED_RESPONSE:
+ /* Add your code here */
+ break;
+
+ case CDC_ECM_SET_ETH_MULTICAST_FILTERS:
+ /* Add your code here */
+ break;
+
+ case CDC_ECM_SET_ETH_PWRM_PATTERN_FILTER:
+ /* Add your code here */
+ break;
+
+ case CDC_ECM_GET_ETH_PWRM_PATTERN_FILTER:
+ /* Add your code here */
+ break;
+
+ case CDC_ECM_SET_ETH_PACKET_FILTER:
+ /* Check if this is the first time we enter */
+ if (hcdc_cdc_ecm->LinkStatus == 0U)
+ {
+ /*
+ Setup the Link up at TCP/IP level
+ */
+ hcdc_cdc_ecm->LinkStatus = 1U;
+
+ /* Modification for MacOS which doesn't send SetInterface before receiving INs */
+ if (hcdc_cdc_ecm->NotificationStatus == 0U)
+ {
+ /* Send notification: NETWORK_CONNECTION Event */
+ (void)USBD_CDC_ECM_SendNotification(&hUsbDevice, ECM_NETWORK_CONNECTION,
+ CDC_ECM_NET_CONNECTED, NULL);
+
+ /* Prepare for sending Connection Speed Change notification */
+ hcdc_cdc_ecm->NotificationStatus = 1U;
+ }
+ }
+ /* Add your code here */
+ break;
+
+ case CDC_ECM_GET_ETH_STATISTIC:
+ /* Add your code here */
+ break;
+
+ default:
+ break;
+ }
+ UNUSED(length);
+ UNUSED(pbuf);
+
+ return (0);
+}
+
+/**
+ * @brief CDC_ECM_Itf_Receive
+ * Data received over USB OUT endpoint are sent over CDC_ECM interface
+ * through this function.
+ * @param Buf: Buffer of data to be transmitted
+ * @param Len: Number of data received (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_ECM_Itf_Receive(uint8_t *Buf, uint32_t *Len)
+{
+ /* Get the CDC_ECM handler pointer */
+ USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(hUsbDevice.pClassData_CDC_ECM);
+
+ /* Call Eth buffer processing */
+ hcdc_cdc_ecm->RxState = 1U;
+
+ UNUSED(Len);
+ UNUSED(Buf);
+
+ return (0);
+}
+
+/**
+ * @brief CDC_ECM_Itf_TransmitCplt
+ * Data transmitted callback
+ *
+ * @note
+ * This function is IN transfer complete callback used to inform user that
+ * the submitted Data is successfully sent over USB.
+ *
+ * @param Buf: Buffer of data to be received
+ * @param Len: Number of data received (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_ECM_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
+{
+ UNUSED(Buf);
+ UNUSED(Len);
+ UNUSED(epnum);
+
+ return (0);
+}
+
+/**
+ * @brief CDC_ECM_Itf_Process
+ * Data received over USB OUT endpoint are sent over CDC_ECM interface
+ * through this function.
+ * @param pdef: pointer to the USB Device Handle
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_ECM_Itf_Process(USBD_HandleTypeDef *pdev)
+{
+ /* Get the CDC_ECM handler pointer */
+ USBD_CDC_ECM_HandleTypeDef *hcdc_cdc_ecm = (USBD_CDC_ECM_HandleTypeDef *)(pdev->pClassData_CDC_ECM);
+
+ if ((hcdc_cdc_ecm != NULL) && (hcdc_cdc_ecm->LinkStatus != 0U))
+ {
+ /*
+ Read a received packet from the Ethernet buffers and send it
+ to the lwIP for handling
+ Call here the TCP/IP background tasks.
+ */
+ }
+
+ return (0);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_ecm_if.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_ecm_if.h
new file mode 100644
index 0000000..7ce8714
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_ecm_if.h
@@ -0,0 +1,82 @@
+/**
+ ******************************************************************************
+ * @file Inc/usbd_cdc_ecm_if_template.h
+ * @author MCD Application Team
+ * @brief Header for usbd_cdc_ecm_if_template.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CDC_ECM_IF_H
+#define __USBD_CDC_ECM_IF_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc_ecm.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* Ensure this MAC address value is same as MAC_ADDRx declared in STM32xxx_conf.h */
+#define CDC_ECM_MAC_STR_DESC (uint8_t *)"000202030000"
+#define CDC_ECM_MAC_ADDR0 0x00U /* 01 */
+#define CDC_ECM_MAC_ADDR1 0x02U /* 02 */
+#define CDC_ECM_MAC_ADDR2 0x02U /* 03 */
+#define CDC_ECM_MAC_ADDR3 0x03U /* 00 */
+#define CDC_ECM_MAC_ADDR4 0x00U /* 00 */
+#define CDC_ECM_MAC_ADDR5 0x00U /* 00 */
+
+/* Max Number of Trials waiting for Tx ready */
+#define CDC_ECM_MAX_TX_WAIT_TRIALS 1000000U
+
+#define CDC_ECM_ETH_STATS_BYTE0 0U
+/*(uint8_t)(CDC_ECM_XMIT_OK_VAL | CDC_ECM_RVC_OK_VAL | CDC_ECM_XMIT_ERROR_VAL | \
+ CDC_ECM_RCV_ERROR_VAL | CDC_ECM_RCV_NO_BUFFER_VAL | CDC_ECM_DIRECTED_BYTES_XMIT_VAL | \
+ CDC_ECM_DIRECTED_FRAMES_XMIT_VAL | CDC_ECM_MULTICAST_BYTES_XMIT_VAL) */
+
+#define CDC_ECM_ETH_STATS_BYTE1 0U
+/*(uint8_t)(CDC_ECM_MULTICAST_FRAMES_XMIT_VAL | CDC_ECM_BROADCAST_BYTES_XMIT_VAL | \
+ CDC_ECM_BROADCAST_FRAMES_XMIT_VAL | CDC_ECM_DIRECTED_BYTES_RCV_VAL | \
+ CDC_ECM_DIRECTED_FRAMES_RCV_VAL | CDC_ECM_MULTICAST_BYTES_RCV_VAL | \
+ CDC_ECM_MULTICAST_FRAMES_RCV_VAL | CDC_ECM_BROADCAST_BYTES_RCV_VAL) */
+
+#define CDC_ECM_ETH_STATS_BYTE2 0U
+/*(uint8_t)(CDC_ECM_BROADCAST_FRAMES_RCV_VAL | CDC_ECM_RCV_CRC_ERROR_VAL | \
+ CDC_ECM_TRANSMIT_QUEUE_LENGTH_VAL | CDC_ECM_RCV_ERROR_ALIGNMENT_VAL | \
+ CDC_ECM_XMIT_ONE_COLLISION_VAL | CDC_ECM_XMIT_MORE_COLLISIONS_VAL | \
+ CDC_ECM_XMIT_DEFERRED_VAL | CDC_ECM_XMIT_MAX_COLLISIONS_VAL) */
+
+#define CDC_ECM_ETH_STATS_BYTE3 0U
+/*(uint8_t)(CDC_ECM_RCV_OVERRUN_VAL | CDC_ECM_XMIT_UNDERRUN_VAL | CDC_ECM_XMIT_HEARTBEAT_FAILURE_VAL | \
+ CDC_ECM_XMIT_TIMES_CRS_LOST_VAL | CDC_ECM_XMIT_LATE_COLLISIONS_VAL | CDC_ECM_ETH_STATS_RESERVED) */
+
+/* Ethernet Maximum Segment size, typically 1514 bytes */
+#define CDC_ECM_ETH_MAX_SEGSZE 1514U
+
+/* Number of Ethernet multicast filters */
+#define CDC_ECM_ETH_NBR_MACFILTERS 0U
+
+/* Number of wakeup power filters */
+#define CDC_ECM_ETH_NBR_PWRFILTERS 0U
+
+
+#define CDC_ECM_CONNECT_SPEED_UPSTREAM 0x004C4B40U /* 5Mbps */
+#define CDC_ECM_CONNECT_SPEED_DOWNSTREAM 0x004C4B40U /* 5Mbps */
+
+extern USBD_CDC_ECM_ItfTypeDef USBD_CDC_ECM_fops;
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+#endif /* __USBD_CDC_ECM_IF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_rndis_if.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_rndis_if.c
new file mode 100644
index 0000000..9a36f40
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_rndis_if.c
@@ -0,0 +1,231 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_rndis_if_template.c
+ * @author MCD Application Team
+ * @brief Source file for USBD CDC_RNDIS interface template
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+
+/* Include TCP/IP stack header files */
+/*
+#include "lwip/opt.h"
+#include "lwip/init.h"
+#include "lwip/dhcp.h"
+#include "lwip/netif.h"
+#include "lwip/timeouts.h"
+#include "netif/etharp.h"
+#include "http_cgi_ssi.h"
+#include "ethernetif.h"
+*/
+
+#include "usbd_cdc_rndis_if.h"
+
+extern USBD_HandleTypeDef hUsbDevice;
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma data_alignment=4
+#endif
+__ALIGN_BEGIN uint8_t UserRxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; /* Received Data over USB are stored in this buffer */
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma data_alignment=4
+#endif
+__ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; /* Received Data over CDC_RNDIS (CDC_RNDIS interface) are stored in this buffer */
+
+static uint8_t CDC_RNDISInitialized = 0U;
+
+/* Private function prototypes -----------------------------------------------*/
+static int8_t CDC_RNDIS_Itf_Init(void);
+static int8_t CDC_RNDIS_Itf_DeInit(void);
+static int8_t CDC_RNDIS_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length);
+static int8_t CDC_RNDIS_Itf_Receive(uint8_t *pbuf, uint32_t *Len);
+static int8_t CDC_RNDIS_Itf_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
+static int8_t CDC_RNDIS_Itf_Process(USBD_HandleTypeDef *pdev);
+
+USBD_CDC_RNDIS_ItfTypeDef USBD_CDC_RNDIS_fops =
+{
+ CDC_RNDIS_Itf_Init,
+ CDC_RNDIS_Itf_DeInit,
+ CDC_RNDIS_Itf_Control,
+ CDC_RNDIS_Itf_Receive,
+ CDC_RNDIS_Itf_TransmitCplt,
+ CDC_RNDIS_Itf_Process,
+ (uint8_t *)CDC_RNDIS_MAC_STR_DESC,
+};
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief CDC_RNDIS_Itf_Init
+ * Initializes the CDC_RNDIS media low layer
+ * @param None
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_RNDIS_Itf_Init(void)
+{
+ if (CDC_RNDISInitialized == 0U)
+ {
+ /*
+ Initialize the LwIP stack
+ Add your code here
+
+ */
+
+ CDC_RNDISInitialized = 1U;
+ }
+
+ /* Set Application Buffers */
+ (void)USBD_CDC_RNDIS_SetTxBuffer(&hUsbDevice, UserTxBuffer, 0U);
+ (void)USBD_CDC_RNDIS_SetRxBuffer(&hUsbDevice, UserRxBuffer);
+
+ return (0);
+}
+
+/**
+ * @brief CDC_RNDIS_Itf_DeInit
+ * DeInitializes the CDC_RNDIS media low layer
+ * @param None
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_RNDIS_Itf_DeInit(void)
+{
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(hUsbDevice.pClassData_CDC_RNDIS);
+
+ /*
+ Add your code here
+ */
+
+ /* Notify application layer that link is down */
+ hcdc_cdc_rndis->LinkStatus = 0U;
+
+ return (0);
+}
+
+/**
+ * @brief CDC_RNDIS_Itf_Control
+ * Manage the CDC_RNDIS class requests
+ * @param Cmd: Command code
+ * @param Buf: Buffer containing command data (request parameters)
+ * @param Len: Number of data to be sent (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_RNDIS_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
+{
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(hUsbDevice.pClassData_CDC_RNDIS);
+
+ switch (cmd)
+ {
+ case CDC_RNDIS_SEND_ENCAPSULATED_COMMAND:
+ /* Add your code here */
+ break;
+
+ case CDC_RNDIS_GET_ENCAPSULATED_RESPONSE:
+ /* Check if this is the first time we enter */
+ if (hcdc_cdc_rndis->LinkStatus == 0U)
+ {
+ /* Setup the Link up at TCP/IP stack level */
+ hcdc_cdc_rndis->LinkStatus = 1U;
+ /*
+ Add your code here
+ */
+ }
+ /* Add your code here */
+ break;
+
+ default:
+ /* Add your code here */
+ break;
+ }
+
+ UNUSED(length);
+ UNUSED(pbuf);
+
+ return (0);
+}
+
+/**
+ * @brief CDC_RNDIS_Itf_Receive
+ * Data received over USB OUT endpoint are sent over CDC_RNDIS interface
+ * through this function.
+ * @param Buf: Buffer of data to be transmitted
+ * @param Len: Number of data received (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_RNDIS_Itf_Receive(uint8_t *Buf, uint32_t *Len)
+{
+ /* Get the CDC_RNDIS handler pointer */
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(hUsbDevice.pClassData_CDC_RNDIS);
+
+ /* Call Eth buffer processing */
+ hcdc_cdc_rndis->RxState = 1U;
+
+ UNUSED(Buf);
+ UNUSED(Len);
+
+ return (0);
+}
+
+/**
+ * @brief CDC_RNDIS_Itf_TransmitCplt
+ * Data transmitted callback
+ *
+ * @note
+ * This function is IN transfer complete callback used to inform user that
+ * the submitted Data is successfully sent over USB.
+ *
+ * @param Buf: Buffer of data to be received
+ * @param Len: Number of data received (in bytes)
+ * @param epnum: EP number
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_RNDIS_Itf_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
+{
+ UNUSED(Buf);
+ UNUSED(Len);
+ UNUSED(epnum);
+
+ return (0);
+}
+
+/**
+ * @brief CDC_RNDIS_Itf_Process
+ * Data received over USB OUT endpoint are sent over CDC_RNDIS interface
+ * through this function.
+ * @param pdef: pointer to the USB Device Handle
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CDC_RNDIS_Itf_Process(USBD_HandleTypeDef *pdev)
+{
+ /* Get the CDC_RNDIS handler pointer */
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc_cdc_rndis = (USBD_CDC_RNDIS_HandleTypeDef *)(pdev->pClassData_CDC_RNDIS);
+
+ if ((hcdc_cdc_rndis != NULL) && (hcdc_cdc_rndis->LinkStatus != 0U))
+ {
+ /*
+ Add your code here
+ Read a received packet from the Ethernet buffers and send it
+ to the lwIP for handling
+ */
+ }
+
+ return (0);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_rndis_if.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_rndis_if.h
new file mode 100644
index 0000000..3cf0271
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_cdc_rndis_if.h
@@ -0,0 +1,60 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_rndis_if_template.h
+ * @author MCD Application Team
+ * @brief Header for usbd_cdc_rndis_if.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CDC_RNDIS_IF_H
+#define __USBD_CDC_RNDIS_IF_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc_rndis.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* Ensure this MAC address value is same as MAC_ADDRx declared in STM32xxx_conf.h */
+#define CDC_RNDIS_MAC_STR_DESC (uint8_t *)"000202030000"
+#define CDC_RNDIS_MAC_ADDR0 0x00U /* 01 */
+#define CDC_RNDIS_MAC_ADDR1 0x02U /* 02 */
+#define CDC_RNDIS_MAC_ADDR2 0x02U /* 03 */
+#define CDC_RNDIS_MAC_ADDR3 0x03U /* 00 */
+#define CDC_RNDIS_MAC_ADDR4 0x00U /* 00 */
+#define CDC_RNDIS_MAC_ADDR5 0x00U /* 00 */
+
+#define USBD_CDC_RNDIS_VENDOR_DESC "STMicroelectronics"
+#define USBD_CDC_RNDIS_LINK_SPEED 100000U /* 10Mbps */
+#define USBD_CDC_RNDIS_VID 0x0483U
+
+/* Max Number of Trials waiting for Tx ready */
+#define CDC_RNDIS_MAX_TX_WAIT_TRIALS 1000000U
+
+/* Ethernet Maximum Segment size, typically 1514 bytes */
+#define CDC_RNDIS_ETH_MAX_SEGSZE 1514U
+
+#define CDC_RNDIS_CONNECT_SPEED_UPSTREAM 0x1E000000U
+#define CDC_RNDIS_CONNECT_SPEED_DOWNSTREAM 0x1E000000U
+
+
+extern USBD_CDC_RNDIS_ItfTypeDef USBD_CDC_RNDIS_fops;
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#endif /* __USBD_CDC_RNDIS_IF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_dfu_if.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_dfu_if.c
new file mode 100644
index 0000000..6d85cff
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_dfu_if.c
@@ -0,0 +1,253 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : usbd_dfu_if.c
+ * @brief : Usb device for Download Firmware Update.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_dfu_if.h"
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+/* Private variables ---------------------------------------------------------*/
+
+/* USER CODE END PV */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @brief Usb device.
+ * @{
+ */
+
+/** @defgroup USBD_DFU
+ * @brief Usb DFU device module.
+ * @{
+ */
+
+/** @defgroup USBD_DFU_Private_TypesDefinitions
+ * @brief Private types.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_TYPES */
+
+/* USER CODE END PRIVATE_TYPES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DFU_Private_Defines
+ * @brief Private defines.
+ * @{
+ */
+
+#define FLASH_DESC_STR "@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg,04*016Kg,01*064Kg,07*128Kg"
+
+/* USER CODE BEGIN PRIVATE_DEFINES */
+
+/* USER CODE END PRIVATE_DEFINES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DFU_Private_Macros
+ * @brief Private macros.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_MACRO */
+
+/* USER CODE END PRIVATE_MACRO */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DFU_Private_Variables
+ * @brief Private variables.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_VARIABLES */
+
+/* USER CODE END PRIVATE_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DFU_Exported_Variables
+ * @brief Public variables.
+ * @{
+ */
+
+extern USBD_HandleTypeDef hUsbDevice;
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DFU_Private_FunctionPrototypes
+ * @brief Private functions declaration.
+ * @{
+ */
+
+static uint16_t MEM_If_Init(void);
+static uint16_t MEM_If_Erase(uint32_t Add);
+static uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len);
+static uint8_t *MEM_If_Read(uint8_t *src, uint8_t *dest, uint32_t Len);
+static uint16_t MEM_If_DeInit(void);
+static uint16_t MEM_If_GetStatus(uint32_t Add, uint8_t Cmd, uint8_t *buffer);
+
+/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
+
+/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
+
+/**
+ * @}
+ */
+
+#if defined ( __ICCARM__ ) /* IAR Compiler */
+ #pragma data_alignment=4
+#endif
+
+__ALIGN_BEGIN USBD_DFU_MediaTypeDef USBD_DFU_fops __ALIGN_END =
+{
+ (uint8_t*)FLASH_DESC_STR,
+ MEM_If_Init,
+ MEM_If_DeInit,
+ MEM_If_Erase,
+ MEM_If_Write,
+ MEM_If_Read,
+ MEM_If_GetStatus
+};
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief Memory initialization routine.
+ * @retval USBD_OK if operation is successful, MAL_FAIL else.
+ */
+uint16_t MEM_If_Init(void)
+{
+ /* USER CODE BEGIN 6 */
+ return (USBD_OK);
+ /* USER CODE END 6 */
+}
+
+/**
+ * @brief De-Initializes Memory.
+ * @retval USBD_OK if operation is successful, MAL_FAIL else.
+ */
+uint16_t MEM_If_DeInit(void)
+{
+ /* USER CODE BEGIN 7 */
+ return (USBD_OK);
+ /* USER CODE END 7 */
+}
+
+/**
+ * @brief Erase sector.
+ * @param Add: Address of sector to be erased.
+ * @retval USBD_OK if operation is successful, MAL_FAIL else.
+ */
+uint16_t MEM_If_Erase(uint32_t Add)
+{
+ /* USER CODE BEGIN 8 */
+ return (USBD_OK);
+ /* USER CODE END 8 */
+}
+
+/**
+ * @brief Memory write routine.
+ * @param src: Pointer to the source buffer. Address to be written to.
+ * @param dest: Pointer to the destination buffer.
+ * @param Len: Number of data to be written (in bytes).
+ * @retval USBD_OK if operation is successful, MAL_FAIL else.
+ */
+uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len)
+{
+ /* USER CODE BEGIN 9 */
+ return (USBD_OK);
+ /* USER CODE END 9 */
+}
+
+/**
+ * @brief Memory read routine.
+ * @param src: Pointer to the source buffer. Address to be written to.
+ * @param dest: Pointer to the destination buffer.
+ * @param Len: Number of data to be read (in bytes).
+ * @retval Pointer to the physical address where data should be read.
+ */
+uint8_t *MEM_If_Read(uint8_t *src, uint8_t *dest, uint32_t Len)
+{
+ /* Return a valid address to avoid HardFault */
+ /* USER CODE BEGIN 10 */
+ return (uint8_t*)(USBD_OK);
+ /* USER CODE END 10 */
+}
+
+/**
+ * @brief Get status routine.
+ * @param Add: Address to be read from.
+ * @param Cmd: Number of data to be read (in bytes).
+ * @param buffer: used for returning the time necessary for a program or an erase operation
+ * @retval 0 if operation is successful
+ */
+uint16_t MEM_If_GetStatus(uint32_t Add, uint8_t Cmd, uint8_t *buffer)
+{
+ /* USER CODE BEGIN 11 */
+ switch(Cmd)
+ {
+ case DFU_MEDIA_PROGRAM:
+
+ break;
+
+ case DFU_MEDIA_ERASE:
+ default:
+
+ break;
+ }
+ return (USBD_OK);
+ /* USER CODE END 11 */
+}
+
+/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
+
+/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_dfu_if.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_dfu_if.h
new file mode 100644
index 0000000..d21d214
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_dfu_if.h
@@ -0,0 +1,128 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : usbd_dfu_if.h
+ * @brief : Header for usbd_dfu_if.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_DFU_IF_H__
+#define __USBD_DFU_IF_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_dfu.h"
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @brief For Usb device.
+ * @{
+ */
+
+/** @defgroup USBD_MEDIA USBD_MEDIA
+ * @brief Header file for the usbd_dfu_if.c file.
+ * @{
+ */
+
+/** @defgroup USBD_MEDIA_Exported_Defines USBD_MEDIA_Exported_Defines
+ * @brief Defines.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_DEFINES */
+
+/* USER CODE END EXPORTED_DEFINES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_MEDIA_Exported_Types USBD_MEDIA_Exported_Types
+ * @brief Types.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_TYPES */
+
+/* USER CODE END EXPORTED_TYPES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_MEDIA_Exported_Macros USBD_MEDIA_Exported_Macros
+ * @brief Aliases.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_MACRO */
+
+/* USER CODE END EXPORTED_MACRO */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_MEDIA_Exported_Variables USBD_MEDIA_Exported_Variables
+ * @brief Public variables.
+ * @{
+ */
+
+/** MEDIA Interface callback. */
+extern USBD_DFU_MediaTypeDef USBD_DFU_fops;
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_MEDIA_Exported_FunctionsPrototype USBD_MEDIA_Exported_FunctionsPrototype
+ * @brief Public functions declaration.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_FUNCTIONS */
+
+/* USER CODE END EXPORTED_FUNCTIONS */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_DFU_IF_H__ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_hid_custom_if.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_hid_custom_if.c
new file mode 100644
index 0000000..de07897
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_hid_custom_if.c
@@ -0,0 +1,256 @@
+/**
+ ******************************************************************************
+ * @file : usbd_custom_hid_if.c
+ * @version : v1.0_Cube
+ * @brief : USB Device Custom HID interface file.
+ ******************************************************************************
+ * This notice applies to any and all portions of this file
+ * that are not between comment pairs USER CODE BEGIN and
+ * USER CODE END. Other portions of this file, whether
+ * inserted by the user or by software development tools
+ * are owned by their respective copyright owners.
+ *
+ * Copyright (c) 2018 STMicroelectronics International N.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted, provided that the following conditions are met:
+ *
+ * 1. Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of other
+ * contributors to this software may be used to endorse or promote products
+ * derived from this software without specific written permission.
+ * 4. This software, including modifications and/or derivative works of this
+ * software, must execute solely and exclusively on microcontroller or
+ * microprocessor devices manufactured by or for STMicroelectronics.
+ * 5. Redistribution and use of this software other than as permitted under
+ * this license is void and will automatically terminate your rights under
+ * this license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
+ * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
+ * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_hid_custom_if.h"
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+/* Private variables ---------------------------------------------------------*/
+uint8_t buffer[0x40];
+/* USER CODE END PV */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @brief Usb device.
+ * @{
+ */
+
+/** @addtogroup USBD_CUSTOM_HID
+ * @{
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions USBD_CUSTOM_HID_Private_TypesDefinitions
+ * @brief Private types.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_TYPES */
+
+/* USER CODE END PRIVATE_TYPES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Defines USBD_CUSTOM_HID_Private_Defines
+ * @brief Private defines.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_DEFINES */
+
+/* USER CODE END PRIVATE_DEFINES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Macros USBD_CUSTOM_HID_Private_Macros
+ * @brief Private macros.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_MACRO */
+
+/* USER CODE END PRIVATE_MACRO */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Variables USBD_CUSTOM_HID_Private_Variables
+ * @brief Private variables.
+ * @{
+ */
+
+/** Usb HID report descriptor. */
+__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
+ {
+ /* USER CODE BEGIN 0 */
+ 0x06, 0x00, 0xff, //Usage Page(Undefined )
+ 0x09, 0x01, // USAGE (Undefined)
+ 0xa1, 0x01, // COLLECTION (Application)
+ 0x15, 0x00, // LOGICAL_MINIMUM (0)
+ 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
+ 0x75, 0x08, // REPORT_SIZE (8)
+ 0x95, 0x40, // REPORT_COUNT (64)
+ 0x09, 0x01, // USAGE (Undefined)
+ 0x81, 0x02, // INPUT (Data,Var,Abs)
+ 0x95, 0x40, // REPORT_COUNT (64)
+ 0x09, 0x01, // USAGE (Undefined)
+ 0x91, 0x02, // OUTPUT (Data,Var,Abs)
+ 0x95, 0x01, // REPORT_COUNT (1)
+ 0x09, 0x01, // USAGE (Undefined)
+ 0xb1, 0x02, // FEATURE (Data,Var,Abs)
+
+ /* USER CODE END 0 */
+ 0xC0 /* END_COLLECTION */
+};
+
+/* USER CODE BEGIN PRIVATE_VARIABLES */
+
+/* USER CODE END PRIVATE_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Exported_Variables USBD_CUSTOM_HID_Exported_Variables
+ * @brief Public variables.
+ * @{
+ */
+extern USBD_HandleTypeDef hUsbDevice;
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes USBD_CUSTOM_HID_Private_FunctionPrototypes
+ * @brief Private functions declaration.
+ * @{
+ */
+
+static int8_t CUSTOM_HID_Init(void);
+static int8_t CUSTOM_HID_DeInit(void);
+static int8_t CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state);
+
+/**
+ * @}
+ */
+
+USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_fops = {CUSTOM_HID_ReportDesc,
+ CUSTOM_HID_Init,
+ CUSTOM_HID_DeInit,
+ CUSTOM_HID_OutEvent};
+
+/** @defgroup USBD_CUSTOM_HID_Private_Functions USBD_CUSTOM_HID_Private_Functions
+ * @brief Private functions.
+ * @{
+ */
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief Initializes the CUSTOM HID media low layer
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CUSTOM_HID_Init(void)
+{
+ /* USER CODE BEGIN 4 */
+ return (USBD_OK);
+ /* USER CODE END 4 */
+}
+
+/**
+ * @brief DeInitializes the CUSTOM HID media low layer
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CUSTOM_HID_DeInit(void)
+{
+ /* USER CODE BEGIN 5 */
+ return (USBD_OK);
+ /* USER CODE END 5 */
+}
+
+/**
+ * @brief Manage the CUSTOM HID class events
+ * @param event_idx: Event index
+ * @param state: Event state
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state)
+{
+ /* USER CODE BEGIN 6 */
+ //memcpy(buffer, state, 0x40);
+ //USBD_CUSTOM_HID_SendReport(&hUsbDevice, (uint8_t *)buffer, 0x40);
+ return (USBD_OK);
+ /* USER CODE END 6 */
+}
+
+/* USER CODE BEGIN 7 */
+/**
+ * @brief Send the report to the Host
+ * @param report: The report to be sent
+ * @param len: The report length
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+/*
+static int8_t USBD_CUSTOM_HID_SendReport(uint8_t *report, uint16_t len)
+{
+ return USBD_CUSTOM_HID_SendReport(&hUsbDevice, report, len);
+}
+*/
+/* USER CODE END 7 */
+
+/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
+
+/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_hid_custom_if.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_hid_custom_if.h
new file mode 100644
index 0000000..ee297a1
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_hid_custom_if.h
@@ -0,0 +1,157 @@
+/**
+ ******************************************************************************
+ * @file : usbd_custom_hid_if.h
+ * @version : v1.0_Cube
+ * @brief : Header for usbd_custom_hid_if.c file.
+ ******************************************************************************
+ * This notice applies to any and all portions of this file
+ * that are not between comment pairs USER CODE BEGIN and
+ * USER CODE END. Other portions of this file, whether
+ * inserted by the user or by software development tools
+ * are owned by their respective copyright owners.
+ *
+ * Copyright (c) 2018 STMicroelectronics International N.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted, provided that the following conditions are met:
+ *
+ * 1. Redistribution of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of other
+ * contributors to this software may be used to endorse or promote products
+ * derived from this software without specific written permission.
+ * 4. This software, including modifications and/or derivative works of this
+ * software, must execute solely and exclusively on microcontroller or
+ * microprocessor devices manufactured by or for STMicroelectronics.
+ * 5. Redistribution and use of this software other than as permitted under
+ * this license is void and will automatically terminate your rights under
+ * this license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
+ * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
+ * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CUSTOM_HID_IF_H__
+#define __USBD_CUSTOM_HID_IF_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_hid_custom.h"
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @brief For Usb device.
+ * @{
+ */
+
+/** @defgroup USBD_CUSTOM_HID USBD_CUSTOM_HID
+ * @brief Usb custom human interface device module.
+ * @{
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Exported_Defines USBD_CUSTOM_HID_Exported_Defines
+ * @brief Defines.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_DEFINES */
+
+/* USER CODE END EXPORTED_DEFINES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Exported_Types USBD_CUSTOM_HID_Exported_Types
+ * @brief Types.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_TYPES */
+
+/* USER CODE END EXPORTED_TYPES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Exported_Macros USBD_CUSTOM_HID_Exported_Macros
+ * @brief Aliases.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_MACRO */
+
+/* USER CODE END EXPORTED_MACRO */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Exported_Variables USBD_CUSTOM_HID_Exported_Variables
+ * @brief Public variables.
+ * @{
+ */
+
+/** CUSTOMHID Interface callback. */
+extern USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_fops;
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Exported_FunctionsPrototype USBD_CUSTOM_HID_Exported_FunctionsPrototype
+ * @brief Public functions declaration.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_FUNCTIONS */
+
+/* USER CODE END EXPORTED_FUNCTIONS */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_CUSTOM_HID_IF_H__ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_msc_if.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_msc_if.c
index 4b5f130..195cbec 100644
--- a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_msc_if.c
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_msc_if.c
@@ -64,7 +64,7 @@ uint8_t MSC_Storage[32*1024];
*/
#define STORAGE_LUN_NBR 1
-#define STORAGE_BLK_NBR 100*1024/512
+#define STORAGE_BLK_NBR 32*1024/512
#define STORAGE_BLK_SIZ 512
/* USER CODE BEGIN PRIVATE_DEFINES */
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_printer_if.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_printer_if.c
new file mode 100644
index 0000000..3cde8c9
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_printer_if.c
@@ -0,0 +1,210 @@
+/**
+ ******************************************************************************
+ * @file usbd_printer_if_template.c
+ * @author MCD Application Team
+ * @brief Generic media access Layer.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * http://www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_printer_if.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_PRNT
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_PRNT_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_PRNT_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_PRNT_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_PRNT_Private_FunctionPrototypes
+ * @{
+ */
+
+static int8_t PRINTER_Init(void);
+static int8_t PRINTER_DeInit(void);
+static int8_t PRINTER_Control_req(uint8_t req, uint8_t *pbuf, uint16_t *length);
+static int8_t PRINTER_Receive(uint8_t *pbuf, uint32_t *Len);
+
+/*printer Private function prototypes*/
+void PRINTER_PageEndManager(uint8_t *Buf, uint32_t Len);
+
+USBD_PRNT_ItfTypeDef USBD_PRNT_fops = {PRINTER_Init,
+ PRINTER_DeInit,
+ PRINTER_Control_req,
+ PRINTER_Receive};
+
+static uint8_t PRNT_DEVICE_ID[] =
+ {
+ 0x00, 0x6D,
+ 'M', 'A', 'N', 'U', 'F', 'A', 'C', 'T', 'U', 'R', 'E', 'R', ':',
+ 'S', 'T', 'M', 'i', 'c', 'r', 'o', 'e', 'l', 'e', 'c', 't', 'r', 'o', 'n', 'i', 'c', 's', ';',
+ 'C', 'O', 'M', 'M', 'A', 'N', 'D', ' ', 'S', 'E', 'T', ':',
+ 'P', 'D', 'L', ',', 'P', 'C', 'P', ';',
+ 'M', 'O', 'D', 'E', 'L', ':',
+ 'U', 'S', 'B', 'P', 'r', 'i', 'n', 't', 'e', 'r', ';',
+ 'C', 'O', 'M', 'M', 'E', 'N', 'T', ':',
+ 'G', 'o', 'o', 'd', ' ', '!', ';',
+ 'A', 'C', 'T', 'I', 'V', 'E', ' ', 'C', 'O', 'M', 'M', 'A', 'N', 'D', ' ', 'S', 'E', 'T', ':',
+ 'P', 'C', 'P', ';'};
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief PRINTER_Init
+ * Initializes the PRNT media low layer
+ * @param None
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t PRINTER_Init(void)
+{
+ /*
+ Add your initialization code here
+ */
+ return (0);
+}
+
+/**
+ * @brief PRINTER_DeInit
+ * DeInitializes the PRNT media low layer
+ * @param None
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t PRINTER_DeInit(void)
+{
+ /*
+ Add your deinitialization code here
+ */
+ return (0);
+}
+
+/**
+ * @brief PRINTER_Receive
+ * Data received over USB OUT endpoint are sent over PRNT interface
+ * through this function.
+ *
+ * @note
+ * This function will issue a NAK packet on any OUT packet received on
+ * USB endpoint untill exiting this function. If you exit this function
+ * before transfer is complete on PRNT interface (ie. using DMA controller)
+ * it will result in receiving more data while previous ones are still
+ * not sent.
+ *
+ * @param Buf: Buffer of data to be received
+ * @param Len: Number of data received (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t PRINTER_Receive(uint8_t *Buf, uint32_t *Len)
+{
+ UNUSED(Buf);
+ UNUSED(Len);
+
+ return (0);
+}
+
+/**
+ * @brief PRINTER_Itf_Control_req
+ * Manage the PRNT class requests
+ * @param req: Command code
+ * @param pbuf: Buffer containing command data (request parameters)
+ * @param length: Number of data to be sent (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t PRINTER_Control_req(uint8_t req, uint8_t *pbuf, uint16_t *length)
+{
+ uint32_t i = 0;
+
+ /* Check on the setup request value */
+ switch (req)
+ {
+ /* Get Printer Device ID request */
+ case PRNT_GET_DEVICE_ID:
+ /* Not using for loop here due to MISRA-C2012-Rule-16.1 */
+ while (i < sizeof(PRNT_DEVICE_ID))
+ {
+ pbuf[i] = PRNT_DEVICE_ID[i];
+ i++;
+ }
+ *length = i;
+ break;
+
+ /* Get Printer current status */
+ case PRNT_GET_PORT_STATUS:
+ pbuf[0] = PRNT_STATUS_PAPER_EMPTY |
+ PRNT_STATUS_SELECTED |
+ PRNT_STATUS_NO_ERROR;
+
+ *length = 1U;
+ break;
+
+ /* Printer SOFT RESET request: cleanup pending tasks */
+ case PRNT_SOFT_RESET:
+ //(void)f_close(&hSD.MyFile);
+ break;
+
+ default:
+ /* Unkown commands are not managed */
+ break;
+ }
+
+ return USBD_OK;
+}
+
+/**
+* @brief PRINTER_PageEndManager, defined by user
+* Call this function frequently to check if data is received.
+* @param Buf: Buffer of data to be received
+* @param Len: Number of data received (in bytes)
+*/
+void PRINTER_PageEndManager(uint8_t *Buf, uint32_t Len)
+{
+ UNUSED(Buf);
+ UNUSED(Len);
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_printer_if.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_printer_if.h
new file mode 100644
index 0000000..a3e7f14
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_printer_if.h
@@ -0,0 +1,45 @@
+/**
+ ******************************************************************************
+ * @file usbd_printer_if_template.h
+ * @author MCD Application Team
+ * @brief Header for usbd_PRNT_if_template.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * http://www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_PRNT_IF_TEMPLATE_H
+#define __USBD_PRNT_IF_TEMPLATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_printer.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+extern USBD_PRNT_ItfTypeDef USBD_PRNT_fops;
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_PRNT_IF_TEMPLATE_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_video_if.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_video_if.c
new file mode 100644
index 0000000..cdf29e1
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_video_if.c
@@ -0,0 +1,222 @@
+/**
+ ******************************************************************************
+ * @file usbd_video_if_template.c
+ * @author MCD Application Team
+ * @brief Template file for Video Interface application layer functions
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_video_if.h"
+
+/* Include you image binary file here
+ Binary image template shall provide:
+ - tImagesList: table containing pointers to all images
+ - tImagesSizes: table containing sizes of each image respectively
+ - img_count: global image counter variable
+ - IMG_NBR: Total image number
+
+ To generate such file, it is possible to use tools converting video to MJPEG then to JPEG images.
+ */
+/* #include "img_bin.h" */
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+/* Private variables ---------------------------------------------------------*/
+
+/* USER CODE END PV */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @brief Usb device library.
+ * @{
+ */
+
+/** @addtogroup USBD_VIDEO_IF
+ * @{
+ */
+
+/** @defgroup USBD_VIDEO_IF_Private_TypesDefinitions
+ * @brief Private types.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_TYPES */
+
+/* USER CODE END PRIVATE_TYPES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_IF_Private_Defines
+ * @brief Private defines.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_DEFINES */
+
+/* USER CODE END PRIVATE_DEFINES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_IF_Private_Macros
+ * @brief Private macros.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_MACRO */
+
+/* USER CODE END PRIVATE_MACRO */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_IF_Private_Variables
+ * @brief Private variables.
+ * @{
+ */
+
+/* USER CODE BEGIN PRIVATE_VARIABLES */
+
+/* USER CODE END PRIVATE_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_IF_Exported_Variables
+ * @brief Public variables.
+ * @{
+ */
+
+
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_IF_Private_FunctionPrototypes
+ * @brief Private functions declaration.
+ * @{
+ */
+
+static int8_t VIDEO_Itf_Init(void);
+static int8_t VIDEO_Itf_DeInit(void);
+static int8_t VIDEO_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length);
+static int8_t VIDEO_Itf_Data(uint8_t **pbuf, uint16_t *psize, uint16_t *pcktidx);
+
+
+/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
+
+/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
+
+/**
+ * @}
+ */
+
+USBD_VIDEO_ItfTypeDef USBD_VIDEO_fops_FS =
+{
+ VIDEO_Itf_Init,
+ VIDEO_Itf_DeInit,
+ VIDEO_Itf_Control,
+ VIDEO_Itf_Data,
+};
+
+/* Private functions ---------------------------------------------------------*/
+/**
+ * @brief Initializes the VIDEO media low layer over USB FS IP
+ * @param VIDEOFreq: VIDEO frequency used to play the VIDEO stream.
+ * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
+ * @param options: Reserved for future use
+ * @retval USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t VIDEO_Itf_Init(void)
+{
+ /*
+ Add your initialization code here
+ */
+
+ return (0);
+}
+
+/**
+ * @brief TEMPLATE_DeInit
+ * DeInitializes the UVC media low layer
+ * @param None
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t VIDEO_Itf_DeInit(void)
+{
+ /*
+ Add your deinitialization code here
+ */
+ return (0);
+}
+
+
+/**
+ * @brief TEMPLATE_Control
+ * Manage the UVC class requests
+ * @param Cmd: Command code
+ * @param Buf: Buffer containing command data (request parameters)
+ * @param Len: Number of data to be sent (in bytes)
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t VIDEO_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
+{
+
+ return (0);
+}
+
+/**
+ * @brief TEMPLATE_Data
+ * Manage the UVC data packets
+ * @param pbuf: pointer to the buffer data to be filled
+ * @param psize: pointer tot he current packet size to be filled
+ * @param pcktidx: pointer to the current packet index in the current image
+ * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t VIDEO_Itf_Data(uint8_t **pbuf, uint16_t *psize, uint16_t *pcktidx)
+{
+
+ return (0);
+}
+
+/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
+
+/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_video_if.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_video_if.h
new file mode 100644
index 0000000..036c7aa
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/App/usbd_video_if.h
@@ -0,0 +1,142 @@
+/**
+ ******************************************************************************
+ * @file usbd_video_if_template.h
+ * @author MCD Application Team
+ * @brief Template Header file for the video Interface application layer functions
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_VIDEO_IF_H__
+#define __USBD_VIDEO_IF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_video.h"
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+ * @brief For Usb device.
+ * @{
+ */
+
+/** @defgroup USBD_VIDEO_IF
+ * @brief Usb VIDEO interface device module.
+ * @{
+ */
+
+/** @defgroup USBD_VIDEO_IF_Exported_Defines
+ * @brief Defines.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_DEFINES */
+
+/* USER CODE END EXPORTED_DEFINES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_IF_Exported_Types
+ * @brief Types.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_TYPES */
+
+/* USER CODE END EXPORTED_TYPES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_IF_Exported_Macros
+ * @brief Aliases.
+ * @{
+ */
+
+/* USER CODE BEGIN EXPORTED_MACRO */
+
+/* USER CODE END EXPORTED_MACRO */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_IF_Exported_Variables
+ * @brief Public variables.
+ * @{
+ */
+
+/** VIDEO_IF Interface callback. */
+extern USBD_VIDEO_ItfTypeDef USBD_VIDEO_fops_FS;
+
+/* USER CODE BEGIN EXPORTED_VARIABLES */
+
+/* USER CODE END EXPORTED_VARIABLES */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_IF_Exported_FunctionsPrototype
+ * @brief Public functions declaration.
+ * @{
+ */
+
+/**
+ * @brief Manages the DMA full transfer complete event.
+ * @retval None
+ */
+void TransferComplete_CallBack_FS(void);
+
+/**
+ * @brief Manages the DMA half transfer complete event.
+ * @retval None
+ */
+void HalfTransfer_CallBack_FS(void);
+
+/* USER CODE BEGIN EXPORTED_FUNCTIONS */
+
+/* USER CODE END EXPORTED_FUNCTIONS */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USBD_VIDEO_IF_H_ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_COMMON/usbd_audio.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_COMMON/usbd_audio.h
new file mode 100644
index 0000000..3c79c6e
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_COMMON/usbd_audio.h
@@ -0,0 +1,84 @@
+#ifndef _AUDIO_COMMON_USBD_AUDIO_H_
+#define _AUDIO_COMMON_USBD_AUDIO_H_
+
+#include "usbd_ioreq.h"
+
+#define AUDIO_HS_BINTERVAL 0x01U
+
+#define AUDIO_FS_BINTERVAL 0x01U
+
+
+#define AUDIO_INTERFACE_DESC_SIZE 0x09U
+#define USB_AUDIO_DESC_SIZ 0x09U
+#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09U
+#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07U
+
+#define AUDIO_DESCRIPTOR_TYPE 0x21U
+#define USB_DEVICE_CLASS_AUDIO 0x01U
+#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01U
+#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02U
+#define AUDIO_PROTOCOL_UNDEFINED 0x00U
+#define AUDIO_STREAMING_GENERAL 0x01U
+#define AUDIO_STREAMING_FORMAT_TYPE 0x02U
+
+/* Audio Descriptor Types */
+#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24U
+#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25U
+
+/* Audio Control Interface Descriptor Subtypes */
+#define AUDIO_CONTROL_HEADER 0x01U
+#define AUDIO_CONTROL_INPUT_TERMINAL 0x02U
+#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03U
+#define AUDIO_CONTROL_FEATURE_UNIT 0x06U
+
+#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0CU
+#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09U
+#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07U
+
+#define AUDIO_CONTROL_MUTE 0x0001U
+
+#define AUDIO_FORMAT_TYPE_I 0x01U
+#define AUDIO_FORMAT_TYPE_III 0x03U
+
+#define AUDIO_ENDPOINT_GENERAL 0x01U
+
+#define AUDIO_REQ_GET_CUR 0x81U
+#define AUDIO_REQ_GET_MIN 0x82
+#define AUDIO_REQ_GET_MAX 0x83
+#define AUDIO_REQ_GET_RES 0x84
+#define AUDIO_REQ_SET_CUR 0x01U
+
+#define AUDIO_STREAMING_CTRL 0x02U
+
+
+/* Audio Commands enmueration */
+typedef enum
+{
+ AUDIO_CMD_START = 1,
+ AUDIO_CMD_PLAY,
+ AUDIO_CMD_STOP,
+} AUDIO_CMD_TypeDef;
+
+typedef enum
+{
+ AUDIO_OFFSET_NONE = 0,
+ AUDIO_OFFSET_HALF,
+ AUDIO_OFFSET_FULL,
+ AUDIO_OFFSET_UNKNOWN,
+} AUDIO_OffsetTypeDef;
+
+/**
+* @}
+*/
+
+/** @defgroup USBD_AUDIO_IN_Exported_TypesDefinitions
+* @{
+*/
+typedef struct
+{
+ uint8_t cmd;
+ uint8_t data[USB_MAX_EP0_SIZE];
+ uint8_t len;
+ uint8_t unit;
+} USBD_AUDIO_ControlTypeDef;
+#endif /* _AUDIO_COMMON_USBD_AUDIO_H_ */
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_MIC/Inc/usbd_audio_mic.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_MIC/Inc/usbd_audio_mic.h
new file mode 100644
index 0000000..1d2810f
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_MIC/Inc/usbd_audio_mic.h
@@ -0,0 +1,166 @@
+/**
+******************************************************************************
+* @file usbd_audio_in.h
+* @author Central Labs
+* @version V2.4.2 MOD
+* @date 01-Sep-2016
+ * @brief header file for the usbd_audio.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_AUDIO_MIC_H_
+#define __USBD_AUDIO_MIC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+#include "usbd_audio.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_AUDIO
+ * @brief This file is the Header file for usbd_audio.c
+ * @{
+ */
+
+
+/** @defgroup USBD_AUDIO_Exported_Defines
+ * @{
+ */
+
+#define AUDIO_MIC_STR_DESC "STM32 MICROPHONE"
+
+/* AUDIO Class Config */
+#define AUDIO_MIC_CHANNELS 0x01
+#define AUDIO_MIC_SMPL_FREQ 16000U
+#define USBD_AUDIO_MIC_CONFIG_DESC_SIZE (116 + AUDIO_MIC_CHANNELS)
+
+
+
+#define AUDIO_MIC_VOL_MIN 0xDBE0
+#define AUDIO_MIC_VOL_RES 0x0023
+#define AUDIO_MIC_VOL_MAX 0x0000
+#define AUDIO_MIC_PACKET (uint32_t)((((AUDIO_MIC_SMPL_FREQ/1000)+2)*8)*2)
+#define AUDIO_MIC_TERMINAL_ID 1
+#define AUDIO_MIC_FU_ID 2
+#define AUDIO_MIC_OUT_TERMINAL_ID 3
+
+/* Buffering state definitions */
+typedef enum
+{
+ STATE_USB_WAITING_FOR_INIT = 0,
+ STATE_USB_IDLE = 1,
+ STATE_USB_REQUESTS_STARTED = 2,
+ STATE_USB_BUFFER_WRITE_STARTED = 3,
+} AUDIO_MIC_StatesTypeDef;
+
+/* Number of sub-packets in the audio transfer buffer.*/
+#define AUDIO_MIC_PACKET_NUM 20
+
+#define TIMEOUT_VALUE 200
+
+
+typedef struct
+{
+ __IO uint32_t alt_setting;
+ uint8_t channels;
+ uint32_t frequency;
+ __IO int16_t timeout;
+ uint16_t buffer_length;
+ uint16_t dataAmount;
+ uint16_t paketDimension;
+ uint8_t state;
+ uint16_t rd_ptr;
+ uint16_t wr_ptr;
+ uint8_t upper_treshold;
+ uint8_t lower_treshold;
+ USBD_AUDIO_ControlTypeDef control;
+ uint8_t *buffer;
+} USBD_AUDIO_MIC_HandleTypeDef;
+
+typedef struct
+{
+ int8_t (*Init)(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr);
+ int8_t (*DeInit)(uint32_t options);
+ int8_t (*Record)(void);
+ int8_t (*VolumeCtl)(int16_t Volume);
+ int8_t (*MuteCtl)(uint8_t cmd);
+ int8_t (*Stop)(void);
+ int8_t (*Pause)(void);
+ int8_t (*Resume)(void);
+ int8_t (*CommandMgr)(uint8_t cmd);
+} USBD_AUDIO_MIC_ItfTypeDef;
+/**
+* @}
+*/
+
+/** @defgroup USBD_AUDIO_IN_Exported_Macros
+* @{
+*/
+
+/**
+* @}
+*/
+
+/** @defgroup USBD_AUDIO_IN_Exported_Variables
+* @{
+*/
+
+extern USBD_ClassTypeDef USBD_AUDIO_MIC;
+
+extern uint8_t AUDIO_MIC_EP;
+extern uint8_t AUDIO_MIC_AC_ITF_NBR;
+extern uint8_t AUDIO_MIC_AS_ITF_NBR;
+extern uint8_t AUDIO_MIC_STR_DESC_IDX;
+
+/**
+* @}
+*/
+
+/** @defgroup USBD_AUDIO_IN_Exported_Functions
+* @{
+*/
+uint8_t USBD_AUDIO_MIC_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_AUDIO_MIC_ItfTypeDef *fops);
+uint8_t USBD_AUDIO_MIC_Data_Transfer(USBD_HandleTypeDef *pdev, int16_t *audioData, uint16_t dataAmount);
+
+ void USBD_Update_Audio_MIC_DESC(uint8_t *desc,
+ uint8_t ac_itf,
+ uint8_t as_itf,
+ uint8_t in_ep,
+ uint8_t str_idx);
+ /**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif // __USBD_AUDIO_MIC_H_
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_MIC/Src/usbd_audio_mic.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_MIC/Src/usbd_audio_mic.c
new file mode 100644
index 0000000..751bdc8
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_MIC/Src/usbd_audio_mic.c
@@ -0,0 +1,1008 @@
+/**
+ ******************************************************************************
+ * @file usbd_audio.c
+ * @author MCD Application Team
+ * @brief This file provides the Audio core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * AUDIO Class Description
+ * ===================================================================
+ * This driver manages the Audio Class 1.0 following the "USB Device Class Definition for
+ * Audio Devices V1.0 Mar 18, 98".
+* This driver implements the following aspects:
+* - Device descriptor management
+* - Configuration descriptor management
+* - Standard AC Interface Descriptor management
+* - 1 Audio Streaming Interface
+* - 1 Audio Streaming Endpoint
+* - 1 Audio Terminal Input
+* - Audio Class-Specific AC Interfaces
+* - Audio Class-Specific AS Interfaces
+* - AudioControl Requests: mute and volume control
+* - Audio Synchronization type: Asynchronous
+* - Multiple frequencies and channel number configurable using ad hoc
+* init function
+*
+* The current audio class version supports the following audio features:
+* - Pulse Coded Modulation (PCM) format
+* - Configurable sampling rate
+* - Bit resolution: 16
+* - Configurable Number of channels
+* - Volume control
+* - Mute/Unmute capability
+* - Asynchronous Endpoints
+*
+* @note This driver has been developed starting from the usbd_audio.c file
+* included within the standard Cube Package for STM32F4
+*
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "usbd_audio_mic.h"
+#include "usbd_ctlreq.h"
+
+#define _AUDIO_MIC_EP 0x81
+#define _AUDIO_MIC_AC_ITF_NBR 0x00U
+#define _AUDIO_MIC_AS_ITF_NBR 0x01U
+#define _AUDIO_MIC_STR_DESC_IDX 0x00U
+
+uint8_t AUDIO_MIC_EP = _AUDIO_MIC_EP;
+uint8_t AUDIO_MIC_AC_ITF_NBR = _AUDIO_MIC_AC_ITF_NBR;
+uint8_t AUDIO_MIC_AS_ITF_NBR = _AUDIO_MIC_AS_ITF_NBR;
+uint8_t AUDIO_MIC_STR_DESC_IDX = _AUDIO_MIC_STR_DESC_IDX;
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+* @{
+*/
+
+/** @defgroup USBD_AUDIO
+
+ * @{
+ */
+
+/** @defgroup USBD_AUDIO_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_Private_FunctionPrototypes
+ * @{
+ */
+static uint8_t USBD_AUDIO_MIC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_AUDIO_MIC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_AUDIO_MIC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static uint8_t *USBD_AUDIO_MIC_GetCfgDesc(uint16_t *length);
+static uint8_t *USBD_AUDIO_MIC_GetDeviceQualifierDesc(uint16_t *length);
+static uint8_t USBD_AUDIO_MIC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_AUDIO_MIC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_AUDIO_MIC_EP0_RxReady(USBD_HandleTypeDef *pdev);
+static uint8_t USBD_AUDIO_MIC_EP0_TxReady(USBD_HandleTypeDef *pdev);
+static uint8_t USBD_AUDIO_MIC_SOF(USBD_HandleTypeDef *pdev);
+static uint8_t USBD_AUDIO_MIC_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_AUDIO_MIC_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static void USBD_AUDIO_MIC_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static void USBD_AUDIO_MIC_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static void USBD_AUDIO_MIC_REQ_GetMaximum(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static void USBD_AUDIO_MIC_REQ_GetMinimum(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static void USBD_AUDIO_MIC_REQ_GetResolution(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_Private_Variables
+ * @{
+ */
+/* This dummy buffer with 0 values will be sent when there is no availble data */
+static uint8_t IsocInBuffDummy[48 * 4 * 2];
+static int16_t VOL_CUR;
+static USBD_AUDIO_MIC_HandleTypeDef haudioInstance;
+
+USBD_ClassTypeDef USBD_AUDIO_MIC =
+ {
+ USBD_AUDIO_MIC_Init,
+ USBD_AUDIO_MIC_DeInit,
+ USBD_AUDIO_MIC_Setup,
+ USBD_AUDIO_MIC_EP0_TxReady,
+ USBD_AUDIO_MIC_EP0_RxReady,
+ USBD_AUDIO_MIC_DataIn,
+ USBD_AUDIO_MIC_DataOut,
+ USBD_AUDIO_MIC_SOF,
+ USBD_AUDIO_MIC_IsoINIncomplete,
+ USBD_AUDIO_MIC_IsoOutIncomplete,
+ USBD_AUDIO_MIC_GetCfgDesc,
+ USBD_AUDIO_MIC_GetCfgDesc,
+ USBD_AUDIO_MIC_GetCfgDesc,
+ USBD_AUDIO_MIC_GetDeviceQualifierDesc,
+};
+
+/* USB AUDIO device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_AUDIO_MIC_CfgDesc[USBD_AUDIO_MIC_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /* Configuration 1 */
+ 0x09, /* bLength */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType */
+ LOBYTE(USBD_AUDIO_MIC_CONFIG_DESC_SIZE), /* wTotalLength: Total size of the Config descriptor */
+ HIBYTE(USBD_AUDIO_MIC_CONFIG_DESC_SIZE),
+ 0x02, /* bNumInterfaces */
+ 0x01, /* bConfigurationValue */
+ 0x00, /* iConfiguration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* bMaxPower = 100 mA */
+ /* 09 byte*/
+
+ /******** IAD to associate the two MIC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _AUDIO_MIC_AC_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ USB_DEVICE_CLASS_AUDIO, /* bFunctionClass */
+ AUDIO_SUBCLASS_AUDIOCONTROL, /* bFunctionSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+ /* 17 byte*/
+
+ /* USB Microphone Standard interface descriptor */
+ AUDIO_INTERFACE_DESC_SIZE, /* bLength */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
+ _AUDIO_MIC_AC_ITF_NBR, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x00, /* bNumEndpoints */
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
+ AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ _AUDIO_MIC_STR_DESC_IDX, /* iInterface */
+ /* 26 byte*/
+
+ /* USB Microphone Class-specific AC Interface Descriptor */
+ AUDIO_INTERFACE_DESC_SIZE, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */
+ 0x00, /* 1.00 */ /* bcdADC */
+ 0x01,
+ 0x25 + AUDIO_MIC_CHANNELS, /* wTotalLength = 37+AUDIO_CHANNELS*/
+ 0x00,
+ 0x01, /* bInCollection */
+ _AUDIO_MIC_AS_ITF_NBR, /* baInterfaceNr */
+ /* 35 byte*/
+
+ /* USB Microphone Input Terminal Descriptor */
+ AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */
+ AUDIO_MIC_TERMINAL_ID, /* bTerminalID */
+ 0x01, /* wTerminalType AUDIO_TERMINAL_USB_MICROPHONE 0x0201 */
+ 0x02,
+ 0x00, /* bAssocTerminal */
+ AUDIO_MIC_CHANNELS, /* bNrChannels */
+#if (AUDIO_MIC_CHANNELS == 1)
+ 0x00, /* wChannelConfig 0x0000 Mono */
+ 0x00,
+#else
+ 0x03, /* wChannelConfig 0x0003 Stereo */
+ 0x00,
+#endif
+ 0x00, /* iChannelNames */
+ 0x00, /* iTerminal */
+ /* 47 byte*/
+
+ /* USB Microphone Audio Feature Unit Descriptor */
+ 0x07 + AUDIO_MIC_CHANNELS + 1, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */
+ AUDIO_MIC_FU_ID, /* bUnitID */
+ 0x01, /* bSourceID */
+ 0x01, /* bControlSize */
+
+#if (AUDIO_MIC_CHANNELS == 1)
+ 0x02,
+ 0x00,
+#else
+ 0x00,
+ 0x02,
+ 0x02,
+#endif
+
+#if (AUDIO_MIC_CHANNELS > 2)
+ 0x02,
+#endif
+
+#if (AUDIO_MIC_CHANNELS > 3)
+ 0x02,
+#endif
+
+#if (AUDIO_MIC_CHANNELS > 4)
+ 0x02,
+#endif
+
+#if (AUDIO_MIC_CHANNELS > 5)
+ 0x02,
+#endif
+
+#if (AUDIO_MIC_CHANNELS > 6)
+ 0x02,
+#endif
+
+#if (AUDIO_MIC_CHANNELS > 7)
+ 0x02,
+#endif
+ 0x00, /* iTerminal */
+ //55 + AUDIO_MIC_CHANNELS byte
+
+ /*USB Microphone Output Terminal Descriptor */
+ 0x09, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */
+ AUDIO_MIC_OUT_TERMINAL_ID, /* bTerminalID */
+ 0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101*/
+ 0x01,
+ 0x00,
+ 0x02,
+ 0x00,
+ //64 + AUDIO_MIC_CHANNELS byte
+
+ /* USB Microphone Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */
+ /* Interface 1, Alternate Setting 0 */
+ 0x09, /* bLength */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
+ _AUDIO_MIC_AS_ITF_NBR, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x00, /* bNumEndpoints */
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
+ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+ //73 + AUDIO_MIC_CHANNELS byte
+
+ /* USB Microphone Standard AS Interface Descriptor - Audio Streaming Operational */
+ /* Interface 1, Alternate Setting 1 */
+ 0x09, /* bLength */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
+ _AUDIO_MIC_AS_ITF_NBR, /* bInterfaceNumber */
+ 0x01, /* bAlternateSetting */
+ 0x01, /* bNumEndpoints */
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
+ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+ //82 + AUDIO_MIC_CHANNELS byte
+
+ /* USB Microphone Audio Streaming Interface Descriptor */
+ AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
+ 0x03, /* bTerminalLink */
+ 0x01, /* bDelay */
+ 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/
+ 0x00,
+ //89 + AUDIO_MIC_CHANNELS byte
+
+ /* USB Microphone Audio Type I Format Interface Descriptor */
+ 0x0B, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
+ AUDIO_FORMAT_TYPE_I, /* bFormatType */
+ AUDIO_MIC_CHANNELS, /* bNrChannels */
+ 0x02, /* bSubFrameSize */
+ 16, /* bBitResolution */
+ 0x01, /* bSamFreqType */
+ AUDIO_MIC_SMPL_FREQ & 0xff, /* tSamFreq 8000 = 0x1F40 */
+ (AUDIO_MIC_SMPL_FREQ >> 8) & 0xff,
+ AUDIO_MIC_SMPL_FREQ >> 16,
+ //100 + AUDIO_MIC_CHANNELS byte
+
+ /* Endpoint 1 - Standard Descriptor */
+ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
+ 0x05, /* bDescriptorType */
+ _AUDIO_MIC_EP, /* bEndpointAddress 1 in endpoint*/
+ 0x05, /* bmAttributes */
+ ((AUDIO_MIC_SMPL_FREQ / 1000 + 2) * AUDIO_MIC_CHANNELS * 2) & 0xFF, /* wMaxPacketSize */
+ ((AUDIO_MIC_SMPL_FREQ / 1000 + 2) * AUDIO_MIC_CHANNELS * 2) >> 8,
+ 0x01, /* bInterval */
+ 0x00, /* bRefresh */
+ 0x00, /* bSynchAddress */
+ //109 + AUDIO_MIC_CHANNELS byte
+
+ /* Endpoint - Audio Streaming Descriptor*/
+ AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */
+ AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_ENDPOINT_GENERAL, /* bDescriptor */
+ 0x00, /* bmAttributes */
+ 0x00, /* bLockDelayUnits */
+ 0x00, /* wLockDelay */
+ 0x00,
+ //116 + AUDIO_MIC_CHANNELS byte
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_AUDIO_MIC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_AUDIO_Init
+ * Initialize the AUDIO interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_MIC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ if (haudioInstance.state != STATE_USB_WAITING_FOR_INIT)
+ {
+ return USBD_FAIL;
+ }
+
+ USBD_AUDIO_MIC_HandleTypeDef *haudio;
+ pdev->pClassData_UAC_MIC = &haudioInstance;
+ haudio = (USBD_AUDIO_MIC_HandleTypeDef *)pdev->pClassData_UAC_MIC;
+ if (haudio->paketDimension == 0)
+ {
+ haudio->paketDimension = 1;
+ }
+ uint16_t packet_dim = haudio->paketDimension;
+ uint16_t wr_rd_offset = (AUDIO_MIC_PACKET_NUM / 2) * haudio->dataAmount / haudio->paketDimension;
+ haudio->wr_ptr = wr_rd_offset * packet_dim;
+ haudio->rd_ptr = 0;
+ haudio->timeout = 0;
+
+ ((USBD_AUDIO_MIC_ItfTypeDef *)pdev->pUserData_UAC_MIC)->Init(haudio->frequency, 0, haudio->channels);
+
+ USBD_LL_OpenEP(pdev,
+ AUDIO_MIC_EP,
+ USBD_EP_TYPE_ISOC,
+ AUDIO_MIC_PACKET);
+
+ USBD_LL_FlushEP(pdev, AUDIO_MIC_EP);
+
+ USBD_LL_Transmit(pdev, AUDIO_MIC_EP,
+ IsocInBuffDummy,
+ packet_dim);
+
+ haudio->state = STATE_USB_IDLE;
+ return USBD_OK;
+}
+
+/**
+ * @brief USBD_AUDIO_Init
+ * DeInitialize the AUDIO layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_MIC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ /* Close EP IN */
+ USBD_LL_CloseEP(pdev, AUDIO_MIC_EP);
+ /* DeInit physical Interface components */
+ if (pdev->pClassData_UAC_MIC != NULL)
+ {
+ ((USBD_AUDIO_MIC_ItfTypeDef *)pdev->pUserData_UAC_MIC)->DeInit(0);
+ haudioInstance.state = STATE_USB_WAITING_FOR_INIT;
+ }
+ return USBD_OK;
+}
+
+/**
+ * @brief USBD_AUDIO_Setup
+ * Handle the AUDIO specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_MIC_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req)
+{
+ USBD_AUDIO_MIC_HandleTypeDef *haudio;
+ uint16_t len;
+ uint8_t *pbuf;
+ uint16_t status_info = 0U;
+ USBD_StatusTypeDef ret = USBD_OK;
+
+ haudio = (USBD_AUDIO_MIC_HandleTypeDef *)pdev->pClassData_UAC_MIC;
+
+ if (haudio == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS:
+ switch (req->bRequest)
+ {
+ case AUDIO_REQ_GET_CUR:
+ USBD_AUDIO_MIC_REQ_GetCurrent(pdev, req);
+ break;
+
+ case AUDIO_REQ_SET_CUR:
+ USBD_AUDIO_MIC_REQ_SetCurrent(pdev, req);
+ break;
+
+ case AUDIO_REQ_GET_MIN:
+ USBD_AUDIO_MIC_REQ_GetMinimum(pdev, req);
+ break;
+
+ case AUDIO_REQ_GET_MAX:
+ USBD_AUDIO_MIC_REQ_GetMaximum(pdev, req);
+ break;
+
+ case AUDIO_REQ_GET_RES:
+ USBD_AUDIO_MIC_REQ_GetResolution(pdev, req);
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_DESCRIPTOR:
+ if ((req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE)
+ {
+
+ pbuf = USBD_AUDIO_MIC_CfgDesc + 18;
+ len = MIN(USBD_AUDIO_MIC_CONFIG_DESC_SIZE, req->wLength);
+
+ (void)USBD_CtlSendData(pdev, pbuf, len);
+ }
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&haudio->alt_setting, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ if ((uint8_t)(req->wValue) <= USBD_MAX_NUM_INTERFACES)
+ {
+ haudio->alt_setting = (uint8_t)(req->wValue);
+ }
+ else
+ {
+ /* Call the error management function (command will be NAKed */
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_AUDIO_GetCfgDesc
+ * return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_AUDIO_MIC_GetCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_AUDIO_MIC_CfgDesc);
+
+ return USBD_AUDIO_MIC_CfgDesc;
+}
+
+uint16_t app;
+uint16_t rd_ptr;
+uint16_t wr_ptr;
+/**
+ * @brief USBD_AUDIO_DataIn
+ * handle data IN Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_MIC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+
+ USBD_AUDIO_MIC_HandleTypeDef *haudio;
+
+ haudio = pdev->pClassData_UAC_MIC;
+
+ rd_ptr = haudio->rd_ptr;
+ wr_ptr = haudio->wr_ptr;
+
+ uint32_t length_usb_pck;
+ // uint16_t app;
+ uint16_t IsocInWr_app = haudio->wr_ptr;
+ uint16_t true_dim = haudio->buffer_length;
+ uint16_t packet_dim = haudio->paketDimension;
+ uint16_t channels = haudio->channels;
+ length_usb_pck = packet_dim;
+ haudio->timeout = 0;
+ if (epnum == (AUDIO_MIC_EP & 0x7F))
+ {
+ if (haudio->state == STATE_USB_IDLE)
+ {
+ haudio->state = STATE_USB_REQUESTS_STARTED;
+ ((USBD_AUDIO_MIC_ItfTypeDef *)pdev->pUserData_UAC_MIC)->Record();
+ }
+ if (haudio->state == STATE_USB_BUFFER_WRITE_STARTED)
+ {
+ haudio->rd_ptr = haudio->rd_ptr % (true_dim);
+ if (IsocInWr_app < haudio->rd_ptr)
+ {
+ app = ((true_dim)-haudio->rd_ptr) + IsocInWr_app;
+ }
+ else
+ {
+ app = IsocInWr_app - haudio->rd_ptr;
+ }
+ if (app >= (packet_dim * haudio->upper_treshold))
+ {
+ length_usb_pck += channels * 2;
+ }
+ else if (app <= (packet_dim * haudio->lower_treshold))
+ {
+ length_usb_pck -= channels * 2;
+ }
+ USBD_LL_Transmit(pdev, AUDIO_MIC_EP,
+ (uint8_t *)(&haudio->buffer[haudio->rd_ptr]),
+ length_usb_pck);
+ haudio->rd_ptr += length_usb_pck;
+
+ if (app < haudio->buffer_length / 10)
+ {
+ ((USBD_AUDIO_MIC_ItfTypeDef *)pdev->pUserData_UAC_MIC)->Stop();
+ haudio->state = STATE_USB_IDLE;
+ haudio->timeout = 0;
+ memset(haudio->buffer, 0, (haudio->buffer_length + haudio->dataAmount));
+ }
+ }
+ else
+ {
+ USBD_LL_Transmit(pdev, AUDIO_MIC_EP,
+ IsocInBuffDummy,
+ length_usb_pck);
+ }
+ }
+ return USBD_OK;
+}
+
+/**
+* @brief USBD_AUDIO_EP0_RxReady
+* handle EP0 Rx Ready event
+* @param pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_AUDIO_MIC_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+ USBD_AUDIO_MIC_HandleTypeDef *haudio;
+ haudio = pdev->pClassData_UAC_MIC;
+ if (haudio->control.cmd == AUDIO_REQ_SET_CUR)
+ {
+ if (haudio->control.unit == AUDIO_STREAMING_CTRL)
+ {
+ ((USBD_AUDIO_MIC_ItfTypeDef *)pdev->pUserData_UAC_MIC)->VolumeCtl(VOL_CUR);
+
+ haudio->control.cmd = 0;
+ haudio->control.len = 0;
+ haudio->control.unit = 0;
+ haudio->control.data[0] = 0;
+ haudio->control.data[0] = 0;
+ }
+ }
+ return USBD_OK;
+}
+/**
+* @brief USBD_AUDIO_EP0_TxReady
+* handle EP0 TRx Ready event
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_AUDIO_MIC_EP0_TxReady(USBD_HandleTypeDef *pdev)
+{
+ /* Only OUT control data are processed */
+ return USBD_OK;
+}
+/**
+* @brief USBD_AUDIO_SOF
+* handle SOF event
+* @param pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_AUDIO_MIC_SOF(USBD_HandleTypeDef *pdev)
+{
+ return USBD_OK;
+}
+
+/**
+ * @brief USBD_AUDIO_IsoINIncomplete
+ * handle data ISO IN Incomplete event
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_MIC_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(pdev);
+ UNUSED(epnum);
+
+ return (uint8_t)USBD_OK;
+}
+/**
+ * @brief USBD_AUDIO_IsoOutIncomplete
+ * handle data ISO OUT Incomplete event
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_MIC_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(pdev);
+ UNUSED(epnum);
+
+ return (uint8_t)USBD_OK;
+}
+/**
+* @brief USBD_AUDIO_DataOut
+* handle data OUT Stage
+* @param pdev: device instance
+* @param epnum: endpoint index
+* @retval status
+*/
+static uint8_t USBD_AUDIO_MIC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ return USBD_OK;
+}
+
+/**
+* @brief DeviceQualifierDescriptor
+* return Device Qualifier descriptor
+* @param length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+static uint8_t *USBD_AUDIO_MIC_GetDeviceQualifierDesc(uint16_t *length)
+{
+ *length = sizeof(USBD_AUDIO_MIC_DeviceQualifierDesc);
+ return USBD_AUDIO_MIC_DeviceQualifierDesc;
+}
+
+/**
+* @brief AUDIO_REQ_GetMaximum
+* Handles the VOL_MAX Audio control request.
+* @param pdev: instance
+* @param req: setup class request
+* @retval status
+*/
+static void USBD_AUDIO_MIC_REQ_GetMaximum(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_AUDIO_MIC_HandleTypeDef *haudio;
+ haudio = pdev->pClassData_UAC_MIC;
+
+ (haudio->control.data)[0] = (uint16_t)AUDIO_MIC_VOL_MAX & 0xFF;
+ (haudio->control.data)[1] = ((uint16_t)AUDIO_MIC_VOL_MAX & 0xFF00) >> 8;
+
+ USBD_CtlSendData(pdev,
+ haudio->control.data,
+ req->wLength);
+}
+
+/**
+* @brief AUDIO_REQ_GetMinimum
+* Handles the VOL_MIN Audio control request.
+* @param pdev: instance
+* @param req: setup class request
+* @retval status
+*/
+static void USBD_AUDIO_MIC_REQ_GetMinimum(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_AUDIO_MIC_HandleTypeDef *haudio;
+ haudio = pdev->pClassData_UAC_MIC;
+ (haudio->control.data)[0] = (uint16_t)AUDIO_MIC_VOL_MIN & 0xFF;
+ (haudio->control.data)[1] = ((uint16_t)AUDIO_MIC_VOL_MIN & 0xFF00) >> 8;
+ /* Send the current mute state */
+ USBD_CtlSendData(pdev,
+ haudio->control.data,
+ req->wLength);
+}
+
+/**
+* @brief AUDIO_Req_GetResolution
+* Handles the VOL_RES Audio control request.
+* @param pdev: instance
+* @param req: setup class request
+* @retval status
+*/
+static void USBD_AUDIO_MIC_REQ_GetResolution(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_AUDIO_MIC_HandleTypeDef *haudio;
+ haudio = pdev->pClassData_UAC_MIC;
+ (haudio->control.data)[0] = (uint16_t)AUDIO_MIC_VOL_RES & 0xFF;
+ (haudio->control.data)[1] = ((uint16_t)AUDIO_MIC_VOL_RES & 0xFF00) >> 8;
+ USBD_CtlSendData(pdev,
+ haudio->control.data,
+ req->wLength);
+}
+
+/**
+* @brief AUDIO_Req_GetCurrent
+* Handles the GET_CUR Audio control request.
+* @param pdev: instance
+* @param req: setup class request
+* @retval status
+*/
+static void USBD_AUDIO_MIC_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_AUDIO_MIC_HandleTypeDef *haudio;
+ haudio = pdev->pClassData_UAC_MIC;
+
+ (haudio->control.data)[0] = (uint16_t)VOL_CUR & 0xFF;
+ (haudio->control.data)[1] = ((uint16_t)VOL_CUR & 0xFF00) >> 8;
+
+ USBD_CtlSendData(pdev,
+ haudio->control.data,
+ req->wLength);
+}
+
+/**
+* @brief AUDIO_Req_SetCurrent
+* Handles the SET_CUR Audio control request.
+* @param pdev: instance
+* @param req: setup class request
+* @retval status
+*/
+static void USBD_AUDIO_MIC_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_AUDIO_MIC_HandleTypeDef *haudio;
+ haudio = pdev->pClassData_UAC_MIC;
+ if (req->wLength)
+ {
+ /* Prepare the reception of the buffer over EP0 */
+ USBD_CtlPrepareRx(pdev,
+ (uint8_t *)&VOL_CUR,
+ req->wLength);
+
+ haudio->control.cmd = AUDIO_REQ_SET_CUR; /* Set the request value */
+ haudio->control.len = req->wLength; /* Set the request data length */
+ haudio->control.unit = HIBYTE(req->wIndex); /* Set the request target unit */
+ }
+}
+
+/**
+* @}
+*/
+
+/** @defgroup USBD_AUDIO_IN_Exported_Functions
+* @{
+*/
+
+/**
+* @brief USBD_AUDIO_Data_Transfer
+* Fills the USB internal buffer with audio data from user
+* @param pdev: device instance
+* @param audioData: audio data to be sent via USB
+* @param dataAmount: number of PCM samples to be copyed
+* @note Depending on the calling frequency, a coherent amount of samples must be passed to
+* the function. E.g.: assuming a Sampling frequency of 16 KHz and 1 channel,
+* you can pass 16 PCM samples if the function is called each millisecond,
+* 32 samples if called every 2 milliseconds and so on.
+* @retval status
+*/
+uint8_t USBD_AUDIO_MIC_Data_Transfer(USBD_HandleTypeDef *pdev, int16_t *audioData, uint16_t PCMSamples)
+{
+
+ USBD_AUDIO_MIC_HandleTypeDef *haudio;
+ haudio = (USBD_AUDIO_MIC_HandleTypeDef *)pdev->pClassData_UAC_MIC;
+
+ if (haudioInstance.state == STATE_USB_WAITING_FOR_INIT)
+ {
+ return USBD_BUSY;
+ }
+ uint16_t dataAmount = PCMSamples * 2; /*Bytes*/
+ uint16_t true_dim = haudio->buffer_length;
+ uint16_t current_data_Amount = haudio->dataAmount;
+ uint16_t packet_dim = haudio->paketDimension;
+
+ if (haudio->state == STATE_USB_REQUESTS_STARTED || current_data_Amount != dataAmount)
+ {
+ /*USB parameters definition, based on the amount of data passed*/
+ haudio->dataAmount = dataAmount;
+ uint16_t wr_rd_offset = (AUDIO_MIC_PACKET_NUM / 2) * dataAmount / packet_dim;
+ haudio->wr_ptr = wr_rd_offset * packet_dim;
+ haudio->rd_ptr = 0;
+ haudio->upper_treshold = wr_rd_offset + 1;
+ haudio->lower_treshold = wr_rd_offset - 1;
+ haudio->buffer_length = (packet_dim * (dataAmount / packet_dim) * AUDIO_MIC_PACKET_NUM);
+
+ /*Memory allocation for data buffer, depending (also) on data amount passed to the transfer function*/
+ if (haudio->buffer != NULL)
+ {
+ USBD_free(haudio->buffer);
+ }
+ haudio->buffer = USBD_malloc(haudio->buffer_length + haudio->dataAmount);
+ if (haudio->buffer == NULL)
+ {
+ return USBD_FAIL;
+ }
+ memset(haudio->buffer, 0, (haudio->buffer_length + haudio->dataAmount));
+ haudio->state = STATE_USB_BUFFER_WRITE_STARTED;
+ }
+ else if (haudio->state == STATE_USB_BUFFER_WRITE_STARTED)
+ {
+ if (haudio->timeout++ == TIMEOUT_VALUE)
+ {
+ haudio->state = STATE_USB_IDLE;
+ ((USBD_AUDIO_MIC_ItfTypeDef *)pdev->pUserData_UAC_MIC)->Stop();
+ haudio->timeout = 0;
+ }
+ memcpy((uint8_t *)&haudio->buffer[haudio->wr_ptr], (uint8_t *)(audioData), dataAmount);
+ haudio->wr_ptr += dataAmount;
+ haudio->wr_ptr = haudio->wr_ptr % (true_dim);
+ if ((haudio->wr_ptr - dataAmount) == 0)
+ {
+ memcpy((uint8_t *)(((uint8_t *)haudio->buffer) + true_dim), (uint8_t *)haudio->buffer, dataAmount);
+ }
+ }
+ return USBD_OK;
+}
+
+/**
+ * @brief USBD_AUDIO_RegisterInterface
+ * @param fops: Audio interface callback
+ * @retval status
+ */
+uint8_t USBD_AUDIO_MIC_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_AUDIO_MIC_ItfTypeDef *fops)
+{
+ if (fops == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ pdev->pUserData_UAC_MIC = fops;
+
+ return (uint8_t)USBD_OK;
+}
+
+void USBD_Update_Audio_MIC_DESC(uint8_t *desc,
+ uint8_t ac_itf,
+ uint8_t as_itf,
+ uint8_t in_ep,
+ uint8_t str_idx)
+{
+ desc[11] = ac_itf;
+ desc[19] = ac_itf;
+ desc[25] = str_idx;
+ desc[34] = as_itf;
+ desc[66 + AUDIO_MIC_CHANNELS] = as_itf;
+ desc[75 + AUDIO_MIC_CHANNELS] = as_itf;
+ desc[102 + AUDIO_MIC_CHANNELS] = in_ep;
+
+ AUDIO_MIC_EP = in_ep;
+ AUDIO_MIC_AC_ITF_NBR = ac_itf;
+ AUDIO_MIC_AS_ITF_NBR = as_itf;
+
+ AUDIO_MIC_STR_DESC_IDX = str_idx;
+
+ haudioInstance.paketDimension = (AUDIO_MIC_SMPL_FREQ / 1000 * AUDIO_MIC_CHANNELS * 2);
+ haudioInstance.frequency = AUDIO_MIC_SMPL_FREQ;
+ haudioInstance.buffer_length = haudioInstance.paketDimension * AUDIO_MIC_PACKET_NUM;
+ haudioInstance.channels = AUDIO_MIC_CHANNELS;
+ haudioInstance.upper_treshold = 5;
+ haudioInstance.lower_treshold = 2;
+ haudioInstance.state = STATE_USB_WAITING_FOR_INIT;
+ haudioInstance.wr_ptr = 3 * haudioInstance.paketDimension;
+ haudioInstance.rd_ptr = 0;
+ haudioInstance.dataAmount = 0;
+ haudioInstance.buffer = 0;
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_SPKR/Inc/usbd_audio_spkr.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_SPKR/Inc/usbd_audio_spkr.h
new file mode 100644
index 0000000..fe0d696
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_SPKR/Inc/usbd_audio_spkr.h
@@ -0,0 +1,143 @@
+/**
+ ******************************************************************************
+ * @file usbd_audio.h
+ * @author MCD Application Team
+ * @brief header file for the usbd_audio.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_AUDIO_SPKR_H
+#define __USB_AUDIO_SPKR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+#include "usbd_audio.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_AUDIO
+ * @brief This file is the Header file for usbd_audio.c
+ * @{
+ */
+
+
+/** @defgroup USBD_AUDIO_Exported_Defines
+ * @{
+ */
+
+#define AUDIO_SPKR_STR_DESC "STM32 SPEAKER"
+
+#define USBD_AUDIO_FREQ 16000U
+
+#define USBD_AUDIO_SPKR_CONFIG_DESC_SIZE 117
+
+#define AUDIO_OUT_TC 0x01U
+#define AUDIO_IN_TC 0x02U
+
+
+#define AUDIO_OUT_PACKET (uint16_t)(((USBD_AUDIO_FREQ * 2U * 2U) / 1000U))
+#define AUDIO_DEFAULT_VOLUME 70U
+
+/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure
+ that it is an even number and higher than 3 */
+#define AUDIO_OUT_PACKET_NUM 80U
+/* Total size of the audio transfer buffer */
+#define AUDIO_TOTAL_BUF_SIZE ((uint16_t)(AUDIO_OUT_PACKET * AUDIO_OUT_PACKET_NUM))
+
+ typedef struct
+ {
+ uint32_t alt_setting;
+ uint8_t buffer[AUDIO_TOTAL_BUF_SIZE];
+ AUDIO_OffsetTypeDef offset;
+ uint8_t rd_enable;
+ uint16_t rd_ptr;
+ uint16_t wr_ptr;
+ USBD_AUDIO_ControlTypeDef control;
+ } USBD_AUDIO_SPKR_HandleTypeDef;
+
+ typedef struct
+ {
+ int8_t (*Init)(uint32_t AudioFreq, uint32_t Volume, uint32_t options);
+ int8_t (*DeInit)(uint32_t options);
+ int8_t (*AudioCmd)(uint8_t *pbuf, uint32_t size, uint8_t cmd);
+ int8_t (*VolumeCtl)(uint8_t vol);
+ int8_t (*MuteCtl)(uint8_t cmd);
+ int8_t (*PeriodicTC)(uint8_t *pbuf, uint32_t size, uint8_t cmd);
+ int8_t (*GetState)(void);
+ } USBD_AUDIO_SPKR_ItfTypeDef;
+ /**
+ * @}
+ */
+
+ /** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+ /**
+ * @}
+ */
+
+ /** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+ extern USBD_ClassTypeDef USBD_AUDIO_SPKR;
+
+ extern uint8_t AUDIO_SPKR_EP;
+ extern uint8_t AUDIO_SPKR_AC_ITF_NBR;
+ extern uint8_t AUDIO_SPKR_AS_ITF_NBR;
+ extern uint8_t AUDIO_SPKR_STR_DESC_IDX;
+
+ /**
+ * @}
+ */
+
+ /** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+ uint8_t USBD_AUDIO_SPKR_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_AUDIO_SPKR_ItfTypeDef *fops);
+
+ void USBD_AUDIO_SPKR_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset);
+
+ void USBD_Update_Audio_SPKR_DESC(uint8_t *desc,
+ uint8_t ac_itf,
+ uint8_t as_itf,
+ uint8_t out_ep,
+ uint8_t str_idx);
+ /**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_AUDIO_SPKR_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_SPKR/Src/usbd_audio_spkr.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_SPKR/Src/usbd_audio_spkr.c
new file mode 100644
index 0000000..2fdf361
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/AUDIO_SPKR/Src/usbd_audio_spkr.c
@@ -0,0 +1,895 @@
+/**
+ ******************************************************************************
+ * @file usbd_audio.c
+ * @author MCD Application Team
+ * @brief This file provides the Audio core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * AUDIO Class Description
+ * ===================================================================
+ * This driver manages the Audio Class 1.0 following the "USB Device Class Definition for
+ * Audio Devices V1.0 Mar 18, 98".
+ * This driver implements the following aspects of the specification:
+ * - Device descriptor management
+ * - Configuration descriptor management
+ * - Standard AC Interface Descriptor management
+ * - 1 Audio Streaming Interface (with single channel, PCM, Stereo mode)
+ * - 1 Audio Streaming Endpoint
+ * - 1 Audio Terminal Input (1 channel)
+ * - Audio Class-Specific AC Interfaces
+ * - Audio Class-Specific AS Interfaces
+ * - AudioControl Requests: only SET_CUR and GET_CUR requests are supported (for Mute)
+ * - Audio Feature Unit (limited to Mute control)
+ * - Audio Synchronization type: Asynchronous
+ * - Single fixed audio sampling rate (configurable in usbd_conf.h file)
+ * The current audio class version supports the following audio features:
+ * - Pulse Coded Modulation (PCM) format
+ * - sampling rate: 48KHz.
+ * - Bit resolution: 16
+ * - Number of channels: 2
+ * - No volume control
+ * - Mute/Unmute capability
+ * - Asynchronous Endpoints
+ *
+ * @note In HS mode and when the DMA is used, all variables and data structures
+ * dealing with the DMA during the transaction process should be 32-bit aligned.
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "usbd_audio_spkr.h"
+#include "usbd_ctlreq.h"
+
+#define _AUDIO_SPKR_EP 0x01U
+#define _AUDIO_SPKR_AC_ITF_NBR 0x00U
+#define _AUDIO_SPKR_AS_ITF_NBR 0x01U
+#define _AUDIO_SPKR_STR_DESC_IDX 0x00U
+
+uint8_t AUDIO_SPKR_EP = _AUDIO_SPKR_EP;
+uint8_t AUDIO_SPKR_AC_ITF_NBR = _AUDIO_SPKR_AC_ITF_NBR;
+uint8_t AUDIO_SPKR_AS_ITF_NBR = _AUDIO_SPKR_AS_ITF_NBR;
+uint8_t AUDIO_SPKR_STR_DESC_IDX = _AUDIO_SPKR_STR_DESC_IDX;
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+* @{
+*/
+
+/** @defgroup USBD_AUDIO
+
+ * @{
+ */
+
+/** @defgroup USBD_AUDIO_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_Private_Macros
+ * @{
+ */
+#define AUDIO_SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
+
+#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2U * 2U) / 1000U) & 0xFFU), \
+ (uint8_t)((((frq * 2U * 2U) / 1000U) >> 8) & 0xFFU)
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_Private_FunctionPrototypes
+ * @{
+ */
+static uint8_t USBD_AUDIO_SPKR_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_AUDIO_SPKR_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_AUDIO_SPKR_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static uint8_t *USBD_AUDIO_SPKR_GetCfgDesc(uint16_t *length);
+static uint8_t *USBD_AUDIO_SPKR_GetDeviceQualifierDesc(uint16_t *length);
+static uint8_t USBD_AUDIO_SPKR_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_AUDIO_SPKR_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_AUDIO_SPKR_EP0_RxReady(USBD_HandleTypeDef *pdev);
+static uint8_t USBD_AUDIO_SPKR_EP0_TxReady(USBD_HandleTypeDef *pdev);
+static uint8_t USBD_AUDIO_SPKR_SOF(USBD_HandleTypeDef *pdev);
+static uint8_t USBD_AUDIO_SPKR_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_AUDIO_SPKR_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static void USBD_AUDIO_SPKR_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static void USBD_AUDIO_SPKR_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_Private_Variables
+ * @{
+ */
+
+static USBD_AUDIO_SPKR_HandleTypeDef haudioInstance;
+
+USBD_ClassTypeDef USBD_AUDIO_SPKR =
+ {
+ USBD_AUDIO_SPKR_Init,
+ USBD_AUDIO_SPKR_DeInit,
+ USBD_AUDIO_SPKR_Setup,
+ USBD_AUDIO_SPKR_EP0_TxReady,
+ USBD_AUDIO_SPKR_EP0_RxReady,
+ USBD_AUDIO_SPKR_DataIn,
+ USBD_AUDIO_SPKR_DataOut,
+ USBD_AUDIO_SPKR_SOF,
+ USBD_AUDIO_SPKR_IsoINIncomplete,
+ USBD_AUDIO_SPKR_IsoOutIncomplete,
+ USBD_AUDIO_SPKR_GetCfgDesc,
+ USBD_AUDIO_SPKR_GetCfgDesc,
+ USBD_AUDIO_SPKR_GetCfgDesc,
+ USBD_AUDIO_SPKR_GetDeviceQualifierDesc,
+};
+
+/* USB AUDIO device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_AUDIO_SPKR_CfgDesc[USBD_AUDIO_SPKR_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /* Configuration 1 */
+ 0x09, /* bLength */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType */
+ LOBYTE(USBD_AUDIO_SPKR_CONFIG_DESC_SIZE), /* wTotalLength 109 bytes*/
+ HIBYTE(USBD_AUDIO_SPKR_CONFIG_DESC_SIZE),
+ 0x02, /* bNumInterfaces */
+ 0x01, /* bConfigurationValue */
+ 0x00, /* iConfiguration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* bMaxPower = 100 mA */
+ /* 09 byte*/
+
+ /******** IAD to associate the two SPKR interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _AUDIO_SPKR_AC_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ USB_DEVICE_CLASS_AUDIO, /* bFunctionClass */
+ AUDIO_SUBCLASS_AUDIOCONTROL, /* bFunctionSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* USB Speaker Standard interface descriptor */
+ AUDIO_INTERFACE_DESC_SIZE, /* bLength */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
+ _AUDIO_SPKR_AC_ITF_NBR, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x00, /* bNumEndpoints */
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
+ AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ _AUDIO_SPKR_STR_DESC_IDX, /* iInterface */
+ /* 09 byte*/
+
+ /* USB Speaker Class-specific AC Interface Descriptor */
+ AUDIO_INTERFACE_DESC_SIZE, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */
+ 0x00, /* 1.00 */ /* bcdADC */
+ 0x01,
+ 0x27, /* wTotalLength = 39*/
+ 0x00,
+ 0x01, /* bInCollection */
+ _AUDIO_SPKR_AS_ITF_NBR, /* baInterfaceNr */
+ /* 09 byte*/
+
+ /* USB Speaker Input Terminal Descriptor */
+ AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */
+ 0x01, /* bTerminalID */
+ 0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */
+ 0x01,
+ 0x00, /* bAssocTerminal */
+ 0x01, /* bNrChannels */
+ 0x00, /* wChannelConfig 0x0000 Mono */
+ 0x00,
+ 0x00, /* iChannelNames */
+ 0x00, /* iTerminal */
+ /* 12 byte*/
+
+ /* USB Speaker Audio Feature Unit Descriptor */
+ 0x09, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */
+ AUDIO_STREAMING_CTRL, /* bUnitID */
+ 0x01, /* bSourceID */
+ 0x01, /* bControlSize */
+ AUDIO_CONTROL_MUTE, /* bmaControls(0) */
+ 0x00, /* bmaControls(1) */
+ 0x00, /* iTerminal */
+ /* 09 byte*/
+
+ /*USB Speaker Output Terminal Descriptor */
+ 0x09, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */
+ 0x03, /* bTerminalID */
+ 0x01, /* wTerminalType 0x0301*/
+ 0x03,
+ 0x00, /* bAssocTerminal */
+ 0x02, /* bSourceID */
+ 0x00, /* iTerminal */
+ /* 09 byte*/
+
+ /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwidth */
+ /* Interface 1, Alternate Setting 0 */
+ AUDIO_INTERFACE_DESC_SIZE, /* bLength */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
+ _AUDIO_SPKR_AS_ITF_NBR, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x00, /* bNumEndpoints */
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
+ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+ /* 09 byte*/
+
+ /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */
+ /* Interface 1, Alternate Setting 1 */
+ AUDIO_INTERFACE_DESC_SIZE, /* bLength */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
+ _AUDIO_SPKR_AS_ITF_NBR, /* bInterfaceNumber */
+ 0x01, /* bAlternateSetting */
+ 0x01, /* bNumEndpoints */
+ USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */
+ AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */
+ AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+ /* 09 byte*/
+
+ /* USB Speaker Audio Streaming Interface Descriptor */
+ AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */
+ 0x01, /* bTerminalLink */
+ 0x01, /* bDelay */
+ 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001 */
+ 0x00,
+ /* 07 byte*/
+
+ /* USB Speaker Audio Type III Format Interface Descriptor */
+ 0x0B, /* bLength */
+ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */
+ AUDIO_FORMAT_TYPE_I, /* bFormatType */
+ 0x02, /* bNrChannels */
+ 0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */
+ 16, /* bBitResolution (16-bits per sample) */
+ 0x01, /* bSamFreqType only one frequency supported */
+ AUDIO_SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */
+ /* 11 byte*/
+
+ /* Endpoint 1 - Standard Descriptor */
+ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */
+ _AUDIO_SPKR_EP, /* bEndpointAddress 1 out endpoint */
+ USBD_EP_TYPE_ISOC, /* bmAttributes */
+ AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
+ AUDIO_FS_BINTERVAL, /* bInterval */
+ 0x00, /* bRefresh */
+ 0x00, /* bSynchAddress */
+ /* 09 byte*/
+
+ /* Endpoint - Audio Streaming Descriptor*/
+ AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */
+ AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
+ AUDIO_ENDPOINT_GENERAL, /* bDescriptor */
+ 0x00, /* bmAttributes */
+ 0x00, /* bLockDelayUnits */
+ 0x00, /* wLockDelay */
+ 0x00,
+ /* 07 byte*/
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_AUDIO_SPKR_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_AUDIO_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_AUDIO_Init
+ * Initialize the AUDIO interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_SPKR_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+ USBD_AUDIO_SPKR_HandleTypeDef *haudio;
+
+ /* Allocate Audio structure */
+ haudio = &haudioInstance;
+
+ if (haudio == NULL)
+ {
+ pdev->pClassData_UAC_SPKR = NULL;
+ return (uint8_t)USBD_EMEM;
+ }
+
+ pdev->pClassData_UAC_SPKR = (void *)haudio;
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ pdev->ep_out[AUDIO_SPKR_EP & 0xFU].bInterval = AUDIO_HS_BINTERVAL;
+ }
+ else /* LOW and FULL-speed endpoints */
+ {
+ pdev->ep_out[AUDIO_SPKR_EP & 0xFU].bInterval = AUDIO_FS_BINTERVAL;
+ }
+
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, AUDIO_SPKR_EP, USBD_EP_TYPE_ISOC, AUDIO_OUT_PACKET);
+ pdev->ep_out[AUDIO_SPKR_EP & 0xFU].is_used = 1U;
+
+ haudio->alt_setting = 0U;
+ haudio->offset = AUDIO_OFFSET_UNKNOWN;
+ haudio->wr_ptr = 0U;
+ haudio->rd_ptr = 0U;
+ haudio->rd_enable = 0U;
+
+ /* Initialize the Audio output Hardware layer */
+ if (((USBD_AUDIO_SPKR_ItfTypeDef *)pdev->pUserData_UAC_SPKR)->Init(USBD_AUDIO_FREQ, AUDIO_DEFAULT_VOLUME, 0U) != 0U)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Prepare Out endpoint to receive 1st packet */
+ (void)USBD_LL_PrepareReceive(pdev, AUDIO_SPKR_EP, haudio->buffer,
+ AUDIO_OUT_PACKET);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_AUDIO_Init
+ * DeInitialize the AUDIO layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_SPKR_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ /* Open EP OUT */
+ (void)USBD_LL_CloseEP(pdev, AUDIO_SPKR_EP);
+ pdev->ep_out[AUDIO_SPKR_EP & 0xFU].is_used = 0U;
+ pdev->ep_out[AUDIO_SPKR_EP & 0xFU].bInterval = 0U;
+
+ /* DeInit physical Interface components */
+ if (pdev->pClassData_UAC_SPKR != NULL)
+ {
+ ((USBD_AUDIO_SPKR_ItfTypeDef *)pdev->pUserData_UAC_SPKR)->DeInit(0U);
+#if (0)
+ (void)USBD_free(pdev->pClassData_UAC_SPKR);
+#endif
+ pdev->pClassData_UAC_SPKR = NULL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_AUDIO_Setup
+ * Handle the AUDIO specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_SPKR_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req)
+{
+ USBD_AUDIO_SPKR_HandleTypeDef *haudio;
+ uint16_t len;
+ uint8_t *pbuf;
+ uint16_t status_info = 0U;
+ USBD_StatusTypeDef ret = USBD_OK;
+
+ haudio = (USBD_AUDIO_SPKR_HandleTypeDef *)pdev->pClassData_UAC_SPKR;
+
+ if (haudio == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS:
+ switch (req->bRequest)
+ {
+ case AUDIO_REQ_GET_CUR:
+ USBD_AUDIO_SPKR_REQ_GetCurrent(pdev, req);
+ break;
+
+ case AUDIO_REQ_SET_CUR:
+ USBD_AUDIO_SPKR_REQ_SetCurrent(pdev, req);
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_DESCRIPTOR:
+ if ((req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE)
+ {
+ pbuf = USBD_AUDIO_SPKR_CfgDesc + 18;
+ len = MIN(USBD_AUDIO_SPKR_CONFIG_DESC_SIZE, req->wLength);
+
+ (void)USBD_CtlSendData(pdev, pbuf, len);
+ }
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&haudio->alt_setting, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ if ((uint8_t)(req->wValue) <= USBD_MAX_NUM_INTERFACES)
+ {
+ haudio->alt_setting = (uint8_t)(req->wValue);
+ }
+ else
+ {
+ /* Call the error management function (command will be NAKed */
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_AUDIO_GetCfgDesc
+ * return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_AUDIO_SPKR_GetCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_AUDIO_SPKR_CfgDesc);
+
+ return USBD_AUDIO_SPKR_CfgDesc;
+}
+
+/**
+ * @brief USBD_AUDIO_DataIn
+ * handle data IN Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_SPKR_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(pdev);
+ UNUSED(epnum);
+
+ /* Only OUT data are processed */
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_AUDIO_EP0_RxReady
+ * handle EP0 Rx Ready event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_SPKR_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+ USBD_AUDIO_SPKR_HandleTypeDef *haudio;
+ haudio = (USBD_AUDIO_SPKR_HandleTypeDef *)pdev->pClassData_UAC_SPKR;
+
+ if (haudio == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if (haudio->control.cmd == AUDIO_REQ_SET_CUR)
+ {
+ /* In this driver, to simplify code, only SET_CUR request is managed */
+
+ if (haudio->control.unit == AUDIO_STREAMING_CTRL)
+ {
+ ((USBD_AUDIO_SPKR_ItfTypeDef *)pdev->pUserData_UAC_SPKR)->MuteCtl(haudio->control.data[0]);
+ haudio->control.cmd = 0U;
+ haudio->control.len = 0U;
+ }
+ }
+
+ return (uint8_t)USBD_OK;
+}
+/**
+ * @brief USBD_AUDIO_EP0_TxReady
+ * handle EP0 TRx Ready event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_SPKR_EP0_TxReady(USBD_HandleTypeDef *pdev)
+{
+ UNUSED(pdev);
+
+ /* Only OUT control data are processed */
+ return (uint8_t)USBD_OK;
+}
+/**
+ * @brief USBD_AUDIO_SOF
+ * handle SOF event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_SPKR_SOF(USBD_HandleTypeDef *pdev)
+{
+ UNUSED(pdev);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_AUDIO_SOF
+ * handle SOF event
+ * @param pdev: device instance
+ * @retval status
+ */
+void USBD_AUDIO_SPKR_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset)
+{
+ USBD_AUDIO_SPKR_HandleTypeDef *haudio;
+ uint32_t BufferSize = AUDIO_TOTAL_BUF_SIZE / 2U;
+
+ if (pdev->pClassData_UAC_SPKR == NULL)
+ {
+ return;
+ }
+
+ haudio = (USBD_AUDIO_SPKR_HandleTypeDef *)pdev->pClassData_UAC_SPKR;
+
+ haudio->offset = offset;
+
+ if (haudio->rd_enable == 1U)
+ {
+ haudio->rd_ptr += (uint16_t)BufferSize;
+
+ if (haudio->rd_ptr == AUDIO_TOTAL_BUF_SIZE)
+ {
+ /* roll back */
+ haudio->rd_ptr = 0U;
+ }
+ }
+
+ if (haudio->rd_ptr > haudio->wr_ptr)
+ {
+ if ((haudio->rd_ptr - haudio->wr_ptr) < AUDIO_OUT_PACKET)
+ {
+ BufferSize += 4U;
+ }
+ else
+ {
+ if ((haudio->rd_ptr - haudio->wr_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET))
+ {
+ BufferSize -= 4U;
+ }
+ }
+ }
+ else
+ {
+ if ((haudio->wr_ptr - haudio->rd_ptr) < AUDIO_OUT_PACKET)
+ {
+ BufferSize -= 4U;
+ }
+ else
+ {
+ if ((haudio->wr_ptr - haudio->rd_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET))
+ {
+ BufferSize += 4U;
+ }
+ }
+ }
+
+ if (haudio->offset == AUDIO_OFFSET_FULL)
+ {
+ ((USBD_AUDIO_SPKR_ItfTypeDef *)pdev->pUserData_UAC_SPKR)->AudioCmd(&haudio->buffer[0], BufferSize, AUDIO_CMD_PLAY);
+ haudio->offset = AUDIO_OFFSET_NONE;
+ }
+}
+
+/**
+ * @brief USBD_AUDIO_IsoINIncomplete
+ * handle data ISO IN Incomplete event
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_SPKR_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(pdev);
+ UNUSED(epnum);
+
+ return (uint8_t)USBD_OK;
+}
+/**
+ * @brief USBD_AUDIO_IsoOutIncomplete
+ * handle data ISO OUT Incomplete event
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_SPKR_IsoOutIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(pdev);
+ UNUSED(epnum);
+
+ return (uint8_t)USBD_OK;
+}
+/**
+ * @brief USBD_AUDIO_DataOut
+ * handle data OUT Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_AUDIO_SPKR_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ uint16_t PacketSize;
+ USBD_AUDIO_SPKR_HandleTypeDef *haudio;
+
+ haudio = (USBD_AUDIO_SPKR_HandleTypeDef *)pdev->pClassData_UAC_SPKR;
+
+ if (haudio == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if (epnum == AUDIO_SPKR_EP)
+ {
+ /* Get received data packet length */
+ PacketSize = (uint16_t)USBD_LL_GetRxDataSize(pdev, epnum);
+
+ /* Packet received Callback */
+ ((USBD_AUDIO_SPKR_ItfTypeDef *)pdev->pUserData_UAC_SPKR)->PeriodicTC(&haudio->buffer[haudio->wr_ptr], PacketSize, AUDIO_OUT_TC);
+
+ /* Increment the Buffer pointer or roll it back when all buffers are full */
+ haudio->wr_ptr += PacketSize;
+
+ if (haudio->wr_ptr == AUDIO_TOTAL_BUF_SIZE)
+ {
+ /* All buffers are full: roll back */
+ haudio->wr_ptr = 0U;
+
+ if (haudio->offset == AUDIO_OFFSET_UNKNOWN)
+ {
+ ((USBD_AUDIO_SPKR_ItfTypeDef *)pdev->pUserData_UAC_SPKR)->AudioCmd(&haudio->buffer[0], AUDIO_TOTAL_BUF_SIZE / 2U, AUDIO_CMD_START);
+ haudio->offset = AUDIO_OFFSET_NONE;
+ }
+ }
+
+ if (haudio->rd_enable == 0U)
+ {
+ if (haudio->wr_ptr == (AUDIO_TOTAL_BUF_SIZE / 2U))
+ {
+ haudio->rd_enable = 1U;
+ }
+ }
+
+ /* Prepare Out endpoint to receive next audio packet */
+ (void)USBD_LL_PrepareReceive(pdev, AUDIO_SPKR_EP,
+ &haudio->buffer[haudio->wr_ptr],
+ AUDIO_OUT_PACKET);
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief AUDIO_Req_GetCurrent
+ * Handles the GET_CUR Audio control request.
+ * @param pdev: instance
+ * @param req: setup class request
+ * @retval status
+ */
+static void USBD_AUDIO_SPKR_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_AUDIO_SPKR_HandleTypeDef *haudio;
+ haudio = (USBD_AUDIO_SPKR_HandleTypeDef *)pdev->pClassData_UAC_SPKR;
+
+ if (haudio == NULL)
+ {
+ return;
+ }
+
+ (void)USBD_memset(haudio->control.data, 0, 64U);
+
+ /* Send the current mute state */
+ (void)USBD_CtlSendData(pdev, haudio->control.data, req->wLength);
+}
+
+/**
+ * @brief AUDIO_Req_SetCurrent
+ * Handles the SET_CUR Audio control request.
+ * @param pdev: instance
+ * @param req: setup class request
+ * @retval status
+ */
+static void USBD_AUDIO_SPKR_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_AUDIO_SPKR_HandleTypeDef *haudio;
+ haudio = (USBD_AUDIO_SPKR_HandleTypeDef *)pdev->pClassData_UAC_SPKR;
+
+ if (haudio == NULL)
+ {
+ return;
+ }
+
+ if (req->wLength != 0U)
+ {
+ /* Prepare the reception of the buffer over EP0 */
+ (void)USBD_CtlPrepareRx(pdev, haudio->control.data, req->wLength);
+
+ haudio->control.cmd = AUDIO_REQ_SET_CUR; /* Set the request value */
+ haudio->control.len = (uint8_t)req->wLength; /* Set the request data length */
+ haudio->control.unit = HIBYTE(req->wIndex); /* Set the request target unit */
+ }
+}
+
+/**
+ * @brief DeviceQualifierDescriptor
+ * return Device Qualifier descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_AUDIO_SPKR_GetDeviceQualifierDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_AUDIO_SPKR_DeviceQualifierDesc);
+
+ return USBD_AUDIO_SPKR_DeviceQualifierDesc;
+}
+
+/**
+ * @brief USBD_AUDIO_RegisterInterface
+ * @param fops: Audio interface callback
+ * @retval status
+ */
+uint8_t USBD_AUDIO_SPKR_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_AUDIO_SPKR_ItfTypeDef *fops)
+{
+ if (fops == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ pdev->pUserData_UAC_SPKR = fops;
+
+ return (uint8_t)USBD_OK;
+}
+
+void USBD_Update_Audio_SPKR_DESC(uint8_t *desc,
+ uint8_t ac_itf,
+ uint8_t as_itf,
+ uint8_t out_ep,
+ uint8_t str_idx)
+{
+ desc[11] = ac_itf;
+ desc[19] = ac_itf;
+ desc[25] = str_idx;
+ desc[34] = as_itf;
+ desc[67] = as_itf;
+ desc[76] = as_itf;
+ desc[103] = out_ep;
+
+ AUDIO_SPKR_EP = out_ep;
+ AUDIO_SPKR_AC_ITF_NBR = ac_itf;
+ AUDIO_SPKR_AS_ITF_NBR = as_itf;
+
+ AUDIO_SPKR_STR_DESC_IDX = str_idx;
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ACM/Inc/usbd_cdc_acm.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ACM/Inc/usbd_cdc_acm.h
new file mode 100644
index 0000000..f7d6657
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ACM/Inc/usbd_cdc_acm.h
@@ -0,0 +1,189 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc.h
+ * @author MCD Application Team
+ * @brief header file for the usbd_cdc.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CDC_H
+#define __USB_CDC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+#include "AL94.I-CUBE-USBD-COMPOSITE_conf.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup usbd_cdc
+ * @brief This file is the Header file for usbd_cdc.c
+ * @{
+ */
+
+
+/** @defgroup usbd_cdc_Exported_Defines
+ * @{
+ */
+
+#define CDC_ACM_STR_DESC "STM32 CDC ACM%d"
+
+#define NUMBER_OF_CDC _USBD_CDC_ACM_COUNT
+#ifndef CDC_HS_BINTERVAL
+#define CDC_HS_BINTERVAL 0x10U
+#endif /* CDC_HS_BINTERVAL */
+
+#ifndef CDC_FS_BINTERVAL
+#define CDC_FS_BINTERVAL 0x10U
+#endif /* CDC_FS_BINTERVAL */
+
+/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
+#define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
+#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
+#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
+
+#define USB_CDC_CONFIG_DESC_SIZ (9 + 66 * NUMBER_OF_CDC)
+#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
+#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
+
+#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
+#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
+
+#define CDC_REQ_MAX_DATA_SIZE 0x7U
+/*---------------------------------------------------------------------*/
+/* CDC definitions */
+/*---------------------------------------------------------------------*/
+#define CDC_SEND_ENCAPSULATED_COMMAND 0x00U
+#define CDC_GET_ENCAPSULATED_RESPONSE 0x01U
+#define CDC_SET_COMM_FEATURE 0x02U
+#define CDC_GET_COMM_FEATURE 0x03U
+#define CDC_CLEAR_COMM_FEATURE 0x04U
+#define CDC_SET_LINE_CODING 0x20U
+#define CDC_GET_LINE_CODING 0x21U
+#define CDC_SET_CONTROL_LINE_STATE 0x22U
+#define CDC_SEND_BREAK 0x23U
+
+ /**
+ * @}
+ */
+
+ /** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+
+ /**
+ * @}
+ */
+ typedef struct
+ {
+ uint32_t bitrate;
+ uint8_t format;
+ uint8_t paritytype;
+ uint8_t datatype;
+ } USBD_CDC_ACM_LineCodingTypeDef;
+
+ typedef struct _USBD_CDC_Itf
+ {
+ int8_t (*Init)(uint8_t cdc_ch);
+ int8_t (*DeInit)(uint8_t cdc_ch);
+ int8_t (*Control)(uint8_t cdc_ch, uint8_t cmd, uint8_t *pbuf, uint16_t length);
+ int8_t (*Receive)(uint8_t cdc_ch, uint8_t *Buf, uint32_t *Len);
+ int8_t (*TransmitCplt)(uint8_t cdc_ch, uint8_t *Buf, uint32_t *Len, uint8_t epnum);
+ } USBD_CDC_ACM_ItfTypeDef;
+
+ typedef struct
+ {
+ uint32_t data[NUMBER_OF_CDC][CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits alignment */
+ uint8_t CmdOpCode;
+ uint8_t CmdLength;
+ uint8_t *RxBuffer;
+ uint8_t *TxBuffer;
+ uint32_t RxLength;
+ uint32_t TxLength;
+
+ __IO uint32_t TxState;
+ __IO uint32_t RxState;
+ } USBD_CDC_ACM_HandleTypeDef;
+
+ /** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+ /**
+ * @}
+ */
+
+ /** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+ extern USBD_ClassTypeDef USBD_CDC_ACM;
+
+ extern uint8_t CDC_IN_EP[NUMBER_OF_CDC]; /* EP1 for data IN */
+ extern uint8_t CDC_OUT_EP[NUMBER_OF_CDC]; /* EP1 for data OUT */
+ extern uint8_t CDC_CMD_EP[NUMBER_OF_CDC]; /* EP2 for CDC commands */
+
+ extern uint8_t CDC_CMD_ITF_NBR[NUMBER_OF_CDC]; /* Command Interface Number */
+ extern uint8_t CDC_COM_ITF_NBR[NUMBER_OF_CDC]; /* Communication Interface Number */
+
+ extern uint8_t CDC_STR_DESC_IDX[NUMBER_OF_CDC];
+
+ /**
+ * @}
+ */
+
+ /** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+ uint8_t USBD_CDC_ACM_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_CDC_ACM_ItfTypeDef *fops);
+
+ uint8_t USBD_CDC_SetTxBuffer(uint8_t ch, USBD_HandleTypeDef *pdev, uint8_t *pbuff,
+ uint32_t length);
+
+ uint8_t USBD_CDC_SetRxBuffer(uint8_t ch, USBD_HandleTypeDef *pdev, uint8_t *pbuff);
+ uint8_t USBD_CDC_ReceivePacket(uint8_t ch, USBD_HandleTypeDef *pdev);
+ uint8_t USBD_CDC_TransmitPacket(uint8_t ch, USBD_HandleTypeDef *pdev);
+
+ void USBD_Update_CDC_ACM_DESC(uint8_t *desc,
+ uint8_t cmd_itf,
+ uint8_t com_itf,
+ uint8_t in_ep,
+ uint8_t cmd_ep,
+ uint8_t out_ep,
+ uint8_t str_idx);
+ /**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_CDC_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ACM/Src/usbd_cdc_acm.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ACM/Src/usbd_cdc_acm.c
new file mode 100644
index 0000000..b5f85d5
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ACM/Src/usbd_cdc_acm.c
@@ -0,0 +1,2209 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc.c
+ * @author MCD Application Team
+ * @brief This file provides the high layer firmware functions to manage the
+ * following functionalities of the USB CDC Class:
+ * - Initialization and Configuration of high and low layer
+ * - Enumeration as CDC Device (and enumeration for each implemented memory interface)
+ * - OUT/IN data transfer
+ * - Command IN transfer (class requests management)
+ * - Error management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * CDC Class Driver Description
+ * ===================================================================
+ * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
+ * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
+ * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
+ * This driver implements the following aspects of the specification:
+ * - Device descriptor management
+ * - Configuration descriptor management
+ * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
+ * - Requests management (as described in section 6.2 in specification)
+ * - Abstract Control Model compliant
+ * - Union Functional collection (using 1 IN endpoint for control)
+ * - Data interface class
+ *
+ * These aspects may be enriched or modified for a specific user application.
+ *
+ * This driver doesn't implement the following aspects of the specification
+ * (but it is possible to manage these features with some modifications on this driver):
+ * - Any class-specific aspect relative to communication classes should be managed by user application.
+ * - All communication classes other than PSTN are not managed
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc_acm.h"
+#include "usbd_ctlreq.h"
+
+#define _CDC_IN_EP 0x81U /* EP1 for data IN */
+#define _CDC_OUT_EP 0x01U /* EP1 for data OUT */
+#define _CDC_CMD_EP 0x82U /* EP2 for CDC commands */
+
+#define _CDC_CMD_ITF_NBR 0x00U /* Command Interface Number */
+#define _CDC_COM_ITF_NBR 0x01U /* Communication Interface Number */
+
+#define _CDC_STR_DESC_IDX 0x00
+
+uint8_t CDC_IN_EP[NUMBER_OF_CDC];
+uint8_t CDC_OUT_EP[NUMBER_OF_CDC];
+uint8_t CDC_CMD_EP[NUMBER_OF_CDC];
+
+uint8_t CDC_CMD_ITF_NBR[NUMBER_OF_CDC];
+uint8_t CDC_COM_ITF_NBR[NUMBER_OF_CDC];
+
+uint8_t CDC_STR_DESC_IDX[NUMBER_OF_CDC];
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_CDC
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_CDC_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_Private_FunctionPrototypes
+ * @{
+ */
+
+static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev);
+
+static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length);
+static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length);
+static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
+static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
+static uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
+
+USBD_CDC_ACM_HandleTypeDef CDC_ACM_Class_Data[NUMBER_OF_CDC];
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_Private_Variables
+ * @{
+ */
+
+/* CDC interface class callbacks structure */
+USBD_ClassTypeDef USBD_CDC_ACM =
+ {
+ USBD_CDC_Init,
+ USBD_CDC_DeInit,
+ USBD_CDC_Setup,
+ NULL, /* EP0_TxSent, */
+ USBD_CDC_EP0_RxReady,
+ USBD_CDC_DataIn,
+ USBD_CDC_DataOut,
+ NULL,
+ NULL,
+ NULL,
+ USBD_CDC_GetHSCfgDesc,
+ USBD_CDC_GetFSCfgDesc,
+ USBD_CDC_GetOtherSpeedCfgDesc,
+ USBD_CDC_GetDeviceQualifierDescriptor,
+};
+
+/* USB CDC device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
+ {
+ /* Configuration Descriptor */
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ LOBYTE(USB_CDC_CONFIG_DESC_SIZ), /* wTotalLength:no of returned bytes */
+ HIBYTE(USB_CDC_CONFIG_DESC_SIZ),
+ (2 * NUMBER_OF_CDC), /* bNumInterfaces: 2 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA */
+
+ /******************** CDC0 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX, /* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_HS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+#if (NUMBER_OF_CDC > 1)
+ /******************** CDC1 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX, /* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_HS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 2)
+ /******************** CDC2 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX, /* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_HS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 3)
+ /******************** CDC3 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX, /* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_HS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 4)
+ /******************** CDC4 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX, /* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_HS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 5)
+ /******************** CDC5 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX, /* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_HS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 6)
+ /******************** CDC6 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX, /* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_HS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 7)
+ /******************** CDC7 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX, /* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_HS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
+ 0x00 /* bInterval: ignore for Bulk transfer */
+#endif
+};
+
+/* USB CDC device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
+ {
+ /* Configuration Descriptor */
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ LOBYTE(USB_CDC_CONFIG_DESC_SIZ), /* wTotalLength:no of returned bytes */
+ HIBYTE(USB_CDC_CONFIG_DESC_SIZ),
+ 0x02, /* bNumInterfaces: 2 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA */
+
+ /*---------------------------------------------------------------------------*/
+ /******************** CDC0 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ /* Interface descriptor type */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX,/* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_FS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+#if (NUMBER_OF_CDC > 1)
+ /******************** CDC1 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ /* Interface descriptor type */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX,/* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_FS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 2)
+ /******************** CDC2 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ /* Interface descriptor type */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX,/* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_FS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 3)
+ /******************** CDC3 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ /* Interface descriptor type */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX,/* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_FS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 4)
+ /******************** CDC4 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ /* Interface descriptor type */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX,/* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_FS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 5)
+ /******************** CDC5 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ /* Interface descriptor type */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX,/* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_FS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 6)
+ /******************** CDC6 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ /* Interface descriptor type */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX,/* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_FS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+#endif
+
+#if (NUMBER_OF_CDC > 7)
+ /******************** CDC7 block ********************/
+ /******** IAD to associate the two CDC interfaces */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass */
+ 0x02, /* bFunctionSubClass */
+ 0x01, /* bFunctionProtocol */
+ 0x00, /* iFunction (Index of string descriptor describing this function) */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ /* Interface descriptor type */
+ _CDC_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoints used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol: Common AT commands */
+ _CDC_STR_DESC_IDX,/* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header Func Desc */
+ 0x10, /* bcdCDC: spec release number */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x02, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union func desc */
+ _CDC_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Endpoint 2 Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_CMD_PACKET_SIZE),
+ CDC_FS_BINTERVAL, /* bInterval: */
+ /*---------------------------------------------------------------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass: */
+ 0x00, /* bInterfaceProtocol: */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
+ 0x00 /* bInterval: ignore for Bulk transfer */
+#endif
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_CDC_Init
+ * Initialize the CDC interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+ USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
+
+ for (uint8_t i = 0; i < NUMBER_OF_CDC; i++)
+ {
+ hcdc = &CDC_ACM_Class_Data[i];
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, CDC_IN_EP[i], USBD_EP_TYPE_BULK,
+ CDC_DATA_HS_IN_PACKET_SIZE);
+
+ pdev->ep_in[CDC_IN_EP[i] & 0xFU].is_used = 1U;
+
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP[i], USBD_EP_TYPE_BULK,
+ CDC_DATA_HS_OUT_PACKET_SIZE);
+
+ pdev->ep_out[CDC_OUT_EP[i] & 0xFU].is_used = 1U;
+
+ /* Set bInterval for CDC CMD Endpoint */
+ pdev->ep_in[CDC_CMD_EP[i] & 0xFU].bInterval = CDC_HS_BINTERVAL;
+ }
+ else
+ {
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, CDC_IN_EP[i], USBD_EP_TYPE_BULK,
+ CDC_DATA_FS_IN_PACKET_SIZE);
+
+ pdev->ep_in[CDC_IN_EP[i] & 0xFU].is_used = 1U;
+
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP[i], USBD_EP_TYPE_BULK,
+ CDC_DATA_FS_OUT_PACKET_SIZE);
+
+ pdev->ep_out[CDC_OUT_EP[i] & 0xFU].is_used = 1U;
+
+ /* Set bInterval for CMD Endpoint */
+ pdev->ep_in[CDC_CMD_EP[i] & 0xFU].bInterval = CDC_FS_BINTERVAL;
+ }
+
+ /* Open Command IN EP */
+ (void)USBD_LL_OpenEP(pdev, CDC_CMD_EP[i], USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
+ pdev->ep_in[CDC_CMD_EP[i] & 0xFU].is_used = 1U;
+
+ /* Init physical Interface components */
+ ((USBD_CDC_ACM_ItfTypeDef *)pdev->pUserData_CDC_ACM)->Init(i);
+
+ /* Init Xfer states */
+ hcdc->TxState = 0U;
+ hcdc->RxState = 0U;
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP[i], hcdc->RxBuffer,
+ CDC_DATA_HS_OUT_PACKET_SIZE);
+ }
+ else
+ {
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP[i], hcdc->RxBuffer,
+ CDC_DATA_FS_OUT_PACKET_SIZE);
+ }
+ }
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_Init
+ * DeInitialize the CDC layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+ for (uint8_t i = 0; i < NUMBER_OF_CDC; i++)
+ {
+ /* Close EP IN */
+ (void)USBD_LL_CloseEP(pdev, CDC_IN_EP[i]);
+ pdev->ep_in[CDC_IN_EP[i] & 0xFU].is_used = 0U;
+
+ /* Close EP OUT */
+ (void)USBD_LL_CloseEP(pdev, CDC_OUT_EP[i]);
+ pdev->ep_out[CDC_OUT_EP[i] & 0xFU].is_used = 0U;
+
+ /* Close Command IN EP */
+ (void)USBD_LL_CloseEP(pdev, CDC_CMD_EP[i]);
+ pdev->ep_in[CDC_CMD_EP[i] & 0xFU].is_used = 0U;
+ pdev->ep_in[CDC_CMD_EP[i] & 0xFU].bInterval = 0U;
+
+ /* DeInit physical Interface components */
+ ((USBD_CDC_ACM_ItfTypeDef *)pdev->pUserData_CDC_ACM)->DeInit(i);
+ }
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_Setup
+ * Handle the CDC specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req)
+{
+ USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
+ uint16_t len;
+ uint8_t ifalt = 0U;
+ uint16_t status_info = 0U;
+ USBD_StatusTypeDef ret = USBD_OK;
+
+ uint8_t windex_to_ch = 0;
+
+ for (uint8_t i = 0; i < NUMBER_OF_CDC; i++)
+ {
+ if (LOBYTE(req->wIndex) == CDC_CMD_ITF_NBR[i] || LOBYTE(req->wIndex) == CDC_COM_ITF_NBR[i])
+ {
+ windex_to_ch = i;
+ break;
+ }
+ }
+
+ hcdc = &CDC_ACM_Class_Data[windex_to_ch];
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS:
+ if (req->wLength != 0U)
+ {
+ if ((req->bmRequest & 0x80U) != 0U)
+ {
+ ((USBD_CDC_ACM_ItfTypeDef *)pdev->pUserData_CDC_ACM)->Control(windex_to_ch, req->bRequest, (uint8_t *)hcdc->data[windex_to_ch], req->wLength);
+
+ len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength);
+ (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data[windex_to_ch], len);
+ }
+ else
+ {
+ hcdc->CmdOpCode = req->bRequest;
+ hcdc->CmdLength = (uint8_t)req->wLength;
+
+ (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data[windex_to_ch], req->wLength);
+ }
+ }
+ else
+ {
+ ((USBD_CDC_ACM_ItfTypeDef *)pdev->pUserData_CDC_ACM)->Control(windex_to_ch, req->bRequest, (uint8_t *)req, 0U);
+ }
+ break;
+
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, &ifalt, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state != USBD_STATE_CONFIGURED)
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_CDC_DataIn
+ * Data sent on non-control IN endpoint
+ * @param pdev: device instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
+ PCD_HandleTypeDef *hpcd = pdev->pData;
+ uint8_t ep_to_ch = 0;
+
+ for (uint8_t i = 0; i < NUMBER_OF_CDC; i++)
+ {
+ if (epnum == (CDC_IN_EP[i] & 0x0F))
+ {
+ ep_to_ch = i;
+ break;
+ }
+ }
+
+ hcdc = &CDC_ACM_Class_Data[ep_to_ch];
+
+ if ((pdev->ep_in[epnum].total_length > 0U) &&
+ ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
+ {
+ /* Update the packet total length */
+ pdev->ep_in[epnum].total_length = 0U;
+
+ /* Send ZLP */
+ (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
+ }
+ else
+ {
+ hcdc->TxState = 0U;
+
+ if (((USBD_CDC_ACM_ItfTypeDef *)pdev->pUserData_CDC_ACM)->TransmitCplt != NULL)
+ {
+ ((USBD_CDC_ACM_ItfTypeDef *)pdev->pUserData_CDC_ACM)->TransmitCplt(ep_to_ch, hcdc->TxBuffer, &hcdc->TxLength, epnum);
+ }
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_DataOut
+ * Data received on non-control Out endpoint
+ * @param pdev: device instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
+ uint8_t ep_to_ch = 0;
+
+ for (uint8_t i = 0; i < NUMBER_OF_CDC; i++)
+ {
+ if (epnum == CDC_OUT_EP[i])
+ {
+ ep_to_ch = i;
+ break;
+ }
+ }
+
+ hcdc = &CDC_ACM_Class_Data[ep_to_ch];
+
+ /* Get the received data length */
+ hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
+
+ /* USB data will be immediately processed, this allow next USB traffic being
+ NAKed till the end of the application Xfer */
+
+ ((USBD_CDC_ACM_ItfTypeDef *)pdev->pUserData_CDC_ACM)->Receive(ep_to_ch, hcdc->RxBuffer, &hcdc->RxLength);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_EP0_RxReady
+ * Handle EP0 Rx Ready event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+ USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
+
+ for (uint8_t i = 0; i < NUMBER_OF_CDC; i++)
+ {
+ hcdc = &CDC_ACM_Class_Data[i];
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if ((pdev->pUserData_CDC_ACM != NULL) && (hcdc->CmdOpCode != 0xFFU))
+ {
+ ((USBD_CDC_ACM_ItfTypeDef *)pdev->pUserData_CDC_ACM)->Control(i, hcdc->CmdOpCode, (uint8_t *)hcdc->data[i], (uint16_t)hcdc->CmdLength);
+ hcdc->CmdOpCode = 0xFFU;
+ }
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_GetFSCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc);
+
+ return USBD_CDC_CfgFSDesc;
+}
+
+/**
+ * @brief USBD_CDC_GetHSCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CDC_CfgHSDesc);
+
+ return USBD_CDC_CfgHSDesc;
+}
+
+/**
+ * @brief USBD_CDC_GetOtherSpeedCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc);
+
+ return USBD_CDC_CfgFSDesc;
+}
+
+/**
+ * @brief USBD_CDC_GetDeviceQualifierDescriptor
+ * return Device Qualifier descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc);
+
+ return USBD_CDC_DeviceQualifierDesc;
+}
+
+/**
+ * @brief USBD_CDC_RegisterInterface
+ * @param pdev: device instance
+ * @param fops: CD Interface callback
+ * @retval status
+ */
+uint8_t USBD_CDC_ACM_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_CDC_ACM_ItfTypeDef *fops)
+{
+ if (fops == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ pdev->pUserData_CDC_ACM = fops;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_SetTxBuffer
+ * @param pdev: device instance
+ * @param pbuff: Tx Buffer
+ * @retval status
+ */
+uint8_t USBD_CDC_SetTxBuffer(uint8_t ch, USBD_HandleTypeDef *pdev,
+ uint8_t *pbuff, uint32_t length)
+{
+ USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
+
+ hcdc = &CDC_ACM_Class_Data[ch];
+
+ hcdc->TxBuffer = pbuff;
+ hcdc->TxLength = length;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_SetRxBuffer
+ * @param pdev: device instance
+ * @param pbuff: Rx Buffer
+ * @retval status
+ */
+uint8_t USBD_CDC_SetRxBuffer(uint8_t ch, USBD_HandleTypeDef *pdev, uint8_t *pbuff)
+{
+ USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
+
+ hcdc = &CDC_ACM_Class_Data[ch];
+
+ hcdc->RxBuffer = pbuff;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_TransmitPacket
+ * Transmit packet on IN endpoint
+ * @param pdev: device instance
+ * @retval status
+ */
+uint8_t USBD_CDC_TransmitPacket(uint8_t ch, USBD_HandleTypeDef *pdev)
+{
+ USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
+ USBD_StatusTypeDef ret = USBD_BUSY;
+
+ hcdc = &CDC_ACM_Class_Data[ch];
+
+ if (hcdc->TxState == 0U)
+ {
+ /* Tx Transfer in progress */
+ hcdc->TxState = 1U;
+
+ /* Update the packet total length */
+ pdev->ep_in[CDC_IN_EP[ch] & 0xFU].total_length = hcdc->TxLength;
+
+ /* Transmit next packet */
+ (void)USBD_LL_Transmit(pdev, CDC_IN_EP[ch], hcdc->TxBuffer, hcdc->TxLength);
+
+ ret = USBD_OK;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_CDC_ACM_ReceivePacket
+ * prepare OUT Endpoint for reception
+ * @param pdev: device instance
+ * @retval status
+ */
+uint8_t USBD_CDC_ReceivePacket(uint8_t ch, USBD_HandleTypeDef *pdev)
+{
+ USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
+
+ hcdc = &CDC_ACM_Class_Data[ch];
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP[ch], hcdc->RxBuffer,
+ CDC_DATA_HS_OUT_PACKET_SIZE);
+ }
+ else
+ {
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP[ch], hcdc->RxBuffer,
+ CDC_DATA_FS_OUT_PACKET_SIZE);
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+void USBD_Update_CDC_ACM_DESC(uint8_t *desc,
+ uint8_t cmd_itf,
+ uint8_t com_itf,
+ uint8_t in_ep,
+ uint8_t cmd_ep,
+ uint8_t out_ep,
+ uint8_t str_idx)
+{
+ desc += 9;
+ for (uint8_t i = 0; i < NUMBER_OF_CDC; i++)
+ {
+ desc[2] = cmd_itf;
+ desc[16] = str_idx;
+ desc[10] = cmd_itf;
+ desc[26] = com_itf;
+ desc[34] = cmd_itf;
+ desc[35] = com_itf;
+ desc[38] = cmd_ep;
+ desc[45] = com_itf;
+ desc[54] = out_ep;
+ desc[61] = in_ep;
+
+ desc += 66;
+ CDC_IN_EP[i] = in_ep;
+ CDC_OUT_EP[i] = out_ep;
+ CDC_CMD_EP[i] = cmd_ep;
+ CDC_CMD_ITF_NBR[i] = cmd_itf;
+ CDC_COM_ITF_NBR[i] = com_itf;
+ CDC_STR_DESC_IDX[i] = str_idx;
+
+ in_ep += 2;
+ cmd_ep = in_ep + 1;
+ out_ep++;
+ str_idx++;
+
+ cmd_itf += 2;
+ com_itf = cmd_itf + 1;
+ }
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ECM/Inc/usbd_cdc_ecm.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ECM/Inc/usbd_cdc_ecm.h
new file mode 100644
index 0000000..a602326
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ECM/Inc/usbd_cdc_ecm.h
@@ -0,0 +1,262 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_ecm.h
+ * @author MCD Application Team
+ * @brief header file for the usbd_cdc_ecm.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CDC_ECM_H
+#define __USB_CDC_ECM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup usbd_cdc_ecm
+ * @brief This file is the Header file for usbd_cdc_ecm.c
+ * @{
+ */
+
+
+/** @defgroup usbd_cdc_ecm_Exported_Defines
+ * @{
+ */
+
+#define CDC_ECM_STR_DESC "STM32 CDC ECM"
+
+/* Comment this define in order to disable the CDC ECM Notification pipe */
+
+#ifndef CDC_ECM_HS_BINTERVAL
+#define CDC_ECM_HS_BINTERVAL 0x10U
+#endif /* CDC_ECM_HS_BINTERVAL */
+
+#ifndef CDC_ECM_FS_BINTERVAL
+#define CDC_ECM_FS_BINTERVAL 0x10U
+#endif /* CDC_ECM_FS_BINTERVAL */
+
+#ifndef USBD_SUPPORT_USER_STRING_DESC
+#define USBD_SUPPORT_USER_STRING_DESC 1U
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
+
+/* CDC_ECM Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
+#define CDC_ECM_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
+#define CDC_ECM_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
+#define CDC_ECM_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */
+
+#define CDC_ECM_CONFIG_DESC_SIZE 79U
+
+#define CDC_ECM_DATA_BUFFER_SIZE 2000U
+
+#define CDC_ECM_DATA_HS_IN_PACKET_SIZE CDC_ECM_DATA_HS_MAX_PACKET_SIZE
+#define CDC_ECM_DATA_HS_OUT_PACKET_SIZE CDC_ECM_DATA_HS_MAX_PACKET_SIZE
+
+#define CDC_ECM_DATA_FS_IN_PACKET_SIZE CDC_ECM_DATA_FS_MAX_PACKET_SIZE
+#define CDC_ECM_DATA_FS_OUT_PACKET_SIZE CDC_ECM_DATA_FS_MAX_PACKET_SIZE
+
+/*---------------------------------------------------------------------*/
+/* CDC_ECM definitions */
+/*---------------------------------------------------------------------*/
+#define CDC_ECM_SEND_ENCAPSULATED_COMMAND 0x00U
+#define CDC_ECM_GET_ENCAPSULATED_RESPONSE 0x01U
+#define CDC_ECM_SET_ETH_MULTICAST_FILTERS 0x40U
+#define CDC_ECM_SET_ETH_PWRM_PATTERN_FILTER 0x41U
+#define CDC_ECM_GET_ETH_PWRM_PATTERN_FILTER 0x42U
+#define CDC_ECM_SET_ETH_PACKET_FILTER 0x43U
+#define CDC_ECM_GET_ETH_STATISTIC 0x44U
+
+#define CDC_ECM_NET_DISCONNECTED 0x00U
+#define CDC_ECM_NET_CONNECTED 0x01U
+
+
+/* Ethernet statistics definitions */
+#define CDC_ECM_XMIT_OK_VAL CDC_ECM_ETH_STATS_VAL_ENABLED
+#define CDC_ECM_XMIT_OK 0x01U
+#define CDC_ECM_RVC_OK 0x02U
+#define CDC_ECM_XMIT_ERROR 0x04U
+#define CDC_ECM_RCV_ERROR 0x08U
+#define CDC_ECM_RCV_NO_BUFFER 0x10U
+#define CDC_ECM_DIRECTED_BYTES_XMIT 0x20U
+#define CDC_ECM_DIRECTED_FRAMES_XMIT 0x40U
+#define CDC_ECM_MULTICAST_BYTES_XMIT 0x80U
+
+#define CDC_ECM_MULTICAST_FRAMES_XMIT 0x01U
+#define CDC_ECM_BROADCAST_BYTES_XMIT 0x02U
+#define CDC_ECM_BROADCAST_FRAMES_XMIT 0x04U
+#define CDC_ECM_DIRECTED_BYTES_RCV 0x08U
+#define CDC_ECM_DIRECTED_FRAMES_RCV 0x10U
+#define CDC_ECM_MULTICAST_BYTES_RCV 0x20U
+#define CDC_ECM_MULTICAST_FRAMES_RCV 0x40U
+#define CDC_ECM_BROADCAST_BYTES_RCV 0x80U
+
+#define CDC_ECM_BROADCAST_FRAMES_RCV 0x01U
+#define CDC_ECM_RCV_CRC_ERROR 0x02U
+#define CDC_ECM_TRANSMIT_QUEUE_LENGTH 0x04U
+#define CDC_ECM_RCV_ERROR_ALIGNMENT 0x08U
+#define CDC_ECM_XMIT_ONE_COLLISION 0x10U
+#define CDC_ECM_XMIT_MORE_COLLISIONS 0x20U
+#define CDC_ECM_XMIT_DEFERRED 0x40U
+#define CDC_ECM_XMIT_MAX_COLLISIONS 0x80U
+
+#define CDC_ECM_RCV_OVERRUN 0x40U
+#define CDC_ECM_XMIT_UNDERRUN 0x40U
+#define CDC_ECM_XMIT_HEARTBEAT_FAILURE 0x40U
+#define CDC_ECM_XMIT_TIMES_CRS_LOST 0x40U
+#define CDC_ECM_XMIT_LATE_COLLISIONS 0x40U
+
+#define CDC_ECM_ETH_STATS_RESERVED 0xE0U
+#define CDC_ECM_BMREQUEST_TYPE_ECM 0xA1U
+
+/* MAC String index */
+#define CDC_ECM_MAC_STRING_INDEX 6U
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+typedef struct
+{
+ int8_t (*Init)(void);
+ int8_t (*DeInit)(void);
+ int8_t (*Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length);
+ int8_t (*Receive)(uint8_t *Buf, uint32_t *Len);
+ int8_t (*TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum);
+ int8_t (*Process)(USBD_HandleTypeDef *pdev);
+ const uint8_t *pStrDesc;
+} USBD_CDC_ECM_ItfTypeDef;
+
+typedef struct
+{
+ uint8_t bmRequest;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+ uint8_t data[8];
+} USBD_CDC_ECM_NotifTypeDef;
+
+typedef struct
+{
+ uint32_t data[CDC_ECM_DATA_BUFFER_SIZE / 4U]; /* Force 32-bit alignment */
+ uint8_t CmdOpCode;
+ uint8_t CmdLength;
+ uint8_t Reserved1; /* Reserved Byte to force 4 bytes alignment of following fields */
+ uint8_t Reserved2; /* Reserved Byte to force 4 bytes alignment of following fields */
+ uint8_t *RxBuffer;
+ uint8_t *TxBuffer;
+ uint32_t RxLength;
+ uint32_t TxLength;
+
+ __IO uint32_t TxState;
+ __IO uint32_t RxState;
+
+ __IO uint32_t MaxPcktLen;
+ __IO uint32_t LinkStatus;
+ __IO uint32_t NotificationStatus;
+ USBD_CDC_ECM_NotifTypeDef Req;
+} USBD_CDC_ECM_HandleTypeDef;
+
+typedef enum
+{
+ ECM_NETWORK_CONNECTION = 0x00,
+ ECM_RESPONSE_AVAILABLE = 0x01,
+ ECM_CONNECTION_SPEED_CHANGE = 0x2A
+} USBD_CDC_ECM_NotifCodeTypeDef;
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern USBD_ClassTypeDef USBD_CDC_ECM;
+
+extern uint8_t CDC_ECM_IN_EP;
+extern uint8_t CDC_ECM_OUT_EP;
+extern uint8_t CDC_ECM_CMD_EP;
+extern uint8_t CDC_ECM_CMD_ITF_NBR;
+extern uint8_t CDC_ECM_COM_ITF_NBR;
+extern uint8_t CDC_ECM_STR_DESC_IDX;
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+uint8_t USBD_CDC_ECM_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_CDC_ECM_ItfTypeDef *fops);
+
+uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
+ uint32_t length);
+
+uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
+
+uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev);
+
+uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev);
+
+uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev,
+ USBD_CDC_ECM_NotifCodeTypeDef Notif,
+ uint16_t bVal, uint8_t *pData);
+
+void USBD_Update_CDC_ECM_DESC(uint8_t *desc,
+ uint8_t cmd_itf,
+ uint8_t com_itf,
+ uint8_t in_ep,
+ uint8_t cmd_ep,
+ uint8_t out_ep,
+ uint8_t str_idx);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_CDC_ECM_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ECM/Src/usbd_cdc_ecm.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ECM/Src/usbd_cdc_ecm.c
new file mode 100644
index 0000000..9d5ab5f
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_ECM/Src/usbd_cdc_ecm.c
@@ -0,0 +1,1160 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_ecm.c
+ * @author MCD Application Team
+ * @brief This file provides the high layer firmware functions to manage the
+ * following functionalities of the USB CDC_ECM Class:
+ * - Initialization and Configuration of high and low layer
+ * - Enumeration as CDC_ECM Device (and enumeration for each implemented memory interface)
+ * - OUT/IN data transfer
+ * - Command IN transfer (class requests management)
+ * - Error management
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc_ecm.h"
+#include "usbd_ctlreq.h"
+
+#include "usbd_cdc_ecm_if.h"
+
+#define _CDC_ECM_IN_EP 0x81U /* EP1 for data IN */
+#define _CDC_ECM_OUT_EP 0x01U /* EP1 for data OUT */
+#define _CDC_ECM_CMD_EP 0x82U /* EP2 for CDC ECM commands */
+#define _CDC_ECM_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */
+#define _CDC_ECM_COM_ITF_NBR 0x01U /* Communication Interface Number 0 */
+#define _CDC_ECM_STR_DESC_IDX 0x00U
+
+uint8_t CDC_ECM_IN_EP = _CDC_ECM_IN_EP;
+uint8_t CDC_ECM_OUT_EP = _CDC_ECM_OUT_EP;
+uint8_t CDC_ECM_CMD_EP = _CDC_ECM_CMD_EP;
+uint8_t CDC_ECM_CMD_ITF_NBR = _CDC_ECM_CMD_ITF_NBR;
+uint8_t CDC_ECM_COM_ITF_NBR = _CDC_ECM_COM_ITF_NBR;
+uint8_t CDC_ECM_STR_DESC_IDX = _CDC_ECM_STR_DESC_IDX;
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_CDC_ECM
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_CDC_ECM_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_ECM_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_ECM_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_ECM_Private_FunctionPrototypes
+ * @{
+ */
+
+static uint8_t USBD_CDC_ECM_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_CDC_ECM_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_CDC_ECM_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev);
+static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req);
+
+static uint8_t *USBD_CDC_ECM_GetFSCfgDesc(uint16_t *length);
+static uint8_t *USBD_CDC_ECM_GetHSCfgDesc(uint16_t *length);
+static uint8_t *USBD_CDC_ECM_GetOtherSpeedCfgDesc(uint16_t *length);
+
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev,
+ uint8_t index, uint16_t *length);
+#endif
+
+uint8_t *USBD_CDC_ECM_GetDeviceQualifierDescriptor(uint16_t *length);
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+static uint32_t ConnSpeedTab[2] = {CDC_ECM_CONNECT_SPEED_UPSTREAM,
+ CDC_ECM_CONNECT_SPEED_DOWNSTREAM};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_ECM_Private_Variables
+ * @{
+ */
+
+static USBD_CDC_ECM_HandleTypeDef CDC_ECM_Instance;
+
+/* CDC_ECM interface class callbacks structure */
+USBD_ClassTypeDef USBD_CDC_ECM =
+ {
+ USBD_CDC_ECM_Init,
+ USBD_CDC_ECM_DeInit,
+ USBD_CDC_ECM_Setup,
+ NULL, /* EP0_TxSent, */
+ USBD_CDC_ECM_EP0_RxReady,
+ USBD_CDC_ECM_DataIn,
+ USBD_CDC_ECM_DataOut,
+ NULL,
+ NULL,
+ NULL,
+ USBD_CDC_ECM_GetHSCfgDesc,
+ USBD_CDC_ECM_GetFSCfgDesc,
+ USBD_CDC_ECM_GetOtherSpeedCfgDesc,
+ USBD_CDC_ECM_GetDeviceQualifierDescriptor,
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ USBD_CDC_ECM_USRStringDescriptor,
+#endif
+};
+
+/* USB CDC_ECM device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgHSDesc[CDC_ECM_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /* Configuration Descriptor */
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ LOBYTE(CDC_ECM_CONFIG_DESC_SIZE), /* wTotalLength:no of returned bytes */
+ HIBYTE(CDC_ECM_CONFIG_DESC_SIZE),
+ 0x02, /* bNumInterfaces: 2 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower (mA) */
+
+ /*---------------------------------------------------------------------------*/
+
+ /* IAD descriptor */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_ECM_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass (Wireless Controller) */
+ 0x06, /* bFunctionSubClass */
+ 0x00, /* bFunctionProtocol */
+ _CDC_ECM_STR_DESC_IDX, /* iFunction */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _CDC_ECM_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoint used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x06, /* bInterfaceSubClass: Ethernet Control Model */
+ 0x00, /* bInterfaceProtocol: No specific protocol required */
+ 0x00, /* iInterface */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header functional descriptor */
+ 0x10, /* bcd CDC_ECM: spec release number: 1.10 */
+ 0x01,
+
+ /* CDC_ECM Functional Descriptor */
+ 0x0D, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x0F, /* Ethernet Networking functional descriptor subtype */
+ CDC_ECM_MAC_STRING_INDEX, /* Device's MAC string index */
+ CDC_ECM_ETH_STATS_BYTE3, /* Ethernet statistics byte 3 (bitmap) */
+ CDC_ECM_ETH_STATS_BYTE2, /* Ethernet statistics byte 2 (bitmap) */
+ CDC_ECM_ETH_STATS_BYTE1, /* Ethernet statistics byte 1 (bitmap) */
+ CDC_ECM_ETH_STATS_BYTE0, /* Ethernet statistics byte 0 (bitmap) */
+ LOBYTE(CDC_ECM_ETH_MAX_SEGSZE),
+ HIBYTE(CDC_ECM_ETH_MAX_SEGSZE), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */
+ LOBYTE(CDC_ECM_ETH_NBR_MACFILTERS),
+ HIBYTE(CDC_ECM_ETH_NBR_MACFILTERS), /* wNumberMCFilters: the number of multicast filters */
+ CDC_ECM_ETH_NBR_PWRFILTERS, /* bNumberPowerFilters: the number of wakeup power filters */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union functional descriptor */
+ _CDC_ECM_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_ECM_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Communication Endpoint Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_ECM_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_ECM_CMD_PACKET_SIZE),
+ CDC_ECM_HS_BINTERVAL, /* bInterval */
+
+ /*----------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_ECM_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass */
+ 0x00, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_ECM_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE),
+ 0xFF, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_ECM_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE),
+ 0xFF /* bInterval: ignore for Bulk transfer */
+};
+
+/* USB CDC_ECM device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[CDC_ECM_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /* Configuration Descriptor */
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ LOBYTE(CDC_ECM_CONFIG_DESC_SIZE), /* wTotalLength: Total size of the Config descriptor */
+ HIBYTE(CDC_ECM_CONFIG_DESC_SIZE),
+ 0x02, /* bNumInterfaces: 2 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower (mA) */
+
+ /*---------------------------------------------------------------------------*/
+ /* IAD descriptor */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_ECM_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass (Wireless Controller) */
+ 0x06, /* bFunctionSubClass */
+ 0x00, /* bFunctionProtocol */
+ _CDC_ECM_STR_DESC_IDX, /* iFunction */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _CDC_ECM_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoint used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x06, /* bInterfaceSubClass: Ethernet Control Model */
+ 0x00, /* bInterfaceProtocol: No specific protocol required */
+ 0x00, /* iInterface */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header functional descriptor */
+ 0x10, /* bcd CDC_ECM : spec release number: 1.20 */
+ 0x01,
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union functional descriptor */
+ _CDC_ECM_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_ECM_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* CDC_ECM Functional Descriptor */
+ 0x0D, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x0F, /* Ethernet Networking functional descriptor subtype */
+ CDC_ECM_MAC_STRING_INDEX, /* Device's MAC string index */
+ CDC_ECM_ETH_STATS_BYTE3, /* Ethernet statistics byte 3 (bitmap) */
+ CDC_ECM_ETH_STATS_BYTE2, /* Ethernet statistics byte 2 (bitmap) */
+ CDC_ECM_ETH_STATS_BYTE1, /* Ethernet statistics byte 1 (bitmap) */
+ CDC_ECM_ETH_STATS_BYTE0, /* Ethernet statistics byte 0 (bitmap) */
+ LOBYTE(CDC_ECM_ETH_MAX_SEGSZE),
+ HIBYTE(CDC_ECM_ETH_MAX_SEGSZE), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */
+ LOBYTE(CDC_ECM_ETH_NBR_MACFILTERS),
+ HIBYTE(CDC_ECM_ETH_NBR_MACFILTERS), /* wNumberMCFilters: the number of multicast filters */
+ CDC_ECM_ETH_NBR_PWRFILTERS, /* bNumberPowerFilters: the number of wakeup power filters */
+
+ /* Communication Endpoint Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_ECM_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_ECM_CMD_PACKET_SIZE),
+ CDC_ECM_FS_BINTERVAL, /* bInterval */
+
+ /*----------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_ECM_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC_ECM */
+ 0x00, /* bInterfaceSubClass */
+ 0x00, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_ECM_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE),
+ 0xFF, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_ECM_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE),
+ 0xFF /* bInterval: ignore for Bulk transfer */
+};
+
+__ALIGN_BEGIN static uint8_t USBD_CDC_ECM_OtherSpeedCfgDesc[CDC_ECM_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /* Configuration Descriptor */
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ LOBYTE(CDC_ECM_CONFIG_DESC_SIZE), /* wTotalLength */
+ HIBYTE(CDC_ECM_CONFIG_DESC_SIZE),
+ 0x02, /* bNumInterfaces: 2 interfaces */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x04, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower (mA) */
+
+ /*--------------------------------------- ------------------------------------*/
+ /* IAD descriptor */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_ECM_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0x02, /* bFunctionClass (Wireless Controller) */
+ 0x06, /* bFunctionSubClass */
+ 0x00, /* bFunctionProtocol */
+ _CDC_ECM_STR_DESC_IDX, /* iFunction */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _CDC_ECM_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoint used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x06, /* bInterfaceSubClass: Ethernet Control Model */
+ 0x00, /* bInterfaceProtocol: No specific protocol required */
+ 0x00, /* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header functional descriptor */
+ 0x10, /* bcd CDC_ECM : spec release number: 1.20 */
+ 0x01,
+
+ /* CDC_ECM Functional Descriptor */
+ 0x0D, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x0F, /* Ethernet Networking functional descriptor subtype */
+ CDC_ECM_MAC_STRING_INDEX, /* Device's MAC string index */
+ CDC_ECM_ETH_STATS_BYTE3, /* Ethernet statistics byte 3 (bitmap) */
+ CDC_ECM_ETH_STATS_BYTE2, /* Ethernet statistics byte 2 (bitmap) */
+ CDC_ECM_ETH_STATS_BYTE1, /* Ethernet statistics byte 1 (bitmap) */
+ CDC_ECM_ETH_STATS_BYTE0, /* Ethernet statistics byte 0 (bitmap) */
+ LOBYTE(CDC_ECM_ETH_MAX_SEGSZE),
+ HIBYTE(CDC_ECM_ETH_MAX_SEGSZE), /* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */
+ LOBYTE(CDC_ECM_ETH_NBR_MACFILTERS),
+ HIBYTE(CDC_ECM_ETH_NBR_MACFILTERS), /* wNumberMCFilters: the number of multicast filters */
+ CDC_ECM_ETH_NBR_PWRFILTERS, /* bNumberPowerFilters: the number of wakeup power filters */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union functional descriptor */
+ _CDC_ECM_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_ECM_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Communication Endpoint Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_ECM_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_ECM_CMD_PACKET_SIZE),
+ CDC_ECM_FS_BINTERVAL, /* bInterval */
+
+ /*----------------------*/
+
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: interface */
+ _CDC_ECM_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass */
+ 0x00, /* bInterfaceProtocol */
+ 0x00, /* iInterface: */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_ECM_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ 0x40, /* wMaxPacketSize */
+ 0x00,
+ 0xFF, /* bInterval: ignore for Bulk transfer */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_ECM_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ 0x40, /* wMaxPacketSize */
+ 0x00,
+ 0xFF /* bInterval: ignore for Bulk transfer */
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_ECM_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_CDC_ECM_Init
+ * Initialize the CDC_ECM interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_CDC_ECM_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ USBD_CDC_ECM_HandleTypeDef *hcdc;
+
+ hcdc = &CDC_ECM_Instance;
+
+ if (hcdc == NULL)
+ {
+ pdev->pClassData_CDC_ECM = NULL;
+ return (uint8_t)USBD_EMEM;
+ }
+
+ pdev->pClassData_CDC_ECM = (void *)hcdc;
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, CDC_ECM_IN_EP, USBD_EP_TYPE_BULK,
+ CDC_ECM_DATA_HS_IN_PACKET_SIZE);
+
+ pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 1U;
+
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, CDC_ECM_OUT_EP, USBD_EP_TYPE_BULK,
+ CDC_ECM_DATA_HS_OUT_PACKET_SIZE);
+
+ pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 1U;
+
+ /* Set bInterval for CDC ECM CMD Endpoint */
+ pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].bInterval = CDC_ECM_HS_BINTERVAL;
+ }
+ else
+ {
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, CDC_ECM_IN_EP, USBD_EP_TYPE_BULK,
+ CDC_ECM_DATA_FS_IN_PACKET_SIZE);
+
+ pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 1U;
+
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, CDC_ECM_OUT_EP, USBD_EP_TYPE_BULK,
+ CDC_ECM_DATA_FS_OUT_PACKET_SIZE);
+
+ pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 1U;
+
+ /* Set bInterval for CDC ECM CMD Endpoint */
+ pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].bInterval = CDC_ECM_FS_BINTERVAL;
+ }
+
+ /* Open Command IN EP */
+ (void)USBD_LL_OpenEP(pdev, CDC_ECM_CMD_EP, USBD_EP_TYPE_INTR, CDC_ECM_CMD_PACKET_SIZE);
+ pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].is_used = 1U;
+
+ /* Init physical Interface components */
+ ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData_CDC_ECM)->Init();
+
+ /* Init Xfer states */
+ hcdc->TxState = 0U;
+ hcdc->RxState = 0U;
+ hcdc->RxLength = 0U;
+ hcdc->TxLength = 0U;
+ hcdc->LinkStatus = 0U;
+ hcdc->NotificationStatus = 0U;
+ hcdc->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? CDC_ECM_DATA_HS_MAX_PACKET_SIZE : CDC_ECM_DATA_FS_MAX_PACKET_SIZE;
+
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP, hcdc->RxBuffer, hcdc->MaxPcktLen);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_ECM_DeInit
+ * DeInitialize the CDC_ECM layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_CDC_ECM_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ /* Close EP IN */
+ (void)USBD_LL_CloseEP(pdev, CDC_ECM_IN_EP);
+ pdev->ep_in[CDC_ECM_IN_EP & 0xFU].is_used = 0U;
+
+ /* Close EP OUT */
+ (void)USBD_LL_CloseEP(pdev, CDC_ECM_OUT_EP);
+ pdev->ep_out[CDC_ECM_OUT_EP & 0xFU].is_used = 0U;
+
+ /* Close Command IN EP */
+ (void)USBD_LL_CloseEP(pdev, CDC_ECM_CMD_EP);
+ pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].is_used = 0U;
+ pdev->ep_in[CDC_ECM_CMD_EP & 0xFU].bInterval = 0U;
+
+ /* DeInit physical Interface components */
+ if (pdev->pClassData_CDC_ECM != NULL)
+ {
+ ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData_CDC_ECM)->DeInit();
+#if (0)
+ USBD_free(pdev->pClassData_CDC_ECM);
+#endif
+ pdev->pClassData_CDC_ECM = NULL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_ECM_Setup
+ * Handle the CDC_ECM specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req)
+{
+ USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData_CDC_ECM;
+ USBD_CDC_ECM_ItfTypeDef *EcmInterface = (USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData_CDC_ECM;
+ USBD_StatusTypeDef ret = USBD_OK;
+ uint16_t len;
+ uint16_t status_info = 0U;
+ uint8_t ifalt = 0U;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS:
+ if (req->wLength != 0U)
+ {
+ if ((req->bmRequest & 0x80U) != 0U)
+ {
+ EcmInterface->Control(req->bRequest,
+ (uint8_t *)hcdc->data, req->wLength);
+
+ len = MIN(CDC_ECM_DATA_BUFFER_SIZE, req->wLength);
+ (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len);
+ }
+ else
+ {
+ hcdc->CmdOpCode = req->bRequest;
+ hcdc->CmdLength = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE);
+
+ (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength);
+ }
+ }
+ else
+ {
+ EcmInterface->Control(req->bRequest, (uint8_t *)req, 0U);
+ }
+ break;
+
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, &ifalt, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state != USBD_STATE_CONFIGURED)
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_CDC_ECM_DataIn
+ * Data sent on non-control IN endpoint
+ * @param pdev: device instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_CDC_ECM_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData_CDC_ECM;
+ PCD_HandleTypeDef *hpcd = pdev->pData;
+
+ if (pdev->pClassData_CDC_ECM == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if (epnum == (CDC_ECM_IN_EP & 0x7FU))
+ {
+ if ((pdev->ep_in[epnum].total_length > 0U) &&
+ ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
+ {
+ /* Update the packet total length */
+ pdev->ep_in[epnum].total_length = 0U;
+
+ /* Send ZLP */
+ (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
+ }
+ else
+ {
+ hcdc->TxState = 0U;
+ if (((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData_CDC_ECM)->TransmitCplt != NULL)
+ {
+ ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData_CDC_ECM)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
+ }
+ }
+ }
+ else if (epnum == (CDC_ECM_CMD_EP & 0x7FU))
+ {
+ if (hcdc->NotificationStatus != 0U)
+ {
+ (void)USBD_CDC_ECM_SendNotification(pdev, ECM_CONNECTION_SPEED_CHANGE,
+ 0U, (uint8_t *)ConnSpeedTab);
+
+ hcdc->NotificationStatus = 0U;
+ }
+ }
+ else
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_ECM_DataOut
+ * Data received on non-control Out endpoint
+ * @param pdev: device instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData_CDC_ECM;
+ uint32_t CurrPcktLen;
+
+ if (pdev->pClassData_CDC_ECM == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if (epnum == CDC_ECM_OUT_EP)
+ {
+ /* Get the received data length */
+ CurrPcktLen = USBD_LL_GetRxDataSize(pdev, epnum);
+
+ /* Increment the frame length */
+ hcdc->RxLength += CurrPcktLen;
+
+ /* If the buffer size is less than max packet size: it is the last packet in current frame */
+ if ((CurrPcktLen < hcdc->MaxPcktLen) || (hcdc->RxLength >= CDC_ECM_ETH_MAX_SEGSZE))
+ {
+ /* USB data will be immediately processed, this allow next USB traffic being
+ NAKed till the end of the application Xfer */
+
+ /* Process data by application (ie. copy to app buffer or notify user)
+ hcdc->RxLength must be reset to zero at the end of the call of this function */
+ ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData_CDC_ECM)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
+ }
+ else
+ {
+ /* Prepare Out endpoint to receive next packet in current/new frame */
+ (void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP,
+ (uint8_t *)(hcdc->RxBuffer + hcdc->RxLength),
+ hcdc->MaxPcktLen);
+ }
+ }
+ else
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_ECM_EP0_RxReady
+ * Handle EP0 Rx Ready event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+ USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData_CDC_ECM;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if ((pdev->pUserData_CDC_ECM != NULL) && (hcdc->CmdOpCode != 0xFFU))
+ {
+ ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData_CDC_ECM)->Control(hcdc->CmdOpCode, (uint8_t *)hcdc->data, (uint16_t)hcdc->CmdLength);
+ hcdc->CmdOpCode = 0xFFU;
+ }
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_ECM_GetFSCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_ECM_GetFSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CDC_ECM_CfgFSDesc);
+
+ return USBD_CDC_ECM_CfgFSDesc;
+}
+
+/**
+ * @brief USBD_CDC_ECM_GetHSCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_ECM_GetHSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CDC_ECM_CfgHSDesc);
+
+ return USBD_CDC_ECM_CfgHSDesc;
+}
+
+/**
+ * @brief USBD_CDC_ECM_GetCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_ECM_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CDC_ECM_OtherSpeedCfgDesc);
+
+ return USBD_CDC_ECM_OtherSpeedCfgDesc;
+}
+
+/**
+ * @brief DeviceQualifierDescriptor
+ * return Device Qualifier descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+uint8_t *USBD_CDC_ECM_GetDeviceQualifierDescriptor(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CDC_ECM_DeviceQualifierDesc);
+
+ return USBD_CDC_ECM_DeviceQualifierDesc;
+}
+
+/**
+ * @brief USBD_CDC_ECM_RegisterInterface
+ * @param pdev: device instance
+ * @param fops: CD Interface callback
+ * @retval status
+ */
+uint8_t USBD_CDC_ECM_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_CDC_ECM_ItfTypeDef *fops)
+{
+ if (fops == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ pdev->pUserData_CDC_ECM = fops;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_ECM_USRStringDescriptor
+ * Manages the transfer of user string descriptors.
+ * @param speed : current device speed
+ * @param index: descriptor index
+ * @param length : pointer data length
+ * @retval pointer to the descriptor table or NULL if the descriptor is not supported.
+ */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+static uint8_t *USBD_CDC_ECM_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length)
+{
+ static uint8_t USBD_StrDesc[255];
+
+ /* Check if the requested string interface is supported */
+ if (index == CDC_ECM_MAC_STRING_INDEX)
+ {
+ USBD_GetString((uint8_t *)((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData_CDC_ECM)->pStrDesc, USBD_StrDesc, length);
+ return USBD_StrDesc;
+ }
+ /* Not supported Interface Descriptor index */
+ else
+ {
+ return NULL;
+ }
+}
+#endif
+
+/**
+ * @brief USBD_CDC_ECM_SetTxBuffer
+ * @param pdev: device instance
+ * @param pbuff: Tx Buffer
+ * @retval status
+ */
+uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length)
+{
+ USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData_CDC_ECM;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hcdc->TxBuffer = pbuff;
+ hcdc->TxLength = length;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_ECM_SetRxBuffer
+ * @param pdev: device instance
+ * @param pbuff: Rx Buffer
+ * @retval status
+ */
+uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
+{
+ USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData_CDC_ECM;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hcdc->RxBuffer = pbuff;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_ECM_TransmitPacket
+ * Transmit packet on IN endpoint
+ * @param pdev: device instance
+ * @retval status
+ */
+uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev)
+{
+ USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData_CDC_ECM;
+ USBD_StatusTypeDef ret = USBD_BUSY;
+
+ if (pdev->pClassData_CDC_ECM == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if (hcdc->TxState == 0U)
+ {
+ /* Tx Transfer in progress */
+ hcdc->TxState = 1U;
+
+ /* Update the packet total length */
+ pdev->ep_in[CDC_ECM_IN_EP & 0xFU].total_length = hcdc->TxLength;
+
+ /* Transmit next packet */
+ (void)USBD_LL_Transmit(pdev, CDC_ECM_IN_EP, hcdc->TxBuffer, hcdc->TxLength);
+
+ ret = USBD_OK;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_CDC_ECM_ReceivePacket
+ * prepare OUT Endpoint for reception
+ * @param pdev: device instance
+ * @retval status
+ */
+uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev)
+{
+ USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData_CDC_ECM;
+
+ if (pdev->pClassData_CDC_ECM == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP, hcdc->RxBuffer, hcdc->MaxPcktLen);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_ECM_SendNotification
+ * Transmit Notification packet on CMD IN interrupt endpoint
+ * @param pdev: device instance
+ * Notif: value of the notification type (from CDC_ECM_Notification_TypeDef enumeration list)
+ * bVal: value of the notification switch (ie. 0x00 or 0x01 for Network Connection notification)
+ * pData: pointer to data buffer (ie. upstream and downstream connection speed values)
+ * @retval status
+ */
+uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev,
+ USBD_CDC_ECM_NotifCodeTypeDef Notif,
+ uint16_t bVal, uint8_t *pData)
+{
+ uint32_t Idx;
+ uint32_t ReqSize = 0U;
+ USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData_CDC_ECM;
+ USBD_StatusTypeDef ret = USBD_OK;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Initialize the request fields */
+ (hcdc->Req).bmRequest = CDC_ECM_BMREQUEST_TYPE_ECM;
+ (hcdc->Req).bRequest = (uint8_t)Notif;
+
+ switch ((hcdc->Req).bRequest)
+ {
+ case ECM_NETWORK_CONNECTION:
+ (hcdc->Req).wValue = bVal;
+ (hcdc->Req).wIndex = CDC_ECM_CMD_ITF_NBR;
+ (hcdc->Req).wLength = 0U;
+
+ for (Idx = 0U; Idx < 8U; Idx++)
+ {
+ (hcdc->Req).data[Idx] = 0U;
+ }
+ ReqSize = 8U;
+ break;
+
+ case ECM_RESPONSE_AVAILABLE:
+ (hcdc->Req).wValue = 0U;
+ (hcdc->Req).wIndex = CDC_ECM_CMD_ITF_NBR;
+ (hcdc->Req).wLength = 0U;
+ for (Idx = 0U; Idx < 8U; Idx++)
+ {
+ (hcdc->Req).data[Idx] = 0U;
+ }
+ ReqSize = 8U;
+ break;
+
+ case ECM_CONNECTION_SPEED_CHANGE:
+ (hcdc->Req).wValue = 0U;
+ (hcdc->Req).wIndex = CDC_ECM_CMD_ITF_NBR;
+ (hcdc->Req).wLength = 0x0008U;
+ ReqSize = 16U;
+
+ /* Check pointer to data buffer */
+ if (pData != NULL)
+ {
+ for (Idx = 0U; Idx < 8U; Idx++)
+ {
+ (hcdc->Req).data[Idx] = pData[Idx];
+ }
+ }
+ break;
+
+ default:
+ ret = USBD_FAIL;
+ break;
+ }
+
+ /* Transmit notification packet */
+ if (ReqSize != 0U)
+ {
+ (void)USBD_LL_Transmit(pdev, CDC_ECM_CMD_EP, (uint8_t *)&(hcdc->Req), ReqSize);
+ }
+
+ return (uint8_t)ret;
+}
+
+void USBD_Update_CDC_ECM_DESC(uint8_t *desc,
+ uint8_t cmd_itf,
+ uint8_t com_itf,
+ uint8_t in_ep,
+ uint8_t cmd_ep,
+ uint8_t out_ep,
+ uint8_t str_idx)
+{
+ desc[11] = cmd_itf;
+ desc[16] = str_idx;
+ desc[19] = cmd_itf;
+ desc[47] = com_itf;
+ desc[48] = cmd_itf;
+ desc[51] = cmd_ep;
+ desc[58] = com_itf;
+ desc[67] = out_ep;
+ desc[74] = in_ep;
+
+ CDC_ECM_IN_EP = in_ep;
+ CDC_ECM_OUT_EP = out_ep;
+ CDC_ECM_CMD_EP = cmd_ep;
+ CDC_ECM_CMD_ITF_NBR = cmd_itf;
+ CDC_ECM_COM_ITF_NBR = com_itf;
+ CDC_ECM_STR_DESC_IDX = str_idx;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h
new file mode 100644
index 0000000..e3f4537
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h
@@ -0,0 +1,530 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_rndis.h
+ * @author MCD Application Team
+ * @brief header file for the usbd_cdc_rndis.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CDC_RNDIS_H
+#define __USB_CDC_RNDIS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+
+ /** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+ /** @defgroup usbd_cdc_rndis
+ * @brief This file is the Header file for usbd_cdc_rndis.c
+ * @{
+ */
+
+ /** @defgroup usbd_cdc_rndis_Exported_Defines
+ * @{
+ */
+
+#define CDC_RNDIS_STR_DESC "STM32 CDC RNDIS"
+
+#ifndef CDC_RNDIS_HS_BINTERVAL
+#define CDC_RNDIS_HS_BINTERVAL 0x10U
+#endif /* CDC_RNDIS_HS_BINTERVAL */
+
+#ifndef CDC_RNDIS_FS_BINTERVAL
+#define CDC_RNDIS_FS_BINTERVAL 0x10U
+#endif /* CDC_RNDIS_FS_BINTERVAL */
+
+
+/* CDC_RNDIS Endpoints parameters: you can fine tune these values
+ depending on the needed baudrates and performance. */
+#define CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
+#define CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
+#define CDC_RNDIS_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */
+
+#define CDC_RNDIS_CONFIG_DESC_SIZE 75U
+#define CDC_RNDIS_DATA_HS_IN_PACKET_SIZE CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE
+#define CDC_RNDIS_DATA_HS_OUT_PACKET_SIZE CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE
+
+#define CDC_RNDIS_DATA_FS_IN_PACKET_SIZE CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE
+#define CDC_RNDIS_DATA_FS_OUT_PACKET_SIZE CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE
+
+/*---------------------------------------------------------------------*/
+/* CDC_RNDIS definitions */
+/*---------------------------------------------------------------------*/
+
+/** Implemented CDC_RNDIS Version Major */
+#define CDC_RNDIS_VERSION_MAJOR 0x01U
+
+/* Implemented CDC_RNDIS Version Minor */
+#define CDC_RNDIS_VERSION_MINOR 0x00U
+
+/* Maximum size in bytes of a CDC_RNDIS control message
+ which can be sent or received */
+#define CDC_RNDIS_MESSAGE_BUFFER_SIZE 128U
+
+/* Maximum size in bytes of an Ethernet frame
+ according to the Ethernet standard */
+#define CDC_RNDIS_ETH_FRAME_SIZE_MAX 1536U
+
+/* Maximum size allocated for buffer
+ inside Query messages structures */
+#define CDC_RNDIS_MAX_INFO_BUFF_SZ 200U
+#define CDC_RNDIS_MAX_DATA_SZE 2000U
+
+/* Notification request value for a CDC_RNDIS
+ Response Available notification */
+#define CDC_RNDIS_NOTIFICATION_RESP_AVAILABLE 0x00000001UL
+
+
+#define CDC_RNDIS_PACKET_MSG_ID 0x00000001UL
+#define CDC_RNDIS_INITIALIZE_MSG_ID 0x00000002UL
+#define CDC_RNDIS_HALT_MSG_ID 0x00000003UL
+#define CDC_RNDIS_QUERY_MSG_ID 0x00000004UL
+#define CDC_RNDIS_SET_MSG_ID 0x00000005UL
+#define CDC_RNDIS_RESET_MSG_ID 0x00000006UL
+#define CDC_RNDIS_INDICATE_STATUS_MSG_ID 0x00000007UL
+#define CDC_RNDIS_KEEPALIVE_MSG_ID 0x00000008UL
+
+#define CDC_RNDIS_INITIALIZE_CMPLT_ID 0x80000002UL
+#define CDC_RNDIS_QUERY_CMPLT_ID 0x80000004UL
+#define CDC_RNDIS_SET_CMPLT_ID 0x80000005UL
+#define CDC_RNDIS_RESET_CMPLT_ID 0x80000006UL
+#define CDC_RNDIS_KEEPALIVE_CMPLT_ID 0x80000008UL
+
+#define CDC_RNDIS_STATUS_SUCCESS 0x00000000UL
+#define CDC_RNDIS_STATUS_FAILURE 0xC0000001UL
+#define CDC_RNDIS_STATUS_INVALID_DATA 0xC0010015UL
+#define CDC_RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL
+#define CDC_RNDIS_STATUS_MEDIA_CONNECT 0x4001000BUL
+#define CDC_RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL
+/** Media state */
+#define CDC_RNDIS_MEDIA_STATE_CONNECTED 0x00000000UL
+#define CDC_RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL
+
+/** Media types */
+#define CDC_RNDIS_MEDIUM_802_3 0x00000000UL
+
+#define CDC_RNDIS_DF_CONNECTIONLESS 0x00000001UL
+#define CDC_RNDIS_DF_CONNECTION_ORIENTED 0x00000002UL
+
+/** Hardware status of the underlying NIC */
+#define CDC_RNDIS_HW_STS_READY 0x00000000UL
+#define CDC_RNDIS_HW_STS_INITIALIZING 0x00000001UL
+#define CDC_RNDIS_HW_STS_RESET 0x00000002UL
+#define CDC_RNDIS_HW_STS_CLOSING 0x00000003UL
+#define CDC_RNDIS_HW_STS_NOT_READY 0x00000004UL
+
+/** Packet filter */
+#define CDC_RNDIS_PACKET_DIRECTED 0x00000001UL
+#define CDC_RNDIS_PACKET_MULTICAST 0x00000002UL
+#define CDC_RNDIS_PACKET_ALL_MULTICAST 0x00000004UL
+#define CDC_RNDIS_PACKET_BROADCAST 0x00000008UL
+#define CDC_RNDIS_PACKET_SOURCE_ROUTING 0x00000010UL
+#define CDC_RNDIS_PACKET_PROMISCUOUS 0x00000020UL
+#define CDC_RNDIS_PACKET_SMT 0x00000040UL
+#define CDC_RNDIS_PACKET_ALL_LOCAL 0x00000080UL
+#define CDC_RNDIS_PACKET_GROUP 0x00001000UL
+#define CDC_RNDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL
+#define CDC_RNDIS_PACKET_FUNCTIONAL 0x00004000UL
+#define CDC_RNDIS_PACKET_MAC_FRAME 0x00008000UL
+
+#define OID_GEN_SUPPORTED_LIST 0x00010101UL
+#define OID_GEN_HARDWARE_STATUS 0x00010102UL
+#define OID_GEN_MEDIA_SUPPORTED 0x00010103UL
+#define OID_GEN_MEDIA_IN_USE 0x00010104UL
+#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL
+#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL
+#define OID_GEN_LINK_SPEED 0x00010107UL
+#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL
+#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL
+#define OID_GEN_VENDOR_ID 0x0001010CUL
+#define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL
+#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL
+#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
+#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115UL
+#define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL
+#define OID_GEN_XMIT_OK 0x00020101UL
+#define OID_GEN_RCV_OK 0x00020102UL
+#define OID_GEN_XMIT_ERROR 0x00020103UL
+#define OID_GEN_RCV_ERROR 0x00020104UL
+#define OID_GEN_RCV_NO_BUFFER 0x00020105UL
+#define OID_GEN_CDC_RNDIS_CONFIG_PARAMETER 0x0001021BUL
+#define OID_802_3_PERMANENT_ADDRESS 0x01010101UL
+#define OID_802_3_CURRENT_ADDRESS 0x01010102UL
+#define OID_802_3_MULTICAST_LIST 0x01010103UL
+#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL
+#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL
+#define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL
+#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL
+
+
+#define CDC_RNDIS_SEND_ENCAPSULATED_COMMAND 0x00U
+#define CDC_RNDIS_GET_ENCAPSULATED_RESPONSE 0x01U
+
+#define CDC_RNDIS_NET_DISCONNECTED 0x00U
+#define CDC_RNDIS_NET_CONNECTED 0x01U
+
+#define CDC_RNDIS_BMREQUEST_TYPE_RNDIS 0xA1U
+#define CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET 8U
+
+/* MAC String index */
+#define CDC_RNDIS_MAC_STRING_INDEX 6U
+
+/**
+ * @}
+ */
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+ typedef struct _USBD_CDC_RNDIS_Itf
+ {
+ int8_t (*Init)(void);
+ int8_t (*DeInit)(void);
+ int8_t (*Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length);
+ int8_t (*Receive)(uint8_t *Buf, uint32_t *Len);
+ int8_t (*TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum);
+ int8_t (*Process)(USBD_HandleTypeDef *pdev);
+ uint8_t *pStrDesc;
+ } USBD_CDC_RNDIS_ItfTypeDef;
+
+ /* CDC_RNDIS State values */
+ typedef enum
+ {
+ CDC_RNDIS_STATE_UNINITIALIZED = 0,
+ CDC_RNDIS_STATE_BUS_INITIALIZED = 1,
+ CDC_RNDIS_STATE_INITIALIZED = 2,
+ CDC_RNDIS_STATE_DATA_INITIALIZED = 3
+ } USBD_CDC_RNDIS_StateTypeDef;
+
+ typedef struct
+ {
+ uint8_t bmRequest;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+ uint8_t data[8];
+ } USBD_CDC_RNDIS_NotifTypeDef;
+
+ typedef struct
+ {
+ uint32_t data[CDC_RNDIS_MAX_DATA_SZE / 4U]; /* Force 32-bit alignment */
+ uint8_t CmdOpCode;
+ uint8_t CmdLength;
+ uint8_t ResponseRdy; /* Indicates if the Device Response to an CDC_RNDIS msg is ready */
+ uint8_t Reserved1; /* Reserved Byte to force 4 bytes alignment of following fields */
+ uint8_t *RxBuffer;
+ uint8_t *TxBuffer;
+ uint32_t RxLength;
+ uint32_t TxLength;
+
+ USBD_CDC_RNDIS_NotifTypeDef Req;
+ USBD_CDC_RNDIS_StateTypeDef State;
+
+ __IO uint32_t TxState;
+ __IO uint32_t RxState;
+
+ __IO uint32_t MaxPcktLen;
+ __IO uint32_t LinkStatus;
+ __IO uint32_t NotificationStatus;
+ __IO uint32_t PacketFilter;
+ } USBD_CDC_RNDIS_HandleTypeDef;
+
+ typedef enum
+ {
+ RNDIS_NETWORK_CONNECTION = 0x00,
+ RNDIS_RESPONSE_AVAILABLE = 0x01,
+ RNDIS_CONNECTION_SPEED_CHANGE = 0x2A
+ } USBD_CDC_RNDIS_NotifCodeTypeDef;
+
+ /* Messages Sent by the Host ---------------------*/
+
+ /* Type define for a CDC_RNDIS Initialize command message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t ReqId;
+ uint32_t MajorVersion;
+ uint32_t MinorVersion;
+ uint32_t MaxTransferSize;
+ } USBD_CDC_RNDIS_InitMsgTypeDef;
+
+ /* Type define for a CDC_RNDIS Halt Message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t ReqId;
+ } USBD_CDC_RNDIS_HaltMsgTypeDef;
+
+ /* Type define for a CDC_RNDIS Query command message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t RequestId;
+ uint32_t Oid;
+ uint32_t InfoBufLength;
+ uint32_t InfoBufOffset;
+ uint32_t DeviceVcHandle;
+ uint32_t InfoBuf[CDC_RNDIS_MAX_INFO_BUFF_SZ];
+ } USBD_CDC_RNDIS_QueryMsgTypeDef;
+
+ /* Type define for a CDC_RNDIS Set command message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t ReqId;
+ uint32_t Oid;
+ uint32_t InfoBufLength;
+ uint32_t InfoBufOffset;
+ uint32_t DeviceVcHandle;
+ uint32_t InfoBuf[CDC_RNDIS_MAX_INFO_BUFF_SZ];
+ } USBD_CDC_RNDIS_SetMsgTypeDef;
+
+ /* Type define for a CDC_RNDIS Reset message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t Reserved;
+ } USBD_CDC_RNDIS_ResetMsgTypeDef;
+
+ /* Type define for a CDC_RNDIS Keepalive command message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t ReqId;
+ } USBD_CDC_RNDIS_KpAliveMsgTypeDef;
+
+ /* Messages Sent by the Device ---------------------*/
+
+ /* Type define for a CDC_RNDIS Initialize complete response message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t ReqId;
+ uint32_t Status;
+ uint32_t MajorVersion;
+ uint32_t MinorVersion;
+ uint32_t DeviceFlags;
+ uint32_t Medium;
+ uint32_t MaxPacketsPerTransfer;
+ uint32_t MaxTransferSize;
+ uint32_t PacketAlignmentFactor;
+ uint32_t AFListOffset;
+ uint32_t AFListSize;
+ } USBD_CDC_RNDIS_InitCpltMsgTypeDef;
+
+ /* Type define for a CDC_RNDIS Query complete response message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t ReqId;
+ uint32_t Status;
+ uint32_t InfoBufLength;
+ uint32_t InfoBufOffset;
+ uint32_t InfoBuf[CDC_RNDIS_MAX_INFO_BUFF_SZ];
+ } USBD_CDC_RNDIS_QueryCpltMsgTypeDef;
+
+ /* Type define for a CDC_RNDIS Set complete response message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t ReqId;
+ uint32_t Status;
+ } USBD_CDC_RNDIS_SetCpltMsgTypeDef;
+
+ /* Type define for a CDC_RNDIS Reset complete message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t Status;
+ uint32_t AddrReset;
+ } USBD_CDC_RNDIS_ResetCpltMsgTypeDef;
+
+ /* Type define for CDC_RNDIS struct to indicate a change
+ in the status of the device */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t Status;
+ uint32_t StsBufLength;
+ uint32_t StsBufOffset;
+ } USBD_CDC_RNDIS_StsChangeMsgTypeDef;
+
+ /* Type define for a CDC_RNDIS Keepalive complete message */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t ReqId;
+ uint32_t Status;
+ } USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef;
+
+ /* Messages Sent by both Host and Device ---------------------*/
+
+ /* Type define for a CDC_RNDIS packet message, used to encapsulate
+ Ethernet packets sent to and from the adapter */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t DataOffset;
+ uint32_t DataLength;
+ uint32_t OOBDataOffset;
+ uint32_t OOBDataLength;
+ uint32_t NumOOBDataElements;
+ uint32_t PerPacketInfoOffset;
+ uint32_t PerPacketInfoLength;
+ uint32_t VcHandle;
+ uint32_t Reserved;
+ } USBD_CDC_RNDIS_PacketMsgTypeDef;
+
+ /* Miscellaneous types used for parsing ---------------------*/
+
+ /* The common part for all CDC_RNDIS messages Complete response */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ uint32_t ReqId;
+ uint32_t Status;
+ } USBD_CDC_RNDIS_CommonCpltMsgTypeDef;
+
+ /* Type define for a single parameter structure */
+ typedef struct
+ {
+ uint32_t ParamNameOffset;
+ uint32_t ParamNameLength;
+ uint32_t ParamType;
+ uint32_t ParamValueOffset;
+ uint32_t ParamValueLength;
+ } USBD_CDC_RNDIS_ParamStructTypeDef;
+
+ /* Type define of a single CDC_RNDIS OOB data record */
+ typedef struct
+ {
+ uint32_t Size;
+ uint32_t Type;
+ uint32_t ClassInfoType;
+ uint32_t OOBData[sizeof(uint32_t)];
+ } USBD_CDC_RNDIS_OOBPacketTypeDef;
+
+ /* Type define for notification structure */
+ typedef struct
+ {
+ uint32_t notification;
+ uint32_t reserved;
+ } USBD_CDC_RNDIS_NotifStructTypeDef;
+
+ /* This structure will be used to store the type, the size and ID for any
+ received message from the control endpoint */
+ typedef struct
+ {
+ uint32_t MsgType;
+ uint32_t MsgLength;
+ } USBD_CDC_RNDIS_CtrlMsgTypeDef;
+
+ /** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+ /**
+ * @}
+ */
+
+ /** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+ extern USBD_ClassTypeDef USBD_CDC_RNDIS;
+
+ extern uint8_t CDC_RNDIS_IN_EP;
+ extern uint8_t CDC_RNDIS_OUT_EP;
+ extern uint8_t CDC_RNDIS_CMD_EP;
+
+ extern uint8_t CDC_RNDIS_CMD_ITF_NBR;
+ extern uint8_t CDC_RNDIS_COM_ITF_NBR;
+ extern uint8_t CDC_RNDIS_STR_DESC_IDX;
+
+ /**
+ * @}
+ */
+
+ /** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+ uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
+ uint8_t USBD_CDC_RNDIS_ReceivePacket(USBD_HandleTypeDef *pdev);
+ uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev);
+
+ uint8_t USBD_CDC_RNDIS_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_ItfTypeDef *fops);
+
+ uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev,
+ uint8_t *pbuff, uint32_t length);
+
+ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_NotifCodeTypeDef Notif,
+ uint16_t bVal, uint8_t *pData);
+
+ void USBD_Update_CDC_RNDIS_DESC(uint8_t *desc,
+ uint8_t cmd_itf,
+ uint8_t com_itf,
+ uint8_t in_ep,
+ uint8_t cmd_ep,
+ uint8_t out_ep,
+ uint8_t str_idx);
+
+ /**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_CDC_RNDIS_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c
new file mode 100644
index 0000000..529ce4a
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c
@@ -0,0 +1,1800 @@
+/**
+ ******************************************************************************
+ * @file usbd_cdc_rndis.c
+ * @author MCD Application Team
+ * @brief This file provides the high layer firmware functions to manage the
+ * following functionalities of the USB CDC_RNDIS Class:
+ * - Initialization and Configuration of high and low layer
+ * - Enumeration as CDC_RNDIS Device (and enumeration for each implemented memory interface)
+ * - OUT/IN data transfer
+ * - Command IN transfer (class requests management)
+ * - Error management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * CDC_RNDIS Class Driver Description
+ * ===================================================================
+ * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
+ * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
+ * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
+ * This driver implements the following aspects of the specification:
+ * - Device descriptor management
+ * - Configuration descriptor management
+ * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
+ * - Requests management (as described in section 6.2 in specification)
+ * - Abstract Control Model compliant
+ * - Union Functional collection (using 1 IN endpoint for control)
+ * - Data interface class
+ *
+ * These aspects may be enriched or modified for a specific user application.
+ *
+ * This driver doesn't implement the following aspects of the specification
+ * (but it is possible to manage these features with some modifications on this driver):
+ * - Any class-specific aspect relative to communication classes should be managed by user application.
+ * - All communication classes other than PSTN are not managed
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc_rndis.h"
+#include "usbd_ctlreq.h"
+
+#include "usbd_cdc_rndis_if.h"
+
+#define _CDC_RNDIS_IN_EP 0x81U /* EP1 for data IN */
+#define _CDC_RNDIS_OUT_EP 0x01U /* EP1 for data OUT */
+#define _CDC_RNDIS_CMD_EP 0x82U /* EP2 for CDC_RNDIS commands */
+#define _CDC_RNDIS_CMD_ITF_NBR 0x00U /* Command Interface Number 0 */
+#define _CDC_RNDIS_COM_ITF_NBR 0x01U /* Communication Interface Number 0 */
+#define _CDC_RNDIS_STR_DESC_IDX 0x00U
+
+uint8_t CDC_RNDIS_IN_EP = _CDC_RNDIS_IN_EP;
+uint8_t CDC_RNDIS_OUT_EP = _CDC_RNDIS_OUT_EP;
+uint8_t CDC_RNDIS_CMD_EP = _CDC_RNDIS_CMD_EP;
+uint8_t CDC_RNDIS_CMD_ITF_NBR = _CDC_RNDIS_CMD_ITF_NBR;
+uint8_t CDC_RNDIS_COM_ITF_NBR = _CDC_RNDIS_COM_ITF_NBR;
+uint8_t CDC_RNDIS_STR_DESC_IDX = _CDC_RNDIS_STR_DESC_IDX;
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_CDC_RNDIS
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_CDC_RNDIS_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_RNDIS_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_RNDIS_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_RNDIS_Private_FunctionPrototypes
+ * @{
+ */
+
+static uint8_t USBD_CDC_RNDIS_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_CDC_RNDIS_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+
+static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req);
+
+static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev);
+static uint8_t *USBD_CDC_RNDIS_GetFSCfgDesc(uint16_t *length);
+static uint8_t *USBD_CDC_RNDIS_GetHSCfgDesc(uint16_t *length);
+static uint8_t *USBD_CDC_RNDIS_GetOtherSpeedCfgDesc(uint16_t *length);
+static uint8_t *USBD_CDC_RNDIS_GetOtherSpeedCfgDesc(uint16_t *length);
+
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length);
+#endif
+
+uint8_t *USBD_CDC_RNDIS_GetDeviceQualifierDescriptor(uint16_t *length);
+
+/* CDC_RNDIS Internal messages parsing and construction functions */
+static uint8_t USBD_CDC_RNDIS_MsgParsing(USBD_HandleTypeDef *pdev, uint8_t *RxBuff);
+static uint8_t USBD_CDC_RNDIS_ProcessInitMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_InitMsgTypeDef *Msg);
+static uint8_t USBD_CDC_RNDIS_ProcessHaltMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_HaltMsgTypeDef *Msg);
+static uint8_t USBD_CDC_RNDIS_ProcessKeepAliveMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_KpAliveMsgTypeDef *Msg);
+static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_QueryMsgTypeDef *Msg);
+static uint8_t USBD_CDC_RNDIS_ProcessSetMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_SetMsgTypeDef *Msg);
+static uint8_t USBD_CDC_RNDIS_ProcessResetMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_ResetMsgTypeDef *Msg);
+static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_PacketMsgTypeDef *Msg);
+static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg);
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+static uint8_t MAC_StrDesc[6] = {CDC_RNDIS_MAC_ADDR0, CDC_RNDIS_MAC_ADDR1, CDC_RNDIS_MAC_ADDR2,
+ CDC_RNDIS_MAC_ADDR3, CDC_RNDIS_MAC_ADDR4, CDC_RNDIS_MAC_ADDR5};
+
+static uint32_t ConnSpeedTab[2] = {CDC_RNDIS_CONNECT_SPEED_UPSTREAM,
+ CDC_RNDIS_CONNECT_SPEED_DOWNSTREAM};
+
+static uint8_t EmptyResponse = 0x00U;
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_RNDIS_Private_Variables
+ * @{
+ */
+
+static USBD_CDC_RNDIS_HandleTypeDef CDC_RNDIS_Instance;
+
+/* CDC_RNDIS interface class callbacks structure */
+USBD_ClassTypeDef USBD_CDC_RNDIS =
+ {
+ USBD_CDC_RNDIS_Init,
+ USBD_CDC_RNDIS_DeInit,
+ USBD_CDC_RNDIS_Setup,
+ NULL, /* EP0_TxSent, */
+ USBD_CDC_RNDIS_EP0_RxReady,
+ USBD_CDC_RNDIS_DataIn,
+ USBD_CDC_RNDIS_DataOut,
+ NULL,
+ NULL,
+ NULL,
+ USBD_CDC_RNDIS_GetHSCfgDesc,
+ USBD_CDC_RNDIS_GetFSCfgDesc,
+ USBD_CDC_RNDIS_GetOtherSpeedCfgDesc,
+ USBD_CDC_RNDIS_GetDeviceQualifierDescriptor,
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ USBD_CDC_RNDIS_USRStringDescriptor,
+#endif
+};
+
+/* USB CDC_RNDIS device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgHSDesc[CDC_RNDIS_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /* Configuration Descriptor */
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ LOBYTE(CDC_RNDIS_CONFIG_DESC_SIZE), /* wTotalLength: Total size of the Config descriptor */
+ HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZE),
+ 0x02, /* bNumInterfaces: 2 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA */
+
+ /*---------------------------------------------------------------------------*/
+ /* IAD descriptor */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_RNDIS_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0xE0, /* bFunctionClass (Wireless Controller) */
+ 0x01, /* bFunctionSubClass */
+ 0x03, /* bFunctionProtocol */
+ _CDC_RNDIS_STR_DESC_IDX, /* iFunction */
+
+ /*---------------------------------------------------------------------------*/
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _CDC_RNDIS_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoint used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass:Abstract Control Model */
+ 0xFF, /* bInterfaceProtocol: Common AT commands */
+ 0x00, /* iInterface: */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header functional descriptor */
+ 0x10, /* bcdCDC: spec release number: 1.20 */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_RNDIS_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x00, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union functional descriptor */
+ _CDC_RNDIS_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_RNDIS_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Notification Endpoint Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_RNDIS_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_RNDIS_CMD_PACKET_SIZE),
+ CDC_RNDIS_HS_BINTERVAL, /* bInterval */
+
+ /*---------------------------------------------------------------------------*/
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_RNDIS_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass */
+ 0x00, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_RNDIS_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_RNDIS_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE),
+ 0x00 /* bInterval */
+};
+
+/* USB CDC device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[CDC_RNDIS_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /* Configuration Descriptor */
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ LOBYTE(CDC_RNDIS_CONFIG_DESC_SIZE), /* wTotalLength: Total size of the Config descriptor */
+ HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZE),
+ 0x02, /* bNumInterfaces: 2 interfaces */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA */
+
+ /*---------------------------------------------------------------------------*/
+ /* IAD descriptor */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_RNDIS_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0xE0, /* bFunctionClass (Wireless Controller) */
+ 0x01, /* bFunctionSubClass */
+ 0x03, /* bFunctionProtocol */
+ _CDC_RNDIS_STR_DESC_IDX, /* iFunction */
+
+ /*---------------------------------------------------------------------------*/
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _CDC_RNDIS_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoint used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass:Abstract Control Model */
+ 0xFF, /* bInterfaceProtocol: Common AT commands */
+ 0x00, /* iInterface */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header functional descriptor */
+ 0x10, /* bcdCDC: spec release number: 1.20 */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_RNDIS_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x00, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union functional descriptor */
+ _CDC_RNDIS_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_RNDIS_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Notification Endpoint Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_RNDIS_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_RNDIS_CMD_PACKET_SIZE),
+ CDC_RNDIS_FS_BINTERVAL, /* bInterval */
+
+ /*---------------------------------------------------------------------------*/
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_RNDIS_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass */
+ 0x00, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_RNDIS_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
+ HIBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE),
+ 0x00, /* bInterval */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_RNDIS_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE),
+ 0x00 /* bInterval */
+};
+
+__ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_OtherSpeedCfgDesc[] __ALIGN_END =
+ {
+ /* Configuration Descriptor */
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ LOBYTE(CDC_RNDIS_CONFIG_DESC_SIZE), /* wTotalLength:no of returned bytes */
+ HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZE),
+ 0x02, /* bNumInterfaces: 2 interfaces */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x04, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower (mA) */
+
+ /*---------------------------------------------------------------------------*/
+ /* IAD descriptor */
+ 0x08, /* bLength */
+ 0x0B, /* bDescriptorType */
+ _CDC_RNDIS_CMD_ITF_NBR, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ 0xE0, /* bFunctionClass (Wireless Controller) */
+ 0x01, /* bFunctionSubClass */
+ 0x03, /* bFunctionProtocol */
+ _CDC_RNDIS_STR_DESC_IDX, /* iFunction */
+
+ /*---------------------------------------------------------------------------*/
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _CDC_RNDIS_CMD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints: One endpoint used */
+ 0x02, /* bInterfaceClass: Communication Interface Class */
+ 0x02, /* bInterfaceSubClass:Abstract Control Model */
+ 0xFF, /* bInterfaceProtocol: Common AT commands */
+ 0x00, /* iInterface */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength: Endpoint Descriptor size */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x00, /* bDescriptorSubtype: Header functional descriptor */
+ 0x10, /* bcdCDC: spec release number: 1.20 */
+ 0x01,
+
+ /* Call Management Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x01, /* bDescriptorSubtype: Call Management Func Desc */
+ 0x00, /* bmCapabilities: D0+D1 */
+ _CDC_RNDIS_COM_ITF_NBR, /* bDataInterface: 1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
+ 0x00, /* bmCapabilities */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptorType: CS_INTERFACE */
+ 0x06, /* bDescriptorSubtype: Union functional descriptor */
+ _CDC_RNDIS_CMD_ITF_NBR, /* bMasterInterface: Communication class interface */
+ _CDC_RNDIS_COM_ITF_NBR, /* bSlaveInterface0: Data Class Interface */
+
+ /* Communication Endpoint Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_RNDIS_CMD_EP, /* bEndpointAddress */
+ 0x03, /* bmAttributes: Interrupt */
+ LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(CDC_RNDIS_CMD_PACKET_SIZE),
+ CDC_RNDIS_FS_BINTERVAL, /* bInterval */
+
+ /*---------------------------------------------------------------------------*/
+ /* Data class interface descriptor */
+ 0x09, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
+ _CDC_RNDIS_COM_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: Two endpoints used */
+ 0x0A, /* bInterfaceClass: CDC */
+ 0x00, /* bInterfaceSubClass */
+ 0x00, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_RNDIS_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ 0x40, /* wMaxPacketSize */
+ 0x00,
+ 0x00, /* bInterval */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _CDC_RNDIS_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ 0x40, /* wMaxPacketSize */
+ 0x00,
+ 0x00 /* bInterval */
+};
+
+static const uint32_t CDC_RNDIS_SupportedOIDs[] =
+ {
+ OID_GEN_SUPPORTED_LIST,
+ OID_GEN_HARDWARE_STATUS,
+ OID_GEN_MEDIA_SUPPORTED,
+ OID_GEN_MEDIA_IN_USE,
+ OID_GEN_MAXIMUM_FRAME_SIZE,
+ OID_GEN_LINK_SPEED,
+ OID_GEN_TRANSMIT_BLOCK_SIZE,
+ OID_GEN_RECEIVE_BLOCK_SIZE,
+ OID_GEN_VENDOR_ID,
+ OID_GEN_VENDOR_DESCRIPTION,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_MEDIA_CONNECT_STATUS,
+ OID_GEN_MAXIMUM_SEND_PACKETS,
+ OID_802_3_PERMANENT_ADDRESS,
+ OID_802_3_CURRENT_ADDRESS,
+ OID_802_3_MULTICAST_LIST,
+ OID_802_3_MAXIMUM_LIST_SIZE,
+ OID_802_3_RCV_ERROR_ALIGNMENT,
+ OID_802_3_XMIT_ONE_COLLISION,
+ OID_802_3_XMIT_MORE_COLLISIONS,
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CDC_RNDIS_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_CDC_RNDIS_Init
+ * Initialize the CDC CDC_RNDIS interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc;
+
+ hcdc = &CDC_RNDIS_Instance;
+
+ if (hcdc == NULL)
+ {
+ pdev->pClassData_CDC_RNDIS = NULL;
+ return (uint8_t)USBD_EMEM;
+ }
+
+ pdev->pClassData_CDC_RNDIS = (void *)hcdc;
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_IN_EP, USBD_EP_TYPE_BULK,
+ CDC_RNDIS_DATA_HS_IN_PACKET_SIZE);
+
+ pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 1U;
+
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_OUT_EP, USBD_EP_TYPE_BULK,
+ CDC_RNDIS_DATA_HS_OUT_PACKET_SIZE);
+
+ pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 1U;
+
+ /* Set bInterval for CDC RNDIS CMD Endpoint */
+ pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].bInterval = CDC_RNDIS_HS_BINTERVAL;
+ }
+ else
+ {
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_IN_EP, USBD_EP_TYPE_BULK,
+ CDC_RNDIS_DATA_FS_IN_PACKET_SIZE);
+
+ pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 1U;
+
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_OUT_EP, USBD_EP_TYPE_BULK,
+ CDC_RNDIS_DATA_FS_OUT_PACKET_SIZE);
+
+ pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 1U;
+
+ /* Set bInterval for CDC RNDIS CMD Endpoint */
+ pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].bInterval = CDC_RNDIS_FS_BINTERVAL;
+ }
+
+ /* Open Command IN EP */
+ (void)USBD_LL_OpenEP(pdev, CDC_RNDIS_CMD_EP, USBD_EP_TYPE_INTR, CDC_RNDIS_CMD_PACKET_SIZE);
+ pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].is_used = 1U;
+
+ /* Init physical Interface components */
+ ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData_CDC_RNDIS)->Init();
+
+ /* Init the CDC_RNDIS state */
+ hcdc->State = CDC_RNDIS_STATE_BUS_INITIALIZED;
+
+ /* Init Xfer states */
+ hcdc->TxState = 0U;
+ hcdc->RxState = 0U;
+ hcdc->RxLength = 0U;
+ hcdc->TxLength = 0U;
+ hcdc->LinkStatus = 0U;
+ hcdc->NotificationStatus = 0U;
+ hcdc->MaxPcktLen = (pdev->dev_speed == USBD_SPEED_HIGH) ? CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE : CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE;
+
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP,
+ hcdc->RxBuffer, hcdc->MaxPcktLen);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_DeInit
+ * DeInitialize the CDC layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ /* Close EP IN */
+ (void)USBD_LL_CloseEP(pdev, CDC_RNDIS_IN_EP);
+ pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].is_used = 0U;
+
+ /* Close EP OUT */
+ (void)USBD_LL_CloseEP(pdev, CDC_RNDIS_OUT_EP);
+ pdev->ep_out[CDC_RNDIS_OUT_EP & 0xFU].is_used = 0U;
+
+ /* Close Command IN EP */
+ (void)USBD_LL_CloseEP(pdev, CDC_RNDIS_CMD_EP);
+ pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].is_used = 0U;
+ pdev->ep_in[CDC_RNDIS_CMD_EP & 0xFU].bInterval = 0U;
+
+ /* DeInit physical Interface components */
+ if (pdev->pClassData_CDC_RNDIS != NULL)
+ {
+ ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData_CDC_RNDIS)->DeInit();
+#if (0)
+ USBD_free(pdev->pClassData_CDC_RNDIS);
+#endif
+ pdev->pClassData_CDC_RNDIS = NULL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_Setup
+ * Handle the CDC specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req)
+{
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+ USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)(void *)hcdc->data;
+ uint8_t ifalt = 0U;
+ uint16_t status_info = 0U;
+ USBD_StatusTypeDef ret = USBD_OK;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS:
+ if (req->wLength != 0U)
+ {
+ /* Control Request Data from Device to Host, send data prepared by device */
+ if ((req->bmRequest & 0x80U) != 0U)
+ {
+ /* Update opcode and length */
+ hcdc->CmdOpCode = req->bRequest;
+ hcdc->CmdLength = (uint8_t)req->wLength;
+
+ if (hcdc->CmdOpCode == CDC_RNDIS_GET_ENCAPSULATED_RESPONSE)
+ {
+ /* Data of Response Message has already been prepared by USBD_CDC_RNDIS_MsgParsing.
+ Just check that length is corresponding to right expected value */
+ if (req->wLength != Msg->MsgLength)
+ {
+ }
+ }
+
+ /* Allow application layer to pre-process data or add own processing before sending response */
+ ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData_CDC_RNDIS)->Control(req->bRequest, (uint8_t *)hcdc->data, req->wLength);
+ /* Check if Response is ready */
+ if (hcdc->ResponseRdy != 0U)
+ {
+ /* Clear Response Ready flag */
+ hcdc->ResponseRdy = 0U;
+
+ /* Send data on control endpoint */
+ (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data,
+ MIN(CDC_RNDIS_MAX_DATA_SZE, Msg->MsgLength));
+ }
+ else
+ {
+ /* CDC_RNDIS Specification says: If for some reason the device receives a GET ENCAPSULATED RESPONSE
+ and is unable to respond with a valid data on the Control endpoint,
+ then it should return a one-byte packet set to 0x00, rather than
+ stalling the Control endpoint */
+ (void)USBD_CtlSendData(pdev, &EmptyResponse, 1U);
+ }
+ }
+ /* Control Request Data from Host to Device: Prepare reception of control data stage */
+ else
+ {
+ hcdc->CmdOpCode = req->bRequest;
+ hcdc->CmdLength = (uint8_t)MIN(CDC_RNDIS_CMD_PACKET_SIZE, req->wLength);
+
+ (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength);
+ }
+ }
+ /* No Data control request: there is no such request for CDC_RNDIS protocol,
+ so let application layer manage this case */
+ else
+ {
+ ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData_CDC_RNDIS)->Control(req->bRequest, (uint8_t *)req, 0U);
+ }
+ break;
+
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, &ifalt, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state != USBD_STATE_CONFIGURED)
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_DataIn
+ * Data sent on non-control IN endpoint
+ * @param pdev: device instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc;
+ PCD_HandleTypeDef *hpcd = pdev->pData;
+
+ if (pdev->pClassData_CDC_RNDIS == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ if (epnum == (CDC_RNDIS_IN_EP & 0x7FU))
+ {
+ if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) &&
+ ((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U))
+ {
+ /* Update the packet total length */
+ pdev->ep_in[epnum & 0xFU].total_length = 0U;
+
+ /* Send ZLP */
+ (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
+ }
+ else
+ {
+ hcdc->TxState = 0U;
+
+ if (((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData_CDC_RNDIS)->TransmitCplt != NULL)
+ {
+ ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData_CDC_RNDIS)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
+ }
+ }
+ }
+ else if (epnum == (CDC_RNDIS_CMD_EP & 0x7FU))
+ {
+ if (hcdc->NotificationStatus != 0U)
+ {
+ (void)USBD_CDC_RNDIS_SendNotification(pdev, RNDIS_CONNECTION_SPEED_CHANGE,
+ 0U, (uint8_t *)ConnSpeedTab);
+
+ hcdc->NotificationStatus = 0U;
+ }
+ }
+ else
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_DataOut
+ * Data received on non-control Out endpoint
+ * @param pdev: device instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc;
+ uint32_t CurrPcktLen;
+
+ if (pdev->pClassData_CDC_RNDIS == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ if (epnum == CDC_RNDIS_OUT_EP)
+ {
+ /* Get the received data length */
+ CurrPcktLen = USBD_LL_GetRxDataSize(pdev, epnum);
+
+ /* Increment the frame length */
+ hcdc->RxLength += CurrPcktLen;
+
+ /* If the buffer size is less than max packet size: it is the last packet in current frame */
+ if ((CurrPcktLen < hcdc->MaxPcktLen) ||
+ (hcdc->RxLength >= (CDC_RNDIS_ETH_MAX_SEGSZE + sizeof(USBD_CDC_RNDIS_PacketMsgTypeDef))))
+ {
+ /* USB data will be immediately processed, this allow next USB traffic being
+ NAKed till the end of the application Xfer */
+
+ /* Call data packet message parsing and processing function */
+ (void)USBD_CDC_RNDIS_ProcessPacketMsg(pdev, (USBD_CDC_RNDIS_PacketMsgTypeDef *)(void *)hcdc->RxBuffer);
+ }
+ else
+ {
+ /* Prepare Out endpoint to receive next packet in current/new frame */
+ (void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP,
+ (uint8_t *)(hcdc->RxBuffer + hcdc->RxLength),
+ hcdc->MaxPcktLen);
+ }
+ }
+ else
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_EP0_RxReady
+ * Handle EP0 Rx Ready event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if ((pdev->pUserData_CDC_RNDIS != NULL) && (hcdc->CmdOpCode != 0xFFU))
+ {
+ /* Check if the received command is SendEncapsulated command */
+ if (hcdc->CmdOpCode == CDC_RNDIS_SEND_ENCAPSULATED_COMMAND)
+ {
+ /* Process Received CDC_RNDIS Control Message */
+ (void)USBD_CDC_RNDIS_MsgParsing(pdev, (uint8_t *)(hcdc->data));
+
+ /* Reset the command opcode for next processing */
+ hcdc->CmdOpCode = 0xFFU;
+ }
+ else
+ {
+ /* Reset the command opcode for next processing */
+ hcdc->CmdOpCode = 0xFFU;
+
+ /* Ignore the command and return fail */
+ return (uint8_t)USBD_FAIL;
+ }
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_GetFSCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_RNDIS_GetFSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgFSDesc));
+
+ return USBD_CDC_RNDIS_CfgFSDesc;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_GetHSCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_RNDIS_GetHSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_CfgHSDesc));
+
+ return USBD_CDC_RNDIS_CfgHSDesc;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_GetOtherSpeedCfgDesc
+ * Return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CDC_RNDIS_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_OtherSpeedCfgDesc));
+
+ return USBD_CDC_RNDIS_OtherSpeedCfgDesc;
+}
+
+/**
+ * @brief DeviceQualifierDescriptor
+ * return Device Qualifier descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+uint8_t *USBD_CDC_RNDIS_GetDeviceQualifierDescriptor(uint16_t *length)
+{
+ *length = (uint16_t)(sizeof(USBD_CDC_RNDIS_DeviceQualifierDesc));
+
+ return USBD_CDC_RNDIS_DeviceQualifierDesc;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_RegisterInterface
+ * @param pdev: device instance
+ * @param fops: CD Interface callback
+ * @retval status
+ */
+uint8_t USBD_CDC_RNDIS_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_ItfTypeDef *fops)
+{
+ if (fops == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ pdev->pUserData_CDC_RNDIS = fops;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_USRStringDescriptor
+ * Manages the transfer of user string descriptors.
+ * @param speed : current device speed
+ * @param index: descriptor index
+ * @param length : pointer data length
+ * @retval pointer to the descriptor table or NULL if the descriptor is not supported.
+ */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+static uint8_t *USBD_CDC_RNDIS_USRStringDescriptor(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length)
+{
+ static uint8_t USBD_StrDesc[255];
+
+ /* Check if the requested string interface is supported */
+ if (index == CDC_RNDIS_MAC_STRING_INDEX)
+ {
+ USBD_GetString((uint8_t *)((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData_CDC_RNDIS)->pStrDesc, USBD_StrDesc, length);
+ return USBD_StrDesc;
+ }
+ /* Not supported Interface Descriptor index */
+ else
+ {
+ return NULL;
+ }
+}
+#endif /* USBD_SUPPORT_USER_STRING_DESC */
+
+/**
+ * @brief USBD_CDC_RNDIS_SetTxBuffer
+ * @param pdev: device instance
+ * @param pbuff: Tx Buffer
+ * @retval status
+ */
+uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length)
+{
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hcdc->TxBuffer = pbuff;
+ hcdc->TxLength = length;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_SetRxBuffer
+ * @param pdev: device instance
+ * @param pbuff: Rx Buffer
+ * @retval status
+ */
+uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
+{
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hcdc->RxBuffer = pbuff;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_TransmitPacket
+ * Transmit packet on IN endpoint
+ * @param pdev: device instance
+ * @retval status
+ */
+uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev)
+{
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc;
+ USBD_CDC_RNDIS_PacketMsgTypeDef *PacketMsg;
+ USBD_StatusTypeDef ret = USBD_BUSY;
+
+ if (pdev->pClassData_CDC_RNDIS == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+ PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)(void *)hcdc->TxBuffer;
+
+ if (hcdc->TxState == 0U)
+ {
+ /* Tx Transfer in progress */
+ hcdc->TxState = 1U;
+
+ /* Format the packet information */
+ PacketMsg->MsgType = CDC_RNDIS_PACKET_MSG_ID;
+ PacketMsg->MsgLength = hcdc->TxLength;
+ PacketMsg->DataOffset = sizeof(USBD_CDC_RNDIS_PacketMsgTypeDef) - CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET;
+ PacketMsg->DataLength = hcdc->TxLength - sizeof(USBD_CDC_RNDIS_PacketMsgTypeDef);
+ PacketMsg->OOBDataOffset = 0U;
+ PacketMsg->OOBDataLength = 0U;
+ PacketMsg->NumOOBDataElements = 0U;
+ PacketMsg->PerPacketInfoOffset = 0U;
+ PacketMsg->PerPacketInfoLength = 0U;
+ PacketMsg->VcHandle = 0U;
+ PacketMsg->Reserved = 0U;
+
+ /* Update the packet total length */
+ pdev->ep_in[CDC_RNDIS_IN_EP & 0xFU].total_length = hcdc->TxLength;
+
+ /* Transmit next packet */
+ (void)USBD_LL_Transmit(pdev, CDC_RNDIS_IN_EP, hcdc->TxBuffer, hcdc->TxLength);
+
+ ret = USBD_OK;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_ReceivePacket
+ * prepare OUT Endpoint for reception
+ * @param pdev: device instance
+ * @retval status
+ */
+uint8_t USBD_CDC_RNDIS_ReceivePacket(USBD_HandleTypeDef *pdev)
+{
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc;
+
+ if (pdev->pClassData_CDC_RNDIS == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, CDC_RNDIS_OUT_EP,
+ hcdc->RxBuffer, hcdc->MaxPcktLen);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_SendNotification
+ * Transmit Notification packet on CMD IN interrupt endpoint
+ * @param pdev: device instance
+ * Notif: value of the notification type (from CDC_RNDIS_Notification_TypeDef enumeration list)
+ * bVal: value of the notification switch (ie. 0x00 or 0x01 for Network Connection notification)
+ * pData: pointer to data buffer (ie. upstream and downstream connection speed values)
+ * @retval status
+ */
+uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_NotifCodeTypeDef Notif,
+ uint16_t bVal, uint8_t *pData)
+{
+ uint32_t Idx;
+ uint16_t ReqSize = 0U;
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+ USBD_StatusTypeDef ret = USBD_OK;
+
+ UNUSED(bVal);
+ UNUSED(pData);
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Initialize the request fields */
+ (hcdc->Req).bmRequest = CDC_RNDIS_BMREQUEST_TYPE_RNDIS;
+ (hcdc->Req).bRequest = (uint8_t)Notif;
+
+ switch (Notif)
+ {
+ case RNDIS_RESPONSE_AVAILABLE:
+ (hcdc->Req).wValue = 0U;
+ (hcdc->Req).wIndex = CDC_RNDIS_CMD_ITF_NBR;
+ (hcdc->Req).wLength = 0U;
+
+ for (Idx = 0U; Idx < 8U; Idx++)
+ {
+ (hcdc->Req).data[Idx] = 0U;
+ }
+
+ ReqSize = 8U;
+ break;
+
+ default:
+ ret = USBD_FAIL;
+ break;
+ }
+
+ /* Transmit notification packet */
+ if (ReqSize != 0U)
+ {
+ (void)USBD_LL_Transmit(pdev, CDC_RNDIS_CMD_EP, (uint8_t *)&(hcdc->Req), ReqSize);
+ }
+
+ return (uint8_t)ret;
+}
+
+/* ----------------------------- CDC_RNDIS Messages processing functions ----------------------- */
+/**
+ * @brief USBD_CDC_RNDIS_MsgParsing
+ * Parse received message and process it depending on its nature.
+ * @param pdev: USB Device Handle pointer
+ * @param RxBuff: Pointer to the message data extracted from SendEncapsulated command
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_MsgParsing(USBD_HandleTypeDef *pdev, uint8_t *RxBuff)
+{
+ USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)(void *)RxBuff;
+ static uint8_t ret = (uint8_t)USBD_OK;
+
+ /* Check message type */
+ switch (Msg->MsgType)
+ {
+ /* CDC_RNDIS Initialize message */
+ case CDC_RNDIS_INITIALIZE_MSG_ID:
+ ret = USBD_CDC_RNDIS_ProcessInitMsg(pdev, (USBD_CDC_RNDIS_InitMsgTypeDef *)(void *)Msg);
+ break;
+
+ /* CDC_RNDIS Halt message */
+ case CDC_RNDIS_HALT_MSG_ID:
+ ret = USBD_CDC_RNDIS_ProcessHaltMsg(pdev, (USBD_CDC_RNDIS_HaltMsgTypeDef *)(void *)Msg);
+ break;
+
+ /* CDC_RNDIS Query message */
+ case CDC_RNDIS_QUERY_MSG_ID:
+ ret = USBD_CDC_RNDIS_ProcessQueryMsg(pdev, (USBD_CDC_RNDIS_QueryMsgTypeDef *)(void *)Msg);
+ break;
+
+ /* CDC_RNDIS Set message */
+ case CDC_RNDIS_SET_MSG_ID:
+ ret = USBD_CDC_RNDIS_ProcessSetMsg(pdev, (USBD_CDC_RNDIS_SetMsgTypeDef *)(void *)Msg);
+ break;
+
+ /* CDC_RNDIS Reset message */
+ case CDC_RNDIS_RESET_MSG_ID:
+ ret = USBD_CDC_RNDIS_ProcessResetMsg(pdev, (USBD_CDC_RNDIS_ResetMsgTypeDef *)(void *)Msg);
+ break;
+
+ /* CDC_RNDIS Keep-Alive message */
+ case CDC_RNDIS_KEEPALIVE_MSG_ID:
+ ret = USBD_CDC_RNDIS_ProcessKeepAliveMsg(pdev, (USBD_CDC_RNDIS_KpAliveMsgTypeDef *)(void *)Msg);
+ break;
+
+ /* CDC_RNDIS unsupported message */
+ default:
+ ret = USBD_CDC_RNDIS_ProcessUnsupportedMsg(pdev, (USBD_CDC_RNDIS_CtrlMsgTypeDef *)(void *)Msg);
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_ProcessInitMsg
+ * Parse, extract data and check correctness of CDC_RNDIS INIT_MSG command.
+ * @param pdev: USB Device Handle pointer
+ * @param Msg: Pointer to the message data extracted from SendEncapsulated command
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_ProcessInitMsg(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_InitMsgTypeDef *Msg)
+{
+ /* Get the CDC_RNDIS handle pointer */
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ /* Get and format the Msg input */
+ USBD_CDC_RNDIS_InitMsgTypeDef *InitMessage = (USBD_CDC_RNDIS_InitMsgTypeDef *)Msg;
+
+ /* Use same Msg input buffer as response buffer */
+ USBD_CDC_RNDIS_InitCpltMsgTypeDef *InitResponse = (USBD_CDC_RNDIS_InitCpltMsgTypeDef *)(void *)Msg;
+
+ /* Store the Message Request ID */
+ uint32_t ReqId = InitMessage->ReqId;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Check correctness of the message (MsgType already checked by entry to this function) */
+ if ((InitMessage->MsgLength != sizeof(USBD_CDC_RNDIS_InitMsgTypeDef)) ||
+ (InitMessage->MajorVersion < CDC_RNDIS_VERSION_MAJOR))
+ {
+ InitResponse->Status = CDC_RNDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ InitResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ }
+
+ /* Setup the response buffer content */
+ InitResponse->MsgType = CDC_RNDIS_INITIALIZE_CMPLT_ID;
+ InitResponse->MsgLength = sizeof(USBD_CDC_RNDIS_InitCpltMsgTypeDef);
+ InitResponse->ReqId = ReqId;
+ InitResponse->MajorVersion = CDC_RNDIS_VERSION_MAJOR;
+ InitResponse->MinorVersion = CDC_RNDIS_VERSION_MINOR;
+ InitResponse->DeviceFlags = CDC_RNDIS_DF_CONNECTIONLESS;
+ InitResponse->Medium = CDC_RNDIS_MEDIUM_802_3;
+ InitResponse->MaxPacketsPerTransfer = 1U;
+ InitResponse->MaxTransferSize = (sizeof(USBD_CDC_RNDIS_PacketMsgTypeDef) + CDC_RNDIS_ETH_FRAME_SIZE_MAX);
+ InitResponse->PacketAlignmentFactor = 2U; /* Not needed as single packet by transfer set */
+ InitResponse->AFListOffset = 0U; /* Reserved for connection-oriented devices. Set value to zero. */
+ InitResponse->AFListSize = 0U; /* Reserved for connection-oriented devices. Set value to zero. */
+
+ /* Set CDC_RNDIS state to INITIALIZED */
+ hcdc->State = CDC_RNDIS_STATE_INITIALIZED;
+
+ /* Set Response Ready field in order to send response during next control request */
+ hcdc->ResponseRdy = 1U;
+
+ /* Send Notification on Interrupt EP to inform Host that response is ready */
+ (void)USBD_CDC_RNDIS_SendNotification(pdev, RNDIS_RESPONSE_AVAILABLE, 0U, NULL);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_ProcessHaltMsg
+ * Parse, extract data and check correctness of CDC_RNDIS Halt command.
+ * @param pdev: USB Device Handle pointer
+ * @param Msg: Pointer to the message data extracted from SendEncapsulated command
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_ProcessHaltMsg(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_HaltMsgTypeDef *Msg)
+{
+ /* Get the CDC_RNDIS handle pointer */
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Set CDC_RNDIS state to INITIALIZED */
+ hcdc->State = CDC_RNDIS_STATE_UNINITIALIZED;
+
+ /* No response required for this message, so no notification (RESPONSE_AVAILABLE) is sent */
+
+ UNUSED(Msg);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_ProcessKeepAliveMsg
+ * Parse, extract data and check correctness of CDC_RNDIS KeepAlive command.
+ * @param pdev: USB Device Handle pointer
+ * @param Msg: Pointer to the message data extracted from SendEncapsulated command
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_ProcessKeepAliveMsg(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_KpAliveMsgTypeDef *Msg)
+{
+ /* Get the CDC_RNDIS handle pointer */
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ /* Use same Msg input buffer as response buffer */
+ USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *InitResponse = (USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *)(void *)Msg;
+
+ /* Store the Message Request ID */
+ uint32_t ReqId = Msg->ReqId;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Check correctness of the message (MsgType already checked by entry to this function) */
+ if (Msg->MsgLength != sizeof(USBD_CDC_RNDIS_KpAliveMsgTypeDef))
+ {
+ InitResponse->Status = CDC_RNDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ InitResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ }
+
+ /* Setup the response buffer content */
+ InitResponse->MsgType = CDC_RNDIS_KEEPALIVE_CMPLT_ID;
+ InitResponse->MsgLength = sizeof(USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef);
+ InitResponse->ReqId = ReqId;
+ InitResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+
+ /* Set Response Ready field in order to send response during next control request */
+ hcdc->ResponseRdy = 1U;
+
+ /* Send Notification on Interrupt EP to inform Host that response is ready */
+ (void)USBD_CDC_RNDIS_SendNotification(pdev, RNDIS_RESPONSE_AVAILABLE, 0U, NULL);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_ProcessQueryMsg
+ * Parse, extract data and check correctness of CDC_RNDIS Query command.
+ * @param pdev: USB Device Handle pointer
+ * @param Msg: Pointer to the message data extracted from SendEncapsulated command
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_QueryMsgTypeDef *Msg)
+{
+ /* Get the CDC_RNDIS handle pointer */
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ /* Use same Msg input buffer as response buffer */
+ USBD_CDC_RNDIS_QueryCpltMsgTypeDef *QueryResponse = (USBD_CDC_RNDIS_QueryCpltMsgTypeDef *)(void *)Msg;
+
+ /* Store the Message Request ID */
+ uint32_t ReqId = Msg->RequestId;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Process the OID depending on its code */
+ switch (Msg->Oid)
+ {
+ case OID_GEN_SUPPORTED_LIST:
+ QueryResponse->InfoBufLength = sizeof(CDC_RNDIS_SupportedOIDs);
+ (void)USBD_memcpy(QueryResponse->InfoBuf, CDC_RNDIS_SupportedOIDs,
+ sizeof(CDC_RNDIS_SupportedOIDs));
+
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_HARDWARE_STATUS:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ QueryResponse->InfoBuf[0] = CDC_RNDIS_HW_STS_READY;
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ QueryResponse->InfoBuf[0] = CDC_RNDIS_MEDIUM_802_3;
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_VENDOR_ID:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ QueryResponse->InfoBuf[0] = USBD_CDC_RNDIS_VID;
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ QueryResponse->InfoBuf[0] = CDC_RNDIS_ETH_FRAME_SIZE_MAX;
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_VENDOR_DESCRIPTION:
+ QueryResponse->InfoBufLength = (strlen(USBD_CDC_RNDIS_VENDOR_DESC) + 1U);
+ (void)USBD_memcpy(QueryResponse->InfoBuf, USBD_CDC_RNDIS_VENDOR_DESC,
+ strlen(USBD_CDC_RNDIS_VENDOR_DESC));
+
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ QueryResponse->InfoBuf[0] = CDC_RNDIS_MEDIA_STATE_CONNECTED;
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_MAXIMUM_SEND_PACKETS:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ QueryResponse->InfoBuf[0] = 1U;
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_LINK_SPEED:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ QueryResponse->InfoBuf[0] = USBD_CDC_RNDIS_LINK_SPEED;
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_802_3_PERMANENT_ADDRESS:
+ case OID_802_3_CURRENT_ADDRESS:
+ QueryResponse->InfoBufLength = 6U;
+ (void)USBD_memcpy(QueryResponse->InfoBuf, MAC_StrDesc, 6);
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ QueryResponse->InfoBuf[0] = 1U; /* Only one multicast address supported */
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ QueryResponse->InfoBuf[0] = 0xFFFFFFU; /* USBD_CDC_RNDIS_DEVICE.packetFilter; */
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_802_3_RCV_ERROR_ALIGNMENT:
+ case OID_802_3_XMIT_ONE_COLLISION:
+ case OID_802_3_XMIT_MORE_COLLISIONS:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ QueryResponse->InfoBuf[0] = 0U; /* Unused OIDs, return zero */
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+ QueryResponse->InfoBufLength = sizeof(uint32_t);
+ /* Indicate maximum overall buffer (Ethernet frame and CDC_RNDIS header) the adapter can handle */
+ QueryResponse->InfoBuf[0] = (CDC_RNDIS_MESSAGE_BUFFER_SIZE + CDC_RNDIS_ETH_FRAME_SIZE_MAX);
+ QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ default:
+ /* Unknown or unsupported OID */
+ QueryResponse->InfoBufLength = 0U;
+ QueryResponse->Status = CDC_RNDIS_STATUS_FAILURE;
+ break;
+ }
+
+ /* Setup the response buffer content */
+ QueryResponse->MsgType = CDC_RNDIS_QUERY_CMPLT_ID;
+ QueryResponse->MsgLength = QueryResponse->InfoBufLength + 24U;
+ QueryResponse->ReqId = ReqId;
+ QueryResponse->InfoBufOffset = 16U;
+
+ /* Set Response Ready field in order to send response during next control request */
+ hcdc->ResponseRdy = 1U;
+
+ /* Send Notification on Interrupt EP to inform Host that response is ready */
+ (void)USBD_CDC_RNDIS_SendNotification(pdev, RNDIS_RESPONSE_AVAILABLE, 0U, NULL);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_ProcessSetMsg
+ * Parse, extract data and check correctness of CDC_RNDIS Set Message command.
+ * @param pdev: USB Device Handle pointer
+ * @param Msg: Pointer to the message data extracted from SendEncapsulated command
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_ProcessSetMsg(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_SetMsgTypeDef *Msg)
+{
+ /* Get the CDC_RNDIS handle pointer */
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ /* Get and format the Msg input */
+ USBD_CDC_RNDIS_SetMsgTypeDef *SetMessage = (USBD_CDC_RNDIS_SetMsgTypeDef *)Msg;
+
+ /* Use same Msg input buffer as response buffer */
+ USBD_CDC_RNDIS_SetCpltMsgTypeDef *SetResponse = (USBD_CDC_RNDIS_SetCpltMsgTypeDef *)(void *)Msg;
+
+ /* Store the Message Request ID */
+ uint32_t ReqId = SetMessage->ReqId;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ switch (SetMessage->Oid)
+ {
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ /* Setup the packet filter value */
+ hcdc->PacketFilter = SetMessage->InfoBuf[0];
+ SetResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ case OID_802_3_MULTICAST_LIST:
+ /* List of multicast addresses on a miniport adapter */
+ SetResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ break;
+
+ default:
+ /* Report an error */
+ SetResponse->Status = CDC_RNDIS_STATUS_FAILURE;
+ break;
+ }
+
+ /* Prepare response buffer */
+ SetResponse->MsgType = CDC_RNDIS_SET_CMPLT_ID;
+ SetResponse->MsgLength = sizeof(USBD_CDC_RNDIS_SetCpltMsgTypeDef);
+ SetResponse->ReqId = ReqId;
+
+ /* Set Response Ready field in order to send response during next control request */
+ hcdc->ResponseRdy = 1U;
+
+ /* Send Notification on Interrupt EP to inform Host that response is ready */
+ (void)USBD_CDC_RNDIS_SendNotification(pdev, RNDIS_RESPONSE_AVAILABLE, 0U, NULL);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_ProcessResetMsg
+ * Parse, extract data and check correctness of CDC_RNDIS Set Message command.
+ * @param pdev: USB Device Handle pointer
+ * @param Msg: Pointer to the message data extracted from SendEncapsulated command
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_ProcessResetMsg(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_ResetMsgTypeDef *Msg)
+{
+ /* Get and format the Msg input */
+ USBD_CDC_RNDIS_ResetMsgTypeDef *ResetMessage = (USBD_CDC_RNDIS_ResetMsgTypeDef *)Msg;
+ /* Get the CDC_RNDIS handle pointer */
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+ /* Use same Msg input buffer as response buffer */
+ USBD_CDC_RNDIS_ResetCpltMsgTypeDef *ResetResponse = (USBD_CDC_RNDIS_ResetCpltMsgTypeDef *)(void *)Msg;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if ((ResetMessage->MsgLength != sizeof(USBD_CDC_RNDIS_ResetMsgTypeDef)) ||
+ (ResetMessage->Reserved != 0U))
+ {
+ ResetResponse->Status = CDC_RNDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ ResetResponse->Status = CDC_RNDIS_STATUS_SUCCESS;
+ }
+
+ /* Prepare response buffer */
+ ResetResponse->MsgType = CDC_RNDIS_RESET_CMPLT_ID;
+ ResetResponse->MsgLength = sizeof(USBD_CDC_RNDIS_ResetCpltMsgTypeDef);
+ ResetResponse->AddrReset = 0U;
+
+ /* Set CDC_RNDIS state to INITIALIZED */
+ hcdc->State = CDC_RNDIS_STATE_BUS_INITIALIZED;
+ hcdc->LinkStatus = 0U;
+
+ /* Set Response Ready field in order to send response during next control request */
+ hcdc->ResponseRdy = 1U;
+
+ /* Send Notification on Interrupt EP to inform Host that response is ready */
+ (void)USBD_CDC_RNDIS_SendNotification(pdev, RNDIS_RESPONSE_AVAILABLE, 0U, NULL);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_ProcessPacketMsg
+ * Parse, extract data and check correctness of CDC_RNDIS Data Packet.
+ * @param pdev: USB Device Handle pointer
+ * @param Msg: Pointer to the message data extracted from Packet
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_PacketMsgTypeDef *Msg)
+{
+ uint32_t tmp1, tmp2;
+
+ /* Get the CDC_RNDIS handle pointer */
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ /* Get and format the Msg input */
+ USBD_CDC_RNDIS_PacketMsgTypeDef *PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)Msg;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Check correctness of the message */
+ if ((PacketMsg->MsgType != CDC_RNDIS_PACKET_MSG_ID))
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Point to the payload and update the message length */
+
+ /* Use temporary storage variables to comply with MISRA-C 2012 rule of (+) operand allowed types */
+ tmp1 = (uint32_t)PacketMsg;
+ tmp2 = (uint32_t)(PacketMsg->DataOffset);
+ hcdc->RxBuffer = (uint8_t *)(tmp1 + tmp2 + CDC_RNDIS_PCKTMSG_DATAOFFSET_OFFSET);
+ hcdc->RxLength = PacketMsg->DataLength;
+
+ /* Process data by application */
+ ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData_CDC_RNDIS)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CDC_RNDIS_ProcessUnsupportedMsg
+ * Parse, extract data and check correctness of CDC_RNDIS KeepAlive command.
+ * @param pdev: USB Device Handle pointer
+ * @param Msg: Pointer to the message data extracted from SendEncapsulated command
+ * @retval status
+ */
+static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev,
+ USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg)
+{
+ /* Get the CDC_RNDIS handle pointer */
+ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData_CDC_RNDIS;
+
+ /* Use same Msg input buffer as response buffer */
+ USBD_CDC_RNDIS_StsChangeMsgTypeDef *Response = (USBD_CDC_RNDIS_StsChangeMsgTypeDef *)(void *)Msg;
+
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Setup the response buffer content */
+ Response->MsgType = CDC_RNDIS_INDICATE_STATUS_MSG_ID;
+ Response->MsgLength = sizeof(USBD_CDC_RNDIS_StsChangeMsgTypeDef);
+ Response->Status = CDC_RNDIS_STATUS_NOT_SUPPORTED;
+ Response->StsBufLength = 0U;
+ Response->StsBufOffset = 20U;
+
+ /* Set Response Ready field in order to send response during next control request */
+ hcdc->ResponseRdy = 1U;
+
+ /* Send Notification on Interrupt EP to inform Host that response is ready */
+ (void)USBD_CDC_RNDIS_SendNotification(pdev, RNDIS_RESPONSE_AVAILABLE, 0U, NULL);
+
+ UNUSED(Msg);
+
+ return (uint8_t)USBD_OK;
+}
+
+void USBD_Update_CDC_RNDIS_DESC(uint8_t *desc,
+ uint8_t cmd_itf,
+ uint8_t com_itf,
+ uint8_t in_ep,
+ uint8_t cmd_ep,
+ uint8_t out_ep,
+ uint8_t str_idx)
+{
+ desc[11] = cmd_itf;
+ desc[16] = str_idx;
+ desc[19] = cmd_itf;
+ desc[35] = com_itf;
+ desc[43] = cmd_itf;
+ desc[44] = com_itf;
+ desc[47] = cmd_ep;
+ desc[54] = com_itf;
+ desc[63] = out_ep;
+ desc[70] = in_ep;
+
+ CDC_RNDIS_IN_EP = in_ep;
+ CDC_RNDIS_OUT_EP = out_ep;
+ CDC_RNDIS_CMD_EP = cmd_ep;
+ CDC_RNDIS_CMD_ITF_NBR = cmd_itf;
+ CDC_RNDIS_COM_ITF_NBR = com_itf;
+ CDC_RNDIS_STR_DESC_IDX = str_idx;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/DFU/Inc/usbd_dfu.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/DFU/Inc/usbd_dfu.h
new file mode 100644
index 0000000..fb57b62
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/DFU/Inc/usbd_dfu.h
@@ -0,0 +1,240 @@
+/**
+ ******************************************************************************
+ * @file usbd_dfu.h
+ * @author MCD Application Team
+ * @brief Header file for the usbd_dfu.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_DFU_H
+#define __USB_DFU_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_DFU
+ * @brief This file is the Header file for usbd_dfu.c
+ * @{
+ */
+
+
+/** @defgroup USBD_DFU_Exported_Defines
+ * @{
+ */
+
+#define DFU_STR_DESC "STM32 USB DFU"
+
+#ifndef USBD_DFU_MAX_ITF_NUM
+#define USBD_DFU_MAX_ITF_NUM 1U
+#endif /* USBD_DFU_MAX_ITF_NUM */
+
+#ifndef USBD_DFU_XFER_SIZE
+#define USBD_DFU_XFER_SIZE 1024U
+#endif /* USBD_DFU_XFER_SIZE */
+
+#ifndef USBD_DFU_APP_DEFAULT_ADD
+#define USBD_DFU_APP_DEFAULT_ADD 0x08008000U /* The first sector (32 KB) is reserved for DFU code */
+#endif /* USBD_DFU_APP_DEFAULT_ADD */
+
+#define USB_DFU_CONFIG_DESC_SIZ (18U + (9U * USBD_DFU_MAX_ITF_NUM))
+#define USB_DFU_DESC_SIZ 9U
+
+#define DFU_DESCRIPTOR_TYPE 0x21U
+
+
+/**************************************************/
+/* DFU Requests DFU states */
+/**************************************************/
+#define APP_STATE_IDLE 0U
+#define APP_STATE_DETACH 1U
+#define DFU_STATE_IDLE 2U
+#define DFU_STATE_DNLOAD_SYNC 3U
+#define DFU_STATE_DNLOAD_BUSY 4U
+#define DFU_STATE_DNLOAD_IDLE 5U
+#define DFU_STATE_MANIFEST_SYNC 6U
+#define DFU_STATE_MANIFEST 7U
+#define DFU_STATE_MANIFEST_WAIT_RESET 8U
+#define DFU_STATE_UPLOAD_IDLE 9U
+#define DFU_STATE_ERROR 10U
+
+/**************************************************/
+/* DFU errors */
+/**************************************************/
+#define DFU_ERROR_NONE 0x00U
+#define DFU_ERROR_TARGET 0x01U
+#define DFU_ERROR_FILE 0x02U
+#define DFU_ERROR_WRITE 0x03U
+#define DFU_ERROR_ERASE 0x04U
+#define DFU_ERROR_CHECK_ERASED 0x05U
+#define DFU_ERROR_PROG 0x06U
+#define DFU_ERROR_VERIFY 0x07U
+#define DFU_ERROR_ADDRESS 0x08U
+#define DFU_ERROR_NOTDONE 0x09U
+#define DFU_ERROR_FIRMWARE 0x0AU
+#define DFU_ERROR_VENDOR 0x0BU
+#define DFU_ERROR_USB 0x0CU
+#define DFU_ERROR_POR 0x0DU
+#define DFU_ERROR_UNKNOWN 0x0EU
+#define DFU_ERROR_STALLEDPKT 0x0FU
+
+/**************************************************/
+/* DFU Manifestation State */
+/**************************************************/
+#define DFU_MANIFEST_COMPLETE 0x00U
+#define DFU_MANIFEST_IN_PROGRESS 0x01U
+
+
+/**************************************************/
+/* Special Commands with Download Request */
+/**************************************************/
+#define DFU_CMD_GETCOMMANDS 0x00U
+#define DFU_CMD_SETADDRESSPOINTER 0x21U
+#define DFU_CMD_ERASE 0x41U
+
+#define DFU_MEDIA_ERASE 0x00U
+#define DFU_MEDIA_PROGRAM 0x01U
+
+/**************************************************/
+/* Other defines */
+/**************************************************/
+/* Bit Detach capable = bit 3 in bmAttributes field */
+#define DFU_DETACH_MASK (1U << 4)
+#define DFU_STATUS_DEPTH 6U
+
+typedef enum
+{
+ DFU_DETACH = 0U,
+ DFU_DNLOAD,
+ DFU_UPLOAD,
+ DFU_GETSTATUS,
+ DFU_CLRSTATUS,
+ DFU_GETSTATE,
+ DFU_ABORT
+} DFU_RequestTypeDef;
+
+typedef void (*pFunction)(void);
+
+
+/********** Descriptor of DFU interface 0 Alternate setting n ****************/
+#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ \
+ _DFU_ITF_NBR, /* bInterfaceNumber: Number of Interface */ \
+ (n), /* bAlternateSetting: Alternate setting */ \
+ 0x00, /* bNumEndpoints*/ \
+ 0xFE, /* bInterfaceClass: Application Specific Class Code */ \
+ 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \
+ 0x02, /* nInterfaceProtocol: DFU mode protocol */ \
+ 0x00 /* iInterface: Index of string descriptor */ \
+
+#define TRANSFER_SIZE_BYTES(size) ((uint8_t)(size)), /* XFERSIZEB0 */\
+ ((uint8_t)((size) >> 8)) /* XFERSIZEB1 */
+
+#define IS_PROTECTED_AREA(add) (uint8_t)((((add) >= 0x08000000) && ((add) < (APP_DEFAULT_ADD)))? 1:0)
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+
+typedef struct
+{
+ union
+ {
+ uint32_t d32[USBD_DFU_XFER_SIZE / 4U];
+ uint8_t d8[USBD_DFU_XFER_SIZE];
+ } buffer;
+
+ uint32_t wblock_num;
+ uint32_t wlength;
+ uint32_t data_ptr;
+ uint32_t alt_setting;
+
+ uint8_t dev_status[DFU_STATUS_DEPTH];
+ uint8_t ReservedForAlign[2];
+ uint8_t dev_state;
+ uint8_t manif_state;
+} USBD_DFU_HandleTypeDef;
+
+typedef struct
+{
+ const uint8_t *pStrDesc;
+ uint16_t (*Init)(void);
+ uint16_t (*DeInit)(void);
+ uint16_t (*Erase)(uint32_t Add);
+ uint16_t (*Write)(uint8_t *src, uint8_t *dest, uint32_t Len);
+ uint8_t *(*Read)(uint8_t *src, uint8_t *dest, uint32_t Len);
+ uint16_t (*GetStatus)(uint32_t Add, uint8_t cmd, uint8_t *buff);
+} USBD_DFU_MediaTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern USBD_ClassTypeDef USBD_DFU;
+
+extern uint8_t DFU_ITF_NBR;
+extern uint8_t DFU_STR_DESC_IDX;
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev,
+ USBD_DFU_MediaTypeDef *fops);
+
+void USBD_Update_DFU_DESC(uint8_t *desc, uint8_t itf_no, uint8_t str_idx);
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_DFU_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/DFU/Src/usbd_dfu.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/DFU/Src/usbd_dfu.c
new file mode 100644
index 0000000..8538734
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/DFU/Src/usbd_dfu.c
@@ -0,0 +1,1143 @@
+/**
+ ******************************************************************************
+ * @file usbd_dfu.c
+ * @author MCD Application Team
+ * @brief This file provides the DFU core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * DFU Class Driver Description
+ * ===================================================================
+ * This driver manages the DFU class V1.1 following the "Device Class Specification for
+ * Device Firmware Upgrade Version 1.1 Aug 5, 2004".
+ * This driver implements the following aspects of the specification:
+ * - Device descriptor management
+ * - Configuration descriptor management
+ * - Enumeration as DFU device (in DFU mode only)
+ * - Requests management (supporting ST DFU sub-protocol)
+ * - Memory operations management (Download/Upload/Erase/Detach/GetState/GetStatus)
+ * - DFU state machine implementation.
+ *
+ * @note
+ * ST DFU sub-protocol is compliant with DFU protocol and use sub-requests to manage
+ * memory addressing, commands processing, specific memories operations (ie. Erase) ...
+ * As required by the DFU specification, only endpoint 0 is used in this application.
+ * Other endpoints and functions may be added to the application (ie. DFU ...)
+ *
+ * These aspects may be enriched or modified for a specific user application.
+ *
+ * This driver doesn't implement the following aspects of the specification
+ * (but it is possible to manage these features with some modifications on this driver):
+ * - Manifestation Tolerant mode
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_dfu.h"
+#include "usbd_ctlreq.h"
+
+#define _DFU_ITF_NBR 0x00
+#define _DFU_STR_DESC_IDX 0x01
+
+uint8_t DFU_ITF_NBR = _DFU_ITF_NBR;
+uint8_t DFU_STR_DESC_IDX = _DFU_STR_DESC_IDX;
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_DFU
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_DFU_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DFU_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DFU_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DFU_Private_FunctionPrototypes
+ * @{
+ */
+
+static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static uint8_t USBD_DFU_EP0_RxReady(USBD_HandleTypeDef *pdev);
+static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev);
+static uint8_t USBD_DFU_SOF(USBD_HandleTypeDef *pdev);
+
+static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length);
+static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length);
+
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev,
+ uint8_t index, uint16_t *length);
+#endif
+
+static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static void DFU_GetStatus(USBD_HandleTypeDef *pdev);
+static void DFU_ClearStatus(USBD_HandleTypeDef *pdev);
+static void DFU_GetState(USBD_HandleTypeDef *pdev);
+static void DFU_Abort(USBD_HandleTypeDef *pdev);
+static void DFU_Leave(USBD_HandleTypeDef *pdev);
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DFU_Private_Variables
+ * @{
+ */
+
+static USBD_DFU_HandleTypeDef DFU_Instance;
+
+USBD_ClassTypeDef USBD_DFU =
+ {
+ USBD_DFU_Init,
+ USBD_DFU_DeInit,
+ USBD_DFU_Setup,
+ USBD_DFU_EP0_TxReady,
+ USBD_DFU_EP0_RxReady,
+ NULL,
+ NULL,
+ USBD_DFU_SOF,
+ NULL,
+ NULL,
+ USBD_DFU_GetCfgDesc,
+ USBD_DFU_GetCfgDesc,
+ USBD_DFU_GetCfgDesc,
+ USBD_DFU_GetDeviceQualifierDesc,
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+ USBD_DFU_GetUsrStringDesc
+#endif
+};
+
+/* USB DFU device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_DFU_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x02, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower (mA) */
+ /* 09 */
+
+ /********** Descriptor of DFU interface 0 Alternate setting 0 **************/
+ USBD_DFU_IF_DESC(0U), /* This interface is mandatory for all devices */
+
+#if (USBD_DFU_MAX_ITF_NUM > 1U)
+ /********** Descriptor of DFU interface 0 Alternate setting 1 **************/
+ USBD_DFU_IF_DESC(1),
+#endif /* (USBD_DFU_MAX_ITF_NUM > 1) */
+
+#if (USBD_DFU_MAX_ITF_NUM > 2U)
+ /********** Descriptor of DFU interface 0 Alternate setting 2 **************/
+ USBD_DFU_IF_DESC(2),
+#endif /* (USBD_DFU_MAX_ITF_NUM > 2) */
+
+#if (USBD_DFU_MAX_ITF_NUM > 3U)
+ /********** Descriptor of DFU interface 0 Alternate setting 3 **************/
+ USBD_DFU_IF_DESC(3),
+#endif /* (USBD_DFU_MAX_ITF_NUM > 3) */
+
+#if (USBD_DFU_MAX_ITF_NUM > 4U)
+ /********** Descriptor of DFU interface 0 Alternate setting 4 **************/
+ USBD_DFU_IF_DESC(4),
+#endif /* (USBD_DFU_MAX_ITF_NUM > 4) */
+
+#if (USBD_DFU_MAX_ITF_NUM > 5U)
+ /********** Descriptor of DFU interface 0 Alternate setting 5 **************/
+ USBD_DFU_IF_DESC(5),
+#endif /* (USBD_DFU_MAX_ITF_NUM > 5) */
+
+#if (USBD_DFU_MAX_ITF_NUM > 6U)
+#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!"
+#endif /* (USBD_DFU_MAX_ITF_NUM > 6) */
+
+ /******************** DFU Functional Descriptor********************/
+ 0x09, /* blength = 9 Bytes */
+ DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor */
+ 0x0B, /* bmAttribute: bitCanDnload = 1 (bit 0)
+ bitCanUpload = 1 (bit 1)
+ bitManifestationTolerant = 0 (bit 2)
+ bitWillDetach = 1 (bit 3)
+ Reserved (bit4-6)
+ bitAcceleratedST = 0 (bit 7) */
+ 0xFF, /* DetachTimeOut= 255 ms*/
+ 0x00,
+ /* WARNING: In DMA mode the multiple MPS packets feature is still not supported
+ ==> In this case, when using DMA USBD_DFU_XFER_SIZE should be set to 64 in usbd_conf.h */
+ TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte */
+ 0x1A, /* bcdDFUVersion */
+ 0x01
+ /***********************************************************/
+ /* 9*/
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_DFU_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_DFU_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_DFU_Init
+ * Initialize the DFU interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ USBD_DFU_HandleTypeDef *hdfu;
+
+ /* Allocate Audio structure */
+ hdfu = &DFU_Instance;
+
+ if (hdfu == NULL)
+ {
+ pdev->pClassData_DFU = NULL;
+ return (uint8_t)USBD_EMEM;
+ }
+
+ pdev->pClassData_DFU = (void *)hdfu;
+
+ hdfu->alt_setting = 0U;
+ hdfu->data_ptr = USBD_DFU_APP_DEFAULT_ADD;
+ hdfu->wblock_num = 0U;
+ hdfu->wlength = 0U;
+
+ hdfu->manif_state = DFU_MANIFEST_COMPLETE;
+ hdfu->dev_state = DFU_STATE_IDLE;
+
+ hdfu->dev_status[0] = DFU_ERROR_NONE;
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = DFU_STATE_IDLE;
+ hdfu->dev_status[5] = 0U;
+
+ /* Initialize Hardware layer */
+ if (((USBD_DFU_MediaTypeDef *)pdev->pUserData_DFU)->Init() != USBD_OK)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_DFU_Init
+ * De-Initialize the DFU layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_DFU_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+ USBD_DFU_HandleTypeDef *hdfu;
+
+ if (pdev->pClassData_DFU == NULL)
+ {
+ return (uint8_t)USBD_EMEM;
+ }
+
+ hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+ hdfu->wblock_num = 0U;
+ hdfu->wlength = 0U;
+
+ hdfu->dev_state = DFU_STATE_IDLE;
+ hdfu->dev_status[0] = DFU_ERROR_NONE;
+ hdfu->dev_status[4] = DFU_STATE_IDLE;
+
+ /* DeInit physical Interface components and Hardware Layer */
+ ((USBD_DFU_MediaTypeDef *)pdev->pUserData_DFU)->DeInit();
+#if (0)
+ USBD_free(pdev->pClassData_DFU);
+#endif
+ pdev->pClassData_DFU = NULL;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_DFU_Setup
+ * Handle the DFU specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+ USBD_StatusTypeDef ret = USBD_OK;
+ uint8_t *pbuf = NULL;
+ uint16_t len = 0U;
+ uint16_t status_info = 0U;
+
+ if (hdfu == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS:
+ switch (req->bRequest)
+ {
+ case DFU_DNLOAD:
+ DFU_Download(pdev, req);
+ break;
+
+ case DFU_UPLOAD:
+ DFU_Upload(pdev, req);
+ break;
+
+ case DFU_GETSTATUS:
+ DFU_GetStatus(pdev);
+ break;
+
+ case DFU_CLRSTATUS:
+ DFU_ClearStatus(pdev);
+ break;
+
+ case DFU_GETSTATE:
+ DFU_GetState(pdev);
+ break;
+
+ case DFU_ABORT:
+ DFU_Abort(pdev);
+ break;
+
+ case DFU_DETACH:
+ DFU_Detach(pdev, req);
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_DESCRIPTOR:
+ if ((req->wValue >> 8) == DFU_DESCRIPTOR_TYPE)
+ {
+ pbuf = USBD_DFU_CfgDesc + (9U * (USBD_DFU_MAX_ITF_NUM + 1U));
+ len = MIN(USB_DFU_DESC_SIZ, req->wLength);
+ }
+
+ (void)USBD_CtlSendData(pdev, pbuf, len);
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hdfu->alt_setting, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if ((uint8_t)(req->wValue) < USBD_DFU_MAX_ITF_NUM)
+ {
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ hdfu->alt_setting = (uint8_t)(req->wValue);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ }
+ else
+ {
+ /* Call the error management function (command will be NAKed */
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_DFU_GetCfgDesc
+ * return configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_DFU_GetCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_DFU_CfgDesc);
+
+ return USBD_DFU_CfgDesc;
+}
+
+/**
+ * @brief USBD_DFU_EP0_RxReady
+ * handle EP0 Rx Ready event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_DFU_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+ UNUSED(pdev);
+
+ return (uint8_t)USBD_OK;
+}
+/**
+ * @brief USBD_DFU_EP0_TxReady
+ * handle EP0 TRx Ready event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev)
+{
+ USBD_SetupReqTypedef req;
+ uint32_t addr;
+ USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+ USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData_DFU;
+
+ if (hdfu == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if (hdfu->dev_state == DFU_STATE_DNLOAD_BUSY)
+ {
+ /* Decode the Special Command */
+ if (hdfu->wblock_num == 0U)
+ {
+ if (hdfu->wlength == 1U)
+ {
+ if (hdfu->buffer.d8[0] == DFU_CMD_GETCOMMANDS)
+ {
+ /* Nothing to do */
+ }
+ }
+ else if (hdfu->wlength == 5U)
+ {
+ if (hdfu->buffer.d8[0] == DFU_CMD_SETADDRESSPOINTER)
+ {
+ hdfu->data_ptr = hdfu->buffer.d8[1];
+ hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[2] << 8;
+ hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[3] << 16;
+ hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[4] << 24;
+ }
+ else if (hdfu->buffer.d8[0] == DFU_CMD_ERASE)
+ {
+ hdfu->data_ptr = hdfu->buffer.d8[1];
+ hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[2] << 8;
+ hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[3] << 16;
+ hdfu->data_ptr += (uint32_t)hdfu->buffer.d8[4] << 24;
+
+ if (DfuInterface->Erase(hdfu->data_ptr) != USBD_OK)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+ }
+ else
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+ }
+ else
+ {
+ /* Reset the global length and block number */
+ hdfu->wlength = 0U;
+ hdfu->wblock_num = 0U;
+ /* Call the error management function (command will be NAKed) */
+ req.bmRequest = 0U;
+ req.wLength = 1U;
+ USBD_CtlError(pdev, &req);
+ }
+ }
+ /* Regular Download Command */
+ else
+ {
+ if (hdfu->wblock_num > 1U)
+ {
+ /* Decode the required address */
+ addr = ((hdfu->wblock_num - 2U) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr;
+
+ /* Perform the write operation */
+ if (DfuInterface->Write(hdfu->buffer.d8, (uint8_t *)addr, hdfu->wlength) != USBD_OK)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+ }
+ }
+
+ /* Reset the global length and block number */
+ hdfu->wlength = 0U;
+ hdfu->wblock_num = 0U;
+
+ /* Update the state machine */
+ hdfu->dev_state = DFU_STATE_DNLOAD_SYNC;
+
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+ }
+ else if (hdfu->dev_state == DFU_STATE_MANIFEST) /* Manifestation in progress */
+ {
+ /* Start leaving DFU mode */
+ DFU_Leave(pdev);
+ }
+ else
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+/**
+ * @brief USBD_DFU_SOF
+ * handle SOF event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_DFU_SOF(USBD_HandleTypeDef *pdev)
+{
+ UNUSED(pdev);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief DeviceQualifierDescriptor
+ * return Device Qualifier descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_DFU_DeviceQualifierDesc);
+
+ return USBD_DFU_DeviceQualifierDesc;
+}
+
+/**
+ * @brief USBD_DFU_GetUsrStringDesc
+ * Manages the transfer of memory interfaces string descriptors.
+ * @param speed : current device speed
+ * @param index: descriptor index
+ * @param length : pointer data length
+ * @retval pointer to the descriptor table or NULL if the descriptor is not supported.
+ */
+#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
+static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length)
+{
+ static uint8_t USBD_StrDesc[255];
+ USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData_DFU;
+
+ /* Check if the requested string interface is supported */
+ if (index <= (USBD_IDX_INTERFACE_STR + USBD_DFU_MAX_ITF_NUM))
+ {
+ USBD_GetString((uint8_t *)DfuInterface->pStrDesc, USBD_StrDesc, length);
+ return USBD_StrDesc;
+ }
+ else
+ {
+ /* Not supported Interface Descriptor index */
+ return NULL;
+ }
+}
+#endif
+
+/**
+ * @brief USBD_MSC_RegisterStorage
+ * @param fops: storage callback
+ * @retval status
+ */
+uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev,
+ USBD_DFU_MediaTypeDef *fops)
+{
+ if (fops == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ pdev->pUserData_DFU = fops;
+
+ return (uint8_t)USBD_OK;
+}
+
+/******************************************************************************
+ DFU Class requests management
+ ******************************************************************************/
+/**
+ * @brief DFU_Detach
+ * Handles the DFU DETACH request.
+ * @param pdev: device instance
+ * @param req: pointer to the request structure.
+ * @retval None.
+ */
+static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+
+ if (hdfu == NULL)
+ {
+ return;
+ }
+
+ if ((hdfu->dev_state == DFU_STATE_IDLE) ||
+ (hdfu->dev_state == DFU_STATE_DNLOAD_SYNC) ||
+ (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) ||
+ (hdfu->dev_state == DFU_STATE_MANIFEST_SYNC) ||
+ (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE))
+ {
+ /* Update the state machine */
+ hdfu->dev_state = DFU_STATE_IDLE;
+ hdfu->dev_status[0] = DFU_ERROR_NONE;
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U; /*bwPollTimeout=0ms*/
+ hdfu->dev_status[4] = hdfu->dev_state;
+ hdfu->dev_status[5] = 0U; /*iString*/
+ hdfu->wblock_num = 0U;
+ hdfu->wlength = 0U;
+ }
+
+ /* Check the detach capability in the DFU functional descriptor */
+ if (((USBD_DFU_CfgDesc[12U + (9U * USBD_DFU_MAX_ITF_NUM)]) & DFU_DETACH_MASK) != 0U)
+ {
+ /* Perform an Attach-Detach operation on USB bus */
+ (void)USBD_Stop(pdev);
+ (void)USBD_Start(pdev);
+ }
+ else
+ {
+ /* Wait for the period of time specified in Detach request */
+ USBD_Delay((uint32_t)req->wValue);
+ }
+}
+
+/**
+ * @brief DFU_Download
+ * Handles the DFU DNLOAD request.
+ * @param pdev: device instance
+ * @param req: pointer to the request structure
+ * @retval None
+ */
+static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+
+ if (hdfu == NULL)
+ {
+ return;
+ }
+
+ /* Data setup request */
+ if (req->wLength > 0U)
+ {
+ if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE))
+ {
+ /* Update the global length and block number */
+ hdfu->wblock_num = req->wValue;
+ hdfu->wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE);
+
+ /* Update the state machine */
+ hdfu->dev_state = DFU_STATE_DNLOAD_SYNC;
+ hdfu->dev_status[4] = hdfu->dev_state;
+
+ /* Prepare the reception of the buffer over EP0 */
+ (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hdfu->buffer.d8, hdfu->wlength);
+ }
+ /* Unsupported state */
+ else
+ {
+ /* Call the error management function (command will be NAKed */
+ USBD_CtlError(pdev, req);
+ }
+ }
+ /* 0 Data DNLOAD request */
+ else
+ {
+ /* End of DNLOAD operation*/
+ if ((hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) || (hdfu->dev_state == DFU_STATE_IDLE))
+ {
+ hdfu->manif_state = DFU_MANIFEST_IN_PROGRESS;
+ hdfu->dev_state = DFU_STATE_MANIFEST_SYNC;
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+ }
+ else
+ {
+ /* Call the error management function (command will be NAKed */
+ USBD_CtlError(pdev, req);
+ }
+ }
+}
+
+/**
+ * @brief DFU_Upload
+ * Handles the DFU UPLOAD request.
+ * @param pdev: instance
+ * @param req: pointer to the request structure
+ * @retval status
+ */
+static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+ USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData_DFU;
+ uint8_t *phaddr;
+ uint32_t addr;
+
+ if (hdfu == NULL)
+ {
+ return;
+ }
+
+ /* Data setup request */
+ if (req->wLength > 0U)
+ {
+ if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE))
+ {
+ /* Update the global length and block number */
+ hdfu->wblock_num = req->wValue;
+ hdfu->wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE);
+
+ /* DFU Get Command */
+ if (hdfu->wblock_num == 0U)
+ {
+ /* Update the state machine */
+ hdfu->dev_state = (hdfu->wlength > 3U) ? DFU_STATE_IDLE : DFU_STATE_UPLOAD_IDLE;
+
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+
+ /* Store the values of all supported commands */
+ hdfu->buffer.d8[0] = DFU_CMD_GETCOMMANDS;
+ hdfu->buffer.d8[1] = DFU_CMD_SETADDRESSPOINTER;
+ hdfu->buffer.d8[2] = DFU_CMD_ERASE;
+
+ /* Send the status data over EP0 */
+ (void)USBD_CtlSendData(pdev, (uint8_t *)(&(hdfu->buffer.d8[0])), 3U);
+ }
+ else if (hdfu->wblock_num > 1U)
+ {
+ hdfu->dev_state = DFU_STATE_UPLOAD_IDLE;
+
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+
+ addr = ((hdfu->wblock_num - 2U) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr;
+
+ /* Return the physical address where data are stored */
+ phaddr = DfuInterface->Read((uint8_t *)addr, hdfu->buffer.d8, hdfu->wlength);
+
+ /* Send the status data over EP0 */
+ (void)USBD_CtlSendData(pdev, phaddr, hdfu->wlength);
+ }
+ else /* unsupported hdfu->wblock_num */
+ {
+ hdfu->dev_state = DFU_ERROR_STALLEDPKT;
+
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+
+ /* Call the error management function (command will be NAKed */
+ USBD_CtlError(pdev, req);
+ }
+ }
+ /* Unsupported state */
+ else
+ {
+ hdfu->wlength = 0U;
+ hdfu->wblock_num = 0U;
+
+ /* Call the error management function (command will be NAKed */
+ USBD_CtlError(pdev, req);
+ }
+ }
+ /* No Data setup request */
+ else
+ {
+ hdfu->dev_state = DFU_STATE_IDLE;
+
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+ }
+}
+
+/**
+ * @brief DFU_GetStatus
+ * Handles the DFU GETSTATUS request.
+ * @param pdev: instance
+ * @retval status
+ */
+static void DFU_GetStatus(USBD_HandleTypeDef *pdev)
+{
+ USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+ USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData_DFU;
+
+ if (hdfu == NULL)
+ {
+ return;
+ }
+
+ switch (hdfu->dev_state)
+ {
+ case DFU_STATE_DNLOAD_SYNC:
+ if (hdfu->wlength != 0U)
+ {
+ hdfu->dev_state = DFU_STATE_DNLOAD_BUSY;
+
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+
+ if ((hdfu->wblock_num == 0U) && (hdfu->buffer.d8[0] == DFU_CMD_ERASE))
+ {
+ DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_ERASE, hdfu->dev_status);
+ }
+ else
+ {
+ DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_PROGRAM, hdfu->dev_status);
+ }
+ }
+ else /* (hdfu->wlength==0)*/
+ {
+ hdfu->dev_state = DFU_STATE_DNLOAD_IDLE;
+
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+ }
+ break;
+
+ case DFU_STATE_MANIFEST_SYNC:
+ if (hdfu->manif_state == DFU_MANIFEST_IN_PROGRESS)
+ {
+ hdfu->dev_state = DFU_STATE_MANIFEST;
+
+ hdfu->dev_status[1] = 1U; /*bwPollTimeout = 1ms*/
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+ }
+ else
+ {
+ if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) &&
+ (((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U))
+ {
+ hdfu->dev_state = DFU_STATE_IDLE;
+
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Send the status data over EP0 */
+ (void)USBD_CtlSendData(pdev, (uint8_t *)(&(hdfu->dev_status[0])), 6U);
+}
+
+/**
+ * @brief DFU_ClearStatus
+ * Handles the DFU CLRSTATUS request.
+ * @param pdev: device instance
+ * @retval status
+ */
+static void DFU_ClearStatus(USBD_HandleTypeDef *pdev)
+{
+ USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+
+ if (hdfu == NULL)
+ {
+ return;
+ }
+
+ if (hdfu->dev_state == DFU_STATE_ERROR)
+ {
+ hdfu->dev_state = DFU_STATE_IDLE;
+ hdfu->dev_status[0] = DFU_ERROR_NONE; /* bStatus */
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U; /* bwPollTimeout=0ms */
+ hdfu->dev_status[4] = hdfu->dev_state; /* bState */
+ hdfu->dev_status[5] = 0U; /* iString */
+ }
+ else
+ {
+ /* State Error */
+ hdfu->dev_state = DFU_STATE_ERROR;
+ hdfu->dev_status[0] = DFU_ERROR_UNKNOWN; /* bStatus */
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U; /* bwPollTimeout=0ms */
+ hdfu->dev_status[4] = hdfu->dev_state; /* bState */
+ hdfu->dev_status[5] = 0U; /* iString */
+ }
+}
+
+/**
+ * @brief DFU_GetState
+ * Handles the DFU GETSTATE request.
+ * @param pdev: device instance
+ * @retval None
+ */
+static void DFU_GetState(USBD_HandleTypeDef *pdev)
+{
+ USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+
+ if (hdfu == NULL)
+ {
+ return;
+ }
+
+ /* Return the current state of the DFU interface */
+ (void)USBD_CtlSendData(pdev, &hdfu->dev_state, 1U);
+}
+
+/**
+ * @brief DFU_Abort
+ * Handles the DFU ABORT request.
+ * @param pdev: device instance
+ * @retval None
+ */
+static void DFU_Abort(USBD_HandleTypeDef *pdev)
+{
+ USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+
+ if (hdfu == NULL)
+ {
+ return;
+ }
+
+ if ((hdfu->dev_state == DFU_STATE_IDLE) ||
+ (hdfu->dev_state == DFU_STATE_DNLOAD_SYNC) ||
+ (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) ||
+ (hdfu->dev_state == DFU_STATE_MANIFEST_SYNC) ||
+ (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE))
+ {
+ hdfu->dev_state = DFU_STATE_IDLE;
+ hdfu->dev_status[0] = DFU_ERROR_NONE;
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U; /* bwPollTimeout=0ms */
+ hdfu->dev_status[4] = hdfu->dev_state;
+ hdfu->dev_status[5] = 0U; /* iString */
+ hdfu->wblock_num = 0U;
+ hdfu->wlength = 0U;
+ }
+}
+
+/**
+ * @brief DFU_Leave
+ * Handles the sub-protocol DFU leave DFU mode request (leaves DFU mode
+ * and resets device to jump to user loaded code).
+ * @param pdev: device instance
+ * @retval None
+ */
+static void DFU_Leave(USBD_HandleTypeDef *pdev)
+{
+ USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData_DFU;
+
+ if (hdfu == NULL)
+ {
+ return;
+ }
+
+ hdfu->manif_state = DFU_MANIFEST_COMPLETE;
+
+ if (((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U)
+ {
+ hdfu->dev_state = DFU_STATE_MANIFEST_SYNC;
+
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+ return;
+ }
+ else
+ {
+ hdfu->dev_state = DFU_STATE_MANIFEST_WAIT_RESET;
+
+ hdfu->dev_status[1] = 0U;
+ hdfu->dev_status[2] = 0U;
+ hdfu->dev_status[3] = 0U;
+ hdfu->dev_status[4] = hdfu->dev_state;
+
+ /* Disconnect the USB device */
+ (void)USBD_Stop(pdev);
+
+ /* Generate system reset to allow jumping to the user code */
+ NVIC_SystemReset();
+
+ /* The next instructions will not be reached (system reset) */
+ }
+}
+
+void USBD_Update_DFU_DESC(uint8_t *desc, uint8_t itf_no, uint8_t str_idx)
+{
+ desc[11] = itf_no;
+ desc[17] = str_idx;
+
+#if (USBD_DFU_MAX_ITF_NUM > 1U)
+ desc[20] = itf_no;
+#endif /* (USBD_DFU_MAX_ITF_NUM > 1) */
+
+#if (USBD_DFU_MAX_ITF_NUM > 2U)
+ desc[29] = itf_no;
+#endif /* (USBD_DFU_MAX_ITF_NUM > 2) */
+
+#if (USBD_DFU_MAX_ITF_NUM > 3U)
+ desc[38] = itf_no;
+#endif /* (USBD_DFU_MAX_ITF_NUM > 3) */
+
+#if (USBD_DFU_MAX_ITF_NUM > 4U)
+ desc[47] = itf_no;
+#endif /* (USBD_DFU_MAX_ITF_NUM > 4) */
+
+#if (USBD_DFU_MAX_ITF_NUM > 5U)
+ desc[56] = itf_no;
+#endif /* (USBD_DFU_MAX_ITF_NUM > 5) */
+
+ DFU_ITF_NBR = itf_no;
+ DFU_STR_DESC_IDX = str_idx;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_CUSTOM/Inc/usbd_hid_custom.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_CUSTOM/Inc/usbd_hid_custom.h
new file mode 100644
index 0000000..1509003
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_CUSTOM/Inc/usbd_hid_custom.h
@@ -0,0 +1,168 @@
+/**
+ ******************************************************************************
+ * @file usbd_customhid.h
+ * @author MCD Application Team
+ * @brief header file for the usbd_customhid.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CUSTOMHID_H
+#define __USB_CUSTOMHID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_CUSTOM_HID
+ * @brief This file is the Header file for USBD_customhid.c
+ * @{
+ */
+
+
+/** @defgroup USBD_CUSTOM_HID_Exported_Defines
+ * @{
+ */
+
+#define CUSTOM_HID_STR_DESC "STM32 HID CUSTOM"
+
+#define CUSTOM_HID_EPIN_SIZE 0x02U
+#define CUSTOM_HID_EPOUT_SIZE 0x02U
+
+#define USB_CUSTOM_HID_CONFIG_DESC_SIZ 41U
+#define USB_CUSTOM_HID_DESC_SIZ 9U
+
+#ifndef CUSTOM_HID_HS_BINTERVAL
+#define CUSTOM_HID_HS_BINTERVAL 0x05U
+#endif /* CUSTOM_HID_HS_BINTERVAL */
+
+#ifndef CUSTOM_HID_FS_BINTERVAL
+#define CUSTOM_HID_FS_BINTERVAL 0x05U
+#endif /* CUSTOM_HID_FS_BINTERVAL */
+
+#ifndef USBD_CUSTOMHID_OUTREPORT_BUF_SIZE
+#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U
+#endif /* USBD_CUSTOMHID_OUTREPORT_BUF_SIZE */
+
+#ifndef USBD_CUSTOM_HID_REPORT_DESC_SIZE
+#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 33U
+#endif /* USBD_CUSTOM_HID_REPORT_DESC_SIZE */
+
+#define CUSTOM_HID_DESCRIPTOR_TYPE 0x21U
+#define CUSTOM_HID_REPORT_DESC 0x22U
+
+#define CUSTOM_HID_REQ_SET_PROTOCOL 0x0BU
+#define CUSTOM_HID_REQ_GET_PROTOCOL 0x03U
+
+#define CUSTOM_HID_REQ_SET_IDLE 0x0AU
+#define CUSTOM_HID_REQ_GET_IDLE 0x02U
+
+#define CUSTOM_HID_REQ_SET_REPORT 0x09U
+#define CUSTOM_HID_REQ_GET_REPORT 0x01U
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+typedef enum
+{
+ CUSTOM_HID_IDLE = 0U,
+ CUSTOM_HID_BUSY,
+} CUSTOM_HID_StateTypeDef;
+
+typedef struct _USBD_CUSTOM_HID_Itf
+{
+ uint8_t *pReport;
+ int8_t (*Init)(void);
+ int8_t (*DeInit)(void);
+ int8_t (*OutEvent)(uint8_t event_idx, uint8_t state);
+
+} USBD_CUSTOM_HID_ItfTypeDef;
+
+typedef struct
+{
+ uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
+ uint32_t Protocol;
+ uint32_t IdleState;
+ uint32_t AltSetting;
+ uint32_t IsReportAvailable;
+ CUSTOM_HID_StateTypeDef state;
+} USBD_CUSTOM_HID_HandleTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern USBD_ClassTypeDef USBD_HID_CUSTOM;
+
+extern uint8_t CUSTOM_HID_IN_EP;
+extern uint8_t CUSTOM_HID_OUT_EP;
+extern uint8_t CUSTOM_HID_ITF_NBR;
+extern uint8_t CUSTOM_HID_STR_DESC_IDX;
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
+ uint8_t *report, uint16_t len);
+
+uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
+
+uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_CUSTOM_HID_ItfTypeDef *fops);
+
+void USBD_Update_HID_Custom_DESC(uint8_t *desc, uint8_t itf_no, uint8_t in_ep, uint8_t out_ep, uint8_t str_idx);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_CUSTOMHID_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_CUSTOM/Src/usbd_hid_custom.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_CUSTOM/Src/usbd_hid_custom.c
new file mode 100644
index 0000000..f4d44d4
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_CUSTOM/Src/usbd_hid_custom.c
@@ -0,0 +1,797 @@
+/**
+ ******************************************************************************
+ * @file usbd_customhid.c
+ * @author MCD Application Team
+ * @brief This file provides the CUSTOM_HID core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * CUSTOM_HID Class Description
+ * ===================================================================
+ * This module manages the CUSTOM_HID class V1.11 following the "Device Class Definition
+ * for Human Interface Devices (CUSTOM_HID) Version 1.11 Jun 27, 2001".
+ * This driver implements the following aspects of the specification:
+ * - The Boot Interface Subclass
+ * - Usage Page : Generic Desktop
+ * - Usage : Vendor
+ * - Collection : Application
+ *
+ * @note In HS mode and when the DMA is used, all variables and data structures
+ * dealing with the DMA during the transaction process should be 32-bit aligned.
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_hid_custom.h"
+#include "usbd_ctlreq.h"
+
+#define _CUSTOM_HID_IN_EP 0x81U
+#define _CUSTOM_HID_OUT_EP 0x01U
+#define _CUSTOM_HID_ITF_NBR 0x00U
+#define _CUSTOM_HID_STR_DESC_IDX 0x00U
+
+uint8_t CUSTOM_HID_IN_EP = _CUSTOM_HID_IN_EP;
+uint8_t CUSTOM_HID_OUT_EP = _CUSTOM_HID_OUT_EP;
+uint8_t CUSTOM_HID_ITF_NBR = _CUSTOM_HID_ITF_NBR;
+uint8_t CUSTOM_HID_STR_DESC_IDX = _CUSTOM_HID_STR_DESC_IDX;
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_CUSTOM_HID
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+/** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes
+ * @{
+ */
+
+static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+
+static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev);
+
+static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length);
+static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length);
+static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length);
+static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length);
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Variables
+ * @{
+ */
+
+static USBD_CUSTOM_HID_HandleTypeDef CUSTOM_HID_Instance;
+
+USBD_ClassTypeDef USBD_HID_CUSTOM =
+ {
+ USBD_CUSTOM_HID_Init,
+ USBD_CUSTOM_HID_DeInit,
+ USBD_CUSTOM_HID_Setup,
+ NULL, /*EP0_TxSent*/
+ USBD_CUSTOM_HID_EP0_RxReady,
+ /*EP0_RxReady*/ /* STATUS STAGE IN */
+ USBD_CUSTOM_HID_DataIn, /*DataIn*/
+ USBD_CUSTOM_HID_DataOut,
+ NULL, /*SOF */
+ NULL,
+ NULL,
+ USBD_CUSTOM_HID_GetHSCfgDesc,
+ USBD_CUSTOM_HID_GetFSCfgDesc,
+ USBD_CUSTOM_HID_GetOtherSpeedCfgDesc,
+ USBD_CUSTOM_HID_GetDeviceQualifierDesc,
+};
+
+/* USB CUSTOM_HID device FS Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA: this current is used for detecting Vbus */
+
+ /************** Descriptor of CUSTOM HID interface ****************/
+ /* 09 */
+ 0x09, /* bLength: Interface Descriptor size*/
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _CUSTOM_HID_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints*/
+ 0x03, /* bInterfaceClass: CUSTOM_HID */
+ 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+ 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+ _CUSTOM_HID_STR_DESC_IDX, /* iInterface: Index of string descriptor */
+ /******************** Descriptor of CUSTOM_HID *************************/
+ /* 18 */
+ 0x09, /* bLength: CUSTOM_HID Descriptor size */
+ CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */
+ 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+ /******************** Descriptor of Custom HID endpoints ********************/
+ /* 27 */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
+ _CUSTOM_HID_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Byte max */
+ 0x00,
+ CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */
+ /* 34 */
+
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
+ _CUSTOM_HID_OUT_EP, /* bEndpointAddress: Endpoint Address (OUT) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */
+ 0x00,
+ CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */
+ /* 41 */
+};
+
+/* USB CUSTOM_HID device HS Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA: this current is used for detecting Vbus */
+
+ /************** Descriptor of CUSTOM HID interface ****************/
+ /* 09 */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _CUSTOM_HID_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints */
+ 0x03, /* bInterfaceClass: CUSTOM_HID */
+ 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+ 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+ _CUSTOM_HID_STR_DESC_IDX, /* iInterface: Index of string descriptor */
+ /******************** Descriptor of CUSTOM_HID *************************/
+ /* 18 */
+ 0x09, /* bLength: CUSTOM_HID Descriptor size */
+ CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */
+ 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+ /******************** Descriptor of Custom HID endpoints ********************/
+ /* 27 */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
+ _CUSTOM_HID_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Byte max */
+ 0x00,
+ CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */
+ /* 34 */
+
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
+ _CUSTOM_HID_OUT_EP, /* bEndpointAddress: Endpoint Address (OUT) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */
+ 0x00,
+ CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */
+ /* 41 */
+};
+
+/* USB CUSTOM_HID device Other Speed Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA: this current is used for detecting Vbus */
+
+ /************** Descriptor of CUSTOM HID interface ****************/
+ /* 09 */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _CUSTOM_HID_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints */
+ 0x03, /* bInterfaceClass: CUSTOM_HID */
+ 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+ 0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+ _CUSTOM_HID_STR_DESC_IDX, /* iInterface: Index of string descriptor */
+ /******************** Descriptor of CUSTOM_HID *************************/
+ /* 18 */
+ 0x09, /* bLength: CUSTOM_HID Descriptor size */
+ CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */
+ 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+ /******************** Descriptor of Custom HID endpoints ********************/
+ /* 27 */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
+ _CUSTOM_HID_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */
+ 0x00,
+ CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */
+ /* 34 */
+
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
+ _CUSTOM_HID_OUT_EP, /* bEndpointAddress: Endpoint Address (OUT) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */
+ 0x00,
+ CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */
+ /* 41 */
+};
+
+/* USB CUSTOM_HID device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALIGN_END =
+ {
+ /* 18 */
+ 0x09, /* bLength: CUSTOM_HID Descriptor size */
+ CUSTOM_HID_DESCRIPTOR_TYPE, /* bDescriptorType: CUSTOM_HID */
+ 0x11, /* bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of CUSTOM_HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ USBD_CUSTOM_HID_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CUSTOM_HID_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_CUSTOM_HID_Init
+ * Initialize the CUSTOM_HID interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+ USBD_CUSTOM_HID_HandleTypeDef *hhid;
+
+ hhid = &CUSTOM_HID_Instance;
+
+ if (hhid == NULL)
+ {
+ pdev->pClassData_HID_Custom = NULL;
+ return (uint8_t)USBD_EMEM;
+ }
+
+ pdev->pClassData_HID_Custom = (void *)hhid;
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ pdev->ep_in[CUSTOM_HID_IN_EP & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
+ pdev->ep_out[CUSTOM_HID_OUT_EP & 0xFU].bInterval = CUSTOM_HID_HS_BINTERVAL;
+ }
+ else /* LOW and FULL-speed endpoints */
+ {
+ pdev->ep_in[CUSTOM_HID_IN_EP & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
+ pdev->ep_out[CUSTOM_HID_OUT_EP & 0xFU].bInterval = CUSTOM_HID_FS_BINTERVAL;
+ }
+
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, CUSTOM_HID_IN_EP, USBD_EP_TYPE_INTR,
+ CUSTOM_HID_EPIN_SIZE);
+
+ pdev->ep_in[CUSTOM_HID_IN_EP & 0xFU].is_used = 1U;
+
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, CUSTOM_HID_OUT_EP, USBD_EP_TYPE_INTR,
+ CUSTOM_HID_EPOUT_SIZE);
+
+ pdev->ep_out[CUSTOM_HID_OUT_EP & 0xFU].is_used = 1U;
+
+ hhid->state = CUSTOM_HID_IDLE;
+
+ ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData_HID_Custom)->Init();
+
+ /* Prepare Out endpoint to receive 1st packet */
+ (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_OUT_EP, hhid->Report_buf,
+ USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_Init
+ * DeInitialize the CUSTOM_HID layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ /* Close CUSTOM_HID EP IN */
+ (void)USBD_LL_CloseEP(pdev, CUSTOM_HID_IN_EP);
+ pdev->ep_in[CUSTOM_HID_IN_EP & 0xFU].is_used = 0U;
+ pdev->ep_in[CUSTOM_HID_IN_EP & 0xFU].bInterval = 0U;
+
+ /* Close CUSTOM_HID EP OUT */
+ (void)USBD_LL_CloseEP(pdev, CUSTOM_HID_OUT_EP);
+ pdev->ep_out[CUSTOM_HID_OUT_EP & 0xFU].is_used = 0U;
+ pdev->ep_out[CUSTOM_HID_OUT_EP & 0xFU].bInterval = 0U;
+
+ /* Free allocated memory */
+ if (pdev->pClassData_HID_Custom != NULL)
+ {
+ ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData_HID_Custom)->DeInit();
+#if (0)
+ USBD_free(pdev->pClassData_HID_Custom);
+#endif
+ pdev->pClassData_HID_Custom = NULL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_Setup
+ * Handle the CUSTOM_HID specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev,
+ USBD_SetupReqTypedef *req)
+{
+ USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData_HID_Custom;
+ uint16_t len = 0U;
+ uint8_t *pbuf = NULL;
+ uint16_t status_info = 0U;
+ USBD_StatusTypeDef ret = USBD_OK;
+
+ if (hhid == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS:
+ switch (req->bRequest)
+ {
+ case CUSTOM_HID_REQ_SET_PROTOCOL:
+ hhid->Protocol = (uint8_t)(req->wValue);
+ break;
+
+ case CUSTOM_HID_REQ_GET_PROTOCOL:
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U);
+ break;
+
+ case CUSTOM_HID_REQ_SET_IDLE:
+ hhid->IdleState = (uint8_t)(req->wValue >> 8);
+ break;
+
+ case CUSTOM_HID_REQ_GET_IDLE:
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U);
+ break;
+
+ case CUSTOM_HID_REQ_SET_REPORT:
+ hhid->IsReportAvailable = 1U;
+ (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, req->wLength);
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_DESCRIPTOR:
+ if ((req->wValue >> 8) == CUSTOM_HID_REPORT_DESC)
+ {
+ len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE, req->wLength);
+ pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData_HID_Custom)->pReport;
+ }
+ else
+ {
+ if ((req->wValue >> 8) == CUSTOM_HID_DESCRIPTOR_TYPE)
+ {
+ pbuf = USBD_CUSTOM_HID_Desc;
+ len = MIN(USB_CUSTOM_HID_DESC_SIZ, req->wLength);
+ }
+ }
+
+ (void)USBD_CtlSendData(pdev, pbuf, len);
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ hhid->AltSetting = (uint8_t)(req->wValue);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_SendReport
+ * Send CUSTOM_HID Report
+ * @param pdev: device instance
+ * @param buff: pointer to report
+ * @retval status
+ */
+uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev,
+ uint8_t *report, uint16_t len)
+{
+ USBD_CUSTOM_HID_HandleTypeDef *hhid;
+
+ if (pdev->pClassData_HID_Custom == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData_HID_Custom;
+
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ if (hhid->state == CUSTOM_HID_IDLE)
+ {
+ hhid->state = CUSTOM_HID_BUSY;
+ (void)USBD_LL_Transmit(pdev, CUSTOM_HID_IN_EP, report, len);
+ }
+ else
+ {
+ return (uint8_t)USBD_BUSY;
+ }
+ }
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_GetFSCfgDesc
+ * return FS configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CUSTOM_HID_GetFSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgFSDesc);
+
+ return USBD_CUSTOM_HID_CfgFSDesc;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_GetHSCfgDesc
+ * return HS configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CUSTOM_HID_GetHSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CUSTOM_HID_CfgHSDesc);
+
+ return USBD_CUSTOM_HID_CfgHSDesc;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_GetOtherSpeedCfgDesc
+ * return other speed configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CUSTOM_HID_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CUSTOM_HID_OtherSpeedCfgDesc);
+
+ return USBD_CUSTOM_HID_OtherSpeedCfgDesc;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_DataIn
+ * handle data IN Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_CUSTOM_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(epnum);
+
+ /* Ensure that the FIFO is empty before a new transfer, this condition could
+ be caused by a new transfer before the end of the previous transfer */
+ ((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData_HID_Custom)->state = CUSTOM_HID_IDLE;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_DataOut
+ * handle data OUT Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(epnum);
+ USBD_CUSTOM_HID_HandleTypeDef *hhid;
+
+ if (pdev->pClassData_HID_Custom == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData_HID_Custom;
+
+ /* USB data will be immediately processed, this allow next USB traffic being
+ NAKed till the end of the application processing */
+ ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData_HID_Custom)->OutEvent(hhid->Report_buf[0], hhid->Report_buf[1]);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_ReceivePacket
+ * prepare OUT Endpoint for reception
+ * @param pdev: device instance
+ * @retval status
+ */
+uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev)
+{
+ USBD_CUSTOM_HID_HandleTypeDef *hhid;
+
+ if (pdev->pClassData_HID_Custom == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData_HID_Custom;
+
+ /* Resume USB Out process */
+ (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_OUT_EP, hhid->Report_buf,
+ USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_EP0_RxReady
+ * Handles control request data.
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+ USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData_HID_Custom;
+
+ if (hhid == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if (hhid->IsReportAvailable == 1U)
+ {
+ ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData_HID_Custom)->OutEvent(hhid->Report_buf[0], hhid->Report_buf[1]);
+ hhid->IsReportAvailable = 0U;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief DeviceQualifierDescriptor
+ * return Device Qualifier descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_CUSTOM_HID_DeviceQualifierDesc);
+
+ return USBD_CUSTOM_HID_DeviceQualifierDesc;
+}
+
+/**
+ * @brief USBD_CUSTOM_HID_RegisterInterface
+ * @param pdev: device instance
+ * @param fops: CUSTOMHID Interface callback
+ * @retval status
+ */
+uint8_t USBD_CUSTOM_HID_RegisterInterface(USBD_HandleTypeDef *pdev,
+ USBD_CUSTOM_HID_ItfTypeDef *fops)
+{
+ if (fops == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ pdev->pUserData_HID_Custom = fops;
+
+ return (uint8_t)USBD_OK;
+}
+
+void USBD_Update_HID_Custom_DESC(uint8_t *desc, uint8_t itf_no, uint8_t in_ep, uint8_t out_ep, uint8_t str_idx)
+{
+ desc[11] = itf_no;
+ desc[17] = str_idx;
+ desc[29] = in_ep;
+ desc[36] = out_ep;
+
+ CUSTOM_HID_IN_EP = in_ep;
+ CUSTOM_HID_OUT_EP = out_ep;
+ CUSTOM_HID_ITF_NBR = itf_no;
+ CUSTOM_HID_STR_DESC_IDX = str_idx;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_KEYBOARD/Inc/usbd_hid_keyboard.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_KEYBOARD/Inc/usbd_hid_keyboard.h
new file mode 100644
index 0000000..2d3c9ef
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_KEYBOARD/Inc/usbd_hid_keyboard.h
@@ -0,0 +1,144 @@
+/**
+ ******************************************************************************
+ * @file usbd_hid.h
+ * @author MCD Application Team
+ * @brief Header file for the usbd_hid_core.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_HID_KEYBAORD_H
+#define __USB_HID_KEYBAORD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_HID
+ * @brief This file is the Header file for usbd_hid.c
+ * @{
+ */
+
+
+/** @defgroup USBD_HID_Exported_Defines
+ * @{
+ */
+
+#define HID_KEYBOARD_STR_DESC "STM32 USB KEYBOARD"
+
+#define HID_KEYBOARD_EPIN_SIZE 0x08U
+
+#define HID_KEYBOARD_CONFIG_DESC_SIZE 34U
+#define HID_KEYBOARD_DESC_SIZE 9U
+
+#define HID_KEYBOARD_REPORT_DESC_SIZE 187U
+
+#define HID_KEYBOARD_DESCRIPTOR_TYPE 0x21U
+#define HID_KEYBOARD_REPORT_DESC 0x22U
+
+#ifndef HID_KEYBOARD_HS_BINTERVAL
+#define HID_KEYBOARD_HS_BINTERVAL 0x07U
+#endif /* HID_KEYBOARD_HS_BINTERVAL */
+
+#ifndef HID_KEYBOARD_FS_BINTERVAL
+#define HID_KEYBOARD_FS_BINTERVAL 0x0AU
+#endif /* HID_KEYBOARD_FS_BINTERVAL */
+
+#define HID_KEYBOARD_REQ_SET_PROTOCOL 0x0BU
+#define HID_KEYBOARD_REQ_GET_PROTOCOL 0x03U
+
+#define HID_KEYBOARD_REQ_SET_IDLE 0x0AU
+#define HID_KEYBOARD_REQ_GET_IDLE 0x02U
+
+#define HID_KEYBOARD_REQ_SET_REPORT 0x09U
+#define HID_KEYBOARD_REQ_GET_REPORT 0x01U
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+typedef enum
+{
+ KEYBOARD_HID_IDLE = 0,
+ KEYBOARD_HID_BUSY,
+} HID_Keyboard_StateTypeDef;
+
+typedef struct
+{
+ uint32_t Protocol;
+ uint32_t IdleState;
+ uint32_t AltSetting;
+ HID_Keyboard_StateTypeDef state;
+} USBD_HID_Keyboard_HandleTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern USBD_ClassTypeDef USBD_HID_KEYBOARD;
+
+extern uint8_t HID_KEYBOARD_IN_EP;
+extern uint8_t HID_KEYBOARD_ITF_NBR;
+extern uint8_t HID_KEYBOARD_STR_DESC_IDX;
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+uint8_t USBD_HID_Keybaord_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
+uint32_t USBD_HID_Keyboard_GetPollingInterval(USBD_HandleTypeDef *pdev);
+
+void USBD_Update_HID_KBD_DESC(uint8_t *desc, uint8_t itf_no, uint8_t in_ep, uint8_t str_idx);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_HID_KEYBAORD_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_KEYBOARD/Src/usbd_hid_keyboard.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_KEYBOARD/Src/usbd_hid_keyboard.c
new file mode 100644
index 0000000..9500cc9
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_KEYBOARD/Src/usbd_hid_keyboard.c
@@ -0,0 +1,713 @@
+/**
+ ******************************************************************************
+ * @file usbd_hid.c
+ * @author MCD Application Team
+ * @brief This file provides the HID core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * HID Class Description
+ * ===================================================================
+ * This module manages the HID class V1.11 following the "Device Class Definition
+ * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
+ * This driver implements the following aspects of the specification:
+ * - The Boot Interface Subclass
+ * - The Keyboard protocol
+ * - Usage Page : Generic Desktop
+ * - Collection : Application
+ *
+ * @note In HS mode and when the DMA is used, all variables and data structures
+ * dealing with the DMA during the transaction process should be 32-bit aligned.
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_hid_keyboard.h"
+#include "usbd_ctlreq.h"
+
+#define _HID_KEYBOARD_IN_EP 0x81U
+#define _HID_KEYBOARD_ITF_NBR 0x00
+#define _HID_KEYBOARD_STR_DESC_IDX 0x00U
+
+uint8_t HID_KEYBOARD_IN_EP = _HID_KEYBOARD_IN_EP;
+uint8_t HID_KEYBOARD_ITF_NBR = _HID_KEYBOARD_ITF_NBR;
+uint8_t HID_KEYBOARD_STR_DESC_IDX = _HID_KEYBOARD_STR_DESC_IDX;
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_HID
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_HID_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_FunctionPrototypes
+ * @{
+ */
+
+static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length);
+static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length);
+static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length);
+static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length);
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_Variables
+ * @{
+ */
+
+static USBD_HID_Keyboard_HandleTypeDef USBD_HID_KBD_Instace;
+
+USBD_ClassTypeDef USBD_HID_KEYBOARD =
+ {
+ USBD_HID_Init,
+ USBD_HID_DeInit,
+ USBD_HID_Setup,
+ NULL, /* EP0_TxSent */
+ NULL, /* EP0_RxReady */
+ USBD_HID_DataIn, /* DataIn */
+ NULL, /* DataOut */
+ NULL, /* SOF */
+ NULL,
+ NULL,
+ USBD_HID_GetHSCfgDesc,
+ USBD_HID_GetFSCfgDesc,
+ USBD_HID_GetOtherSpeedCfgDesc,
+ USBD_HID_GetDeviceQualifierDesc,
+};
+
+/* USB HID device FS Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_HID_KEYBOARD_CfgFSDesc[HID_KEYBOARD_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ HID_KEYBOARD_CONFIG_DESC_SIZE, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xE0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0xA0, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA: this current is used for detecting Vbus */
+
+ /************** Descriptor of Keyboard interface ****************/
+ /* 09 */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _HID_KEYBOARD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints */
+ 0x03, /* bInterfaceClass: HID */
+ 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+ 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+ _HID_KEYBOARD_STR_DESC_IDX, /* iInterface: Index of string descriptor */
+ /******************** Descriptor of Keyboard HID ********************/
+ /* 18 */
+ 0x09, /* bLength: HID Descriptor size */
+ HID_KEYBOARD_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
+ 0x11, /* bcdHID: HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+ /******************** Descriptor of Keyboard endpoint ********************/
+ /* 27 */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType:*/
+ _HID_KEYBOARD_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ HID_KEYBOARD_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */
+ 0x00,
+ HID_KEYBOARD_FS_BINTERVAL, /* bInterval: Polling Interval */
+ /* 34 */
+};
+
+/* USB HID device HS Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_HID_KEYBOARD_CfgHSDesc[HID_KEYBOARD_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ HID_KEYBOARD_CONFIG_DESC_SIZE, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xE0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0xA0, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA: this current is used for detecting Vbus */
+
+ /************** Descriptor of Keyboard interface ****************/
+ /* 09 */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _HID_KEYBOARD_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints */
+ 0x03, /* bInterfaceClass: HID */
+ 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+ 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+ _HID_KEYBOARD_STR_DESC_IDX, /* iInterface: Index of string descriptor */
+ /******************** Descriptor of Keyboard HID ********************/
+ /* 18 */
+ 0x09, /* bLength: HID Descriptor size */
+ HID_KEYBOARD_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
+ 0x11, /* bcdHID: HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+ /******************** Descriptor of Keyboard endpoint ********************/
+ /* 27 */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
+ _HID_KEYBOARD_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ HID_KEYBOARD_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */
+ 0x00,
+ HID_KEYBOARD_HS_BINTERVAL, /* bInterval: Polling Interval */
+ /* 34 */
+};
+
+/* USB HID device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_HID_KEYBOARD_Desc[HID_KEYBOARD_DESC_SIZE] __ALIGN_END =
+ {
+ /* 18 */
+ 0x09, /* bLength: HID Descriptor size */
+ HID_KEYBOARD_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
+ 0x11, /* bcdHID: HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+/* HID keyboard report descriptor */
+__ALIGN_BEGIN static uint8_t HID_KEYBOARD_ReportDesc[HID_KEYBOARD_REPORT_DESC_SIZE] __ALIGN_END =
+ {
+ 0x05, 0x01,
+ 0x09, 0x06,
+ 0xA1, 0x01,
+ 0x85, 0x01,
+ 0x05, 0x07,
+ 0x19, 0xE0,
+ 0x29, 0xE7,
+ 0x15, 0x00,
+ 0x25, 0x01,
+ 0x75, 0x01,
+ 0x95, 0x08,
+ 0x81, 0x02,
+ 0x75, 0x08,
+ 0x95, 0x01,
+ 0x81, 0x01,
+ 0x05, 0x07,
+ 0x19, 0x00,
+ 0x29, 0x65,
+ 0x15, 0x00,
+ 0x25, 0x65,
+ 0x75, 0x08,
+ 0x95, 0x05,
+ 0x81, 0x00,
+ 0xC0, 0x05,
+ 0x0C, 0x09,
+ 0x01, 0xA1,
+ 0x01, 0x85,
+ 0x02, 0x19,
+ 0x00, 0x2A,
+ 0x3C, 0x02,
+ 0x15, 0x00,
+ 0x26, 0x3C,
+ 0x02, 0x95,
+ 0x01, 0x75,
+ 0x10, 0x81,
+ 0x00, 0xC0,
+ 0x05, 0x01,
+ 0x09, 0x80,
+ 0xA1, 0x01,
+ 0x85, 0x03,
+ 0x19, 0x81,
+ 0x29, 0x83,
+ 0x15, 0x00,
+ 0x25, 0x01,
+ 0x75, 0x01,
+ 0x95, 0x03,
+ 0x81, 0x02,
+ 0x95, 0x05,
+ 0x81, 0x01,
+ 0xC0, 0x06,
+ 0x01, 0xFF,
+ 0x09, 0x01,
+ 0xA1, 0x01,
+ 0x85, 0x04,
+ 0x95, 0x01,
+ 0x75, 0x08,
+ 0x15, 0x01,
+ 0x25, 0x0A,
+ 0x09, 0x20,
+ 0xB1, 0x03,
+ 0x09, 0x23,
+ 0xB1, 0x03,
+ 0x25, 0x4F,
+ 0x09, 0x21,
+ 0xB1, 0x03,
+ 0x25, 0x30,
+ 0x09, 0x22,
+ 0xB1, 0x03,
+ 0x95, 0x03,
+ 0x09, 0x24,
+ 0xB1, 0x03,
+ 0xC0, 0x06,
+ 0x01, 0xFF,
+ 0x09, 0x01,
+ 0xA1, 0x01,
+ 0x85, 0x05,
+ 0x95, 0x01,
+ 0x75, 0x08,
+ 0x15, 0x01,
+ 0x25, 0x0A,
+ 0x09, 0x20,
+ 0xB1, 0x03,
+ 0x09, 0x23,
+ 0xB1, 0x03,
+ 0x25, 0x4F,
+ 0x09, 0x21,
+ 0xB1, 0x03,
+ 0x25, 0x30,
+ 0x09, 0x22,
+ 0xB1, 0x03,
+ 0x95, 0x03,
+ 0x09, 0x24,
+ 0xB1, 0x03,
+ 0xC0};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_HID_Init
+ * Initialize the HID interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ USBD_HID_Keyboard_HandleTypeDef *hhid;
+
+ hhid = &USBD_HID_KBD_Instace;
+
+ if (hhid == NULL)
+ {
+ pdev->pClassData_HID_Keyboard = NULL;
+ return (uint8_t)USBD_EMEM;
+ }
+
+ pdev->pClassData_HID_Keyboard = (void *)hhid;
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ pdev->ep_in[HID_KEYBOARD_IN_EP & 0xFU].bInterval = HID_KEYBOARD_HS_BINTERVAL;
+ }
+ else /* LOW and FULL-speed endpoints */
+ {
+ pdev->ep_in[HID_KEYBOARD_IN_EP & 0xFU].bInterval = HID_KEYBOARD_FS_BINTERVAL;
+ }
+
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, HID_KEYBOARD_IN_EP, USBD_EP_TYPE_INTR, HID_KEYBOARD_EPIN_SIZE);
+ pdev->ep_in[HID_KEYBOARD_IN_EP & 0xFU].is_used = 1U;
+
+ hhid->state = KEYBOARD_HID_IDLE;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_HID_DeInit
+ * DeInitialize the HID layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ /* Close HID EPs */
+ (void)USBD_LL_CloseEP(pdev, HID_KEYBOARD_IN_EP);
+ pdev->ep_in[HID_KEYBOARD_IN_EP & 0xFU].is_used = 0U;
+ pdev->ep_in[HID_KEYBOARD_IN_EP & 0xFU].bInterval = 0U;
+
+ /* Free allocated memory */
+ if (pdev->pClassData_HID_Keyboard != NULL)
+ {
+#if (0)
+ (void)USBD_free(pdev->pClassData_HID_Keyboard);
+#endif
+ pdev->pClassData_HID_Keyboard = NULL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_HID_Setup
+ * Handle the HID specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_HID_Keyboard_HandleTypeDef *hhid = (USBD_HID_Keyboard_HandleTypeDef *)pdev->pClassData_HID_Keyboard;
+ USBD_StatusTypeDef ret = USBD_OK;
+ uint16_t len;
+ uint8_t *pbuf;
+ uint16_t status_info = 0U;
+
+ if (hhid == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS:
+ switch (req->bRequest)
+ {
+ case HID_KEYBOARD_REQ_SET_PROTOCOL:
+ hhid->Protocol = (uint8_t)(req->wValue);
+ break;
+
+ case HID_KEYBOARD_REQ_GET_PROTOCOL:
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U);
+ break;
+
+ case HID_KEYBOARD_REQ_SET_IDLE:
+ hhid->IdleState = (uint8_t)(req->wValue >> 8);
+ break;
+
+ case HID_KEYBOARD_REQ_GET_IDLE:
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U);
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_DESCRIPTOR:
+ if ((req->wValue >> 8) == HID_KEYBOARD_REPORT_DESC)
+ {
+ len = MIN(HID_KEYBOARD_REPORT_DESC_SIZE, req->wLength);
+ pbuf = HID_KEYBOARD_ReportDesc;
+ }
+ else if ((req->wValue >> 8) == HID_KEYBOARD_DESCRIPTOR_TYPE)
+ {
+ pbuf = USBD_HID_KEYBOARD_Desc;
+ len = MIN(HID_KEYBOARD_DESC_SIZE, req->wLength);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ (void)USBD_CtlSendData(pdev, pbuf, len);
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ hhid->AltSetting = (uint8_t)(req->wValue);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_HID_GetCfgFSDesc
+ * return FS configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_HID_KEYBOARD_CfgFSDesc);
+
+ return USBD_HID_KEYBOARD_CfgFSDesc;
+}
+
+/**
+ * @brief USBD_HID_GetCfgHSDesc
+ * return HS configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_HID_KEYBOARD_CfgHSDesc);
+
+ return USBD_HID_KEYBOARD_CfgHSDesc;
+}
+
+/**
+ * @brief USBD_HID_GetOtherSpeedCfgDesc
+ * return other speed configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_HID_KEYBOARD_CfgFSDesc);
+
+ return USBD_HID_KEYBOARD_CfgFSDesc;
+}
+
+/**
+ * @brief USBD_HID_DataIn
+ * handle data IN Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(epnum);
+ /* Ensure that the FIFO is empty before a new transfer, this condition could
+ be caused by a new transfer before the end of the previous transfer */
+ ((USBD_HID_Keyboard_HandleTypeDef *)pdev->pClassData_HID_Keyboard)->state = KEYBOARD_HID_IDLE;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief DeviceQualifierDescriptor
+ * return Device Qualifier descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_HID_DeviceQualifierDesc);
+
+ return USBD_HID_DeviceQualifierDesc;
+}
+
+/**
+ * @brief USBD_HID_SendReport
+ * Send HID Report
+ * @param pdev: device instance
+ * @param buff: pointer to report
+ * @retval status
+ */
+uint8_t USBD_HID_Keybaord_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len)
+{
+ USBD_HID_Keyboard_HandleTypeDef *hhid = (USBD_HID_Keyboard_HandleTypeDef *)pdev->pClassData_HID_Keyboard;
+
+ if (hhid == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ if (hhid->state == KEYBOARD_HID_IDLE)
+ {
+ hhid->state = KEYBOARD_HID_BUSY;
+ (void)USBD_LL_Transmit(pdev, HID_KEYBOARD_IN_EP, report, len);
+ }
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_HID_GetPollingInterval
+ * return polling interval from endpoint descriptor
+ * @param pdev: device instance
+ * @retval polling interval
+ */
+uint32_t USBD_HID_Keyboard_GetPollingInterval(USBD_HandleTypeDef *pdev)
+{
+ uint32_t polling_interval;
+
+ /* HIGH-speed endpoints */
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ /* Sets the data transfer polling interval for high speed transfers.
+ Values between 1..16 are allowed. Values correspond to interval
+ of 2 ^ (bInterval-1). This option (8 ms, corresponds to HID_HS_BINTERVAL */
+ polling_interval = (((1U << (HID_KEYBOARD_HS_BINTERVAL - 1U))) / 8U);
+ }
+ else /* LOW and FULL-speed endpoints */
+ {
+ /* Sets the data transfer polling interval for low and full
+ speed transfers */
+ polling_interval = HID_KEYBOARD_FS_BINTERVAL;
+ }
+
+ return ((uint32_t)(polling_interval));
+}
+
+void USBD_Update_HID_KBD_DESC(uint8_t *desc, uint8_t itf_no, uint8_t in_ep, uint8_t str_idx)
+{
+ desc[11] = itf_no;
+ desc[17] = str_idx;
+ desc[29] = in_ep;
+
+ HID_KEYBOARD_IN_EP = in_ep;
+ HID_KEYBOARD_ITF_NBR = itf_no;
+ HID_KEYBOARD_STR_DESC_IDX = str_idx;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_MOUSE/Inc/usbd_hid_mouse.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_MOUSE/Inc/usbd_hid_mouse.h
new file mode 100644
index 0000000..9cfae3d
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_MOUSE/Inc/usbd_hid_mouse.h
@@ -0,0 +1,142 @@
+/**
+ ******************************************************************************
+ * @file usbd_hid.h
+ * @author MCD Application Team
+ * @brief Header file for the usbd_hid_core.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_HID_H
+#define __USB_HID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_HID
+ * @brief This file is the Header file for usbd_hid.c
+ * @{
+ */
+
+
+/** @defgroup USBD_HID_Exported_Defines
+ * @{
+ */
+#define HID_MOUSE_STR_DESC "STM32 USB MOUSE"
+
+#define HID_EPIN_SIZE 0x04U
+
+#define USB_HID_CONFIG_DESC_SIZ 34U
+#define USB_HID_DESC_SIZ 9U
+#define HID_MOUSE_REPORT_DESC_SIZE 74U
+
+#define HID_DESCRIPTOR_TYPE 0x21U
+#define HID_REPORT_DESC 0x22U
+
+#ifndef HID_HS_BINTERVAL
+#define HID_HS_BINTERVAL 0x07U
+#endif /* HID_HS_BINTERVAL */
+
+#ifndef HID_FS_BINTERVAL
+#define HID_FS_BINTERVAL 0x0AU
+#endif /* HID_FS_BINTERVAL */
+
+#define HID_REQ_SET_PROTOCOL 0x0BU
+#define HID_REQ_GET_PROTOCOL 0x03U
+
+#define HID_REQ_SET_IDLE 0x0AU
+#define HID_REQ_GET_IDLE 0x02U
+
+#define HID_REQ_SET_REPORT 0x09U
+#define HID_REQ_GET_REPORT 0x01U
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+typedef enum
+{
+ HID_IDLE = 0,
+ HID_BUSY,
+} HID_StateTypeDef;
+
+typedef struct
+{
+ uint32_t Protocol;
+ uint32_t IdleState;
+ uint32_t AltSetting;
+ HID_StateTypeDef state;
+} USBD_HID_HandleTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern USBD_ClassTypeDef USBD_HID_MOUSE;
+
+extern uint8_t HID_MOUSE_IN_EP;
+extern uint8_t HID_MOUSE_ITF_NBR;
+extern uint8_t HID_MOUSE_STR_DESC_IDX;
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+uint8_t USBD_HID_Mouse_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
+uint32_t USBD_HID_Mouse_GetPollingInterval(USBD_HandleTypeDef *pdev);
+
+void USBD_Update_HID_Mouse_DESC(uint8_t *desc, uint8_t itf_no, uint8_t in_ep, uint8_t str_idx);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_HID_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_MOUSE/Src/usbd_hid_mouse.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_MOUSE/Src/usbd_hid_mouse.c
new file mode 100644
index 0000000..a028e72
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/HID_MOUSE/Src/usbd_hid_mouse.c
@@ -0,0 +1,665 @@
+/**
+ ******************************************************************************
+ * @file usbd_hid.c
+ * @author MCD Application Team
+ * @brief This file provides the HID core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * HID Class Description
+ * ===================================================================
+ * This module manages the HID class V1.11 following the "Device Class Definition
+ * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
+ * This driver implements the following aspects of the specification:
+ * - The Boot Interface Subclass
+ * - The Mouse protocol
+ * - Usage Page : Generic Desktop
+ * - Usage : Joystick
+ * - Collection : Application
+ *
+ * @note In HS mode and when the DMA is used, all variables and data structures
+ * dealing with the DMA during the transaction process should be 32-bit aligned.
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2015 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_hid_mouse.h"
+#include "usbd_ctlreq.h"
+
+#define _HID_MOUSE_IN_EP 0x81U
+#define _HID_MOUSE_ITF_NBR 0x00
+#define _HID_MOUSE_STR_DESC_IDX 0x00U
+
+uint8_t HID_MOUSE_IN_EP = _HID_MOUSE_IN_EP;
+uint8_t HID_MOUSE_ITF_NBR = _HID_MOUSE_ITF_NBR;
+uint8_t HID_MOUSE_STR_DESC_IDX = _HID_MOUSE_STR_DESC_IDX;
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_HID
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_HID_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_FunctionPrototypes
+ * @{
+ */
+
+static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length);
+static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length);
+static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length);
+static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length);
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_Variables
+ * @{
+ */
+
+static USBD_HID_HandleTypeDef USBD_HID_Instance;
+
+USBD_ClassTypeDef USBD_HID_MOUSE =
+ {
+ USBD_HID_Init,
+ USBD_HID_DeInit,
+ USBD_HID_Setup,
+ NULL, /* EP0_TxSent */
+ NULL, /* EP0_RxReady */
+ USBD_HID_DataIn, /* DataIn */
+ NULL, /* DataOut */
+ NULL, /* SOF */
+ NULL,
+ NULL,
+ USBD_HID_GetHSCfgDesc,
+ USBD_HID_GetFSCfgDesc,
+ USBD_HID_GetOtherSpeedCfgDesc,
+ USBD_HID_GetDeviceQualifierDesc,
+};
+
+/* USB HID device FS Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xE0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0xA0, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA: this current is used for detecting Vbus */
+
+ /************** Descriptor of Joystick Mouse interface ****************/
+ /* 09 */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _HID_MOUSE_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints */
+ 0x03, /* bInterfaceClass: HID */
+ 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+ 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+ _HID_MOUSE_STR_DESC_IDX, /* iInterface: Index of string descriptor */
+ /******************** Descriptor of Joystick Mouse HID ********************/
+ /* 18 */
+ 0x09, /* bLength: HID Descriptor size */
+ HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
+ 0x11, /* bcdHID: HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+ /******************** Descriptor of Mouse endpoint ********************/
+ /* 27 */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType:*/
+ _HID_MOUSE_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ HID_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */
+ 0x00,
+ HID_FS_BINTERVAL, /* bInterval: Polling Interval */
+ /* 34 */
+};
+
+/* USB HID device HS Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_HID_CfgHSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
+ {
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xE0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0xA0, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower 100 mA: this current is used for detecting Vbus */
+
+ /************** Descriptor of Joystick Mouse interface ****************/
+ /* 09 */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
+ _HID_MOUSE_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x01, /* bNumEndpoints */
+ 0x03, /* bInterfaceClass: HID */
+ 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
+ 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
+ _HID_MOUSE_STR_DESC_IDX, /* iInterface: Index of string descriptor */
+ /******************** Descriptor of Joystick Mouse HID ********************/
+ /* 18 */
+ 0x09, /* bLength: HID Descriptor size */
+ HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
+ 0x11, /* bcdHID: HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+ /******************** Descriptor of Mouse endpoint ********************/
+ /* 27 */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
+ _HID_MOUSE_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
+ 0x03, /* bmAttributes: Interrupt endpoint */
+ HID_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */
+ 0x00,
+ HID_HS_BINTERVAL, /* bInterval: Polling Interval */
+ /* 34 */
+};
+
+/* USB HID device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END =
+ {
+ /* 18 */
+ 0x09, /* bLength: HID Descriptor size */
+ HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
+ 0x11, /* bcdHID: HID Class Spec release number */
+ 0x01,
+ 0x00, /* bCountryCode: Hardware target country */
+ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
+ 0x22, /* bDescriptorType */
+ HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
+ 0x00,
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
+ {
+ 0x05, 0x01,
+ 0x09, 0x02,
+ 0xA1, 0x01,
+ 0x09, 0x01,
+
+ 0xA1, 0x00,
+ 0x05, 0x09,
+ 0x19, 0x01,
+ 0x29, 0x03,
+
+ 0x15, 0x00,
+ 0x25, 0x01,
+ 0x95, 0x03,
+ 0x75, 0x01,
+
+ 0x81, 0x02,
+ 0x95, 0x01,
+ 0x75, 0x05,
+ 0x81, 0x01,
+
+ 0x05, 0x01,
+ 0x09, 0x30,
+ 0x09, 0x31,
+ 0x09, 0x38,
+
+ 0x15, 0x81,
+ 0x25, 0x7F,
+ 0x75, 0x08,
+ 0x95, 0x03,
+
+ 0x81, 0x06,
+ 0xC0, 0x09,
+ 0x3c, 0x05,
+ 0xff, 0x09,
+
+ 0x01, 0x15,
+ 0x00, 0x25,
+ 0x01, 0x75,
+ 0x01, 0x95,
+
+ 0x02, 0xb1,
+ 0x22, 0x75,
+ 0x06, 0x95,
+ 0x01, 0xb1,
+
+ 0x01, 0xc0};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_HID_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_HID_Init
+ * Initialize the HID interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ USBD_HID_HandleTypeDef *hhid;
+
+ hhid = &USBD_HID_Instance;
+
+ if (hhid == NULL)
+ {
+ pdev->pClassData_HID_Mouse = NULL;
+ return (uint8_t)USBD_EMEM;
+ }
+
+ pdev->pClassData_HID_Mouse = (void *)hhid;
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ pdev->ep_in[HID_MOUSE_IN_EP & 0xFU].bInterval = HID_HS_BINTERVAL;
+ }
+ else /* LOW and FULL-speed endpoints */
+ {
+ pdev->ep_in[HID_MOUSE_IN_EP & 0xFU].bInterval = HID_FS_BINTERVAL;
+ }
+
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, HID_MOUSE_IN_EP, USBD_EP_TYPE_INTR, HID_EPIN_SIZE);
+ pdev->ep_in[HID_MOUSE_IN_EP & 0xFU].is_used = 1U;
+
+ hhid->state = HID_IDLE;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_HID_DeInit
+ * DeInitialize the HID layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ /* Close HID EPs */
+ (void)USBD_LL_CloseEP(pdev, HID_MOUSE_IN_EP);
+ pdev->ep_in[HID_MOUSE_IN_EP & 0xFU].is_used = 0U;
+ pdev->ep_in[HID_MOUSE_IN_EP & 0xFU].bInterval = 0U;
+
+ /* Free allocated memory */
+ if (pdev->pClassData_HID_Mouse != NULL)
+ {
+#if (0)
+ (void)USBD_free(pdev->pClassData_HID_Mouse);
+#endif
+ pdev->pClassData_HID_Mouse = NULL;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_HID_Setup
+ * Handle the HID specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData_HID_Mouse;
+ USBD_StatusTypeDef ret = USBD_OK;
+ uint16_t len;
+ uint8_t *pbuf;
+ uint16_t status_info = 0U;
+
+ if (hhid == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS:
+ switch (req->bRequest)
+ {
+ case HID_REQ_SET_PROTOCOL:
+ hhid->Protocol = (uint8_t)(req->wValue);
+ break;
+
+ case HID_REQ_GET_PROTOCOL:
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U);
+ break;
+
+ case HID_REQ_SET_IDLE:
+ hhid->IdleState = (uint8_t)(req->wValue >> 8);
+ break;
+
+ case HID_REQ_GET_IDLE:
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U);
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_DESCRIPTOR:
+ if ((req->wValue >> 8) == HID_REPORT_DESC)
+ {
+ len = MIN(HID_MOUSE_REPORT_DESC_SIZE, req->wLength);
+ pbuf = HID_MOUSE_ReportDesc;
+ }
+ else if ((req->wValue >> 8) == HID_DESCRIPTOR_TYPE)
+ {
+ pbuf = USBD_HID_Desc;
+ len = MIN(USB_HID_DESC_SIZ, req->wLength);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ (void)USBD_CtlSendData(pdev, pbuf, len);
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ hhid->AltSetting = (uint8_t)(req->wValue);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_HID_GetCfgFSDesc
+ * return FS configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_HID_CfgFSDesc);
+
+ return USBD_HID_CfgFSDesc;
+}
+
+/**
+ * @brief USBD_HID_GetCfgHSDesc
+ * return HS configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_HID_CfgHSDesc);
+
+ return USBD_HID_CfgHSDesc;
+}
+
+/**
+ * @brief USBD_HID_GetOtherSpeedCfgDesc
+ * return other speed configuration descriptor
+ * @param speed : current device speed
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_HID_CfgFSDesc);
+
+ return USBD_HID_CfgFSDesc;
+}
+
+/**
+ * @brief USBD_HID_DataIn
+ * handle data IN Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(epnum);
+ /* Ensure that the FIFO is empty before a new transfer, this condition could
+ be caused by a new transfer before the end of the previous transfer */
+ ((USBD_HID_HandleTypeDef *)pdev->pClassData_HID_Mouse)->state = HID_IDLE;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief DeviceQualifierDescriptor
+ * return Device Qualifier descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_HID_DeviceQualifierDesc);
+
+ return USBD_HID_DeviceQualifierDesc;
+}
+
+/**
+ * @brief USBD_HID_SendReport
+ * Send HID Report
+ * @param pdev: device instance
+ * @param buff: pointer to report
+ * @retval status
+ */
+uint8_t USBD_HID_Mouse_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len)
+{
+ USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData_HID_Mouse;
+
+ if (hhid == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ if (hhid->state == HID_IDLE)
+ {
+ hhid->state = HID_BUSY;
+ (void)USBD_LL_Transmit(pdev, HID_MOUSE_IN_EP, report, len);
+ }
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_HID_GetPollingInterval
+ * return polling interval from endpoint descriptor
+ * @param pdev: device instance
+ * @retval polling interval
+ */
+uint32_t USBD_HID_Mouse_GetPollingInterval(USBD_HandleTypeDef *pdev)
+{
+ uint32_t polling_interval;
+
+ /* HIGH-speed endpoints */
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ /* Sets the data transfer polling interval for high speed transfers.
+ Values between 1..16 are allowed. Values correspond to interval
+ of 2 ^ (bInterval-1). This option (8 ms, corresponds to HID_HS_BINTERVAL */
+ polling_interval = (((1U << (HID_HS_BINTERVAL - 1U))) / 8U);
+ }
+ else /* LOW and FULL-speed endpoints */
+ {
+ /* Sets the data transfer polling interval for low and full
+ speed transfers */
+ polling_interval = HID_FS_BINTERVAL;
+ }
+
+ return ((uint32_t)(polling_interval));
+}
+
+void USBD_Update_HID_Mouse_DESC(uint8_t *desc, uint8_t itf_no, uint8_t in_ep, uint8_t str_idx)
+{
+ desc[11] = itf_no;
+ desc[17] = str_idx;
+ desc[29] = in_ep;
+
+ HID_MOUSE_IN_EP = in_ep;
+ HID_MOUSE_ITF_NBR = itf_no;
+ HID_MOUSE_STR_DESC_IDX = str_idx;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/PRINTER/Inc/usbd_printer.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/PRINTER/Inc/usbd_printer.h
new file mode 100644
index 0000000..4542a8b
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/PRINTER/Inc/usbd_printer.h
@@ -0,0 +1,161 @@
+/**
+ ******************************************************************************
+ * @file usbd_printer.h
+ * @author MCD Application Team
+ * @brief header file for the usbd_printer.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_PRNT_H
+#define __USB_PRNT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup usbd_PRNT
+ * @brief This file is the Header file for usbd_PRNT.c
+ * @{
+ */
+
+
+/** @defgroup usbd_PRNT_Exported_Defines
+ * @{
+ */
+#define PRNT_STR_DESC "STM32 USB PRINTER"
+
+#ifndef PRNT_DATA_HS_MAX_PACKET_SIZE
+#define PRNT_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
+#endif /* PRNT_DATA_HS_MAX_PACKET_SIZE */
+
+#ifndef PRNT_DATA_FS_MAX_PACKET_SIZE
+#define PRNT_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
+#endif /* PRNT_DATA_FS_MAX_PACKET_SIZE */
+
+#define USB_PRNT_CONFIG_DESC_SIZE 32U
+#define PRNT_DATA_HS_IN_PACKET_SIZE PRNT_DATA_HS_MAX_PACKET_SIZE
+#define PRNT_DATA_HS_OUT_PACKET_SIZE PRNT_DATA_HS_MAX_PACKET_SIZE
+
+#define PRNT_DATA_FS_IN_PACKET_SIZE PRNT_DATA_FS_MAX_PACKET_SIZE
+#define PRNT_DATA_FS_OUT_PACKET_SIZE PRNT_DATA_FS_MAX_PACKET_SIZE
+
+/*---------------------------------------------------------------------*/
+/* PRNT definitions */
+/*---------------------------------------------------------------------*/
+#define PRNT_STATUS_PAPER_EMPTY 0x10U
+#define PRNT_STATUS_SELECTED 0x08U
+#define PRNT_STATUS_NO_ERROR 0x00U
+
+#define USB_PRNT_SUBCLASS 0x01U
+
+#define USB_PRNT_UNIDIRECTIONAL 0x01U
+#define USB_PRNT_BIDIRECTIONAL 0x02U
+
+/* USB PRNT Request types */
+#define PRNT_GET_DEVICE_ID 0x00U
+#define PRNT_GET_PORT_STATUS 0x01U
+#define PRNT_SOFT_RESET 0x02U
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+typedef struct _USBD_PRNT_Itf
+{
+ int8_t (*Init)(void);
+ int8_t (*DeInit)(void);
+ int8_t (*Control_req)(uint8_t req, uint8_t *pbuf, uint16_t *length);
+ int8_t (*Receive)(uint8_t *Buf, uint32_t *Len);
+
+} USBD_PRNT_ItfTypeDef;
+
+typedef struct
+{
+ uint32_t data[PRNT_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32-bit alignment */
+ uint8_t CmdOpCode;
+ uint8_t CmdLength;
+ uint8_t *RxBuffer;
+ uint8_t *TxBuffer;
+ uint32_t RxLength;
+ uint32_t TxLength;
+
+ __IO uint32_t TxState;
+ __IO uint32_t RxState;
+} USBD_PRNT_HandleTypeDef;
+
+/** @defgroup USBD_CORE_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_CORE_Exported_Variables
+ * @{
+ */
+
+extern USBD_ClassTypeDef USBD_PRNT;
+
+extern uint8_t PRNT_IN_EP;
+extern uint8_t PRNT_OUT_EP;
+extern uint8_t PRNT_ITF_NBR;
+extern uint8_t PRINTER_STR_DESC_IDX;
+
+/**
+ * @}
+ */
+
+/** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+uint8_t USBD_PRNT_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_PRNT_ItfTypeDef *fops);
+uint8_t USBD_PRNT_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
+uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev);
+
+void USBD_Update_PRNT_DESC(uint8_t *desc, uint8_t itf_no, uint8_t in_ep, uint8_t out_ep, uint8_t str_idx);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USB_PRNT_H */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/PRINTER/Src/usbd_printer.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/PRINTER/Src/usbd_printer.c
new file mode 100644
index 0000000..f195f66
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/PRINTER/Src/usbd_printer.c
@@ -0,0 +1,696 @@
+/**
+ ******************************************************************************
+ * @file usbd_printer.c
+ * @author MCD Application Team
+ * @brief This file provides the high layer firmware functions to manage the
+ * following functionalities of the USB printer Class:
+ * - Initialization and Configuration of high and low layer
+ * - Enumeration as printer Device (and enumeration for each implemented memory interface)
+ * - OUT data transfer
+ * - Command OUT transfer (class requests management)
+ * - Error management
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * PRINTER Class Driver Description
+ * ===================================================================
+ * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
+ * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
+ * printer Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
+ * This driver implements the following aspects of the specification:
+ * - Device descriptor management
+ * - Configuration descriptor management
+ * - Enumeration as printer device with 2 data endpoints (IN and OUT)
+ * - Control Requests management (PRNT_GET_DEVICE_ID,PRNT_GET_PORT_STATUS,PRNT_SOFT_RESET)
+ * - protocol USB_PRNT_BIDIRECTIONAL
+ *
+ *
+ *
+ * These aspects may be enriched or modified for a specific user application.
+ *
+ * This driver doesn't implement the following aspects of the specification
+ * (but it is possible to manage these features with some modifications on this driver):
+ * - Any class-specific aspect relative to communication classes should be managed by user application.
+ * - All communication classes other than PSTN are not managed
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* BSPDependencies
+- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
+- "stm32xxxxx_{eval}{discovery}_io.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_printer.h"
+#include "usbd_ctlreq.h"
+
+#define _PRNT_IN_EP 0x81U /* Default: EP1 for data IN */
+#define _PRNT_OUT_EP 0x01U /* Default: EP1 for data OUT */
+#define _PRNT_ITF_NBR 0x00
+#define _PRINTER_STR_DESC_IDX 0x01
+
+uint8_t PRNT_IN_EP = _PRNT_IN_EP;
+uint8_t PRNT_OUT_EP = _PRNT_OUT_EP;
+uint8_t PRNT_ITF_NBR = _PRNT_ITF_NBR;
+uint8_t PRINTER_STR_DESC_IDX = _PRINTER_STR_DESC_IDX;
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_PRNT
+ * @brief usbd core module
+ * @{
+ */
+
+/** @defgroup USBD_PRNT_Private_TypesDefinitions
+ * @{
+ */
+/**
+ * @}
+ */
+static uint32_t usbd_PRNT_altset = 0U;
+
+/** @defgroup USBD_PRNT_Private_Defines
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_PRNT_Private_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBD_PRNT_Private_FunctionPrototypes
+ * @{
+ */
+static uint8_t USBD_PRNT_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_PRNT_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_PRNT_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+static uint8_t *USBD_PRNT_GetFSCfgDesc(uint16_t *length);
+static uint8_t *USBD_PRNT_GetHSCfgDesc(uint16_t *length);
+static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length);
+static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length);
+uint8_t *USBD_PRNT_GetDeviceQualifierDescriptor(uint16_t *length);
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_PRNT_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_PRNT_Private_Variables
+ * @{
+ */
+
+static USBD_PRNT_HandleTypeDef USBD_PRNT_Instance;
+
+/* PRNT interface class callbacks structure */
+USBD_ClassTypeDef USBD_PRNT =
+ {
+ USBD_PRNT_Init,
+ USBD_PRNT_DeInit,
+ USBD_PRNT_Setup,
+ NULL,
+ NULL,
+ USBD_PRNT_DataIn,
+ USBD_PRNT_DataOut,
+ NULL,
+ NULL,
+ NULL,
+ USBD_PRNT_GetHSCfgDesc,
+ USBD_PRNT_GetFSCfgDesc,
+ USBD_PRNT_GetOtherSpeedCfgDesc,
+ USBD_PRNT_GetDeviceQualifierDescriptor,
+};
+
+/* USB PRNT device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgHSDesc[USB_PRNT_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /*Configuration Descriptor*/
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_PRNT_CONFIG_DESC_SIZE, /* wTotalLength:no of returned bytes */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Self Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower in mA */
+
+ /* Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _PRNT_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: 2 endpoints used */
+ 0x07, /* bInterfaceClass: Communication Interface Class */
+ 0x01, /* bInterfaceSubClass: Abstract Control Model */
+ USB_PRNT_BIDIRECTIONAL, /* bDeviceProtocol */
+ _PRINTER_STR_DESC_IDX, /* iInterface */
+
+ /* Endpoint IN Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _PRNT_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(PRNT_DATA_HS_IN_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(PRNT_DATA_HS_IN_PACKET_SIZE),
+ 0x00, /* bInterval */
+
+ /* Endpoint OUT Descriptor */
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _PRNT_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(PRNT_DATA_HS_OUT_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(PRNT_DATA_HS_OUT_PACKET_SIZE),
+ 0x00 /* bInterval */
+};
+
+/* USB PRNT device Configuration Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgFSDesc[USB_PRNT_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /*Configuration Descriptor*/
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_PRNT_CONFIG_DESC_SIZE, /* wTotalLength:no of returned bytes */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Self Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower in mA */
+
+ /*Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _PRNT_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: 2 endpoints used */
+ 0x07, /* bInterfaceClass: Communication Interface Class */
+ 0x01, /* bInterfaceSubClass: Abstract Control Model */
+ USB_PRNT_BIDIRECTIONAL, /* bDeviceProtocol */
+ _PRINTER_STR_DESC_IDX, /* iInterface */
+
+ /*Endpoint IN Descriptor*/
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _PRNT_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(PRNT_DATA_FS_IN_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(PRNT_DATA_FS_IN_PACKET_SIZE),
+ 0x00, /* bInterval */
+
+ /*Endpoint OUT Descriptor*/
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _PRNT_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE),
+ 0x00 /* bInterval */
+};
+
+__ALIGN_BEGIN static uint8_t USBD_PRNT_OtherSpeedCfgDesc[USB_PRNT_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /*Configuration Descriptor*/
+ 0x09, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ USB_PRNT_CONFIG_DESC_SIZE, /* wTotalLength:no of returned bytes */
+ 0x00,
+ 0x01, /* bNumInterfaces: 1 interface */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Self Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* MaxPower in mA */
+
+ /*Interface Descriptor */
+ 0x09, /* bLength: Interface Descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
+ _PRNT_ITF_NBR, /* bInterfaceNumber: Number of Interface */
+ 0x00, /* bAlternateSetting: Alternate setting */
+ 0x02, /* bNumEndpoints: 2 endpoints used */
+ 0x07, /* bInterfaceClass: Communication Interface Class */
+ 0x01, /* bInterfaceSubClass: Abstract Control Model */
+ USB_PRNT_BIDIRECTIONAL, /* bDeviceProtocol */
+ _PRINTER_STR_DESC_IDX, /* iInterface */
+
+ /*Endpoint IN Descriptor*/
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _PRNT_IN_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(PRNT_DATA_FS_IN_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(PRNT_DATA_FS_IN_PACKET_SIZE),
+ 0x00, /* bInterval */
+
+ /*Endpoint OUT Descriptor*/
+ 0x07, /* bLength: Endpoint Descriptor size */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
+ _PRNT_OUT_EP, /* bEndpointAddress */
+ 0x02, /* bmAttributes: Bulk */
+ LOBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE), /* wMaxPacketSize */
+ HIBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE),
+ 0x00 /* bInterval */
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_PRNT_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_PRNT_Init
+ * Initialize the PRNT interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_PRNT_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ USBD_PRNT_HandleTypeDef *hPRNT;
+ uint16_t mps;
+ hPRNT = &USBD_PRNT_Instance;
+
+ if (hPRNT == NULL)
+ {
+ pdev->pClassData_PRNTR = NULL;
+ return (uint8_t)USBD_EMEM;
+ }
+
+ /* Setup the pClassData pointer */
+ pdev->pClassData_PRNTR = (void *)hPRNT;
+
+ /* Setup the max packet size according to selected speed */
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ mps = PRNT_DATA_HS_IN_PACKET_SIZE;
+ }
+ else
+ {
+ mps = PRNT_DATA_FS_IN_PACKET_SIZE;
+ }
+
+ /* Open EP IN */
+ (void)USBD_LL_OpenEP(pdev, PRNT_IN_EP, USBD_EP_TYPE_BULK, mps);
+
+ /* Set endpoint as used */
+ pdev->ep_in[PRNT_IN_EP & 0xFU].is_used = 1U;
+
+ /* Open EP OUT */
+ (void)USBD_LL_OpenEP(pdev, PRNT_OUT_EP, USBD_EP_TYPE_BULK, mps);
+
+ /* Set endpoint as used */
+ pdev->ep_out[PRNT_OUT_EP & 0xFU].is_used = 1U;
+
+ /* Init physical Interface components */
+ ((USBD_PRNT_ItfTypeDef *)pdev->pUserData_PRNTR)->Init();
+
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer, mps);
+
+ /* End of initialization phase */
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_PRNT_DeInit
+ * DeInitialize the PRNT layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_PRNT_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ /* Close EP IN */
+ (void)USBD_LL_CloseEP(pdev, PRNT_IN_EP);
+ pdev->ep_in[PRNT_IN_EP & 0xFU].is_used = 0U;
+
+ /* Close EP OUT */
+ (void)USBD_LL_CloseEP(pdev, PRNT_OUT_EP);
+ pdev->ep_out[PRNT_OUT_EP & 0xFU].is_used = 0U;
+
+ /* DeInit physical Interface components */
+ if (pdev->pClassData_PRNTR != NULL)
+ {
+ ((USBD_PRNT_ItfTypeDef *)pdev->pUserData_PRNTR)->DeInit();
+#if (0)
+ (void)USBD_free(pdev->pClassData_PRNTR);
+#endif
+ pdev->pClassData_PRNTR = NULL;
+ }
+
+ return 0U;
+}
+
+/**
+ * @brief USBD_PRNT_Setup
+ * Handle the PRNT specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_PRNT_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData_PRNTR;
+ USBD_PRNT_ItfTypeDef *hPRNTitf = (USBD_PRNT_ItfTypeDef *)pdev->pUserData_PRNTR;
+
+ USBD_StatusTypeDef ret = USBD_OK;
+ uint16_t status_info = 0U;
+ uint16_t data_length;
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ case USB_REQ_TYPE_CLASS:
+ if (req->wLength != 0U)
+ {
+ data_length = MIN(req->wLength, PRNT_DATA_HS_MAX_PACKET_SIZE);
+
+ if ((req->bmRequest & 0x80U) != 0U)
+ {
+ /* Call the User class interface function to process the command */
+ hPRNTitf->Control_req(req->bRequest, (uint8_t *)hPRNT->data, &data_length);
+
+ /* Return the answer to host */
+ (void)USBD_CtlSendData(pdev, (uint8_t *)hPRNT->data, data_length);
+ }
+ else
+ {
+ /* Prepare for control data reception */
+ (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hPRNT->data, data_length);
+ }
+ }
+ else
+ {
+ data_length = 0U;
+ hPRNTitf->Control_req(req->bRequest, (uint8_t *)req, &data_length);
+ }
+ break;
+
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&usbd_PRNT_altset, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state != USBD_STATE_CONFIGURED)
+ {
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = USBD_FAIL;
+ break;
+ }
+
+ return (uint8_t)ret;
+}
+
+/**
+ * @brief USBD_PRNT_DataIn
+ * Data sent on non-control IN endpoint
+ * @param pdev: device instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData_PRNTR;
+ PCD_HandleTypeDef *hpcd = pdev->pData;
+
+ if (hPRNT == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if ((pdev->ep_in[epnum].total_length > 0U) &&
+ ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
+ {
+ /* Update the packet total length */
+ pdev->ep_in[epnum].total_length = 0U;
+
+ /* Send ZLP */
+ (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
+ }
+ else
+ {
+ hPRNT->TxState = 0U;
+ }
+
+ return (uint8_t)USBD_OK;
+}
+/**
+ * @brief USBD_PRNT_DataOut
+ * Data received on non-control Out endpoint
+ * @param pdev: device instance
+ * @param epnum: endpoint number
+ * @retval status
+ */
+static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData_PRNTR;
+
+ if (hPRNT == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Get the received data length */
+ hPRNT->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
+
+ /* USB data will be immediately processed, this allow next USB traffic being
+ NAKed till the end of the application Xfer */
+ ((USBD_PRNT_ItfTypeDef *)pdev->pUserData_PRNTR)->Receive(hPRNT->RxBuffer, &hPRNT->RxLength);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_PRNT_GetFSCfgDesc
+ * Return configuration descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_PRNT_GetFSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_PRNT_CfgFSDesc);
+ return USBD_PRNT_CfgFSDesc;
+}
+
+/**
+ * @brief USBD_PRNT_GetHSCfgDesc
+ * Return configuration descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_PRNT_GetHSCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_PRNT_CfgHSDesc);
+ return USBD_PRNT_CfgHSDesc;
+}
+
+/**
+ * @brief USBD_PRNT_GetOtherSpeedCfgDesc
+ * Return configuration descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_PRNT_OtherSpeedCfgDesc);
+ return USBD_PRNT_OtherSpeedCfgDesc;
+}
+
+/**
+ * @brief USBD_PRNT_GetDeviceQualifierDescriptor
+ * return Device Qualifier descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+uint8_t *USBD_PRNT_GetDeviceQualifierDescriptor(uint16_t *length)
+{
+ *length = (uint16_t)sizeof(USBD_PRNT_DeviceQualifierDesc);
+ return USBD_PRNT_DeviceQualifierDesc;
+}
+
+/**
+ * @brief USBD_PRNT_RegisterInterface
+ * @param pdev: device instance
+ * @param fops: Interface callbacks
+ * @retval status
+ */
+uint8_t USBD_PRNT_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_PRNT_ItfTypeDef *fops)
+{
+ /* Check if the fops pointer is valid */
+ if (fops == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Setup the fops pointer */
+ pdev->pUserData_PRNTR = fops;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_PRNT_SetRxBuffer
+ * @param pdev: device instance
+ * @param pbuff: Rx Buffer
+ * @retval status
+ */
+uint8_t USBD_PRNT_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
+{
+ USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData_PRNTR;
+
+ hPRNT->RxBuffer = pbuff;
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_PRNT_ReceivePacket
+ * prepare OUT Endpoint for reception
+ * @param pdev: device instance
+ * @retval status
+ */
+uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev)
+{
+ USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData_PRNTR;
+
+ if (hPRNT == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer,
+ PRNT_DATA_HS_OUT_PACKET_SIZE);
+ }
+ else
+ {
+ /* Prepare Out endpoint to receive next packet */
+ (void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer,
+ PRNT_DATA_FS_OUT_PACKET_SIZE);
+ }
+
+ return (uint8_t)USBD_OK;
+}
+
+void USBD_Update_PRNT_DESC(uint8_t *desc, uint8_t itf_no, uint8_t in_ep, uint8_t out_ep, uint8_t str_idx)
+{
+ desc[11] = itf_no;
+ desc[17] = str_idx;
+ desc[20] = in_ep;
+ desc[27] = out_ep;
+
+ PRNT_IN_EP = in_ep;
+ PRNT_OUT_EP = out_ep;
+ PRNT_ITF_NBR = itf_no;
+ PRINTER_STR_DESC_IDX = str_idx;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/VIDEO/Inc/usbd_video.h b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/VIDEO/Inc/usbd_video.h
new file mode 100644
index 0000000..0469816
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/VIDEO/Inc/usbd_video.h
@@ -0,0 +1,462 @@
+/**
+ ******************************************************************************
+ * @file usbd_video.h
+ * @author MCD Application Team
+ * @brief header file for the usbd_video.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_VIDEO_H
+#define __USBD_VIDEO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_VIDEO
+ * @brief This file is the Header file for usbd_video.c
+ * @{
+ */
+
+
+/** @defgroup usbd_VIDEO_Exported_Defines
+ * @{
+ */
+#define UVC_STR_DESC "STM32 UVC"
+
+/* USB Video device class specification version 1.10 */
+#ifdef UVC_1_0
+#define UVC_VERSION 0x0100U /* UVC 1.0 */
+#else
+#define UVC_VERSION 0x0110U /* UVC 1.1 */
+#endif
+
+//#define USBD_UVC_FORMAT_UNCOMPRESSED
+
+/* These defines shall be updated in the usbd_conf.h file */
+#ifndef UVC_WIDTH
+#define UVC_WIDTH 400U
+#endif /* UVC_WIDTH */
+
+#ifndef UVC_HEIGHT
+#define UVC_HEIGHT 240U
+#endif /* UVC_HEIGHT */
+
+#ifndef UVC_CAM_FPS_FS
+#define UVC_CAM_FPS_FS 10U
+#endif /* UVC_CAM_FPS_FS */
+
+#ifndef UVC_CAM_FPS_HS
+#define UVC_CAM_FPS_HS 5U
+#endif /* UVC_CAM_FPS_HS */
+
+#ifndef UVC_PACKET_SIZE
+#define UVC_PACKET_SIZE 512U
+#endif /* UVC_PACKET_SIZE */
+
+#ifndef UVC_MAX_FRAME_SIZE
+#define UVC_MAX_FRAME_SIZE (UVC_WIDTH * UVC_HEIGHT * 16U / 2U)
+#endif /* UVC_MAX_FRAME_SIZE */
+
+#ifndef UVC_COLOR_PRIMARIE
+#define UVC_COLOR_PRIMARIE 0x01U
+#endif /* UVC_COLOR_PRIMARIE */
+
+#ifndef UVC_TFR_CHARACTERISTICS
+#define UVC_TFR_CHARACTERISTICS 0x01U
+#endif /* UVC_TFR_CHARACTERISTICS */
+
+#ifndef UVC_MATRIX_COEFFICIENTS
+#define UVC_MATRIX_COEFFICIENTS 0x04U
+#endif /* UVC_MATRIX_COEFFICIENTS */
+
+#ifndef UVC_BITS_PER_PIXEL
+#define UVC_BITS_PER_PIXEL 12U
+#endif /* UVC_BITS_PER_PIXEL */
+
+#define UVC_GUID_YUY2 0x32595559U
+#define UVC_GUID_NV12 0x3231564EU
+
+#ifndef UVC_UNCOMPRESSED_GUID
+#define UVC_UNCOMPRESSED_GUID UVC_GUID_NV12
+#endif /* UVC_UNCOMPRESSED_GUID */
+
+#define UVC_INTERVAL(n) (10000000U/(n))
+
+#define UVC_MIN_BIT_RATE(n) (UVC_WIDTH * UVC_HEIGHT * 16U * (n)) /* 16 bit */
+#define UVC_MAX_BIT_RATE(n) (UVC_WIDTH * UVC_HEIGHT * 16U * (n)) /* 16 bit */
+
+#define UVC_PACKETS_IN_FRAME(n) (UVC_MAX_FRAME_SIZE / (n))
+
+#ifndef UVC_ISO_FS_MPS
+#define UVC_ISO_FS_MPS 256U
+#endif
+
+#ifndef UVC_ISO_HS_MPS
+#define UVC_ISO_HS_MPS 512U
+#endif
+
+#ifndef UVC_HEADER_PACKET_CNT
+#define UVC_HEADER_PACKET_CNT 0x01U
+#endif
+
+
+#define UVC_REQ_READ_MASK 0x80U
+#define UVC_TOTAL_IF_NUM 0x02U
+
+#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
+#define UVC_CONFIG_DESC_SIZE (0x88U + 0x16U)
+#else
+#define UVC_CONFIG_DESC_SIZE 0x88U
+#endif
+
+#define UVC_TOTAL_BUF_SIZE 0x04U
+
+#define UVC_VC_EP_DESC_SIZE 0x05U
+#define UVC_STREAMING_EP_DESC_SIZE 0x07U
+#define UVC_EP_DESC_TYPE 0x25U
+
+/* Video Interface Class Codes*/
+#define UVC_CC_VIDEO 0x0EU
+
+#define UVC_PLAY_STATUS_STOP 0x00U
+#define UVC_PLAY_STATUS_READY 0x01U
+#define UVC_PLAY_STATUS_STREAMING 0x02U
+
+#ifndef WBVAL
+#define WBVAL(x) ((x) & 0xFFU),(((x) >> 8) & 0xFFU)
+#endif
+#ifndef DBVAL
+#define DBVAL(x) ((x)& 0xFFU),(((x) >> 8) & 0xFFU),(((x)>> 16) & 0xFFU),(((x) >> 24) & 0xFFU)
+#endif
+
+/* Video Interface Protocol Codes */
+#define PC_PROTOCOL_UNDEFINED 0x00U
+
+#define VIDEO_VC_IF_HEADER_DESC_SIZE 0x0DU
+#define VIDEO_IN_TERMINAL_DESC_SIZE 0x08U
+#define VIDEO_OUT_TERMINAL_DESC_SIZE 0x09U
+#define VIDEO_VS_IF_IN_HEADER_DESC_SIZE 0x0EU
+
+#define VS_FORMAT_UNCOMPRESSED_DESC_SIZE 0x1BU
+#define VS_FORMAT_MJPEG_DESC_SIZE 0x0BU
+#define VS_FRAME_DESC_SIZE 0x1EU
+#define VS_COLOR_MATCHING_DESC_SIZE 0x06U
+
+#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
+#define VS_FORMAT_DESC_SIZE VS_FORMAT_UNCOMPRESSED_DESC_SIZE
+#define VS_FORMAT_SUBTYPE VS_FORMAT_UNCOMPRESSED
+#define VS_FRAME_SUBTYPE VS_FRAME_UNCOMPRESSED
+
+#define VC_HEADER_SIZE (VIDEO_VS_IF_IN_HEADER_DESC_SIZE + \
+ VS_FORMAT_UNCOMPRESSED_DESC_SIZE + \
+ VS_FRAME_DESC_SIZE + \
+ VS_COLOR_MATCHING_DESC_SIZE)
+#else
+#define VS_FORMAT_DESC_SIZE VS_FORMAT_MJPEG_DESC_SIZE
+#define VS_FORMAT_SUBTYPE VS_FORMAT_MJPEG
+#define VS_FRAME_SUBTYPE VS_FRAME_MJPEG
+
+#define VC_HEADER_SIZE (VIDEO_VS_IF_IN_HEADER_DESC_SIZE + \
+ VS_FORMAT_DESC_SIZE + \
+ VS_FRAME_DESC_SIZE)
+#endif
+
+/*
+ * Video Class specification release 1.1
+ * Appendix A. Video Device Class Codes defines
+ */
+
+/* Video Interface Subclass values */
+#define SC_UNDEFINED 0x00U
+#define SC_VIDEOCONTROL 0x01U
+#define SC_VIDEOSTREAMING 0x02U
+#define SC_VIDEO_INTERFACE_COLLECTION 0x03U
+
+/* Video Class-Specific Descriptor Types */
+#define CS_UNDEFINED 0x20U
+#define CS_DEVICE 0x21U
+#define CS_CONFIGURATION 0x22U
+#define CS_STRING 0x23U
+#define CS_INTERFACE 0x24U
+#define CS_ENDPOINT 0x25U
+
+/* Video Class-Specific VideoControl Interface Descriptor Subtypes */
+#define VC_DESCRIPTOR_UNDEFINED 0x00U
+#define VC_HEADER 0x01U
+#define VC_INPUT_TERMINAL 0x02U
+#define VC_OUTPUT_TERMINAL 0x03U
+#define VC_SELECTOR_UNIT 0x04U
+#define VC_PROCESSING_UNIT 0x05U
+#define VC_EXTENSION_UNIT 0x06U
+
+/* Video Class-Specific VideoStreaming Interface Descriptor Subtypes */
+#define VS_UNDEFINED 0x00U
+#define VS_INPUT_HEADER 0x01U
+#define VS_OUTPUT_HEADER 0x02U
+#define VS_STILL_IMAGE_FRAME 0x03U
+#define VS_FORMAT_UNCOMPRESSED 0x04U
+#define VS_FRAME_UNCOMPRESSED 0x05U
+#define VS_FORMAT_MJPEG 0x06U
+#define VS_FRAME_MJPEG 0x07U
+#define VS_FORMAT_MPEG2TS 0x0AU
+#define VS_FORMAT_DV 0x0CU
+#define VS_COLORFORMAT 0x0DU
+#define VS_FORMAT_FRAME_BASED 0x10U
+#define VS_FRAME_FRAME_BASED 0x11U
+#define VS_FORMAT_STREAM_BASED 0x12U
+
+/* Video Class-Specific Request values */
+#define UVC_RQ_UNDEFINED 0x00U
+#define UVC_SET_CUR 0x01U
+#define UVC_GET_CUR 0x81U
+#define UVC_GET_MIN 0x82U
+#define UVC_GET_MAX 0x83U
+#define UVC_GET_RES 0x84U
+#define UVC_GET_LEN 0x85U
+#define UVC_GET_INFO 0x86U
+#define UVC_GET_DEF 0x87U
+
+/* VideoControl Interface Control Selectors */
+#define VC_CONTROL_UNDEFINED 0x00U
+#define VC_VIDEO_POWER_MODE_CONTROL 0x01U
+#define VC_REQUEST_ERROR_CODE_CONTROL 0x02U
+
+/* Request Error Code Control */
+#define UVC_NO_ERROR_ERR 0x00U
+#define UVC_NOT_READY_ERR 0x01U
+#define UVC_WRONG_STATE_ERR 0x02U
+#define UVC_POWER_ERR 0x03U
+#define UVC_OUT_OF_RANGE_ERR 0x04U
+#define UVC_INVALID_UNIT_ERR 0x05U
+#define UVC_INVALID_CONTROL_ERR 0x06U
+#define UVC_INVALID_REQUEST_ERR 0x07U
+#define UVC_UNKNOWN_ERR 0xFFU
+
+/*Terminal Control Selectors*/
+#define TE_CONTROL_UNDEFINED 0x00U
+
+/* Selector Unit Control Selectors */
+#define SU_CONTROL_UNDEFINED 0x00U
+#define SU_INPUT_SELECT_CONTROL 0x01U
+
+/* Camera Terminal Control Selectors */
+#define CT_CONTROL_UNDEFINED 0x00U
+#define CT_SCANNING_MODE_CONTROL 0x01U
+#define CT_AE_MODE_CONTROL 0x02U
+#define CT_AE_PRIORITY_CONTROL 0x03U
+#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04U
+#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05U
+#define CT_FOCUS_ABSOLUTE_CONTROL 0x06U
+#define CT_FOCUS_RELATIVE_CONTROL 0x07U
+#define CT_FOCUS_AUTO_CONTROL 0x08U
+#define CT_IRIS_ABSOLUTE_CONTROL 0x09U
+#define CT_IRIS_RELATIVE_CONTROL 0x0AU
+#define CT_ZOOM_ABSOLUTE_CONTROL 0x0BU
+#define CT_ZOOM_RELATIVE_CONTROL 0x0CU
+#define CT_PANTILT_ABSOLUTE_CONTROL 0x0DU
+#define CT_PANTILT_RELATIVE_CONTROL 0x0EU
+#define CT_ROLL_ABSOLUTE_CONTROL 0x0FU
+#define CT_ROLL_RELATIVE_CONTROL 0x10U
+#define CT_PRIVACY_CONTROL 0x11U
+
+/* Processing Unit Control Selectors */
+#define PU_CONTROL_UNDEFINED 0x00U
+#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01U
+#define PU_BRIGHTNESS_CONTROL 0x02U
+#define PU_CONTRAST_CONTROL 0x03U
+#define PU_GAIN_CONTROL 0x04U
+#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05U
+#define PU_HUE_CONTROL 0x06U
+#define PU_SATURATION_CONTROL 0x07U
+#define PU_SHARPNESS_CONTROL 0x08U
+#define PU_GAMMA_CONTROL 0x09U
+#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0AU
+#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0BU
+#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0CU
+#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0DU
+#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0EU
+#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0FU
+#define PU_HUE_AUTO_CONTROL 0x10U
+#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11U
+#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12U
+
+/*Extension Unit Control Selectors */
+#define XU_CONTROL_UNDEFINED 0x00U
+
+/* VideoStreaming Interface Control Selectors */
+#define VS_CONTROL_UNDEFINED 0x00U
+#define VS_PROBE_CONTROL 0x100U
+#define VS_COMMIT_CONTROL 0x200U
+#define VS_STILL_PROBE_CONTROL 0x03U
+#define VS_STILL_COMMIT_CONTROL 0x04U
+#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05U
+#define VS_STREAM_ERROR_CODE_CONTROL 0x06U
+#define VS_GENERATE_KEY_FRAME_CONTROL 0x07U
+#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08U
+#define VS_SYNC_DELAY_CONTROL 0x09U
+
+
+/* Control Capabilities */
+#define UVC_SUPPORTS_GET 0x01U
+#define UVC_SUPPORTS_SET 0x02U
+#define UVC_STATE_DISABLED 0x04U
+#define UVC_AUTOUPDATE_CONTROL 0x08U
+#define UVC_ASYNCHRONOUS_CONTROL 0x10U
+
+/* USB Terminal Types */
+#define TT_VENDOR_SPECIFIC 0x0100U
+#define TT_STREAMING 0x0101U
+
+/* Input Terminal Types */
+#define ITT_VENDOR_SPECIFIC 0x0200U
+#define ITT_CAMERA 0x0201U
+#define ITT_MEDIA_TRANSPORT_INPUT 0x0202U
+
+/*Output Terminal Types */
+#define OTT_VENDOR_SPECIFIC 0x0300U
+#define OTT_DISPLAY 0x0301U
+#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302U
+
+/* External Terminal Types */
+#define EXTERNAL_VENDOR_SPECIFIC 0x0400U
+#define COMPOSITE_CONNECTOR 0x0401U
+#define SVIDEO_CONNECTOR 0x0402U
+#define COMPONENT_CONNECTOR 0x0403U
+
+ /* VIDEO Commands enumeration */
+ typedef enum
+ {
+ VIDEO_CMD_START = 1U,
+ VIDEO_CMD_PLAY,
+ VIDEO_CMD_STOP,
+ } VIDEO_CMD_TypeDef;
+
+ typedef enum
+ {
+ VIDEO_OFFSET_NONE = 0U,
+ VIDEO_OFFSET_HALF,
+ VIDEO_OFFSET_FULL,
+ VIDEO_OFFSET_UNKNOWN,
+ } VIDEO_OffsetTypeDef;
+
+ typedef struct _VIDEO_DescHeader
+ {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bDescriptorSubType;
+ } USBD_VIDEO_DescHeader_t;
+
+ typedef struct
+ {
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bDescriptorSubType;
+ uint8_t bFrameIndex;
+ uint8_t bmCapabilities;
+ uint16_t wWidth;
+ uint16_t wHeight;
+ uint32_t dwMinBitRate;
+ uint32_t dwMaxBitRate;
+ uint32_t dwMaxVideoFrameBufSize;
+ uint32_t dwDefaultFrameInterval;
+ uint8_t bFrameIntervalType;
+ uint32_t dwMinFrameInterval;
+ uint32_t dwMaxFrameInterval;
+ uint32_t dwFrameIntervalStep;
+ } __PACKED USBD_VIDEO_VSFrameDescTypeDef;
+
+ typedef struct
+ {
+ uint8_t cmd;
+ uint8_t data[USB_MAX_EP0_SIZE];
+ uint8_t len;
+ uint8_t unit;
+ } USBD_VIDEO_ControlTypeDef;
+
+ typedef struct
+ {
+ uint32_t interface;
+ uint32_t uvc_state;
+ uint8_t buffer[UVC_TOTAL_BUF_SIZE];
+ VIDEO_OffsetTypeDef offset;
+ USBD_VIDEO_ControlTypeDef control;
+ } USBD_VIDEO_HandleTypeDef;
+
+ typedef struct
+ {
+ int8_t (*Init)(void);
+ int8_t (*DeInit)(void);
+ int8_t (*Control)(uint8_t, uint8_t *, uint16_t);
+ int8_t (*Data)(uint8_t **, uint16_t *, uint16_t *);
+ uint8_t *pStrDesc;
+ } USBD_VIDEO_ItfTypeDef;
+
+ /* UVC uses only 26 first bytes */
+ typedef struct
+ {
+ uint16_t bmHint;
+ uint8_t bFormatIndex;
+ uint8_t bFrameIndex;
+ uint32_t dwFrameInterval;
+ uint16_t wKeyFrameRate;
+ uint16_t wPFrameRate;
+ uint16_t wCompQuality;
+ uint16_t wCompWindowSize;
+ uint16_t wDelay;
+ uint32_t dwMaxVideoFrameSize;
+ uint32_t dwMaxPayloadTransferSize;
+ uint32_t dwClockFrequency;
+ uint8_t bmFramingInfo;
+ uint8_t bPreferedVersion;
+ uint8_t bMinVersion;
+ uint8_t bMaxVersion;
+ } __PACKED USBD_VideoControlTypeDef;
+
+ extern USBD_ClassTypeDef USBD_VIDEO;
+
+ extern uint8_t UVC_IN_EP;
+ extern uint8_t UVC_VC_IF_NUM;
+ extern uint8_t UVC_VS_IF_NUM;
+ extern uint8_t UVC_STR_DESC_IDX;
+
+ /**
+ * @}
+ */
+
+ /** @defgroup USB_CORE_Exported_Functions
+ * @{
+ */
+
+ uint8_t USBD_VIDEO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_VIDEO_ItfTypeDef *fops);
+
+ void USBD_Update_UVC_DESC(uint8_t *desc, uint8_t vc_itf, uint8_t vs_itf, uint8_t in_ep, uint8_t str_idx);
+
+ /**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _USBD_VIDEO_H_ */
diff --git a/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/VIDEO/Src/usbd_video.c b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/VIDEO/Src/usbd_video.c
new file mode 100644
index 0000000..facd5af
--- /dev/null
+++ b/USBD_Test/Middlewares/Third_Party/AL94_USB_Composite/COMPOSITE/Class/VIDEO/Src/usbd_video.c
@@ -0,0 +1,1081 @@
+/**
+ ******************************************************************************
+ * @file usbd_video.c
+ * @author MCD Application Team
+ * @brief This file provides the Video core functions.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * VIDEO Class Description
+ * ===================================================================
+ * This driver manages the Video Class 1.1 following the "USB Device Class Definition for
+ * Video Devices V1.0 Mar 18, 98".
+ * This driver implements the following aspects of the specification:
+ * - Device descriptor management
+ * - Configuration descriptor management
+ * - Interface Association Descriptor
+ * -Standard VC Interface Descriptor = interface 0
+ * -Standard Vs Interface Descriptor = interface 1
+ * - 1 Video Streaming Interface
+ * - 1 Video Streaming Endpoint
+ * - 1 Video Terminal Input (camera)
+ * - Video Class-Specific AC Interfaces
+ * - Video Class-Specific AS Interfaces
+ * - VideoControl Requests
+ * - Video Synchronization type: Asynchronous
+ * The current Video class version supports the following Video features:
+ * - image JPEG format
+ * - Asynchronous Endpoints
+ *
+ * @note In HS mode and when the USB DMA is used, all variables and data structures
+ * dealing with the DMA during the transaction process should be 32-bit aligned.
+ *
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_video.h"
+#include "usbd_ctlreq.h"
+#include "usbd_core.h"
+
+#define _UVC_IN_EP 0x81U
+#define _UVC_VC_IF_NUM 0x00U
+#define _UVC_VS_IF_NUM 0x01U
+#define _UVC_STR_DESC_IDX 0x00U
+
+uint8_t UVC_IN_EP = _UVC_IN_EP;
+uint8_t UVC_VC_IF_NUM = _UVC_VC_IF_NUM;
+uint8_t UVC_VS_IF_NUM = _UVC_VS_IF_NUM;
+uint8_t UVC_STR_DESC_IDX = _UVC_STR_DESC_IDX;
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+ * @{
+ */
+
+/** @defgroup USBD_VIDEO
+ * @brief USB Device Video Class core module
+ * @{
+ */
+
+/** @defgroup USBD_VIDEO_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_Private_Defines
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_Private_Macros
+ * @{
+ */
+
+/* VIDEO Device library callbacks */
+static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static uint8_t *USBD_VIDEO_GetFSCfgDesc(uint16_t *length);
+static uint8_t *USBD_VIDEO_GetHSCfgDesc(uint16_t *length);
+static uint8_t *USBD_VIDEO_GetOtherSpeedCfgDesc(uint16_t *length);
+static uint8_t *USBD_VIDEO_GetDeviceQualifierDesc(uint16_t *length);
+static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev);
+static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+/* VIDEO Requests management functions */
+static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+
+static USBD_VIDEO_DescHeader_t *USBD_VIDEO_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
+static void *USBD_VIDEO_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr);
+static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc);
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_Private_Variables
+ * @{
+ */
+static USBD_VIDEO_HandleTypeDef USBD_VIDEO_Instance;
+
+USBD_ClassTypeDef USBD_VIDEO =
+ {
+ USBD_VIDEO_Init,
+ USBD_VIDEO_DeInit,
+ USBD_VIDEO_Setup,
+ NULL,
+ NULL,
+ USBD_VIDEO_DataIn,
+ NULL,
+ USBD_VIDEO_SOF,
+ USBD_VIDEO_IsoINIncomplete,
+ NULL,
+ USBD_VIDEO_GetHSCfgDesc,
+ USBD_VIDEO_GetFSCfgDesc,
+ USBD_VIDEO_GetOtherSpeedCfgDesc,
+ USBD_VIDEO_GetDeviceQualifierDesc,
+};
+
+/* USB VIDEO device Configuration Descriptor (same for all speeds thanks to user defines) */
+__ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[UVC_CONFIG_DESC_SIZE] __ALIGN_END =
+ {
+ /* Configuration 1 */
+ USB_CONF_DESC_SIZE, /* bLength: Configuration Descriptor size */
+ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+ LOBYTE(UVC_CONFIG_DESC_SIZE), /* wTotalLength: no of returned bytes */
+ HIBYTE(UVC_CONFIG_DESC_SIZE),
+ 0x02, /* bNumInterfaces: 2 interfaces */
+ 0x01, /* bConfigurationValue: Configuration value */
+ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
+#if (USBD_SELF_POWERED == 1U)
+ 0xC0, /* bmAttributes: Bus Powered according to user configuration */
+#else
+ 0x80, /* bmAttributes: Bus Powered according to user configuration */
+#endif
+ USBD_MAX_POWER, /* bMaxPower in mA according to user configuration */
+
+ /* Interface Association Descriptor */
+ USB_IAD_DESC_SIZE, /* bLength: Interface Association Descriptor size */
+ USB_DESC_TYPE_IAD, /* bDescriptorType: interface association */
+ _UVC_VC_IF_NUM, /* bFirstInterface */
+ 0x02, /* bInterfaceCount */
+ UVC_CC_VIDEO, /* bFunctionClass: Video class */
+ SC_VIDEO_INTERFACE_COLLECTION, /* bFunctionSubClass: Video Interface Collection */
+ PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol: protocol undefined */
+ _UVC_STR_DESC_IDX, /* iFunction */
+
+ /* Standard VC (Video Control) Interface Descriptor = interface 0 */
+ USB_IF_DESC_SIZE, /* bLength: interface descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: interface */
+ _UVC_VC_IF_NUM, /* bInterfaceNumber: interface number */
+ 0x00, /* bAlternateSetting: index of this alternate setting */
+ 0x00, /* bNumEndpoints: No endpoints used for this interface */
+ UVC_CC_VIDEO, /* bInterfaceClass: Video Class */
+ SC_VIDEOCONTROL, /* bInterfaceSubClass: Video Control */
+ PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol: protocol is undefined */
+ 0x00, /* iFunction: index of string descriptor relative to this item */
+
+ /* Class-specific VC Interface Descriptor */
+ VIDEO_VC_IF_HEADER_DESC_SIZE, /* bLength */
+ CS_INTERFACE, /* bDescriptorType */
+ VC_HEADER, /* bDescriptorSubtype */
+ LOBYTE(UVC_VERSION),
+ HIBYTE(UVC_VERSION), /* bcdUVC: UVC1.0 or UVC1.1 revision */
+ VS_FRAME_DESC_SIZE, /* wTotalLength: total size of class-specific descriptors */
+ 0x00,
+ 0x00, /* dwClockFrequency: not used. 48 Mhz value is set, but not used */
+ 0x6C,
+ 0xDC,
+ 0x02,
+ 0x01, /* bInCollection: number of streaming interfaces */
+ _UVC_VS_IF_NUM, /* baInterfaceNr(1): VideoStreaming interface 1 is part of VC interface */
+
+ /* Input Terminal Descriptor */
+ VIDEO_IN_TERMINAL_DESC_SIZE, /* bLength: Input terminal descriptor size */
+ CS_INTERFACE, /* bDescriptorType: INTERFACE */
+ VC_INPUT_TERMINAL, /* bDescriptorSubtype: INPUT_TERMINAL */
+ 0x01, /* bTerminalID: ID of this Terminal */
+ LOBYTE(ITT_VENDOR_SPECIFIC), /* wTerminalType: 0x0200 ITT_VENDOR_SPECIFIC */
+ HIBYTE(ITT_VENDOR_SPECIFIC),
+ 0x00, /* bAssocTerminal: no Terminal is associated */
+ 0x00, /* iTerminal: index of string descriptor relative to this item */
+
+ /* Output Terminal Descriptor */
+ VIDEO_OUT_TERMINAL_DESC_SIZE, /* bLength: output terminal descriptor size */
+ CS_INTERFACE, /* bDescriptorType */
+ VC_OUTPUT_TERMINAL, /* bDescriptorSubtype */
+ 0x02, /* bTerminalID */
+ LOBYTE(TT_STREAMING), /* wTerminalType: USB streaming terminal */
+ HIBYTE(TT_STREAMING),
+ 0x00, /* bAssocTerminal: no Terminal is associated */
+ 0x01, /* bSourceID: input is connected to output unit ID 1 */
+ 0x00, /* iTerminal: index of string descriptor relative to this item */
+
+ /* Standard VS (Video Streaming) Interface Descriptor = interface 1, alternate setting 0 = Zero Bandwidth
+ (when no data are sent from the device) */
+ USB_IF_DESC_SIZE, /* bLength: interface descriptor size */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
+ _UVC_VS_IF_NUM, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x00, /* bNumEndpoints: no endpoints used for alternate setting 0 */
+ UVC_CC_VIDEO, /* bInterfaceClass */
+ SC_VIDEOSTREAMING, /* bInterfaceSubClass */
+ PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ 0x00, /* iInterface: index of string descriptor relative to this item */
+
+ /* Class-specific VS Header Descriptor (Input) */
+ VIDEO_VS_IF_IN_HEADER_DESC_SIZE, /* bLength */
+ CS_INTERFACE, /* bDescriptorType */
+ VS_INPUT_HEADER, /* bDescriptorSubtype */
+ 0x01, /* bNumFormats: 1 format descriptor is used */
+ VC_HEADER_SIZE,
+ 0x00, /* Total size of Video Control Specific Descriptors */
+ _UVC_IN_EP, /* bEndPointAddress: In endpoint is used for the alternate setting */
+ 0x00, /* bmInfo: dynamic format change not supported */
+ 0x02, /* bTerminalLink: output to terminal ID 2 */
+ 0x00, /* bStillCaptureMethod: not supported */
+ 0x00, /* bTriggerSupport: not supported */
+ 0x00, /* bTriggerUsage: not supported */
+ 0x01, /* bControlSize: 1 byte field size */
+ 0x00, /* bmaControls: No specific controls used */
+
+ /* Payload Format Descriptor */
+ VS_FORMAT_DESC_SIZE, /* blength */
+ CS_INTERFACE, /* bDescriptorType */
+ VS_FORMAT_SUBTYPE, /* bDescriptorSubType */
+ 0x01, /* bFormatIndex */
+ 0x01, /* bNumFrameDescriptor */
+#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
+ DBVAL(UVC_UNCOMPRESSED_GUID), /* Giud Format: YUY2 {32595559-0000-0010-8000-00AA00389B71} */
+ 0x00, 0x00,
+ 0x10, 0x00,
+ 0x80, 0x00,
+ 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71,
+ UVC_BITS_PER_PIXEL, /* bBitsPerPixel : Number of bits per pixel */
+#else
+ 0x01, /* bmFlags: FixedSizeSamples */
+#endif
+ 0x01, /* bDefaultFrameIndex: default frame used is frame 1 (only one frame used) */
+ 0x00, /* bAspectRatioX: not required by specification */
+ 0x00, /* bAspectRatioY: not required by specification */
+ 0x00, /* bInterlaceFlags: non interlaced stream */
+ 0x00, /* bCopyProtect: no protection restrictions */
+
+ /* Class-specific VS (Video Streaming) Frame Descriptor */
+ VS_FRAME_DESC_SIZE, /* bLength */
+ CS_INTERFACE, /* bDescriptorType */
+ VS_FRAME_SUBTYPE, /* bDescriptorSubType */
+ 0x01, /* bFrameIndex */
+#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
+ 0x00, /* bmCapabilities: no till image capture */
+#else
+ 0x02, /* bmCapabilities: fixed frame rate supported */
+#endif
+ WBVAL(UVC_WIDTH), /* wWidth: Image Frame Width */
+ WBVAL(UVC_HEIGHT), /* wHeight: Image Frame Height */
+ DBVAL(UVC_MIN_BIT_RATE(UVC_CAM_FPS_FS)), /* dwMinBitRate: Minimum supported bit rate in bits/s */
+ DBVAL(UVC_MAX_BIT_RATE(UVC_CAM_FPS_FS)), /* dwMaxBitRate: Maximum supported bit rate in bits/s */
+ DBVAL(UVC_MAX_FRAME_SIZE), /* dwMaxVideoFrameBufSize: Maximum video frame size, in bytes */
+ DBVAL(UVC_INTERVAL(UVC_CAM_FPS_FS)), /* dwDefaultFrameInterval: following number of FPS */
+ 0x01, /* bFrameIntervalType: Discrete frame interval type */
+ DBVAL(UVC_INTERVAL(UVC_CAM_FPS_FS)), /* dwMinFrameInterval: One supported value of interval (FPS) */
+
+#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
+ /* Color Matching Descriptor */
+ VS_COLOR_MATCHING_DESC_SIZE, /* bLength */
+ CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
+ VS_COLORFORMAT, /* bDescriptorSubType: VS_COLORFORMAT */
+ UVC_COLOR_PRIMARIE, /* bColorPrimarie: 1: BT.709, sRGB (default) */
+ UVC_TFR_CHARACTERISTICS, /* bTransferCharacteristics: 1: BT.709 (default) */
+ UVC_MATRIX_COEFFICIENTS, /* bMatrixCoefficients: 4: BT.601, (default) */
+#endif
+
+ /* Standard VS Interface Descriptor = interface 1, alternate setting 1 = data transfer mode */
+ USB_IF_DESC_SIZE, /* bLength */
+ USB_DESC_TYPE_INTERFACE, /* bDescriptorType */
+ _UVC_VS_IF_NUM, /* bInterfaceNumber */
+ 0x01, /* bAlternateSetting */
+ 0x01, /* bNumEndpoints: one endpoint is used */
+ UVC_CC_VIDEO, /* bInterfaceClass */
+ SC_VIDEOSTREAMING, /* bInterfaceSubClass */
+ PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */
+ 0x00, /* iInterface: index of string descriptor relative to this item */
+
+ /* Standard VS (Video Streaming) data Endpoint */
+ USB_EP_DESC_SIZE, /* bLength */
+ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */
+ _UVC_IN_EP, /* bEndpointAddress */
+ 0x05, /* bmAttributes: ISO transfer */
+ LOBYTE(UVC_ISO_FS_MPS), /* wMaxPacketSize */
+ HIBYTE(UVC_ISO_FS_MPS),
+ 0x01, /* bInterval: 1 frame interval */
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN static uint8_t USBD_VIDEO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+ {
+ USB_LEN_DEV_QUALIFIER_DESC,
+ USB_DESC_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0xEF,
+ 0x02,
+ 0x01,
+ 0x40,
+ 0x01,
+ 0x00,
+};
+
+/* Video Commit data structure */
+static USBD_VideoControlTypeDef video_Commit_Control =
+ {
+ .bmHint = 0x0000U,
+ .bFormatIndex = 0x01U,
+ .bFrameIndex = 0x01U,
+ .dwFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS),
+ .wKeyFrameRate = 0x0000U,
+ .wPFrameRate = 0x0000U,
+ .wCompQuality = 0x0000U,
+ .wCompWindowSize = 0x0000U,
+ .wDelay = 0x0000U,
+ .dwMaxVideoFrameSize = 0x0000U,
+ .dwMaxPayloadTransferSize = 0x00000000U,
+ .dwClockFrequency = 0x00000000U,
+ .bmFramingInfo = 0x00U,
+ .bPreferedVersion = 0x00U,
+ .bMinVersion = 0x00U,
+ .bMaxVersion = 0x00U,
+};
+
+/* Video Probe data structure */
+static USBD_VideoControlTypeDef video_Probe_Control =
+ {
+ .bmHint = 0x0000U,
+ .bFormatIndex = 0x01U,
+ .bFrameIndex = 0x01U,
+ .dwFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS),
+ .wKeyFrameRate = 0x0000U,
+ .wPFrameRate = 0x0000U,
+ .wCompQuality = 0x0000U,
+ .wCompWindowSize = 0x0000U,
+ .wDelay = 0x0000U,
+ .dwMaxVideoFrameSize = 0x0000U,
+ .dwMaxPayloadTransferSize = 0x00000000U,
+ .dwClockFrequency = 0x00000000U,
+ .bmFramingInfo = 0x00U,
+ .bPreferedVersion = 0x00U,
+ .bMinVersion = 0x00U,
+ .bMaxVersion = 0x00U,
+};
+
+/**
+ * @}
+ */
+
+/** @defgroup USBD_VIDEO_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief USBD_VIDEO_Init
+ * Initialize the VIDEO interface
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ USBD_VIDEO_HandleTypeDef *hVIDEO;
+
+ /* Allocate memory for the video control structure */
+ hVIDEO = &USBD_VIDEO_Instance;
+
+ /* Check if allocated point is NULL, then exit with error code */
+ if (hVIDEO == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Assign the pClassData_UVC pointer to the allocated structure */
+ pdev->pClassData_UVC = (void *)hVIDEO;
+
+ /* Open EP IN */
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ (void)USBD_LL_OpenEP(pdev, UVC_IN_EP, USBD_EP_TYPE_ISOC, UVC_ISO_HS_MPS);
+
+ pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 1U;
+ pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket = UVC_ISO_HS_MPS;
+ }
+ else
+ {
+ (void)USBD_LL_OpenEP(pdev, UVC_IN_EP, USBD_EP_TYPE_ISOC, UVC_ISO_FS_MPS);
+
+ pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 1U;
+ pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket = UVC_ISO_FS_MPS;
+ }
+
+ /* Init physical Interface components */
+ ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData_UVC)->Init();
+
+ /* Init Xfer states */
+ hVIDEO->interface = 0U;
+
+ /* Some calls to unused variables, to comply with MISRA-C 2012 rules */
+ UNUSED(USBD_VIDEO_CfgDesc);
+ UNUSED(cfgidx);
+
+ /* Exit with no error code */
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_VIDEO_DeInit
+ * DeInitialize the VIDEO layer
+ * @param pdev: device instance
+ * @param cfgidx: Configuration index
+ * @retval status
+ */
+static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+ UNUSED(cfgidx);
+
+ /* Check if the video structure pointer is valid */
+ if (pdev->pClassData_UVC == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Close EP IN */
+ (void)USBD_LL_CloseEP(pdev, UVC_IN_EP);
+ pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 0U;
+
+ /* DeInit physical Interface components */
+ ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData_UVC)->DeInit();
+#if (0)
+ USBD_free(pdev->pClassData_UVC);
+#endif
+ pdev->pClassData_UVC = NULL;
+
+ /* Exit with no error code */
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_VIDEO_Setup
+ * Handle the VIDEO specific requests
+ * @param pdev: instance
+ * @param req: usb requests
+ * @retval status
+ */
+static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *)pdev->pClassData_UVC;
+ uint8_t ret = (uint8_t)USBD_OK;
+ uint16_t len = 0U;
+ uint8_t *pbuf = NULL;
+ uint16_t status_info = 0U;
+
+ switch (req->bmRequest & USB_REQ_TYPE_MASK)
+ {
+ /* Class Requests -------------------------------*/
+ case USB_REQ_TYPE_CLASS:
+ switch (req->bRequest)
+ {
+ case UVC_GET_CUR:
+ case UVC_GET_DEF:
+ case UVC_GET_MIN:
+ case UVC_GET_MAX:
+ VIDEO_REQ_GetCurrent(pdev, req);
+ break;
+ case UVC_GET_RES:
+ case UVC_GET_LEN:
+ case UVC_GET_INFO:
+ break;
+ case UVC_SET_CUR:
+ VIDEO_REQ_SetCurrent(pdev, req);
+ break;
+ default:
+ (void)USBD_CtlError(pdev, req);
+ ret = (uint8_t)USBD_FAIL;
+ break;
+ }
+ break;
+
+ /* Standard Requests -------------------------------*/
+ case USB_REQ_TYPE_STANDARD:
+ switch (req->bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = (uint8_t)USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_GET_DESCRIPTOR:
+ if ((req->wValue >> 8) == CS_DEVICE)
+ {
+ pbuf = USBD_VIDEO_CfgDesc + 18;
+ len = MIN((uint16_t)USB_CONF_DESC_SIZE, (uint16_t)req->wLength);
+ }
+ (void)USBD_CtlSendData(pdev, pbuf, len);
+ break;
+
+ case USB_REQ_GET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&hVIDEO->interface, 1U);
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = (uint8_t)USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_SET_INTERFACE:
+ if (pdev->dev_state == USBD_STATE_CONFIGURED)
+ {
+ if (req->wValue <= USBD_MAX_NUM_INTERFACES)
+ {
+ hVIDEO->interface = LOBYTE(req->wValue);
+ if (hVIDEO->interface == 1U)
+ {
+ /* Start Streaming (First endpoint writing will be done on next SOF) */
+ (void)USBD_LL_FlushEP(pdev, UVC_IN_EP);
+ hVIDEO->uvc_state = UVC_PLAY_STATUS_READY;
+ }
+ else
+ {
+ /* Stop Streaming */
+ hVIDEO->uvc_state = UVC_PLAY_STATUS_STOP;
+ (void)USBD_LL_FlushEP(pdev, UVC_IN_EP);
+ }
+ }
+ else
+ {
+ /* Call the error management function (command will be NAKed) */
+ USBD_CtlError(pdev, req);
+ ret = (uint8_t)USBD_FAIL;
+ }
+ }
+ else
+ {
+ USBD_CtlError(pdev, req);
+ ret = (uint8_t)USBD_FAIL;
+ }
+ break;
+
+ case USB_REQ_CLEAR_FEATURE:
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = (uint8_t)USBD_FAIL;
+ break;
+ }
+ break;
+
+ default:
+ USBD_CtlError(pdev, req);
+ ret = (uint8_t)USBD_FAIL;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * @brief USBD_VIDEO_DataIn
+ * handle data IN Stage
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *)pdev->pClassData_UVC;
+ static uint8_t packet[UVC_PACKET_SIZE + (UVC_HEADER_PACKET_CNT * 2U)] = {0x00U};
+ static uint8_t *Pcktdata = packet;
+ static uint16_t PcktIdx = 0U;
+ static uint16_t PcktSze = UVC_PACKET_SIZE;
+ static uint8_t payload_header[2] = {0x02U, 0x00U};
+ uint8_t i = 0U;
+ uint32_t RemainData, DataOffset = 0U;
+
+ /* Check if the Streaming has already been started */
+ if (hVIDEO->uvc_state == UVC_PLAY_STATUS_STREAMING)
+ {
+ /* Get the current packet buffer, index and size from the application layer */
+ ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData_UVC)->Data(&Pcktdata, &PcktSze, &PcktIdx);
+
+ /* Check if end of current image has been reached */
+ if (PcktSze > 2U)
+ {
+ /* Check if this is the first packet in current image */
+ if (PcktIdx == 0U)
+ {
+ /* Set the packet start index */
+ payload_header[1] ^= 0x01U;
+ }
+
+ RemainData = PcktSze;
+
+ /* fill the Transmit buffer */
+ while (RemainData > 0U)
+ {
+ packet[((DataOffset + 0U) * i)] = payload_header[0];
+ packet[((DataOffset + 0U) * i) + 1U] = payload_header[1];
+ if (RemainData > pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket)
+ {
+ DataOffset = pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket;
+ (void)USBD_memcpy((packet + ((DataOffset + 0U) * i) + 2U),
+ Pcktdata + ((DataOffset - 2U) * i), (DataOffset - 2U));
+
+ RemainData -= DataOffset;
+ i++;
+ }
+ else
+ {
+ (void)USBD_memcpy((packet + ((DataOffset + 0U) * i) + 2U),
+ Pcktdata + ((DataOffset - 2U) * i), (RemainData - 2U));
+
+ RemainData = 0U;
+ }
+ }
+ }
+ else
+ {
+ /* Add the packet header */
+ packet[0] = payload_header[0];
+ packet[1] = payload_header[1];
+ }
+
+ /* Transmit the packet on Endpoint */
+ (void)USBD_LL_Transmit(pdev, (uint8_t)(epnum | 0x80U),
+ (uint8_t *)&packet, (uint32_t)PcktSze);
+ }
+
+ /* Exit with no error code */
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_VIDEO_SOF
+ * handle SOF event
+ * @param pdev: device instance
+ * @retval status
+ */
+static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev)
+{
+ USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *)pdev->pClassData_UVC;
+ uint8_t payload[2] = {0x02U, 0x00U};
+
+ /* Check if the Streaming has already been started by SetInterface AltSetting 1 */
+ if (hVIDEO->uvc_state == UVC_PLAY_STATUS_READY)
+ {
+ /* Transmit the first packet indicating that Streaming is starting */
+ (void)USBD_LL_Transmit(pdev, UVC_IN_EP, (uint8_t *)payload, 2U);
+
+ /* Enable Streaming state */
+ hVIDEO->uvc_state = UVC_PLAY_STATUS_STREAMING;
+ }
+
+ /* Exit with no error code */
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief USBD_VIDEO_IsoINIncomplete
+ * handle data ISO IN Incomplete event
+ * @param pdev: device instance
+ * @param epnum: endpoint index
+ * @retval status
+ */
+static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+ UNUSED(pdev);
+ UNUSED(epnum);
+
+ return (uint8_t)USBD_OK;
+}
+
+/**
+ * @brief VIDEO_Req_GetCurrent
+ * Handles the GET_CUR VIDEO control request.
+ * @param pdev: instance
+ * @param req: setup class request
+ * @retval status
+ */
+static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_VIDEO_HandleTypeDef *hVIDEO;
+ hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassData_UVC);
+ static __IO uint8_t EntityStatus[8] = {0};
+
+ /* Reset buffer to zeros */
+ (void)USBD_memset(hVIDEO->control.data, 0, USB_MAX_EP0_SIZE);
+
+ /* Manage Video Control interface requests */
+ if (LOBYTE(req->wIndex) == UVC_VC_IF_NUM)
+ {
+ if (HIBYTE(req->wValue) == 0x02U)
+ {
+ /* Get the status of the current requested Entity */
+ EntityStatus[0] = 0x06U;
+
+ /* Send current status */
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&EntityStatus, 1U);
+ }
+ else
+ {
+ /* Unknown request */
+ USBD_CtlError(pdev, req);
+ }
+ }
+ /* Manage Video Streaming interface requests */
+ else
+ {
+ if (LOBYTE(req->wValue) == (uint8_t)VS_PROBE_CONTROL)
+ {
+ /* Update bPreferedVersion, bMinVersion and bMaxVersion which must be set only by Device */
+ video_Probe_Control.bPreferedVersion = 0x00U;
+ video_Probe_Control.bMinVersion = 0x00U;
+ video_Probe_Control.bMaxVersion = 0x00U;
+ video_Probe_Control.dwMaxVideoFrameSize = UVC_MAX_FRAME_SIZE;
+
+ video_Probe_Control.dwClockFrequency = 0x02DC6C00U;
+
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ video_Probe_Control.dwFrameInterval = (UVC_INTERVAL(UVC_CAM_FPS_HS));
+ video_Probe_Control.dwMaxPayloadTransferSize = UVC_ISO_HS_MPS;
+ }
+ else
+ {
+ video_Probe_Control.dwFrameInterval = (UVC_INTERVAL(UVC_CAM_FPS_FS));
+ video_Probe_Control.dwMaxPayloadTransferSize = UVC_ISO_FS_MPS;
+ }
+
+ /* Probe Request */
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&video_Probe_Control,
+ MIN(req->wLength, sizeof(USBD_VideoControlTypeDef)));
+ }
+ else if (LOBYTE(req->wValue) == (uint8_t)VS_COMMIT_CONTROL)
+ {
+ if (pdev->dev_speed == USBD_SPEED_HIGH)
+ {
+ video_Commit_Control.dwFrameInterval = (UVC_INTERVAL(UVC_CAM_FPS_HS));
+ video_Commit_Control.dwMaxPayloadTransferSize = UVC_ISO_HS_MPS;
+ }
+ else
+ {
+ video_Commit_Control.dwFrameInterval = (UVC_INTERVAL(UVC_CAM_FPS_FS));
+ video_Commit_Control.dwMaxPayloadTransferSize = UVC_ISO_FS_MPS;
+ }
+
+ /* Commit Request */
+ (void)USBD_CtlSendData(pdev, (uint8_t *)&video_Commit_Control,
+ MIN(req->wLength, sizeof(USBD_VideoControlTypeDef)));
+ }
+ else
+ {
+ /* Send the current state */
+ (void)USBD_CtlSendData(pdev, hVIDEO->control.data,
+ MIN(req->wLength, USB_MAX_EP0_SIZE));
+ }
+ }
+}
+
+/**
+ * @brief VIDEO_Req_SetCurrent
+ * Handles the SET_CUR VIDEO control request.
+ * @param pdev: instance
+ * @param req: setup class request
+ * @retval status
+ */
+static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+ USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassData_UVC);
+
+ /* Check that the request has control data */
+ if (req->wLength > 0U)
+ {
+ /* Prepare the reception of the buffer over EP0 */
+ if (LOBYTE(req->wValue) == (uint8_t)VS_PROBE_CONTROL)
+ {
+ /* Probe Request */
+ (void)USBD_CtlPrepareRx(pdev, (uint8_t *)&video_Probe_Control,
+ MIN(req->wLength, sizeof(USBD_VideoControlTypeDef)));
+ }
+ else if (LOBYTE(req->wValue) == (uint8_t)VS_COMMIT_CONTROL)
+ {
+ /* Commit Request */
+ (void)USBD_CtlPrepareRx(pdev, (uint8_t *)&video_Commit_Control,
+ MIN(req->wLength, sizeof(USBD_VideoControlTypeDef)));
+ }
+ else
+ {
+ /* Prepare the reception of the buffer over EP0 */
+ (void)USBD_CtlPrepareRx(pdev, hVIDEO->control.data,
+ MIN(req->wLength, USB_MAX_EP0_SIZE));
+ }
+ }
+}
+
+/**
+ * @brief USBD_VIDEO_GetFSCfgDesc
+ * return configuration descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_VIDEO_GetFSCfgDesc(uint16_t *length)
+{
+ USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP);
+ USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc);
+
+ if (pEpDesc != NULL)
+ {
+ pEpDesc->wMaxPacketSize = UVC_ISO_FS_MPS;
+ }
+
+ if (pVSFrameDesc != NULL)
+ {
+ pVSFrameDesc->dwMinBitRate = UVC_MIN_BIT_RATE(UVC_CAM_FPS_FS);
+ pVSFrameDesc->dwMaxBitRate = UVC_MAX_BIT_RATE(UVC_CAM_FPS_FS);
+ pVSFrameDesc->dwDefaultFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS);
+ pVSFrameDesc->dwMinFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS);
+ }
+
+ *length = (uint16_t)(sizeof(USBD_VIDEO_CfgDesc));
+ return USBD_VIDEO_CfgDesc;
+}
+
+/**
+ * @brief USBD_VIDEO_GetHSCfgDesc
+ * return configuration descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_VIDEO_GetHSCfgDesc(uint16_t *length)
+{
+ USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP);
+ USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc);
+
+ if (pEpDesc != NULL)
+ {
+ pEpDesc->wMaxPacketSize = UVC_ISO_HS_MPS;
+ }
+
+ if (pVSFrameDesc != NULL)
+ {
+ pVSFrameDesc->dwMinBitRate = UVC_MIN_BIT_RATE(UVC_CAM_FPS_HS);
+ pVSFrameDesc->dwMaxBitRate = UVC_MAX_BIT_RATE(UVC_CAM_FPS_HS);
+ pVSFrameDesc->dwDefaultFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_HS);
+ pVSFrameDesc->dwMinFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_HS);
+ }
+
+ *length = (uint16_t)(sizeof(USBD_VIDEO_CfgDesc));
+ return USBD_VIDEO_CfgDesc;
+}
+
+/**
+ * @brief USBD_VIDEO_GetOtherSpeedCfgDesc
+ * return configuration descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_VIDEO_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+ USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP);
+ USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc);
+
+ if (pEpDesc != NULL)
+ {
+ pEpDesc->wMaxPacketSize = UVC_ISO_FS_MPS;
+ }
+
+ if (pVSFrameDesc != NULL)
+ {
+ pVSFrameDesc->dwMinBitRate = UVC_MIN_BIT_RATE(UVC_CAM_FPS_FS);
+ pVSFrameDesc->dwMaxBitRate = UVC_MAX_BIT_RATE(UVC_CAM_FPS_FS);
+ pVSFrameDesc->dwDefaultFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS);
+ pVSFrameDesc->dwMinFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS);
+ }
+
+ *length = (uint16_t)(sizeof(USBD_VIDEO_CfgDesc));
+ return USBD_VIDEO_CfgDesc;
+}
+
+/**
+ * @brief DeviceQualifierDescriptor
+ * return Device Qualifier descriptor
+ * @param length : pointer data length
+ * @retval pointer to descriptor buffer
+ */
+static uint8_t *USBD_VIDEO_GetDeviceQualifierDesc(uint16_t *length)
+{
+ *length = (uint16_t)(sizeof(USBD_VIDEO_DeviceQualifierDesc));
+ return USBD_VIDEO_DeviceQualifierDesc;
+}
+
+/**
+ * @brief USBD_VIDEO_GetNextDesc
+ * This function return the next descriptor header
+ * @param buf: Buffer where the descriptor is available
+ * @param ptr: data pointer inside the descriptor
+ * @retval next header
+ */
+static USBD_VIDEO_DescHeader_t *USBD_VIDEO_GetNextDesc(uint8_t *pbuf, uint16_t *ptr)
+{
+ USBD_VIDEO_DescHeader_t *pnext = (USBD_VIDEO_DescHeader_t *)(void *)pbuf;
+
+ *ptr += pnext->bLength;
+ pnext = (USBD_VIDEO_DescHeader_t *)(void *)(pbuf + pnext->bLength);
+
+ return (pnext);
+}
+
+/**
+ * @brief USBD_VIDEO_GetVSFrameDesc
+ * This function return the Video Endpoint descriptor
+ * @param pdev: device instance
+ * @param pConfDesc: pointer to Bos descriptor
+ * @retval pointer to video endpoint descriptor
+ */
+static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc)
+{
+ USBD_VIDEO_DescHeader_t *pdesc = (USBD_VIDEO_DescHeader_t *)(void *)pConfDesc;
+ USBD_ConfigDescTypedef *desc = (USBD_ConfigDescTypedef *)(void *)pConfDesc;
+ USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = NULL;
+ uint16_t ptr;
+
+ if (desc->wTotalLength > desc->bLength)
+ {
+ ptr = desc->bLength;
+
+ while (ptr < desc->wTotalLength)
+ {
+ pdesc = USBD_VIDEO_GetNextDesc((uint8_t *)pdesc, &ptr);
+
+ if (((pdesc->bDescriptorSubType == VS_FRAME_MJPEG) ||
+ (pdesc->bDescriptorSubType == VS_FRAME_UNCOMPRESSED)) &&
+ (pdesc->bLength == VS_FRAME_DESC_SIZE))
+ {
+ pVSFrameDesc = (USBD_VIDEO_VSFrameDescTypeDef *)(void *)pdesc;
+ break;
+ }
+ }
+ }
+
+ return (void *)pVSFrameDesc;
+}
+
+/**
+ * @brief USBD_VIDEO_GetEpDesc
+ * This function return the Video Endpoint descriptor
+ * @param pdev: device instance
+ * @param pConfDesc: pointer to Bos descriptor
+ * @param EpAddr: endpoint address
+ * @retval pointer to video endpoint descriptor
+ */
+static void *USBD_VIDEO_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr)
+{
+ USBD_VIDEO_DescHeader_t *pdesc = (USBD_VIDEO_DescHeader_t *)(void *)pConfDesc;
+ USBD_ConfigDescTypedef *desc = (USBD_ConfigDescTypedef *)(void *)pConfDesc;
+ USBD_EpDescTypedef *pEpDesc = NULL;
+ uint16_t ptr;
+
+ if (desc->wTotalLength > desc->bLength)
+ {
+ ptr = desc->bLength;
+
+ while (ptr < desc->wTotalLength)
+ {
+ pdesc = USBD_VIDEO_GetNextDesc((uint8_t *)pdesc, &ptr);
+
+ if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT)
+ {
+ pEpDesc = (USBD_EpDescTypedef *)(void *)pdesc;
+
+ if (pEpDesc->bEndpointAddress == EpAddr)
+ {
+ break;
+ }
+ else
+ {
+ pEpDesc = NULL;
+ }
+ }
+ }
+ }
+
+ return (void *)pEpDesc;
+}
+
+/**
+ * @brief USBD_VIDEO_RegisterInterface
+ * @param pdev: instance
+ * @param fops: VIDEO interface callback
+ * @retval status
+ */
+uint8_t USBD_VIDEO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_VIDEO_ItfTypeDef *fops)
+{
+ /* Check if the FOPS pointer is valid */
+ if (fops == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
+ /* Assign the FOPS pointer */
+ pdev->pUserData_UVC = fops;
+
+ /* Exit with no error code */
+ return (uint8_t)USBD_OK;
+}
+
+void USBD_Update_UVC_DESC(uint8_t *desc, uint8_t vc_itf, uint8_t vs_itf, uint8_t in_ep, uint8_t str_idx)
+{
+#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
+#define _OFFSET 44
+#else
+#define _OFFSET 22
+#endif
+
+ desc[11] = vc_itf;
+ desc[16] = str_idx;
+ desc[19] = vc_itf;
+ desc[38] = vs_itf;
+ desc[58] = vs_itf;
+ desc[71] = in_ep;
+ desc[100 + _OFFSET] = vs_itf;
+ desc[109 + _OFFSET] = in_ep;
+
+ UVC_IN_EP = in_ep;
+ UVC_VC_IF_NUM = vc_itf;
+ UVC_VS_IF_NUM = vs_itf;
+ UVC_STR_DESC_IDX = str_idx;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/USBD_Test/USBD_Test.ioc_bkp b/USBD_Test/USBD_Test.ioc_bkp
new file mode 100644
index 0000000..02238f7
--- /dev/null
+++ b/USBD_Test/USBD_Test.ioc_bkp
@@ -0,0 +1,246 @@
+#MicroXplorer Configuration settings - do not modify
+Mcu.Family=STM32H7
+RCC.DIVQ2Freq_Value=200000000
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjHIDIiCUSTOM=true
+NVIC.OTG_HS_IRQn=true\:0\:0\:false\:false\:true\:true\:true
+ProjectManager.MainLocation=Core/Src
+PH0-OSC_IN.Signal=RCC_OSC_IN
+RCC.CDCPREFreq_Value=72000000
+RCC.SAI1Freq_Value=48000000
+RCC.CortexFreq_Value=72000000
+ProjectManager.KeepUserCode=true
+Mcu.UserName=STM32H7B3LIHxQ
+PB10.Mode=Device_HS
+RCC.PLLFRACN=0
+ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USB_OTG_HS_PCD_Init-USB_OTG_HS-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
+RCC.RTCFreq_Value=32768
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjMSCIiBOT=true
+RCC.PLL2FRACN=0
+RCC.CpuClockFreq_Value=72000000
+RCC.VCO2OutputFreq_Value=400000000
+USART1.IPParameters=VirtualMode-Asynchronous
+PB11.Signal=USB_OTG_HS_ULPI_D4
+PB13.Signal=USB_OTG_HS_ULPI_D6
+PinOutPanel.RotationAngle=0
+USB_OTG_HS.VirtualMode-Device_HS=Device_HS
+RCC.MCO1PinFreq_Value=24000000
+RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
+ProjectManager.StackSize=0x400
+RCC.AHB4Freq_Value=72000000
+RCC.VCOInput3Freq_Value=1000000
+RCC.SPI123CLockSelection=RCC_SPI123CLKSOURCE_CLKP
+RCC.LPTIM1Freq_Value=72000000
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_HID_CUSTOM=true
+Mcu.IP4=USART1
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjPRINTER=true
+RCC.SAI2BFreq_Value=48000000
+Mcu.IP5=USB_OTG_HS
+NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+Mcu.IP2=RCC
+Mcu.IP3=SYS
+PI11.Mode=Device_HS
+Mcu.IP0=CORTEX_M7
+Mcu.IP1=NVIC
+Mcu.UserConstants=
+RCC.DIVP3Freq_Value=11294117.647058824
+RCC.SDMMCFreq_Value=100000000
+Mcu.ThirdPartyNb=1
+RCC.HCLKFreq_Value=72000000
+RCC.I2C4Freq_Value=72000000
+Mcu.IPNb=6
+ProjectManager.PreviousToolchain=
+PB6.Signal=USART1_TX
+RCC.SPDIFRXFreq_Value=48000000
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjCDCIiRNDIS=true
+PB6.Mode=Asynchronous
+RCC.DIVQ3Freq_Value=96000000
+Mcu.Pin6=PH1-OSC_OUT
+Mcu.Pin7=PC0
+Mcu.Pin8=PB1
+Mcu.Pin9=PH4
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjUACIiMIC=true
+PH0-OSC_IN.Mode=HSE-External-Oscillator
+Mcu.Pin0=PB6
+Mcu.Pin1=PB7
+GPIO.groupedBy=Group By Peripherals
+Mcu.Pin2=PB5
+Mcu.Pin3=PI11
+Mcu.Pin4=PA8
+Mcu.Pin5=PH0-OSC_IN
+ProjectManager.ProjectBuild=false
+RCC.DIVR3Freq_Value=96000000
+NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+RCC.DIVM3=24
+RCC.DIVM2=12
+NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true
+RCC.DIVM1=2
+RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE
+RCC.RCC_MCO1Source=RCC_MCO1SOURCE_HSE
+RCC.DFSDM2Freq_Value=72000000
+ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.9.0
+MxDb.Version=DB.6.0.21
+Mcu.ThirdParty0=AL94.I-CUBE-USBD-COMPOSITE.1.0.2
+RCC.DIVP1Freq_Value=72000000
+ProjectManager.BackupPrevious=false
+RCC.FMCFreq_Value=100000000
+VP_AL94.I-CUBE-USBD-COMPOSITE_VS_USBJjComposite_1.0.0_1.0.2.Mode=USBJjComposite
+RCC.DFSDM2ACLkFreq_Value=72000000
+PB5.Mode=Device_HS
+RCC.USART16Freq_Value=72000000
+File.Version=6
+PB7.Signal=USART1_RX
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_CDC_ACM=true
+PA8.Signal=RCC_MCO_1
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjCOMPOSITE=true
+NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+USB_OTG_HS.IPParameters=VirtualMode-Device_HS
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjCDCIiECM=true
+RCC.DIVR2Freq_Value=100000000
+ProjectManager.HalAssertFull=false
+RCC.DIVP2Freq_Value=200000000
+ProjectManager.ProjectName=USBD_Test
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjHIDIiMOUSE=true
+RCC.APB3Freq_Value=72000000
+PH1-OSC_OUT.Mode=HSE-External-Oscillator
+RCC.MCO2PinFreq_Value=72000000
+Mcu.Package=TFBGA225
+PB1.Signal=USB_OTG_HS_ULPI_D2
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjDFU=true
+PB12.Mode=Device_HS
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_UAC_MIC=true
+RCC.PLL3FRACN=0
+RCC.SDMMC1CLockSelection=RCC_SDMMCCLKSOURCE_PLL2
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_HID_KEYBOARD=true
+ProjectManager.ToolChainLocation=
+VP_SYS_VS_Systick.Signal=SYS_VS_Systick
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjUACIiSPKR=true
+RCC.DFSDMFreq_Value=72000000
+RCC.DIVR1Freq_Value=36000000
+RCC.TraceFreq_Value=64000000
+RCC.APB4Freq_Value=72000000
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_DFU=true
+RCC.CECFreq_Value=32000
+NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjHIDIiKEYBOARD=true
+RCC.LPUART1Freq_Value=72000000
+PB13.Mode=Device_HS
+PI11.Signal=USB_OTG_HS_ULPI_DIR
+ProjectManager.CustomerFirmwarePackage=
+RCC.SupplySource=PWR_DIRECT_SMPS_SUPPLY
+RCC.Tim2OutputFreq_Value=72000000
+RCC.DFSDMACLkFreq_Value=48000000
+RCC.VCO3OutputFreq_Value=192000000
+PA3.Signal=USB_OTG_HS_ULPI_D0
+PA5.Mode=Device_HS
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjUVC=true
+RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
+ProjectManager.ProjectFileName=USBD_Test.ioc
+RCC.DIVQ1=3
+Mcu.PinsNb=19
+ProjectManager.NoMain=false
+RCC.SWPMI1Freq_Value=72000000
+RCC.DIVP3=17
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_UAC_SPKR=true
+ProjectManager.DefaultFWLocation=true
+ProjectManager.DeletePrevious=true
+PC0.Signal=USB_OTG_HS_ULPI_STP
+RCC.QSPIFreq_Value=100000000
+boardIOC=true
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_UVC=true
+RCC.PWR_Regulator_Voltage_Scale=PWR_REGULATOR_VOLTAGE_SCALE0
+PinOutPanel.CurrentBGAView=Top
+RCC.FamilyName=M
+PC0.Mode=Device_HS
+RCC.SPI6Freq_Value=72000000
+USART1.VirtualMode-Asynchronous=VM_ASYNC
+PA3.Mode=Device_HS
+RCC.USART234578Freq_Value=72000000
+RCC.SPI45Freq_Value=72000000
+RCC.Tim1OutputFreq_Value=72000000
+PH4.Signal=USB_OTG_HS_ULPI_NXT
+RCC.SPI123Freq_Value=64000000
+PB11.Mode=Device_HS
+ProjectManager.TargetToolchain=STM32CubeIDE
+RCC.VCO1OutputFreq_Value=144000000
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_MSC=true
+RCC.DIVN3=192
+RCC.DIVN2=200
+RCC.AXIClockFreq_Value=72000000
+RCC.DIVN1=12
+ProjectManager.RegisterCallBack=
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.USBJjComposite_Checked=true
+RCC.USBFreq_Value=48000000
+RCC.CKPERFreq_Value=64000000
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.IPParameters=_USBD_USE_HS,_USBD_USE_CDC_ACM,_USBD_USE_CDC_RNDIS,_USBD_USE_CDC_ECM,_USBD_USE_HID_MOUSE,_USBD_USE_HID_KEYBOARD,_USBD_USE_HID_CUSTOM,_USBD_USE_UAC_MIC,_USBD_USE_UAC_SPKR,_USBD_USE_UVC,_USBD_USE_MSC,_USBD_USE_DFU,_USBD_USE_PRNTR,CompositeCcUSBJjCOMPOSITEJjCore,CompositeCcUSBJjCOMPOSITEJjCDCIiACM,CompositeCcUSBJjCOMPOSITEJjCDCIiRNDIS,CompositeCcUSBJjCOMPOSITEJjHIDIiMOUSE,CompositeCcUSBJjCOMPOSITEJjHIDIiKEYBOARD,CompositeCcUSBJjCOMPOSITEJjHIDIiCUSTOM,CompositeCcUSBJjCOMPOSITEJjMSCIiBOT,CompositeCcUSBJjCOMPOSITEJjUACIiMIC,CompositeCcUSBJjCOMPOSITEJjUACIiSPKR,CompositeCcUSBJjCOMPOSITEJjUVC,CompositeCcUSBJjCOMPOSITEJjDFU,CompositeCcUSBJjCOMPOSITEJjCDCIiECM,CompositeCcUSBJjCOMPOSITEJjCOMPOSITE,CompositeCcUSBJjCOMPOSITEJjPRINTER
+PB10.Signal=USB_OTG_HS_ULPI_D3
+PA5.Signal=USB_OTG_HS_ULPI_CK
+PB0.Mode=Device_HS
+board=STM32H7B3I-DK
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_PRNTR=true
+ProjectManager.LastFirmware=false
+RCC.VCOInput1Freq_Value=12000000
+RCC.AHB12Freq_Value=72000000
+RCC.APB2Freq_Value=72000000
+MxCube.Version=6.2.1
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjCore=true
+RCC.FMCCLockSelection=RCC_FMCCLKSOURCE_PLL2
+RCC.FDCANFreq_Value=48000000
+RCC.RNGFreq_Value=48000000
+RCC.ADCFreq_Value=200000000
+VP_SYS_VS_Systick.Mode=SysTick
+PH1-OSC_OUT.Signal=RCC_OSC_OUT
+NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2.CompositeCcUSBJjCOMPOSITEJjCDCIiACM=true
+ProjectManager.FreePins=false
+RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CDCPREFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,DFSDM2ACLkFreq_Value,DFSDM2Freq_Value,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVM3,DIVN1,DIVN2,DIVN3,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1,DIVR1Freq_Value,DIVR2,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCCLockSelection,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,PWR_Regulator_Voltage_Scale,QSPICLockSelection,QSPIFreq_Value,RCC_MCO1Source,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SAI2AFreq_Value,SAI2BFreq_Value,SDMMC1CLockSelection,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123CLockSelection,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,SupplySource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_CDC_ECM=true
+ProjectManager.AskForMigrate=true
+Mcu.Name=STM32H7B3LIHxQ
+RCC.LPTIM2Freq_Value=72000000
+PH4.Mode=Device_HS
+ProjectManager.UnderRoot=true
+ProjectManager.CoupleFile=true
+RCC.SYSCLKFreq_VALUE=72000000
+PB5.Signal=USB_OTG_HS_ULPI_D7
+RCC.I2C123Freq_Value=72000000
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_HID_MOUSE=true
+NVIC.ForceEnableDMAVector=true
+KeepUserPlacement=false
+NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+ProjectManager.CompilerOptimize=6
+RCC.QSPICLockSelection=RCC_OSPICLKSOURCE_PLL2
+PB7.Mode=Asynchronous
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2_SwParameter=CompositeCcUSBJjCOMPOSITEJjHIDIiCUSTOM\:true;CompositeCcUSBJjCOMPOSITEJjMSCIiBOT\:true;CompositeCcUSBJjCOMPOSITEJjCOMPOSITE\:true;CompositeCcUSBJjCOMPOSITEJjUACIiSPKR\:true;CompositeCcUSBJjCOMPOSITEJjUACIiMIC\:true;CompositeCcUSBJjCOMPOSITEJjHIDIiMOUSE\:true;CompositeCcUSBJjCOMPOSITEJjDFU\:true;CompositeCcUSBJjCOMPOSITEJjHIDIiKEYBOARD\:true;CompositeCcUSBJjCOMPOSITEJjCore\:true;CompositeCcUSBJjCOMPOSITEJjCDCIiECM\:true;CompositeCcUSBJjCOMPOSITEJjCDCIiRNDIS\:true;CompositeCcUSBJjCOMPOSITEJjCDCIiACM\:true;CompositeCcUSBJjCOMPOSITEJjUVC\:true;CompositeCcUSBJjCOMPOSITEJjPRINTER\:true;
+ProjectManager.HeapSize=0x200
+Mcu.Pin15=PA3
+NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+Mcu.Pin16=PB10
+PB1.Mode=Device_HS
+Mcu.Pin13=PB0
+Mcu.Pin14=PB11
+RCC.LPTIM345Freq_Value=72000000
+ProjectManager.ComputerToolchain=false
+Mcu.Pin17=VP_SYS_VS_Systick
+Mcu.Pin18=VP_AL94.I-CUBE-USBD-COMPOSITE_VS_USBJjComposite_1.0.0_1.0.2
+RCC.LTDCFreq_Value=96000000
+NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
+Mcu.Pin11=PA5
+Mcu.Pin12=PB12
+Mcu.Pin10=PB13
+RCC.DIVQ1Freq_Value=48000000
+PA8.Mode=Clock-out-1
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_CDC_RNDIS=true
+AL94.I-CUBE-USBD-COMPOSITE.1.0.2._USBD_USE_HS=true
+RCC.HCLK3ClockFreq_Value=72000000
+RCC.VCOInput2Freq_Value=2000000
+RCC.APB1Freq_Value=72000000
+RCC.DIVR2=4
+RCC.DIVR1=4
+PB0.Signal=USB_OTG_HS_ULPI_D1
+RCC.SAI2AFreq_Value=48000000
+ProjectManager.DeviceId=STM32H7B3LIHxQ
+PB12.Signal=USB_OTG_HS_ULPI_D5
+ProjectManager.LibraryCopy=1
+VP_AL94.I-CUBE-USBD-COMPOSITE_VS_USBJjComposite_1.0.0_1.0.2.Signal=AL94.I-CUBE-USBD-COMPOSITE_VS_USBJjComposite_1.0.0_1.0.2
+isbadioc=false
diff --git a/stm32_mw_usb_device/App/usbd_msc_if.c b/stm32_mw_usb_device/App/usbd_msc_if.c
index 4b5f130..195cbec 100644
--- a/stm32_mw_usb_device/App/usbd_msc_if.c
+++ b/stm32_mw_usb_device/App/usbd_msc_if.c
@@ -64,7 +64,7 @@ uint8_t MSC_Storage[32*1024];
*/
#define STORAGE_LUN_NBR 1
-#define STORAGE_BLK_NBR 100*1024/512
+#define STORAGE_BLK_NBR 32*1024/512
#define STORAGE_BLK_SIZ 512
/* USER CODE BEGIN PRIVATE_DEFINES */
diff --git a/stm32_mw_usb_device/Class/CDC_ACM/Src/usbd_cdc_acm.c b/stm32_mw_usb_device/Class/CDC_ACM/Src/usbd_cdc_acm.c
index d5cbd30..b5f85d5 100644
--- a/stm32_mw_usb_device/Class/CDC_ACM/Src/usbd_cdc_acm.c
+++ b/stm32_mw_usb_device/Class/CDC_ACM/Src/usbd_cdc_acm.c
@@ -1968,15 +1968,15 @@ static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
{
USBD_CDC_ACM_HandleTypeDef *hcdc = NULL;
- if (hcdc == NULL)
- {
- return (uint8_t)USBD_FAIL;
- }
-
for (uint8_t i = 0; i < NUMBER_OF_CDC; i++)
{
hcdc = &CDC_ACM_Class_Data[i];
+ if (hcdc == NULL)
+ {
+ return (uint8_t)USBD_FAIL;
+ }
+
if ((pdev->pUserData_CDC_ACM != NULL) && (hcdc->CmdOpCode != 0xFFU))
{
((USBD_CDC_ACM_ItfTypeDef *)pdev->pUserData_CDC_ACM)->Control(i, hcdc->CmdOpCode, (uint8_t *)hcdc->data[i], (uint16_t)hcdc->CmdLength);