diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py
index 8100842b4c13eb4494b6f65fcbcf9814b30df8e4..d30cf3ec4e9594602992fbcb570e602ab78deed5 100644
--- a/py/makeqstrdata.py
+++ b/py/makeqstrdata.py
@@ -35,6 +35,7 @@ codepoint2name[ord('}')] = 'brace_close'
 codepoint2name[ord('*')] = 'star'
 codepoint2name[ord('!')] = 'bang'
 codepoint2name[ord('\\')] = 'backslash'
+codepoint2name[ord('+')] = 'plus'
 
 # this must match the equivalent function in qstr.c
 def compute_hash(qstr, bytes_hash):
diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h
index fe6077ec47ae1b5e5332ff0be66aa18aca2d0305..ee7c6fe0669729daa1f4f6111e70d28831b08460 100644
--- a/stmhal/qstrdefsport.h
+++ b/stmhal/qstrdefsport.h
@@ -97,6 +97,19 @@ Q(hid)
 Q(hid_mouse)
 Q(hid_keyboard)
 
+// for usb modes
+Q(host)
+Q(VCP)
+Q(MSC)
+Q(HID)
+Q(MSC+HID)
+Q(VCP+MSC)
+Q(VCP+HID)
+// CDC is a synonym for VCP for backwards compatibility
+Q(CDC)
+Q(CDC+MSC)
+Q(CDC+HID)
+
 // for USB VCP class
 Q(USB_VCP)
 Q(setinterrupt)
diff --git a/stmhal/usb.c b/stmhal/usb.c
index 1209ec5f12e99de7d0d027bb41571b15cf6fe5ac..085eae12994344839a1e3a76d6d6abc4de79edcb 100644
--- a/stmhal/usb.c
+++ b/stmhal/usb.c
@@ -179,6 +179,7 @@ void usb_vcp_send_strn_cooked(const char *str, int len) {
 
   We have:
 
+    pyb.usb_mode()          # return the current usb mode
     pyb.usb_mode(None)      # disable USB
     pyb.usb_mode('VCP')     # enable with VCP interface
     pyb.usb_mode('VCP+MSC') # enable with VCP and MSC interfaces
@@ -205,6 +206,31 @@ STATIC mp_obj_t pyb_usb_mode(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
         { MP_QSTR_hid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = (mp_obj_t)&pyb_usb_hid_mouse_obj} },
     };
 
+    // fetch the current usb mode -> pyb.usb_mode()
+    if (n_args == 0) {
+    #if defined(USE_HOST_MODE)
+        return MP_OBJ_NEW_QSTR(MP_QSTR_host);
+    #elif defined(USE_DEVICE_MODE)
+        uint8_t mode = USBD_GetMode();
+        switch (mode) {
+            case USBD_MODE_CDC:
+                return MP_OBJ_NEW_QSTR(MP_QSTR_VCP);
+            case USBD_MODE_MSC:
+                return MP_OBJ_NEW_QSTR(MP_QSTR_MSC);
+            case USBD_MODE_HID:
+                return MP_OBJ_NEW_QSTR(MP_QSTR_HID);
+            case USBD_MODE_CDC_MSC:
+                return MP_OBJ_NEW_QSTR(MP_QSTR_VCP_plus_MSC);
+            case USBD_MODE_CDC_HID:
+                return MP_OBJ_NEW_QSTR(MP_QSTR_VCP_plus_HID);
+            case USBD_MODE_MSC_HID:
+                return MP_OBJ_NEW_QSTR(MP_QSTR_MSC_plus_HID);
+            default:
+                return mp_const_none;
+        }
+    #endif
+    }
+
     // parse args
     mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
     mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -296,7 +322,7 @@ STATIC mp_obj_t pyb_usb_mode(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
 bad_mode:
     nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "bad USB mode"));
 }
-MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_mode_obj, 1, pyb_usb_mode);
+MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_mode_obj, 0, pyb_usb_mode);
 
 /******************************************************************************/
 // Micro Python bindings for USB VCP
diff --git a/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h b/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h
index 52d845b24af529e32a12f50de442583fe627d7eb..248ce17f3ebae9f3fa86b0b8c9ee41b891516136 100644
--- a/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h
+++ b/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h
@@ -94,6 +94,8 @@ extern USBD_ClassTypeDef USBD_CDC_MSC_HID;
 
 // returns 0 on success, -1 on failure
 int USBD_SelectMode(uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info);
+// returns the current usb mode
+uint8_t USBD_GetMode();
 
 uint8_t USBD_CDC_RegisterInterface  (USBD_HandleTypeDef   *pdev, USBD_CDC_ItfTypeDef *fops);
 uint8_t USBD_CDC_SetTxBuffer  (USBD_HandleTypeDef   *pdev, uint8_t  *pbuff, uint16_t length);
diff --git a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c
index bbb666861bbde6b4ce940b11555c85f8b873f7b0..d50934ada416f808b8bc348294bb38b03ec2e8e4 100644
--- a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c
+++ b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c
@@ -559,6 +559,11 @@ __ALIGN_BEGIN const uint8_t USBD_HID_KEYBOARD_ReportDesc[USBD_HID_KEYBOARD_REPOR
     0xC0            // End Collection
 };
 
+// return the saved usb mode
+uint8_t USBD_GetMode() {
+    return usbd_mode;
+}
+
 int USBD_SelectMode(uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info) {
     // save mode
     usbd_mode = mode;