From 26f5806b035a206152e02a2ade8f9d05047d25df Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Fri, 29 May 2020 14:23:58 +0100
Subject: [PATCH 01/37] initial commit of new cdc_msc and updated msc

---
 .../stm32/usb/cdc_msc/usbd_cdc_msc.cpp        | 508 +++++++++++++
 .../arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h  |  39 +
 cores/arduino/stm32/usb/msc/usbd_msc.c        | 601 +++++++++++++++
 cores/arduino/stm32/usb/msc/usbd_msc.h        | 133 ++++
 cores/arduino/stm32/usb/msc/usbd_msc_bot.c    | 387 ++++++++++
 cores/arduino/stm32/usb/msc/usbd_msc_bot.h    | 150 ++++
 cores/arduino/stm32/usb/msc/usbd_msc_data.c   | 135 ++++
 cores/arduino/stm32/usb/msc/usbd_msc_data.h   | 103 +++
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c   | 716 ++++++++++++++++++
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.h   | 192 +++++
 10 files changed, 2964 insertions(+)
 create mode 100644 cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
 create mode 100644 cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
 create mode 100644 cores/arduino/stm32/usb/msc/usbd_msc.c
 create mode 100644 cores/arduino/stm32/usb/msc/usbd_msc.h
 create mode 100644 cores/arduino/stm32/usb/msc/usbd_msc_bot.c
 create mode 100644 cores/arduino/stm32/usb/msc/usbd_msc_bot.h
 create mode 100644 cores/arduino/stm32/usb/msc/usbd_msc_data.c
 create mode 100644 cores/arduino/stm32/usb/msc/usbd_msc_data.h
 create mode 100644 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
 create mode 100644 cores/arduino/stm32/usb/msc/usbd_msc_scsi.h

diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
new file mode 100644
index 0000000000..20a859a408
--- /dev/null
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -0,0 +1,508 @@
+/**
+  ******************************************************************************
+  * @file    usbd_template.c
+  * @author  MCD Application Team
+  * @brief   This file provides the HID core functions.
+  *
+  * @verbatim
+  *
+  *          ===================================================================
+  *                                COMPOSITE Class Description
+  *          ===================================================================
+  *
+  *
+  *
+  *
+  *
+  *
+  * @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
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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_msc.h"
+#include "usbd_ctlreq.h"
+
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup USBD_COMPOSITE
+  * @brief usbd core module
+  * @{
+  */
+
+/** @defgroup USBD_COMPOSITE_Private_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_COMPOSITE_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_COMPOSITE_Private_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+
+
+/** @defgroup USBD_COMPOSITE_Private_FunctionPrototypes
+  * @{
+  */
+
+
+static uint8_t  USBD_COMPOSITE_Init(USBD_HandleTypeDef *pdev,
+                                   uint8_t cfgidx);
+
+static uint8_t  USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
+                                     uint8_t cfgidx);
+
+static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
+                                    USBD_SetupReqTypedef *req);
+
+static uint8_t  *USBD_COMPOSITE_GetCfgDesc(uint16_t *length);
+
+static uint8_t  *USBD_COMPOSITE_GetDeviceQualifierDesc(uint16_t *length);
+
+static uint8_t  USBD_COMPOSITE_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+static uint8_t  USBD_COMPOSITE_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+static uint8_t  USBD_COMPOSITE_EP0_RxReady(USBD_HandleTypeDef *pdev);
+
+static uint8_t  USBD_COMPOSITE_EP0_TxReady(USBD_HandleTypeDef *pdev);
+
+static uint8_t  USBD_COMPOSITE_SOF(USBD_HandleTypeDef *pdev);
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_COMPOSITE_Private_Variables
+  * @{
+  */
+
+USBD_ClassTypeDef  USBD_COMPOSITE_ClassDriver =
+{
+  USBD_COMPOSITE_Init,
+  USBD_COMPOSITE_DeInit,
+  USBD_COMPOSITE_Setup,
+  nullptr,
+  USBD_COMPOSITE_EP0_RxReady,
+  USBD_COMPOSITE_DataIn,
+  USBD_COMPOSITE_DataOut,
+  USBD_COMPOSITE_SOF,
+  nullptr,
+  nullptr,
+  USBD_COMPOSITE_GetCfgDesc,
+  USBD_COMPOSITE_GetCfgDesc,
+  USBD_COMPOSITE_GetCfgDesc,
+  USBD_COMPOSITE_GetDeviceQualifierDesc,
+};
+
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma data_alignment=4
+#endif
+/* USB COMPOSITE device Configuration Descriptor */
+static uint8_t USBD_COMPOSITE_CfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] =
+{
+  0x09, /* bLength: Configuation Descriptor size */
+  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, /* bDescriptorType: Configuration */
+  USB_CDC_MSC_CONFIG_DESC_SIZ,
+  /* wTotalLength: Bytes returned */
+  0x00,
+  0x03,         /*bNumInterfaces: 3 interface*/
+  0x01,         /*bConfigurationValue: Configuration value*/
+  0x02,         /*iConfiguration: Index of string descriptor describing the configuration*/
+  0xC0,         /*bmAttributes: bus powered and Supports Remote Wakeup */
+  0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/
+  /* 09 */
+
+  /*---------------------------------------------------------------------------*/
+
+  /*Interface Descriptor */
+  0x09,   /* bLength: Interface Descriptor size */
+  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
+  /* Interface descriptor type */
+  0x00,   /* 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 */
+  0x00,   /* 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 */
+  0x01,   /* 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 */
+  0x00,   /* bMasterInterface: Communication class interface */
+  0x01,   /* 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: */
+  0x01,   /* 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,
+
+
+  /********************  Mass Storage interface ********************/
+  0x09,                                            /* bLength: Interface Descriptor size */
+  0x04,                                            /* bDescriptorType: */
+  0x02,                                            /* bInterfaceNumber: Number of Interface */
+  0x00,                                            /* bAlternateSetting: Alternate setting */
+  0x02,                                            /* bNumEndpoints */
+  0x08,                                            /* bInterfaceClass: MSC Class */
+  0x06,                                            /* bInterfaceSubClass : SCSI transparent */
+  0x50,                                            /* nInterfaceProtocol */
+  0x05,                                            /* iInterface: */
+
+  /********************  Mass Storage Endpoints ********************/
+  0x07,                                            /* Endpoint descriptor length = 7 */
+  0x05,                                            /* Endpoint descriptor type */
+  MSC_EPIN_ADDR,                                   /* Endpoint address (IN, address 1) */
+  0x02,                                            /* Bulk endpoint type */
+  LOBYTE(MSC_MAX_HS_PACKET),
+  HIBYTE(MSC_MAX_HS_PACKET),
+  0x00,                                            /* Polling interval in milliseconds */
+
+  0x07,                                            /* Endpoint descriptor length = 7 */
+  0x05,                                            /* Endpoint descriptor type */
+  MSC_EPOUT_ADDR,                                  /* Endpoint address (OUT, address 1) */
+  0x02,                                            /* Bulk endpoint type */
+  LOBYTE(MSC_MAX_HS_PACKET),
+  HIBYTE(MSC_MAX_HS_PACKET),
+  0x00                                             /* Polling interval in milliseconds */
+};
+
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma data_alignment=4
+#endif
+/* USB Standard Device Descriptor */
+static uint8_t USBD_COMPOSITE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
+{
+  USB_LEN_DEV_QUALIFIER_DESC,
+  USB_DESC_TYPE_DEVICE_QUALIFIER,
+  0x00,
+  0x02,
+  0x00,
+  0x00,
+  0x00,
+  0x40,
+  0x01,
+  0x00,
+};
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_COMPOSITE_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  USBD_COMPOSITE_Init
+  *         Initialize the COMPOSITE interface
+  * @param  pdev: device instance
+  * @param  cfgidx: Configuration index
+  * @retval status
+  */
+static uint8_t  USBD_COMPOSITE_Init(USBD_HandleTypeDef *pdev,
+                                   uint8_t cfgidx)
+{
+  USBD_MSC.Init(pdev, cfgidx);
+
+  USBD_CDC.Init(pdev, cfgidx);
+
+  return (uint8_t)USBD_OK;
+}
+
+/**
+  * @brief  USBD_COMPOSITE_Init
+  *         DeInitialize the COMPOSITE layer
+  * @param  pdev: device instance
+  * @param  cfgidx: Configuration index
+  * @retval status
+  */
+static uint8_t  USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
+                                     uint8_t cfgidx)
+{
+  USBD_MSC.DeInit(pdev, cfgidx);
+
+  USBD_CDC.DeInit(pdev, cfgidx);
+
+  return USBD_OK;
+}
+
+/**
+  * @brief  USBD_COMPOSITE_Setup
+  *         Handle the COMPOSITE specific requests
+  * @param  pdev: instance
+  * @param  req: usb requests
+  * @retval status
+  */
+static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
+                                    USBD_SetupReqTypedef *req)
+{
+  switch (req->bmRequest & USB_REQ_RECIPIENT_MASK)
+  {
+    case USB_REQ_RECIPIENT_INTERFACE:
+      switch(req->wIndex) {
+        case CDC_ACM_INTERFACE:
+        case CDC_COM_INTERFACE:
+          return USBD_CDC.Setup(pdev, req);
+          break;
+
+        case MSC_INTERFACE:
+          return USBD_MSC.Setup(pdev, req);
+          break;
+      
+        // invalid interface
+        default:
+          return USBD_FAIL;
+      }
+    break;
+
+    case USB_REQ_RECIPIENT_ENDPOINT:
+      switch (req->wIndex) {
+        case CDC_IN_EP:
+        case CDC_OUT_EP:
+        case CDC_CMD_EP:
+          return USBD_CDC.Setup(pdev, req);
+
+        case MSC_IN_EP:
+        case MSC_OUT_EP:
+          return USBD_MSC.Setup(pdev, req);
+
+        // invalid endpoint
+        default:
+          return USBD_FAIL;
+      }
+    break;
+
+    default:
+      break;
+  }
+
+  return USBD_OK;
+}
+
+
+/**
+  * @brief  USBD_COMPOSITE_GetCfgDesc
+  *         return configuration descriptor
+  * @param  length : pointer data length
+  * @retval pointer to descriptor buffer
+  */
+static uint8_t  *USBD_COMPOSITE_GetCfgDesc(uint16_t *length)
+{
+  *length = sizeof(USBD_COMPOSITE_CfgDesc);
+  return USBD_COMPOSITE_CfgDesc;
+}
+
+/**
+* @brief  DeviceQualifierDescriptor
+*         return Device Qualifier descriptor
+* @param  length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t  *USBD_COMPOSITE_DeviceQualifierDescriptor(uint16_t *length)
+{
+  *length = sizeof(USBD_COMPOSITE_DeviceQualifierDesc);
+  return USBD_COMPOSITE_DeviceQualifierDesc;
+}
+
+
+/**
+  * @brief  USBD_COMPOSITE_DataIn
+  *         handle data IN Stage
+  * @param  pdev: device instance
+  * @param  epnum: endpoint index
+  * @retval status
+  */
+static uint8_t  USBD_COMPOSITE_DataIn(USBD_HandleTypeDef *pdev,
+                                     uint8_t epnum)
+{
+  switch (epnum)
+  {
+    case CDC_IN_EP:
+    case CDC_CMD_EP:
+    case CDC_OUT_EP:
+      return USBD_CDC.DataIn(pdev, epnum);
+
+    case MSC_IN_EP:
+    case MSC_OUT_EP:
+      return USBD_MSC.DataIn(pdev, epnum);
+
+    // invalid endpoint
+    default:
+      return USBD_FAIL;
+  }
+}
+
+/**
+  * @brief  USBD_COMPOSITE_EP0_RxReady
+  *         handle EP0 Rx Ready event
+  * @param  pdev: device instance
+  * @retval status
+  */
+static uint8_t  USBD_COMPOSITE_EP0_RxReady(USBD_HandleTypeDef *pdev)
+{
+  // only needed by CDC
+  return USBD_CDC.EP0_RxReady(pdev);
+}
+
+/**
+  * @brief  USBD_COMPOSITE_SOF
+  *         handle SOF event
+  * @param  pdev: device instance
+  * @retval status
+  */
+static uint8_t  USBD_COMPOSITE_SOF(USBD_HandleTypeDef *pdev)
+{
+  // only needed for CDC
+  return USBD_CDC.SOF(pdev);
+}
+
+/**
+  * @brief  USBD_COMPOSITE_DataOut
+  *         handle data OUT Stage
+  * @param  pdev: device instance
+  * @param  epnum: endpoint index
+  * @retval status
+  */
+static uint8_t  USBD_COMPOSITE_DataOut(USBD_HandleTypeDef *pdev,
+                                      uint8_t epnum)
+{
+  switch (epnum)
+  {
+    case CDC_IN_EP:
+    case CDC_CMD_EP:
+    case CDC_OUT_EP:
+      return USBD_CDC.DataOut(pdev, epnum);
+
+    case MSC_IN_EP:
+    case MSC_OUT_EP:
+      return USBD_MSC.DataOut(pdev, epnum);
+
+    // invalid endpoint
+    default:
+      return USBD_FAIL;
+  }
+}
+
+/**
+* @brief  DeviceQualifierDescriptor
+*         return Device Qualifier descriptor
+* @param  length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t  *USBD_COMPOSITE_GetDeviceQualifierDesc(uint16_t *length)
+{
+  *length = sizeof(USBD_COMPOSITE_DeviceQualifierDesc);
+  return USBD_COMPOSITE_DeviceQualifierDesc;
+}
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
new file mode 100644
index 0000000000..3d50cb967a
--- /dev/null
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
@@ -0,0 +1,39 @@
+/**
+  ******************************************************************************
+  * @file    usbd_cdc_msc_core.h
+  * @author  MCD Application Team
+  * @version V1.2.1
+  * @date    17-March-2018
+  * @brief   header file for the usbd_cdc_msc_core.c file.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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 ------------------------------------------------------------------*/
+
+#ifndef __USB_CDC_MSC_CORE_H_
+#define __USB_CDC_MSC_CORE_H_
+
+#include "../cdc/usbd_cdc.h"
+#include "usbd_msc.h"
+#include "usbd_ioreq.h"
+
+#define CDC_ACM_INTERFACE   0x0
+#define CDC_COM_INTERFACE   0x1
+#define MSC_INTERFACE       0x2
+
+#define USB_CDC_MSC_CONFIG_DESC_SIZ  (USB_CDC_CONFIG_DESC_SIZ - 9 + USB_MSC_CONFIG_DESC_SIZ)
+
+#endif  /* __USB_CDC_MSC_CORE_H_ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.c b/cores/arduino/stm32/usb/msc/usbd_msc.c
new file mode 100644
index 0000000000..e196cefe46
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.c
@@ -0,0 +1,601 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc.c
+  * @author  MCD Application Team
+  * @brief   This file provides all the MSC core functions.
+  *
+  * @verbatim
+  *
+  *          ===================================================================
+  *                                MSC Class  Description
+  *          ===================================================================
+  *           This module manages the MSC class V1.0 following the "Universal
+  *           Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
+  *           Sep. 31, 1999".
+  *           This driver implements the following aspects of the specification:
+  *             - Bulk-Only Transport protocol
+  *             - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
+  *
+  *  @endverbatim
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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"
+- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc.h"
+
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup MSC_CORE
+  * @brief Mass storage core module
+  * @{
+  */
+
+/** @defgroup MSC_CORE_Private_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_CORE_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_CORE_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_CORE_Private_FunctionPrototypes
+  * @{
+  */
+uint8_t  USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+uint8_t  USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+uint8_t  USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+uint8_t  USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+uint8_t  USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+
+uint8_t  *USBD_MSC_GetHSCfgDesc(uint16_t *length);
+uint8_t  *USBD_MSC_GetFSCfgDesc(uint16_t *length);
+uint8_t  *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length);
+uint8_t  *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length);
+
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_CORE_Private_Variables
+  * @{
+  */
+
+
+USBD_ClassTypeDef  USBD_MSC =
+{
+  USBD_MSC_Init,
+  USBD_MSC_DeInit,
+  USBD_MSC_Setup,
+  NULL, /*EP0_TxSent*/
+  NULL, /*EP0_RxReady*/
+  USBD_MSC_DataIn,
+  USBD_MSC_DataOut,
+  NULL, /*SOF */
+  NULL,
+  NULL,
+  USBD_MSC_GetHSCfgDesc,
+  USBD_MSC_GetFSCfgDesc,
+  USBD_MSC_GetOtherSpeedCfgDesc,
+  USBD_MSC_GetDeviceQualifierDescriptor,
+};
+
+/* USB Mass storage device Configuration Descriptor */
+/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
+__ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
+{
+
+  0x09,   /* bLength: Configuation Descriptor size */
+  USB_DESC_TYPE_CONFIGURATION,   /* bDescriptorType: Configuration */
+  USB_MSC_CONFIG_DESC_SIZ,
+
+  0x00,
+  0x01,   /* bNumInterfaces: 1 interface */
+  0x01,   /* bConfigurationValue: */
+  0x04,   /* iConfiguration: */
+  0xC0,   /* bmAttributes: */
+  0x32,   /* MaxPower 100 mA */
+
+  /********************  Mass Storage interface ********************/
+  0x09,   /* bLength: Interface Descriptor size */
+  0x04,   /* bDescriptorType: */
+  0x00,   /* bInterfaceNumber: Number of Interface */
+  0x00,   /* bAlternateSetting: Alternate setting */
+  0x02,   /* bNumEndpoints*/
+  0x08,   /* bInterfaceClass: MSC Class */
+  0x06,   /* bInterfaceSubClass : SCSI transparent*/
+  0x50,   /* nInterfaceProtocol */
+  0x05,          /* iInterface: */
+  /********************  Mass Storage Endpoints ********************/
+  0x07,   /*Endpoint descriptor length = 7*/
+  0x05,   /*Endpoint descriptor type */
+  MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
+  0x02,   /*Bulk endpoint type */
+  LOBYTE(MSC_MAX_HS_PACKET),
+  HIBYTE(MSC_MAX_HS_PACKET),
+  0x00,   /*Polling interval in milliseconds */
+
+  0x07,   /*Endpoint descriptor length = 7 */
+  0x05,   /*Endpoint descriptor type */
+  MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
+  0x02,   /*Bulk endpoint type */
+  LOBYTE(MSC_MAX_HS_PACKET),
+  HIBYTE(MSC_MAX_HS_PACKET),
+  0x00     /*Polling interval in milliseconds*/
+};
+
+/* USB Mass storage device Configuration Descriptor */
+/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
+__ALIGN_BEGIN uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
+{
+  0x09,   /* bLength: Configuation Descriptor size */
+  USB_DESC_TYPE_CONFIGURATION,   /* bDescriptorType: Configuration */
+  USB_MSC_CONFIG_DESC_SIZ,
+
+  0x00,
+  0x01,   /* bNumInterfaces: 1 interface */
+  0x01,   /* bConfigurationValue: */
+  0x04,   /* iConfiguration: */
+  0xC0,   /* bmAttributes: */
+  0x32,   /* MaxPower 100 mA */
+
+  /********************  Mass Storage interface ********************/
+  0x09,   /* bLength: Interface Descriptor size */
+  0x04,   /* bDescriptorType: */
+  0x00,   /* bInterfaceNumber: Number of Interface */
+  0x00,   /* bAlternateSetting: Alternate setting */
+  0x02,   /* bNumEndpoints*/
+  0x08,   /* bInterfaceClass: MSC Class */
+  0x06,   /* bInterfaceSubClass : SCSI transparent*/
+  0x50,   /* nInterfaceProtocol */
+  0x05,          /* iInterface: */
+  /********************  Mass Storage Endpoints ********************/
+  0x07,   /*Endpoint descriptor length = 7*/
+  0x05,   /*Endpoint descriptor type */
+  MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
+  0x02,   /*Bulk endpoint type */
+  LOBYTE(MSC_MAX_FS_PACKET),
+  HIBYTE(MSC_MAX_FS_PACKET),
+  0x00,   /*Polling interval in milliseconds */
+
+  0x07,   /*Endpoint descriptor length = 7 */
+  0x05,   /*Endpoint descriptor type */
+  MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
+  0x02,   /*Bulk endpoint type */
+  LOBYTE(MSC_MAX_FS_PACKET),
+  HIBYTE(MSC_MAX_FS_PACKET),
+  0x00     /*Polling interval in milliseconds*/
+};
+
+__ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __ALIGN_END  =
+{
+  0x09,   /* bLength: Configuation Descriptor size */
+  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
+  USB_MSC_CONFIG_DESC_SIZ,
+
+  0x00,
+  0x01,   /* bNumInterfaces: 1 interface */
+  0x01,   /* bConfigurationValue: */
+  0x04,   /* iConfiguration: */
+  0xC0,   /* bmAttributes: */
+  0x32,   /* MaxPower 100 mA */
+
+  /********************  Mass Storage interface ********************/
+  0x09,   /* bLength: Interface Descriptor size */
+  0x04,   /* bDescriptorType: */
+  0x00,   /* bInterfaceNumber: Number of Interface */
+  0x00,   /* bAlternateSetting: Alternate setting */
+  0x02,   /* bNumEndpoints*/
+  0x08,   /* bInterfaceClass: MSC Class */
+  0x06,   /* bInterfaceSubClass : SCSI transparent command set*/
+  0x50,   /* nInterfaceProtocol */
+  0x05,          /* iInterface: */
+  /********************  Mass Storage Endpoints ********************/
+  0x07,   /*Endpoint descriptor length = 7*/
+  0x05,   /*Endpoint descriptor type */
+  MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
+  0x02,   /*Bulk endpoint type */
+  0x40,
+  0x00,
+  0x00,   /*Polling interval in milliseconds */
+
+  0x07,   /*Endpoint descriptor length = 7 */
+  0x05,   /*Endpoint descriptor type */
+  MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
+  0x02,   /*Bulk endpoint type */
+  0x40,
+  0x00,
+  0x00     /*Polling interval in milliseconds*/
+};
+
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN  uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]  __ALIGN_END =
+{
+  USB_LEN_DEV_QUALIFIER_DESC,
+  USB_DESC_TYPE_DEVICE_QUALIFIER,
+  0x00,
+  0x02,
+  0x00,
+  0x00,
+  0x00,
+  MSC_MAX_FS_PACKET,
+  0x01,
+  0x00,
+};
+/**
+  * @}
+  */
+
+USBD_MSC_BOT_HandleTypeDef msc_handle_dat;
+USBD_MSC_BOT_HandleTypeDef *msc_handle = &msc_handle_dat;
+
+USBD_StorageTypeDef *msc_storage = NULL;
+
+/** @defgroup MSC_CORE_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  USBD_MSC_Init
+  *         Initialize  the mass storage configuration
+  * @param  pdev: device instance
+  * @param  cfgidx: configuration index
+  * @retval status
+  */
+uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+{
+  if (pdev->dev_speed == USBD_SPEED_HIGH)
+  {
+    /* Open EP OUT */
+    USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
+    pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
+
+    /* Open EP IN */
+    USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
+    pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
+  }
+  else
+  {
+    /* Open EP OUT */
+    USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
+    pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
+
+    /* Open EP IN */
+    USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
+    pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
+  }
+
+  /* Init the BOT  layer */
+  MSC_BOT_Init(pdev);
+
+  return USBD_OK;
+}
+
+/**
+  * @brief  USBD_MSC_DeInit
+  *         DeInitilaize  the mass storage configuration
+  * @param  pdev: device instance
+  * @param  cfgidx: configuration index
+  * @retval status
+  */
+uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev,
+                         uint8_t cfgidx)
+{
+  /* Close MSC EPs */
+  USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR);
+  pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 0U;
+
+  /* Close EP IN */
+  USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR);
+  pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 0U;
+
+  /* De-Init the BOT layer */
+  MSC_BOT_DeInit(pdev);
+
+  return USBD_OK;
+}
+/**
+* @brief  USBD_MSC_Setup
+*         Handle the MSC specific requests
+* @param  pdev: device instance
+* @param  req: USB request
+* @retval status
+*/
+uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+  uint8_t ret = USBD_OK;
+  uint16_t status_info = 0U;
+
+  switch (req->bmRequest & USB_REQ_TYPE_MASK)
+  {
+    /* Class request */
+    case USB_REQ_TYPE_CLASS:
+      switch (req->bRequest)
+      {
+        case BOT_GET_MAX_LUN:
+          if ((req->wValue  == 0U) && (req->wLength == 1U) &&
+              ((req->bmRequest & 0x80U) == 0x80U))
+          {
+            if (msc_storage != NULL) {
+              hmsc->max_lun = (uint32_t)msc_storage->GetMaxLun();
+              USBD_CtlSendData(pdev, (uint8_t *)(void *)&hmsc->max_lun, 1U);
+            }
+            else {
+              ret = USBD_FAIL;
+            }
+          }
+          else
+          {
+            USBD_CtlError(pdev, req);
+            ret = USBD_FAIL;
+          }
+          break;
+
+        case BOT_RESET :
+          if ((req->wValue  == 0U) && (req->wLength == 0U) &&
+              ((req->bmRequest & 0x80U) != 0x80U))
+          {
+            MSC_BOT_Reset(pdev);
+          }
+          else
+          {
+            USBD_CtlError(pdev, req);
+            ret = USBD_FAIL;
+          }
+          break;
+
+        default:
+          USBD_CtlError(pdev, req);
+          ret = USBD_FAIL;
+          break;
+      }
+      break;
+    /* Interface & Endpoint request */
+    case USB_REQ_TYPE_STANDARD:
+      switch (req->bRequest)
+      {
+        case USB_REQ_GET_STATUS:
+          if (pdev->dev_state == USBD_STATE_CONFIGURED)
+          {
+            USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U);
+          }
+          else
+          {
+            USBD_CtlError(pdev, req);
+            ret = USBD_FAIL;
+          }
+          break;
+
+        case USB_REQ_GET_INTERFACE:
+          if (pdev->dev_state == USBD_STATE_CONFIGURED)
+          {
+            USBD_CtlSendData(pdev, (uint8_t *)(void *)&hmsc->interface, 1U);
+          }
+          else
+          {
+            USBD_CtlError(pdev, req);
+            ret = USBD_FAIL;
+          }
+          break;
+
+        case USB_REQ_SET_INTERFACE:
+          if (pdev->dev_state == USBD_STATE_CONFIGURED)
+          {
+            hmsc->interface = (uint8_t)(req->wValue);
+          }
+          else
+          {
+            USBD_CtlError(pdev, req);
+            ret = USBD_FAIL;
+          }
+          break;
+
+        case USB_REQ_CLEAR_FEATURE:
+
+          /* Flush the FIFO and Clear the stall status */
+          USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
+
+          /* Reactivate the EP */
+          USBD_LL_CloseEP(pdev, (uint8_t)req->wIndex);
+          if ((((uint8_t)req->wIndex) & 0x80U) == 0x80U)
+          {
+            pdev->ep_in[(uint8_t)req->wIndex & 0xFU].is_used = 0U;
+            if (pdev->dev_speed == USBD_SPEED_HIGH)
+            {
+              /* Open EP IN */
+              USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK,
+                             MSC_MAX_HS_PACKET);
+            }
+            else
+            {
+              /* Open EP IN */
+              USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK,
+                             MSC_MAX_FS_PACKET);
+            }
+            pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
+          }
+          else
+          {
+            pdev->ep_out[(uint8_t)req->wIndex & 0xFU].is_used = 0U;
+            if (pdev->dev_speed == USBD_SPEED_HIGH)
+            {
+              /* Open EP OUT */
+              USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK,
+                             MSC_MAX_HS_PACKET);
+            }
+            else
+            {
+              /* Open EP OUT */
+              USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK,
+                             MSC_MAX_FS_PACKET);
+            }
+            pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
+          }
+
+          /* Handle BOT error */
+          MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
+          break;
+
+        default:
+          USBD_CtlError(pdev, req);
+          ret = USBD_FAIL;
+          break;
+      }
+      break;
+
+    default:
+      USBD_CtlError(pdev, req);
+      ret = USBD_FAIL;
+      break;
+  }
+
+  return ret;
+}
+
+/**
+* @brief  USBD_MSC_DataIn
+*         handle data IN Stage
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval status
+*/
+uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+  MSC_BOT_DataIn(pdev, epnum);
+
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_MSC_DataOut
+*         handle data OUT Stage
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval status
+*/
+uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+{
+  MSC_BOT_DataOut(pdev, epnum);
+
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_MSC_GetHSCfgDesc
+*         return configuration descriptor
+* @param  length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length)
+{
+  *length = sizeof(USBD_MSC_CfgHSDesc);
+
+  return USBD_MSC_CfgHSDesc;
+}
+
+/**
+* @brief  USBD_MSC_GetFSCfgDesc
+*         return configuration descriptor
+* @param  length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length)
+{
+  *length = sizeof(USBD_MSC_CfgFSDesc);
+
+  return USBD_MSC_CfgFSDesc;
+}
+
+/**
+* @brief  USBD_MSC_GetOtherSpeedCfgDesc
+*         return other speed configuration descriptor
+* @param  length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length)
+{
+  *length = sizeof(USBD_MSC_OtherSpeedCfgDesc);
+
+  return USBD_MSC_OtherSpeedCfgDesc;
+}
+/**
+* @brief  DeviceQualifierDescriptor
+*         return Device Qualifier descriptor
+* @param  length : pointer data length
+* @retval pointer to descriptor buffer
+*/
+uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length)
+{
+  *length = sizeof(USBD_MSC_DeviceQualifierDesc);
+
+  return USBD_MSC_DeviceQualifierDesc;
+}
+
+/**
+* @brief  USBD_MSC_RegisterStorage
+* @param  fops: storage callback
+* @retval status
+*/
+uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev,
+                                 USBD_StorageTypeDef *fops)
+{
+  msc_storage = fops;
+
+  return USBD_OK;
+}
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.h b/cores/arduino/stm32/usb/msc/usbd_msc.h
new file mode 100644
index 0000000000..35c234068b
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.h
@@ -0,0 +1,133 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc.h
+  * @author  MCD Application Team
+  * @brief   Header for the usbd_msc.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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_MSC_H
+#define __USBD_MSC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include  "usbd_msc_bot.h"
+#include  "usbd_msc_scsi.h"
+#include  "usbd_ioreq.h"
+
+/** @addtogroup USBD_MSC_BOT
+  * @{
+  */
+
+/** @defgroup USBD_MSC
+  * @brief This file is the Header file for usbd_msc.c
+  * @{
+  */
+
+
+/** @defgroup USBD_BOT_Exported_Defines
+  * @{
+  */
+/* MSC Class Config */
+#ifndef MSC_MEDIA_PACKET
+#define MSC_MEDIA_PACKET             512U
+#endif /* MSC_MEDIA_PACKET */
+
+#define MSC_MAX_FS_PACKET            0x40U
+#define MSC_MAX_HS_PACKET            0x200U
+
+#define BOT_GET_MAX_LUN              0xFE
+#define BOT_RESET                    0xFF
+#define USB_MSC_CONFIG_DESC_SIZ      32
+
+
+#define MSC_EPIN_ADDR                0x81U
+#define MSC_EPOUT_ADDR               0x01U
+
+/**
+  * @}
+  */
+
+/** @defgroup USB_CORE_Exported_Types
+  * @{
+  */
+typedef struct _USBD_STORAGE
+{
+  int8_t (* Init)(uint8_t lun);
+  int8_t (* GetCapacity)(uint8_t lun, uint32_t *block_num, uint16_t *block_size);
+  int8_t (* IsReady)(uint8_t lun);
+  int8_t (* IsWriteProtected)(uint8_t lun);
+  int8_t (* Read)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
+  int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
+  int8_t (* GetMaxLun)(void);
+  int8_t *pInquiry;
+
+} USBD_StorageTypeDef;
+
+
+typedef struct
+{
+  uint32_t                 max_lun;
+  uint32_t                 interface;
+  uint8_t                  bot_state;
+  uint8_t                  bot_status;
+  uint16_t                 bot_data_length;
+  uint8_t                  bot_data[MSC_MEDIA_PACKET];
+  USBD_MSC_BOT_CBWTypeDef  cbw;
+  USBD_MSC_BOT_CSWTypeDef  csw;
+
+  USBD_SCSI_SenseTypeDef   scsi_sense [SENSE_LIST_DEEPTH];
+  uint8_t                  scsi_sense_head;
+  uint8_t                  scsi_sense_tail;
+
+  uint16_t                 scsi_blk_size;
+  uint32_t                 scsi_blk_nbr;
+
+  uint32_t                 scsi_blk_addr;
+  uint32_t                 scsi_blk_len;
+}
+USBD_MSC_BOT_HandleTypeDef;
+
+/* Structure for MSC process */
+extern USBD_ClassTypeDef  USBD_MSC;
+#define USBD_MSC_CLASS    &USBD_MSC
+
+/* Handle */
+extern USBD_MSC_BOT_HandleTypeDef *msc_handle;
+extern USBD_StorageTypeDef *msc_storage;
+
+uint8_t  USBD_MSC_RegisterStorage(USBD_HandleTypeDef   *pdev,
+                                  USBD_StorageTypeDef *fops);
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __USBD_MSC_H */
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_bot.c b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
new file mode 100644
index 0000000000..fe8f840b11
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
@@ -0,0 +1,387 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc_bot.c
+  * @author  MCD Application Team
+  * @brief   This file provides all the BOT protocol core functions.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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"
+- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_bot.h"
+#include "usbd_msc.h"
+#include "usbd_msc_scsi.h"
+#include "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup MSC_BOT
+  * @brief BOT protocol module
+  * @{
+  */
+
+/** @defgroup MSC_BOT_Private_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_BOT_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_BOT_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_BOT_Private_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_BOT_Private_FunctionPrototypes
+  * @{
+  */
+static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef  *pdev);
+static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
+                             uint16_t len);
+
+static void MSC_BOT_Abort(USBD_HandleTypeDef  *pdev);
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_BOT_Private_Functions
+  * @{
+  */
+
+
+
+/**
+* @brief  MSC_BOT_Init
+*         Initialize the BOT Process
+* @param  pdev: device instance
+* @retval None
+*/
+void MSC_BOT_Init(USBD_HandleTypeDef  *pdev)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  hmsc->bot_state = USBD_BOT_IDLE;
+  hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
+
+  hmsc->scsi_sense_tail = 0U;
+  hmsc->scsi_sense_head = 0U;
+
+  msc_storage->Init(0U);
+
+  USBD_LL_FlushEP(pdev, MSC_EPOUT_ADDR);
+  USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR);
+
+  /* Prapare EP to Receive First BOT Cmd */
+  USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw,
+                         USBD_BOT_CBW_LENGTH);
+}
+
+/**
+* @brief  MSC_BOT_Reset
+*         Reset the BOT Machine
+* @param  pdev: device instance
+* @retval  None
+*/
+void MSC_BOT_Reset(USBD_HandleTypeDef  *pdev)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  hmsc->bot_state  = USBD_BOT_IDLE;
+  hmsc->bot_status = USBD_BOT_STATUS_RECOVERY;
+
+  /* Prapare EP to Receive First BOT Cmd */
+  USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw,
+                         USBD_BOT_CBW_LENGTH);
+}
+
+/**
+* @brief  MSC_BOT_DeInit
+*         Deinitialize the BOT Machine
+* @param  pdev: device instance
+* @retval None
+*/
+void MSC_BOT_DeInit(USBD_HandleTypeDef  *pdev)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+  hmsc->bot_state = USBD_BOT_IDLE;
+}
+
+/**
+* @brief  MSC_BOT_DataIn
+*         Handle BOT IN data stage
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval None
+*/
+void MSC_BOT_DataIn(USBD_HandleTypeDef  *pdev,
+                    uint8_t epnum)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  switch (hmsc->bot_state)
+  {
+    case USBD_BOT_DATA_IN:
+      if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0)
+      {
+        MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
+      }
+      break;
+
+    case USBD_BOT_SEND_DATA:
+    case USBD_BOT_LAST_DATA_IN:
+      MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
+      break;
+
+    default:
+      break;
+  }
+}
+/**
+* @brief  MSC_BOT_DataOut
+*         Process MSC OUT data
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval None
+*/
+void MSC_BOT_DataOut(USBD_HandleTypeDef  *pdev,
+                     uint8_t epnum)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  switch (hmsc->bot_state)
+  {
+    case USBD_BOT_IDLE:
+      MSC_BOT_CBW_Decode(pdev);
+      break;
+
+    case USBD_BOT_DATA_OUT:
+
+      if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0)
+      {
+        MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
+      }
+      break;
+
+    default:
+      break;
+  }
+}
+
+/**
+* @brief  MSC_BOT_CBW_Decode
+*         Decode the CBW command and set the BOT state machine accordingly
+* @param  pdev: device instance
+* @retval None
+*/
+static void  MSC_BOT_CBW_Decode(USBD_HandleTypeDef  *pdev)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  hmsc->csw.dTag = hmsc->cbw.dTag;
+  hmsc->csw.dDataResidue = hmsc->cbw.dDataLength;
+
+  if ((USBD_LL_GetRxDataSize(pdev, MSC_EPOUT_ADDR) != USBD_BOT_CBW_LENGTH) ||
+      (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) ||
+      (hmsc->cbw.bLUN > 1U) ||
+      (hmsc->cbw.bCBLength < 1U) || (hmsc->cbw.bCBLength > 16U))
+  {
+
+    SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+
+    hmsc->bot_status = USBD_BOT_STATUS_ERROR;
+    MSC_BOT_Abort(pdev);
+  }
+  else
+  {
+    if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0)
+    {
+      if (hmsc->bot_state == USBD_BOT_NO_DATA)
+      {
+        MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
+      }
+      else
+      {
+        MSC_BOT_Abort(pdev);
+      }
+    }
+    /*Burst xfer handled internally*/
+    else if ((hmsc->bot_state != USBD_BOT_DATA_IN) &&
+             (hmsc->bot_state != USBD_BOT_DATA_OUT) &&
+             (hmsc->bot_state != USBD_BOT_LAST_DATA_IN))
+    {
+      if (hmsc->bot_data_length > 0U)
+      {
+        MSC_BOT_SendData(pdev, hmsc->bot_data, hmsc->bot_data_length);
+      }
+      else if (hmsc->bot_data_length == 0U)
+      {
+        MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
+      }
+      else
+      {
+        MSC_BOT_Abort(pdev);
+      }
+    }
+    else
+    {
+      return;
+    }
+  }
+}
+
+/**
+* @brief  MSC_BOT_SendData
+*         Send the requested data
+* @param  pdev: device instance
+* @param  buf: pointer to data buffer
+* @param  len: Data Length
+* @retval None
+*/
+static void  MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
+                              uint16_t len)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  uint16_t length = (uint16_t)MIN(hmsc->cbw.dDataLength, len);
+
+  hmsc->csw.dDataResidue -= len;
+  hmsc->csw.bStatus = USBD_CSW_CMD_PASSED;
+  hmsc->bot_state = USBD_BOT_SEND_DATA;
+
+  USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, pbuf, length);
+}
+
+/**
+* @brief  MSC_BOT_SendCSW
+*         Send the Command Status Wrapper
+* @param  pdev: device instance
+* @param  status : CSW status
+* @retval None
+*/
+void  MSC_BOT_SendCSW(USBD_HandleTypeDef  *pdev,
+                      uint8_t CSW_Status)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  hmsc->csw.dSignature = USBD_BOT_CSW_SIGNATURE;
+  hmsc->csw.bStatus = CSW_Status;
+  hmsc->bot_state = USBD_BOT_IDLE;
+
+  USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, (uint8_t *)(void *)&hmsc->csw,
+                   USBD_BOT_CSW_LENGTH);
+
+  /* Prepare EP to Receive next Cmd */
+  USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw,
+                         USBD_BOT_CBW_LENGTH);
+}
+
+/**
+* @brief  MSC_BOT_Abort
+*         Abort the current transfer
+* @param  pdev: device instance
+* @retval status
+*/
+
+static void  MSC_BOT_Abort(USBD_HandleTypeDef  *pdev)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  if ((hmsc->cbw.bmFlags == 0U) &&
+      (hmsc->cbw.dDataLength != 0U) &&
+      (hmsc->bot_status == USBD_BOT_STATUS_NORMAL))
+  {
+    USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
+  }
+
+  USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
+
+  if (hmsc->bot_status == USBD_BOT_STATUS_ERROR)
+  {
+    USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw,
+                           USBD_BOT_CBW_LENGTH);
+  }
+}
+
+/**
+* @brief  MSC_BOT_CplClrFeature
+*         Complete the clear feature request
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval None
+*/
+
+void  MSC_BOT_CplClrFeature(USBD_HandleTypeDef  *pdev, uint8_t epnum)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) /* Bad CBW Signature */
+  {
+    USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
+    hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
+  }
+  else if (((epnum & 0x80U) == 0x80U) && (hmsc->bot_status != USBD_BOT_STATUS_RECOVERY))
+  {
+    MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
+  }
+  else
+  {
+    return;
+  }
+}
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_bot.h b/cores/arduino/stm32/usb/msc/usbd_msc_bot.h
new file mode 100644
index 0000000000..f5b1b6d42e
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_bot.h
@@ -0,0 +1,150 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc_bot.h
+  * @author  MCD Application Team
+  * @brief   Header for the usbd_msc_bot.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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_MSC_BOT_H
+#define __USBD_MSC_BOT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup MSC_BOT
+  * @brief This file is the Header file for usbd_msc_bot.c
+  * @{
+  */
+
+
+/** @defgroup USBD_CORE_Exported_Defines
+  * @{
+  */
+#define USBD_BOT_IDLE                      0U       /* Idle state */
+#define USBD_BOT_DATA_OUT                  1U       /* Data Out state */
+#define USBD_BOT_DATA_IN                   2U       /* Data In state */
+#define USBD_BOT_LAST_DATA_IN              3U       /* Last Data In Last */
+#define USBD_BOT_SEND_DATA                 4U       /* Send Immediate data */
+#define USBD_BOT_NO_DATA                   5U       /* No data Stage */
+
+#define USBD_BOT_CBW_SIGNATURE             0x43425355U
+#define USBD_BOT_CSW_SIGNATURE             0x53425355U
+#define USBD_BOT_CBW_LENGTH                31U
+#define USBD_BOT_CSW_LENGTH                13U
+#define USBD_BOT_MAX_DATA                  256U
+
+/* CSW Status Definitions */
+#define USBD_CSW_CMD_PASSED                0x00U
+#define USBD_CSW_CMD_FAILED                0x01U
+#define USBD_CSW_PHASE_ERROR               0x02U
+
+/* BOT Status */
+#define USBD_BOT_STATUS_NORMAL             0U
+#define USBD_BOT_STATUS_RECOVERY           1U
+#define USBD_BOT_STATUS_ERROR              2U
+
+
+#define USBD_DIR_IN                        0U
+#define USBD_DIR_OUT                       1U
+#define USBD_BOTH_DIR                      2U
+
+/**
+  * @}
+  */
+
+/** @defgroup MSC_CORE_Private_TypesDefinitions
+  * @{
+  */
+
+typedef struct
+{
+  uint32_t dSignature;
+  uint32_t dTag;
+  uint32_t dDataLength;
+  uint8_t  bmFlags;
+  uint8_t  bLUN;
+  uint8_t  bCBLength;
+  uint8_t  CB[16];
+  uint8_t  ReservedForAlign;
+}
+USBD_MSC_BOT_CBWTypeDef;
+
+
+typedef struct
+{
+  uint32_t dSignature;
+  uint32_t dTag;
+  uint32_t dDataResidue;
+  uint8_t  bStatus;
+  uint8_t  ReservedForAlign[3];
+}
+USBD_MSC_BOT_CSWTypeDef;
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_CORE_Exported_Types
+  * @{
+  */
+
+/**
+  * @}
+  */
+/** @defgroup USBD_CORE_Exported_FunctionsPrototypes
+  * @{
+  */
+void MSC_BOT_Init(USBD_HandleTypeDef  *pdev);
+void MSC_BOT_Reset(USBD_HandleTypeDef  *pdev);
+void MSC_BOT_DeInit(USBD_HandleTypeDef  *pdev);
+void MSC_BOT_DataIn(USBD_HandleTypeDef  *pdev,
+                    uint8_t epnum);
+
+void MSC_BOT_DataOut(USBD_HandleTypeDef  *pdev,
+                     uint8_t epnum);
+
+void MSC_BOT_SendCSW(USBD_HandleTypeDef  *pdev,
+                     uint8_t CSW_Status);
+
+void  MSC_BOT_CplClrFeature(USBD_HandleTypeDef  *pdev,
+                            uint8_t epnum);
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_MSC_BOT_H */
+/**
+  * @}
+  */
+
+/**
+* @}
+*/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.c b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
new file mode 100644
index 0000000000..aaafc3aa1e
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
@@ -0,0 +1,135 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc_data.c
+  * @author  MCD Application Team
+  * @brief   This file provides all the vital inquiry pages and sense data.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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"
+- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_data.h"
+
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup MSC_DATA
+  * @brief Mass storage info/data module
+  * @{
+  */
+
+/** @defgroup MSC_DATA_Private_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_DATA_Private_Defines
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_DATA_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_DATA_Private_Variables
+  * @{
+  */
+
+
+/* USB Mass storage Page 0 Inquiry Data */
+const uint8_t  MSC_Page00_Inquiry_Data[] =
+{
+  0x00,
+  0x00,
+  0x00,
+  (LENGTH_INQUIRY_PAGE00 - 4U),
+  0x00,
+  0x80,
+  0x83
+};
+/* USB Mass storage sense 6  Data */
+const uint8_t  MSC_Mode_Sense6_data[] =
+{
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+/* USB Mass storage sense 10  Data */
+const uint8_t  MSC_Mode_Sense10_data[] =
+{
+  0x00,
+  0x06,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00
+};
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_DATA_Private_FunctionPrototypes
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_DATA_Private_Functions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.h b/cores/arduino/stm32/usb/msc/usbd_msc_data.h
new file mode 100644
index 0000000000..79dafbd67f
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.h
@@ -0,0 +1,103 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc_data.h
+  * @author  MCD Application Team
+  * @brief   Header for the usbd_msc_data.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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_MSC_DATA_H
+#define __USBD_MSC_DATA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_conf.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup USB_INFO
+  * @brief general defines for the usb device library file
+  * @{
+  */
+
+/** @defgroup USB_INFO_Exported_Defines
+  * @{
+  */
+#define MODE_SENSE6_LEN                    8U
+#define MODE_SENSE10_LEN                   8U
+#define LENGTH_INQUIRY_PAGE00              7U
+#define LENGTH_FORMAT_CAPACITIES           20U
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_INFO_Exported_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+
+/** @defgroup USBD_INFO_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_INFO_Exported_Variables
+  * @{
+  */
+extern const uint8_t MSC_Page00_Inquiry_Data[];
+extern const uint8_t MSC_Mode_Sense6_data[];
+extern const uint8_t MSC_Mode_Sense10_data[] ;
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_INFO_Exported_FunctionsPrototype
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_MSC_DATA_H */
+
+/**
+  * @}
+  */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
new file mode 100644
index 0000000000..3c98584244
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -0,0 +1,716 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc_scsi.c
+  * @author  MCD Application Team
+  * @brief   This file provides all the USBD SCSI layer functions.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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"
+- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_bot.h"
+#include "usbd_msc_scsi.h"
+#include "usbd_msc.h"
+#include "usbd_msc_data.h"
+
+
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup MSC_SCSI
+  * @brief Mass storage SCSI layer module
+  * @{
+  */
+
+/** @defgroup MSC_SCSI_Private_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_SCSI_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_SCSI_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_SCSI_Private_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_SCSI_Private_FunctionPrototypes
+  * @{
+  */
+static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
+                                     uint32_t blk_offset, uint32_t blk_nbr);
+
+static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun);
+static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun);
+/**
+  * @}
+  */
+
+
+/** @defgroup MSC_SCSI_Private_Functions
+  * @{
+  */
+
+
+/**
+* @brief  SCSI_ProcessCmd
+*         Process SCSI commands
+* @param  pdev: device instance
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
+{
+  switch (cmd[0])
+  {
+    case SCSI_TEST_UNIT_READY:
+      SCSI_TestUnitReady(pdev, lun, cmd);
+      break;
+
+    case SCSI_REQUEST_SENSE:
+      SCSI_RequestSense(pdev, lun, cmd);
+      break;
+    case SCSI_INQUIRY:
+      SCSI_Inquiry(pdev, lun, cmd);
+      break;
+
+    case SCSI_START_STOP_UNIT:
+      SCSI_StartStopUnit(pdev, lun, cmd);
+      break;
+
+    case SCSI_ALLOW_MEDIUM_REMOVAL:
+      SCSI_StartStopUnit(pdev, lun, cmd);
+      break;
+
+    case SCSI_MODE_SENSE6:
+      SCSI_ModeSense6(pdev, lun, cmd);
+      break;
+
+    case SCSI_MODE_SENSE10:
+      SCSI_ModeSense10(pdev, lun, cmd);
+      break;
+
+    case SCSI_READ_FORMAT_CAPACITIES:
+      SCSI_ReadFormatCapacity(pdev, lun, cmd);
+      break;
+
+    case SCSI_READ_CAPACITY10:
+      SCSI_ReadCapacity10(pdev, lun, cmd);
+      break;
+
+    case SCSI_READ10:
+      SCSI_Read10(pdev, lun, cmd);
+      break;
+
+    case SCSI_WRITE10:
+      SCSI_Write10(pdev, lun, cmd);
+      break;
+
+    case SCSI_VERIFY10:
+      SCSI_Verify10(pdev, lun, cmd);
+      break;
+
+    default:
+      SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+  }
+
+  return 0;
+}
+
+
+/**
+* @brief  SCSI_TestUnitReady
+*         Process SCSI Test Unit Ready Command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+{
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  /* case 9 : Hi > D0 */
+  if (hmsc->cbw.dDataLength != 0U)
+  {
+    SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+
+    return -1;
+  }
+
+  if (msc_storage->IsReady(lun) != 0)
+  {
+    SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+    hmsc->bot_state = USBD_BOT_NO_DATA;
+
+    return -1;
+  }
+  hmsc->bot_data_length = 0U;
+
+  return 0;
+}
+
+/**
+* @brief  SCSI_Inquiry
+*         Process Inquiry command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t  SCSI_Inquiry(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+{
+  uint8_t *pPage;
+  uint16_t len;
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  if (params[1] & 0x01U)/*Evpd is set*/
+  {
+    len = LENGTH_INQUIRY_PAGE00;
+    hmsc->bot_data_length = len;
+
+    while (len)
+    {
+      len--;
+      hmsc->bot_data[len] = MSC_Page00_Inquiry_Data[len];
+    }
+  }
+  else
+  {
+    pPage = (uint8_t *)(void *) & msc_storage->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN];
+    len = (uint16_t)pPage[4] + 5U;
+
+    if (params[4] <= len)
+    {
+      len = params[4];
+    }
+    hmsc->bot_data_length = len;
+
+    while (len)
+    {
+      len--;
+      hmsc->bot_data[len] = pPage[len];
+    }
+  }
+
+  return 0;
+}
+
+/**
+* @brief  SCSI_ReadCapacity10
+*         Process Read Capacity 10 command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+{
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  if (msc_storage->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size) != 0)
+  {
+    SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+    return -1;
+  }
+  else
+  {
+
+    hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24);
+    hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16);
+    hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >>  8);
+    hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1U);
+
+    hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >>  24);
+    hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >>  16);
+    hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >>  8);
+    hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size);
+
+    hmsc->bot_data_length = 8U;
+    return 0;
+  }
+}
+/**
+* @brief  SCSI_ReadFormatCapacity
+*         Process Read Format Capacity command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+{
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  uint16_t blk_size;
+  uint32_t blk_nbr;
+  uint16_t i;
+
+  for (i = 0U; i < 12U ; i++)
+  {
+    hmsc->bot_data[i] = 0U;
+  }
+
+  if (msc_storage->GetCapacity(lun, &blk_nbr, &blk_size) != 0U)
+  {
+    SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+    return -1;
+  }
+  else
+  {
+    hmsc->bot_data[3] = 0x08U;
+    hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1U) >> 24);
+    hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1U) >> 16);
+    hmsc->bot_data[6] = (uint8_t)((blk_nbr - 1U) >>  8);
+    hmsc->bot_data[7] = (uint8_t)(blk_nbr - 1U);
+
+    hmsc->bot_data[8] = 0x02U;
+    hmsc->bot_data[9] = (uint8_t)(blk_size >>  16);
+    hmsc->bot_data[10] = (uint8_t)(blk_size >>  8);
+    hmsc->bot_data[11] = (uint8_t)(blk_size);
+
+    hmsc->bot_data_length = 12U;
+    return 0;
+  }
+}
+/**
+* @brief  SCSI_ModeSense6
+*         Process Mode Sense6 command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ModeSense6(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+{
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+  uint16_t len = 8U;
+  hmsc->bot_data_length = len;
+
+  while (len)
+  {
+    len--;
+    hmsc->bot_data[len] = MSC_Mode_Sense6_data[len];
+  }
+  return 0;
+}
+
+/**
+* @brief  SCSI_ModeSense10
+*         Process Mode Sense10 command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ModeSense10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+{
+  uint16_t len = 8U;
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  hmsc->bot_data_length = len;
+
+  while (len)
+  {
+    len--;
+    hmsc->bot_data[len] = MSC_Mode_Sense10_data[len];
+  }
+
+  return 0;
+}
+
+/**
+* @brief  SCSI_RequestSense
+*         Process Request Sense command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+
+static int8_t SCSI_RequestSense(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+{
+  uint8_t i;
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  for (i = 0U ; i < REQUEST_SENSE_DATA_LEN; i++)
+  {
+    hmsc->bot_data[i] = 0U;
+  }
+
+  hmsc->bot_data[0] = 0x70U;
+  hmsc->bot_data[7] = REQUEST_SENSE_DATA_LEN - 6U;
+
+  if ((hmsc->scsi_sense_head != hmsc->scsi_sense_tail))
+  {
+
+    hmsc->bot_data[2]     = hmsc->scsi_sense[hmsc->scsi_sense_head].Skey;
+    hmsc->bot_data[12]    = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ;
+    hmsc->bot_data[13]    = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC;
+    hmsc->scsi_sense_head++;
+
+    if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH)
+    {
+      hmsc->scsi_sense_head = 0U;
+    }
+  }
+  hmsc->bot_data_length = REQUEST_SENSE_DATA_LEN;
+
+  if (params[4] <= REQUEST_SENSE_DATA_LEN)
+  {
+    hmsc->bot_data_length = params[4];
+  }
+  return 0;
+}
+
+/**
+* @brief  SCSI_SenseCode
+*         Load the last error code in the error list
+* @param  lun: Logical unit number
+* @param  sKey: Sense Key
+* @param  ASC: Additional Sense Key
+* @retval none
+
+*/
+void SCSI_SenseCode(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC)
+{
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey  = sKey;
+  hmsc->scsi_sense[hmsc->scsi_sense_tail].w.ASC = ASC << 8;
+  hmsc->scsi_sense_tail++;
+  if (hmsc->scsi_sense_tail == SENSE_LIST_DEEPTH)
+  {
+    hmsc->scsi_sense_tail = 0U;
+  }
+}
+/**
+* @brief  SCSI_StartStopUnit
+*         Process Start Stop Unit command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+{
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+  hmsc->bot_data_length = 0U;
+  return 0;
+}
+
+/**
+* @brief  SCSI_Read10
+*         Process Read10 command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
+  {
+    /* case 10 : Ho <> Di */
+    if ((hmsc->cbw.bmFlags & 0x80U) != 0x80U)
+    {
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+    }
+
+    if (msc_storage->IsReady(lun) != 0)
+    {
+      SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+      return -1;
+    }
+
+    hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
+                          ((uint32_t)params[3] << 16) |
+                          ((uint32_t)params[4] <<  8) |
+                          (uint32_t)params[5];
+
+    hmsc->scsi_blk_len = ((uint32_t)params[7] <<  8) | (uint32_t)params[8];
+
+    if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
+                               hmsc->scsi_blk_len) < 0)
+    {
+      return -1; /* error */
+    }
+
+    hmsc->bot_state = USBD_BOT_DATA_IN;
+
+    /* cases 4,5 : Hi <> Dn */
+    if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size))
+    {
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+    }
+  }
+  hmsc->bot_data_length = MSC_MEDIA_PACKET;
+
+  return SCSI_ProcessRead(pdev, lun);
+}
+
+/**
+* @brief  SCSI_Write10
+*         Process Write10 command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+
+static int8_t SCSI_Write10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+{
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+  uint32_t len;
+
+  if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
+  {
+    /* case 8 : Hi <> Do */
+    if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U)
+    {
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+    }
+
+    /* Check whether Media is ready */
+    if (msc_storage->IsReady(lun) != 0)
+    {
+      SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+      return -1;
+    }
+
+    /* Check If media is write-protected */
+    if (msc_storage->IsWriteProtected(lun) != 0)
+    {
+      SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
+      return -1;
+    }
+
+    hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
+                          ((uint32_t)params[3] << 16) |
+                          ((uint32_t)params[4] << 8) |
+                          (uint32_t)params[5];
+
+    hmsc->scsi_blk_len = ((uint32_t)params[7] << 8) |
+                         (uint32_t)params[8];
+
+    /* check if LBA address is in the right range */
+    if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
+                               hmsc->scsi_blk_len) < 0)
+    {
+      return -1; /* error */
+    }
+
+    len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+
+    /* cases 3,11,13 : Hn,Ho <> D0 */
+    if (hmsc->cbw.dDataLength != len)
+    {
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+    }
+
+    len = MIN(len, MSC_MEDIA_PACKET);
+
+    /* Prepare EP to receive first data packet */
+    hmsc->bot_state = USBD_BOT_DATA_OUT;
+    USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
+  }
+  else /* Write Process ongoing */
+  {
+    return SCSI_ProcessWrite(pdev, lun);
+  }
+  return 0;
+}
+
+
+/**
+* @brief  SCSI_Verify10
+*         Process Verify10 command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+
+static int8_t SCSI_Verify10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+{
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  if ((params[1] & 0x02U) == 0x02U)
+  {
+    SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+    return -1; /* Error, Verify Mode Not supported*/
+  }
+
+  if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
+                             hmsc->scsi_blk_len) < 0)
+  {
+    return -1; /* error */
+  }
+  hmsc->bot_data_length = 0U;
+  return 0;
+}
+
+/**
+* @brief  SCSI_CheckAddressRange
+*         Check address range
+* @param  lun: Logical unit number
+* @param  blk_offset: first block address
+* @param  blk_nbr: number of block to be processed
+* @retval status
+*/
+static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
+                                     uint32_t blk_offset, uint32_t blk_nbr)
+{
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr)
+  {
+    SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
+    return -1;
+  }
+  return 0;
+}
+
+/**
+* @brief  SCSI_ProcessRead
+*         Handle Read Process
+* @param  lun: Logical unit number
+* @retval status
+*/
+static int8_t SCSI_ProcessRead(USBD_HandleTypeDef  *pdev, uint8_t lun)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+  uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+
+  len = MIN(len, MSC_MEDIA_PACKET);
+
+  if (msc_storage->Read(lun,
+                        hmsc->bot_data,
+                        hmsc->scsi_blk_addr,
+                        (len / hmsc->scsi_blk_size)) < 0)
+  {
+    SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR);
+    return -1;
+  }
+
+  USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, hmsc->bot_data, len);
+
+  hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
+  hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
+
+  /* case 6 : Hi = Di */
+  hmsc->csw.dDataResidue -= len;
+
+  if (hmsc->scsi_blk_len == 0U)
+  {
+    hmsc->bot_state = USBD_BOT_LAST_DATA_IN;
+  }
+  return 0;
+}
+
+/**
+* @brief  SCSI_ProcessWrite
+*         Handle Write Process
+* @param  lun: Logical unit number
+* @retval status
+*/
+
+static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef  *pdev, uint8_t lun)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+  uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+
+  len = MIN(len, MSC_MEDIA_PACKET);
+
+  if (msc_storage->Write(lun, hmsc->bot_data,
+                         hmsc->scsi_blk_addr,
+                         (len / hmsc->scsi_blk_size)) < 0)
+  {
+    SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, WRITE_FAULT);
+
+    return -1;
+  }
+
+  hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
+  hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
+
+  /* case 12 : Ho = Do */
+  hmsc->csw.dDataResidue -= len;
+
+  if (hmsc->scsi_blk_len == 0U)
+  {
+    MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
+  }
+  else
+  {
+    len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET);
+    /* Prepare EP to Receive next packet */
+    USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
+  }
+
+  return 0;
+}
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
new file mode 100644
index 0000000000..1629d786c3
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
@@ -0,0 +1,192 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc_scsi.h
+  * @author  MCD Application Team
+  * @brief   Header for the usbd_msc_scsi.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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_MSC_SCSI_H
+#define __USBD_MSC_SCSI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_def.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup USBD_SCSI
+  * @brief header file for the storage disk file
+  * @{
+  */
+
+/** @defgroup USBD_SCSI_Exported_Defines
+  * @{
+  */
+
+#define SENSE_LIST_DEEPTH                           4U
+
+/* SCSI Commands */
+#define SCSI_FORMAT_UNIT                            0x04U
+#define SCSI_INQUIRY                                0x12U
+#define SCSI_MODE_SELECT6                           0x15U
+#define SCSI_MODE_SELECT10                          0x55U
+#define SCSI_MODE_SENSE6                            0x1AU
+#define SCSI_MODE_SENSE10                           0x5AU
+#define SCSI_ALLOW_MEDIUM_REMOVAL                   0x1EU
+#define SCSI_READ6                                  0x08U
+#define SCSI_READ10                                 0x28U
+#define SCSI_READ12                                 0xA8U
+#define SCSI_READ16                                 0x88U
+
+#define SCSI_READ_CAPACITY10                        0x25U
+#define SCSI_READ_CAPACITY16                        0x9EU
+
+#define SCSI_REQUEST_SENSE                          0x03U
+#define SCSI_START_STOP_UNIT                        0x1BU
+#define SCSI_TEST_UNIT_READY                        0x00U
+#define SCSI_WRITE6                                 0x0AU
+#define SCSI_WRITE10                                0x2AU
+#define SCSI_WRITE12                                0xAAU
+#define SCSI_WRITE16                                0x8AU
+
+#define SCSI_VERIFY10                               0x2FU
+#define SCSI_VERIFY12                               0xAFU
+#define SCSI_VERIFY16                               0x8FU
+
+#define SCSI_SEND_DIAGNOSTIC                        0x1DU
+#define SCSI_READ_FORMAT_CAPACITIES                 0x23U
+
+#define NO_SENSE                                    0U
+#define RECOVERED_ERROR                             1U
+#define NOT_READY                                   2U
+#define MEDIUM_ERROR                                3U
+#define HARDWARE_ERROR                              4U
+#define ILLEGAL_REQUEST                             5U
+#define UNIT_ATTENTION                              6U
+#define DATA_PROTECT                                7U
+#define BLANK_CHECK                                 8U
+#define VENDOR_SPECIFIC                             9U
+#define COPY_ABORTED                                10U
+#define ABORTED_COMMAND                             11U
+#define VOLUME_OVERFLOW                             13U
+#define MISCOMPARE                                  14U
+
+
+#define INVALID_CDB                                 0x20U
+#define INVALID_FIELED_IN_COMMAND                   0x24U
+#define PARAMETER_LIST_LENGTH_ERROR                 0x1AU
+#define INVALID_FIELD_IN_PARAMETER_LIST             0x26U
+#define ADDRESS_OUT_OF_RANGE                        0x21U
+#define MEDIUM_NOT_PRESENT                          0x3AU
+#define MEDIUM_HAVE_CHANGED                         0x28U
+#define WRITE_PROTECTED                             0x27U
+#define UNRECOVERED_READ_ERROR                      0x11U
+#define WRITE_FAULT                                 0x03U
+
+#define READ_FORMAT_CAPACITY_DATA_LEN               0x0CU
+#define READ_CAPACITY10_DATA_LEN                    0x08U
+#define MODE_SENSE10_DATA_LEN                       0x08U
+#define MODE_SENSE6_DATA_LEN                        0x04U
+#define REQUEST_SENSE_DATA_LEN                      0x12U
+#define STANDARD_INQUIRY_DATA_LEN                   0x24U
+#define BLKVFY                                      0x04U
+
+extern  uint8_t Page00_Inquiry_Data[];
+extern  uint8_t Standard_Inquiry_Data[];
+extern  uint8_t Standard_Inquiry_Data2[];
+extern  uint8_t Mode_Sense6_data[];
+extern  uint8_t Mode_Sense10_data[];
+extern  uint8_t Scsi_Sense_Data[];
+extern  uint8_t ReadCapacity10_Data[];
+extern  uint8_t ReadFormatCapacity_Data [];
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_SCSI_Exported_TypesDefinitions
+  * @{
+  */
+
+typedef struct _SENSE_ITEM
+{
+  char Skey;
+  union
+  {
+    struct _ASCs
+    {
+      char ASC;
+      char ASCQ;
+    } b;
+    uint8_t ASC;
+    char *pData;
+  } w;
+} USBD_SCSI_SenseTypeDef;
+/**
+  * @}
+  */
+
+/** @defgroup USBD_SCSI_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_SCSI_Exported_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+/** @defgroup USBD_SCSI_Exported_FunctionsPrototype
+  * @{
+  */
+int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd);
+
+void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey,
+                    uint8_t ASC);
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_MSC_SCSI_H */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+

From db11e1b27f1f006a2c226a51bd935507581327c2 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Fri, 29 May 2020 14:26:38 +0100
Subject: [PATCH 02/37] added endpoint configuration

---
 cores/arduino/stm32/usb/cdc/usbd_cdc.c | 180 +++++++++++++------------
 1 file changed, 91 insertions(+), 89 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index 9ee0d7885a..219efa06f7 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -51,18 +51,17 @@
   */
 
 #ifdef USBCON
-#ifdef USBD_USE_CDC
 
 /* Includes ------------------------------------------------------------------*/
 #include "usbd_cdc.h"
 #include "usbd_ctlreq.h"
 
+#ifdef USBD_USE_CDC_CLASS
 
 /** @addtogroup STM32_USB_DEVICE_LIBRARY
   * @{
   */
 
-
 /** @defgroup USBD_CDC
   * @brief usbd core module
   * @{
@@ -75,7 +74,6 @@
   * @}
   */
 
-
 /** @defgroup USBD_CDC_Private_Defines
   * @{
   */
@@ -83,7 +81,6 @@
   * @}
   */
 
-
 /** @defgroup USBD_CDC_Private_Macros
   * @{
   */
@@ -92,22 +89,35 @@
   * @}
   */
 
-
 /** @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_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);
+
 uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
 
 /* USB Standard Device Descriptor */
@@ -402,6 +412,15 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ]
   0x00                                  /* bInterval */
 };
 
+
+
+USBD_CDC_HandleTypeDef cdc_handle_dat;
+USBD_CDC_HandleTypeDef *cdc_handle = &cdc_handle_dat;
+
+USBD_CDC_ItfTypeDef *cdc_itf = NULL; /* TODO */
+
+
+
 /**
   * @}
   */
@@ -420,7 +439,8 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ]
 static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 {
   UNUSED(cfgidx);
-  USBD_CDC_HandleTypeDef   *hcdc;
+
+  USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
   hcdc = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
 
@@ -468,7 +488,7 @@ static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
   pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U;
 
   /* Init  physical Interface components */
-  ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
+  cdc_itf->Init();
 
   /* Init Xfer states */
   hcdc->TxState = 0U;
@@ -476,15 +496,15 @@ static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 
   if (pdev->dev_speed == USBD_SPEED_HIGH) {
     /* Prepare Out endpoint to receive next packet */
-    (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
-                                 CDC_DATA_HS_OUT_PACKET_SIZE);
+    USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
+                            CDC_DATA_HS_OUT_PACKET_SIZE);
   } else {
     /* Prepare Out endpoint to receive next packet */
-    (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
-                                 CDC_DATA_FS_OUT_PACKET_SIZE);
+    USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
+                            CDC_DATA_FS_OUT_PACKET_SIZE);
   }
 
-  return (uint8_t)USBD_OK;
+  return ret;
 }
 
 /**
@@ -513,11 +533,8 @@ static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
   pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = 0U;
 
   /* DeInit  physical Interface components */
-  if (pdev->pClassData != NULL) {
-    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
-    (void)USBD_free(pdev->pClassData);
-    pdev->pClassData = NULL;
-  }
+  /* TODO remove user data reference */
+  cdc_itf->DeInit();
 
   return ret;
 }
@@ -532,18 +549,18 @@ static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
                                USBD_SetupReqTypedef *req)
 {
-  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
+  USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
   uint8_t ifalt = 0U;
   uint16_t status_info = 0U;
   USBD_StatusTypeDef ret = USBD_OK;
 
   switch (req->bmRequest & USB_REQ_TYPE_MASK) {
-    case USB_REQ_TYPE_CLASS:
-      if (req->wLength != 0U) {
-        if ((req->bmRequest & 0x80U) != 0U) {
-          ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
-                                                            (uint8_t *)hcdc->data,
-                                                            req->wLength);
+    case USB_REQ_TYPE_CLASS :
+      if (req->wLength) {
+        if (req->bmRequest & 0x80U) {
+          cdc_itf->Control(req->bRequest,
+                           (uint8_t *)(void *)hcdc->data,
+                           req->wLength);
 
           (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, req->wLength);
         } else {
@@ -553,8 +570,8 @@ static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
           (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength);
         }
       } else {
-        ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
-                                                          (uint8_t *)req, 0U);
+        cdc_itf->Control(req->bRequest,
+                         (uint8_t *)(void *)req, 0U);
       }
       break;
 
@@ -613,26 +630,23 @@ static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
   */
 static uint8_t  USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
 {
-  USBD_CDC_HandleTypeDef *hcdc;
+  USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
   PCD_HandleTypeDef *hpcd = pdev->pData;
-
-  if (pdev->pClassData == NULL) {
-    return (uint8_t)USBD_FAIL;
-  }
-  hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
+  USBD_CDC_ItfTypeDef *ctrl = cdc_itf;
 
   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);
+    USBD_LL_Transmit(pdev, epnum, NULL, 0U);
   } else {
     hcdc->TxState = 0U;
-    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
+    if (ctrl->Transferred) {
+      ctrl->Transferred();
+    }
   }
-
-  return (uint8_t)USBD_OK;
+  return USBD_OK;
 }
 
 /**
@@ -644,21 +658,16 @@ static uint8_t  USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
   */
 static uint8_t  USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
 {
-  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
-
-  if (pdev->pClassData == NULL) {
-    return (uint8_t)USBD_FAIL;
-  }
+  USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
   /* 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 */
+  cdc_itf->Receive(hcdc->RxBuffer, &hcdc->RxLength);
 
-  ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
-
-  return (uint8_t)USBD_OK;
+  return USBD_OK;
 }
 
 /**
@@ -669,14 +678,13 @@ static uint8_t  USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
   */
 static uint8_t  USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
 {
-  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
+  USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
   if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) {
-    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
-                                                      (uint8_t *)hcdc->data,
-                                                      (uint16_t)hcdc->CmdLength);
+    cdc_itf->Control(hcdc->CmdOpCode,
+                     (uint8_t *)(void *)hcdc->data,
+                     (uint16_t)hcdc->CmdLength);
     hcdc->CmdOpCode = 0xFFU;
-
   }
 
   return (uint8_t)USBD_OK;
@@ -764,7 +772,7 @@ uint8_t  USBD_CDC_RegisterInterface(USBD_HandleTypeDef   *pdev,
 uint8_t  USBD_CDC_SetTxBuffer(USBD_HandleTypeDef   *pdev,
                               uint8_t  *pbuff, uint32_t length)
 {
-  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
+  USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
   hcdc->TxBuffer = pbuff;
   hcdc->TxLength = length;
@@ -781,7 +789,7 @@ uint8_t  USBD_CDC_SetTxBuffer(USBD_HandleTypeDef   *pdev,
   */
 uint8_t  USBD_CDC_SetRxBuffer(USBD_HandleTypeDef   *pdev, uint8_t  *pbuff)
 {
-  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
+  USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
   hcdc->RxBuffer = pbuff;
 
@@ -796,12 +804,7 @@ uint8_t  USBD_CDC_SetRxBuffer(USBD_HandleTypeDef   *pdev, uint8_t  *pbuff)
   */
 uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
 {
-  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
-  USBD_StatusTypeDef ret = USBD_BUSY;
-
-  if (pdev->pClassData == NULL) {
-    return (uint8_t)USBD_FAIL;
-  }
+  USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
   if (hcdc->TxState == 0U) {
     /* Tx Transfer in progress */
@@ -811,9 +814,12 @@ uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
     pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength;
 
     /* Transmit next packet */
-    (void)USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, hcdc->TxLength);
+    USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer,
+                      (uint16_t)hcdc->TxLength);
 
-    ret = USBD_OK;
+    return USBD_OK;
+  } else {
+    return USBD_BUSY;
   }
 
   return (uint8_t)ret;
@@ -828,37 +834,33 @@ uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
   */
 uint8_t  USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
 {
-  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
-
-  if (pdev->pClassData == NULL) {
-    return (uint8_t)USBD_FAIL;
-  }
+  USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
+  /* Suspend or Resume USB Out process */
   if (pdev->dev_speed == USBD_SPEED_HIGH) {
     /* Prepare Out endpoint to receive next packet */
-    (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
-                                 CDC_DATA_HS_OUT_PACKET_SIZE);
+    USBD_LL_PrepareReceive(pdev,
+                            CDC_OUT_EP,
+                            hcdc->RxBuffer,
+                            CDC_DATA_HS_OUT_PACKET_SIZE);
   } else {
     /* Prepare Out endpoint to receive next packet */
-    (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
-                                 CDC_DATA_FS_OUT_PACKET_SIZE);
+    USBD_LL_PrepareReceive(pdev,
+                            CDC_OUT_EP,
+                            hcdc->RxBuffer,
+                            CDC_DATA_FS_OUT_PACKET_SIZE);
   }
-
-  return (uint8_t)USBD_OK;
+  return USBD_OK;
 }
 
 uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev)
 {
   /* Suspend or Resume USB Out process */
-  if (pdev->pClassData != NULL) {
-    /* Prepare Out endpoint to receive next packet */
-    USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, 0, 0);
-    return (uint8_t)USBD_OK;
-  } else {
-    return (uint8_t)USBD_FAIL;
-  }
+  /* Prepare Out endpoint to receive next packet */
+  USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, 0, 0);
+  return USBD_OK;
 }
 
-#endif /* USBD_USE_CDC */
+#endif /* USBD_USE_CDC_CLASS */
 #endif /* USBCON */
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

From 1c247ede5ad9a731b3ef7766acc8f4f1dc911a79 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Fri, 29 May 2020 14:30:27 +0100
Subject: [PATCH 03/37] added endpoint define changes

---
 cores/arduino/stm32/usb/usbd_conf.h    | 13 +++++++
 cores/arduino/stm32/usb/usbd_ep_conf.h | 53 ++++++++++++++++++--------
 2 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/cores/arduino/stm32/usb/usbd_conf.h b/cores/arduino/stm32/usb/usbd_conf.h
index c1a4808380..db346747b0 100644
--- a/cores/arduino/stm32/usb/usbd_conf.h
+++ b/cores/arduino/stm32/usb/usbd_conf.h
@@ -40,6 +40,7 @@ extern "C" {
 #include <stdlib.h>
 #include <string.h>
 
+
 #if defined(USB_BASE)
 
 #if defined(STM32F1xx)
@@ -107,6 +108,18 @@ extern "C" {
 #define USB_BB_MAX_NUM_ALT_MODE             0x2U
 #endif /* USB_BB_MAX_NUM_ALT_MODE */
 
+
+/*  Endpoint Configuration */
+
+#define CDC_IN_EP                       0x81  /* EP1 for data IN */
+#define CDC_OUT_EP                      0x01  /* EP1 for data OUT */
+#define CDC_CMD_EP                      0x82  /* EP2 for CDC commands */
+
+#define MSC_IN_EP                       0x83 /* EP3 for Interrupt IN */
+#define MSC_OUT_EP                       0x02 /* EP3 for Interrupt IN */
+
+
+
 /* MSC Class Config */
 #ifndef MSC_MEDIA_PACKET
 #define MSC_MEDIA_PACKET                    8192U
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.h b/cores/arduino/stm32/usb/usbd_ep_conf.h
index 354b6f4d0c..f370164e00 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.h
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.h
@@ -36,6 +36,7 @@ typedef struct {
 
 /* CDC Endpoints Configurations */
 #ifdef USBD_USE_CDC
+  #define USBD_USE_CDC_CLASS
 
   #define CDC_OUT_EP                    0x01U  /* EP1 for data OUT */
   #define CDC_IN_EP                     0x82U  /* EP1 for data IN */
@@ -50,6 +51,25 @@ typedef struct {
 #endif /* USBD_USE_CDC */
 
 
+#ifdef USBD_USE_CDC_MSC_COMPOSITE
+  #define USBD_USE_CDC_CLASS
+  #define USBD_USE_MSC_CLASS
+
+  #define CDC_OUT_EP                    0x01U /*  EP1 for CDC data OUT */
+  #define CDC_IN_EP                     0x81U /*  EP1 for CDC data IN */
+  #define CDC_CMD_EP                    0x82U /*  EP2 for CDC commands */
+
+  #define MSC_OUT_EP                    0x02U /*  EP2 for MSC data IN */
+  #define MSC_IN_EP                     0x83U /*  EP3 for MSC data IN */
+
+  #define DEV_NUM_EP                    0x04U   /* Device Endpoints number including EP0 */
+
+  /* CDC Endpoints parameters*/
+  #define CDC_DATA_HS_MAX_PACKET_SIZE   USB_HS_MAX_PACKET_SIZE  /* Endpoint IN & OUT Packet size */
+  #define CDC_DATA_FS_MAX_PACKET_SIZE   USB_FS_MAX_PACKET_SIZE  /* Endpoint IN & OUT Packet size */
+  #define CDC_CMD_PACKET_SIZE                               8U  /* Control Endpoint Packet size */
+#endif
+
 /* HID composite (Mouse + Keyboard) Endpoints Configurations */
 #ifdef USBD_USE_HID_COMPOSITE
   #define HID_MOUSE_EPIN_ADDR           0x81U
@@ -61,23 +81,24 @@ typedef struct {
   #define DEV_NUM_EP                    0x03U   /* Device Endpoints number including EP0 */
 #endif /* USBD_USE_HID_COMPOSITE */
 
+
 /* Require DEV_NUM_EP to be defined */
 #if defined (USB)
-/* Size in words, byte size divided by 2 */
-#define PMA_EP0_OUT_ADDR    (8 * DEV_NUM_EP)
-#define PMA_EP0_IN_ADDR     (PMA_EP0_OUT_ADDR + USB_MAX_EP0_SIZE)
-
-#ifdef USBD_USE_CDC
-#define PMA_CDC_OUT_BASE    (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE)
-#define PMA_CDC_OUT_ADDR    ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \
-                            (PMA_CDC_OUT_BASE << 16U))
-#define PMA_CDC_IN_ADDR     (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2)
-#define PMA_CDC_CMD_ADDR    (PMA_CDC_IN_ADDR + CDC_CMD_PACKET_SIZE)
-#endif /* USBD_USE_CDC */
-#ifdef USBD_USE_HID_COMPOSITE
-  #define PMA_MOUSE_IN_ADDR   (PMA_EP0_IN_ADDR + HID_MOUSE_EPIN_SIZE)
-  #define PMA_KEYBOARD_IN_ADDR    (PMA_MOUSE_IN_ADDR + HID_KEYBOARD_EPIN_SIZE)
-#endif /* USBD_USE_HID_COMPOSITE */
+  /* Size in words, byte size divided by 2 */
+  #define PMA_EP0_OUT_ADDR    (8 * DEV_NUM_EP)
+  #define PMA_EP0_IN_ADDR     (PMA_EP0_OUT_ADDR + USB_MAX_EP0_SIZE)
+
+  #ifdef USBD_USE_CDC
+  #define PMA_CDC_OUT_BASE    (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE)
+  #define PMA_CDC_OUT_ADDR    ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \
+                              (PMA_CDC_OUT_BASE << 16U))
+  #define PMA_CDC_IN_ADDR     (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2)
+  #define PMA_CDC_CMD_ADDR    (PMA_CDC_IN_ADDR + CDC_CMD_PACKET_SIZE)
+  #endif /* USBD_USE_CDC */
+  #ifdef USBD_USE_HID_COMPOSITE
+    #define PMA_MOUSE_IN_ADDR   (PMA_EP0_IN_ADDR + HID_MOUSE_EPIN_SIZE)
+    #define PMA_KEYBOARD_IN_ADDR    (PMA_MOUSE_IN_ADDR + HID_KEYBOARD_EPIN_SIZE)
+  #endif /* USBD_USE_HID_COMPOSITE */
 #endif /* USB */
 
 extern const ep_desc_t ep_def[DEV_NUM_EP + 1];
@@ -86,4 +107,4 @@ extern const ep_desc_t ep_def[DEV_NUM_EP + 1];
 #endif /* USBCON */
 #endif /* __USBD_EP_CONF_H */
 
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\ No newline at end of file
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

From 0b9e38e9922283beae216c3ff8c42ebea00dc6a5 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Fri, 29 May 2020 14:57:39 +0100
Subject: [PATCH 04/37] added default msc interface

---
 cores/arduino/stm32/usb/msc/usbd_msc.c        |   3 +-
 .../stm32/usb/msc/usbd_msc_storage_if.c       | 177 ++++++++++++++++++
 .../stm32/usb/msc/usbd_msc_storage_if.h       |  97 ++++++++++
 3 files changed, 276 insertions(+), 1 deletion(-)
 create mode 100644 cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
 create mode 100644 cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h

diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.c b/cores/arduino/stm32/usb/msc/usbd_msc.c
index e196cefe46..f7e537d4cb 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.c
@@ -40,6 +40,7 @@ EndBSPDependencies */
 
 /* Includes ------------------------------------------------------------------*/
 #include "usbd_msc.h"
+#include "usbd_msc_storage_if.h"
 
 
 /** @addtogroup STM32_USB_DEVICE_LIBRARY
@@ -268,7 +269,7 @@ __ALIGN_BEGIN  uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]
 USBD_MSC_BOT_HandleTypeDef msc_handle_dat;
 USBD_MSC_BOT_HandleTypeDef *msc_handle = &msc_handle_dat;
 
-USBD_StorageTypeDef *msc_storage = NULL;
+USBD_StorageTypeDef *msc_storage = &USBD_MSC_Template_fops;
 
 /** @defgroup MSC_CORE_Private_Functions
   * @{
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
new file mode 100644
index 0000000000..dc6cc3dead
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
@@ -0,0 +1,177 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc_storage_template.c
+  * @author  MCD Application Team
+  * @brief   Memory management layer
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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"
+- "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
+EndBSPDependencies */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_storage_template.h"
+
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Extern function prototypes ------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+#define STORAGE_LUN_NBR                  1U
+#define STORAGE_BLK_NBR                  0x10000U
+#define STORAGE_BLK_SIZ                  0x200U
+
+int8_t STORAGE_Init(uint8_t lun);
+
+int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num,
+                           uint16_t *block_size);
+
+int8_t  STORAGE_IsReady(uint8_t lun);
+
+int8_t  STORAGE_IsWriteProtected(uint8_t lun);
+
+int8_t STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
+                    uint16_t blk_len);
+
+int8_t STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
+                     uint16_t blk_len);
+
+int8_t STORAGE_GetMaxLun(void);
+
+/* USB Mass storage Standard Inquiry Data */
+int8_t  STORAGE_Inquirydata[] =  /* 36 */
+{
+
+  /* LUN 0 */
+  0x00,
+  0x80,
+  0x02,
+  0x02,
+  (STANDARD_INQUIRY_DATA_LEN - 5),
+  0x00,
+  0x00,
+  0x00,
+  'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
+  'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product      : 16 Bytes */
+  ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+  '0', '.', '0', '1',                     /* Version      : 4 Bytes */
+};
+
+USBD_StorageTypeDef USBD_MSC_Template_fops =
+{
+  STORAGE_Init,
+  STORAGE_GetCapacity,
+  STORAGE_IsReady,
+  STORAGE_IsWriteProtected,
+  STORAGE_Read,
+  STORAGE_Write,
+  STORAGE_GetMaxLun,
+  STORAGE_Inquirydata,
+
+};
+/*******************************************************************************
+* Function Name  : Read_Memory
+* Description    : Handle the Read operation from the microSD card.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+int8_t STORAGE_Init(uint8_t lun)
+{
+  return (0);
+}
+
+/*******************************************************************************
+* Function Name  : Read_Memory
+* Description    : Handle the Read operation from the STORAGE card.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
+{
+  *block_num  = STORAGE_BLK_NBR;
+  *block_size = STORAGE_BLK_SIZ;
+  return (0);
+}
+
+/*******************************************************************************
+* Function Name  : Read_Memory
+* Description    : Handle the Read operation from the STORAGE card.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+int8_t  STORAGE_IsReady(uint8_t lun)
+{
+  return (0);
+}
+
+/*******************************************************************************
+* Function Name  : Read_Memory
+* Description    : Handle the Read operation from the STORAGE card.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+int8_t  STORAGE_IsWriteProtected(uint8_t lun)
+{
+  return  0;
+}
+
+/*******************************************************************************
+* Function Name  : Read_Memory
+* Description    : Handle the Read operation from the STORAGE card.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+int8_t STORAGE_Read(uint8_t lun, uint8_t *buf,
+                    uint32_t blk_addr, uint16_t blk_len)
+{
+  return 0;
+}
+/*******************************************************************************
+* Function Name  : Write_Memory
+* Description    : Handle the Write operation to the STORAGE card.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+int8_t STORAGE_Write(uint8_t lun, uint8_t *buf,
+                     uint32_t blk_addr, uint16_t blk_len)
+{
+  return (0);
+}
+/*******************************************************************************
+* Function Name  : Write_Memory
+* Description    : Handle the Write operation to the STORAGE card.
+* Input          : None.
+* Output         : None.
+* Return         : None.
+*******************************************************************************/
+int8_t STORAGE_GetMaxLun(void)
+{
+  return (STORAGE_LUN_NBR - 1);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h
new file mode 100644
index 0000000000..0288c308fc
--- /dev/null
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h
@@ -0,0 +1,97 @@
+/**
+  ******************************************************************************
+  * @file    usbd_msc_storage.h
+  * @author  MCD Application Team
+  * @brief   Header file for the usbd_msc_storage.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * 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_MSC_STORAGE_H
+#define __USBD_MSC_STORAGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc.h"
+
+/** @addtogroup STM32_USB_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup USBD_STORAGE
+  * @brief header file for the usbd_msc_storage.c file
+  * @{
+  */
+
+/** @defgroup USBD_STORAGE_Exported_Defines
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_STORAGE_Exported_Types
+  * @{
+  */
+
+
+/**
+  * @}
+  */
+
+
+
+/** @defgroup USBD_STORAGE_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_STORAGE_Exported_Variables
+  * @{
+  */
+extern USBD_StorageTypeDef  USBD_MSC_Template_fops;
+/**
+  * @}
+  */
+
+/** @defgroup USBD_STORAGE_Exported_FunctionsPrototype
+  * @{
+  */
+
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __USBD_MSC_STORAGE_H */
+
+/**
+  * @}
+  */
+
+/**
+* @}
+*/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

From 162ade3bae828a2f514a4668e80e048c1ab3a2ad Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Fri, 29 May 2020 15:29:33 +0100
Subject: [PATCH 05/37] fixed cdc handle nad renamed cdc msc flag

---
 cores/arduino/stm32/usb/cdc/usbd_cdc.c        |  7 ++-
 cores/arduino/stm32/usb/cdc/usbd_cdc.h        |  6 ++
 cores/arduino/stm32/usb/cdc/usbd_cdc_if.c     | 57 +++++--------------
 cores/arduino/stm32/usb/cdc/usbd_cdc_if.h     |  5 +-
 .../stm32/usb/cdc_msc/usbd_cdc_msc.cpp        |  2 +-
 .../arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h  |  2 +
 cores/arduino/stm32/usb/usbd_ep_conf.h        |  2 +-
 7 files changed, 32 insertions(+), 49 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index 219efa06f7..49ee9e2f7a 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -754,8 +754,11 @@ uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
 uint8_t  USBD_CDC_RegisterInterface(USBD_HandleTypeDef   *pdev,
                                     USBD_CDC_ItfTypeDef *fops)
 {
-  if (fops == NULL) {
-    return (uint8_t)USBD_FAIL;
+  uint8_t  ret = USBD_FAIL;
+
+  if (fops != NULL) {
+    cdc_itf = fops;
+    ret = USBD_OK;
   }
 
   pdev->pUserData = fops;
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.h b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
index 5395708c06..bfcbfab31d 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.h
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
@@ -126,8 +126,14 @@ typedef struct {
   * @{
   */
 
+
 extern USBD_ClassTypeDef  USBD_CDC;
 #define USBD_CDC_CLASS    &USBD_CDC
+
+extern USBD_CDC_HandleTypeDef *cdc_handle;
+
+extern USBD_CDC_ItfTypeDef *cdc_itf;
+
 /**
   * @}
   */
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
index c09675f95e..e5ee766c33 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
@@ -18,7 +18,10 @@
   */
 
 #ifdef USBCON
-#ifdef USBD_USE_CDC
+
+#include "usbd_ep_conf.h"
+
+#ifdef USBD_USE_CDC_CLASS
 
 /* Includes ------------------------------------------------------------------*/
 #include "usbd_desc.h"
@@ -44,9 +47,7 @@
 
 /* USBD_CDC Private Variables */
 /* USB Device Core CDC handle declaration */
-USBD_HandleTypeDef hUSBD_Device_CDC;
-
-static bool CDC_initialized = false;
+USBD_HandleTypeDef *hUSBD_Device_CDC;
 
 /* Received Data over USB are stored in this buffer       */
 CDC_TransmitQueue_TypeDef TransmitQueue;
@@ -98,7 +99,7 @@ static int8_t USBD_CDC_Init(void)
   CDC_TransmitQueue_Init(&TransmitQueue);
   CDC_ReceiveQueue_Init(&ReceiveQueue);
   receivePended = true;
-  USBD_CDC_SetRxBuffer(&hUSBD_Device_CDC, CDC_ReceiveQueue_ReserveBlock(&ReceiveQueue));
+  USBD_CDC_SetRxBuffer(hUSBD_Device_CDC, CDC_ReceiveQueue_ReserveBlock(&ReceiveQueue));
 
   return ((int8_t)USBD_OK);
 }
@@ -235,7 +236,7 @@ static int8_t USBD_CDC_Receive(uint8_t *Buf, uint32_t *Len)
   receivePended = false;
   /* If enough space in the queue for a full buffer then continue receive */
   if (!CDC_resume_receive()) {
-    USBD_CDC_ClearBuffer(&hUSBD_Device_CDC);
+    USBD_CDC_ClearBuffer(hUSBD_Device_CDC);
   }
   return ((int8_t)USBD_OK);
 }
@@ -264,34 +265,6 @@ static int8_t USBD_CDC_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
   return ((int8_t)USBD_OK);
 }
 
-void CDC_init(void)
-{
-  if (!CDC_initialized) {
-    /* Init Device Library */
-    if (USBD_Init(&hUSBD_Device_CDC, &USBD_Desc, 0) == USBD_OK) {
-      /* Add Supported Class */
-      if (USBD_RegisterClass(&hUSBD_Device_CDC, USBD_CDC_CLASS) == USBD_OK) {
-        /* Add CDC Interface Class */
-        if (USBD_CDC_RegisterInterface(&hUSBD_Device_CDC, &USBD_CDC_fops) == USBD_OK) {
-          /* Start Device Process */
-          USBD_Start(&hUSBD_Device_CDC);
-          CDC_initialized = true;
-        }
-      }
-    }
-  }
-}
-
-void CDC_deInit(void)
-{
-  if (CDC_initialized) {
-    USBD_Stop(&hUSBD_Device_CDC);
-    USBD_CDC_DeInit();
-    USBD_DeInit(&hUSBD_Device_CDC);
-    CDC_initialized = false;
-  }
-}
-
 bool CDC_connected()
 {
   /* Save the transmitStart value in a local variable to avoid twice reading - fix #478 */
@@ -299,16 +272,16 @@ bool CDC_connected()
   if (transmitTime) {
     transmitTime = HAL_GetTick() - transmitTime;
   }
-  return ((hUSBD_Device_CDC.dev_state == USBD_STATE_CONFIGURED)
-          && (transmitTime < USB_CDC_TRANSMIT_TIMEOUT)
-          && lineState);
+  return hUSBD_Device_CDC->dev_state == USBD_STATE_CONFIGURED
+         && transmitTime < USB_CDC_TRANSMIT_TIMEOUT
+         && lineState;
 }
 
 void CDC_continue_transmit(void)
 {
   uint16_t size;
   uint8_t *buffer;
-  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) hUSBD_Device_CDC.pClassData;
+  USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
   /*
    * TS: This method can be called both in the main thread
    * (via USBSerial::write) and in the IRQ stream (via USBD_CDC_TransmistCplt),
@@ -321,12 +294,12 @@ void CDC_continue_transmit(void)
     buffer = CDC_TransmitQueue_ReadBlock(&TransmitQueue, &size);
     if (size > 0) {
       transmitStart = HAL_GetTick();
-      USBD_CDC_SetTxBuffer(&hUSBD_Device_CDC, buffer, size);
+      USBD_CDC_SetTxBuffer(hUSBD_Device_CDC, buffer, size);
       /*
        * size never exceed PMA buffer and USBD_CDC_TransmitPacket make full
        * copy of block in PMA, so no need to worry about buffer damage
        */
-      USBD_CDC_TransmitPacket(&hUSBD_Device_CDC);
+      USBD_CDC_TransmitPacket(hUSBD_Device_CDC);
     }
   }
 }
@@ -342,8 +315,8 @@ bool CDC_resume_receive(void)
     if (block != NULL) {
       receivePended = true;
       /* Set new buffer */
-      USBD_CDC_SetRxBuffer(&hUSBD_Device_CDC, block);
-      USBD_CDC_ReceivePacket(&hUSBD_Device_CDC);
+      USBD_CDC_SetRxBuffer(hUSBD_Device_CDC, block);
+      USBD_CDC_ReceivePacket(hUSBD_Device_CDC);
       return true;
     }
   }
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.h b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.h
index b415ac16de..1f2e311471 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.h
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.h
@@ -22,7 +22,7 @@
 #define __USBD_CDC_IF_H
 
 #ifdef USBCON
-#ifdef USBD_USE_CDC
+#ifdef USBD_USE_CDC_CLASS
 
 #ifdef __cplusplus
 extern "C" {
@@ -39,6 +39,7 @@ extern "C" {
 /* Exported types ------------------------------------------------------------*/
 /* Exported constants --------------------------------------------------------*/
 
+extern USBD_HandleTypeDef *hUSBD_Device_CDC;
 extern USBD_CDC_ItfTypeDef  USBD_CDC_fops;
 extern CDC_TransmitQueue_TypeDef TransmitQueue;
 extern CDC_ReceiveQueue_TypeDef ReceiveQueue;
@@ -48,8 +49,6 @@ extern CDC_ReceiveQueue_TypeDef ReceiveQueue;
 /* Exported functions ------------------------------------------------------- */
 void CDC_continue_transmit(void);
 bool CDC_resume_receive(void);
-void CDC_init(void);
-void CDC_deInit(void);
 bool CDC_connected(void);
 
 #ifdef __cplusplus
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index 20a859a408..008381fbec 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -115,7 +115,7 @@ static uint8_t  USBD_COMPOSITE_SOF(USBD_HandleTypeDef *pdev);
   * @{
   */
 
-USBD_ClassTypeDef  USBD_COMPOSITE_ClassDriver =
+USBD_ClassTypeDef  USBD_CDC_MSC_CLASS =
 {
   USBD_COMPOSITE_Init,
   USBD_COMPOSITE_DeInit,
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
index 3d50cb967a..ae561f5d44 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
@@ -34,6 +34,8 @@
 
 #define USB_CDC_MSC_CONFIG_DESC_SIZ  (USB_CDC_CONFIG_DESC_SIZ - 9 + USB_MSC_CONFIG_DESC_SIZ)
 
+extern USBD_ClassTypeDef  USBD_CDC_MSC_CLASS;
+
 #endif  /* __USB_CDC_MSC_CORE_H_ */
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.h b/cores/arduino/stm32/usb/usbd_ep_conf.h
index f370164e00..5bd4f88d06 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.h
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.h
@@ -51,7 +51,7 @@ typedef struct {
 #endif /* USBD_USE_CDC */
 
 
-#ifdef USBD_USE_CDC_MSC_COMPOSITE
+#ifdef USBD_USE_CDC_MSC
   #define USBD_USE_CDC_CLASS
   #define USBD_USE_MSC_CLASS
 

From 8d7e9d80fe831027042a3b3adaee429b56a79ded Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Fri, 29 May 2020 15:29:55 +0100
Subject: [PATCH 06/37] added usb class

---
 cores/arduino/USB.cpp       | 72 +++++++++++++++++++++++++++++++++++++
 cores/arduino/USB.h         | 41 +++++++++++++++++++++
 cores/arduino/USBSerial.cpp |  6 ++--
 cores/arduino/USBSerial.h   |  5 +--
 4 files changed, 119 insertions(+), 5 deletions(-)
 create mode 100644 cores/arduino/USB.cpp
 create mode 100644 cores/arduino/USB.h

diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
new file mode 100644
index 0000000000..546be48787
--- /dev/null
+++ b/cores/arduino/USB.cpp
@@ -0,0 +1,72 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "USBSerial.h"
+
+#include "cdc/usbd_cdc.h"
+#include "cdc_msc/usbd_cdc_msc.h"
+#include "cdc/usbd_cdc_if.h"
+#include "usbd_desc.h"
+#include "wiring.h"
+
+void USB::begin() {
+  if (!initialized) initialize();
+}
+
+void USB::initialize() {
+  hUSBD_Device_CDC = &hUSBD_Device;
+
+  /* Init Device Library */
+  if (USBD_Init(&hUSBD_Device, &USBD_Desc, 0) == USBD_OK) {
+  #ifdef USBD_USE_CDC
+    /* Add Supported Class */
+    if (USBD_RegisterClass(&hUSBD_Device_CDC, USBD_CDC_CLASS) == USBD_OK) {
+      /* Add CDC Interface Class */
+      if (USBD_CDC_RegisterInterface(&hUSBD_Device_CDC, &USBD_CDC_fops) == USBD_OK) {
+        /* Start Device Process */
+        USBD_Start(&hUSBD_Device_CDC);
+        initialized = true;
+      }
+    }
+  #elif USBD_USE_CDC_MSC
+    /* Add Supported Class */
+    if (USBD_RegisterClass(&hUSBD_Device, USBD_CDC_MSC_CLASS) == USBD_OK) {
+      /* Add CDC Interface Class */
+      if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) == USBD_OK) {
+          /* Add MSC Interface Class */
+        if (USBD_MSC_RegisterStorage(&hUSBD_Device, &USBD_MSC_fops) == USBD_OK) {
+          /* Start Device Process */
+          USBD_Start(&hUSBD_Device);
+          initialized = true;
+        }
+      }
+    }
+  #endif
+  }
+}
+
+void USB::end() {
+  if (initialized) deinitialize();
+}
+
+void USB::deinitialize() {
+  USBD_Stop(&hUSBD_Device_CDC);
+  USBD_CDC_DeInit();
+  USBD_DeInit(&hUSBD_Device_CDC);
+  initialized = false;
+}
\ No newline at end of file
diff --git a/cores/arduino/USB.h b/cores/arduino/USB.h
new file mode 100644
index 0000000000..872a16c01e
--- /dev/null
+++ b/cores/arduino/USB.h
@@ -0,0 +1,41 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _USB_H_
+#define _USB_H_
+
+#if defined (USBCON)
+#include "Stream.h"
+#include "usbd_core.h"
+
+class USB {
+  public:
+    void begin(void);
+
+    void end(void);
+
+  protected:
+    void initialize();
+    void deinitialize();
+
+    bool initialized();
+    
+    USBD_HandleTypeDef hUSBD_Device;
+}
+
+#endif
\ No newline at end of file
diff --git a/cores/arduino/USBSerial.cpp b/cores/arduino/USBSerial.cpp
index 256b5a1df8..e729386b60 100644
--- a/cores/arduino/USBSerial.cpp
+++ b/cores/arduino/USBSerial.cpp
@@ -16,7 +16,7 @@
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
-#if defined (USBCON) && defined(USBD_USE_CDC)
+#if defined (USBCON) && defined(USBD_USE_CDC_CLASS)
 
 #include "USBSerial.h"
 #include "usbd_cdc.h"
@@ -31,7 +31,7 @@ void serialEventUSB() __attribute__((weak));
 
 void USBSerial::begin(void)
 {
-  CDC_init();
+  USB::begin();
 }
 
 void USBSerial::begin(uint32_t /* baud_count */)
@@ -48,7 +48,7 @@ void USBSerial::begin(uint32_t /* baud_count */, uint8_t /* config */)
 
 void USBSerial::end()
 {
-  CDC_deInit();
+  USB::end();
 }
 
 int USBSerial::availableForWrite()
diff --git a/cores/arduino/USBSerial.h b/cores/arduino/USBSerial.h
index 1628eef358..63e2263830 100644
--- a/cores/arduino/USBSerial.h
+++ b/cores/arduino/USBSerial.h
@@ -19,10 +19,11 @@
 #ifndef _USBSERIAL_H_
 #define _USBSERIAL_H_
 
-#if defined (USBCON) && defined(USBD_USE_CDC)
-#include "Stream.h"
 #include "usbd_core.h"
 
+#if defined (USBCON) && defined(USBD_USE_CDC_CLASS)
+#include "Stream.h"
+
 //================================================================================
 // Serial over CDC
 class USBSerial : public Stream {

From 4b489ef7ccebfc5878fc5e245dff141ca2e8b2f1 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Sat, 30 May 2020 14:18:17 +0100
Subject: [PATCH 07/37] add new include dirs

---
 platform.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/platform.txt b/platform.txt
index 3674dfe7d2..925aa620ea 100644
--- a/platform.txt
+++ b/platform.txt
@@ -9,7 +9,7 @@ version=1.0.0
 
 # STM compile variables
 # ----------------------
-compiler.stm.extra_include="-I{build.source.path}" "-I{build.core.path}/avr" "-I{build.core.path}/stm32" "-I{build.core.path}/stm32/LL" "-I{build.core.path}/stm32/usb" "-I{build.core.path}/stm32/OpenAMP" "-I{build.core.path}/stm32/usb/hid" "-I{build.core.path}/stm32/usb/cdc" "-I{build.system.path}/Drivers/{build.series}_HAL_Driver/Inc" "-I{build.system.path}/Drivers/{build.series}_HAL_Driver/Src" "-I{build.system.path}/{build.series}" "-I{build.system.path}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc" "-I{build.system.path}/Middlewares/ST/STM32_USB_Device_Library/Core/Src" {build.virtio_extra_include}
+compiler.stm.extra_include="-I{build.source.path}" "-I{build.core.path}/avr" "-I{build.core.path}/stm32" "-I{build.core.path}/stm32/LL" "-I{build.core.path}/stm32/usb" "-I{build.core.path}/stm32/OpenAMP" "-I{build.core.path}/stm32/usb/hid" "-I{build.core.path}/stm32/usb/cdc" "-I{build.core.path}/stm32/usb/msc" "-I{build.core.path}/stm32/usb/cdc_msc" "-I{build.system.path}/Drivers/{build.series}_HAL_Driver/Inc" "-I{build.system.path}/Drivers/{build.series}_HAL_Driver/Src" "-I{build.system.path}/{build.series}" "-I{build.system.path}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc" "-I{build.system.path}/Middlewares/ST/STM32_USB_Device_Library/Core/Src" {build.virtio_extra_include}
 
 compiler.warning_flags=-w
 compiler.warning_flags.none=-w

From a144bca45c37943600b1292cb6247f801348dabf Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Mon, 1 Jun 2020 11:29:25 +0100
Subject: [PATCH 08/37] formatting changes, improved usbd_ep_conf and now
 compiles in marlin

---
 cores/arduino/USB.cpp                         | 22 +++--
 cores/arduino/USB.h                           |  9 +-
 cores/arduino/USBSerial.cpp                   |  7 +-
 cores/arduino/USBSerial.h                     |  3 +-
 cores/arduino/stm32/usb/cdc/cdc_queue.c       |  4 +-
 cores/arduino/stm32/usb/cdc/usbd_cdc.c        |  4 +-
 cores/arduino/stm32/usb/cdc/usbd_cdc.h        |  1 -
 cores/arduino/stm32/usb/cdc/usbd_cdc_if.c     |  3 +-
 .../stm32/usb/cdc_msc/usbd_cdc_msc.cpp        | 84 ++---------------
 .../arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h  |  4 +-
 cores/arduino/stm32/usb/msc/usbd_msc.c        | 77 ++-------------
 cores/arduino/stm32/usb/msc/usbd_msc.h        | 29 ------
 cores/arduino/stm32/usb/msc/usbd_msc_bot.c    | 75 ++-------------
 cores/arduino/stm32/usb/msc/usbd_msc_bot.h    | 44 ---------
 cores/arduino/stm32/usb/msc/usbd_msc_data.c   | 74 ++-------------
 cores/arduino/stm32/usb/msc/usbd_msc_data.h   | 54 -----------
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c   | 75 ++-------------
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.h   | 55 -----------
 .../stm32/usb/msc/usbd_msc_storage_if.c       | 23 ++---
 .../stm32/usb/msc/usbd_msc_storage_if.h       | 61 +-----------
 cores/arduino/stm32/usb/usbd_conf.c           | 12 ++-
 cores/arduino/stm32/usb/usbd_conf.h           | 12 ---
 cores/arduino/stm32/usb/usbd_desc.c           | 10 +-
 cores/arduino/stm32/usb/usbd_ep_conf.c        | 94 +++++++++++--------
 cores/arduino/stm32/usb/usbd_ep_conf.h        | 22 ++++-
 tools/platformio-build.py                     |  4 +-
 26 files changed, 173 insertions(+), 689 deletions(-)

diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
index 546be48787..db54cf7138 100644
--- a/cores/arduino/USB.cpp
+++ b/cores/arduino/USB.cpp
@@ -16,14 +16,17 @@
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
-#include "USBSerial.h"
-
-#include "cdc/usbd_cdc.h"
-#include "cdc_msc/usbd_cdc_msc.h"
-#include "cdc/usbd_cdc_if.h"
+#include "usbd_cdc.h"
+#include "usbd_cdc_msc.h"
+#include "usbd_msc.h"
+#include "usbd_msc_storage_if.h"
+#include "usbd_cdc_if.h"
 #include "usbd_desc.h"
+#include "USB.h"
 #include "wiring.h"
 
+USB USBDevice;
+
 void USB::begin() {
   if (!initialized) initialize();
 }
@@ -35,7 +38,7 @@ void USB::initialize() {
   if (USBD_Init(&hUSBD_Device, &USBD_Desc, 0) == USBD_OK) {
   #ifdef USBD_USE_CDC
     /* Add Supported Class */
-    if (USBD_RegisterClass(&hUSBD_Device_CDC, USBD_CDC_CLASS) == USBD_OK) {
+    if (USBD_RegisterClass(&hUSBD_Device_CDC, &USBD_CDC) == USBD_OK) {
       /* Add CDC Interface Class */
       if (USBD_CDC_RegisterInterface(&hUSBD_Device_CDC, &USBD_CDC_fops) == USBD_OK) {
         /* Start Device Process */
@@ -45,7 +48,7 @@ void USB::initialize() {
     }
   #elif USBD_USE_CDC_MSC
     /* Add Supported Class */
-    if (USBD_RegisterClass(&hUSBD_Device, USBD_CDC_MSC_CLASS) == USBD_OK) {
+    if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC_MSC) == USBD_OK) {
       /* Add CDC Interface Class */
       if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) == USBD_OK) {
           /* Add MSC Interface Class */
@@ -65,8 +68,7 @@ void USB::end() {
 }
 
 void USB::deinitialize() {
-  USBD_Stop(&hUSBD_Device_CDC);
-  USBD_CDC_DeInit();
-  USBD_DeInit(&hUSBD_Device_CDC);
+  USBD_Stop(&hUSBD_Device);
+  USBD_DeInit(&hUSBD_Device);
   initialized = false;
 }
\ No newline at end of file
diff --git a/cores/arduino/USB.h b/cores/arduino/USB.h
index 872a16c01e..2051be1c9b 100644
--- a/cores/arduino/USB.h
+++ b/cores/arduino/USB.h
@@ -33,9 +33,12 @@ class USB {
     void initialize();
     void deinitialize();
 
-    bool initialized();
+    bool initialized;
     
     USBD_HandleTypeDef hUSBD_Device;
-}
+};
 
-#endif
\ No newline at end of file
+extern USB USBDevice;
+
+#endif // USBCON
+#endif // _USB_H_
\ No newline at end of file
diff --git a/cores/arduino/USBSerial.cpp b/cores/arduino/USBSerial.cpp
index e729386b60..741f57ce9c 100644
--- a/cores/arduino/USBSerial.cpp
+++ b/cores/arduino/USBSerial.cpp
@@ -16,8 +16,11 @@
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
+#include "usbd_ep_conf.h"
+
 #if defined (USBCON) && defined(USBD_USE_CDC_CLASS)
 
+#include "USB.h"
 #include "USBSerial.h"
 #include "usbd_cdc.h"
 #include "usbd_cdc_if.h"
@@ -31,7 +34,7 @@ void serialEventUSB() __attribute__((weak));
 
 void USBSerial::begin(void)
 {
-  USB::begin();
+  USBDevice.begin();
 }
 
 void USBSerial::begin(uint32_t /* baud_count */)
@@ -48,7 +51,7 @@ void USBSerial::begin(uint32_t /* baud_count */, uint8_t /* config */)
 
 void USBSerial::end()
 {
-  USB::end();
+  USBDevice.end();
 }
 
 int USBSerial::availableForWrite()
diff --git a/cores/arduino/USBSerial.h b/cores/arduino/USBSerial.h
index 63e2263830..6ff78af907 100644
--- a/cores/arduino/USBSerial.h
+++ b/cores/arduino/USBSerial.h
@@ -19,9 +19,10 @@
 #ifndef _USBSERIAL_H_
 #define _USBSERIAL_H_
 
-#include "usbd_core.h"
+#include "usbd_ep_conf.h"
 
 #if defined (USBCON) && defined(USBD_USE_CDC_CLASS)
+#include "usbd_core.h"
 #include "Stream.h"
 
 //================================================================================
diff --git a/cores/arduino/stm32/usb/cdc/cdc_queue.c b/cores/arduino/stm32/usb/cdc/cdc_queue.c
index 2d2330c195..3209341d42 100644
--- a/cores/arduino/stm32/usb/cdc/cdc_queue.c
+++ b/cores/arduino/stm32/usb/cdc/cdc_queue.c
@@ -35,8 +35,10 @@
   ******************************************************************************
   */
 
+#include "usbd_ep_conf.h"
+
 #ifdef USBCON
-#ifdef USBD_USE_CDC
+#ifdef USBD_USE_CDC_CLASS
 
 #include "cdc_queue.h"
 
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index 49ee9e2f7a..ee2b6d6eb3 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -50,13 +50,15 @@
   ******************************************************************************
   */
 
+#include "usbd_ep_conf.h"
+
 #ifdef USBCON
+#ifdef USBD_USE_CDC_CLASS
 
 /* Includes ------------------------------------------------------------------*/
 #include "usbd_cdc.h"
 #include "usbd_ctlreq.h"
 
-#ifdef USBD_USE_CDC_CLASS
 
 /** @addtogroup STM32_USB_DEVICE_LIBRARY
   * @{
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.h b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
index bfcbfab31d..1c12bbbffb 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.h
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
@@ -128,7 +128,6 @@ typedef struct {
 
 
 extern USBD_ClassTypeDef  USBD_CDC;
-#define USBD_CDC_CLASS    &USBD_CDC
 
 extern USBD_CDC_HandleTypeDef *cdc_handle;
 
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
index e5ee766c33..6b731641b4 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
@@ -17,10 +17,9 @@
   ******************************************************************************
   */
 
-#ifdef USBCON
-
 #include "usbd_ep_conf.h"
 
+#ifdef USBCON
 #ifdef USBD_USE_CDC_CLASS
 
 /* Includes ------------------------------------------------------------------*/
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index 008381fbec..458e4741d9 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -35,55 +35,14 @@
   ******************************************************************************
   */
 
-/* Includes ------------------------------------------------------------------*/
+#include "usbd_ep_conf.h"
+
+#ifdef USBCON
+#ifdef USBD_USE_CDC_MSC
 
 #include "usbd_cdc_msc.h"
 #include "usbd_ctlreq.h"
 
-
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-
-/** @defgroup USBD_COMPOSITE
-  * @brief usbd core module
-  * @{
-  */
-
-/** @defgroup USBD_COMPOSITE_Private_TypesDefinitions
-  * @{
-  */
-/**
-  * @}
-  */
-
-
-/** @defgroup USBD_COMPOSITE_Private_Defines
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-
-/** @defgroup USBD_COMPOSITE_Private_Macros
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-
-
-
-/** @defgroup USBD_COMPOSITE_Private_FunctionPrototypes
-  * @{
-  */
-
-
 static uint8_t  USBD_COMPOSITE_Init(USBD_HandleTypeDef *pdev,
                                    uint8_t cfgidx);
 
@@ -103,19 +62,9 @@ static uint8_t  USBD_COMPOSITE_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
 
 static uint8_t  USBD_COMPOSITE_EP0_RxReady(USBD_HandleTypeDef *pdev);
 
-static uint8_t  USBD_COMPOSITE_EP0_TxReady(USBD_HandleTypeDef *pdev);
-
 static uint8_t  USBD_COMPOSITE_SOF(USBD_HandleTypeDef *pdev);
 
-/**
-  * @}
-  */
-
-/** @defgroup USBD_COMPOSITE_Private_Variables
-  * @{
-  */
-
-USBD_ClassTypeDef  USBD_CDC_MSC_CLASS =
+USBD_ClassTypeDef  USBD_CDC_MSC =
 {
   USBD_COMPOSITE_Init,
   USBD_COMPOSITE_DeInit,
@@ -280,14 +229,6 @@ static uint8_t USBD_COMPOSITE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
   0x00,
 };
 
-/**
-  * @}
-  */
-
-/** @defgroup USBD_COMPOSITE_Private_Functions
-  * @{
-  */
-
 /**
   * @brief  USBD_COMPOSITE_Init
   *         Initialize the COMPOSITE interface
@@ -491,18 +432,7 @@ uint8_t  *USBD_COMPOSITE_GetDeviceQualifierDesc(uint16_t *length)
   return USBD_COMPOSITE_DeviceQualifierDesc;
 }
 
-/**
-  * @}
-  */
-
-
-/**
-  * @}
-  */
-
-
-/**
-  * @}
-  */
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
index ae561f5d44..c3cd830697 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
@@ -24,7 +24,7 @@
 #ifndef __USB_CDC_MSC_CORE_H_
 #define __USB_CDC_MSC_CORE_H_
 
-#include "../cdc/usbd_cdc.h"
+#include "usbd_cdc.h"
 #include "usbd_msc.h"
 #include "usbd_ioreq.h"
 
@@ -34,7 +34,7 @@
 
 #define USB_CDC_MSC_CONFIG_DESC_SIZ  (USB_CDC_CONFIG_DESC_SIZ - 9 + USB_MSC_CONFIG_DESC_SIZ)
 
-extern USBD_ClassTypeDef  USBD_CDC_MSC_CLASS;
+extern USBD_ClassTypeDef  USBD_CDC_MSC;
 
 #endif  /* __USB_CDC_MSC_CORE_H_ */
 
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.c b/cores/arduino/stm32/usb/msc/usbd_msc.c
index f7e537d4cb..8fd17b9c3f 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.c
@@ -38,49 +38,15 @@
 - "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
 EndBSPDependencies */
 
-/* Includes ------------------------------------------------------------------*/
-#include "usbd_msc.h"
-#include "usbd_msc_storage_if.h"
-
-
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-
-/** @defgroup MSC_CORE
-  * @brief Mass storage core module
-  * @{
-  */
-
-/** @defgroup MSC_CORE_Private_TypesDefinitions
-  * @{
-  */
-/**
-  * @}
-  */
+#include "usbd_ep_conf.h"
 
+#ifdef USBCON
+#ifdef USBD_USE_MSC_CLASS
 
-/** @defgroup MSC_CORE_Private_Defines
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_CORE_Private_Macros
-  * @{
-  */
-/**
-  * @}
-  */
+#include "usbd_msc.h"
+#include "usbd_msc_storage_if.h"
 
 
-/** @defgroup MSC_CORE_Private_FunctionPrototypes
-  * @{
-  */
 uint8_t  USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
 uint8_t  USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
 uint8_t  USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
@@ -92,15 +58,6 @@ uint8_t  *USBD_MSC_GetFSCfgDesc(uint16_t *length);
 uint8_t  *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length);
 uint8_t  *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length);
 
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_CORE_Private_Variables
-  * @{
-  */
-
 
 USBD_ClassTypeDef  USBD_MSC =
 {
@@ -269,11 +226,7 @@ __ALIGN_BEGIN  uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]
 USBD_MSC_BOT_HandleTypeDef msc_handle_dat;
 USBD_MSC_BOT_HandleTypeDef *msc_handle = &msc_handle_dat;
 
-USBD_StorageTypeDef *msc_storage = &USBD_MSC_Template_fops;
-
-/** @defgroup MSC_CORE_Private_Functions
-  * @{
-  */
+USBD_StorageTypeDef *msc_storage = &USBD_MSC_fops;
 
 /**
   * @brief  USBD_MSC_Init
@@ -313,7 +266,7 @@ uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 
 /**
   * @brief  USBD_MSC_DeInit
-  *         DeInitilaize  the mass storage configuration
+  *         DeInitialize the mass storage configuration
   * @param  pdev: device instance
   * @param  cfgidx: configuration index
   * @retval status
@@ -334,6 +287,7 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev,
 
   return USBD_OK;
 }
+
 /**
 * @brief  USBD_MSC_Setup
 *         Handle the MSC specific requests
@@ -585,18 +539,7 @@ uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev,
   return USBD_OK;
 }
 
-/**
-  * @}
-  */
-
-
-/**
-  * @}
-  */
-
-
-/**
-  * @}
-  */
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.h b/cores/arduino/stm32/usb/msc/usbd_msc.h
index 35c234068b..9d19a1496d 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.h
@@ -25,24 +25,10 @@
 extern "C" {
 #endif
 
-/* Includes ------------------------------------------------------------------*/
 #include  "usbd_msc_bot.h"
 #include  "usbd_msc_scsi.h"
 #include  "usbd_ioreq.h"
 
-/** @addtogroup USBD_MSC_BOT
-  * @{
-  */
-
-/** @defgroup USBD_MSC
-  * @brief This file is the Header file for usbd_msc.c
-  * @{
-  */
-
-
-/** @defgroup USBD_BOT_Exported_Defines
-  * @{
-  */
 /* MSC Class Config */
 #ifndef MSC_MEDIA_PACKET
 #define MSC_MEDIA_PACKET             512U
@@ -59,13 +45,6 @@ extern "C" {
 #define MSC_EPIN_ADDR                0x81U
 #define MSC_EPOUT_ADDR               0x01U
 
-/**
-  * @}
-  */
-
-/** @defgroup USB_CORE_Exported_Types
-  * @{
-  */
 typedef struct _USBD_STORAGE
 {
   int8_t (* Init)(uint8_t lun);
@@ -79,7 +58,6 @@ typedef struct _USBD_STORAGE
 
 } USBD_StorageTypeDef;
 
-
 typedef struct
 {
   uint32_t                 max_lun;
@@ -113,13 +91,6 @@ extern USBD_StorageTypeDef *msc_storage;
 
 uint8_t  USBD_MSC_RegisterStorage(USBD_HandleTypeDef   *pdev,
                                   USBD_StorageTypeDef *fops);
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
 
 #ifdef __cplusplus
 }
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_bot.c b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
index fe8f840b11..8b83094bd8 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
@@ -23,73 +23,22 @@
 - "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
 EndBSPDependencies */
 
+#include "usbd_ep_conf.h"
+
+#ifdef USBCON
+#ifdef USBD_USE_MSC_CLASS
+
 /* Includes ------------------------------------------------------------------*/
 #include "usbd_msc_bot.h"
 #include "usbd_msc.h"
 #include "usbd_msc_scsi.h"
 #include "usbd_ioreq.h"
 
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-
-/** @defgroup MSC_BOT
-  * @brief BOT protocol module
-  * @{
-  */
-
-/** @defgroup MSC_BOT_Private_TypesDefinitions
-  * @{
-  */
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_BOT_Private_Defines
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_BOT_Private_Macros
-  * @{
-  */
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_BOT_Private_Variables
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_BOT_Private_FunctionPrototypes
-  * @{
-  */
 static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef  *pdev);
 static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
                              uint16_t len);
 
 static void MSC_BOT_Abort(USBD_HandleTypeDef  *pdev);
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_BOT_Private_Functions
-  * @{
-  */
-
 
 
 /**
@@ -370,18 +319,8 @@ void  MSC_BOT_CplClrFeature(USBD_HandleTypeDef  *pdev, uint8_t epnum)
     return;
   }
 }
-/**
-  * @}
-  */
-
 
-/**
-  * @}
-  */
-
-
-/**
-  * @}
-  */
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_bot.h b/cores/arduino/stm32/usb/msc/usbd_msc_bot.h
index f5b1b6d42e..9b2f109969 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_bot.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_bot.h
@@ -28,19 +28,6 @@ extern "C" {
 /* Includes ------------------------------------------------------------------*/
 #include "usbd_core.h"
 
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-/** @defgroup MSC_BOT
-  * @brief This file is the Header file for usbd_msc_bot.c
-  * @{
-  */
-
-
-/** @defgroup USBD_CORE_Exported_Defines
-  * @{
-  */
 #define USBD_BOT_IDLE                      0U       /* Idle state */
 #define USBD_BOT_DATA_OUT                  1U       /* Data Out state */
 #define USBD_BOT_DATA_IN                   2U       /* Data In state */
@@ -69,13 +56,6 @@ extern "C" {
 #define USBD_DIR_OUT                       1U
 #define USBD_BOTH_DIR                      2U
 
-/**
-  * @}
-  */
-
-/** @defgroup MSC_CORE_Private_TypesDefinitions
-  * @{
-  */
 
 typedef struct
 {
@@ -101,21 +81,6 @@ typedef struct
 }
 USBD_MSC_BOT_CSWTypeDef;
 
-/**
-  * @}
-  */
-
-
-/** @defgroup USBD_CORE_Exported_Types
-  * @{
-  */
-
-/**
-  * @}
-  */
-/** @defgroup USBD_CORE_Exported_FunctionsPrototypes
-  * @{
-  */
 void MSC_BOT_Init(USBD_HandleTypeDef  *pdev);
 void MSC_BOT_Reset(USBD_HandleTypeDef  *pdev);
 void MSC_BOT_DeInit(USBD_HandleTypeDef  *pdev);
@@ -130,21 +95,12 @@ void MSC_BOT_SendCSW(USBD_HandleTypeDef  *pdev,
 
 void  MSC_BOT_CplClrFeature(USBD_HandleTypeDef  *pdev,
                             uint8_t epnum);
-/**
-  * @}
-  */
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* __USBD_MSC_BOT_H */
-/**
-  * @}
-  */
 
-/**
-* @}
-*/
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.c b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
index aaafc3aa1e..64556d91a7 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_data.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
@@ -23,47 +23,13 @@
 - "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
 EndBSPDependencies */
 
-/* Includes ------------------------------------------------------------------*/
-#include "usbd_msc_data.h"
-
-
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-
-/** @defgroup MSC_DATA
-  * @brief Mass storage info/data module
-  * @{
-  */
-
-/** @defgroup MSC_DATA_Private_TypesDefinitions
-  * @{
-  */
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_DATA_Private_Defines
-  * @{
-  */
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_DATA_Private_Macros
-  * @{
-  */
-/**
-  * @}
-  */
+#include "usbd_ep_conf.h"
 
+#ifdef USBCON
+#ifdef USBD_USE_MSC_CLASS
 
-/** @defgroup MSC_DATA_Private_Variables
-  * @{
-  */
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_msc_data.h"
 
 
 /* USB Mass storage Page 0 Inquiry Data */
@@ -101,35 +67,9 @@ const uint8_t  MSC_Mode_Sense10_data[] =
   0x00,
   0x00
 };
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_DATA_Private_FunctionPrototypes
-  * @{
-  */
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_DATA_Private_Functions
-  * @{
-  */
-
-/**
-  * @}
-  */
 
 
-/**
-  * @}
-  */
-
-
-/**
-  * @}
-  */
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.h b/cores/arduino/stm32/usb/msc/usbd_msc_data.h
index 79dafbd67f..e0ed04ee82 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_data.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.h
@@ -28,63 +28,17 @@ extern "C" {
 /* Includes ------------------------------------------------------------------*/
 #include "usbd_conf.h"
 
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-/** @defgroup USB_INFO
-  * @brief general defines for the usb device library file
-  * @{
-  */
 
-/** @defgroup USB_INFO_Exported_Defines
-  * @{
-  */
 #define MODE_SENSE6_LEN                    8U
 #define MODE_SENSE10_LEN                   8U
 #define LENGTH_INQUIRY_PAGE00              7U
 #define LENGTH_FORMAT_CAPACITIES           20U
 
-/**
-  * @}
-  */
-
-
-/** @defgroup USBD_INFO_Exported_TypesDefinitions
-  * @{
-  */
-/**
-  * @}
-  */
-
 
-
-/** @defgroup USBD_INFO_Exported_Macros
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-/** @defgroup USBD_INFO_Exported_Variables
-  * @{
-  */
 extern const uint8_t MSC_Page00_Inquiry_Data[];
 extern const uint8_t MSC_Mode_Sense6_data[];
 extern const uint8_t MSC_Mode_Sense10_data[] ;
 
-/**
-  * @}
-  */
-
-/** @defgroup USBD_INFO_Exported_FunctionsPrototype
-  * @{
-  */
-
-/**
-  * @}
-  */
 
 #ifdef __cplusplus
 }
@@ -92,12 +46,4 @@ extern const uint8_t MSC_Mode_Sense10_data[] ;
 
 #endif /* __USBD_MSC_DATA_H */
 
-/**
-  * @}
-  */
-
-/**
-* @}
-*/
-
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
index 3c98584244..f00bb2d62e 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -23,6 +23,11 @@
 - "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
 EndBSPDependencies */
 
+#include "usbd_ep_conf.h"
+
+#ifdef USBCON
+#ifdef USBD_USE_MSC_CLASS
+
 /* Includes ------------------------------------------------------------------*/
 #include "usbd_msc_bot.h"
 #include "usbd_msc_scsi.h"
@@ -31,53 +36,6 @@ EndBSPDependencies */
 
 
 
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-
-/** @defgroup MSC_SCSI
-  * @brief Mass storage SCSI layer module
-  * @{
-  */
-
-/** @defgroup MSC_SCSI_Private_TypesDefinitions
-  * @{
-  */
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_SCSI_Private_Defines
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_SCSI_Private_Macros
-  * @{
-  */
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_SCSI_Private_Variables
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_SCSI_Private_FunctionPrototypes
-  * @{
-  */
 static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
@@ -94,14 +52,6 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
 
 static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun);
 static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun);
-/**
-  * @}
-  */
-
-
-/** @defgroup MSC_SCSI_Private_Functions
-  * @{
-  */
 
 
 /**
@@ -505,7 +455,6 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
 * @param  params: Command parameters
 * @retval status
 */
-
 static int8_t SCSI_Write10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
 {
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
@@ -699,18 +648,8 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef  *pdev, uint8_t lun)
 
   return 0;
 }
-/**
-  * @}
-  */
-
 
-/**
-  * @}
-  */
-
-
-/**
-  * @}
-  */
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
index 1629d786c3..175b83578c 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
@@ -28,19 +28,6 @@ extern "C" {
 /* Includes ------------------------------------------------------------------*/
 #include "usbd_def.h"
 
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-/** @defgroup USBD_SCSI
-  * @brief header file for the storage disk file
-  * @{
-  */
-
-/** @defgroup USBD_SCSI_Exported_Defines
-  * @{
-  */
-
 #define SENSE_LIST_DEEPTH                           4U
 
 /* SCSI Commands */
@@ -117,15 +104,8 @@ extern  uint8_t Mode_Sense10_data[];
 extern  uint8_t Scsi_Sense_Data[];
 extern  uint8_t ReadCapacity10_Data[];
 extern  uint8_t ReadFormatCapacity_Data [];
-/**
-  * @}
-  */
 
 
-/** @defgroup USBD_SCSI_Exported_TypesDefinitions
-  * @{
-  */
-
 typedef struct _SENSE_ITEM
 {
   char Skey;
@@ -140,53 +120,18 @@ typedef struct _SENSE_ITEM
     char *pData;
   } w;
 } USBD_SCSI_SenseTypeDef;
-/**
-  * @}
-  */
 
-/** @defgroup USBD_SCSI_Exported_Macros
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-/** @defgroup USBD_SCSI_Exported_Variables
-  * @{
-  */
-
-/**
-  * @}
-  */
-/** @defgroup USBD_SCSI_Exported_FunctionsPrototype
-  * @{
-  */
 int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd);
 
 void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey,
                     uint8_t ASC);
 
-/**
-  * @}
-  */
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* __USBD_MSC_SCSI_H */
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-* @}
-*/
 
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
index dc6cc3dead..d45dfcd9be 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
@@ -17,23 +17,18 @@
   ******************************************************************************
   */
 
+#include "usbd_ep_conf.h"
+
+#ifdef USBCON
+#ifdef USBD_USE_MSC_CLASS
+
 /* BSPDependencies
 - "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
 - "stm32xxxxx_{eval}{discovery}_io.c"
 - "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
 EndBSPDependencies */
 
-/* Includes ------------------------------------------------------------------*/
-#include "usbd_msc_storage_template.h"
-
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/* Extern function prototypes ------------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
+#include "usbd_msc_storage_if.h"
 
 #define STORAGE_LUN_NBR                  1U
 #define STORAGE_BLK_NBR                  0x10000U
@@ -75,7 +70,7 @@ int8_t  STORAGE_Inquirydata[] =  /* 36 */
   '0', '.', '0', '1',                     /* Version      : 4 Bytes */
 };
 
-USBD_StorageTypeDef USBD_MSC_Template_fops =
+USBD_StorageTypeDef USBD_MSC_fops =
 {
   STORAGE_Init,
   STORAGE_GetCapacity,
@@ -173,5 +168,7 @@ int8_t STORAGE_GetMaxLun(void)
   return (STORAGE_LUN_NBR - 1);
 }
 
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+#endif /* USBD_USE_MSC_CLASS */
+#endif /* USBCON */
 
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h
index 0288c308fc..676b250195 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h
@@ -25,61 +25,9 @@
 extern "C" {
 #endif
 
-/* Includes ------------------------------------------------------------------*/
 #include "usbd_msc.h"
 
-/** @addtogroup STM32_USB_DEVICE_LIBRARY
-  * @{
-  */
-
-/** @defgroup USBD_STORAGE
-  * @brief header file for the usbd_msc_storage.c file
-  * @{
-  */
-
-/** @defgroup USBD_STORAGE_Exported_Defines
-  * @{
-  */
-/**
-  * @}
-  */
-
-
-/** @defgroup USBD_STORAGE_Exported_Types
-  * @{
-  */
-
-
-/**
-  * @}
-  */
-
-
-
-/** @defgroup USBD_STORAGE_Exported_Macros
-  * @{
-  */
-
-/**
-  * @}
-  */
-
-/** @defgroup USBD_STORAGE_Exported_Variables
-  * @{
-  */
-extern USBD_StorageTypeDef  USBD_MSC_Template_fops;
-/**
-  * @}
-  */
-
-/** @defgroup USBD_STORAGE_Exported_FunctionsPrototype
-  * @{
-  */
-
-
-/**
-  * @}
-  */
+extern USBD_StorageTypeDef  USBD_MSC_fops;
 
 #ifdef __cplusplus
 }
@@ -87,11 +35,4 @@ extern USBD_StorageTypeDef  USBD_MSC_Template_fops;
 
 #endif /* __USBD_MSC_STORAGE_H */
 
-/**
-  * @}
-  */
-
-/**
-* @}
-*/
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/usbd_conf.c b/cores/arduino/stm32/usb/usbd_conf.c
index 109f2f56f5..93ed28b8f6 100644
--- a/cores/arduino/stm32/usb/usbd_conf.c
+++ b/cores/arduino/stm32/usb/usbd_conf.c
@@ -517,10 +517,20 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
     HAL_PCDEx_SetTxFiFo(&g_hpcd, ep_def[i].ep_adress & 0xF, ep_def[i].ep_size);
   }
 #else
+  uint32_t offset = 0;
   for (uint32_t i = 0; i < (DEV_NUM_EP + 1); i++) {
-    HAL_PCDEx_PMAConfig(&g_hpcd, ep_def[i].ep_adress, ep_def[i].ep_kind, ep_def[i].ep_size);
+    ep_desc_t *pDesc = &ep_dep[i];
+    uint32_t size = pDesc->ep_size;
+    uint32_t address = offset;
+    if (pDesc->ep_kind == PCD_DBL_BUF) {
+      address = address | ((address + size) << 16U);
+      size *= 2;
+    }
+    HAL_PCDEx_PMAConfig(&g_hpcd, pDesc->ep_adress, pDesc->ep_kind, address);
+    offset += size;
   }
 #endif /* USE_USB_HS */
+
   return USBD_OK;
 }
 
diff --git a/cores/arduino/stm32/usb/usbd_conf.h b/cores/arduino/stm32/usb/usbd_conf.h
index db346747b0..01ef078aa3 100644
--- a/cores/arduino/stm32/usb/usbd_conf.h
+++ b/cores/arduino/stm32/usb/usbd_conf.h
@@ -108,18 +108,6 @@ extern "C" {
 #define USB_BB_MAX_NUM_ALT_MODE             0x2U
 #endif /* USB_BB_MAX_NUM_ALT_MODE */
 
-
-/*  Endpoint Configuration */
-
-#define CDC_IN_EP                       0x81  /* EP1 for data IN */
-#define CDC_OUT_EP                      0x01  /* EP1 for data OUT */
-#define CDC_CMD_EP                      0x82  /* EP2 for CDC commands */
-
-#define MSC_IN_EP                       0x83 /* EP3 for Interrupt IN */
-#define MSC_OUT_EP                       0x02 /* EP3 for Interrupt IN */
-
-
-
 /* MSC Class Config */
 #ifndef MSC_MEDIA_PACKET
 #define MSC_MEDIA_PACKET                    8192U
diff --git a/cores/arduino/stm32/usb/usbd_desc.c b/cores/arduino/stm32/usb/usbd_desc.c
index 229112ea5f..b9ba7cabae 100644
--- a/cores/arduino/stm32/usb/usbd_desc.c
+++ b/cores/arduino/stm32/usb/usbd_desc.c
@@ -37,7 +37,7 @@
   #define USBD_VID 0x0483
   #if defined(USBD_USE_HID_COMPOSITE)
     #define USBD_PID                      0x5711
-  #elif defined(USBD_USE_CDC)
+  #elif defined(USBD_USE_CDC) || defined(USBD_USE_CDC_MSC)
     #define USBD_PID                      0x5740
   #endif
 #endif /* !USBD_PID && !USBD_VID */
@@ -70,7 +70,7 @@
 #elif defined(USBD_USE_HID_COMPOSITE)
   #define USBD_CLASS_PRODUCT_HS_STRING        CONCATS(BOARD_NAME, "HID in HS Mode")
   #define USBD_CLASS_PRODUCT_FS_STRING        CONCATS(BOARD_NAME, "HID in FS Mode")
-#elif defined(USBD_USE_CDC)
+#elif defined(USBD_USE_CDC) || defined(USBD_USE_CDC_MSC)
   #define USBD_CLASS_PRODUCT_HS_STRING        CONCATS(BOARD_NAME, "CDC in HS Mode")
   #define USBD_CLASS_PRODUCT_FS_STRING        CONCATS(BOARD_NAME, "CDC in FS Mode")
 #else
@@ -85,7 +85,7 @@
   #define USBD_CLASS_INTERFACE_FS_STRING      CONCATS(BOARD_NAME, "HID Interface")
 #endif /* USBD_USE_HID_COMPOSITE */
 
-#ifdef USBD_USE_CDC
+#if defined(USBD_USE_CDC) || defined(USBD_USE_CDC_MSC)
   #define USBD_CLASS_CONFIGURATION_HS_STRING  CONCATS(BOARD_NAME, "CDC Config")
   #define USBD_CLASS_INTERFACE_HS_STRING      CONCATS(BOARD_NAME, "CDC Interface")
   #define USBD_CLASS_CONFIGURATION_FS_STRING  CONCATS(BOARD_NAME, "CDC Config")
@@ -158,7 +158,7 @@ __ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
 }; /* USB_DeviceDescriptor */
 #endif /* USBD_USE_HID_COMPOSITE */
 
-#ifdef USBD_USE_CDC
+#if defined(USBD_USE_CDC) || defined(USBD_USE_CDC_MSC)
 /* USB Standard Device Descriptor */
 __ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
   0x12,                       /* bLength */
@@ -185,7 +185,7 @@ __ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
   USBD_IDX_SERIAL_STR,        /* Index of serial number string */
   USBD_MAX_NUM_CONFIGURATION  /* bNumConfigurations */
 }; /* USB_DeviceDescriptor */
-#endif /* USBD_USE_CDC */
+#endif /* USBD_USE_CDC || USBD_USE_CDC_MSC */
 
 /* USB Device LPM BOS descriptor */
 #if (USBD_LPM_ENABLED == 1)
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.c b/cores/arduino/stm32/usb/usbd_ep_conf.c
index 455afe5ecd..91ea4a657c 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.c
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.c
@@ -19,51 +19,65 @@
 /* Includes ------------------------------------------------------------------*/
 #include "usbd_ep_conf.h"
 
-#ifdef USBD_USE_CDC
-const ep_desc_t ep_def[] = {
-#ifdef USE_USB_HS
-  {0x00,       CDC_DATA_HS_MAX_PACKET_SIZE},
-  {0x80,       CDC_DATA_HS_MAX_PACKET_SIZE},
-  {CDC_OUT_EP, CDC_DATA_HS_MAX_PACKET_SIZE},
-  {CDC_IN_EP,  CDC_DATA_HS_MAX_PACKET_SIZE},
-  {CDC_CMD_EP, CDC_CMD_PACKET_SIZE}
-#else /* USE_USB_FS */
-#ifdef USB_OTG_FS
-  {0x00,       CDC_DATA_FS_MAX_PACKET_SIZE},
-  {0x80,       CDC_DATA_FS_MAX_PACKET_SIZE},
-  {CDC_OUT_EP, CDC_DATA_FS_MAX_PACKET_SIZE},
-  {CDC_IN_EP,  CDC_DATA_FS_MAX_PACKET_SIZE},
-  {CDC_CMD_EP, CDC_CMD_PACKET_SIZE}
+#if defined(USB_OTG_FS) || defined(USE_USB_HS)
+  #define EP_DESC(ADDR, SIZE, KIND_TYP) {ADDR, SIZE}
 #else
-  {0x00,       PMA_EP0_OUT_ADDR, PCD_SNG_BUF},
-  {0x80,       PMA_EP0_IN_ADDR,  PCD_SNG_BUF},
-  {CDC_OUT_EP, PMA_CDC_OUT_ADDR, PCD_DBL_BUF},
-  {CDC_IN_EP,  PMA_CDC_IN_ADDR,  PCD_SNG_BUF},
-  {CDC_CMD_EP, PMA_CDC_CMD_ADDR, PCD_SNG_BUF}
-#endif
+  #define EP_DESC(ADDR, SIZE, KIND_TYP)  {ADDR, SIZE, KIND_TYP}
 #endif
-};
+
+#ifdef USBD_USE_CDC
+  #ifdef USE_USB_HS
+    #define CDC_DATA_MAX_PACKET_SIZE  CDC_DATA_HS_MAX_PACKET_SIZE
+  #else /* USE_USB_FS */
+    #define CDC_DATA_MAX_PACKET_SIZE  CDC_DATA_FS_MAX_PACKET_SIZE
+  #endif
+
+
+  const ep_desc_t ep_def[] = {
+    EP_DESC(0x00,       CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(0x80,       CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(CDC_OUT_EP, CDC_DATA_MAX_PACKET_SIZE, PCD_DBL_BUF),
+    EP_DESC(CDC_IN_EP,  CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(CDC_CMD_EP, CDC_CMD_PACKET_SIZE,      PCD_SNG_BUF)
+  };
+#endif /* USBD_USE_CDC */
+
+
+#ifdef USBD_USE_CDC_MSC
+  #ifdef USE_USB_HS
+    #define CDC_DATA_MAX_PACKET_SIZE  CDC_DATA_HS_MAX_PACKET_SIZE
+    #define MSC_DATA_MAX_PACKET_SIZE  MSC_DATA_HS_MAX_PACKET_SIZE
+  #else /* USE_USB_FS */
+    #define CDC_DATA_MAX_PACKET_SIZE  CDC_DATA_FS_MAX_PACKET_SIZE
+    #define MSC_DATA_MAX_PACKET_SIZE  MSC_DATA_FS_MAX_PACKET_SIZE
+  #endif
+
+
+  const ep_desc_t ep_def[] = {
+    EP_DESC(0x00,       CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(0x80,       CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(CDC_OUT_EP, CDC_DATA_MAX_PACKET_SIZE, PCD_DBL_BUF),
+    EP_DESC(CDC_IN_EP,  CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(CDC_CMD_EP, CDC_CMD_PACKET_SIZE,      PCD_SNG_BUF),
+    EP_DESC(MSC_IN_EP,  MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(MSC_OUT_EP, MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF)
+  };
 #endif /* USBD_USE_CDC */
 
+
 #ifdef USBD_USE_HID_COMPOSITE
-const ep_desc_t ep_def[] = {
-#if !defined (USB)
-#ifdef USE_USB_HS
-  {0x00,                   USB_HS_MAX_PACKET_SIZE},
-  {0x80,                   USB_HS_MAX_PACKET_SIZE},
-#else
-  {0x00,                   USB_FS_MAX_PACKET_SIZE},
-  {0x80,                   USB_FS_MAX_PACKET_SIZE},
-#endif
-  {HID_MOUSE_EPIN_ADDR,    HID_MOUSE_EPIN_SIZE},
-  {HID_KEYBOARD_EPIN_ADDR, HID_KEYBOARD_EPIN_SIZE},
-#else
-  {0x00,                   PMA_EP0_OUT_ADDR,     PCD_SNG_BUF},
-  {0x80,                   PMA_EP0_IN_ADDR,      PCD_SNG_BUF},
-  {HID_MOUSE_EPIN_ADDR,    PMA_MOUSE_IN_ADDR,    PCD_SNG_BUF},
-  {HID_KEYBOARD_EPIN_ADDR, PMA_KEYBOARD_IN_ADDR, PCD_SNG_BUF},
-#endif
-};
+  #ifdef USE_USB_HS
+    #define HID_MAX_PACKET_SIZE  USB_HS_MAX_PACKET_SIZE
+  #else /* USE_USB_FS */
+    #define HID_MAX_PACKET_SIZE  USB_FS_MAX_PACKET_SIZE
+  #endif
+  
+  const ep_desc_t ep_def[] = {
+    EP_DESC(0x00,                   HID_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(0x80,                   HID_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(HID_MOUSE_EPIN_ADDR,    HID_MOUSE_EPIN_SIZE, PCD_SNG_BUF),
+    EP_DESC(HID_KEYBOARD_EPIN_ADDR, HID_MOUSE_EPIN_SIZE, PCD_SNG_BUF)
+  };
 #endif /* USBD_USE_HID_COMPOSITE */
 
 #endif /* HAL_PCD_MODULE_ENABLED && USBCON */
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.h b/cores/arduino/stm32/usb/usbd_ep_conf.h
index 5bd4f88d06..0f1105f181 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.h
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.h
@@ -68,6 +68,9 @@ typedef struct {
   #define CDC_DATA_HS_MAX_PACKET_SIZE   USB_HS_MAX_PACKET_SIZE  /* Endpoint IN & OUT Packet size */
   #define CDC_DATA_FS_MAX_PACKET_SIZE   USB_FS_MAX_PACKET_SIZE  /* Endpoint IN & OUT Packet size */
   #define CDC_CMD_PACKET_SIZE                               8U  /* Control Endpoint Packet size */
+  /* MSC Endpoints parameters*/
+  #define MSC_DATA_HS_MAX_PACKET_SIZE   USB_HS_MAX_PACKET_SIZE  /* Endpoint IN & OUT Packet size */
+  #define MSC_DATA_FS_MAX_PACKET_SIZE   USB_FS_MAX_PACKET_SIZE  /* Endpoint IN & OUT Packet size */
 #endif
 
 /* HID composite (Mouse + Keyboard) Endpoints Configurations */
@@ -89,12 +92,21 @@ typedef struct {
   #define PMA_EP0_IN_ADDR     (PMA_EP0_OUT_ADDR + USB_MAX_EP0_SIZE)
 
   #ifdef USBD_USE_CDC
-  #define PMA_CDC_OUT_BASE    (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE)
-  #define PMA_CDC_OUT_ADDR    ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \
-                              (PMA_CDC_OUT_BASE << 16U))
-  #define PMA_CDC_IN_ADDR     (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2)
-  #define PMA_CDC_CMD_ADDR    (PMA_CDC_IN_ADDR + CDC_CMD_PACKET_SIZE)
+    #define PMA_CDC_OUT_BASE    (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE)
+    #define PMA_CDC_OUT_ADDR    ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \
+                                (PMA_CDC_OUT_BASE << 16U))
+    #define PMA_CDC_IN_ADDR     (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2)
+    #define PMA_CDC_CMD_ADDR    (PMA_CDC_IN_ADDR + CDC_CMD_PACKET_SIZE)
   #endif /* USBD_USE_CDC */
+  #ifdef USBD_USE_CDC_MSC
+    #define PMA_CDC_OUT_ADDR0   (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE)
+    #define PMA_CDC_OUT_ADDR1   (PMA_CDC_OUT_ADDR1 + USB_FS_MAX_PACKET_SIZE)
+    #define PMA_CDC_OUT_ADDR    (PMA_CDC_OUT_ADDR0 | (PMA_CDC_OUT_ADDR1 << 16U)) // cdc out has a double buffer
+    #define PMA_CDC_IN_ADDR     (PMA_CDC_OUT_ADDR1 + USB_FS_MAX_PACKET_SIZE)
+    #define PMA_CDC_CMD_ADDR    (PMA_CDC_IN_ADDR + USB_FS_MAX_PACKET_SIZE)
+    #define PMA_MSC_IN_ADDR     (PMA_CDC_CMD_ADDR + CDC_CMD_PACKET_SIZE)
+    #define PMA_MSC_IN_ADDR     (PMA_MSC_IN_ADDR + USB_FS_MAX_PACKET_SIZE)
+  #endif /* USBD_USE_CDC_MSC */
   #ifdef USBD_USE_HID_COMPOSITE
     #define PMA_MOUSE_IN_ADDR   (PMA_EP0_IN_ADDR + HID_MOUSE_EPIN_SIZE)
     #define PMA_KEYBOARD_IN_ADDR    (PMA_MOUSE_IN_ADDR + HID_KEYBOARD_EPIN_SIZE)
diff --git a/tools/platformio-build.py b/tools/platformio-build.py
index 68b0dfc01c..7bdc40d781 100644
--- a/tools/platformio-build.py
+++ b/tools/platformio-build.py
@@ -86,7 +86,7 @@ def process_usb_configuration(cpp_defines):
     elif "PIO_FRAMEWORK_ARDUINO_ENABLE_HID" in cpp_defines:
         env.Append(CPPDEFINES=["USBD_USE_HID_COMPOSITE"])
 
-    if any(f in env["CPPDEFINES"] for f in ("USBD_USE_CDC", "USBD_USE_HID_COMPOSITE")):
+    if any(f in env["CPPDEFINES"] for f in ["USBCON"]):
         env.Append(CPPDEFINES=["HAL_PCD_MODULE_ENABLED"])
 
 
@@ -170,6 +170,8 @@ def configure_application_offset(mcu, upload_protocol):
         join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb"),
         join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb", "hid"),
         join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb", "cdc"),
+        join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb", "msc"),
+        join(FRAMEWORK_DIR, "cores", "arduino", "stm32", "usb", "cdc_msc"),
         join(FRAMEWORK_DIR, "system", "Drivers", series + "_HAL_Driver", "Inc"),
         join(FRAMEWORK_DIR, "system", "Drivers", series + "_HAL_Driver", "Src"),
         join(FRAMEWORK_DIR, "system", series),

From 6717196bd09d485788e8ec4fd19864316dcae895 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Mon, 1 Jun 2020 22:10:17 +0100
Subject: [PATCH 09/37] fixed bug in descriptor, small changes to USB class

---
 cores/arduino/USB.cpp                           | 17 +++++++++--------
 cores/arduino/USB.h                             |  3 +++
 .../arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp  | 16 ++++++++--------
 .../arduino/stm32/usb/msc/usbd_msc_storage_if.c |  4 +++-
 4 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
index db54cf7138..b6c56dddf6 100644
--- a/cores/arduino/USB.cpp
+++ b/cores/arduino/USB.cpp
@@ -31,6 +31,10 @@ void USB::begin() {
   if (!initialized) initialize();
 }
 
+void USB::register_msc(USBD_StorageTypeDef* fops) {
+  USBD_MSC_RegisterStorage(&hUSBD_Device, fops);
+}
+
 void USB::initialize() {
   hUSBD_Device_CDC = &hUSBD_Device;
 
@@ -38,9 +42,9 @@ void USB::initialize() {
   if (USBD_Init(&hUSBD_Device, &USBD_Desc, 0) == USBD_OK) {
   #ifdef USBD_USE_CDC
     /* Add Supported Class */
-    if (USBD_RegisterClass(&hUSBD_Device_CDC, &USBD_CDC) == USBD_OK) {
+    if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC) == USBD_OK) {
       /* Add CDC Interface Class */
-      if (USBD_CDC_RegisterInterface(&hUSBD_Device_CDC, &USBD_CDC_fops) == USBD_OK) {
+      if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) == USBD_OK) {
         /* Start Device Process */
         USBD_Start(&hUSBD_Device_CDC);
         initialized = true;
@@ -51,12 +55,9 @@ void USB::initialize() {
     if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC_MSC) == USBD_OK) {
       /* Add CDC Interface Class */
       if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) == USBD_OK) {
-          /* Add MSC Interface Class */
-        if (USBD_MSC_RegisterStorage(&hUSBD_Device, &USBD_MSC_fops) == USBD_OK) {
-          /* Start Device Process */
-          USBD_Start(&hUSBD_Device);
-          initialized = true;
-        }
+        /* Start Device Process */
+        USBD_Start(&hUSBD_Device);
+        initialized = true;
       }
     }
   #endif
diff --git a/cores/arduino/USB.h b/cores/arduino/USB.h
index 2051be1c9b..64d5900c15 100644
--- a/cores/arduino/USB.h
+++ b/cores/arduino/USB.h
@@ -22,9 +22,12 @@
 #if defined (USBCON)
 #include "Stream.h"
 #include "usbd_core.h"
+#include "usbd_msc.h"
 
 class USB {
   public:
+    void register_msc(USBD_StorageTypeDef* fops);
+
     void begin(void);
 
     void end(void);
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index 458e4741d9..e9bcc25f30 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -87,10 +87,10 @@ USBD_ClassTypeDef  USBD_CDC_MSC =
 #pragma data_alignment=4
 #endif
 /* USB COMPOSITE device Configuration Descriptor */
-static uint8_t USBD_COMPOSITE_CfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] =
+static uint8_t USBD_COMPOSITE_CfgFSDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] =
 {
   0x09, /* bLength: Configuation Descriptor size */
-  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, /* bDescriptorType: Configuration */
+  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
   USB_CDC_MSC_CONFIG_DESC_SIZ,
   /* wTotalLength: Bytes returned */
   0x00,
@@ -198,16 +198,16 @@ static uint8_t USBD_COMPOSITE_CfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] =
   0x05,                                            /* Endpoint descriptor type */
   MSC_EPIN_ADDR,                                   /* Endpoint address (IN, address 1) */
   0x02,                                            /* Bulk endpoint type */
-  LOBYTE(MSC_MAX_HS_PACKET),
-  HIBYTE(MSC_MAX_HS_PACKET),
+  LOBYTE(MSC_MAX_FS_PACKET),
+  HIBYTE(MSC_MAX_FS_PACKET),
   0x00,                                            /* Polling interval in milliseconds */
 
   0x07,                                            /* Endpoint descriptor length = 7 */
   0x05,                                            /* Endpoint descriptor type */
   MSC_EPOUT_ADDR,                                  /* Endpoint address (OUT, address 1) */
   0x02,                                            /* Bulk endpoint type */
-  LOBYTE(MSC_MAX_HS_PACKET),
-  HIBYTE(MSC_MAX_HS_PACKET),
+  LOBYTE(MSC_MAX_FS_PACKET),
+  HIBYTE(MSC_MAX_FS_PACKET),
   0x00                                             /* Polling interval in milliseconds */
 };
 
@@ -325,8 +325,8 @@ static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
   */
 static uint8_t  *USBD_COMPOSITE_GetCfgDesc(uint16_t *length)
 {
-  *length = sizeof(USBD_COMPOSITE_CfgDesc);
-  return USBD_COMPOSITE_CfgDesc;
+  *length = sizeof(USBD_COMPOSITE_CfgFSDesc);
+  return USBD_COMPOSITE_CfgFSDesc;
 }
 
 /**
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
index d45dfcd9be..4a0c4a6902 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
@@ -54,7 +54,6 @@ int8_t STORAGE_GetMaxLun(void);
 /* USB Mass storage Standard Inquiry Data */
 int8_t  STORAGE_Inquirydata[] =  /* 36 */
 {
-
   /* LUN 0 */
   0x00,
   0x80,
@@ -82,6 +81,7 @@ USBD_StorageTypeDef USBD_MSC_fops =
   STORAGE_Inquirydata,
 
 };
+
 /*******************************************************************************
 * Function Name  : Read_Memory
 * Description    : Handle the Read operation from the microSD card.
@@ -144,6 +144,7 @@ int8_t STORAGE_Read(uint8_t lun, uint8_t *buf,
 {
   return 0;
 }
+
 /*******************************************************************************
 * Function Name  : Write_Memory
 * Description    : Handle the Write operation to the STORAGE card.
@@ -156,6 +157,7 @@ int8_t STORAGE_Write(uint8_t lun, uint8_t *buf,
 {
   return (0);
 }
+
 /*******************************************************************************
 * Function Name  : Write_Memory
 * Description    : Handle the Write operation to the STORAGE card.

From 6f3ebfcbce037bc4240e0ea97aa134ef9782c293 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Tue, 2 Jun 2020 10:09:19 +0100
Subject: [PATCH 10/37] fixed duplicate endpoint definition and somewhat fixed
 endpoint configuration

---
 .../stm32/usb/cdc_msc/usbd_cdc_msc.cpp        | 26 +++++-----
 cores/arduino/stm32/usb/msc/usbd_msc.c        | 48 +++++++++----------
 cores/arduino/stm32/usb/msc/usbd_msc.h        |  4 --
 cores/arduino/stm32/usb/msc/usbd_msc_bot.c    | 24 +++++-----
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c   |  6 +--
 cores/arduino/stm32/usb/usbd_conf.c           |  4 +-
 cores/arduino/stm32/usb/usbd_ep_conf.h        |  4 +-
 7 files changed, 57 insertions(+), 59 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index e9bcc25f30..e20dbfb1b6 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -164,20 +164,20 @@ static uint8_t USBD_COMPOSITE_CfgFSDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] =
   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: */
+  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 */
+  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: */
+  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,
 
@@ -196,7 +196,7 @@ static uint8_t USBD_COMPOSITE_CfgFSDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] =
   /********************  Mass Storage Endpoints ********************/
   0x07,                                            /* Endpoint descriptor length = 7 */
   0x05,                                            /* Endpoint descriptor type */
-  MSC_EPIN_ADDR,                                   /* Endpoint address (IN, address 1) */
+  MSC_IN_EP,                                       /* Endpoint address (IN, address 1) */
   0x02,                                            /* Bulk endpoint type */
   LOBYTE(MSC_MAX_FS_PACKET),
   HIBYTE(MSC_MAX_FS_PACKET),
@@ -204,7 +204,7 @@ static uint8_t USBD_COMPOSITE_CfgFSDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] =
 
   0x07,                                            /* Endpoint descriptor length = 7 */
   0x05,                                            /* Endpoint descriptor type */
-  MSC_EPOUT_ADDR,                                  /* Endpoint address (OUT, address 1) */
+  MSC_OUT_EP,                                      /* Endpoint address (OUT, address 1) */
   0x02,                                            /* Bulk endpoint type */
   LOBYTE(MSC_MAX_FS_PACKET),
   HIBYTE(MSC_MAX_FS_PACKET),
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.c b/cores/arduino/stm32/usb/msc/usbd_msc.c
index 8fd17b9c3f..ba6d4a99a9 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.c
@@ -106,7 +106,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
   /********************  Mass Storage Endpoints ********************/
   0x07,   /*Endpoint descriptor length = 7*/
   0x05,   /*Endpoint descriptor type */
-  MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
+  MSC_IN_EP,   /*Endpoint address (IN, address 1) */
   0x02,   /*Bulk endpoint type */
   LOBYTE(MSC_MAX_HS_PACKET),
   HIBYTE(MSC_MAX_HS_PACKET),
@@ -114,7 +114,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
 
   0x07,   /*Endpoint descriptor length = 7 */
   0x05,   /*Endpoint descriptor type */
-  MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
+  MSC_OUT_EP,   /*Endpoint address (OUT, address 1) */
   0x02,   /*Bulk endpoint type */
   LOBYTE(MSC_MAX_HS_PACKET),
   HIBYTE(MSC_MAX_HS_PACKET),
@@ -149,7 +149,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
   /********************  Mass Storage Endpoints ********************/
   0x07,   /*Endpoint descriptor length = 7*/
   0x05,   /*Endpoint descriptor type */
-  MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
+  MSC_IN_EP,   /*Endpoint address (IN, address 1) */
   0x02,   /*Bulk endpoint type */
   LOBYTE(MSC_MAX_FS_PACKET),
   HIBYTE(MSC_MAX_FS_PACKET),
@@ -157,7 +157,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
 
   0x07,   /*Endpoint descriptor length = 7 */
   0x05,   /*Endpoint descriptor type */
-  MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
+  MSC_OUT_EP,   /*Endpoint address (OUT, address 1) */
   0x02,   /*Bulk endpoint type */
   LOBYTE(MSC_MAX_FS_PACKET),
   HIBYTE(MSC_MAX_FS_PACKET),
@@ -190,7 +190,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __AL
   /********************  Mass Storage Endpoints ********************/
   0x07,   /*Endpoint descriptor length = 7*/
   0x05,   /*Endpoint descriptor type */
-  MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
+  MSC_IN_EP,   /*Endpoint address (IN, address 1) */
   0x02,   /*Bulk endpoint type */
   0x40,
   0x00,
@@ -198,7 +198,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __AL
 
   0x07,   /*Endpoint descriptor length = 7 */
   0x05,   /*Endpoint descriptor type */
-  MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
+  MSC_OUT_EP,   /*Endpoint address (OUT, address 1) */
   0x02,   /*Bulk endpoint type */
   0x40,
   0x00,
@@ -240,22 +240,22 @@ uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
   if (pdev->dev_speed == USBD_SPEED_HIGH)
   {
     /* Open EP OUT */
-    USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
-    pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
+    USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
+    pdev->ep_out[MSC_OUT_EP & 0xFU].is_used = 1U;
 
     /* Open EP IN */
-    USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
-    pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
+    USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
+    pdev->ep_in[MSC_IN_EP & 0xFU].is_used = 1U;
   }
   else
   {
     /* Open EP OUT */
-    USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
-    pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
+    USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
+    pdev->ep_out[MSC_OUT_EP & 0xFU].is_used = 1U;
 
     /* Open EP IN */
-    USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
-    pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
+    USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
+    pdev->ep_in[MSC_IN_EP & 0xFU].is_used = 1U;
   }
 
   /* Init the BOT  layer */
@@ -275,12 +275,12 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev,
                          uint8_t cfgidx)
 {
   /* Close MSC EPs */
-  USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR);
-  pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 0U;
+  USBD_LL_CloseEP(pdev, MSC_OUT_EP);
+  pdev->ep_out[MSC_OUT_EP & 0xFU].is_used = 0U;
 
   /* Close EP IN */
-  USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR);
-  pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 0U;
+  USBD_LL_CloseEP(pdev, MSC_IN_EP);
+  pdev->ep_in[MSC_IN_EP & 0xFU].is_used = 0U;
 
   /* De-Init the BOT layer */
   MSC_BOT_DeInit(pdev);
@@ -398,16 +398,16 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
             if (pdev->dev_speed == USBD_SPEED_HIGH)
             {
               /* Open EP IN */
-              USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK,
+              USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK,
                              MSC_MAX_HS_PACKET);
             }
             else
             {
               /* Open EP IN */
-              USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK,
+              USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK,
                              MSC_MAX_FS_PACKET);
             }
-            pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
+            pdev->ep_in[MSC_IN_EP & 0xFU].is_used = 1U;
           }
           else
           {
@@ -415,16 +415,16 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
             if (pdev->dev_speed == USBD_SPEED_HIGH)
             {
               /* Open EP OUT */
-              USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK,
+              USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK,
                              MSC_MAX_HS_PACKET);
             }
             else
             {
               /* Open EP OUT */
-              USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK,
+              USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK,
                              MSC_MAX_FS_PACKET);
             }
-            pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
+            pdev->ep_out[MSC_OUT_EP & 0xFU].is_used = 1U;
           }
 
           /* Handle BOT error */
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.h b/cores/arduino/stm32/usb/msc/usbd_msc.h
index 9d19a1496d..3c19a9a2ac 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.h
@@ -41,10 +41,6 @@ extern "C" {
 #define BOT_RESET                    0xFF
 #define USB_MSC_CONFIG_DESC_SIZ      32
 
-
-#define MSC_EPIN_ADDR                0x81U
-#define MSC_EPOUT_ADDR               0x01U
-
 typedef struct _USBD_STORAGE
 {
   int8_t (* Init)(uint8_t lun);
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_bot.c b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
index 8b83094bd8..f1a80a6b61 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
@@ -59,11 +59,11 @@ void MSC_BOT_Init(USBD_HandleTypeDef  *pdev)
 
   msc_storage->Init(0U);
 
-  USBD_LL_FlushEP(pdev, MSC_EPOUT_ADDR);
-  USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR);
+  USBD_LL_FlushEP(pdev, MSC_OUT_EP);
+  USBD_LL_FlushEP(pdev, MSC_IN_EP);
 
   /* Prapare EP to Receive First BOT Cmd */
-  USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw,
+  USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, (uint8_t *)(void *)&hmsc->cbw,
                          USBD_BOT_CBW_LENGTH);
 }
 
@@ -81,7 +81,7 @@ void MSC_BOT_Reset(USBD_HandleTypeDef  *pdev)
   hmsc->bot_status = USBD_BOT_STATUS_RECOVERY;
 
   /* Prapare EP to Receive First BOT Cmd */
-  USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw,
+  USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, (uint8_t *)(void *)&hmsc->cbw,
                          USBD_BOT_CBW_LENGTH);
 }
 
@@ -171,7 +171,7 @@ static void  MSC_BOT_CBW_Decode(USBD_HandleTypeDef  *pdev)
   hmsc->csw.dTag = hmsc->cbw.dTag;
   hmsc->csw.dDataResidue = hmsc->cbw.dDataLength;
 
-  if ((USBD_LL_GetRxDataSize(pdev, MSC_EPOUT_ADDR) != USBD_BOT_CBW_LENGTH) ||
+  if ((USBD_LL_GetRxDataSize(pdev, MSC_OUT_EP) != USBD_BOT_CBW_LENGTH) ||
       (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) ||
       (hmsc->cbw.bLUN > 1U) ||
       (hmsc->cbw.bCBLength < 1U) || (hmsc->cbw.bCBLength > 16U))
@@ -239,7 +239,7 @@ static void  MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
   hmsc->csw.bStatus = USBD_CSW_CMD_PASSED;
   hmsc->bot_state = USBD_BOT_SEND_DATA;
 
-  USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, pbuf, length);
+  USBD_LL_Transmit(pdev, MSC_IN_EP, pbuf, length);
 }
 
 /**
@@ -258,11 +258,11 @@ void  MSC_BOT_SendCSW(USBD_HandleTypeDef  *pdev,
   hmsc->csw.bStatus = CSW_Status;
   hmsc->bot_state = USBD_BOT_IDLE;
 
-  USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, (uint8_t *)(void *)&hmsc->csw,
+  USBD_LL_Transmit(pdev, MSC_IN_EP, (uint8_t *)(void *)&hmsc->csw,
                    USBD_BOT_CSW_LENGTH);
 
   /* Prepare EP to Receive next Cmd */
-  USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw,
+  USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, (uint8_t *)(void *)&hmsc->cbw,
                          USBD_BOT_CBW_LENGTH);
 }
 
@@ -281,14 +281,14 @@ static void  MSC_BOT_Abort(USBD_HandleTypeDef  *pdev)
       (hmsc->cbw.dDataLength != 0U) &&
       (hmsc->bot_status == USBD_BOT_STATUS_NORMAL))
   {
-    USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
+    USBD_LL_StallEP(pdev, MSC_OUT_EP);
   }
 
-  USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
+  USBD_LL_StallEP(pdev, MSC_IN_EP);
 
   if (hmsc->bot_status == USBD_BOT_STATUS_ERROR)
   {
-    USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)(void *)&hmsc->cbw,
+    USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, (uint8_t *)(void *)&hmsc->cbw,
                            USBD_BOT_CBW_LENGTH);
   }
 }
@@ -307,7 +307,7 @@ void  MSC_BOT_CplClrFeature(USBD_HandleTypeDef  *pdev, uint8_t epnum)
 
   if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) /* Bad CBW Signature */
   {
-    USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
+    USBD_LL_StallEP(pdev, MSC_IN_EP);
     hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
   }
   else if (((epnum & 0x80U) == 0x80U) && (hmsc->bot_status != USBD_BOT_STATUS_RECOVERY))
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
index f00bb2d62e..1887134e79 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -511,7 +511,7 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *para
 
     /* Prepare EP to receive first data packet */
     hmsc->bot_state = USBD_BOT_DATA_OUT;
-    USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
+    USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, hmsc->bot_data, len);
   }
   else /* Write Process ongoing */
   {
@@ -591,7 +591,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef  *pdev, uint8_t lun)
     return -1;
   }
 
-  USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, hmsc->bot_data, len);
+  USBD_LL_Transmit(pdev, MSC_IN_EP, hmsc->bot_data, len);
 
   hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
   hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
@@ -643,7 +643,7 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef  *pdev, uint8_t lun)
   {
     len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET);
     /* Prepare EP to Receive next packet */
-    USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
+    USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, hmsc->bot_data, len);
   }
 
   return 0;
diff --git a/cores/arduino/stm32/usb/usbd_conf.c b/cores/arduino/stm32/usb/usbd_conf.c
index 93ed28b8f6..0bc8b9cc16 100644
--- a/cores/arduino/stm32/usb/usbd_conf.c
+++ b/cores/arduino/stm32/usb/usbd_conf.c
@@ -514,7 +514,9 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
   /* configure EPs FIFOs */
   HAL_PCDEx_SetRxFiFo(&g_hpcd, ep_def[0].ep_size);
   for (uint32_t i = 1; i < (DEV_NUM_EP + 1); i++) {
-    HAL_PCDEx_SetTxFiFo(&g_hpcd, ep_def[i].ep_adress & 0xF, ep_def[i].ep_size);
+    if (ep_def[i].ep_adress & 0xF0U) {
+      HAL_PCDEx_SetTxFiFo(&g_hpcd, ep_def[i].ep_adress & 0xF, ep_def[i].ep_size);
+    }
   }
 #else
   uint32_t offset = 0;
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.h b/cores/arduino/stm32/usb/usbd_ep_conf.h
index 0f1105f181..6d8003ef2f 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.h
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.h
@@ -59,10 +59,10 @@ typedef struct {
   #define CDC_IN_EP                     0x81U /*  EP1 for CDC data IN */
   #define CDC_CMD_EP                    0x82U /*  EP2 for CDC commands */
 
-  #define MSC_OUT_EP                    0x02U /*  EP2 for MSC data IN */
+  #define MSC_OUT_EP                    0x03U /*  EP3 for MSC data IN */
   #define MSC_IN_EP                     0x83U /*  EP3 for MSC data IN */
 
-  #define DEV_NUM_EP                    0x04U   /* Device Endpoints number including EP0 */
+  #define DEV_NUM_EP                    0x07U   /* Device Endpoints number including EP0 */
 
   /* CDC Endpoints parameters*/
   #define CDC_DATA_HS_MAX_PACKET_SIZE   USB_HS_MAX_PACKET_SIZE  /* Endpoint IN & OUT Packet size */

From ccef5566236ba11a20e0c06230ee8b52ddc66281 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Tue, 2 Jun 2020 21:11:44 +0100
Subject: [PATCH 11/37] fixed styling and changed dummy sd usb so it is always
 not ready

---
 cores/arduino/USB.cpp                         |  72 ++++++----
 cores/arduino/USB.h                           |   4 +-
 cores/arduino/stm32/usb/cdc/usbd_cdc.c        |  18 +--
 .../stm32/usb/cdc_msc/usbd_cdc_msc.cpp        |  36 +++--
 .../arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h  |   4 +-
 cores/arduino/stm32/usb/msc/usbd_msc.c        |  86 ++++--------
 cores/arduino/stm32/usb/msc/usbd_msc.h        |   6 +-
 cores/arduino/stm32/usb/msc/usbd_msc_bot.c    |  65 +++------
 cores/arduino/stm32/usb/msc/usbd_msc_bot.h    |   6 +-
 cores/arduino/stm32/usb/msc/usbd_msc_data.c   |  11 +-
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c   | 126 ++++++------------
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.h   |   9 +-
 .../stm32/usb/msc/usbd_msc_storage_if.c       |   8 +-
 13 files changed, 176 insertions(+), 275 deletions(-)

diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
index b6c56dddf6..3685543257 100644
--- a/cores/arduino/USB.cpp
+++ b/cores/arduino/USB.cpp
@@ -27,48 +27,62 @@
 
 USB USBDevice;
 
-void USB::begin() {
-  if (!initialized) initialize();
+void USB::begin()
+{
+  if (!initialized) {
+    initialize();
+  }
 }
 
-void USB::register_msc(USBD_StorageTypeDef* fops) {
+void USB::register_msc(USBD_StorageTypeDef* fops) 
+{
   USBD_MSC_RegisterStorage(&hUSBD_Device, fops);
 }
 
-void USB::initialize() {
+void USB::initialize()
+{
   hUSBD_Device_CDC = &hUSBD_Device;
 
   /* Init Device Library */
-  if (USBD_Init(&hUSBD_Device, &USBD_Desc, 0) == USBD_OK) {
-  #ifdef USBD_USE_CDC
-    /* Add Supported Class */
-    if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC) == USBD_OK) {
-      /* Add CDC Interface Class */
-      if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) == USBD_OK) {
-        /* Start Device Process */
-        USBD_Start(&hUSBD_Device_CDC);
-        initialized = true;
-      }
-    }
-  #elif USBD_USE_CDC_MSC
-    /* Add Supported Class */
-    if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC_MSC) == USBD_OK) {
-      /* Add CDC Interface Class */
-      if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) == USBD_OK) {
-        /* Start Device Process */
-        USBD_Start(&hUSBD_Device);
-        initialized = true;
-      }
-    }
-  #endif
+  if (USBD_Init(&hUSBD_Device, &USBD_Desc, 0) != USBD_OK) {
+    return;
+  }
+
+  /* Add Supported Class and register interface */
+#ifdef USBD_USE_CDC
+  if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC) != USBD_OK) {
+    return;
+  }
+  if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) != USBD_OK) {
+    return;
+  }
+#elif USBD_USE_CDC_MSC
+  if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC_MSC) != USBD_OK) {
+    return;
   }
+  if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) != USBD_OK) {
+    return;
+  }
+#elif USBD_USE_MSC
+  if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC_MSC) != USBD_OK) {
+    return;
+  }
+#endif
+
+  /* Start Device Process */
+  USBD_Start(&hUSBD_Device_CDC);
+  initialized = true;
 }
 
-void USB::end() {
-  if (initialized) deinitialize();
+void USB::end()
+{
+  if (initialized) {
+    deinitialize();
+  }
 }
 
-void USB::deinitialize() {
+void USB::deinitialize()
+{
   USBD_Stop(&hUSBD_Device);
   USBD_DeInit(&hUSBD_Device);
   initialized = false;
diff --git a/cores/arduino/USB.h b/cores/arduino/USB.h
index 64d5900c15..25572d07a2 100644
--- a/cores/arduino/USB.h
+++ b/cores/arduino/USB.h
@@ -26,7 +26,7 @@
 
 class USB {
   public:
-    void register_msc(USBD_StorageTypeDef* fops);
+    void register_msc(USBD_StorageTypeDef *fops);
 
     void begin(void);
 
@@ -37,7 +37,7 @@ class USB {
     void deinitialize();
 
     bool initialized;
-    
+
     USBD_HandleTypeDef hUSBD_Device;
 };
 
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index ee2b6d6eb3..7ce101ae03 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -499,11 +499,11 @@ static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
   if (pdev->dev_speed == USBD_SPEED_HIGH) {
     /* Prepare Out endpoint to receive next packet */
     USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
-                            CDC_DATA_HS_OUT_PACKET_SIZE);
+                           CDC_DATA_HS_OUT_PACKET_SIZE);
   } else {
     /* Prepare Out endpoint to receive next packet */
     USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
-                            CDC_DATA_FS_OUT_PACKET_SIZE);
+                           CDC_DATA_FS_OUT_PACKET_SIZE);
   }
 
   return ret;
@@ -820,7 +820,7 @@ uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
 
     /* Transmit next packet */
     USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer,
-                      (uint16_t)hcdc->TxLength);
+                     (uint16_t)hcdc->TxLength);
 
     return USBD_OK;
   } else {
@@ -845,15 +845,15 @@ uint8_t  USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
   if (pdev->dev_speed == USBD_SPEED_HIGH) {
     /* Prepare Out endpoint to receive next packet */
     USBD_LL_PrepareReceive(pdev,
-                            CDC_OUT_EP,
-                            hcdc->RxBuffer,
-                            CDC_DATA_HS_OUT_PACKET_SIZE);
+                           CDC_OUT_EP,
+                           hcdc->RxBuffer,
+                           CDC_DATA_HS_OUT_PACKET_SIZE);
   } else {
     /* Prepare Out endpoint to receive next packet */
     USBD_LL_PrepareReceive(pdev,
-                            CDC_OUT_EP,
-                            hcdc->RxBuffer,
-                            CDC_DATA_FS_OUT_PACKET_SIZE);
+                           CDC_OUT_EP,
+                           hcdc->RxBuffer,
+                           CDC_DATA_FS_OUT_PACKET_SIZE);
   }
   return USBD_OK;
 }
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index e20dbfb1b6..05ec62476d 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -44,13 +44,13 @@
 #include "usbd_ctlreq.h"
 
 static uint8_t  USBD_COMPOSITE_Init(USBD_HandleTypeDef *pdev,
-                                   uint8_t cfgidx);
+                                    uint8_t cfgidx);
 
 static uint8_t  USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
-                                     uint8_t cfgidx);
+                                      uint8_t cfgidx);
 
 static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
-                                    USBD_SetupReqTypedef *req);
+                                     USBD_SetupReqTypedef *req);
 
 static uint8_t  *USBD_COMPOSITE_GetCfgDesc(uint16_t *length);
 
@@ -64,8 +64,7 @@ static uint8_t  USBD_COMPOSITE_EP0_RxReady(USBD_HandleTypeDef *pdev);
 
 static uint8_t  USBD_COMPOSITE_SOF(USBD_HandleTypeDef *pdev);
 
-USBD_ClassTypeDef  USBD_CDC_MSC =
-{
+USBD_ClassTypeDef  USBD_CDC_MSC = {
   USBD_COMPOSITE_Init,
   USBD_COMPOSITE_DeInit,
   USBD_COMPOSITE_Setup,
@@ -84,11 +83,10 @@ USBD_ClassTypeDef  USBD_CDC_MSC =
 
 
 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
-#pragma data_alignment=4
+  #pragma data_alignment=4
 #endif
 /* USB COMPOSITE device Configuration Descriptor */
-static uint8_t USBD_COMPOSITE_CfgFSDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] =
-{
+static uint8_t USBD_COMPOSITE_CfgFSDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   0x09, /* bLength: Configuation Descriptor size */
   USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
   USB_CDC_MSC_CONFIG_DESC_SIZ,
@@ -212,11 +210,10 @@ static uint8_t USBD_COMPOSITE_CfgFSDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] =
 };
 
 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
-#pragma data_alignment=4
+  #pragma data_alignment=4
 #endif
 /* USB Standard Device Descriptor */
-static uint8_t USBD_COMPOSITE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
-{
+static uint8_t USBD_COMPOSITE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] = {
   USB_LEN_DEV_QUALIFIER_DESC,
   USB_DESC_TYPE_DEVICE_QUALIFIER,
   0x00,
@@ -237,7 +234,7 @@ static uint8_t USBD_COMPOSITE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
   * @retval status
   */
 static uint8_t  USBD_COMPOSITE_Init(USBD_HandleTypeDef *pdev,
-                                   uint8_t cfgidx)
+                                    uint8_t cfgidx)
 {
   USBD_MSC.Init(pdev, cfgidx);
 
@@ -254,7 +251,7 @@ static uint8_t  USBD_COMPOSITE_Init(USBD_HandleTypeDef *pdev,
   * @retval status
   */
 static uint8_t  USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
-                                     uint8_t cfgidx)
+                                      uint8_t cfgidx)
 {
   USBD_MSC.DeInit(pdev, cfgidx);
 
@@ -271,7 +268,7 @@ static uint8_t  USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
   * @retval status
   */
 static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
-                                    USBD_SetupReqTypedef *req)
+                                     USBD_SetupReqTypedef *req)
 {
   switch (req->bmRequest & USB_REQ_RECIPIENT_MASK)
   {
@@ -285,12 +282,12 @@ static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
         case MSC_INTERFACE:
           return USBD_MSC.Setup(pdev, req);
           break;
-      
+
         // invalid interface
         default:
           return USBD_FAIL;
       }
-    break;
+      break;
 
     case USB_REQ_RECIPIENT_ENDPOINT:
       switch (req->wIndex) {
@@ -307,7 +304,7 @@ static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
         default:
           return USBD_FAIL;
       }
-    break;
+      break;
 
     default:
       break;
@@ -350,10 +347,9 @@ uint8_t  *USBD_COMPOSITE_DeviceQualifierDescriptor(uint16_t *length)
   * @retval status
   */
 static uint8_t  USBD_COMPOSITE_DataIn(USBD_HandleTypeDef *pdev,
-                                     uint8_t epnum)
+                                      uint8_t epnum)
 {
-  switch (epnum)
-  {
+  switch (epnum) {
     case CDC_IN_EP:
     case CDC_CMD_EP:
     case CDC_OUT_EP:
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
index c3cd830697..ffe43f6fa2 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
@@ -17,9 +17,7 @@
   *                      <http://www.st.com/SLA0044>
   *
   ******************************************************************************
-  */ 
-
-/* Includes ------------------------------------------------------------------*/
+  */
 
 #ifndef __USB_CDC_MSC_CORE_H_
 #define __USB_CDC_MSC_CORE_H_
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.c b/cores/arduino/stm32/usb/msc/usbd_msc.c
index ba6d4a99a9..b9d300078c 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.c
@@ -59,8 +59,7 @@ uint8_t  *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length);
 uint8_t  *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length);
 
 
-USBD_ClassTypeDef  USBD_MSC =
-{
+USBD_ClassTypeDef  USBD_MSC = {
   USBD_MSC_Init,
   USBD_MSC_DeInit,
   USBD_MSC_Setup,
@@ -79,8 +78,7 @@ USBD_ClassTypeDef  USBD_MSC =
 
 /* USB Mass storage device Configuration Descriptor */
 /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
-__ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
-{
+__ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END = {
 
   0x09,   /* bLength: Configuation Descriptor size */
   USB_DESC_TYPE_CONFIGURATION,   /* bDescriptorType: Configuration */
@@ -123,8 +121,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
 
 /* USB Mass storage device Configuration Descriptor */
 /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
-__ALIGN_BEGIN uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
-{
+__ALIGN_BEGIN uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END = {
   0x09,   /* bLength: Configuation Descriptor size */
   USB_DESC_TYPE_CONFIGURATION,   /* bDescriptorType: Configuration */
   USB_MSC_CONFIG_DESC_SIZ,
@@ -164,8 +161,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
   0x00     /*Polling interval in milliseconds*/
 };
 
-__ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __ALIGN_END  =
-{
+__ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __ALIGN_END  = {
   0x09,   /* bLength: Configuation Descriptor size */
   USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
   USB_MSC_CONFIG_DESC_SIZ,
@@ -237,8 +233,7 @@ USBD_StorageTypeDef *msc_storage = &USBD_MSC_fops;
   */
 uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 {
-  if (pdev->dev_speed == USBD_SPEED_HIGH)
-  {
+  if (pdev->dev_speed == USBD_SPEED_HIGH) {
     /* Open EP OUT */
     USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
     pdev->ep_out[MSC_OUT_EP & 0xFU].is_used = 1U;
@@ -246,9 +241,7 @@ uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
     /* Open EP IN */
     USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
     pdev->ep_in[MSC_IN_EP & 0xFU].is_used = 1U;
-  }
-  else
-  {
+  } else {
     /* Open EP OUT */
     USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
     pdev->ep_out[MSC_OUT_EP & 0xFU].is_used = 1U;
@@ -272,7 +265,7 @@ uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
   * @retval status
   */
 uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev,
-                         uint8_t cfgidx)
+                        uint8_t cfgidx)
 {
   /* Close MSC EPs */
   USBD_LL_CloseEP(pdev, MSC_OUT_EP);
@@ -301,26 +294,21 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
   uint8_t ret = USBD_OK;
   uint16_t status_info = 0U;
 
-  switch (req->bmRequest & USB_REQ_TYPE_MASK)
-  {
+  switch (req->bmRequest & USB_REQ_TYPE_MASK) {
     /* Class request */
     case USB_REQ_TYPE_CLASS:
       switch (req->bRequest)
       {
         case BOT_GET_MAX_LUN:
           if ((req->wValue  == 0U) && (req->wLength == 1U) &&
-              ((req->bmRequest & 0x80U) == 0x80U))
-          {
+              ((req->bmRequest & 0x80U) == 0x80U)) {
             if (msc_storage != NULL) {
               hmsc->max_lun = (uint32_t)msc_storage->GetMaxLun();
               USBD_CtlSendData(pdev, (uint8_t *)(void *)&hmsc->max_lun, 1U);
-            }
-            else {
+            } else {
               ret = USBD_FAIL;
             }
-          }
-          else
-          {
+          } else {
             USBD_CtlError(pdev, req);
             ret = USBD_FAIL;
           }
@@ -328,12 +316,9 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
 
         case BOT_RESET :
           if ((req->wValue  == 0U) && (req->wLength == 0U) &&
-              ((req->bmRequest & 0x80U) != 0x80U))
-          {
+              ((req->bmRequest & 0x80U) != 0x80U)) {
             MSC_BOT_Reset(pdev);
-          }
-          else
-          {
+          } else {
             USBD_CtlError(pdev, req);
             ret = USBD_FAIL;
           }
@@ -347,39 +332,29 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
       break;
     /* Interface & Endpoint request */
     case USB_REQ_TYPE_STANDARD:
-      switch (req->bRequest)
-      {
+      switch (req->bRequest) {
         case USB_REQ_GET_STATUS:
-          if (pdev->dev_state == USBD_STATE_CONFIGURED)
-          {
+          if (pdev->dev_state == USBD_STATE_CONFIGURED) {
             USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U);
-          }
-          else
-          {
+          } else {
             USBD_CtlError(pdev, req);
             ret = USBD_FAIL;
           }
           break;
 
         case USB_REQ_GET_INTERFACE:
-          if (pdev->dev_state == USBD_STATE_CONFIGURED)
-          {
+          if (pdev->dev_state == USBD_STATE_CONFIGURED) {
             USBD_CtlSendData(pdev, (uint8_t *)(void *)&hmsc->interface, 1U);
-          }
-          else
-          {
+          } else {
             USBD_CtlError(pdev, req);
             ret = USBD_FAIL;
           }
           break;
 
         case USB_REQ_SET_INTERFACE:
-          if (pdev->dev_state == USBD_STATE_CONFIGURED)
-          {
+          if (pdev->dev_state == USBD_STATE_CONFIGURED) {
             hmsc->interface = (uint8_t)(req->wValue);
-          }
-          else
-          {
+          } else {
             USBD_CtlError(pdev, req);
             ret = USBD_FAIL;
           }
@@ -392,34 +367,25 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
 
           /* Reactivate the EP */
           USBD_LL_CloseEP(pdev, (uint8_t)req->wIndex);
-          if ((((uint8_t)req->wIndex) & 0x80U) == 0x80U)
-          {
+          if ((((uint8_t)req->wIndex) & 0x80U) == 0x80U) {
             pdev->ep_in[(uint8_t)req->wIndex & 0xFU].is_used = 0U;
-            if (pdev->dev_speed == USBD_SPEED_HIGH)
-            {
+            if (pdev->dev_speed == USBD_SPEED_HIGH) {
               /* Open EP IN */
               USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK,
                              MSC_MAX_HS_PACKET);
-            }
-            else
-            {
+            } else {
               /* Open EP IN */
               USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK,
                              MSC_MAX_FS_PACKET);
             }
             pdev->ep_in[MSC_IN_EP & 0xFU].is_used = 1U;
-          }
-          else
-          {
+          } else {
             pdev->ep_out[(uint8_t)req->wIndex & 0xFU].is_used = 0U;
-            if (pdev->dev_speed == USBD_SPEED_HIGH)
-            {
+            if (pdev->dev_speed == USBD_SPEED_HIGH) {
               /* Open EP OUT */
               USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK,
                              MSC_MAX_HS_PACKET);
-            }
-            else
-            {
+            } else {
               /* Open EP OUT */
               USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK,
                              MSC_MAX_FS_PACKET);
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.h b/cores/arduino/stm32/usb/msc/usbd_msc.h
index 3c19a9a2ac..ee925e7be5 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.h
@@ -41,8 +41,7 @@ extern "C" {
 #define BOT_RESET                    0xFF
 #define USB_MSC_CONFIG_DESC_SIZ      32
 
-typedef struct _USBD_STORAGE
-{
+typedef struct _USBD_STORAGE {
   int8_t (* Init)(uint8_t lun);
   int8_t (* GetCapacity)(uint8_t lun, uint32_t *block_num, uint16_t *block_size);
   int8_t (* IsReady)(uint8_t lun);
@@ -54,8 +53,7 @@ typedef struct _USBD_STORAGE
 
 } USBD_StorageTypeDef;
 
-typedef struct
-{
+typedef struct {
   uint32_t                 max_lun;
   uint32_t                 interface;
   uint8_t                  bot_state;
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_bot.c b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
index f1a80a6b61..403d05425a 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
@@ -109,11 +109,9 @@ void MSC_BOT_DataIn(USBD_HandleTypeDef  *pdev,
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
-  switch (hmsc->bot_state)
-  {
+  switch (hmsc->bot_state) {
     case USBD_BOT_DATA_IN:
-      if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0)
-      {
+      if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) {
         MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
       }
       break;
@@ -139,16 +137,14 @@ void MSC_BOT_DataOut(USBD_HandleTypeDef  *pdev,
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
-  switch (hmsc->bot_state)
-  {
+  switch (hmsc->bot_state) {
     case USBD_BOT_IDLE:
       MSC_BOT_CBW_Decode(pdev);
       break;
 
     case USBD_BOT_DATA_OUT:
 
-      if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0)
-      {
+      if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) {
         MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
       }
       break;
@@ -174,47 +170,32 @@ static void  MSC_BOT_CBW_Decode(USBD_HandleTypeDef  *pdev)
   if ((USBD_LL_GetRxDataSize(pdev, MSC_OUT_EP) != USBD_BOT_CBW_LENGTH) ||
       (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) ||
       (hmsc->cbw.bLUN > 1U) ||
-      (hmsc->cbw.bCBLength < 1U) || (hmsc->cbw.bCBLength > 16U))
-  {
+      (hmsc->cbw.bCBLength < 1U) || (hmsc->cbw.bCBLength > 16U)) {
 
     SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
 
     hmsc->bot_status = USBD_BOT_STATUS_ERROR;
     MSC_BOT_Abort(pdev);
-  }
-  else
-  {
-    if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0)
-    {
-      if (hmsc->bot_state == USBD_BOT_NO_DATA)
-      {
+  } else {
+    if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) {
+      if (hmsc->bot_state == USBD_BOT_NO_DATA) {
         MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
-      }
-      else
-      {
+      } else {
         MSC_BOT_Abort(pdev);
       }
     }
     /*Burst xfer handled internally*/
     else if ((hmsc->bot_state != USBD_BOT_DATA_IN) &&
              (hmsc->bot_state != USBD_BOT_DATA_OUT) &&
-             (hmsc->bot_state != USBD_BOT_LAST_DATA_IN))
-    {
-      if (hmsc->bot_data_length > 0U)
-      {
+             (hmsc->bot_state != USBD_BOT_LAST_DATA_IN)) {
+      if (hmsc->bot_data_length > 0U) {
         MSC_BOT_SendData(pdev, hmsc->bot_data, hmsc->bot_data_length);
-      }
-      else if (hmsc->bot_data_length == 0U)
-      {
+      } else if (hmsc->bot_data_length == 0U) {
         MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
-      }
-      else
-      {
+      } else {
         MSC_BOT_Abort(pdev);
       }
-    }
-    else
-    {
+    } else {
       return;
     }
   }
@@ -279,15 +260,13 @@ static void  MSC_BOT_Abort(USBD_HandleTypeDef  *pdev)
 
   if ((hmsc->cbw.bmFlags == 0U) &&
       (hmsc->cbw.dDataLength != 0U) &&
-      (hmsc->bot_status == USBD_BOT_STATUS_NORMAL))
-  {
+      (hmsc->bot_status == USBD_BOT_STATUS_NORMAL)) {
     USBD_LL_StallEP(pdev, MSC_OUT_EP);
   }
 
   USBD_LL_StallEP(pdev, MSC_IN_EP);
 
-  if (hmsc->bot_status == USBD_BOT_STATUS_ERROR)
-  {
+  if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) {
     USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, (uint8_t *)(void *)&hmsc->cbw,
                            USBD_BOT_CBW_LENGTH);
   }
@@ -305,17 +284,13 @@ void  MSC_BOT_CplClrFeature(USBD_HandleTypeDef  *pdev, uint8_t epnum)
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
-  if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) /* Bad CBW Signature */
-  {
+  if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) {
+    /* Bad CBW Signature */
     USBD_LL_StallEP(pdev, MSC_IN_EP);
     hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
-  }
-  else if (((epnum & 0x80U) == 0x80U) && (hmsc->bot_status != USBD_BOT_STATUS_RECOVERY))
-  {
+  } else if (((epnum & 0x80U) == 0x80U) && (hmsc->bot_status != USBD_BOT_STATUS_RECOVERY)) {
     MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
-  }
-  else
-  {
+  } else {
     return;
   }
 }
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_bot.h b/cores/arduino/stm32/usb/msc/usbd_msc_bot.h
index 9b2f109969..de1af53223 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_bot.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_bot.h
@@ -57,8 +57,7 @@ extern "C" {
 #define USBD_BOTH_DIR                      2U
 
 
-typedef struct
-{
+typedef struct {
   uint32_t dSignature;
   uint32_t dTag;
   uint32_t dDataLength;
@@ -71,8 +70,7 @@ typedef struct
 USBD_MSC_BOT_CBWTypeDef;
 
 
-typedef struct
-{
+typedef struct {
   uint32_t dSignature;
   uint32_t dTag;
   uint32_t dDataResidue;
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.c b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
index 64556d91a7..7f960191a6 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_data.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
@@ -33,8 +33,7 @@ EndBSPDependencies */
 
 
 /* USB Mass storage Page 0 Inquiry Data */
-const uint8_t  MSC_Page00_Inquiry_Data[] =
-{
+const uint8_t  MSC_Page00_Inquiry_Data[] = {
   0x00,
   0x00,
   0x00,
@@ -43,9 +42,9 @@ const uint8_t  MSC_Page00_Inquiry_Data[] =
   0x80,
   0x83
 };
+
 /* USB Mass storage sense 6  Data */
-const uint8_t  MSC_Mode_Sense6_data[] =
-{
+const uint8_t  MSC_Mode_Sense6_data[] = {
   0x00,
   0x00,
   0x00,
@@ -55,9 +54,9 @@ const uint8_t  MSC_Mode_Sense6_data[] =
   0x00,
   0x00
 };
+
 /* USB Mass storage sense 10  Data */
-const uint8_t  MSC_Mode_Sense10_data[] =
-{
+const uint8_t  MSC_Mode_Sense10_data[] = {
   0x00,
   0x06,
   0x00,
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
index 1887134e79..4df0ee9e5c 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -64,8 +64,7 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun);
 */
 int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
 {
-  switch (cmd[0])
-  {
+  switch (cmd[0]) {
     case SCSI_TEST_UNIT_READY:
       SCSI_TestUnitReady(pdev, lun, cmd);
       break;
@@ -134,15 +133,13 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
   /* case 9 : Hi > D0 */
-  if (hmsc->cbw.dDataLength != 0U)
-  {
+  if (hmsc->cbw.dDataLength != 0U) {
     SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
 
     return -1;
   }
 
-  if (msc_storage->IsReady(lun) != 0)
-  {
+  if (msc_storage->IsReady(lun) != 0) {
     SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
     hmsc->bot_state = USBD_BOT_NO_DATA;
 
@@ -166,30 +163,25 @@ static int8_t  SCSI_Inquiry(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *par
   uint16_t len;
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
-  if (params[1] & 0x01U)/*Evpd is set*/
-  {
+  if (params[1] & 0x01U) {
+    /*Evpd is set*/
     len = LENGTH_INQUIRY_PAGE00;
     hmsc->bot_data_length = len;
 
-    while (len)
-    {
+    while (len) {
       len--;
       hmsc->bot_data[len] = MSC_Page00_Inquiry_Data[len];
     }
-  }
-  else
-  {
+  } else {
     pPage = (uint8_t *)(void *) & msc_storage->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN];
     len = (uint16_t)pPage[4] + 5U;
 
-    if (params[4] <= len)
-    {
+    if (params[4] <= len) {
       len = params[4];
     }
     hmsc->bot_data_length = len;
 
-    while (len)
-    {
+    while (len) {
       len--;
       hmsc->bot_data[len] = pPage[len];
     }
@@ -209,13 +201,10 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_
 {
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
-  if (msc_storage->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size) != 0)
-  {
+  if (msc_storage->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size) != 0) {
     SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
     return -1;
-  }
-  else
-  {
+  } else {
 
     hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24);
     hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16);
@@ -246,18 +235,14 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef  *pdev, uint8_t lun, ui
   uint32_t blk_nbr;
   uint16_t i;
 
-  for (i = 0U; i < 12U ; i++)
-  {
+  for (i = 0U; i < 12U ; i++) {
     hmsc->bot_data[i] = 0U;
   }
 
-  if (msc_storage->GetCapacity(lun, &blk_nbr, &blk_size) != 0U)
-  {
+  if (msc_storage->GetCapacity(lun, &blk_nbr, &blk_size) != 0U) {
     SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
     return -1;
-  }
-  else
-  {
+  } else {
     hmsc->bot_data[3] = 0x08U;
     hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1U) >> 24);
     hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1U) >> 16);
@@ -286,8 +271,7 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *p
   uint16_t len = 8U;
   hmsc->bot_data_length = len;
 
-  while (len)
-  {
+  while (len) {
     len--;
     hmsc->bot_data[len] = MSC_Mode_Sense6_data[len];
   }
@@ -308,8 +292,7 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *
 
   hmsc->bot_data_length = len;
 
-  while (len)
-  {
+  while (len) {
     len--;
     hmsc->bot_data[len] = MSC_Mode_Sense10_data[len];
   }
@@ -330,31 +313,27 @@ static int8_t SCSI_RequestSense(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t
   uint8_t i;
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
-  for (i = 0U ; i < REQUEST_SENSE_DATA_LEN; i++)
-  {
+  for (i = 0U ; i < REQUEST_SENSE_DATA_LEN; i++) {
     hmsc->bot_data[i] = 0U;
   }
 
   hmsc->bot_data[0] = 0x70U;
   hmsc->bot_data[7] = REQUEST_SENSE_DATA_LEN - 6U;
 
-  if ((hmsc->scsi_sense_head != hmsc->scsi_sense_tail))
-  {
+  if ((hmsc->scsi_sense_head != hmsc->scsi_sense_tail)) {
 
     hmsc->bot_data[2]     = hmsc->scsi_sense[hmsc->scsi_sense_head].Skey;
     hmsc->bot_data[12]    = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ;
     hmsc->bot_data[13]    = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC;
     hmsc->scsi_sense_head++;
 
-    if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH)
-    {
+    if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH) {
       hmsc->scsi_sense_head = 0U;
     }
   }
   hmsc->bot_data_length = REQUEST_SENSE_DATA_LEN;
 
-  if (params[4] <= REQUEST_SENSE_DATA_LEN)
-  {
+  if (params[4] <= REQUEST_SENSE_DATA_LEN) {
     hmsc->bot_data_length = params[4];
   }
   return 0;
@@ -376,8 +355,7 @@ void SCSI_SenseCode(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t sKey, uint8_
   hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey  = sKey;
   hmsc->scsi_sense[hmsc->scsi_sense_tail].w.ASC = ASC << 8;
   hmsc->scsi_sense_tail++;
-  if (hmsc->scsi_sense_tail == SENSE_LIST_DEEPTH)
-  {
+  if (hmsc->scsi_sense_tail == SENSE_LIST_DEEPTH) {
     hmsc->scsi_sense_tail = 0U;
   }
 }
@@ -406,8 +384,8 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
 {
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
-  if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
-  {
+  if (hmsc->bot_state == USBD_BOT_IDLE) {
+    /* Idle */
     /* case 10 : Ho <> Di */
     if ((hmsc->cbw.bmFlags & 0x80U) != 0x80U)
     {
@@ -415,8 +393,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
       return -1;
     }
 
-    if (msc_storage->IsReady(lun) != 0)
-    {
+    if (msc_storage->IsReady(lun) != 0) {
       SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
       return -1;
     }
@@ -429,16 +406,14 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
     hmsc->scsi_blk_len = ((uint32_t)params[7] <<  8) | (uint32_t)params[8];
 
     if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
-                               hmsc->scsi_blk_len) < 0)
-    {
+                               hmsc->scsi_blk_len) < 0) {
       return -1; /* error */
     }
 
     hmsc->bot_state = USBD_BOT_DATA_IN;
 
     /* cases 4,5 : Hi <> Dn */
-    if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size))
-    {
+    if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) {
       SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
       return -1;
     }
@@ -460,25 +435,22 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *para
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
   uint32_t len;
 
-  if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
-  {
+  if (hmsc->bot_state == USBD_BOT_IDLE) {
+    /* Idle */
     /* case 8 : Hi <> Do */
-    if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U)
-    {
+    if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U) {
       SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
       return -1;
     }
 
     /* Check whether Media is ready */
-    if (msc_storage->IsReady(lun) != 0)
-    {
+    if (msc_storage->IsReady(lun) != 0) {
       SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
       return -1;
     }
 
     /* Check If media is write-protected */
-    if (msc_storage->IsWriteProtected(lun) != 0)
-    {
+    if (msc_storage->IsWriteProtected(lun) != 0) {
       SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
       return -1;
     }
@@ -493,16 +465,14 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *para
 
     /* check if LBA address is in the right range */
     if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
-                               hmsc->scsi_blk_len) < 0)
-    {
+                               hmsc->scsi_blk_len) < 0) {
       return -1; /* error */
     }
 
     len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
 
     /* cases 3,11,13 : Hn,Ho <> D0 */
-    if (hmsc->cbw.dDataLength != len)
-    {
+    if (hmsc->cbw.dDataLength != len) {
       SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
       return -1;
     }
@@ -512,9 +482,8 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *para
     /* Prepare EP to receive first data packet */
     hmsc->bot_state = USBD_BOT_DATA_OUT;
     USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, hmsc->bot_data, len);
-  }
-  else /* Write Process ongoing */
-  {
+  } else {
+    /* Write Process ongoing */
     return SCSI_ProcessWrite(pdev, lun);
   }
   return 0;
@@ -533,15 +502,13 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *par
 {
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
-  if ((params[1] & 0x02U) == 0x02U)
-  {
+  if ((params[1] & 0x02U) == 0x02U) {
     SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
     return -1; /* Error, Verify Mode Not supported*/
   }
 
   if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
-                             hmsc->scsi_blk_len) < 0)
-  {
+                             hmsc->scsi_blk_len) < 0) {
     return -1; /* error */
   }
   hmsc->bot_data_length = 0U;
@@ -561,8 +528,7 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
 {
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
-  if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr)
-  {
+  if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr) {
     SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
     return -1;
   }
@@ -585,8 +551,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef  *pdev, uint8_t lun)
   if (msc_storage->Read(lun,
                         hmsc->bot_data,
                         hmsc->scsi_blk_addr,
-                        (len / hmsc->scsi_blk_size)) < 0)
-  {
+                        (len / hmsc->scsi_blk_size)) < 0) {
     SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR);
     return -1;
   }
@@ -599,8 +564,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef  *pdev, uint8_t lun)
   /* case 6 : Hi = Di */
   hmsc->csw.dDataResidue -= len;
 
-  if (hmsc->scsi_blk_len == 0U)
-  {
+  if (hmsc->scsi_blk_len == 0U) {
     hmsc->bot_state = USBD_BOT_LAST_DATA_IN;
   }
   return 0;
@@ -622,8 +586,7 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef  *pdev, uint8_t lun)
 
   if (msc_storage->Write(lun, hmsc->bot_data,
                          hmsc->scsi_blk_addr,
-                         (len / hmsc->scsi_blk_size)) < 0)
-  {
+                         (len / hmsc->scsi_blk_size)) < 0) {
     SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, WRITE_FAULT);
 
     return -1;
@@ -635,12 +598,9 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef  *pdev, uint8_t lun)
   /* case 12 : Ho = Do */
   hmsc->csw.dDataResidue -= len;
 
-  if (hmsc->scsi_blk_len == 0U)
-  {
+  if (hmsc->scsi_blk_len == 0U) {
     MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
-  }
-  else
-  {
+  } else {
     len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET);
     /* Prepare EP to Receive next packet */
     USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, hmsc->bot_data, len);
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
index 175b83578c..3c0d97ac6c 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
@@ -106,13 +106,10 @@ extern  uint8_t ReadCapacity10_Data[];
 extern  uint8_t ReadFormatCapacity_Data [];
 
 
-typedef struct _SENSE_ITEM
-{
+typedef struct _SENSE_ITEM {
   char Skey;
-  union
-  {
-    struct _ASCs
-    {
+  union {
+    struct _ASCs {
       char ASC;
       char ASCQ;
     } b;
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
index 4a0c4a6902..a9f9752de8 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
@@ -69,8 +69,7 @@ int8_t  STORAGE_Inquirydata[] =  /* 36 */
   '0', '.', '0', '1',                     /* Version      : 4 Bytes */
 };
 
-USBD_StorageTypeDef USBD_MSC_fops =
-{
+USBD_StorageTypeDef USBD_MSC_fops = {
   STORAGE_Init,
   STORAGE_GetCapacity,
   STORAGE_IsReady,
@@ -113,11 +112,12 @@ int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_siz
 * Description    : Handle the Read operation from the STORAGE card.
 * Input          : None.
 * Output         : None.
-* Return         : None.
+* Return         : 0 if device is ready, otherwise not ready
 *******************************************************************************/
 int8_t  STORAGE_IsReady(uint8_t lun)
 {
-  return (0);
+  // the dummy device is never ready
+  return 1;
 }
 
 /*******************************************************************************

From ff6cecfb8078826fb6f8ed76c7120644b468424a Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Tue, 2 Jun 2020 21:27:25 +0100
Subject: [PATCH 12/37] fixed small type and more formatting

---
 cores/arduino/USB.cpp                            |  4 ++--
 cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp | 10 ++++------
 cores/arduino/stm32/usb/msc/usbd_msc.c           |  6 ++----
 3 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
index 3685543257..a7724b9ffd 100644
--- a/cores/arduino/USB.cpp
+++ b/cores/arduino/USB.cpp
@@ -34,7 +34,7 @@ void USB::begin()
   }
 }
 
-void USB::register_msc(USBD_StorageTypeDef* fops) 
+void USB::register_msc(USBD_StorageTypeDef *fops)
 {
   USBD_MSC_RegisterStorage(&hUSBD_Device, fops);
 }
@@ -70,7 +70,7 @@ void USB::initialize()
 #endif
 
   /* Start Device Process */
-  USBD_Start(&hUSBD_Device_CDC);
+  USBD_Start(&hUSBD_Device);
   initialized = true;
 }
 
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index 05ec62476d..64c557a37a 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -270,10 +270,9 @@ static uint8_t  USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
 static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
                                      USBD_SetupReqTypedef *req)
 {
-  switch (req->bmRequest & USB_REQ_RECIPIENT_MASK)
-  {
+  switch (req->bmRequest & USB_REQ_RECIPIENT_MASK) {
     case USB_REQ_RECIPIENT_INTERFACE:
-      switch(req->wIndex) {
+      switch (req->wIndex) {
         case CDC_ACM_INTERFACE:
         case CDC_COM_INTERFACE:
           return USBD_CDC.Setup(pdev, req);
@@ -397,10 +396,9 @@ static uint8_t  USBD_COMPOSITE_SOF(USBD_HandleTypeDef *pdev)
   * @retval status
   */
 static uint8_t  USBD_COMPOSITE_DataOut(USBD_HandleTypeDef *pdev,
-                                      uint8_t epnum)
+                                       uint8_t epnum)
 {
-  switch (epnum)
-  {
+  switch (epnum) {
     case CDC_IN_EP:
     case CDC_CMD_EP:
     case CDC_OUT_EP:
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.c b/cores/arduino/stm32/usb/msc/usbd_msc.c
index b9d300078c..2de3df3428 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.c
@@ -202,8 +202,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __AL
 };
 
 /* USB Standard Device Descriptor */
-__ALIGN_BEGIN  uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]  __ALIGN_END =
-{
+__ALIGN_BEGIN  uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]  __ALIGN_END = {
   USB_LEN_DEV_QUALIFIER_DESC,
   USB_DESC_TYPE_DEVICE_QUALIFIER,
   0x00,
@@ -297,8 +296,7 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
   switch (req->bmRequest & USB_REQ_TYPE_MASK) {
     /* Class request */
     case USB_REQ_TYPE_CLASS:
-      switch (req->bRequest)
-      {
+      switch (req->bRequest) {
         case BOT_GET_MAX_LUN:
           if ((req->wValue  == 0U) && (req->wLength == 1U) &&
               ((req->bmRequest & 0x80U) == 0x80U)) {

From da5c702a3f351f0ef18204222741aed0d529e003 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Tue, 2 Jun 2020 21:39:02 +0100
Subject: [PATCH 13/37] added ifdef for USB.c

---
 cores/arduino/USB.cpp | 6 +++++-
 cores/arduino/USB.h   | 4 ++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
index a7724b9ffd..c5334f9902 100644
--- a/cores/arduino/USB.cpp
+++ b/cores/arduino/USB.cpp
@@ -16,6 +16,8 @@
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
+#ifdef USBCON
+
 #include "usbd_cdc.h"
 #include "usbd_cdc_msc.h"
 #include "usbd_msc.h"
@@ -86,4 +88,6 @@ void USB::deinitialize()
   USBD_Stop(&hUSBD_Device);
   USBD_DeInit(&hUSBD_Device);
   initialized = false;
-}
\ No newline at end of file
+}
+
+#endif // USBCON
diff --git a/cores/arduino/USB.h b/cores/arduino/USB.h
index 25572d07a2..a743dd4011 100644
--- a/cores/arduino/USB.h
+++ b/cores/arduino/USB.h
@@ -19,8 +19,8 @@
 #ifndef _USB_H_
 #define _USB_H_
 
-#if defined (USBCON)
-#include "Stream.h"
+#ifdef USBCON
+
 #include "usbd_core.h"
 #include "usbd_msc.h"
 

From ffd635d4103fe48c53d918d7018acceda38012d5 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Tue, 2 Jun 2020 23:11:35 +0100
Subject: [PATCH 14/37] fixed bug in ST MSC SCSI library

---
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c | 24 ++++++++++-----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
index 4df0ee9e5c..eb79d9dcbf 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -66,50 +66,50 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
 {
   switch (cmd[0]) {
     case SCSI_TEST_UNIT_READY:
-      SCSI_TestUnitReady(pdev, lun, cmd);
+      return SCSI_TestUnitReady(pdev, lun, cmd);
       break;
 
     case SCSI_REQUEST_SENSE:
-      SCSI_RequestSense(pdev, lun, cmd);
+      return SCSI_RequestSense(pdev, lun, cmd);
       break;
     case SCSI_INQUIRY:
-      SCSI_Inquiry(pdev, lun, cmd);
+      return SCSI_Inquiry(pdev, lun, cmd);
       break;
 
     case SCSI_START_STOP_UNIT:
-      SCSI_StartStopUnit(pdev, lun, cmd);
+      return SCSI_StartStopUnit(pdev, lun, cmd);
       break;
 
     case SCSI_ALLOW_MEDIUM_REMOVAL:
-      SCSI_StartStopUnit(pdev, lun, cmd);
+      return SCSI_StartStopUnit(pdev, lun, cmd);
       break;
 
     case SCSI_MODE_SENSE6:
-      SCSI_ModeSense6(pdev, lun, cmd);
+      return SCSI_ModeSense6(pdev, lun, cmd);
       break;
 
     case SCSI_MODE_SENSE10:
-      SCSI_ModeSense10(pdev, lun, cmd);
+      return SCSI_ModeSense10(pdev, lun, cmd);
       break;
 
     case SCSI_READ_FORMAT_CAPACITIES:
-      SCSI_ReadFormatCapacity(pdev, lun, cmd);
+      return SCSI_ReadFormatCapacity(pdev, lun, cmd);
       break;
 
     case SCSI_READ_CAPACITY10:
-      SCSI_ReadCapacity10(pdev, lun, cmd);
+      return SCSI_ReadCapacity10(pdev, lun, cmd);
       break;
 
     case SCSI_READ10:
-      SCSI_Read10(pdev, lun, cmd);
+      return SCSI_Read10(pdev, lun, cmd);
       break;
 
     case SCSI_WRITE10:
-      SCSI_Write10(pdev, lun, cmd);
+      return SCSI_Write10(pdev, lun, cmd);
       break;
 
     case SCSI_VERIFY10:
-      SCSI_Verify10(pdev, lun, cmd);
+      return SCSI_Verify10(pdev, lun, cmd);
       break;
 
     default:

From 7676e07c74bc415a03e608a0c8d761608c2a78b5 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Tue, 2 Jun 2020 23:25:26 +0100
Subject: [PATCH 15/37] fixed formatting

---
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
index eb79d9dcbf..a1ca379344 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -387,8 +387,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
   if (hmsc->bot_state == USBD_BOT_IDLE) {
     /* Idle */
     /* case 10 : Ho <> Di */
-    if ((hmsc->cbw.bmFlags & 0x80U) != 0x80U)
-    {
+    if ((hmsc->cbw.bmFlags & 0x80U) != 0x80U) {
       SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
       return -1;
     }

From 376112515416466cc41927a14d00deae804510c5 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Wed, 3 Jun 2020 13:28:02 +0100
Subject: [PATCH 16/37] introduced usb msc abstract class

---
 cores/arduino/USB.cpp                         | 38 +++++++++--
 cores/arduino/USB.h                           | 15 ++++-
 cores/arduino/USBMscHandler.h                 | 66 +++++++++++++++++++
 cores/arduino/stm32/usb/msc/usbd_msc.h        |  2 +-
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c   |  2 +-
 ...c_storage_if.c => usbd_msc_storage_if.cpp} | 43 +++++++-----
 .../stm32/usb/msc/usbd_msc_storage_if.h       |  7 ++
 cores/arduino/stm32/usb/usbd_ep_conf.h        | 24 +------
 cores/arduino/stm32/usb/usbd_if.c             |  7 --
 cores/arduino/stm32/usb/usbd_if.h             |  4 +-
 10 files changed, 152 insertions(+), 56 deletions(-)
 create mode 100644 cores/arduino/USBMscHandler.h
 rename cores/arduino/stm32/usb/msc/{usbd_msc_storage_if.c => usbd_msc_storage_if.cpp} (87%)

diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
index c5334f9902..b1b703160e 100644
--- a/cores/arduino/USB.cpp
+++ b/cores/arduino/USB.cpp
@@ -36,15 +36,32 @@ void USB::begin()
   }
 }
 
-void USB::register_msc(USBD_StorageTypeDef *fops)
+#ifdef USBD_USE_MSC_CLASS
+DummyUSBMscHandler dummyHandler;
+
+void USB::registerMscHandler(USBMscHandler &handler)
 {
-  USBD_MSC_RegisterStorage(&hUSBD_Device, fops);
+  pSingleMscHandler= &handler;
+  registerMscHandlers(1, &pSingleMscHandler, USBD_MSC_fops.pInquiry);
+}
+
+void USB::registerMscHandlers(uint8_t count, USBMscHandler **ppHandlers, uint8_t *pInquiryData)
+{
+  if (count == 0) {
+    registerMscHandler(dummyHandler);
+  } else {
+    ppUsbMscHandlers = ppHandlers;
+    usbMscMaxLun = count - 1;
+    USBD_MSC_fops.pInquiry = pInquiryData;
+  }
 }
+#endif
 
 void USB::initialize()
 {
   hUSBD_Device_CDC = &hUSBD_Device;
 
+
   /* Init Device Library */
   if (USBD_Init(&hUSBD_Device, &USBD_Desc, 0) != USBD_OK) {
     return;
@@ -55,18 +72,27 @@ void USB::initialize()
   if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC) != USBD_OK) {
     return;
   }
-  if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) != USBD_OK) {
+#elif USBD_USE_CDC_MSC
+  if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC_MSC) != USBD_OK) {
     return;
   }
-#elif USBD_USE_CDC_MSC
+#elif USBD_USE_MSC
   if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC_MSC) != USBD_OK) {
     return;
   }
+#endif
+
+#ifdef USBD_USE_CDC_CLASS
   if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) != USBD_OK) {
     return;
   }
-#elif USBD_USE_MSC
-  if (USBD_RegisterClass(&hUSBD_Device, &USBD_CDC_MSC) != USBD_OK) {
+#endif
+
+#ifdef USBD_USE_MSC_CLASS
+  if (ppUsbMscHandlers == nullptr) {
+    registerMscHandler(dummyHandler);
+  }
+  if (USBD_MSC_RegisterStorage(&hUSBD_Device, &USBD_MSC_fops) != USBD_OK) {
     return;
   }
 #endif
diff --git a/cores/arduino/USB.h b/cores/arduino/USB.h
index a743dd4011..a5e17aa35a 100644
--- a/cores/arduino/USB.h
+++ b/cores/arduino/USB.h
@@ -22,11 +22,18 @@
 #ifdef USBCON
 
 #include "usbd_core.h"
-#include "usbd_msc.h"
+#include "usbd_ep_conf.h"
+
+#ifdef USBD_USE_MSC_CLASS
+#include "USBMscHandler.h"
+#endif
 
 class USB {
   public:
-    void register_msc(USBD_StorageTypeDef *fops);
+#ifdef USBD_USE_MSC_CLASS
+    void registerMscHandler(USBMscHandler &pHandler);
+    void registerMscHandlers(uint8_t count, USBMscHandler **pHandlers, uint8_t *pInquiryData);
+#endif
 
     void begin(void);
 
@@ -39,6 +46,10 @@ class USB {
     bool initialized;
 
     USBD_HandleTypeDef hUSBD_Device;
+
+#ifdef USBD_USE_MSC_CLASS
+    USBMscHandler *pSingleMscHandler;
+#endif
 };
 
 extern USB USBDevice;
diff --git a/cores/arduino/USBMscHandler.h b/cores/arduino/USBMscHandler.h
new file mode 100644
index 0000000000..fe48329449
--- /dev/null
+++ b/cores/arduino/USBMscHandler.h
@@ -0,0 +1,66 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+#ifndef _USB_MSC_HANDLER_H_
+#define _USB_MSC_HANDLER_H_
+
+#ifdef USBCON
+
+#include "usbd_core.h"
+#include "usbd_msc.h"
+
+/* Handler for mass storage devices */
+class USBMscHandler {
+  public:
+    // Example: A 128 MB SD card has 245760 blocks, at a block size of 512 bytes
+    // Returns true if successful, otherwise false.
+    virtual bool GetCapacity(uint32_t * blockNum, uint16_t * blockSize) = 0;
+
+    // Read [blk_len] blocks, starting at [blk_addr] into [buf].
+    // Returns true if successful, otherwise false.
+    virtual bool Read(uint8_t * pBuf, uint32_t blkAddr, uint16_t blkLen) = 0;
+
+    // Write [blk_len] blocks, starting at [blk_addr] into [buf].
+    // Returns true if successful, otherwise false.
+    virtual bool Write(uint8_t * pBuf, uint32_t blkAddr, uint16_t blkLen) = 0;
+
+    /** Optional functions **/
+
+    virtual bool Init() { return true; }
+
+    // Return false if the mass storage device has not been connected or initialized yet.
+    virtual bool IsReady() { return true; }
+
+    // If the device should be read-only then this function should return true.
+    virtual bool IsWriteProtected() { return false; }
+};
+
+class DummyUSBMscHandler : public USBMscHandler {
+  public:
+    // Any call to one of these functions always fails.
+    bool GetCapacity(uint32_t *pBlockNum, uint16_t *pBlockSize) { return false; }
+    bool Read(uint8_t *pBuf, uint32_t blockAddr, uint16_t blkLen) { return false; }
+    bool Write(uint8_t *pBuf, uint32_t blockAddr, uint16_t blkLen) { return false; }
+
+    // The dummy handler is never ready.
+    bool IsReady() { return false; }
+};
+
+#endif
+#endif
\ No newline at end of file
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.h b/cores/arduino/stm32/usb/msc/usbd_msc.h
index ee925e7be5..861abd5bec 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.h
@@ -49,7 +49,7 @@ typedef struct _USBD_STORAGE {
   int8_t (* Read)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
   int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
   int8_t (* GetMaxLun)(void);
-  int8_t *pInquiry;
+  uint8_t *pInquiry;
 
 } USBD_StorageTypeDef;
 
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
index a1ca379344..589355c365 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -173,7 +173,7 @@ static int8_t  SCSI_Inquiry(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *par
       hmsc->bot_data[len] = MSC_Page00_Inquiry_Data[len];
     }
   } else {
-    pPage = (uint8_t *)(void *) & msc_storage->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN];
+    pPage = &msc_storage->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN];
     len = (uint16_t)pPage[4] + 5U;
 
     if (params[4] <= len) {
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp
similarity index 87%
rename from cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
rename to cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp
index a9f9752de8..b6d80a52c1 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp
@@ -28,11 +28,11 @@
 - "stm32xxxxx_{eval}{discovery}{adafruit}_sd.c"
 EndBSPDependencies */
 
+#include "USBMscHandler.h"
 #include "usbd_msc_storage_if.h"
 
-#define STORAGE_LUN_NBR                  1U
-#define STORAGE_BLK_NBR                  0x10000U
-#define STORAGE_BLK_SIZ                  0x200U
+uint8_t usbMscMaxLun = 0;
+USBMscHandler **ppUsbMscHandlers = nullptr;
 
 int8_t STORAGE_Init(uint8_t lun);
 
@@ -52,7 +52,7 @@ int8_t STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
 int8_t STORAGE_GetMaxLun(void);
 
 /* USB Mass storage Standard Inquiry Data */
-int8_t  STORAGE_Inquirydata[] =  /* 36 */
+uint8_t  STORAGE_Inquirydata[] =  /* 36 */
 {
   /* LUN 0 */
   0x00,
@@ -78,9 +78,13 @@ USBD_StorageTypeDef USBD_MSC_fops = {
   STORAGE_Write,
   STORAGE_GetMaxLun,
   STORAGE_Inquirydata,
-
 };
 
+#define HANDLER_LUN_CHECK \
+  if (lun > usbMscMaxLun) { \
+    return 1; \
+  }
+
 /*******************************************************************************
 * Function Name  : Read_Memory
 * Description    : Handle the Read operation from the microSD card.
@@ -90,7 +94,9 @@ USBD_StorageTypeDef USBD_MSC_fops = {
 *******************************************************************************/
 int8_t STORAGE_Init(uint8_t lun)
 {
-  return (0);
+  HANDLER_LUN_CHECK
+
+  return !ppUsbMscHandlers[lun]->Init();
 }
 
 /*******************************************************************************
@@ -102,9 +108,9 @@ int8_t STORAGE_Init(uint8_t lun)
 *******************************************************************************/
 int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
 {
-  *block_num  = STORAGE_BLK_NBR;
-  *block_size = STORAGE_BLK_SIZ;
-  return (0);
+  HANDLER_LUN_CHECK
+
+  return !ppUsbMscHandlers[lun]->GetCapacity(block_num, block_size);
 }
 
 /*******************************************************************************
@@ -116,8 +122,9 @@ int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_siz
 *******************************************************************************/
 int8_t  STORAGE_IsReady(uint8_t lun)
 {
-  // the dummy device is never ready
-  return 1;
+  HANDLER_LUN_CHECK
+
+  return !ppUsbMscHandlers[lun]->IsReady();
 }
 
 /*******************************************************************************
@@ -129,7 +136,9 @@ int8_t  STORAGE_IsReady(uint8_t lun)
 *******************************************************************************/
 int8_t  STORAGE_IsWriteProtected(uint8_t lun)
 {
-  return  0;
+  HANDLER_LUN_CHECK
+
+  return !ppUsbMscHandlers[lun]->IsWriteProtected();
 }
 
 /*******************************************************************************
@@ -142,7 +151,9 @@ int8_t  STORAGE_IsWriteProtected(uint8_t lun)
 int8_t STORAGE_Read(uint8_t lun, uint8_t *buf,
                     uint32_t blk_addr, uint16_t blk_len)
 {
-  return 0;
+  HANDLER_LUN_CHECK
+
+  return !ppUsbMscHandlers[lun]->Read(buf, blk_addr, blk_len);
 }
 
 /*******************************************************************************
@@ -155,7 +166,9 @@ int8_t STORAGE_Read(uint8_t lun, uint8_t *buf,
 int8_t STORAGE_Write(uint8_t lun, uint8_t *buf,
                      uint32_t blk_addr, uint16_t blk_len)
 {
-  return (0);
+  HANDLER_LUN_CHECK
+
+  return !ppUsbMscHandlers[lun]->Write(buf, blk_addr, blk_len);
 }
 
 /*******************************************************************************
@@ -167,7 +180,7 @@ int8_t STORAGE_Write(uint8_t lun, uint8_t *buf,
 *******************************************************************************/
 int8_t STORAGE_GetMaxLun(void)
 {
-  return (STORAGE_LUN_NBR - 1);
+  return usbMscMaxLun;
 }
 
 #endif /* USBD_USE_MSC_CLASS */
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h
index 676b250195..cddadecda0 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.h
@@ -29,6 +29,13 @@ extern "C" {
 
 extern USBD_StorageTypeDef  USBD_MSC_fops;
 
+#ifdef __cplusplus
+#include "USBMscHandler.h"
+
+extern uint8_t usbMscMaxLun;
+extern USBMscHandler **ppUsbMscHandlers;
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.h b/cores/arduino/stm32/usb/usbd_ep_conf.h
index 6d8003ef2f..18f46cc58f 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.h
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.h
@@ -33,6 +33,7 @@ typedef struct {
 #endif
 } ep_desc_t;
 
+// *INDENT-OFF*
 
 /* CDC Endpoints Configurations */
 #ifdef USBD_USE_CDC
@@ -90,29 +91,10 @@ typedef struct {
   /* Size in words, byte size divided by 2 */
   #define PMA_EP0_OUT_ADDR    (8 * DEV_NUM_EP)
   #define PMA_EP0_IN_ADDR     (PMA_EP0_OUT_ADDR + USB_MAX_EP0_SIZE)
-
-  #ifdef USBD_USE_CDC
-    #define PMA_CDC_OUT_BASE    (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE)
-    #define PMA_CDC_OUT_ADDR    ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \
-                                (PMA_CDC_OUT_BASE << 16U))
-    #define PMA_CDC_IN_ADDR     (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2)
-    #define PMA_CDC_CMD_ADDR    (PMA_CDC_IN_ADDR + CDC_CMD_PACKET_SIZE)
-  #endif /* USBD_USE_CDC */
-  #ifdef USBD_USE_CDC_MSC
-    #define PMA_CDC_OUT_ADDR0   (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE)
-    #define PMA_CDC_OUT_ADDR1   (PMA_CDC_OUT_ADDR1 + USB_FS_MAX_PACKET_SIZE)
-    #define PMA_CDC_OUT_ADDR    (PMA_CDC_OUT_ADDR0 | (PMA_CDC_OUT_ADDR1 << 16U)) // cdc out has a double buffer
-    #define PMA_CDC_IN_ADDR     (PMA_CDC_OUT_ADDR1 + USB_FS_MAX_PACKET_SIZE)
-    #define PMA_CDC_CMD_ADDR    (PMA_CDC_IN_ADDR + USB_FS_MAX_PACKET_SIZE)
-    #define PMA_MSC_IN_ADDR     (PMA_CDC_CMD_ADDR + CDC_CMD_PACKET_SIZE)
-    #define PMA_MSC_IN_ADDR     (PMA_MSC_IN_ADDR + USB_FS_MAX_PACKET_SIZE)
-  #endif /* USBD_USE_CDC_MSC */
-  #ifdef USBD_USE_HID_COMPOSITE
-    #define PMA_MOUSE_IN_ADDR   (PMA_EP0_IN_ADDR + HID_MOUSE_EPIN_SIZE)
-    #define PMA_KEYBOARD_IN_ADDR    (PMA_MOUSE_IN_ADDR + HID_KEYBOARD_EPIN_SIZE)
-  #endif /* USBD_USE_HID_COMPOSITE */
 #endif /* USB */
 
+// *INDENT-ON*
+
 extern const ep_desc_t ep_def[DEV_NUM_EP + 1];
 
 
diff --git a/cores/arduino/stm32/usb/usbd_if.c b/cores/arduino/stm32/usb/usbd_if.c
index e579140f72..0ea854909e 100644
--- a/cores/arduino/stm32/usb/usbd_if.c
+++ b/cores/arduino/stm32/usb/usbd_if.c
@@ -155,11 +155,4 @@ WEAK void USBD_reenumerate(void)
 #else /* !defined(USBD_REENUM_DISABLED) */
 WEAK void USBD_reenumerate(void) { }
 #endif
-
-#ifdef USBD_USE_CDC
-void USBD_CDC_init(void)
-{
-  CDC_init();
-}
-#endif /* USBD_USE_CDC */
 #endif /* USBCON */
diff --git a/cores/arduino/stm32/usb/usbd_if.h b/cores/arduino/stm32/usb/usbd_if.h
index dc026240fe..bcd54020e6 100644
--- a/cores/arduino/stm32/usb/usbd_if.h
+++ b/cores/arduino/stm32/usb/usbd_if.h
@@ -24,9 +24,7 @@ extern "C" {
 #endif
 
 void USBD_reenumerate(void);
-#ifdef USBD_USE_CDC
-void USBD_CDC_init(void);
-#endif
+
 #ifdef __cplusplus
 }
 #endif

From 6f00830eb8979808692a187abe30685edefdac21 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Wed, 3 Jun 2020 13:42:22 +0100
Subject: [PATCH 17/37] changes to formatting

---
 cores/arduino/USBMscHandler.h          | 39 ++++++++++++++++++++------
 cores/arduino/stm32/usb/usbd_ep_conf.c |  6 +++-
 2 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/cores/arduino/USBMscHandler.h b/cores/arduino/USBMscHandler.h
index fe48329449..f349fd5705 100644
--- a/cores/arduino/USBMscHandler.h
+++ b/cores/arduino/USBMscHandler.h
@@ -20,7 +20,7 @@
 #ifndef _USB_MSC_HANDLER_H_
 #define _USB_MSC_HANDLER_H_
 
-#ifdef USBCON
+#if defined(USBCON) && defined(USBD_USE_MSC_CLASS)
 
 #include "usbd_core.h"
 #include "usbd_msc.h"
@@ -42,24 +42,47 @@ class USBMscHandler {
 
     /** Optional functions **/
 
-    virtual bool Init() { return true; }
+    virtual bool Init()
+    {
+      return true;
+    }
 
     // Return false if the mass storage device has not been connected or initialized yet.
-    virtual bool IsReady() { return true; }
+    virtual bool IsReady()
+    {
+      return true;
+    }
 
     // If the device should be read-only then this function should return true.
-    virtual bool IsWriteProtected() { return false; }
+    virtual bool IsWriteProtected()
+    {
+      return false;
+    }
 };
 
 class DummyUSBMscHandler : public USBMscHandler {
   public:
     // Any call to one of these functions always fails.
-    bool GetCapacity(uint32_t *pBlockNum, uint16_t *pBlockSize) { return false; }
-    bool Read(uint8_t *pBuf, uint32_t blockAddr, uint16_t blkLen) { return false; }
-    bool Write(uint8_t *pBuf, uint32_t blockAddr, uint16_t blkLen) { return false; }
+    bool GetCapacity(uint32_t *pBlockNum, uint16_t *pBlockSize)
+    {
+      return false;
+    }
+
+    bool Read(uint8_t *pBuf, uint32_t blockAddr, uint16_t blkLen)
+    {
+      return false;
+    }
+
+    bool Write(uint8_t *pBuf, uint32_t blockAddr, uint16_t blkLen)
+    {
+      return false;
+    }
 
     // The dummy handler is never ready.
-    bool IsReady() { return false; }
+    bool IsReady()
+    {
+      return false;
+    }
 };
 
 #endif
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.c b/cores/arduino/stm32/usb/usbd_ep_conf.c
index 91ea4a657c..74f4eb44c6 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.c
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.c
@@ -25,6 +25,8 @@
   #define EP_DESC(ADDR, SIZE, KIND_TYP)  {ADDR, SIZE, KIND_TYP}
 #endif
 
+// *INDENT-OFF*
+
 #ifdef USBD_USE_CDC
   #ifdef USE_USB_HS
     #define CDC_DATA_MAX_PACKET_SIZE  CDC_DATA_HS_MAX_PACKET_SIZE
@@ -71,7 +73,7 @@
   #else /* USE_USB_FS */
     #define HID_MAX_PACKET_SIZE  USB_FS_MAX_PACKET_SIZE
   #endif
-  
+
   const ep_desc_t ep_def[] = {
     EP_DESC(0x00,                   HID_MAX_PACKET_SIZE, PCD_SNG_BUF),
     EP_DESC(0x80,                   HID_MAX_PACKET_SIZE, PCD_SNG_BUF),
@@ -80,6 +82,8 @@
   };
 #endif /* USBD_USE_HID_COMPOSITE */
 
+// *INDENT-OFF*
+
 #endif /* HAL_PCD_MODULE_ENABLED && USBCON */
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 

From f578d6c63378701060e369eec031e6f2aff788e9 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Wed, 3 Jun 2020 13:47:59 +0100
Subject: [PATCH 18/37] more formatting changes

---
 cores/arduino/USBMscHandler.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/cores/arduino/USBMscHandler.h b/cores/arduino/USBMscHandler.h
index f349fd5705..9f8afea1e1 100644
--- a/cores/arduino/USBMscHandler.h
+++ b/cores/arduino/USBMscHandler.h
@@ -30,15 +30,15 @@ class USBMscHandler {
   public:
     // Example: A 128 MB SD card has 245760 blocks, at a block size of 512 bytes
     // Returns true if successful, otherwise false.
-    virtual bool GetCapacity(uint32_t * blockNum, uint16_t * blockSize) = 0;
+    virtual bool GetCapacity(uint32_t *pBlockNum, uint16_t *pBlockSize) = 0;
 
     // Read [blk_len] blocks, starting at [blk_addr] into [buf].
     // Returns true if successful, otherwise false.
-    virtual bool Read(uint8_t * pBuf, uint32_t blkAddr, uint16_t blkLen) = 0;
+    virtual bool Read(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) = 0;
 
     // Write [blk_len] blocks, starting at [blk_addr] into [buf].
     // Returns true if successful, otherwise false.
-    virtual bool Write(uint8_t * pBuf, uint32_t blkAddr, uint16_t blkLen) = 0;
+    virtual bool Write(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) = 0;
 
     /** Optional functions **/
 

From 805113ddde1cbd74fbcb0e662db3cd9a17254521 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Wed, 3 Jun 2020 13:50:44 +0100
Subject: [PATCH 19/37] and more formatting changes

---
 cores/arduino/USB.cpp | 2 +-
 cores/arduino/USB.h   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
index b1b703160e..fa5fd0e272 100644
--- a/cores/arduino/USB.cpp
+++ b/cores/arduino/USB.cpp
@@ -41,7 +41,7 @@ DummyUSBMscHandler dummyHandler;
 
 void USB::registerMscHandler(USBMscHandler &handler)
 {
-  pSingleMscHandler= &handler;
+  pSingleMscHandler = &handler;
   registerMscHandlers(1, &pSingleMscHandler, USBD_MSC_fops.pInquiry);
 }
 
diff --git a/cores/arduino/USB.h b/cores/arduino/USB.h
index a5e17aa35a..1c06240d27 100644
--- a/cores/arduino/USB.h
+++ b/cores/arduino/USB.h
@@ -25,7 +25,7 @@
 #include "usbd_ep_conf.h"
 
 #ifdef USBD_USE_MSC_CLASS
-#include "USBMscHandler.h"
+  #include "USBMscHandler.h"
 #endif
 
 class USB {

From 5df8d9cbfd7d8122a75463938cba6555d12d45c8 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Wed, 3 Jun 2020 15:23:14 +0100
Subject: [PATCH 20/37] small bugfixes

---
 cores/arduino/USB.cpp                      | 16 +++++++++++-----
 libraries/SrcWrapper/src/stm32/hw_config.c |  4 ----
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
index fa5fd0e272..8f16e1e9ea 100644
--- a/cores/arduino/USB.cpp
+++ b/cores/arduino/USB.cpp
@@ -18,15 +18,21 @@
 
 #ifdef USBCON
 
-#include "usbd_cdc.h"
-#include "usbd_cdc_msc.h"
-#include "usbd_msc.h"
-#include "usbd_msc_storage_if.h"
-#include "usbd_cdc_if.h"
 #include "usbd_desc.h"
 #include "USB.h"
 #include "wiring.h"
 
+#ifdef USBD_USE_CDC_CLASS
+  #include "usbd_cdc.h"
+  #include "usbd_cdc_msc.h"
+  #include "usbd_cdc_if.h"
+#endif
+
+#ifdef USBD_USE_MSC_CLASS
+  #include "usbd_msc.h"
+  #include "usbd_msc_storage_if.h"
+#endif
+
 USB USBDevice;
 
 void USB::begin()
diff --git a/libraries/SrcWrapper/src/stm32/hw_config.c b/libraries/SrcWrapper/src/stm32/hw_config.c
index 3434d6da96..ee23f0ee36 100644
--- a/libraries/SrcWrapper/src/stm32/hw_config.c
+++ b/libraries/SrcWrapper/src/stm32/hw_config.c
@@ -62,10 +62,6 @@ void hw_config_init(void)
   /* Configure the system clock */
   SystemClock_Config();
 
-#if defined (USBCON) && defined(USBD_USE_CDC)
-  USBD_CDC_init();
-#endif
-
 #if defined (STM32MP1xx)
   __HAL_RCC_HSEM_CLK_ENABLE();
 #endif

From 5b3e972cf8c70dacf54469dbca4481a9115c5487 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Wed, 3 Jun 2020 18:47:11 +0100
Subject: [PATCH 21/37] added back early usb initialisation and fixed write
 protection bug in new interface

---
 cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp        | 2 +-
 .../SrcWrapper/src/stm32/{hw_config.c => hw_config.cpp}    | 7 ++++++-
 2 files changed, 7 insertions(+), 2 deletions(-)
 rename libraries/SrcWrapper/src/stm32/{hw_config.c => hw_config.cpp} (95%)

diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp
index b6d80a52c1..a614bfe288 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_storage_if.cpp
@@ -138,7 +138,7 @@ int8_t  STORAGE_IsWriteProtected(uint8_t lun)
 {
   HANDLER_LUN_CHECK
 
-  return !ppUsbMscHandlers[lun]->IsWriteProtected();
+  return ppUsbMscHandlers[lun]->IsWriteProtected();
 }
 
 /*******************************************************************************
diff --git a/libraries/SrcWrapper/src/stm32/hw_config.c b/libraries/SrcWrapper/src/stm32/hw_config.cpp
similarity index 95%
rename from libraries/SrcWrapper/src/stm32/hw_config.c
rename to libraries/SrcWrapper/src/stm32/hw_config.cpp
index ee23f0ee36..6bec1f76f0 100644
--- a/libraries/SrcWrapper/src/stm32/hw_config.c
+++ b/libraries/SrcWrapper/src/stm32/hw_config.cpp
@@ -37,7 +37,8 @@
   */
 #include "stm32_def.h"
 #include "hw_config.h"
-#include "usbd_if.h"
+#include "usbd_ep_conf.h"
+#include "USBSerial.h"
 #include "dwt.h"
 
 #ifdef __cplusplus
@@ -62,6 +63,10 @@ void hw_config_init(void)
   /* Configure the system clock */
   SystemClock_Config();
 
+#if defined (USBCON) && defined(USBD_USE_CDC_CLASS)
+  SerialUSB.begin();
+#endif
+
 #if defined (STM32MP1xx)
   __HAL_RCC_HSEM_CLK_ENABLE();
 #endif

From 77d673b67dca14338b23c8df470e426776b42494 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Wed, 3 Jun 2020 19:19:04 +0100
Subject: [PATCH 22/37] fixed hs/fs/other speed interface descriptors for cdc
 msc

---
 .../stm32/usb/cdc_msc/usbd_cdc_msc.cpp        | 300 +++++++++++++++++-
 1 file changed, 291 insertions(+), 9 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index 64c557a37a..d73427e7e0 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -52,7 +52,11 @@ static uint8_t  USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
 static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
                                      USBD_SetupReqTypedef *req);
 
-static uint8_t  *USBD_COMPOSITE_GetCfgDesc(uint16_t *length);
+static uint8_t  *USBD_COMPOSITE_GetHSCfgDesc(uint16_t *length);
+
+static uint8_t  *USBD_COMPOSITE_GetFSCfgDesc(uint16_t *length);
+
+static uint8_t  *USBD_COMPOSITE_GetOtherSpeedCfgDesc(uint16_t *length);
 
 static uint8_t  *USBD_COMPOSITE_GetDeviceQualifierDesc(uint16_t *length);
 
@@ -75,18 +79,144 @@ USBD_ClassTypeDef  USBD_CDC_MSC = {
   USBD_COMPOSITE_SOF,
   nullptr,
   nullptr,
-  USBD_COMPOSITE_GetCfgDesc,
-  USBD_COMPOSITE_GetCfgDesc,
-  USBD_COMPOSITE_GetCfgDesc,
+  USBD_COMPOSITE_GetHSCfgDesc,
+  USBD_COMPOSITE_GetFSCfgDesc,
+  USBD_COMPOSITE_GetOtherSpeedCfgDesc,
   USBD_COMPOSITE_GetDeviceQualifierDesc,
 };
 
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+  #pragma data_alignment=4
+#endif
+/* USB COMPOSITE device Configuration Descriptor */
+static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
+  0x09, /* bLength: Configuation Descriptor size */
+  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+  USB_CDC_MSC_CONFIG_DESC_SIZ,
+  /* wTotalLength: Bytes returned */
+  0x00,
+  0x03,         /*bNumInterfaces: 3 interface*/
+  0x01,         /*bConfigurationValue: Configuration value*/
+  0x02,         /*iConfiguration: Index of string descriptor describing the configuration*/
+  0xC0,         /*bmAttributes: bus powered and Supports Remote Wakeup */
+  0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/
+  /* 09 */
+
+  /*---------------------------------------------------------------------------*/
+
+  /*Interface Descriptor */
+  0x09,   /* bLength: Interface Descriptor size */
+  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
+  /* Interface descriptor type */
+  0x00,   /* 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 */
+  0x00,   /* 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 */
+  0x01,   /* 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 */
+  0x00,   /* bMasterInterface: Communication class interface */
+  0x01,   /* 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: */
+  0x01,   /* 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,
+
+
+  /********************  Mass Storage interface ********************/
+  0x09,                                            /* bLength: Interface Descriptor size */
+  0x04,                                            /* bDescriptorType: */
+  0x02,                                            /* bInterfaceNumber: Number of Interface */
+  0x00,                                            /* bAlternateSetting: Alternate setting */
+  0x02,                                            /* bNumEndpoints */
+  0x08,                                            /* bInterfaceClass: MSC Class */
+  0x06,                                            /* bInterfaceSubClass : SCSI transparent */
+  0x50,                                            /* nInterfaceProtocol */
+  0x05,                                            /* iInterface: */
+
+  /********************  Mass Storage Endpoints ********************/
+  0x07,                                            /* Endpoint descriptor length = 7 */
+  0x05,                                            /* Endpoint descriptor type */
+  MSC_IN_EP,                                       /* Endpoint address (IN, address 1) */
+  0x02,                                            /* Bulk endpoint type */
+  LOBYTE(MSC_MAX_HS_PACKET),
+  HIBYTE(MSC_MAX_HS_PACKET),
+  0x00,                                            /* Polling interval in milliseconds */
+
+  0x07,                                            /* Endpoint descriptor length = 7 */
+  0x05,                                            /* Endpoint descriptor type */
+  MSC_OUT_EP,                                      /* Endpoint address (OUT, address 1) */
+  0x02,                                            /* Bulk endpoint type */
+  LOBYTE(MSC_MAX_HS_PACKET),
+  HIBYTE(MSC_MAX_HS_PACKET),
+  0x00                                             /* Polling interval in milliseconds */
+};
 
 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
   #pragma data_alignment=4
 #endif
 /* USB COMPOSITE device Configuration Descriptor */
-static uint8_t USBD_COMPOSITE_CfgFSDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
+static uint8_t USBD_COMPOSITE_FSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   0x09, /* bLength: Configuation Descriptor size */
   USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
   USB_CDC_MSC_CONFIG_DESC_SIZ,
@@ -209,6 +339,134 @@ static uint8_t USBD_COMPOSITE_CfgFSDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   0x00                                             /* Polling interval in milliseconds */
 };
 
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+  #pragma data_alignment=4
+#endif
+/* USB COMPOSITE device Configuration Descriptor */
+static uint8_t USBD_COMPOSITE_OtherSpeedCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
+  0x09, /* bLength: Configuation Descriptor size */
+  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
+  USB_CDC_MSC_CONFIG_DESC_SIZ,
+  /* wTotalLength: Bytes returned */
+  0x00,
+  0x03,         /*bNumInterfaces: 3 interface*/
+  0x01,         /*bConfigurationValue: Configuration value*/
+  0x02,         /*iConfiguration: Index of string descriptor describing the configuration*/
+  0xC0,         /*bmAttributes: bus powered and Supports Remote Wakeup */
+  0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/
+  /* 09 */
+
+  /*---------------------------------------------------------------------------*/
+
+  /*Interface Descriptor */
+  0x09,   /* bLength: Interface Descriptor size */
+  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
+  /* Interface descriptor type */
+  0x00,   /* 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 */
+  0x00,   /* 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 */
+  0x01,   /* 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 */
+  0x00,   /* bMasterInterface: Communication class interface */
+  0x01,   /* 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: */
+  0x01,   /* 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,
+
+
+  /********************  Mass Storage interface ********************/
+  0x09,                                            /* bLength: Interface Descriptor size */
+  0x04,                                            /* bDescriptorType: */
+  0x02,                                            /* bInterfaceNumber: Number of Interface */
+  0x00,                                            /* bAlternateSetting: Alternate setting */
+  0x02,                                            /* bNumEndpoints */
+  0x08,                                            /* bInterfaceClass: MSC Class */
+  0x06,                                            /* bInterfaceSubClass : SCSI transparent */
+  0x50,                                            /* nInterfaceProtocol */
+  0x05,                                            /* iInterface: */
+
+  /********************  Mass Storage Endpoints ********************/
+  0x07,                                            /* Endpoint descriptor length = 7 */
+  0x05,                                            /* Endpoint descriptor type */
+  MSC_IN_EP,                                       /* Endpoint address (IN, address 1) */
+  0x02,                                            /* Bulk endpoint type */
+  LOBYTE(MSC_MAX_FS_PACKET),
+  HIBYTE(MSC_MAX_FS_PACKET),
+  0x00,                                            /* Polling interval in milliseconds */
+
+  0x07,                                            /* Endpoint descriptor length = 7 */
+  0x05,                                            /* Endpoint descriptor type */
+  MSC_OUT_EP,                                      /* Endpoint address (OUT, address 1) */
+  0x02,                                            /* Bulk endpoint type */
+  LOBYTE(MSC_MAX_FS_PACKET),
+  HIBYTE(MSC_MAX_FS_PACKET),
+  0x00                                             /* Polling interval in milliseconds */
+};
+
+
 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
   #pragma data_alignment=4
 #endif
@@ -314,15 +572,39 @@ static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
 
 
 /**
-  * @brief  USBD_COMPOSITE_GetCfgDesc
+  * @brief  USBD_COMPOSITE_GetHSCfgDesc
+  *         return configuration descriptor
+  * @param  length : pointer data length
+  * @retval pointer to descriptor buffer
+  */
+static uint8_t  *USBD_COMPOSITE_GetHSCfgDesc(uint16_t *length)
+{
+  *length = sizeof(USBD_COMPOSITE_HSCfgDesc);
+  return USBD_COMPOSITE_HSCfgDesc;
+}
+
+/**
+  * @brief  USBD_COMPOSITE_GetFSCfgDesc
+  *         return configuration descriptor
+  * @param  length : pointer data length
+  * @retval pointer to descriptor buffer
+  */
+static uint8_t  *USBD_COMPOSITE_GetFSCfgDesc(uint16_t *length)
+{
+  *length = sizeof(USBD_COMPOSITE_FSCfgDesc);
+  return USBD_COMPOSITE_FSCfgDesc;
+}
+
+/**
+  * @brief  USBD_COMPOSITE_GetOtherSpeedCfgDesc
   *         return configuration descriptor
   * @param  length : pointer data length
   * @retval pointer to descriptor buffer
   */
-static uint8_t  *USBD_COMPOSITE_GetCfgDesc(uint16_t *length)
+static uint8_t  *USBD_COMPOSITE_GetOtherSpeedCfgDesc(uint16_t *length)
 {
-  *length = sizeof(USBD_COMPOSITE_CfgFSDesc);
-  return USBD_COMPOSITE_CfgFSDesc;
+  *length = sizeof(USBD_COMPOSITE_OtherSpeedCfgDesc);
+  return USBD_COMPOSITE_OtherSpeedCfgDesc;
 }
 
 /**

From 3f3783ece7ddefaa3b22536ece065b6b45db1fcd Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Wed, 3 Jun 2020 19:41:43 +0100
Subject: [PATCH 23/37] small changes to ep conf

---
 cores/arduino/stm32/usb/usbd_conf.c    | 2 +-
 cores/arduino/stm32/usb/usbd_ep_conf.h | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/cores/arduino/stm32/usb/usbd_conf.c b/cores/arduino/stm32/usb/usbd_conf.c
index 0bc8b9cc16..3094d3a331 100644
--- a/cores/arduino/stm32/usb/usbd_conf.c
+++ b/cores/arduino/stm32/usb/usbd_conf.c
@@ -519,7 +519,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
     }
   }
 #else
-  uint32_t offset = 0;
+  uint32_t offset = PMA_BASE_OFFSET;
   for (uint32_t i = 0; i < (DEV_NUM_EP + 1); i++) {
     ep_desc_t *pDesc = &ep_dep[i];
     uint32_t size = pDesc->ep_size;
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.h b/cores/arduino/stm32/usb/usbd_ep_conf.h
index 18f46cc58f..1243aa73ae 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.h
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.h
@@ -89,8 +89,7 @@ typedef struct {
 /* Require DEV_NUM_EP to be defined */
 #if defined (USB)
   /* Size in words, byte size divided by 2 */
-  #define PMA_EP0_OUT_ADDR    (8 * DEV_NUM_EP)
-  #define PMA_EP0_IN_ADDR     (PMA_EP0_OUT_ADDR + USB_MAX_EP0_SIZE)
+  #define PMA_BASE_OFFSET     (8 * DEV_NUM_EP)
 #endif /* USB */
 
 // *INDENT-ON*

From 3c4d73d776379522fa9d0020d4ef05db9a1ebdd1 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 09:09:06 +0100
Subject: [PATCH 24/37] fixed bug where usb device library relies on
 pdev->pClassData to determine if deinitialisation should happen

---
 cores/arduino/stm32/usb/cdc/usbd_cdc.c        | 25 +++++++++----------
 .../stm32/usb/cdc_msc/usbd_cdc_msc.cpp        |  8 ++++++
 cores/arduino/stm32/usb/msc/usbd_msc.c        |  9 +++++++
 3 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index 7ce101ae03..5826d32e48 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -421,7 +421,7 @@ USBD_CDC_HandleTypeDef *cdc_handle = &cdc_handle_dat;
 
 USBD_CDC_ItfTypeDef *cdc_itf = NULL; /* TODO */
 
-
+int cdcInitialized;
 
 /**
   * @}
@@ -444,14 +444,7 @@ static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
-  hcdc = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
-
-  if (hcdc == NULL) {
-    pdev->pClassData = NULL;
-    return (uint8_t)USBD_EMEM;
-  }
-
-  pdev->pClassData = (void *)hcdc;
+  pdev->pClassData = &cdcInitialized;
 
   if (pdev->dev_speed == USBD_SPEED_HIGH) {
     /* Open EP IN */
@@ -534,9 +527,15 @@ static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
   pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U;
   pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = 0U;
 
-  /* DeInit  physical Interface components */
-  /* TODO remove user data reference */
-  cdc_itf->DeInit();
+  if (pdev->pClassData) {
+    /* DeInit physical Interface components */
+    cdc_itf->DeInit();
+  }
+
+  if (pdev->pClassData == &cdcInitialized) {
+    // only mark as uninitialised if we own the initialisation
+    pdev->pClassData = NULL;
+  }
 
   return ret;
 }
@@ -682,7 +681,7 @@ static uint8_t  USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
 {
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
-  if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) {
+  if (hcdc->CmdOpCode != 0xFFU) {
     cdc_itf->Control(hcdc->CmdOpCode,
                      (uint8_t *)(void *)hcdc->data,
                      (uint16_t)hcdc->CmdLength);
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index d73427e7e0..20e743aa45 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -484,6 +484,8 @@ static uint8_t USBD_COMPOSITE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] =
   0x00,
 };
 
+int cdcMscInitialised;
+
 /**
   * @brief  USBD_COMPOSITE_Init
   *         Initialize the COMPOSITE interface
@@ -498,6 +500,8 @@ static uint8_t  USBD_COMPOSITE_Init(USBD_HandleTypeDef *pdev,
 
   USBD_CDC.Init(pdev, cfgidx);
 
+  pdev->pClassData = &cdcMscInitialised;
+
   return (uint8_t)USBD_OK;
 }
 
@@ -515,6 +519,10 @@ static uint8_t  USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
 
   USBD_CDC.DeInit(pdev, cfgidx);
 
+  if (pdev->pClassData == &cdcMscInitialised) {
+    pdev->pClassData = nullptr;
+  }
+
   return USBD_OK;
 }
 
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.c b/cores/arduino/stm32/usb/msc/usbd_msc.c
index 2de3df3428..64b51c2b7f 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.c
@@ -223,6 +223,8 @@ USBD_MSC_BOT_HandleTypeDef *msc_handle = &msc_handle_dat;
 
 USBD_StorageTypeDef *msc_storage = &USBD_MSC_fops;
 
+int mscInitialized;
+
 /**
   * @brief  USBD_MSC_Init
   *         Initialize  the mass storage configuration
@@ -232,6 +234,8 @@ USBD_StorageTypeDef *msc_storage = &USBD_MSC_fops;
   */
 uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 {
+  pdev->pClassData = &mscInitialized;
+
   if (pdev->dev_speed == USBD_SPEED_HIGH) {
     /* Open EP OUT */
     USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
@@ -277,6 +281,11 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev,
   /* De-Init the BOT layer */
   MSC_BOT_DeInit(pdev);
 
+  if (pdev->pClassData == &mscInitialized) {
+    // only mark as uninitialised if we own the initialisation
+    pdev->pClassData = NULL;
+  }
+
   return USBD_OK;
 }
 

From f0e3993f4c1814cad5be25ad77f02937c9901cdb Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 12:39:26 +0100
Subject: [PATCH 25/37] update msc and cdc classes

---
 cores/arduino/stm32/usb/cdc/usbd_cdc.c      | 203 ++++----
 cores/arduino/stm32/usb/cdc/usbd_cdc.h      |  16 +-
 cores/arduino/stm32/usb/cdc/usbd_cdc_if.c   |   2 +-
 cores/arduino/stm32/usb/msc/usbd_msc.c      | 150 +++---
 cores/arduino/stm32/usb/msc/usbd_msc.h      |   4 +-
 cores/arduino/stm32/usb/msc/usbd_msc_bot.c  |  82 +--
 cores/arduino/stm32/usb/msc/usbd_msc_data.c |  64 ++-
 cores/arduino/stm32/usb/msc/usbd_msc_data.h |  16 +-
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c | 540 ++++++++++++++++----
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.h |  20 +-
 cores/arduino/stm32/usb/usbd_ep_conf.c      |  19 +-
 cores/arduino/stm32/usb/usbd_ep_conf.h      |  16 +-
 12 files changed, 758 insertions(+), 374 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index 5826d32e48..e8d6e982d7 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -64,6 +64,7 @@
   * @{
   */
 
+
 /** @defgroup USBD_CDC
   * @brief usbd core module
   * @{
@@ -76,6 +77,7 @@
   * @}
   */
 
+
 /** @defgroup USBD_CDC_Private_Defines
   * @{
   */
@@ -83,6 +85,7 @@
   * @}
   */
 
+
 /** @defgroup USBD_CDC_Private_Macros
   * @{
   */
@@ -91,36 +94,23 @@
   * @}
   */
 
+
 /** @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_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);
-
-uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
+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);
+uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
 
 /* USB Standard Device Descriptor */
 __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = {
@@ -438,7 +428,7 @@ int cdcInitialized;
   * @param  cfgidx: Configuration index
   * @retval status
   */
-static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 {
   UNUSED(cfgidx);
 
@@ -451,31 +441,31 @@ static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
     (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
                          CDC_DATA_HS_IN_PACKET_SIZE);
 
-    pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
+     pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
 
-    /* Open EP OUT */
-    (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
-                         CDC_DATA_HS_OUT_PACKET_SIZE);
+     /* Open EP OUT */
+     (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
+                          CDC_DATA_HS_OUT_PACKET_SIZE);
 
-    pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
+      pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
 
-    /* Set bInterval for CDC CMD Endpoint */
-    pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL;
+      /* Set bInterval for CDC CMD Endpoint */
+      pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL;
   } else {
     /* Open EP IN */
     (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
                          CDC_DATA_FS_IN_PACKET_SIZE);
 
-    pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
+     pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
 
-    /* Open EP OUT */
-    (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
-                         CDC_DATA_FS_OUT_PACKET_SIZE);
+     /* Open EP OUT */
+     (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
+                          CDC_DATA_FS_OUT_PACKET_SIZE);
 
-    pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
+      pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
 
-    /* Set bInterval for CMD Endpoint */
-    pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL;
+      /* Set bInterval for CMD Endpoint */
+      pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL;
   }
 
   /* Open Command IN EP */
@@ -491,15 +481,15 @@ static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 
   if (pdev->dev_speed == USBD_SPEED_HIGH) {
     /* Prepare Out endpoint to receive next packet */
-    USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
-                           CDC_DATA_HS_OUT_PACKET_SIZE);
+    (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
+                                 CDC_DATA_HS_OUT_PACKET_SIZE);
   } else {
     /* Prepare Out endpoint to receive next packet */
-    USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
-                           CDC_DATA_FS_OUT_PACKET_SIZE);
+    (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
+                                 CDC_DATA_FS_OUT_PACKET_SIZE);
   }
 
-  return ret;
+  return (uint8_t)USBD_OK;
 }
 
 /**
@@ -509,7 +499,7 @@ static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
   * @param  cfgidx: Configuration index
   * @retval status
   */
-static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
+static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 {
   UNUSED(cfgidx);
   uint8_t ret = 0U;
@@ -527,7 +517,8 @@ static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
   pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U;
   pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = 0U;
 
-  if (pdev->pClassData) {
+  /* DeInit  physical Interface components */
+  if (pdev->pClassData != NULL) {
     /* DeInit physical Interface components */
     cdc_itf->DeInit();
   }
@@ -547,8 +538,8 @@ static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
   * @param  req: usb requests
   * @retval status
   */
-static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
-                               USBD_SetupReqTypedef *req)
+static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
+                              USBD_SetupReqTypedef *req)
 {
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
   uint8_t ifalt = 0U;
@@ -556,11 +547,11 @@ static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
   USBD_StatusTypeDef ret = USBD_OK;
 
   switch (req->bmRequest & USB_REQ_TYPE_MASK) {
-    case USB_REQ_TYPE_CLASS :
-      if (req->wLength) {
-        if (req->bmRequest & 0x80U) {
+    case USB_REQ_TYPE_CLASS:
+      if (req->wLength != 0U) {
+        if ((req->bmRequest & 0x80U) != 0U) {
           cdc_itf->Control(req->bRequest,
-                           (uint8_t *)(void *)hcdc->data,
+                           (uint8_t *)hcdc->data,
                            req->wLength);
 
           (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, req->wLength);
@@ -572,7 +563,7 @@ static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
         }
       } else {
         cdc_itf->Control(req->bRequest,
-                         (uint8_t *)(void *)req, 0U);
+                         (uint8_t *)req, 0U);
       }
       break;
 
@@ -589,7 +580,7 @@ static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
 
         case USB_REQ_GET_INTERFACE:
           if (pdev->dev_state == USBD_STATE_CONFIGURED) {
-            (void)USBD_CtlSendData(pdev, &ifalt, 1U);
+           (void)USBD_CtlSendData(pdev, &ifalt, 1U);
           } else {
             USBD_CtlError(pdev, req);
             ret = USBD_FAIL;
@@ -629,25 +620,29 @@ static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
   * @param  epnum: endpoint number
   * @retval status
   */
-static uint8_t  USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
+static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
 {
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
   PCD_HandleTypeDef *hpcd = pdev->pData;
   USBD_CDC_ItfTypeDef *ctrl = cdc_itf;
 
-  if ((pdev->ep_in[epnum].total_length > 0U) && ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) {
+  if (pdev->pClassData == 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 */
-    USBD_LL_Transmit(pdev, epnum, NULL, 0U);
+    (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
   } else {
     hcdc->TxState = 0U;
-    if (ctrl->Transferred) {
-      ctrl->Transferred();
-    }
+    ctrl->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
   }
-  return USBD_OK;
+
+  return (uint8_t)USBD_OK;
 }
 
 /**
@@ -657,18 +652,22 @@ static uint8_t  USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
   * @param  epnum: endpoint number
   * @retval status
   */
-static uint8_t  USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
+static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
 {
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
+  if (pdev->pClassData == NULL) {
+    return (uint8_t)USBD_FAIL;
+  }
 
   /* 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 */
+
   cdc_itf->Receive(hcdc->RxBuffer, &hcdc->RxLength);
 
-  return USBD_OK;
+  return (uint8_t)USBD_OK;
 }
 
 /**
@@ -677,15 +676,16 @@ static uint8_t  USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
   * @param  pdev: device instance
   * @retval status
   */
-static uint8_t  USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
+static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
 {
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
-  if (hcdc->CmdOpCode != 0xFFU) {
+  if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) {
     cdc_itf->Control(hcdc->CmdOpCode,
-                     (uint8_t *)(void *)hcdc->data,
+                     (uint8_t *)hcdc->data,
                      (uint16_t)hcdc->CmdLength);
     hcdc->CmdOpCode = 0xFFU;
+
   }
 
   return (uint8_t)USBD_OK;
@@ -698,7 +698,7 @@ static uint8_t  USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
   * @param  length : pointer data length
   * @retval pointer to descriptor buffer
   */
-static uint8_t  *USBD_CDC_GetFSCfgDesc(uint16_t *length)
+static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
 {
   *length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc);
 
@@ -712,7 +712,7 @@ static uint8_t  *USBD_CDC_GetFSCfgDesc(uint16_t *length)
   * @param  length : pointer data length
   * @retval pointer to descriptor buffer
   */
-static uint8_t  *USBD_CDC_GetHSCfgDesc(uint16_t *length)
+static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
 {
   *length = (uint16_t)sizeof(USBD_CDC_CfgHSDesc);
 
@@ -726,7 +726,7 @@ static uint8_t  *USBD_CDC_GetHSCfgDesc(uint16_t *length)
   * @param  length : pointer data length
   * @retval pointer to descriptor buffer
   */
-static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
+static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
 {
   *length = (uint16_t)sizeof(USBD_CDC_OtherSpeedCfgDesc);
 
@@ -739,7 +739,7 @@ static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
 * @param  length : pointer data length
 * @retval pointer to descriptor buffer
 */
-uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
+uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
 {
   *length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc);
 
@@ -752,17 +752,14 @@ uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
   * @param  fops: CD  Interface callback
   * @retval status
   */
-uint8_t  USBD_CDC_RegisterInterface(USBD_HandleTypeDef   *pdev,
-                                    USBD_CDC_ItfTypeDef *fops)
+uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
+                                   USBD_CDC_ItfTypeDef *fops)
 {
-  uint8_t  ret = USBD_FAIL;
-
-  if (fops != NULL) {
-    cdc_itf = fops;
-    ret = USBD_OK;
+  if (fops == NULL) {
+    return (uint8_t)USBD_FAIL;
   }
 
-  pdev->pUserData = fops;
+  cdc_itf = fops;
 
   return (uint8_t)USBD_OK;
 }
@@ -773,8 +770,8 @@ uint8_t  USBD_CDC_RegisterInterface(USBD_HandleTypeDef   *pdev,
   * @param  pbuff: Tx Buffer
   * @retval status
   */
-uint8_t  USBD_CDC_SetTxBuffer(USBD_HandleTypeDef   *pdev,
-                              uint8_t  *pbuff, uint32_t length)
+uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
+                             uint8_t *pbuff, uint32_t length)
 {
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
@@ -791,7 +788,7 @@ uint8_t  USBD_CDC_SetTxBuffer(USBD_HandleTypeDef   *pdev,
   * @param  pbuff: Rx Buffer
   * @retval status
   */
-uint8_t  USBD_CDC_SetRxBuffer(USBD_HandleTypeDef   *pdev, uint8_t  *pbuff)
+uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
 {
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
@@ -806,9 +803,14 @@ uint8_t  USBD_CDC_SetRxBuffer(USBD_HandleTypeDef   *pdev, uint8_t  *pbuff)
   * @param  pdev: device instance
   * @retval status
   */
-uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
+uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
 {
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
+  USBD_StatusTypeDef ret = USBD_BUSY;
+
+  if (pdev->pClassData == NULL) {
+    return (uint8_t)USBD_FAIL;
+  }
 
   if (hcdc->TxState == 0U) {
     /* Tx Transfer in progress */
@@ -818,12 +820,9 @@ uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
     pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength;
 
     /* Transmit next packet */
-    USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer,
-                     (uint16_t)hcdc->TxLength);
+    (void)USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, hcdc->TxLength);
 
-    return USBD_OK;
-  } else {
-    return USBD_BUSY;
+    ret = USBD_OK;
   }
 
   return (uint8_t)ret;
@@ -836,33 +835,25 @@ uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
   * @param  pdev: device instance
   * @retval status
   */
-uint8_t  USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
+uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
 {
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
-  /* Suspend or Resume USB Out process */
+  if (pdev->pClassData == NULL) {
+    return (uint8_t)USBD_FAIL;
+  }
+
   if (pdev->dev_speed == USBD_SPEED_HIGH) {
     /* Prepare Out endpoint to receive next packet */
-    USBD_LL_PrepareReceive(pdev,
-                           CDC_OUT_EP,
-                           hcdc->RxBuffer,
-                           CDC_DATA_HS_OUT_PACKET_SIZE);
+    (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
+                                 CDC_DATA_HS_OUT_PACKET_SIZE);
   } else {
     /* Prepare Out endpoint to receive next packet */
-    USBD_LL_PrepareReceive(pdev,
-                           CDC_OUT_EP,
-                           hcdc->RxBuffer,
-                           CDC_DATA_FS_OUT_PACKET_SIZE);
+    (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
+                                 CDC_DATA_FS_OUT_PACKET_SIZE);
   }
-  return USBD_OK;
-}
 
-uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev)
-{
-  /* Suspend or Resume USB Out process */
-  /* Prepare Out endpoint to receive next packet */
-  USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, 0, 0);
-  return USBD_OK;
+  return (uint8_t)USBD_OK;
 }
 
 #endif /* USBD_USE_CDC_CLASS */
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.h b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
index 1c12bbbffb..0f4dfd89af 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.h
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
@@ -38,6 +38,7 @@ extern "C" {
   * @{
   */
 
+
 /** @defgroup usbd_cdc_Exported_Defines
   * @{
   */
@@ -140,16 +141,15 @@ extern USBD_CDC_ItfTypeDef *cdc_itf;
 /** @defgroup USB_CORE_Exported_Functions
   * @{
   */
-uint8_t  USBD_CDC_RegisterInterface(USBD_HandleTypeDef   *pdev,
-                                    USBD_CDC_ItfTypeDef *fops);
+uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
+                                   USBD_CDC_ItfTypeDef *fops);
 
-uint8_t  USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
-                              uint32_t length);
+uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
+                             uint32_t length);
 
-uint8_t  USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
-uint8_t  USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
-uint8_t  USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev);
-uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
+uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
+uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
+uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
 /**
   * @}
   */
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
index 6b731641b4..c55ece32f7 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
@@ -242,7 +242,7 @@ static int8_t USBD_CDC_Receive(uint8_t *Buf, uint32_t *Len)
 
 
 /**
-  * @brief  USBD_CDC_TransmitCplt
+  * @brief  TEMPLATE_TransmitCplt
   *         Data transmited callback
   *
   *         @note
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.c b/cores/arduino/stm32/usb/msc/usbd_msc.c
index 64b51c2b7f..742d747c30 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.c
@@ -47,16 +47,16 @@ EndBSPDependencies */
 #include "usbd_msc_storage_if.h"
 
 
-uint8_t  USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
-uint8_t  USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
-uint8_t  USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
-uint8_t  USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
-uint8_t  USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
+uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
+uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
+uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
+uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
 
-uint8_t  *USBD_MSC_GetHSCfgDesc(uint16_t *length);
-uint8_t  *USBD_MSC_GetFSCfgDesc(uint16_t *length);
-uint8_t  *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length);
-uint8_t  *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length);
+uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length);
+uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length);
+uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length);
+uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length);
 
 
 USBD_ClassTypeDef  USBD_MSC = {
@@ -78,7 +78,7 @@ USBD_ClassTypeDef  USBD_MSC = {
 
 /* USB Mass storage device Configuration Descriptor */
 /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
-__ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END = {
+__ALIGN_BEGIN static uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END = {
 
   0x09,   /* bLength: Configuation Descriptor size */
   USB_DESC_TYPE_CONFIGURATION,   /* bDescriptorType: Configuration */
@@ -104,7 +104,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
   /********************  Mass Storage Endpoints ********************/
   0x07,   /*Endpoint descriptor length = 7*/
   0x05,   /*Endpoint descriptor type */
-  MSC_IN_EP,   /*Endpoint address (IN, address 1) */
+  MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
   0x02,   /*Bulk endpoint type */
   LOBYTE(MSC_MAX_HS_PACKET),
   HIBYTE(MSC_MAX_HS_PACKET),
@@ -112,7 +112,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
 
   0x07,   /*Endpoint descriptor length = 7 */
   0x05,   /*Endpoint descriptor type */
-  MSC_OUT_EP,   /*Endpoint address (OUT, address 1) */
+  MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
   0x02,   /*Bulk endpoint type */
   LOBYTE(MSC_MAX_HS_PACKET),
   HIBYTE(MSC_MAX_HS_PACKET),
@@ -120,8 +120,8 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
 };
 
 /* USB Mass storage device Configuration Descriptor */
-/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
-__ALIGN_BEGIN uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END = {
+/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
+__ALIGN_BEGIN static uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END = {
   0x09,   /* bLength: Configuation Descriptor size */
   USB_DESC_TYPE_CONFIGURATION,   /* bDescriptorType: Configuration */
   USB_MSC_CONFIG_DESC_SIZ,
@@ -146,7 +146,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
   /********************  Mass Storage Endpoints ********************/
   0x07,   /*Endpoint descriptor length = 7*/
   0x05,   /*Endpoint descriptor type */
-  MSC_IN_EP,   /*Endpoint address (IN, address 1) */
+  MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
   0x02,   /*Bulk endpoint type */
   LOBYTE(MSC_MAX_FS_PACKET),
   HIBYTE(MSC_MAX_FS_PACKET),
@@ -154,14 +154,14 @@ __ALIGN_BEGIN uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ]  __ALIGN_END =
 
   0x07,   /*Endpoint descriptor length = 7 */
   0x05,   /*Endpoint descriptor type */
-  MSC_OUT_EP,   /*Endpoint address (OUT, address 1) */
+  MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
   0x02,   /*Bulk endpoint type */
   LOBYTE(MSC_MAX_FS_PACKET),
   HIBYTE(MSC_MAX_FS_PACKET),
   0x00     /*Polling interval in milliseconds*/
 };
 
-__ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __ALIGN_END  = {
+__ALIGN_BEGIN static uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __ALIGN_END  = {
   0x09,   /* bLength: Configuation Descriptor size */
   USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
   USB_MSC_CONFIG_DESC_SIZ,
@@ -186,7 +186,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __AL
   /********************  Mass Storage Endpoints ********************/
   0x07,   /*Endpoint descriptor length = 7*/
   0x05,   /*Endpoint descriptor type */
-  MSC_IN_EP,   /*Endpoint address (IN, address 1) */
+  MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */
   0x02,   /*Bulk endpoint type */
   0x40,
   0x00,
@@ -194,7 +194,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __AL
 
   0x07,   /*Endpoint descriptor length = 7 */
   0x05,   /*Endpoint descriptor type */
-  MSC_OUT_EP,   /*Endpoint address (OUT, address 1) */
+  MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */
   0x02,   /*Bulk endpoint type */
   0x40,
   0x00,
@@ -202,7 +202,7 @@ __ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ]   __AL
 };
 
 /* USB Standard Device Descriptor */
-__ALIGN_BEGIN  uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]  __ALIGN_END = {
+__ALIGN_BEGIN static uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]  __ALIGN_END = {
   USB_LEN_DEV_QUALIFIER_DESC,
   USB_DESC_TYPE_DEVICE_QUALIFIER,
   0x00,
@@ -234,49 +234,51 @@ int mscInitialized;
   */
 uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 {
+  UNUSED(cfgidx);
   pdev->pClassData = &mscInitialized;
 
   if (pdev->dev_speed == USBD_SPEED_HIGH) {
     /* Open EP OUT */
-    USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
-    pdev->ep_out[MSC_OUT_EP & 0xFU].is_used = 1U;
+    (void)USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
+    pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
 
     /* Open EP IN */
-    USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
-    pdev->ep_in[MSC_IN_EP & 0xFU].is_used = 1U;
+    (void)USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET);
+    pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
   } else {
     /* Open EP OUT */
-    USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
-    pdev->ep_out[MSC_OUT_EP & 0xFU].is_used = 1U;
+    (void)USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
+    pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 1U;
 
     /* Open EP IN */
-    USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
-    pdev->ep_in[MSC_IN_EP & 0xFU].is_used = 1U;
+    (void)USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET);
+    pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 1U;
   }
 
   /* Init the BOT  layer */
   MSC_BOT_Init(pdev);
 
-  return USBD_OK;
+  return (uint8_t)USBD_OK;
 }
 
 /**
   * @brief  USBD_MSC_DeInit
-  *         DeInitialize the mass storage configuration
+  *         DeInitialize  the mass storage configuration
   * @param  pdev: device instance
   * @param  cfgidx: configuration index
   * @retval status
   */
-uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev,
-                        uint8_t cfgidx)
+uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 {
+  UNUSED(cfgidx);
+
   /* Close MSC EPs */
-  USBD_LL_CloseEP(pdev, MSC_OUT_EP);
-  pdev->ep_out[MSC_OUT_EP & 0xFU].is_used = 0U;
+  (void)USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR);
+  pdev->ep_out[MSC_EPOUT_ADDR & 0xFU].is_used = 0U;
 
   /* Close EP IN */
-  USBD_LL_CloseEP(pdev, MSC_IN_EP);
-  pdev->ep_in[MSC_IN_EP & 0xFU].is_used = 0U;
+  (void)USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR);
+  pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 0U;
 
   /* De-Init the BOT layer */
   MSC_BOT_DeInit(pdev);
@@ -286,7 +288,7 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev,
     pdev->pClassData = NULL;
   }
 
-  return USBD_OK;
+  return (uint8_t)USBD_OK;
 }
 
 /**
@@ -309,19 +311,15 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
         case BOT_GET_MAX_LUN:
           if ((req->wValue  == 0U) && (req->wLength == 1U) &&
               ((req->bmRequest & 0x80U) == 0x80U)) {
-            if (msc_storage != NULL) {
-              hmsc->max_lun = (uint32_t)msc_storage->GetMaxLun();
-              USBD_CtlSendData(pdev, (uint8_t *)(void *)&hmsc->max_lun, 1U);
-            } else {
-              ret = USBD_FAIL;
-            }
+            hmsc->max_lun = (uint32_t)msc_storage->GetMaxLun();
+            (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U);
           } else {
             USBD_CtlError(pdev, req);
             ret = USBD_FAIL;
           }
           break;
 
-        case BOT_RESET :
+        case BOT_RESET:
           if ((req->wValue  == 0U) && (req->wLength == 0U) &&
               ((req->bmRequest & 0x80U) != 0x80U)) {
             MSC_BOT_Reset(pdev);
@@ -342,7 +340,7 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
       switch (req->bRequest) {
         case USB_REQ_GET_STATUS:
           if (pdev->dev_state == USBD_STATE_CONFIGURED) {
-            USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U);
+            (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
           } else {
             USBD_CtlError(pdev, req);
             ret = USBD_FAIL;
@@ -351,7 +349,7 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
 
         case USB_REQ_GET_INTERFACE:
           if (pdev->dev_state == USBD_STATE_CONFIGURED) {
-            USBD_CtlSendData(pdev, (uint8_t *)(void *)&hmsc->interface, 1U);
+            (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->interface, 1U);
           } else {
             USBD_CtlError(pdev, req);
             ret = USBD_FAIL;
@@ -368,40 +366,15 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
           break;
 
         case USB_REQ_CLEAR_FEATURE:
+          if (pdev->dev_state == USBD_STATE_CONFIGURED) {
+            if (req->wValue == USB_FEATURE_EP_HALT) {
+              /* Flush the FIFO */
+              (void)USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
 
-          /* Flush the FIFO and Clear the stall status */
-          USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
-
-          /* Reactivate the EP */
-          USBD_LL_CloseEP(pdev, (uint8_t)req->wIndex);
-          if ((((uint8_t)req->wIndex) & 0x80U) == 0x80U) {
-            pdev->ep_in[(uint8_t)req->wIndex & 0xFU].is_used = 0U;
-            if (pdev->dev_speed == USBD_SPEED_HIGH) {
-              /* Open EP IN */
-              USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK,
-                             MSC_MAX_HS_PACKET);
-            } else {
-              /* Open EP IN */
-              USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK,
-                             MSC_MAX_FS_PACKET);
+              /* Handle BOT error */
+              MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
             }
-            pdev->ep_in[MSC_IN_EP & 0xFU].is_used = 1U;
-          } else {
-            pdev->ep_out[(uint8_t)req->wIndex & 0xFU].is_used = 0U;
-            if (pdev->dev_speed == USBD_SPEED_HIGH) {
-              /* Open EP OUT */
-              USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK,
-                             MSC_MAX_HS_PACKET);
-            } else {
-              /* Open EP OUT */
-              USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK,
-                             MSC_MAX_FS_PACKET);
-            }
-            pdev->ep_out[MSC_OUT_EP & 0xFU].is_used = 1U;
           }
-
-          /* Handle BOT error */
-          MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
           break;
 
         default:
@@ -417,7 +390,7 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
       break;
   }
 
-  return ret;
+  return (uint8_t)ret;
 }
 
 /**
@@ -431,7 +404,7 @@ uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
 {
   MSC_BOT_DataIn(pdev, epnum);
 
-  return USBD_OK;
+  return (uint8_t)USBD_OK;
 }
 
 /**
@@ -445,7 +418,7 @@ uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
 {
   MSC_BOT_DataOut(pdev, epnum);
 
-  return USBD_OK;
+  return (uint8_t)USBD_OK;
 }
 
 /**
@@ -456,7 +429,7 @@ uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
 */
 uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length)
 {
-  *length = sizeof(USBD_MSC_CfgHSDesc);
+  *length = (uint16_t)sizeof(USBD_MSC_CfgHSDesc);
 
   return USBD_MSC_CfgHSDesc;
 }
@@ -469,7 +442,7 @@ uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length)
 */
 uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length)
 {
-  *length = sizeof(USBD_MSC_CfgFSDesc);
+  *length = (uint16_t)sizeof(USBD_MSC_CfgFSDesc);
 
   return USBD_MSC_CfgFSDesc;
 }
@@ -482,7 +455,7 @@ uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length)
 */
 uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length)
 {
-  *length = sizeof(USBD_MSC_OtherSpeedCfgDesc);
+  *length = (uint16_t)sizeof(USBD_MSC_OtherSpeedCfgDesc);
 
   return USBD_MSC_OtherSpeedCfgDesc;
 }
@@ -494,7 +467,7 @@ uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length)
 */
 uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length)
 {
-  *length = sizeof(USBD_MSC_DeviceQualifierDesc);
+  *length = (uint16_t)sizeof(USBD_MSC_DeviceQualifierDesc);
 
   return USBD_MSC_DeviceQualifierDesc;
 }
@@ -504,12 +477,15 @@ uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length)
 * @param  fops: storage callback
 * @retval status
 */
-uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev,
-                                 USBD_StorageTypeDef *fops)
+uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef *fops)
 {
+  if (fops == NULL) {
+    return (uint8_t)USBD_FAIL;
+  }
+
   msc_storage = fops;
 
-  return USBD_OK;
+  return (uint8_t)USBD_OK;
 }
 
 #endif /* USBD_USE_MSC_CLASS */
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc.h b/cores/arduino/stm32/usb/msc/usbd_msc.h
index 861abd5bec..a3001d570c 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc.h
@@ -53,12 +53,13 @@ typedef struct _USBD_STORAGE {
 
 } USBD_StorageTypeDef;
 
+
 typedef struct {
   uint32_t                 max_lun;
   uint32_t                 interface;
   uint8_t                  bot_state;
   uint8_t                  bot_status;
-  uint16_t                 bot_data_length;
+  uint32_t                 bot_data_length;
   uint8_t                  bot_data[MSC_MEDIA_PACKET];
   USBD_MSC_BOT_CBWTypeDef  cbw;
   USBD_MSC_BOT_CSWTypeDef  csw;
@@ -66,6 +67,7 @@ typedef struct {
   USBD_SCSI_SenseTypeDef   scsi_sense [SENSE_LIST_DEEPTH];
   uint8_t                  scsi_sense_head;
   uint8_t                  scsi_sense_tail;
+  uint8_t                  scsi_medium_state;
 
   uint16_t                 scsi_blk_size;
   uint32_t                 scsi_blk_nbr;
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_bot.c b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
index 403d05425a..d3338d2292 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_bot.c
@@ -34,11 +34,9 @@ EndBSPDependencies */
 #include "usbd_msc_scsi.h"
 #include "usbd_ioreq.h"
 
-static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef  *pdev);
-static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
-                             uint16_t len);
-
-static void MSC_BOT_Abort(USBD_HandleTypeDef  *pdev);
+static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len);
+static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev);
+static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev);
 
 
 /**
@@ -47,7 +45,7 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef  *pdev);
 * @param  pdev: device instance
 * @retval None
 */
-void MSC_BOT_Init(USBD_HandleTypeDef  *pdev)
+void MSC_BOT_Init(USBD_HandleTypeDef *pdev)
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
@@ -56,15 +54,16 @@ void MSC_BOT_Init(USBD_HandleTypeDef  *pdev)
 
   hmsc->scsi_sense_tail = 0U;
   hmsc->scsi_sense_head = 0U;
+  hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
 
   msc_storage->Init(0U);
 
-  USBD_LL_FlushEP(pdev, MSC_OUT_EP);
-  USBD_LL_FlushEP(pdev, MSC_IN_EP);
+  (void)USBD_LL_FlushEP(pdev, MSC_EPOUT_ADDR);
+  (void)USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR);
 
   /* Prapare EP to Receive First BOT Cmd */
-  USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, (uint8_t *)(void *)&hmsc->cbw,
-                         USBD_BOT_CBW_LENGTH);
+  (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw,
+                               USBD_BOT_CBW_LENGTH);
 }
 
 /**
@@ -73,16 +72,19 @@ void MSC_BOT_Init(USBD_HandleTypeDef  *pdev)
 * @param  pdev: device instance
 * @retval  None
 */
-void MSC_BOT_Reset(USBD_HandleTypeDef  *pdev)
+void MSC_BOT_Reset(USBD_HandleTypeDef *pdev)
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
   hmsc->bot_state  = USBD_BOT_IDLE;
   hmsc->bot_status = USBD_BOT_STATUS_RECOVERY;
 
+  (void)USBD_LL_ClearStallEP(pdev, MSC_EPIN_ADDR);
+  (void)USBD_LL_ClearStallEP(pdev, MSC_EPOUT_ADDR);
+
   /* Prapare EP to Receive First BOT Cmd */
-  USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, (uint8_t *)(void *)&hmsc->cbw,
-                         USBD_BOT_CBW_LENGTH);
+  (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw,
+                               USBD_BOT_CBW_LENGTH);
 }
 
 /**
@@ -104,9 +106,10 @@ void MSC_BOT_DeInit(USBD_HandleTypeDef  *pdev)
 * @param  epnum: endpoint index
 * @retval None
 */
-void MSC_BOT_DataIn(USBD_HandleTypeDef  *pdev,
-                    uint8_t epnum)
+void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
 {
+  UNUSED(epnum);
+
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
   switch (hmsc->bot_state) {
@@ -132,9 +135,10 @@ void MSC_BOT_DataIn(USBD_HandleTypeDef  *pdev,
 * @param  epnum: endpoint index
 * @retval None
 */
-void MSC_BOT_DataOut(USBD_HandleTypeDef  *pdev,
-                     uint8_t epnum)
+void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
 {
+  UNUSED(epnum);
+
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
   switch (hmsc->bot_state) {
@@ -143,7 +147,6 @@ void MSC_BOT_DataOut(USBD_HandleTypeDef  *pdev,
       break;
 
     case USBD_BOT_DATA_OUT:
-
       if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) {
         MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
       }
@@ -167,11 +170,10 @@ static void  MSC_BOT_CBW_Decode(USBD_HandleTypeDef  *pdev)
   hmsc->csw.dTag = hmsc->cbw.dTag;
   hmsc->csw.dDataResidue = hmsc->cbw.dDataLength;
 
-  if ((USBD_LL_GetRxDataSize(pdev, MSC_OUT_EP) != USBD_BOT_CBW_LENGTH) ||
+  if ((USBD_LL_GetRxDataSize(pdev, MSC_EPOUT_ADDR) != USBD_BOT_CBW_LENGTH) ||
       (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) ||
-      (hmsc->cbw.bLUN > 1U) ||
-      (hmsc->cbw.bCBLength < 1U) || (hmsc->cbw.bCBLength > 16U)) {
-
+      (hmsc->cbw.bLUN > 1U) || (hmsc->cbw.bCBLength < 1U) ||
+      (hmsc->cbw.bCBLength > 16U)) {
     SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
 
     hmsc->bot_status = USBD_BOT_STATUS_ERROR;
@@ -184,7 +186,7 @@ static void  MSC_BOT_CBW_Decode(USBD_HandleTypeDef  *pdev)
         MSC_BOT_Abort(pdev);
       }
     }
-    /*Burst xfer handled internally*/
+    /* Burst xfer handled internally */
     else if ((hmsc->bot_state != USBD_BOT_DATA_IN) &&
              (hmsc->bot_state != USBD_BOT_DATA_OUT) &&
              (hmsc->bot_state != USBD_BOT_LAST_DATA_IN)) {
@@ -209,18 +211,17 @@ static void  MSC_BOT_CBW_Decode(USBD_HandleTypeDef  *pdev)
 * @param  len: Data Length
 * @retval None
 */
-static void  MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
-                              uint16_t len)
+static void  MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len)
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
-  uint16_t length = (uint16_t)MIN(hmsc->cbw.dDataLength, len);
+  uint32_t length = MIN(hmsc->cbw.dDataLength, len);
 
   hmsc->csw.dDataResidue -= len;
   hmsc->csw.bStatus = USBD_CSW_CMD_PASSED;
   hmsc->bot_state = USBD_BOT_SEND_DATA;
 
-  USBD_LL_Transmit(pdev, MSC_IN_EP, pbuf, length);
+  (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, pbuf, length);
 }
 
 /**
@@ -230,8 +231,7 @@ static void  MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
 * @param  status : CSW status
 * @retval None
 */
-void  MSC_BOT_SendCSW(USBD_HandleTypeDef  *pdev,
-                      uint8_t CSW_Status)
+void  MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status)
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
@@ -239,12 +239,12 @@ void  MSC_BOT_SendCSW(USBD_HandleTypeDef  *pdev,
   hmsc->csw.bStatus = CSW_Status;
   hmsc->bot_state = USBD_BOT_IDLE;
 
-  USBD_LL_Transmit(pdev, MSC_IN_EP, (uint8_t *)(void *)&hmsc->csw,
-                   USBD_BOT_CSW_LENGTH);
+  (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, (uint8_t *)&hmsc->csw,
+                         USBD_BOT_CSW_LENGTH);
 
   /* Prepare EP to Receive next Cmd */
-  USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, (uint8_t *)(void *)&hmsc->cbw,
-                         USBD_BOT_CBW_LENGTH);
+  (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw,
+                               USBD_BOT_CBW_LENGTH);
 }
 
 /**
@@ -254,21 +254,21 @@ void  MSC_BOT_SendCSW(USBD_HandleTypeDef  *pdev,
 * @retval status
 */
 
-static void  MSC_BOT_Abort(USBD_HandleTypeDef  *pdev)
+static void  MSC_BOT_Abort(USBD_HandleTypeDef *pdev)
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
   if ((hmsc->cbw.bmFlags == 0U) &&
       (hmsc->cbw.dDataLength != 0U) &&
       (hmsc->bot_status == USBD_BOT_STATUS_NORMAL)) {
-    USBD_LL_StallEP(pdev, MSC_OUT_EP);
+    (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
   }
 
-  USBD_LL_StallEP(pdev, MSC_IN_EP);
+  (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
 
   if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) {
-    USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, (uint8_t *)(void *)&hmsc->cbw,
-                           USBD_BOT_CBW_LENGTH);
+    (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
+    (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
   }
 }
 
@@ -280,14 +280,14 @@ static void  MSC_BOT_Abort(USBD_HandleTypeDef  *pdev)
 * @retval None
 */
 
-void  MSC_BOT_CplClrFeature(USBD_HandleTypeDef  *pdev, uint8_t epnum)
+void  MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum)
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
   if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) {
     /* Bad CBW Signature */
-    USBD_LL_StallEP(pdev, MSC_IN_EP);
-    hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
+    (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR);
+    (void)USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR);
   } else if (((epnum & 0x80U) == 0x80U) && (hmsc->bot_status != USBD_BOT_STATUS_RECOVERY)) {
     MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
   } else {
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.c b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
index 7f960191a6..a1456d285c 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_data.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
@@ -33,18 +33,47 @@ EndBSPDependencies */
 
 
 /* USB Mass storage Page 0 Inquiry Data */
-const uint8_t  MSC_Page00_Inquiry_Data[] = {
+uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00] =
+{
   0x00,
   0x00,
   0x00,
   (LENGTH_INQUIRY_PAGE00 - 4U),
   0x00,
-  0x80,
-  0x83
+  0x80
 };
 
-/* USB Mass storage sense 6  Data */
-const uint8_t  MSC_Mode_Sense6_data[] = {
+/* USB Mass storage VPD Page 0x80 Inquiry Data for Unit Serial Number */
+uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] =
+{
+  0x00,
+  0x80,
+  0x00,
+  LENGTH_INQUIRY_PAGE80,
+  0x20,     /* Put Product Serial number */
+  0x20,
+  0x20,
+  0x20
+ };
+
+/* USB Mass storage sense 6 Data */
+uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] =
+{
+  0x22,
+  0x00,
+  0x00,
+  0x00,
+  0x08,
+  0x12,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
   0x00,
   0x00,
   0x00,
@@ -55,10 +84,31 @@ const uint8_t  MSC_Mode_Sense6_data[] = {
   0x00
 };
 
+
 /* USB Mass storage sense 10  Data */
-const uint8_t  MSC_Mode_Sense10_data[] = {
+uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] =
+{
+  0x00,
+  0x26,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x08,
+  0x12,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
+  0x00,
   0x00,
-  0x06,
   0x00,
   0x00,
   0x00,
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.h b/cores/arduino/stm32/usb/msc/usbd_msc_data.h
index e0ed04ee82..24ab8cf1a2 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_data.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.h
@@ -29,15 +29,17 @@ extern "C" {
 #include "usbd_conf.h"
 
 
-#define MODE_SENSE6_LEN                    8U
-#define MODE_SENSE10_LEN                   8U
-#define LENGTH_INQUIRY_PAGE00              7U
-#define LENGTH_FORMAT_CAPACITIES           20U
+#define MODE_SENSE6_LEN                    0x17U
+#define MODE_SENSE10_LEN                   0x1BU
+#define LENGTH_INQUIRY_PAGE00              0x06U
+#define LENGTH_INQUIRY_PAGE80              0x08U
+#define LENGTH_FORMAT_CAPACITIES           0x14U
 
 
-extern const uint8_t MSC_Page00_Inquiry_Data[];
-extern const uint8_t MSC_Mode_Sense6_data[];
-extern const uint8_t MSC_Mode_Sense10_data[] ;
+extern uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00];
+extern uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80];
+extern uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN];
+extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN];
 
 
 #ifdef __cplusplus
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
index 589355c365..59e62b86f7 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -40,12 +40,16 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
 static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
 static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
                                      uint32_t blk_offset, uint32_t blk_nbr);
@@ -53,6 +57,8 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
 static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun);
 static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun);
 
+static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc,
+                                 uint8_t *pBuff, uint16_t length);
 
 /**
 * @brief  SCSI_ProcessCmd
@@ -64,60 +70,78 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun);
 */
 int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
 {
+  int8_t ret;
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_storage;
+
   switch (cmd[0]) {
     case SCSI_TEST_UNIT_READY:
-      return SCSI_TestUnitReady(pdev, lun, cmd);
+      ret = SCSI_TestUnitReady(pdev, lun, cmd);
       break;
 
     case SCSI_REQUEST_SENSE:
-      return SCSI_RequestSense(pdev, lun, cmd);
+      ret = SCSI_RequestSense(pdev, lun, cmd);
       break;
+
     case SCSI_INQUIRY:
-      return SCSI_Inquiry(pdev, lun, cmd);
+      ret = SCSI_Inquiry(pdev, lun, cmd);
       break;
 
     case SCSI_START_STOP_UNIT:
-      return SCSI_StartStopUnit(pdev, lun, cmd);
+      ret = SCSI_StartStopUnit(pdev, lun, cmd);
       break;
 
     case SCSI_ALLOW_MEDIUM_REMOVAL:
-      return SCSI_StartStopUnit(pdev, lun, cmd);
+      ret = SCSI_AllowPreventRemovable(pdev, lun, cmd);
       break;
 
     case SCSI_MODE_SENSE6:
-      return SCSI_ModeSense6(pdev, lun, cmd);
+      ret = SCSI_ModeSense6(pdev, lun, cmd);
       break;
 
     case SCSI_MODE_SENSE10:
-      return SCSI_ModeSense10(pdev, lun, cmd);
+      ret = SCSI_ModeSense10(pdev, lun, cmd);
       break;
 
     case SCSI_READ_FORMAT_CAPACITIES:
-      return SCSI_ReadFormatCapacity(pdev, lun, cmd);
+      ret = SCSI_ReadFormatCapacity(pdev, lun, cmd);
       break;
 
     case SCSI_READ_CAPACITY10:
-      return SCSI_ReadCapacity10(pdev, lun, cmd);
+      ret = SCSI_ReadCapacity10(pdev, lun, cmd);
+      break;
+
+    case SCSI_READ_CAPACITY16:
+      ret = SCSI_ReadCapacity16(pdev, lun, cmd);
       break;
 
     case SCSI_READ10:
-      return SCSI_Read10(pdev, lun, cmd);
+      ret = SCSI_Read10(pdev, lun, cmd);
+      break;
+
+    case SCSI_READ12:
+      ret = SCSI_Read12(pdev, lun, cmd);
       break;
 
     case SCSI_WRITE10:
-      return SCSI_Write10(pdev, lun, cmd);
+      ret = SCSI_Write10(pdev, lun, cmd);
+      break;
+
+    case SCSI_WRITE12:
+      ret = SCSI_Write12(pdev, lun, cmd);
       break;
 
     case SCSI_VERIFY10:
-      return SCSI_Verify10(pdev, lun, cmd);
+      ret = SCSI_Verify10(pdev, lun, cmd);
       break;
 
     default:
       SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB);
-      return -1;
+      hmsc->bot_status = USBD_BOT_STATUS_ERROR;
+      ret = -1;
+      break;
   }
 
-  return 0;
+  return ret;
 }
 
 
@@ -128,8 +152,9 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
 * @param  params: Command parameters
 * @retval status
 */
-static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
 {
+  UNUSED(params);
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
   /* case 9 : Hi > D0 */
@@ -139,7 +164,14 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t
     return -1;
   }
 
-  if (msc_storage->IsReady(lun) != 0) {
+  if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) {
+    SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+    hmsc->bot_state = USBD_BOT_NO_DATA;
+    return -1;
+  }
+
+  if (msc_storage->IsReady(lun) != 0)
+  {
     SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
     hmsc->bot_state = USBD_BOT_NO_DATA;
 
@@ -150,6 +182,7 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t
   return 0;
 }
 
+
 /**
 * @brief  SCSI_Inquiry
 *         Process Inquiry command
@@ -157,20 +190,32 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t
 * @param  params: Command parameters
 * @retval status
 */
-static int8_t  SCSI_Inquiry(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
 {
   uint8_t *pPage;
   uint16_t len;
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
-  if (params[1] & 0x01U) {
-    /*Evpd is set*/
-    len = LENGTH_INQUIRY_PAGE00;
-    hmsc->bot_data_length = len;
+  if (hmsc->cbw.dDataLength == 0U)
+  {
+    SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+    return -1;
+  }
 
-    while (len) {
-      len--;
-      hmsc->bot_data[len] = MSC_Page00_Inquiry_Data[len];
+  if ((params[1] & 0x01U) != 0U) {
+    /* Evpd is set */
+    if (params[2] == 0U) {
+      /* Request for Supported Vital Product Data Pages*/
+      (void)SCSI_UpdateBotData(hmsc, MSC_Page00_Inquiry_Data, LENGTH_INQUIRY_PAGE00);
+    } else if (params[2] == 0x80U) {
+      /* Request for VPD page 0x80 Unit Serial Number */
+      (void)SCSI_UpdateBotData(hmsc, MSC_Page80_Inquiry_Data, LENGTH_INQUIRY_PAGE80);
+    } else {
+      /* Request Not supported */
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST,
+                     INVALID_FIELED_IN_COMMAND);
+
+      return -1;
     }
   } else {
     pPage = &msc_storage->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN];
@@ -179,17 +224,14 @@ static int8_t  SCSI_Inquiry(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *par
     if (params[4] <= len) {
       len = params[4];
     }
-    hmsc->bot_data_length = len;
 
-    while (len) {
-      len--;
-      hmsc->bot_data[len] = pPage[len];
-    }
+    (void)SCSI_UpdateBotData(hmsc, pPage, len);
   }
 
   return 0;
 }
 
+
 /**
 * @brief  SCSI_ReadCapacity10
 *         Process Read Capacity 10 command
@@ -197,29 +239,85 @@ static int8_t  SCSI_Inquiry(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *par
 * @param  params: Command parameters
 * @retval status
 */
-static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
 {
-  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+  UNUSED(params);
+  int8_t ret;
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
-  if (msc_storage->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size) != 0) {
+  ret = msc_storage->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size);
+
+  if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) {
     SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
     return -1;
-  } else {
+  }
+
+  hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24);
+  hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16);
+  hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >>  8);
+  hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1U);
+
+  hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >>  24);
+  hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >>  16);
+  hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >>  8);
+  hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size);
+
+  hmsc->bot_data_length = 8U;
+
+  return 0;
+
+}
 
-    hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24);
-    hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16);
-    hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >>  8);
-    hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1U);
 
-    hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >>  24);
-    hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >>  16);
-    hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >>  8);
-    hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size);
+/**
+* @brief  SCSI_ReadCapacity16
+*         Process Read Capacity 16 command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+  UNUSED(params);
+  uint8_t idx;
+  int8_t ret;
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
-    hmsc->bot_data_length = 8U;
-    return 0;
+  ret = msc_storage->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size);
+
+  if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) {
+    SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+    return -1;
+  }
+
+  hmsc->bot_data_length = ((uint32_t)params[10] << 24) |
+                          ((uint32_t)params[11] << 16) |
+                          ((uint32_t)params[12] <<  8) |
+                           (uint32_t)params[13];
+
+  for (idx = 0U; idx < hmsc->bot_data_length; idx++) {
+    hmsc->bot_data[idx] = 0U;
   }
+
+  hmsc->bot_data[4] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24);
+  hmsc->bot_data[5] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16);
+  hmsc->bot_data[6] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >>  8);
+  hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_nbr - 1U);
+
+  hmsc->bot_data[8] = (uint8_t)(hmsc->scsi_blk_size >>  24);
+  hmsc->bot_data[9] = (uint8_t)(hmsc->scsi_blk_size >>  16);
+  hmsc->bot_data[10] = (uint8_t)(hmsc->scsi_blk_size >>  8);
+  hmsc->bot_data[11] = (uint8_t)(hmsc->scsi_blk_size);
+
+  hmsc->bot_data_length = ((uint32_t)params[10] << 24) |
+                          ((uint32_t)params[11] << 16) |
+                          ((uint32_t)params[12] <<  8) |
+                           (uint32_t)params[13];
+
+  return 0;
 }
+
+
 /**
 * @brief  SCSI_ReadFormatCapacity
 *         Process Read Format Capacity command
@@ -227,37 +325,43 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_
 * @param  params: Command parameters
 * @retval status
 */
-static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
 {
-  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
-
+  UNUSED(params);
   uint16_t blk_size;
   uint32_t blk_nbr;
   uint16_t i;
+  int8_t ret;
+  USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  ret = msc_storage->GetCapacity(lun, &blk_nbr, &blk_size);
+
+  if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) {
+    SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+    return -1;
+  }
 
   for (i = 0U; i < 12U ; i++) {
     hmsc->bot_data[i] = 0U;
   }
 
-  if (msc_storage->GetCapacity(lun, &blk_nbr, &blk_size) != 0U) {
-    SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
-    return -1;
-  } else {
-    hmsc->bot_data[3] = 0x08U;
-    hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1U) >> 24);
-    hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1U) >> 16);
-    hmsc->bot_data[6] = (uint8_t)((blk_nbr - 1U) >>  8);
-    hmsc->bot_data[7] = (uint8_t)(blk_nbr - 1U);
+  hmsc->bot_data[3] = 0x08U;
+  hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1U) >> 24);
+  hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1U) >> 16);
+  hmsc->bot_data[6] = (uint8_t)((blk_nbr - 1U) >>  8);
+  hmsc->bot_data[7] = (uint8_t)(blk_nbr - 1U);
 
-    hmsc->bot_data[8] = 0x02U;
-    hmsc->bot_data[9] = (uint8_t)(blk_size >>  16);
-    hmsc->bot_data[10] = (uint8_t)(blk_size >>  8);
-    hmsc->bot_data[11] = (uint8_t)(blk_size);
+  hmsc->bot_data[8] = 0x02U;
+  hmsc->bot_data[9] = (uint8_t)(blk_size >>  16);
+  hmsc->bot_data[10] = (uint8_t)(blk_size >>  8);
+  hmsc->bot_data[11] = (uint8_t)(blk_size);
 
-    hmsc->bot_data_length = 12U;
-    return 0;
-  }
+  hmsc->bot_data_length = 12U;
+
+  return 0;
 }
+
+
 /**
 * @brief  SCSI_ModeSense6
 *         Process Mode Sense6 command
@@ -265,19 +369,22 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef  *pdev, uint8_t lun, ui
 * @param  params: Command parameters
 * @retval status
 */
-static int8_t SCSI_ModeSense6(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
 {
+  UNUSED(lun);
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
-  uint16_t len = 8U;
-  hmsc->bot_data_length = len;
+  uint16_t len = MODE_SENSE6_LEN;
 
-  while (len) {
-    len--;
-    hmsc->bot_data[len] = MSC_Mode_Sense6_data[len];
+  if (params[4] <= len) {
+    len = params[4];
   }
+
+  (void)SCSI_UpdateBotData(hmsc, MSC_Mode_Sense6_data, len);
+
   return 0;
 }
 
+
 /**
 * @brief  SCSI_ModeSense10
 *         Process Mode Sense10 command
@@ -285,21 +392,22 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *p
 * @param  params: Command parameters
 * @retval status
 */
-static int8_t SCSI_ModeSense10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
 {
-  uint16_t len = 8U;
+  UNUSED(lun);
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+  uint16_t len = MODE_SENSE10_LEN;
 
-  hmsc->bot_data_length = len;
-
-  while (len) {
-    len--;
-    hmsc->bot_data[len] = MSC_Mode_Sense10_data[len];
+  if (params[8] <= len) {
+    len = params[8];
   }
 
+  (void)SCSI_UpdateBotData(hmsc, MSC_Mode_Sense10_data, len);
+
   return 0;
 }
 
+
 /**
 * @brief  SCSI_RequestSense
 *         Process Request Sense command
@@ -307,58 +415,71 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *
 * @param  params: Command parameters
 * @retval status
 */
-
-static int8_t SCSI_RequestSense(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
 {
+  UNUSED(lun);
   uint8_t i;
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
-  for (i = 0U ; i < REQUEST_SENSE_DATA_LEN; i++) {
+  if (hmsc->cbw.dDataLength == 0U) {
+    SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+    return -1;
+  }
+
+  for (i = 0U; i < REQUEST_SENSE_DATA_LEN; i++) {
     hmsc->bot_data[i] = 0U;
   }
 
   hmsc->bot_data[0] = 0x70U;
   hmsc->bot_data[7] = REQUEST_SENSE_DATA_LEN - 6U;
 
-  if ((hmsc->scsi_sense_head != hmsc->scsi_sense_tail)) {
-
-    hmsc->bot_data[2]     = hmsc->scsi_sense[hmsc->scsi_sense_head].Skey;
-    hmsc->bot_data[12]    = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ;
-    hmsc->bot_data[13]    = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC;
+  if ((hmsc->scsi_sense_head != hmsc->scsi_sense_tail))
+  {
+    hmsc->bot_data[2] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].Skey;
+    hmsc->bot_data[12] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC;
+    hmsc->bot_data[13] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ;
     hmsc->scsi_sense_head++;
 
     if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH) {
       hmsc->scsi_sense_head = 0U;
     }
   }
+
   hmsc->bot_data_length = REQUEST_SENSE_DATA_LEN;
 
   if (params[4] <= REQUEST_SENSE_DATA_LEN) {
     hmsc->bot_data_length = params[4];
   }
+
   return 0;
 }
 
+
 /**
 * @brief  SCSI_SenseCode
 *         Load the last error code in the error list
 * @param  lun: Logical unit number
 * @param  sKey: Sense Key
-* @param  ASC: Additional Sense Key
+* @param  ASC: Additional Sense Code
 * @retval none
 
 */
-void SCSI_SenseCode(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC)
+void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC)
 {
+  UNUSED(lun);
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
-  hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey  = sKey;
-  hmsc->scsi_sense[hmsc->scsi_sense_tail].w.ASC = ASC << 8;
+  hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey = sKey;
+  hmsc->scsi_sense[hmsc->scsi_sense_tail].w.b.ASC = ASC;
+  hmsc->scsi_sense[hmsc->scsi_sense_tail].w.b.ASCQ = 0U;
   hmsc->scsi_sense_tail++;
+
   if (hmsc->scsi_sense_tail == SENSE_LIST_DEEPTH) {
     hmsc->scsi_sense_tail = 0U;
   }
 }
+
+
 /**
 * @brief  SCSI_StartStopUnit
 *         Process Start Stop Unit command
@@ -366,13 +487,59 @@ void SCSI_SenseCode(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t sKey, uint8_
 * @param  params: Command parameters
 * @retval status
 */
-static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
 {
+  UNUSED(lun);
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
+
+  if ((hmsc->scsi_medium_state == SCSI_MEDIUM_LOCKED) && ((params[4] & 0x3U) == 2U)) {
+    SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
+
+    return -1;
+  }
+
+  if ((params[4] & 0x3U) == 0x1U) /* START=1 */
+  {
+    hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
+  } else if ((params[4] & 0x3U) == 0x2U) {
+    /* START=0 and LOEJ Load Eject=1 */
+    hmsc->scsi_medium_state = SCSI_MEDIUM_EJECTED;
+  } else if ((params[4] & 0x3U) == 0x3U) {
+    /* START=1 and LOEJ Load Eject=1 */
+    hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
+  } else {
+    /* .. */
+  }
   hmsc->bot_data_length = 0U;
+
+  return 0;
+}
+
+
+/**
+* @brief  SCSI_AllowPreventRemovable
+*         Process Allow Prevent Removable medium command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+  UNUSED(lun);
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  if (params[4] == 0U) {
+    hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
+  } else {
+    hmsc->scsi_medium_state = SCSI_MEDIUM_LOCKED;
+  }
+
+  hmsc->bot_data_length = 0U;
+
   return 0;
 }
 
+
 /**
 * @brief  SCSI_Read10
 *         Process Read10 command
@@ -392,7 +559,13 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
       return -1;
     }
 
-    if (msc_storage->IsReady(lun) != 0) {
+    if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) {
+      SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+
+      return -1;
+    }
+
+    if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) {
       SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
       return -1;
     }
@@ -409,19 +582,78 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
       return -1; /* error */
     }
 
+    /* cases 4,5 : Hi <> Dn */
+    if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) {
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+    }
+
     hmsc->bot_state = USBD_BOT_DATA_IN;
+  }
+  hmsc->bot_data_length = MSC_MEDIA_PACKET;
+
+  return SCSI_ProcessRead(pdev, lun);
+}
+
+
+/**
+* @brief  SCSI_Read12
+*         Process Read12 command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+
+  if (hmsc->bot_state == USBD_BOT_IDLE) {
+    /* Idle */
+    /* case 10 : Ho <> Di */
+    if ((hmsc->cbw.bmFlags & 0x80U) != 0x80U) {
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+    }
+
+    if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED) {
+      SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+      return -1;
+    }
+
+    if (msc_storage->IsReady(lun) != 0) {
+      SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+      return -1;
+    }
+
+    hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
+                          ((uint32_t)params[3] << 16) |
+                          ((uint32_t)params[4] <<  8) |
+                          (uint32_t)params[5];
+
+    hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) |
+                         ((uint32_t)params[7] << 16) |
+                         ((uint32_t)params[8] << 8) |
+                         (uint32_t)params[9];
+
+    if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
+                               hmsc->scsi_blk_len) < 0) {
+      return -1; /* error */
+    }
 
     /* cases 4,5 : Hi <> Dn */
     if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) {
       SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
       return -1;
     }
+
+    hmsc->bot_state = USBD_BOT_DATA_IN;
   }
   hmsc->bot_data_length = MSC_MEDIA_PACKET;
 
   return SCSI_ProcessRead(pdev, lun);
 }
 
+
 /**
 * @brief  SCSI_Write10
 *         Process Write10 command
@@ -429,13 +661,18 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
 * @param  params: Command parameters
 * @retval status
 */
-static int8_t SCSI_Write10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
 {
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
   uint32_t len;
 
   if (hmsc->bot_state == USBD_BOT_IDLE) {
     /* Idle */
+    if (hmsc->cbw.dDataLength == 0U) {
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+    }
+
     /* case 8 : Hi <> Do */
     if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U) {
       SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
@@ -480,11 +717,89 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *para
 
     /* Prepare EP to receive first data packet */
     hmsc->bot_state = USBD_BOT_DATA_OUT;
-    USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, hmsc->bot_data, len);
+    (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
+  } else {
+    /* Write Process ongoing */
+    return SCSI_ProcessWrite(pdev, lun);
+  }
+
+  return 0;
+}
+
+
+/**
+* @brief  SCSI_Write12
+*         Process Write12 command
+* @param  lun: Logical unit number
+* @param  params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
+  uint32_t len;
+
+  if (hmsc->bot_state == USBD_BOT_IDLE) {
+    /* Idle */
+    if (hmsc->cbw.dDataLength == 0U) {
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+    }
+
+    /* case 8 : Hi <> Do */
+    if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U) {
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+    }
+
+    /* Check whether Media is ready */
+    if (msc_storage->IsReady(lun) != 0) {
+      SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
+      hmsc->bot_state = USBD_BOT_NO_DATA;
+      return -1;
+    }
+
+    /* Check If media is write-protected */
+    if (msc_storage->IsWriteProtected(lun) != 0) {
+      SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
+      hmsc->bot_state = USBD_BOT_NO_DATA;
+      return -1;
+    }
+
+    hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
+                          ((uint32_t)params[3] << 16) |
+                          ((uint32_t)params[4] << 8) |
+                          (uint32_t)params[5];
+
+    hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) |
+                         ((uint32_t)params[7] << 16) |
+                         ((uint32_t)params[8] << 8) |
+                         (uint32_t)params[9];
+
+    /* check if LBA address is in the right range */
+    if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
+                               hmsc->scsi_blk_len) < 0) {
+      return -1; /* error */
+    }
+
+    len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
+
+    /* cases 3,11,13 : Hn,Ho <> D0 */
+    if (hmsc->cbw.dDataLength != len) {
+      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
+      return -1;
+    }
+
+    len = MIN(len, MSC_MEDIA_PACKET);
+
+    /* Prepare EP to receive first data packet */
+    hmsc->bot_state = USBD_BOT_DATA_OUT;
+    (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
   } else {
     /* Write Process ongoing */
     return SCSI_ProcessWrite(pdev, lun);
   }
+
   return 0;
 }
 
@@ -496,8 +811,7 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *para
 * @param  params: Command parameters
 * @retval status
 */
-
-static int8_t SCSI_Verify10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
+static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
 {
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
@@ -510,7 +824,9 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *par
                              hmsc->scsi_blk_len) < 0) {
     return -1; /* error */
   }
+
   hmsc->bot_data_length = 0U;
+
   return 0;
 }
 
@@ -531,6 +847,7 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
     SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
     return -1;
   }
+
   return 0;
 }
 
@@ -540,7 +857,7 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
 * @param  lun: Logical unit number
 * @retval status
 */
-static int8_t SCSI_ProcessRead(USBD_HandleTypeDef  *pdev, uint8_t lun)
+static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
   uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
@@ -555,7 +872,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef  *pdev, uint8_t lun)
     return -1;
   }
 
-  USBD_LL_Transmit(pdev, MSC_IN_EP, hmsc->bot_data, len);
+  (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, hmsc->bot_data, len);
 
   hmsc->scsi_blk_addr += (len / hmsc->scsi_blk_size);
   hmsc->scsi_blk_len -= (len / hmsc->scsi_blk_size);
@@ -566,6 +883,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef  *pdev, uint8_t lun)
   if (hmsc->scsi_blk_len == 0U) {
     hmsc->bot_state = USBD_BOT_LAST_DATA_IN;
   }
+
   return 0;
 }
 
@@ -575,8 +893,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef  *pdev, uint8_t lun)
 * @param  lun: Logical unit number
 * @retval status
 */
-
-static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef  *pdev, uint8_t lun)
+static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun)
 {
   USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
   uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
@@ -587,7 +904,6 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef  *pdev, uint8_t lun)
                          hmsc->scsi_blk_addr,
                          (len / hmsc->scsi_blk_size)) < 0) {
     SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, WRITE_FAULT);
-
     return -1;
   }
 
@@ -601,13 +917,39 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef  *pdev, uint8_t lun)
     MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
   } else {
     len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET);
+
     /* Prepare EP to Receive next packet */
-    USBD_LL_PrepareReceive(pdev, MSC_OUT_EP, hmsc->bot_data, len);
+    (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);
   }
 
   return 0;
 }
 
+
+/**
+* @brief  SCSI_UpdateBotData
+*         fill the requested Data to transmit buffer
+* @param  hmsc handler
+* @param  params: Data buffer
+* @param  length: Data length
+* @retval status
+*/
+static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc,
+                                 uint8_t *pBuff, uint16_t length)
+{
+  uint16_t len = length;
+
+  hmsc->bot_data_length = len;
+
+  while (len != 0U) {
+    len--;
+    hmsc->bot_data[len] = pBuff[len];
+  }
+
+  return 0;
+}
+
+
 #endif /* USBD_USE_MSC_CLASS */
 #endif /* USBCON */
 
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
index 3c0d97ac6c..b39ad35c44 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.h
@@ -96,25 +96,19 @@ extern "C" {
 #define STANDARD_INQUIRY_DATA_LEN                   0x24U
 #define BLKVFY                                      0x04U
 
-extern  uint8_t Page00_Inquiry_Data[];
-extern  uint8_t Standard_Inquiry_Data[];
-extern  uint8_t Standard_Inquiry_Data2[];
-extern  uint8_t Mode_Sense6_data[];
-extern  uint8_t Mode_Sense10_data[];
-extern  uint8_t Scsi_Sense_Data[];
-extern  uint8_t ReadCapacity10_Data[];
-extern  uint8_t ReadFormatCapacity_Data [];
-
+#define SCSI_MEDIUM_UNLOCKED                        0x00U
+#define SCSI_MEDIUM_LOCKED                          0x01U
+#define SCSI_MEDIUM_EJECTED                         0x02U
 
 typedef struct _SENSE_ITEM {
-  char Skey;
+  uint8_t Skey;
   union {
     struct _ASCs {
-      char ASC;
-      char ASCQ;
+      uint8_t ASC;
+      uint8_t ASCQ;
     } b;
     uint8_t ASC;
-    char *pData;
+    uint8_t *pData;
   } w;
 } USBD_SCSI_SenseTypeDef;
 
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.c b/cores/arduino/stm32/usb/usbd_ep_conf.c
index 74f4eb44c6..2e72855e5d 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.c
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.c
@@ -44,6 +44,21 @@
   };
 #endif /* USBD_USE_CDC */
 
+#ifdef USBD_USE_MSC
+  #ifdef USE_USB_HS
+    #define MSC_DATA_MAX_PACKET_SIZE  MSC_DATA_HS_MAX_PACKET_SIZE
+  #else /* USE_USB_FS */
+    #define MSC_DATA_MAX_PACKET_SIZE  MSC_DATA_FS_MAX_PACKET_SIZE
+  #endif
+
+
+  const ep_desc_t ep_def[] = {
+    EP_DESC(0x00,       CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(0x80,       CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(MSC_EPIN_ADDR,  MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(MSC_EPOUT_ADDR, MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF)
+  };
+#endif /* USBD_USE_MSC */
 
 #ifdef USBD_USE_CDC_MSC
   #ifdef USE_USB_HS
@@ -61,8 +76,8 @@
     EP_DESC(CDC_OUT_EP, CDC_DATA_MAX_PACKET_SIZE, PCD_DBL_BUF),
     EP_DESC(CDC_IN_EP,  CDC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
     EP_DESC(CDC_CMD_EP, CDC_CMD_PACKET_SIZE,      PCD_SNG_BUF),
-    EP_DESC(MSC_IN_EP,  MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
-    EP_DESC(MSC_OUT_EP, MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF)
+    EP_DESC(MSC_EPIN_ADDR,  MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF),
+    EP_DESC(MSC_EPOUT_ADDR, MSC_DATA_MAX_PACKET_SIZE, PCD_SNG_BUF)
   };
 #endif /* USBD_USE_CDC */
 
diff --git a/cores/arduino/stm32/usb/usbd_ep_conf.h b/cores/arduino/stm32/usb/usbd_ep_conf.h
index 1243aa73ae..75a458b4d1 100644
--- a/cores/arduino/stm32/usb/usbd_ep_conf.h
+++ b/cores/arduino/stm32/usb/usbd_ep_conf.h
@@ -51,6 +51,18 @@ typedef struct {
   #define CDC_CMD_PACKET_SIZE                               8U  /* Control Endpoint Packet size */
 #endif /* USBD_USE_CDC */
 
+#ifdef USBD_USE_MSC
+  #define USBD_USE_MSC_CLASS
+
+  #define MSC_EPOUT_ADDR                0x01U /*  EP1 for MSC data IN */
+  #define MSC_EPIN_ADDR                 0x81U /*  EP1 for MSC data IN */
+
+  #define DEV_NUM_EP                    0x04U   /* Device Endpoints number including EP0 IN and EP0 OUT */
+
+  /* MSC Endpoints parameters*/
+  #define MSC_DATA_HS_MAX_PACKET_SIZE   USB_HS_MAX_PACKET_SIZE  /* Endpoint IN & OUT Packet size */
+  #define MSC_DATA_FS_MAX_PACKET_SIZE   USB_FS_MAX_PACKET_SIZE  /* Endpoint IN & OUT Packet size */
+#endif
 
 #ifdef USBD_USE_CDC_MSC
   #define USBD_USE_CDC_CLASS
@@ -60,8 +72,8 @@ typedef struct {
   #define CDC_IN_EP                     0x81U /*  EP1 for CDC data IN */
   #define CDC_CMD_EP                    0x82U /*  EP2 for CDC commands */
 
-  #define MSC_OUT_EP                    0x03U /*  EP3 for MSC data IN */
-  #define MSC_IN_EP                     0x83U /*  EP3 for MSC data IN */
+  #define MSC_EPOUT_ADDR                0x03U /*  EP3 for MSC data IN */
+  #define MSC_EPIN_ADDR                 0x83U /*  EP3 for MSC data IN */
 
   #define DEV_NUM_EP                    0x07U   /* Device Endpoints number including EP0 */
 

From a7fd6e25c531107ea4939be7290b6d952697777d Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 12:46:51 +0100
Subject: [PATCH 26/37] fixed ep addresses

---
 .../stm32/usb/cdc_msc/usbd_cdc_msc.cpp        | 24 +++++++++----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index 20e743aa45..754bc52c65 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -197,7 +197,7 @@ static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   /********************  Mass Storage Endpoints ********************/
   0x07,                                            /* Endpoint descriptor length = 7 */
   0x05,                                            /* Endpoint descriptor type */
-  MSC_IN_EP,                                       /* Endpoint address (IN, address 1) */
+  MSC_EPIN_ADDR,                                   /* Endpoint address (IN, address 1) */
   0x02,                                            /* Bulk endpoint type */
   LOBYTE(MSC_MAX_HS_PACKET),
   HIBYTE(MSC_MAX_HS_PACKET),
@@ -205,7 +205,7 @@ static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
 
   0x07,                                            /* Endpoint descriptor length = 7 */
   0x05,                                            /* Endpoint descriptor type */
-  MSC_OUT_EP,                                      /* Endpoint address (OUT, address 1) */
+  MSC_EPOUT_ADDR,                                  /* Endpoint address (OUT, address 1) */
   0x02,                                            /* Bulk endpoint type */
   LOBYTE(MSC_MAX_HS_PACKET),
   HIBYTE(MSC_MAX_HS_PACKET),
@@ -324,7 +324,7 @@ static uint8_t USBD_COMPOSITE_FSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   /********************  Mass Storage Endpoints ********************/
   0x07,                                            /* Endpoint descriptor length = 7 */
   0x05,                                            /* Endpoint descriptor type */
-  MSC_IN_EP,                                       /* Endpoint address (IN, address 1) */
+  MSC_EPIN_ADDR,                                   /* Endpoint address (IN, address 1) */
   0x02,                                            /* Bulk endpoint type */
   LOBYTE(MSC_MAX_FS_PACKET),
   HIBYTE(MSC_MAX_FS_PACKET),
@@ -332,7 +332,7 @@ static uint8_t USBD_COMPOSITE_FSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
 
   0x07,                                            /* Endpoint descriptor length = 7 */
   0x05,                                            /* Endpoint descriptor type */
-  MSC_OUT_EP,                                      /* Endpoint address (OUT, address 1) */
+  MSC_EPOUT_ADDR,                                  /* Endpoint address (OUT, address 1) */
   0x02,                                            /* Bulk endpoint type */
   LOBYTE(MSC_MAX_FS_PACKET),
   HIBYTE(MSC_MAX_FS_PACKET),
@@ -451,7 +451,7 @@ static uint8_t USBD_COMPOSITE_OtherSpeedCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   /********************  Mass Storage Endpoints ********************/
   0x07,                                            /* Endpoint descriptor length = 7 */
   0x05,                                            /* Endpoint descriptor type */
-  MSC_IN_EP,                                       /* Endpoint address (IN, address 1) */
+  MSC_EPIN_ADDR,                                   /* Endpoint address (IN, address 1) */
   0x02,                                            /* Bulk endpoint type */
   LOBYTE(MSC_MAX_FS_PACKET),
   HIBYTE(MSC_MAX_FS_PACKET),
@@ -459,7 +459,7 @@ static uint8_t USBD_COMPOSITE_OtherSpeedCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
 
   0x07,                                            /* Endpoint descriptor length = 7 */
   0x05,                                            /* Endpoint descriptor type */
-  MSC_OUT_EP,                                      /* Endpoint address (OUT, address 1) */
+  MSC_EPOUT_ADDR,                                  /* Endpoint address (OUT, address 1) */
   0x02,                                            /* Bulk endpoint type */
   LOBYTE(MSC_MAX_FS_PACKET),
   HIBYTE(MSC_MAX_FS_PACKET),
@@ -561,8 +561,8 @@ static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
         case CDC_CMD_EP:
           return USBD_CDC.Setup(pdev, req);
 
-        case MSC_IN_EP:
-        case MSC_OUT_EP:
+        case MSC_EPIN_ADDR:
+        case MSC_EPOUT_ADDR:
           return USBD_MSC.Setup(pdev, req);
 
         // invalid endpoint
@@ -644,8 +644,8 @@ static uint8_t  USBD_COMPOSITE_DataIn(USBD_HandleTypeDef *pdev,
     case CDC_OUT_EP:
       return USBD_CDC.DataIn(pdev, epnum);
 
-    case MSC_IN_EP:
-    case MSC_OUT_EP:
+    case MSC_EPIN_ADDR:
+    case MSC_EPOUT_ADDR:
       return USBD_MSC.DataIn(pdev, epnum);
 
     // invalid endpoint
@@ -694,8 +694,8 @@ static uint8_t  USBD_COMPOSITE_DataOut(USBD_HandleTypeDef *pdev,
     case CDC_OUT_EP:
       return USBD_CDC.DataOut(pdev, epnum);
 
-    case MSC_IN_EP:
-    case MSC_OUT_EP:
+    case MSC_EPIN_ADDR:
+    case MSC_EPOUT_ADDR:
       return USBD_MSC.DataOut(pdev, epnum);
 
     // invalid endpoint

From df73d28f43f61c78c9c611eb206c6e5148a61f85 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 12:51:28 +0100
Subject: [PATCH 27/37] fixed formatting

---
 cores/arduino/stm32/usb/cdc/usbd_cdc.c      | 28 ++++++++++-----------
 cores/arduino/stm32/usb/msc/usbd_msc_data.c | 12 +++------
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c | 17 ++++++-------
 3 files changed, 25 insertions(+), 32 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index e8d6e982d7..a767e2f831 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -441,31 +441,31 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
     (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
                          CDC_DATA_HS_IN_PACKET_SIZE);
 
-     pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
+    pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
 
-     /* Open EP OUT */
-     (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
-                          CDC_DATA_HS_OUT_PACKET_SIZE);
+    /* Open EP OUT */
+    (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
+                         CDC_DATA_HS_OUT_PACKET_SIZE);
 
-      pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
+    pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
 
-      /* Set bInterval for CDC CMD Endpoint */
-      pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL;
+    /* Set bInterval for CDC CMD Endpoint */
+    pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL;
   } else {
     /* Open EP IN */
     (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
                          CDC_DATA_FS_IN_PACKET_SIZE);
 
-     pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
+    pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
 
      /* Open EP OUT */
-     (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
-                          CDC_DATA_FS_OUT_PACKET_SIZE);
+    (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
+                         CDC_DATA_FS_OUT_PACKET_SIZE);
 
-      pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
+    pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
 
-      /* Set bInterval for CMD Endpoint */
-      pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL;
+    /* Set bInterval for CMD Endpoint */
+    pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL;
   }
 
   /* Open Command IN EP */
@@ -580,7 +580,7 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
 
         case USB_REQ_GET_INTERFACE:
           if (pdev->dev_state == USBD_STATE_CONFIGURED) {
-           (void)USBD_CtlSendData(pdev, &ifalt, 1U);
+            (void)USBD_CtlSendData(pdev, &ifalt, 1U);
           } else {
             USBD_CtlError(pdev, req);
             ret = USBD_FAIL;
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.c b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
index a1456d285c..9d788c64ca 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_data.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
@@ -33,8 +33,7 @@ EndBSPDependencies */
 
 
 /* USB Mass storage Page 0 Inquiry Data */
-uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00] =
-{
+uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00] = {
   0x00,
   0x00,
   0x00,
@@ -44,8 +43,7 @@ uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00] =
 };
 
 /* USB Mass storage VPD Page 0x80 Inquiry Data for Unit Serial Number */
-uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] =
-{
+uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] = {
   0x00,
   0x80,
   0x00,
@@ -57,8 +55,7 @@ uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] =
  };
 
 /* USB Mass storage sense 6 Data */
-uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] =
-{
+uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] = {
   0x22,
   0x00,
   0x00,
@@ -86,8 +83,7 @@ uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] =
 
 
 /* USB Mass storage sense 10  Data */
-uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] =
-{
+uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] = {
   0x00,
   0x26,
   0x00,
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
index 59e62b86f7..ea8e903d10 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -170,8 +170,7 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
     return -1;
   }
 
-  if (msc_storage->IsReady(lun) != 0)
-  {
+  if (msc_storage->IsReady(lun) != 0) {
     SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
     hmsc->bot_state = USBD_BOT_NO_DATA;
 
@@ -196,8 +195,7 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
   uint16_t len;
   USBD_MSC_BOT_HandleTypeDef  *hmsc = msc_handle;
 
-  if (hmsc->cbw.dDataLength == 0U)
-  {
+  if (hmsc->cbw.dDataLength == 0U) {
     SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
     return -1;
   }
@@ -293,7 +291,7 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
   hmsc->bot_data_length = ((uint32_t)params[10] << 24) |
                           ((uint32_t)params[11] << 16) |
                           ((uint32_t)params[12] <<  8) |
-                           (uint32_t)params[13];
+                          (uint32_t)params[13];
 
   for (idx = 0U; idx < hmsc->bot_data_length; idx++) {
     hmsc->bot_data[idx] = 0U;
@@ -312,7 +310,7 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
   hmsc->bot_data_length = ((uint32_t)params[10] << 24) |
                           ((uint32_t)params[11] << 16) |
                           ((uint32_t)params[12] <<  8) |
-                           (uint32_t)params[13];
+                          (uint32_t)params[13];
 
   return 0;
 }
@@ -433,8 +431,7 @@ static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *
   hmsc->bot_data[0] = 0x70U;
   hmsc->bot_data[7] = REQUEST_SENSE_DATA_LEN - 6U;
 
-  if ((hmsc->scsi_sense_head != hmsc->scsi_sense_tail))
-  {
+  if ((hmsc->scsi_sense_head != hmsc->scsi_sense_tail)) {
     hmsc->bot_data[2] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].Skey;
     hmsc->bot_data[12] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC;
     hmsc->bot_data[13] = (uint8_t)hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ;
@@ -498,8 +495,8 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
     return -1;
   }
 
-  if ((params[4] & 0x3U) == 0x1U) /* START=1 */
-  {
+  if ((params[4] & 0x3U) == 0x1U) {
+    /* START=1 */
     hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
   } else if ((params[4] & 0x3U) == 0x2U) {
     /* START=0 and LOEJ Load Eject=1 */

From 760d8e3c2bd95d4eecb2574e5609924214dc1126 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 13:46:30 +0100
Subject: [PATCH 28/37] added back cdc clear buffer

---
 cores/arduino/stm32/usb/cdc/usbd_cdc.c      | 2 +-
 cores/arduino/stm32/usb/cdc/usbd_cdc.h      | 3 +++
 cores/arduino/stm32/usb/cdc/usbd_cdc_if.c   | 8 ++++++++
 cores/arduino/stm32/usb/msc/usbd_msc_data.c | 2 +-
 4 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index a767e2f831..f7b7865a95 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -458,7 +458,7 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 
     pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
 
-     /* Open EP OUT */
+    /* Open EP OUT */
     (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
                          CDC_DATA_FS_OUT_PACKET_SIZE);
 
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.h b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
index 0f4dfd89af..93ce74fbcb 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.h
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
@@ -150,6 +150,9 @@ uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
 uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
 uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
 uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
+
+uint8_t  USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev);
+
 /**
   * @}
   */
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
index c55ece32f7..fa41e06fcf 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
@@ -322,6 +322,14 @@ bool CDC_resume_receive(void)
   return false;
 }
 
+uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev)
+{
+  /* Suspend or Resume USB Out process */
+  /* Prepare Out endpoint to receive next packet */
+  USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, 0, 0);
+  return USBD_OK;
+}
+
 #endif /* USBD_USE_CDC */
 #endif /* USBCON */
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_data.c b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
index 9d788c64ca..a2ae3c0f31 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_data.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_data.c
@@ -52,7 +52,7 @@ uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] = {
   0x20,
   0x20,
   0x20
- };
+};
 
 /* USB Mass storage sense 6 Data */
 uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] = {

From f7dbf85d03b467382ae080426c184b31ae213ed0 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 15:21:58 +0100
Subject: [PATCH 29/37] remove reference to userdata

---
 cores/arduino/stm32/usb/cdc/usbd_cdc.c      | 2 +-
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index f7b7865a95..8523cf43f6 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -680,7 +680,7 @@ static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
 {
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
-  if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) {
+  if ((hcdc->CmdOpCode != 0xFFU)) {
     cdc_itf->Control(hcdc->CmdOpCode,
                      (uint8_t *)hcdc->data,
                      (uint16_t)hcdc->CmdLength);
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
index ea8e903d10..fe80bf50dd 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -562,7 +562,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
       return -1;
     }
 
-    if (((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) != 0) {
+    if (msc_storage->IsReady(lun) != 0) {
       SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
       return -1;
     }

From 6d0023f772f2d98dd77933104948a5290c9c09e4 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 15:41:19 +0100
Subject: [PATCH 30/37] fixed pointer error and warning

---
 cores/arduino/stm32/usb/cdc/usbd_cdc.c      | 1 +
 cores/arduino/stm32/usb/msc/usbd_msc_scsi.c | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index 8523cf43f6..6c1945f23d 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -431,6 +431,7 @@ int cdcInitialized;
 static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 {
   UNUSED(cfgidx);
+  UNUSED(ret);
 
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
diff --git a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
index fe80bf50dd..269bc30ff4 100644
--- a/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
+++ b/cores/arduino/stm32/usb/msc/usbd_msc_scsi.c
@@ -71,7 +71,7 @@ static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc,
 int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
 {
   int8_t ret;
-  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_storage;
+  USBD_MSC_BOT_HandleTypeDef *hmsc = msc_handle;
 
   switch (cmd[0]) {
     case SCSI_TEST_UNIT_READY:

From 4d0f56282a12d6a196dc097597a5b8ba5fa1a46e Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 18:08:15 +0100
Subject: [PATCH 31/37] changes to cdc msc interface definitions

---
 .../stm32/usb/cdc_msc/usbd_cdc_msc.cpp        | 50 +++++++++----------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index 754bc52c65..3ab66d91ab 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -108,13 +108,13 @@ static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   0x09,   /* bLength: Interface Descriptor size */
   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
   /* Interface descriptor type */
-  0x00,   /* bInterfaceNumber: Number of Interface */
+  CDC_ACM_INTERFACE,   /* 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 */
-  0x00,   /* iInterface: */
+  0x05,   /* iInterface: */
 
   /*Header Functional Descriptor*/
   0x05,   /* bLength: Endpoint Descriptor size */
@@ -128,7 +128,7 @@ static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
   0x00,   /* bmCapabilities: D0+D1 */
-  0x01,   /* bDataInterface: 1 */
+  CDC_COM_INTERFACE,   /* bDataInterface: 1 */
 
   /*ACM Functional Descriptor*/
   0x04,   /* bFunctionLength */
@@ -140,8 +140,8 @@ static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   0x05,   /* bFunctionLength */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x06,   /* bDescriptorSubtype: Union func desc */
-  0x00,   /* bMasterInterface: Communication class interface */
-  0x01,   /* bSlaveInterface0: Data Class Interface */
+  CDC_ACM_INTERFACE,   /* bMasterInterface: Communication class interface */
+  CDC_COM_INTERFACE,   /* bSlaveInterface0: Data Class Interface */
 
   /*Endpoint 2 Descriptor*/
   0x07,                           /* bLength: Endpoint Descriptor size */
@@ -156,13 +156,13 @@ static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   /*Data class interface descriptor*/
   0x09,   /* bLength: Endpoint Descriptor size */
   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
-  0x01,   /* bInterfaceNumber: Number of Interface */
+  CDC_COM_INTERFACE,   /* bInterfaceNumber: Number of Interface */
   0x00,   /* bAlternateSetting: Alternate setting */
   0x02,   /* bNumEndpoints: Two endpoints used */
   0x0A,   /* bInterfaceClass: CDC */
   0x00,   /* bInterfaceSubClass: */
   0x00,   /* bInterfaceProtocol: */
-  0x00,   /* iInterface: */
+  0x05,   /* iInterface: */
 
   /*Endpoint OUT Descriptor*/
   0x07,                                /* bLength: Endpoint Descriptor size */
@@ -186,7 +186,7 @@ static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   /********************  Mass Storage interface ********************/
   0x09,                                            /* bLength: Interface Descriptor size */
   0x04,                                            /* bDescriptorType: */
-  0x02,                                            /* bInterfaceNumber: Number of Interface */
+  MSC_INTERFACE,                                            /* bInterfaceNumber: Number of Interface */
   0x00,                                            /* bAlternateSetting: Alternate setting */
   0x02,                                            /* bNumEndpoints */
   0x08,                                            /* bInterfaceClass: MSC Class */
@@ -235,13 +235,13 @@ static uint8_t USBD_COMPOSITE_FSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   0x09,   /* bLength: Interface Descriptor size */
   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
   /* Interface descriptor type */
-  0x00,   /* bInterfaceNumber: Number of Interface */
+  CDC_ACM_INTERFACE,   /* 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 */
-  0x00,   /* iInterface: */
+  0x05,   /* iInterface: */
 
   /*Header Functional Descriptor*/
   0x05,   /* bLength: Endpoint Descriptor size */
@@ -267,29 +267,29 @@ static uint8_t USBD_COMPOSITE_FSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   0x05,   /* bFunctionLength */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x06,   /* bDescriptorSubtype: Union func desc */
-  0x00,   /* bMasterInterface: Communication class interface */
-  0x01,   /* bSlaveInterface0: Data Class Interface */
+  CDC_ACM_INTERFACE,   /* bMasterInterface: Communication class interface */
+  CDC_COM_INTERFACE,   /* bSlaveInterface0: Data Class Interface */
 
   /*Endpoint 2 Descriptor*/
   0x07,                           /* bLength: Endpoint Descriptor size */
-  USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
+  USB_DESC_TYPE_ENDPOINT,         /* bDescriptorType: Endpoint */
   CDC_CMD_EP,                     /* bEndpointAddress */
   0x03,                           /* bmAttributes: Interrupt */
-  LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
+  LOBYTE(CDC_CMD_PACKET_SIZE),    /* wMaxPacketSize: */
   HIBYTE(CDC_CMD_PACKET_SIZE),
-  CDC_FS_BINTERVAL,                           /* bInterval: */
+  CDC_FS_BINTERVAL,               /* bInterval: */
   /*---------------------------------------------------------------------------*/
 
   /*Data class interface descriptor*/
   0x09,   /* bLength: Endpoint Descriptor size */
   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
-  0x01,   /* bInterfaceNumber: Number of Interface */
+  CDC_COM_INTERFACE,   /* bInterfaceNumber: Number of Interface */
   0x00,   /* bAlternateSetting: Alternate setting */
   0x02,   /* bNumEndpoints: Two endpoints used */
   0x0A,   /* bInterfaceClass: CDC */
   0x00,   /* bInterfaceSubClass: */
   0x00,   /* bInterfaceProtocol: */
-  0x00,   /* iInterface: */
+  0x05,   /* iInterface: */
 
   /*Endpoint OUT Descriptor*/
   0x07,                                /* bLength: Endpoint Descriptor size */
@@ -313,7 +313,7 @@ static uint8_t USBD_COMPOSITE_FSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   /********************  Mass Storage interface ********************/
   0x09,                                            /* bLength: Interface Descriptor size */
   0x04,                                            /* bDescriptorType: */
-  0x02,                                            /* bInterfaceNumber: Number of Interface */
+  MSC_INTERFACE,                                   /* bInterfaceNumber: Number of Interface */
   0x00,                                            /* bAlternateSetting: Alternate setting */
   0x02,                                            /* bNumEndpoints */
   0x08,                                            /* bInterfaceClass: MSC Class */
@@ -362,13 +362,13 @@ static uint8_t USBD_COMPOSITE_OtherSpeedCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   0x09,   /* bLength: Interface Descriptor size */
   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
   /* Interface descriptor type */
-  0x00,   /* bInterfaceNumber: Number of Interface */
+  CDC_ACM_INTERFACE,   /* 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 */
-  0x00,   /* iInterface: */
+  0x05,   /* iInterface: */
 
   /*Header Functional Descriptor*/
   0x05,   /* bLength: Endpoint Descriptor size */
@@ -394,8 +394,8 @@ static uint8_t USBD_COMPOSITE_OtherSpeedCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   0x05,   /* bFunctionLength */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x06,   /* bDescriptorSubtype: Union func desc */
-  0x00,   /* bMasterInterface: Communication class interface */
-  0x01,   /* bSlaveInterface0: Data Class Interface */
+  CDC_ACM_INTERFACE,   /* bMasterInterface: Communication class interface */
+  CDC_COM_INTERFACE,   /* bSlaveInterface0: Data Class Interface */
 
   /*Endpoint 2 Descriptor*/
   0x07,                           /* bLength: Endpoint Descriptor size */
@@ -410,13 +410,13 @@ static uint8_t USBD_COMPOSITE_OtherSpeedCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   /*Data class interface descriptor*/
   0x09,   /* bLength: Endpoint Descriptor size */
   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
-  0x01,   /* bInterfaceNumber: Number of Interface */
+  CDC_COM_INTERFACE,        /* bInterfaceNumber: Number of Interface */
   0x00,   /* bAlternateSetting: Alternate setting */
   0x02,   /* bNumEndpoints: Two endpoints used */
   0x0A,   /* bInterfaceClass: CDC */
   0x00,   /* bInterfaceSubClass: */
   0x00,   /* bInterfaceProtocol: */
-  0x00,   /* iInterface: */
+  0x05,   /* iInterface: */
 
   /*Endpoint OUT Descriptor*/
   0x07,                                /* bLength: Endpoint Descriptor size */
@@ -440,7 +440,7 @@ static uint8_t USBD_COMPOSITE_OtherSpeedCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
   /********************  Mass Storage interface ********************/
   0x09,                                            /* bLength: Interface Descriptor size */
   0x04,                                            /* bDescriptorType: */
-  0x02,                                            /* bInterfaceNumber: Number of Interface */
+  MSC_INTERFACE,                                   /* bInterfaceNumber: Number of Interface */
   0x00,                                            /* bAlternateSetting: Alternate setting */
   0x02,                                            /* bNumEndpoints */
   0x08,                                            /* bInterfaceClass: MSC Class */

From b29c3ea6dc83ea3bf959aa8ca6e4b3dd062cd10b Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 18:09:47 +0100
Subject: [PATCH 32/37] remove SOF from MSC+CDC

---
 cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index 3ab66d91ab..5f22361fd6 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -66,7 +66,6 @@ static uint8_t  USBD_COMPOSITE_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
 
 static uint8_t  USBD_COMPOSITE_EP0_RxReady(USBD_HandleTypeDef *pdev);
 
-static uint8_t  USBD_COMPOSITE_SOF(USBD_HandleTypeDef *pdev);
 
 USBD_ClassTypeDef  USBD_CDC_MSC = {
   USBD_COMPOSITE_Init,
@@ -76,7 +75,7 @@ USBD_ClassTypeDef  USBD_CDC_MSC = {
   USBD_COMPOSITE_EP0_RxReady,
   USBD_COMPOSITE_DataIn,
   USBD_COMPOSITE_DataOut,
-  USBD_COMPOSITE_SOF,
+  nullptr,
   nullptr,
   nullptr,
   USBD_COMPOSITE_GetHSCfgDesc,
@@ -666,18 +665,6 @@ static uint8_t  USBD_COMPOSITE_EP0_RxReady(USBD_HandleTypeDef *pdev)
   return USBD_CDC.EP0_RxReady(pdev);
 }
 
-/**
-  * @brief  USBD_COMPOSITE_SOF
-  *         handle SOF event
-  * @param  pdev: device instance
-  * @retval status
-  */
-static uint8_t  USBD_COMPOSITE_SOF(USBD_HandleTypeDef *pdev)
-{
-  // only needed for CDC
-  return USBD_CDC.SOF(pdev);
-}
-
 /**
   * @brief  USBD_COMPOSITE_DataOut
   *         handle data OUT Stage

From 2207a41855b03bf4011f47b0f4c276a320467d75 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 18:33:59 +0000
Subject: [PATCH 33/37] further changes during merging

---
 cores/arduino/stm32/usb/cdc/usbd_cdc.c    | 13 ++++++++++++-
 cores/arduino/stm32/usb/cdc/usbd_cdc.h    |  3 +--
 cores/arduino/stm32/usb/cdc/usbd_cdc_if.c | 10 +---------
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
index 6c1945f23d..f76e248bb4 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c
@@ -431,7 +431,6 @@ int cdcInitialized;
 static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
 {
   UNUSED(cfgidx);
-  UNUSED(ret);
 
   USBD_CDC_HandleTypeDef *hcdc = cdc_handle;
 
@@ -857,6 +856,18 @@ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
   return (uint8_t)USBD_OK;
 }
 
+uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev)
+{
+  /* Suspend or Resume USB Out process */
+  if (pdev->pClassData != NULL) {
+    /* Prepare Out endpoint to receive next packet */
+    USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, 0, 0);
+    return (uint8_t)USBD_OK;
+  } else {
+    return (uint8_t)USBD_FAIL;
+  }
+}
+
 #endif /* USBD_USE_CDC_CLASS */
 #endif /* USBCON */
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.h b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
index 93ce74fbcb..5a9bce8606 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc.h
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.h
@@ -150,8 +150,7 @@ uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
 uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
 uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
 uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev);
-
-uint8_t  USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev);
+uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev);
 
 /**
   * @}
diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
index fa41e06fcf..6b731641b4 100644
--- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
+++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
@@ -242,7 +242,7 @@ static int8_t USBD_CDC_Receive(uint8_t *Buf, uint32_t *Len)
 
 
 /**
-  * @brief  TEMPLATE_TransmitCplt
+  * @brief  USBD_CDC_TransmitCplt
   *         Data transmited callback
   *
   *         @note
@@ -322,14 +322,6 @@ bool CDC_resume_receive(void)
   return false;
 }
 
-uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev)
-{
-  /* Suspend or Resume USB Out process */
-  /* Prepare Out endpoint to receive next packet */
-  USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, 0, 0);
-  return USBD_OK;
-}
-
 #endif /* USBD_USE_CDC */
 #endif /* USBCON */
 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

From a34101102e58d443951c2bd2cd47843b48ccf598 Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Thu, 4 Jun 2020 20:13:16 +0100
Subject: [PATCH 34/37] set cdc usb handle to usb handle

---
 cores/arduino/USB.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp
index 8f16e1e9ea..1b2dfaca24 100644
--- a/cores/arduino/USB.cpp
+++ b/cores/arduino/USB.cpp
@@ -89,6 +89,7 @@ void USB::initialize()
 #endif
 
 #ifdef USBD_USE_CDC_CLASS
+  hUSBD_Device_CDC = &hUSBD_Device;
   if (USBD_CDC_RegisterInterface(&hUSBD_Device, &USBD_CDC_fops) != USBD_OK) {
     return;
   }

From 8709e8f9afeb9b6e0c9c73d734ba5bd14bd7db0a Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Sun, 7 Jun 2020 11:18:47 +0000
Subject: [PATCH 35/37] refactored cdc msc descriptor and fixed for windowsn

---
 .../stm32/usb/cdc_msc/usbd_cdc_msc.cpp        | 527 ++++++------------
 .../arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h  |   2 +-
 cores/arduino/stm32/usb/usbd_desc.c           | 110 ++--
 3 files changed, 207 insertions(+), 432 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index 5f22361fd6..419be31e05 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -84,131 +84,141 @@ USBD_ClassTypeDef  USBD_CDC_MSC = {
   USBD_COMPOSITE_GetDeviceQualifierDesc,
 };
 
+
+#define EP_ATTR_BULK      0x02
+#define EP_ATTR_INTERRUPT 0x03
+
+#define IF_CLASS_COMM     0x02
+#define IF_CLASS_CDC      0x0A
+#define IF_CLASS_MSC      0x08
+
+#define IF_SUBCLASS_NONE              0x00
+#define IF_SUBCLASS_ACM               0x02
+#define IF_SUBCLASS_SCSI_TRANSPARENT  0x06
+
+#define ENDPOINT_DESCRIPTOR(_EP_ADDR, _ATTR, _PACKET_SIZE, _BINTERVAL) \
+  0x07,                           /* bLength: Endpoint Descriptor size */ \
+  USB_DESC_TYPE_ENDPOINT,         /* bDescriptorType: Endpoint */ \
+  _EP_ADDR,                       /* bEndpointAddress */ \
+  _ATTR,                          /* bmAttributes: Interrupt */ \
+  LOBYTE(_PACKET_SIZE),           /* wMaxPacketSize: */ \
+  HIBYTE(_PACKET_SIZE), \
+  _BINTERVAL                      /* bInterval: */
+
+
+/* ACM Interface Descriptor */
+#define INTERFACE_DESCRIPTOR(_IF_NUM, _EP_COUNT, _CLASS, _SUBCLASS, _PROT) \
+  0x09,   /* bLength: Interface Descriptor size */ \
+  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */ \
+  /* Interface descriptor type */ \
+  _IF_NUM,   /* bInterfaceNumber: Number of Interface */ \
+  0x00,   /* bAlternateSetting: Alternate setting */ \
+  _EP_COUNT,   /* bNumEndpoints: One endpoints used */ \
+  _CLASS,   /* bInterfaceClass: Communication Interface Class */ \
+  _SUBCLASS,   /* bInterfaceSubClass: Abstract Control Model */ \
+  _PROT,   /* bInterfaceProtocol: Common AT commands */ \
+  0x05   /* iInterface: */
+
+
+
+#define USB_DESC_TYPE_INTERFACE_ASSOC_DESC        0x0B
+
+#define CONFIGURATION_DESCRIPTOR() \
+  0x09, /* bLength: Configuation Descriptor size */   \
+  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ \
+  USB_CDC_MSC_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */   \
+  0x00,                                               \
+  0x03, /*bNumInterfaces: 3 interface*/               \
+  0x01, /*bConfigurationValue: Configuration value*/  \
+  0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ \
+  0xC0, /*bmAttributes: bus powered and Supports Remote Wakeup */ \
+  0x32  /*MaxPower 100 mA: this current is used for detecting Vbus*/
+/* 09 */
+
+/******** IAD should be positioned just before the CDC interfaces ******
+          IAD to associate the two CDC interfaces */
+#define IAD_DESCRIPTOR() \
+  0x08, /* bLength: Interface Descriptor size */  \
+  USB_DESC_TYPE_INTERFACE_ASSOC_DESC, /* bDescriptorType: Interface */  \
+  0x00, /* bFirstInterface */     \
+  0x02, /* bInterfaceCount */     \
+  0x02, /* bFunctionClass */      \
+  0x02, /* bFunctionSubClass */   \
+  0x01, /* bFunctionProtocol */   \
+  0x04    /* iFunction (Index of string descriptor describing this function) */
+/* 08 */
+
+/* ACM Interface Descriptor */
+#define ACM_INTERFACE_DESCRIPTOR() INTERFACE_DESCRIPTOR(CDC_ACM_INTERFACE, 0x01, IF_CLASS_COMM, IF_SUBCLASS_ACM, 0x01)
+
+/* Header Functional Descriptor */
+#define ACM_HEADER_FUNCTIONAL_DESCRIPTOR() \
+  0x05,   /* bLength: Endpoint Descriptor size */ \
+  0x24,   /* bDescriptorType: CS_INTERFACE */ \
+  0x00,   /* bDescriptorSubtype: Header Func Desc */ \
+  0x10,   /* bcdCDC: spec release number */ \
+  0x01
+
+/* ACM Call Management Functional Descriptor */
+#define ACM_CALL_MANAGEMENT_FUNCTIONAL_DESCRIPTOR() \
+  0x05,   /* bFunctionLength */ \
+  0x24,   /* bDescriptorType: CS_INTERFACE */ \
+  0x01,   /* bDescriptorSubtype: Call Management Func Desc */ \
+  0x00,   /* bmCapabilities: D0+D1 */ \
+  CDC_COM_INTERFACE   /* bDataInterface: 1 */ \
+
+/* ACM Functional Descriptor */
+#define ACM_FUNCTIONAL_DESCRIPTOR() \
+  0x04,   /* bFunctionLength */ \
+  0x24,   /* bDescriptorType: CS_INTERFACE */ \
+  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */ \
+  0x02    /* bmCapabilities */
+
+#define ACM_UNION_FUNCTIONAL_DESCRIPTOR() \
+  0x05,   /* bFunctionLength */ \
+  0x24,   /* bDescriptorType: CS_INTERFACE */ \
+  0x06,   /* bDescriptorSubtype: Union func desc */ \
+  CDC_ACM_INTERFACE,   /* bMasterInterface: Communication class interface */ \
+  CDC_COM_INTERFACE   /* bSlaveInterface0: Data Class Interface */
+
+#define ACM_EP_DESCRIPTOR(_BINTERVAL) ENDPOINT_DESCRIPTOR(CDC_CMD_EP, EP_ATTR_INTERRUPT, CDC_CMD_PACKET_SIZE, _BINTERVAL)
+
+#define CDC_INTERFACE_DESCRIPTOR() INTERFACE_DESCRIPTOR(CDC_COM_INTERFACE, 0x02, IF_CLASS_CDC, IF_SUBCLASS_NONE, 0x00)
+#define CDC_EP_OUT_DESCRIPTOR(_PACKET_SIZE) ENDPOINT_DESCRIPTOR(CDC_OUT_EP, EP_ATTR_BULK, _PACKET_SIZE, 0x00)
+#define CDC_EP_IN_DESCRIPTOR(_PACKET_SIZE) ENDPOINT_DESCRIPTOR(CDC_IN_EP, EP_ATTR_BULK, _PACKET_SIZE, 0x00)
+
+#define MSC_INTERFACE_DESCRIPTOR() INTERFACE_DESCRIPTOR(MSC_INTERFACE, 0x02, IF_CLASS_MSC, IF_SUBCLASS_SCSI_TRANSPARENT, 0x50)
+#define MSC_EP_IN_DESCRIPTOR(_PACKET_SIZE) ENDPOINT_DESCRIPTOR(MSC_EPIN_ADDR, EP_ATTR_BULK, _PACKET_SIZE, 0x00)
+#define MSC_EP_OUT_DESCRIPTOR(_PACKET_SIZE) ENDPOINT_DESCRIPTOR(MSC_EPOUT_ADDR, EP_ATTR_BULK, _PACKET_SIZE, 0x00)
+
+
 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
   #pragma data_alignment=4
 #endif
-/* USB COMPOSITE device Configuration Descriptor */
-static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
-  0x09, /* bLength: Configuation Descriptor size */
-  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
-  USB_CDC_MSC_CONFIG_DESC_SIZ,
-  /* wTotalLength: Bytes returned */
-  0x00,
-  0x03,         /*bNumInterfaces: 3 interface*/
-  0x01,         /*bConfigurationValue: Configuration value*/
-  0x02,         /*iConfiguration: Index of string descriptor describing the configuration*/
-  0xC0,         /*bmAttributes: bus powered and Supports Remote Wakeup */
-  0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/
-  /* 09 */
-
-  /*---------------------------------------------------------------------------*/
-
-  /*Interface Descriptor */
-  0x09,   /* bLength: Interface Descriptor size */
-  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
-  /* Interface descriptor type */
-  CDC_ACM_INTERFACE,   /* 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 */
-  0x05,   /* 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_INTERFACE,   /* 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_ACM_INTERFACE,   /* bMasterInterface: Communication class interface */
-  CDC_COM_INTERFACE,   /* 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_INTERFACE,   /* bInterfaceNumber: Number of Interface */
-  0x00,   /* bAlternateSetting: Alternate setting */
-  0x02,   /* bNumEndpoints: Two endpoints used */
-  0x0A,   /* bInterfaceClass: CDC */
-  0x00,   /* bInterfaceSubClass: */
-  0x00,   /* bInterfaceProtocol: */
-  0x05,   /* 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,
 
 
-  /********************  Mass Storage interface ********************/
-  0x09,                                            /* bLength: Interface Descriptor size */
-  0x04,                                            /* bDescriptorType: */
-  MSC_INTERFACE,                                            /* bInterfaceNumber: Number of Interface */
-  0x00,                                            /* bAlternateSetting: Alternate setting */
-  0x02,                                            /* bNumEndpoints */
-  0x08,                                            /* bInterfaceClass: MSC Class */
-  0x06,                                            /* bInterfaceSubClass : SCSI transparent */
-  0x50,                                            /* nInterfaceProtocol */
-  0x05,                                            /* iInterface: */
-
-  /********************  Mass Storage Endpoints ********************/
-  0x07,                                            /* Endpoint descriptor length = 7 */
-  0x05,                                            /* Endpoint descriptor type */
-  MSC_EPIN_ADDR,                                   /* Endpoint address (IN, address 1) */
-  0x02,                                            /* Bulk endpoint type */
-  LOBYTE(MSC_MAX_HS_PACKET),
-  HIBYTE(MSC_MAX_HS_PACKET),
-  0x00,                                            /* Polling interval in milliseconds */
-
-  0x07,                                            /* Endpoint descriptor length = 7 */
-  0x05,                                            /* Endpoint descriptor type */
-  MSC_EPOUT_ADDR,                                  /* Endpoint address (OUT, address 1) */
-  0x02,                                            /* Bulk endpoint type */
-  LOBYTE(MSC_MAX_HS_PACKET),
-  HIBYTE(MSC_MAX_HS_PACKET),
-  0x00                                             /* Polling interval in milliseconds */
+/* USB COMPOSITE device Configuration Descriptor */
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+  #pragma data_alignment=4
+#endif
+static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
+  CONFIGURATION_DESCRIPTOR(),
+  IAD_DESCRIPTOR(),
+
+  ACM_INTERFACE_DESCRIPTOR(),
+  ACM_HEADER_FUNCTIONAL_DESCRIPTOR(),
+  ACM_CALL_MANAGEMENT_FUNCTIONAL_DESCRIPTOR(),
+  ACM_FUNCTIONAL_DESCRIPTOR(),
+  ACM_UNION_FUNCTIONAL_DESCRIPTOR(),
+  ACM_EP_DESCRIPTOR(CDC_HS_BINTERVAL),
+
+  CDC_INTERFACE_DESCRIPTOR(),
+  CDC_EP_OUT_DESCRIPTOR(CDC_DATA_HS_MAX_PACKET_SIZE),
+  CDC_EP_IN_DESCRIPTOR(CDC_DATA_HS_MAX_PACKET_SIZE),
+
+  MSC_INTERFACE_DESCRIPTOR(),
+  MSC_EP_IN_DESCRIPTOR(MSC_MAX_HS_PACKET),
+  MSC_EP_OUT_DESCRIPTOR(MSC_MAX_HS_PACKET)
 };
 
 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
@@ -216,253 +226,48 @@ static uint8_t USBD_COMPOSITE_HSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
 #endif
 /* USB COMPOSITE device Configuration Descriptor */
 static uint8_t USBD_COMPOSITE_FSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
-  0x09, /* bLength: Configuation Descriptor size */
-  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
-  USB_CDC_MSC_CONFIG_DESC_SIZ,
-  /* wTotalLength: Bytes returned */
-  0x00,
-  0x03,         /*bNumInterfaces: 3 interface*/
-  0x01,         /*bConfigurationValue: Configuration value*/
-  0x02,         /*iConfiguration: Index of string descriptor describing the configuration*/
-  0xC0,         /*bmAttributes: bus powered and Supports Remote Wakeup */
-  0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/
-  /* 09 */
-
-  /*---------------------------------------------------------------------------*/
-
-  /*Interface Descriptor */
-  0x09,   /* bLength: Interface Descriptor size */
-  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
-  /* Interface descriptor type */
-  CDC_ACM_INTERFACE,   /* 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 */
-  0x05,   /* 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 */
-  0x01,   /* 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_ACM_INTERFACE,   /* bMasterInterface: Communication class interface */
-  CDC_COM_INTERFACE,   /* 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_INTERFACE,   /* bInterfaceNumber: Number of Interface */
-  0x00,   /* bAlternateSetting: Alternate setting */
-  0x02,   /* bNumEndpoints: Two endpoints used */
-  0x0A,   /* bInterfaceClass: CDC */
-  0x00,   /* bInterfaceSubClass: */
-  0x00,   /* bInterfaceProtocol: */
-  0x05,   /* 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,
-
-
-  /********************  Mass Storage interface ********************/
-  0x09,                                            /* bLength: Interface Descriptor size */
-  0x04,                                            /* bDescriptorType: */
-  MSC_INTERFACE,                                   /* bInterfaceNumber: Number of Interface */
-  0x00,                                            /* bAlternateSetting: Alternate setting */
-  0x02,                                            /* bNumEndpoints */
-  0x08,                                            /* bInterfaceClass: MSC Class */
-  0x06,                                            /* bInterfaceSubClass : SCSI transparent */
-  0x50,                                            /* nInterfaceProtocol */
-  0x05,                                            /* iInterface: */
-
-  /********************  Mass Storage Endpoints ********************/
-  0x07,                                            /* Endpoint descriptor length = 7 */
-  0x05,                                            /* Endpoint descriptor type */
-  MSC_EPIN_ADDR,                                   /* Endpoint address (IN, address 1) */
-  0x02,                                            /* Bulk endpoint type */
-  LOBYTE(MSC_MAX_FS_PACKET),
-  HIBYTE(MSC_MAX_FS_PACKET),
-  0x00,                                            /* Polling interval in milliseconds */
-
-  0x07,                                            /* Endpoint descriptor length = 7 */
-  0x05,                                            /* Endpoint descriptor type */
-  MSC_EPOUT_ADDR,                                  /* Endpoint address (OUT, address 1) */
-  0x02,                                            /* Bulk endpoint type */
-  LOBYTE(MSC_MAX_FS_PACKET),
-  HIBYTE(MSC_MAX_FS_PACKET),
-  0x00                                             /* Polling interval in milliseconds */
+  CONFIGURATION_DESCRIPTOR(),
+  IAD_DESCRIPTOR(),
+
+  ACM_INTERFACE_DESCRIPTOR(),
+  ACM_HEADER_FUNCTIONAL_DESCRIPTOR(),
+  ACM_CALL_MANAGEMENT_FUNCTIONAL_DESCRIPTOR(),
+  ACM_FUNCTIONAL_DESCRIPTOR(),
+  ACM_UNION_FUNCTIONAL_DESCRIPTOR(),
+  ACM_EP_DESCRIPTOR(CDC_FS_BINTERVAL),
+
+  CDC_INTERFACE_DESCRIPTOR(),
+  CDC_EP_OUT_DESCRIPTOR(CDC_DATA_FS_MAX_PACKET_SIZE),
+  CDC_EP_IN_DESCRIPTOR(CDC_DATA_FS_MAX_PACKET_SIZE),
+
+  MSC_INTERFACE_DESCRIPTOR(),
+  MSC_EP_IN_DESCRIPTOR(MSC_MAX_FS_PACKET),
+  MSC_EP_OUT_DESCRIPTOR(MSC_MAX_FS_PACKET)
 };
 
+
 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
-  #pragma data_alignment=4
+#pragma data_alignment=4
 #endif
 /* USB COMPOSITE device Configuration Descriptor */
 static uint8_t USBD_COMPOSITE_OtherSpeedCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
-  0x09, /* bLength: Configuation Descriptor size */
-  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
-  USB_CDC_MSC_CONFIG_DESC_SIZ,
-  /* wTotalLength: Bytes returned */
-  0x00,
-  0x03,         /*bNumInterfaces: 3 interface*/
-  0x01,         /*bConfigurationValue: Configuration value*/
-  0x02,         /*iConfiguration: Index of string descriptor describing the configuration*/
-  0xC0,         /*bmAttributes: bus powered and Supports Remote Wakeup */
-  0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/
-  /* 09 */
-
-  /*---------------------------------------------------------------------------*/
-
-  /*Interface Descriptor */
-  0x09,   /* bLength: Interface Descriptor size */
-  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
-  /* Interface descriptor type */
-  CDC_ACM_INTERFACE,   /* 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 */
-  0x05,   /* 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 */
-  0x01,   /* 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_ACM_INTERFACE,   /* bMasterInterface: Communication class interface */
-  CDC_COM_INTERFACE,   /* 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_INTERFACE,        /* bInterfaceNumber: Number of Interface */
-  0x00,   /* bAlternateSetting: Alternate setting */
-  0x02,   /* bNumEndpoints: Two endpoints used */
-  0x0A,   /* bInterfaceClass: CDC */
-  0x00,   /* bInterfaceSubClass: */
-  0x00,   /* bInterfaceProtocol: */
-  0x05,   /* 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,
-
-
-  /********************  Mass Storage interface ********************/
-  0x09,                                            /* bLength: Interface Descriptor size */
-  0x04,                                            /* bDescriptorType: */
-  MSC_INTERFACE,                                   /* bInterfaceNumber: Number of Interface */
-  0x00,                                            /* bAlternateSetting: Alternate setting */
-  0x02,                                            /* bNumEndpoints */
-  0x08,                                            /* bInterfaceClass: MSC Class */
-  0x06,                                            /* bInterfaceSubClass : SCSI transparent */
-  0x50,                                            /* nInterfaceProtocol */
-  0x05,                                            /* iInterface: */
-
-  /********************  Mass Storage Endpoints ********************/
-  0x07,                                            /* Endpoint descriptor length = 7 */
-  0x05,                                            /* Endpoint descriptor type */
-  MSC_EPIN_ADDR,                                   /* Endpoint address (IN, address 1) */
-  0x02,                                            /* Bulk endpoint type */
-  LOBYTE(MSC_MAX_FS_PACKET),
-  HIBYTE(MSC_MAX_FS_PACKET),
-  0x00,                                            /* Polling interval in milliseconds */
-
-  0x07,                                            /* Endpoint descriptor length = 7 */
-  0x05,                                            /* Endpoint descriptor type */
-  MSC_EPOUT_ADDR,                                  /* Endpoint address (OUT, address 1) */
-  0x02,                                            /* Bulk endpoint type */
-  LOBYTE(MSC_MAX_FS_PACKET),
-  HIBYTE(MSC_MAX_FS_PACKET),
-  0x00                                             /* Polling interval in milliseconds */
+  CONFIGURATION_DESCRIPTOR(),
+  IAD_DESCRIPTOR(),
+
+  ACM_INTERFACE_DESCRIPTOR(),
+  ACM_HEADER_FUNCTIONAL_DESCRIPTOR(),
+  ACM_CALL_MANAGEMENT_FUNCTIONAL_DESCRIPTOR(),
+  ACM_FUNCTIONAL_DESCRIPTOR(),
+  ACM_UNION_FUNCTIONAL_DESCRIPTOR(),
+  ACM_EP_DESCRIPTOR(CDC_FS_BINTERVAL),
+
+  CDC_INTERFACE_DESCRIPTOR(),
+  CDC_EP_OUT_DESCRIPTOR(CDC_DATA_FS_MAX_PACKET_SIZE),
+  CDC_EP_IN_DESCRIPTOR(CDC_DATA_FS_MAX_PACKET_SIZE),
+
+  MSC_INTERFACE_DESCRIPTOR(),
+  MSC_EP_IN_DESCRIPTOR(MSC_MAX_FS_PACKET),
+  MSC_EP_OUT_DESCRIPTOR(MSC_MAX_FS_PACKET)
 };
 
 
diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
index ffe43f6fa2..e8110535d8 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.h
@@ -30,7 +30,7 @@
 #define CDC_COM_INTERFACE   0x1
 #define MSC_INTERFACE       0x2
 
-#define USB_CDC_MSC_CONFIG_DESC_SIZ  (USB_CDC_CONFIG_DESC_SIZ - 9 + USB_MSC_CONFIG_DESC_SIZ)
+#define USB_CDC_MSC_CONFIG_DESC_SIZ  (USB_CDC_CONFIG_DESC_SIZ - 9 + 8 + USB_MSC_CONFIG_DESC_SIZ)
 
 extern USBD_ClassTypeDef  USBD_CDC_MSC;
 
diff --git a/cores/arduino/stm32/usb/usbd_desc.c b/cores/arduino/stm32/usb/usbd_desc.c
index b9ba7cabae..883557a98a 100644
--- a/cores/arduino/stm32/usb/usbd_desc.c
+++ b/cores/arduino/stm32/usb/usbd_desc.c
@@ -129,81 +129,51 @@ USBD_DescriptorsTypeDef USBD_Desc = {
 #endif
 };
 
-#ifdef USBD_USE_HID_COMPOSITE
-/* USB Standard Device Descriptor */
-__ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
-  0x12,                       /* bLength */
-  USB_DESC_TYPE_DEVICE,       /* bDescriptorType */
+
+#define USB_CDC_CLASS_MULTI 0xEF
+#define CDC_SUBCLASS_ACM    0x02
+#define CDC_PROTOCOL_V25TER 0x01 // Common AT commands
+
+
 #if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
-  0x01,                       /*bcdUSB */     /* changed to USB version 2.01
-                                              in order to support BOS Desc */
+  #define BCD_USB_FLAG 0x01
 #else
-  0x00,                       /* bcdUSB */
+  #define BCD_USB_FLAG 0x00
 #endif
-  0x02,
-  0x00,                       /* bDeviceClass */
-  0x00,                       /* bDeviceSubClass */
-  0x00,                       /* bDeviceProtocol */
-  USB_MAX_EP0_SIZE,           /* bMaxPacketSize */
-  LOBYTE(USBD_VID),           /* idVendor */
-  HIBYTE(USBD_VID),           /* idVendor */
-  LOBYTE(USBD_PID),           /* idProduct */
-  HIBYTE(USBD_PID),           /* idProduct */
-  0x00,                       /* bcdDevice rel. 0.00 */
-  0x00,
-  USBD_IDX_MFC_STR,           /* Index of manufacturer string */
-  USBD_IDX_PRODUCT_STR,       /* Index of product string */
-  USBD_IDX_SERIAL_STR,        /* Index of serial number string */
-  USBD_MAX_NUM_CONFIGURATION  /* bNumConfigurations */
-}; /* USB_DeviceDescriptor */
-#endif /* USBD_USE_HID_COMPOSITE */
 
-#if defined(USBD_USE_CDC) || defined(USBD_USE_CDC_MSC)
-/* USB Standard Device Descriptor */
-__ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
-  0x12,                       /* bLength */
-  USB_DESC_TYPE_DEVICE,       /* bDescriptorType */
-#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
-  0x01,                       /*bcdUSB */     /* changed to USB version 2.01
-                                              in order to support BOS Desc */
-#else
-  0x00,                       /* bcdUSB */
+
+#define USBD_CLASS_DEVICE_DESCRIPTOR(_CLASS, _SUBCLASS, _PROTO)                \
+__ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { \
+  0x12,                      /* bLength */ \
+  USB_DESC_TYPE_DEVICE,      /* bDescriptorType */ \
+  BCD_USB_FLAG,              /* bcdUSB */ \
+  0x02, \
+  _CLASS,                    /* bDeviceClass */ \
+  _SUBCLASS,                 /* bDeviceSubClass */ \
+  _PROTO,                    /* bDeviceProtocol */ \
+  USB_MAX_EP0_SIZE,          /* bMaxPacketSize */ \
+  LOBYTE(USBD_VID),          /* idVendor */ \
+  HIBYTE(USBD_VID),          /* idVendor */ \
+  LOBYTE(USBD_PID),          /* idProduct */ \
+  HIBYTE(USBD_PID),          /* idProduct */ \
+  0x00,                      /* bcdDevice rel. 0.00 */ \
+  0x00, \
+  USBD_IDX_MFC_STR,          /* Index of manufacturer string */ \
+  USBD_IDX_PRODUCT_STR,      /* Index of product string */ \
+  USBD_IDX_SERIAL_STR,       /* Index of serial number string */ \
+  USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */ \
+}
+
+#ifdef USBD_USE_HID_COMPOSITE
+USBD_CLASS_DEVICE_DESCRIPTOR(0x00, 0x00, 0x00);
 #endif
-  0x02,
-  0x02,                       /* bDeviceClass */
-  0x02,                       /* bDeviceSubClass */
-  0x00,                       /* bDeviceProtocol */
-  USB_MAX_EP0_SIZE,           /* bMaxPacketSize */
-  LOBYTE(USBD_VID),           /* idVendor */
-  HIBYTE(USBD_VID),           /* idVendor */
-  LOBYTE(USBD_PID),           /* idProduct */
-  HIBYTE(USBD_PID),           /* idProduct */
-  0x00,                       /* bcdDevice rel. 0.00 */
-  0x00,
-  USBD_IDX_MFC_STR,           /* Index of manufacturer string */
-  USBD_IDX_PRODUCT_STR,       /* Index of product string */
-  USBD_IDX_SERIAL_STR,        /* Index of serial number string */
-  USBD_MAX_NUM_CONFIGURATION  /* bNumConfigurations */
-}; /* USB_DeviceDescriptor */
-#endif /* USBD_USE_CDC || USBD_USE_CDC_MSC */
-
-/* USB Device LPM BOS descriptor */
-#if (USBD_LPM_ENABLED == 1)
-__ALIGN_BEGIN  uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = {
-  0x5,
-  USB_DESC_TYPE_BOS,
-  0xC,
-  0x0,
-  0x1,  /* 1 device capability */
-  /* device capability */
-  0x7,
-  USB_DEVICE_CAPABITY_TYPE,
-  0x2,
-  0x6, /*LPM capability bit set */
-  0x0,
-  0x0,
-  0x0
-};
+
+#ifdef USBD_USE_CDC
+USBD_CLASS_DEVICE_DESCRIPTOR(0x02, 0x02, 0x00);
+#endif
+
+#ifdef USBD_USE_CDC_MSC
+USBD_CLASS_DEVICE_DESCRIPTOR(USB_CDC_CLASS_MULTI, CDC_SUBCLASS_ACM, CDC_PROTOCOL_V25TER);
 #endif
 
 /* USB Device Billboard BOS descriptor Template */

From def086798e3822f8604a7211244f21e3dad34d2f Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Sun, 7 Jun 2020 11:23:47 +0000
Subject: [PATCH 36/37] fixed formatting

---
 cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp | 2 +-
 cores/arduino/stm32/usb/usbd_desc.c              | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
index 419be31e05..d846a4a965 100644
--- a/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
+++ b/cores/arduino/stm32/usb/cdc_msc/usbd_cdc_msc.cpp
@@ -247,7 +247,7 @@ static uint8_t USBD_COMPOSITE_FSCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
 
 
 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
-#pragma data_alignment=4
+  #pragma data_alignment=4
 #endif
 /* USB COMPOSITE device Configuration Descriptor */
 static uint8_t USBD_COMPOSITE_OtherSpeedCfgDesc[USB_CDC_MSC_CONFIG_DESC_SIZ] = {
diff --git a/cores/arduino/stm32/usb/usbd_desc.c b/cores/arduino/stm32/usb/usbd_desc.c
index 883557a98a..3d48f046ed 100644
--- a/cores/arduino/stm32/usb/usbd_desc.c
+++ b/cores/arduino/stm32/usb/usbd_desc.c
@@ -165,15 +165,15 @@ __ALIGN_BEGIN uint8_t USBD_Class_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { \
 }
 
 #ifdef USBD_USE_HID_COMPOSITE
-USBD_CLASS_DEVICE_DESCRIPTOR(0x00, 0x00, 0x00);
+  USBD_CLASS_DEVICE_DESCRIPTOR(0x00, 0x00, 0x00);
 #endif
 
 #ifdef USBD_USE_CDC
-USBD_CLASS_DEVICE_DESCRIPTOR(0x02, 0x02, 0x00);
+  USBD_CLASS_DEVICE_DESCRIPTOR(0x02, 0x02, 0x00);
 #endif
 
 #ifdef USBD_USE_CDC_MSC
-USBD_CLASS_DEVICE_DESCRIPTOR(USB_CDC_CLASS_MULTI, CDC_SUBCLASS_ACM, CDC_PROTOCOL_V25TER);
+  USBD_CLASS_DEVICE_DESCRIPTOR(USB_CDC_CLASS_MULTI, CDC_SUBCLASS_ACM, CDC_PROTOCOL_V25TER);
 #endif
 
 /* USB Device Billboard BOS descriptor Template */

From 444780324d7c51bef6af548fc684c244897c29cd Mon Sep 17 00:00:00 2001
From: Rudi Horn <dyn-git@rudi-horn.de>
Date: Sun, 7 Jun 2020 11:57:03 +0000
Subject: [PATCH 37/37] added extra board configurations

---
 boards.txt | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/boards.txt b/boards.txt
index 65074d3a9f..a91fa61206 100644
--- a/boards.txt
+++ b/boards.txt
@@ -2325,6 +2325,8 @@ Nucleo_144.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 Nucleo_144.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 Nucleo_144.menu.usb.CDC=CDC (no generic 'Serial')
 Nucleo_144.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Nucleo_144.menu.usb.CDC_MSC=CDC + MSC
+Nucleo_144.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 Nucleo_144.menu.usb.HID=HID (keyboard and mouse)
 Nucleo_144.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 Nucleo_144.menu.xusb.FS=Low/Full Speed
@@ -2338,6 +2340,8 @@ Nucleo_64.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 Nucleo_64.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 Nucleo_64.menu.usb.CDC=CDC (no generic 'Serial')
 Nucleo_64.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Nucleo_64.menu.usb.CDC_MSC=CDC + MSC
+Nucleo_64.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 Nucleo_64.menu.usb.HID=HID (keyboard and mouse)
 Nucleo_64.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 Nucleo_64.menu.xusb.FS=Low/Full Speed
@@ -2351,6 +2355,8 @@ Nucleo_32.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 Nucleo_32.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 Nucleo_32.menu.usb.CDC=CDC (no generic 'Serial')
 Nucleo_32.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Nucleo_32.menu.usb.CDC_MSC=CDC + MSC
+Nucleo_32.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 Nucleo_32.menu.usb.HID=HID (keyboard and mouse)
 Nucleo_32.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 Nucleo_32.menu.xusb.FS=Low/Full Speed
@@ -2364,6 +2370,8 @@ Disco.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 Disco.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 Disco.menu.usb.CDC=CDC (no generic 'Serial')
 Disco.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Disco.menu.usb.CDC_MSC=CDC + MSC
+Disco.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 Disco.menu.usb.HID=HID (keyboard and mouse)
 Disco.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 Disco.menu.xusb.FS=Low/Full Speed
@@ -2377,6 +2385,8 @@ Eval.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 Eval.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 Eval.menu.usb.CDC=CDC (no generic 'Serial')
 Eval.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Eval.menu.usb.CDC_MSC=CDC + MSC
+Eval.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 Eval.menu.usb.HID=HID (keyboard and mouse)
 Eval.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 Eval.menu.xusb.FS=Low/Full Speed
@@ -2390,6 +2400,8 @@ GenF1.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 GenF1.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 GenF1.menu.usb.CDC=CDC (no generic 'Serial')
 GenF1.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+GenF1.menu.usb.CDC_MSC=CDC + MSC
+GenF1.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 GenF1.menu.usb.HID=HID (keyboard and mouse)
 GenF1.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 GenF1.menu.xusb.FS=Low/Full Speed
@@ -2403,6 +2415,8 @@ GenF3.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 GenF3.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 GenF3.menu.usb.CDC=CDC (no generic 'Serial')
 GenF3.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+GenF3.menu.usb.CDC_MSC=CDC + MSC
+GenF3.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 GenF3.menu.usb.HID=HID (keyboard and mouse)
 GenF3.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 GenF3.menu.xusb.FS=Low/Full Speed
@@ -2416,6 +2430,8 @@ GenF4.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 GenF4.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 GenF4.menu.usb.CDC=CDC (no generic 'Serial')
 GenF4.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+GenF4.menu.usb.CDC_MSC=CDC + MSC
+GenF4.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 GenF4.menu.usb.HID=HID (keyboard and mouse)
 GenF4.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 GenF4.menu.xusb.FS=Low/Full Speed
@@ -2429,6 +2445,8 @@ GenH7.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 GenH7.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 GenH7.menu.usb.CDC=CDC (no generic 'Serial')
 GenH7.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+GenH7.menu.usb.CDC_MSC=CDC + MSC
+GenH7.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 GenH7.menu.usb.HID=HID (keyboard and mouse)
 GenH7.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 GenH7.menu.xusb.FS=Low/Full Speed
@@ -2440,6 +2458,8 @@ GenL0.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 GenL0.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 GenL0.menu.usb.CDC=CDC (no generic 'Serial')
 GenL0.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+GenL0.menu.usb.CDC_MSC=CDC + MSC
+GenL0.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 GenL0.menu.usb.HID=HID (keyboard and mouse)
 GenL0.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 
@@ -2448,6 +2468,8 @@ GenL0.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 3dprinter.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 3dprinter.menu.usb.CDC=CDC (no generic 'Serial')
 3dprinter.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+3dprinter.menu.usb.CDC_MSC=CDC + MSC
+3dprinter.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 3dprinter.menu.xusb.FS=Low/Full Speed
 3dprinter.menu.xusb.HS=High Speed
 3dprinter.menu.xusb.HS.build.usb_speed=-DUSE_USB_HS
@@ -2459,6 +2481,8 @@ Genericflight.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 Genericflight.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 Genericflight.menu.usb.CDC=CDC (no generic 'Serial')
 Genericflight.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Genericflight.menu.usb.CDC_MSC=CDC + MSC
+Genericflight.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 Genericflight.menu.usb.HID=HID (keyboard and mouse)
 Genericflight.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 Genericflight.menu.xusb.FS=Low/Full Speed
@@ -2472,6 +2496,8 @@ Garatronic.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 Garatronic.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 Garatronic.menu.usb.CDC=CDC (no generic 'Serial')
 Garatronic.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Garatronic.menu.usb.CDC_MSC=CDC + MSC
+Garatronic.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 Garatronic.menu.usb.HID=HID (keyboard and mouse)
 Garatronic.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 
@@ -2480,6 +2506,8 @@ Midatronics.menu.usb.CDCgen=CDC (generic 'Serial' supersede U(S)ART)
 Midatronics.menu.usb.CDCgen.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC
 Midatronics.menu.usb.CDC=CDC (no generic 'Serial')
 Midatronics.menu.usb.CDC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC -DDISABLE_GENERIC_SERIALUSB
+Midatronics.menu.usb.CDC_MSC=CDC + MSC
+Midatronics.menu.usb.CDC_MSC.build.enable_usb={build.usb_flags} -DUSBD_USE_CDC_MSC
 Midatronics.menu.usb.HID=HID (keyboard and mouse)
 Midatronics.menu.usb.HID.build.enable_usb={build.usb_flags} -DUSBD_USE_HID_COMPOSITE
 Midatronics.menu.xusb.FS=Low/Full Speed