diff --git a/stmhal/usb.c b/stmhal/usb.c
index 152dc8f3cd3836fe15f398baa22e121f9c258969..c522b64432fde8abf768daea23cd6a2318515a2e 100644
--- a/stmhal/usb.c
+++ b/stmhal/usb.c
@@ -58,10 +58,14 @@ void pyb_usb_dev_init(usb_device_mode_t mode, usb_storage_medium_t medium) {
 #ifdef USE_DEVICE_MODE
     if (!dev_is_enabled) {
         // only init USB once in the device's power-lifetime
+        // Windows needs a different PID to distinguish different device
+        // configurations, so we set it here depending on mode.
         if (mode == USB_DEVICE_MODE_CDC_MSC) {
             USBD_SelectMode(USBD_MODE_CDC_MSC);
+            USBD_SetPID(0x9800);
         } else {
             USBD_SelectMode(USBD_MODE_CDC_HID);
+            USBD_SetPID(0x9801);
         }
         USBD_Init(&hUSBDDevice, (USBD_DescriptorsTypeDef*)&VCP_Desc, 0);
         USBD_RegisterClass(&hUSBDDevice, &USBD_CDC_MSC_HID);
diff --git a/stmhal/usbd_desc.h b/stmhal/usbd_desc.h
index e2759f9f4fd4f909cfc1156760cc14eeb7c93dda..49e19382af6188320917a2d43d42b52d9e43794f 100644
--- a/stmhal/usbd_desc.h
+++ b/stmhal/usbd_desc.h
@@ -25,3 +25,5 @@
  */
 
 extern const USBD_DescriptorsTypeDef VCP_Desc;
+
+void USBD_SetPID(uint16_t pid);
diff --git a/stmhal/usbd_desc_cdc_msc.c b/stmhal/usbd_desc_cdc_msc.c
index 20844c746847773955ce8ec653a4a10d1eef3885..3556d2bf8ff04d61b4d58f57e3775148fa458dd2 100644
--- a/stmhal/usbd_desc_cdc_msc.c
+++ b/stmhal/usbd_desc_cdc_msc.c
@@ -20,8 +20,8 @@
   *
   *        http://www.st.com/software_license_agreement_liberty_v2
   *
-  * Unless required by applicable law or agreed to in writing, software 
-  * distributed under the License is distributed on an "AS IS" BASIS, 
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
@@ -29,14 +29,10 @@
   ******************************************************************************
   */
 
-/* Includes ------------------------------------------------------------------*/
 #include "usbd_core.h"
 #include "usbd_desc.h"
 #include "usbd_conf.h"
 
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-
 // So we don't clash with existing ST boards, we use the unofficial FOSS VID.
 // This needs a proper solution.
 #define USBD_VID                      0xf055
@@ -52,199 +48,144 @@
 #define USBD_CONFIGURATION_FS_STRING  "VCP Config"
 #define USBD_INTERFACE_FS_STRING      "VCP Interface"
 
-/*
-#define USBD_VID                      0x0483
-#define USBD_PID                      0x5740
-#define USBD_LANGID_STRING            0x409
-#define USBD_MANUFACTURER_STRING      "STMicroelectronics"
-#define USBD_PRODUCT_HS_STRING        "STM32 Virtual ComPort in HS Mode"
-#define USBD_SERIALNUMBER_HS_STRING   "00000000001A"
-#define USBD_PRODUCT_FS_STRING        "STM32 Virtual ComPort in FS Mode"
-#define USBD_SERIALNUMBER_FS_STRING   "00000000001B"
-#define USBD_CONFIGURATION_HS_STRING  "VCP Config"
-#define USBD_INTERFACE_HS_STRING      "VCP Interface"
-#define USBD_CONFIGURATION_FS_STRING  "VCP Config"
-#define USBD_INTERFACE_FS_STRING      "VCP Interface"
-*/
-
-/* Private macro -------------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-uint8_t *USBD_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_VCP_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_VCP_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t *USBD_VCP_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-#ifdef USB_SUPPORT_USER_STRING_DESC
-uint8_t *USBD_VCP_USRStringDesc (USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);  
-#endif /* USB_SUPPORT_USER_STRING_DESC */  
-
-/* Private variables ---------------------------------------------------------*/
-const USBD_DescriptorsTypeDef VCP_Desc = {
-  USBD_VCP_DeviceDescriptor,
-  USBD_VCP_LangIDStrDescriptor, 
-  USBD_VCP_ManufacturerStrDescriptor,
-  USBD_VCP_ProductStrDescriptor,
-  USBD_VCP_SerialStrDescriptor,
-  USBD_VCP_ConfigStrDescriptor,
-  USBD_VCP_InterfaceStrDescriptor,  
+// USB Standard Device Descriptor
+__ALIGN_BEGIN static uint8_t hUSBDDeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
+    0x12,                       // bLength
+    USB_DESC_TYPE_DEVICE,       // bDescriptorType
+    0x00,                       // bcdUSB
+    0x02,
+    0x00,                       // bDeviceClass
+    0x00,                       // bDeviceSubClass
+    0x00,                       // bDeviceProtocol
+    USB_MAX_EP0_SIZE,           // bMaxPacketSize
+    LOBYTE(USBD_VID),           // idVendor
+    HIBYTE(USBD_VID),           // idVendor
+    LOBYTE(USBD_PID),           // idVendor
+    HIBYTE(USBD_PID),           // idVendor
+    0x00,                       // bcdDevice rel. 2.00
+    0x02,
+    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 Standard Device Descriptor */
-#if defined ( __ICCARM__ ) /*!< IAR Compiler */
-  #pragma data_alignment=4   
-#endif
-__ALIGN_BEGIN static uint8_t hUSBDDeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
-  0x12,                       /* bLength */
-  USB_DESC_TYPE_DEVICE,       /* bDescriptorType */
-  0x00,                       /* bcdUSB */
-  0x02,
-  0x00,                       /* bDeviceClass */
-  0x00,                       /* bDeviceSubClass */
-  0x00,                       /* bDeviceProtocol */
-  USB_MAX_EP0_SIZE,           /* bMaxPacketSize */
-  LOBYTE(USBD_VID),           /* idVendor */
-  HIBYTE(USBD_VID),           /* idVendor */
-  LOBYTE(USBD_PID),           /* idVendor */
-  HIBYTE(USBD_PID),           /* idVendor */
-  0x00,                       /* bcdDevice rel. 2.00 */
-  0x02,
-  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 */
-
-/* USB Standard Device Descriptor */
-#if defined ( __ICCARM__ ) /*!< IAR Compiler */
-  #pragma data_alignment=4   
-#endif
 __ALIGN_BEGIN static uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
-  USB_LEN_LANGID_STR_DESC,         
-  USB_DESC_TYPE_STRING,       
-  LOBYTE(USBD_LANGID_STRING),
-  HIBYTE(USBD_LANGID_STRING), 
+    USB_LEN_LANGID_STR_DESC,
+    USB_DESC_TYPE_STRING,
+    LOBYTE(USBD_LANGID_STRING),
+    HIBYTE(USBD_LANGID_STRING),
 };
 
-#if defined ( __ICCARM__ ) /*!< IAR Compiler */
-  #pragma data_alignment=4   
-#endif
 __ALIGN_BEGIN static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
 
-/* Private functions ---------------------------------------------------------*/
+// set the PID
+void USBD_SetPID(uint16_t pid) {
+    hUSBDDeviceDesc[10] = LOBYTE(pid);
+    hUSBDDeviceDesc[11] = HIBYTE(pid);
+}
 
 /**
-  * @brief  Returns the device descriptor. 
+  * @brief  Returns the device descriptor.
   * @param  speed: Current device speed
   * @param  length: Pointer to data length variable
   * @retval Pointer to descriptor buffer
   */
-uint8_t *USBD_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
-  *length = sizeof(hUSBDDeviceDesc);
-  return hUSBDDeviceDesc;
+STATIC uint8_t *USBD_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
+    *length = sizeof(hUSBDDeviceDesc);
+    return hUSBDDeviceDesc;
 }
 
 /**
-  * @brief  Returns the LangID string descriptor.        
+  * @brief  Returns the LangID string descriptor.
   * @param  speed: Current device speed
   * @param  length: Pointer to data length variable
   * @retval Pointer to descriptor buffer
   */
-uint8_t *USBD_VCP_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
-  *length = sizeof(USBD_LangIDDesc);  
-  return USBD_LangIDDesc;
+STATIC uint8_t *USBD_VCP_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
+    *length = sizeof(USBD_LangIDDesc);
+    return USBD_LangIDDesc;
 }
 
 /**
-  * @brief  Returns the product string descriptor. 
+  * @brief  Returns the product string descriptor.
   * @param  speed: Current device speed
   * @param  length: Pointer to data length variable
   * @retval Pointer to descriptor buffer
   */
