summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/main.c2
-rw-r--r--ports/stm32/usb.c31
-rw-r--r--ports/stm32/usb.h3
3 files changed, 31 insertions, 5 deletions
diff --git a/ports/stm32/main.c b/ports/stm32/main.c
index 1a1c505dc..e470522fb 100644
--- a/ports/stm32/main.c
+++ b/ports/stm32/main.c
@@ -652,7 +652,7 @@ soft_reset:
#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 69ba26c43..12e138818 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 b1c8b476a..cb017902e 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