Skip to content

Commit

Permalink
stm32/usb: Add support to auto-detect USB interface, either FS or HS.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dpgeorge committed Jul 3, 2019
1 parent 6d2e654 commit 46b3cc4
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 5 deletions.
2 changes: 1 addition & 1 deletion ports/stm32/main.c
Expand Up @@ -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

Expand Down
31 changes: 28 additions & 3 deletions ports/stm32/usb.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
3 changes: 2 additions & 1 deletion ports/stm32/usb.h
Expand Up @@ -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
Expand Down

0 comments on commit 46b3cc4

Please sign in to comment.