-uint8_t *USBD_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
-  if(speed == 0)
-  {   
-    USBD_GetString((uint8_t *)USBD_PRODUCT_HS_STRING, USBD_StrDesc, length);
-  }
-  else
-  {
-    USBD_GetString((uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length);    
-  }
-  return USBD_StrDesc;
+STATIC uint8_t *USBD_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
+    if(speed == 0) {
+        USBD_GetString((uint8_t *)USBD_PRODUCT_HS_STRING, USBD_StrDesc, length);
+    } else {
+        USBD_GetString((uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length);
+    }
+    return USBD_StrDesc;
 }
 
 /**
-  * @brief  Returns the manufacturer string descriptor. 
+  * @brief  Returns the manufacturer string descriptor.
   * @param  speed: Current device speed
   * @param  length: Pointer to data length variable
   * @retval Pointer to descriptor buffer
   */
-uint8_t *USBD_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
-  USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
-  return USBD_StrDesc;
+STATIC uint8_t *USBD_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
+    USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
+    return USBD_StrDesc;
 }
 
 /**
-  * @brief  Returns the serial number string descriptor.        
+  * @brief  Returns the serial number string descriptor.
   * @param  speed: Current device speed
   * @param  length: Pointer to data length variable
   * @retval Pointer to descriptor buffer
   */
