diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 1a1c505dc480..e470522fbd51 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -652,7 +652,7 @@ void stm32_main(uint32_t reset_mode) { #if MICROPY_HW_ENABLE_USB // init USB device to default setting if it was not already configured if (!(pyb_usb_flags & PYB_USB_FLAG_USB_MODE_CALLED)) { - pyb_usb_dev_init(USBD_VID, USBD_PID_CDC_MSC, USBD_MODE_CDC_MSC, 0, NULL, NULL); + pyb_usb_dev_init(pyb_usb_dev_detect(), USBD_VID, USBD_PID_CDC_MSC, USBD_MODE_CDC_MSC, 0, NULL, NULL); } #endif diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 69ba26c43864..12e138818524 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -120,14 +120,39 @@ void pyb_usb_init0(void) { pyb_usb_vcp_init0(); } -bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, uint8_t mode, size_t msc_n, const void *msc_unit, USBD_HID_ModeInfoTypeDef *hid_info) { +int pyb_usb_dev_detect(void) { + if (usb_device.enabled) { + return usb_device.hUSBDDevice.id; + } + + #if MICROPY_HW_USB_FS && MICROPY_HW_USB_HS + // Try to auto-detect which USB is connected by reading DP/DM pins + for (int i = 0; i < 2; ++i) { + mp_hal_pin_obj_t dp = i == 0 ? pyb_pin_USB_DP : pyb_pin_USB_HS_DP; + mp_hal_pin_obj_t dm = i == 0 ? pyb_pin_USB_DM : pyb_pin_USB_HS_DM; + mp_hal_pin_config(dp, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0); + mp_hal_pin_config(dm, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0); + int state = mp_hal_pin_read(dp) == 0 && mp_hal_pin_read(dm) == 0; + mp_hal_pin_config(dp, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(dm, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); + if (state) { + // DP and DM pins are actively held low so assume USB is connected + return i == 0 ? USB_PHY_FS_ID : USB_PHY_HS_ID; + } + } + #endif + + return MICROPY_HW_USB_MAIN_DEV; +} + +bool pyb_usb_dev_init(int dev_id, uint16_t vid, uint16_t pid, uint8_t mode, size_t msc_n, const void *msc_unit, USBD_HID_ModeInfoTypeDef *hid_info) { usb_device_t *usb_dev = &usb_device; if (!usb_dev->enabled) { // only init USB once in the device's power-lifetime // set up the USBD state USBD_HandleTypeDef *usbd = &usb_dev->hUSBDDevice; - usbd->id = MICROPY_HW_USB_MAIN_DEV; + usbd->id = dev_id; usbd->dev_state = USBD_STATE_DEFAULT; usbd->pDesc = (USBD_DescriptorsTypeDef*)&USBD_Descriptors; usbd->pClass = &USBD_CDC_MSC_HID; @@ -403,7 +428,7 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * #endif // init the USB device - if (!pyb_usb_dev_init(vid, pid, mode, msc_n, msc_unit, &hid_info)) { + if (!pyb_usb_dev_init(pyb_usb_dev_detect(), vid, pid, mode, msc_n, msc_unit, &hid_info)) { goto bad_mode; } diff --git a/ports/stm32/usb.h b/ports/stm32/usb.h index b1c8b476a7d8..cb017902ecb5 100644 --- a/ports/stm32/usb.h +++ b/ports/stm32/usb.h @@ -66,7 +66,8 @@ MP_DECLARE_CONST_FUN_OBJ_0(pyb_have_cdc_obj); // deprecated MP_DECLARE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj); // deprecated void pyb_usb_init0(void); -bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, uint8_t mode, size_t msc_n, const void *msc_unit, USBD_HID_ModeInfoTypeDef *hid_info); +int pyb_usb_dev_detect(void); +bool pyb_usb_dev_init(int dev_id, uint16_t vid, uint16_t pid, uint8_t mode, size_t msc_n, const void *msc_unit, USBD_HID_ModeInfoTypeDef *hid_info); void pyb_usb_dev_deinit(void); bool usb_vcp_is_enabled(void); int usb_vcp_recv_byte(uint8_t *c); // if a byte is available, return 1 and put the byte in *c, else return 0