diff --git a/common/usb_dc.h b/common/usb_dc.h index b11f8a68..30955565 100644 --- a/common/usb_dc.h +++ b/common/usb_dc.h @@ -44,6 +44,15 @@ int usb_dc_deinit(void); */ int usbd_set_address(const uint8_t addr); +/** + * @brief Get USB device speed + * + * @param[in] port port index + * + * @return port speed, USB_SPEED_LOW or USB_SPEED_FULL or USB_SPEED_HIGH + */ +uint8_t usbd_get_port_speed(const uint8_t port); + /** * @brief configure and enable endpoint. * diff --git a/port/ch32/usb_ch58x_dc_usbfs.c b/port/ch32/usb_ch58x_dc_usbfs.c index 44d01971..5dc2a37c 100644 --- a/port/ch32/usb_ch58x_dc_usbfs.c +++ b/port/ch32/usb_ch58x_dc_usbfs.c @@ -124,6 +124,11 @@ int usbd_set_address(const uint8_t address) return 0; } +uint8_t usbd_get_port_speed(const uint8_t port) +{ + return USB_SPEED_FULL; +} + /** * @brief Open endpoint * @pre None diff --git a/port/ch32/usb_dc_usbfs.c b/port/ch32/usb_dc_usbfs.c index acac221e..f404c41b 100644 --- a/port/ch32/usb_dc_usbfs.c +++ b/port/ch32/usb_dc_usbfs.c @@ -99,6 +99,11 @@ int usbd_set_address(const uint8_t addr) return 0; } +uint8_t usbd_get_port_speed(const uint8_t port) +{ + return USB_SPEED_FULL; +} + int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg) { uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr); diff --git a/port/ch32/usb_dc_usbhs.c b/port/ch32/usb_dc_usbhs.c index 80f127a8..6ab8d345 100644 --- a/port/ch32/usb_dc_usbhs.c +++ b/port/ch32/usb_dc_usbhs.c @@ -96,6 +96,11 @@ int usbd_set_address(const uint8_t addr) return 0; } +uint8_t usbd_get_port_speed(const uint8_t port) +{ + return USB_SPEED_HIGH; +} + int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg) { uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr); diff --git a/port/dwc2/usb_dc_dwc2.c b/port/dwc2/usb_dc_dwc2.c index 92d2d1db..0a852c75 100644 --- a/port/dwc2/usb_dc_dwc2.c +++ b/port/dwc2/usb_dc_dwc2.c @@ -675,6 +675,23 @@ int usbd_set_address(const uint8_t addr) return 0; } +uint8_t usbd_get_port_speed(const uint8_t port) +{ + uint8_t speed; + uint32_t DevEnumSpeed = USB_OTG_DEV->DSTS & USB_OTG_DSTS_ENUMSPD; + + if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ) { + speed = USB_SPEED_HIGH; + } else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) || + (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ)) { + speed = USB_SPEED_FULL; + } else { + speed = USB_SPEED_FULL; + } + + return speed; +} + int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg) { uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr); diff --git a/port/fsdev/usb_dc_fsdev.c b/port/fsdev/usb_dc_fsdev.c index a239e54c..295efe1e 100644 --- a/port/fsdev/usb_dc_fsdev.c +++ b/port/fsdev/usb_dc_fsdev.c @@ -116,6 +116,11 @@ int usbd_set_address(const uint8_t addr) return 0; } +uint8_t usbd_get_port_speed(const uint8_t port) +{ + return USB_SPEED_FULL; +} + int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg) { uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr); diff --git a/port/hpm/usb_dc_hpm.c b/port/hpm/usb_dc_hpm.c index fc0aa900..d75133c1 100644 --- a/port/hpm/usb_dc_hpm.c +++ b/port/hpm/usb_dc_hpm.c @@ -87,6 +87,25 @@ int usbd_set_address(const uint8_t addr) return 0; } +uint8_t usbd_get_port_speed(const uint8_t port) +{ + uint8_t speed; + + speed = usb_get_port_speed(g_hpm_udc.handle->regs); + + if (speed == 0x00) { + return USB_SPEED_FULL; + } + if (speed == 0x01) { + return USB_SPEED_LOW; + } + if (speed == 0x02) { + return USB_SPEED_HIGH; + } + + return 0; +} + int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg) { usb_endpoint_config_t tmp_ep_cfg; diff --git a/port/musb/usb_dc_musb.c b/port/musb/usb_dc_musb.c index 3aa64b10..b9fc7289 100644 --- a/port/musb/usb_dc_musb.c +++ b/port/musb/usb_dc_musb.c @@ -268,6 +268,20 @@ int usbd_set_address(const uint8_t addr) return 0; } +uint8_t usbd_get_port_speed(const uint8_t port) +{ + uint8_t speed; + + if (HWREGB(USB_BASE + MUSB_POWER_OFFSET) & USB_POWER_HSMODE) + speed = USB_SPEED_HIGH; + else if (HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_FSDEV) + speed = USB_SPEED_FULL; + else if (HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_LSDEV) + speed = USB_SPEED_LOW; + + return speed; +} + int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg) { uint16_t used = 0; diff --git a/port/nrf5x/usb_dc_nrf5x.c b/port/nrf5x/usb_dc_nrf5x.c index 20c3f8fd..0bf1bef0 100644 --- a/port/nrf5x/usb_dc_nrf5x.c +++ b/port/nrf5x/usb_dc_nrf5x.c @@ -189,6 +189,11 @@ int usbd_set_address(const uint8_t address) return 0; } +uint8_t usbd_get_port_speed(const uint8_t port) +{ + return USB_SPEED_FULL; +} + /** * @brief Open endpoint * @pre None diff --git a/port/rp2040/usb_dc_rp2040.c b/port/rp2040/usb_dc_rp2040.c index 37d33df0..97562264 100644 --- a/port/rp2040/usb_dc_rp2040.c +++ b/port/rp2040/usb_dc_rp2040.c @@ -168,7 +168,7 @@ static void usb_start_transfer(struct usb_dc_ep_state *ep, uint8_t *buf, uint16_ ep->next_pid ^= 1u; /** * !Need delay some cycles - * nop for some clk_sys cycles to ensure that at least one clk_usb cycle has passed. For example if clk_sys was running + * nop for some clk_sys cycles to ensure that at least one clk_usb cycle has passed. For example if clk_sys was running * at 125MHz and clk_usb was running at 48MHz then 125/48 rounded up would be 3 nop instructions */ *ep->buffer_control = val & ~USB_BUF_CTRL_AVAIL; @@ -200,6 +200,11 @@ int usbd_set_address(const uint8_t addr) return 0; } +uint8_t usbd_get_port_speed(const uint8_t port) +{ + return USB_SPEED_FULL; +} + int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg) { uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr); @@ -573,7 +578,7 @@ void USBD_IRQHandler(void) #endif } - /** + /** * Note from pico datasheet 4.1.2.6.4 (v1.2) * If you enable the suspend interrupt, it is likely you will see a suspend interrupt when * the device is first connected but the bus is idle. The bus can be idle for a few ms before