-uint8_t *USBD_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
-  if(speed == USBD_SPEED_HIGH)
-  {    
-    USBD_GetString((uint8_t *)USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length);
-  }
-  else
-  {
-    USBD_GetString((uint8_t *)USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length);    
-  }
-  return USBD_StrDesc;
+STATIC uint8_t *USBD_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
+    if(speed == USBD_SPEED_HIGH) {
+        USBD_GetString((uint8_t *)USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length);
+    } else {
+        USBD_GetString((uint8_t *)USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length);
+    }
+    return USBD_StrDesc;
 }
 
 /**
-  * @brief  Returns the configuration string descriptor.    
+  * @brief  Returns the configuration string descriptor.
   * @param  speed: Current device speed
   * @param  length: Pointer to data length variable
   * @retval Pointer to descriptor buffer
   */
-uint8_t *USBD_VCP_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
-  if(speed == USBD_SPEED_HIGH)
-  {  
-    USBD_GetString((uint8_t *)USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length);
-  }
-  else
-  {
-    USBD_GetString((uint8_t *)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length); 
-  }
-  return USBD_StrDesc;  
+STATIC uint8_t *USBD_VCP_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
+    if(speed == USBD_SPEED_HIGH) {
+        USBD_GetString((uint8_t *)USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length);
+    } else {
+        USBD_GetString((uint8_t *)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length);
+    }
+    return USBD_StrDesc;
 }
 
 /**
-  * @brief  Returns the interface string descriptor.        
+  * @brief  Returns the interface string descriptor.
   * @param  speed: Current device speed
   * @param  length: Pointer to data length variable
   * @retval Pointer to descriptor buffer
   */
-uint8_t *USBD_VCP_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
-{
-  if(speed == 0)
-  {
-    USBD_GetString((uint8_t *)USBD_INTERFACE_HS_STRING, USBD_StrDesc, length);
-  }
-  else
-  {
-    USBD_GetString((uint8_t *)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
-  }
-  return USBD_StrDesc;  
+STATIC uint8_t *USBD_VCP_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
+    if(speed == 0) {
+        USBD_GetString((uint8_t *)USBD_INTERFACE_HS_STRING, USBD_StrDesc, length);
+    } else {
+        USBD_GetString((uint8_t *)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
+    }
+    return USBD_StrDesc;
 }
 
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+const USBD_DescriptorsTypeDef VCP_Desc = {
+    USBD_VCP_DeviceDescriptor,
+    USBD_VCP_LangIDStrDescriptor,
+    USBD_VCP_ManufacturerStrDescriptor,
+    USBD_VCP_ProductStrDescriptor,
+    USBD_VCP_SerialStrDescriptor,
+    USBD_VCP_ConfigStrDescriptor,
+    USBD_VCP_InterfaceStrDescriptor,
+};
 
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/