stm32/usb: Add support to auto-detect USB interface, either FS or HS.

If both FS and HS USB peripherals are enabled for a board then the active
one used for the REPL will now be auto-detected, by checking to see if both
the DP and DM lines are actively pulled low.  By default the code falls
back to use MICROPY_HW_USB_MAIN_DEV if nothing can be detected.
This commit is contained in:
Damien George 2019-07-03 11:51:13 +10:00
parent 6d2e654b14
commit 46b3cc4572
3 changed files with 31 additions and 5 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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