diff --git a/common/usb_dc.h b/common/usb_dc.h index 96f4ffa1..1f2fdddd 100644 --- a/common/usb_dc.h +++ b/common/usb_dc.h @@ -33,6 +33,13 @@ int usb_dc_deinit(uint8_t busid); */ int usbd_set_address(uint8_t busid, const uint8_t addr); +/** + * @brief Set remote wakeup feature + * + * @return On success will return 0, and others indicate fail. + */ +int usbd_set_remote_wakeup(uint8_t busid); + /** * @brief Get USB device speed * @@ -187,8 +194,6 @@ void usbd_event_ep_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt void usbd_execute_test_mode(uint8_t busid, uint8_t test_mode); #endif -void usbd_send_remote_wakeup(uint8_t busid); - #ifdef __cplusplus } #endif diff --git a/core/usbd_core.c b/core/usbd_core.c index 21022e74..fc2aa6ac 100644 --- a/core/usbd_core.c +++ b/core/usbd_core.c @@ -52,9 +52,11 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv { /** Currently selected configuration */ uint8_t configuration; + uint8_t device_address; bool self_powered; bool remote_wakeup_support; bool remote_wakeup_enabled; + bool is_suspend; #ifdef CONFIG_USBDEV_ADVANCE_DESC uint8_t speed; #endif @@ -561,6 +563,7 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet * break; case USB_REQUEST_SET_ADDRESS: + g_usbd_core[busid].device_address = value; usbd_set_address(busid, value); *len = 0; break; @@ -587,6 +590,7 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet * ret = false; } else { g_usbd_core[busid].configuration = value; + g_usbd_core[busid].is_suspend = false; usbd_class_event_notify_handler(busid, USBD_EVENT_CONFIGURED, NULL); g_usbd_core[busid].event_handler(busid, USBD_EVENT_CONFIGURED); } @@ -1071,17 +1075,22 @@ void usbd_event_disconnect_handler(uint8_t busid) void usbd_event_resume_handler(uint8_t busid) { + g_usbd_core[busid].is_suspend = false; g_usbd_core[busid].event_handler(busid, USBD_EVENT_RESUME); } void usbd_event_suspend_handler(uint8_t busid) { - g_usbd_core[busid].event_handler(busid, USBD_EVENT_SUSPEND); + if (g_usbd_core[busid].device_address > 0) { + g_usbd_core[busid].is_suspend = true; + g_usbd_core[busid].event_handler(busid, USBD_EVENT_SUSPEND); + } } void usbd_event_reset_handler(uint8_t busid) { usbd_set_address(busid, 0); + g_usbd_core[busid].device_address = 0; g_usbd_core[busid].configuration = 0; #ifdef CONFIG_USBDEV_ADVANCE_DESC g_usbd_core[busid].speed = USB_SPEED_UNKNOWN; @@ -1347,6 +1356,24 @@ bool usb_device_is_configured(uint8_t busid) return g_usbd_core[busid].configuration; } +int usbd_send_remote_wakeup(uint8_t busid) +{ + if (g_usbd_core[busid].remote_wakeup_support && g_usbd_core[busid].remote_wakeup_enabled && g_usbd_core[busid].is_suspend) { + return usbd_set_remote_wakeup(busid); + } else { + if (!g_usbd_core[busid].remote_wakeup_support) { + USB_LOG_ERR("device does not support remote wakeup\r\n"); + } + if (!g_usbd_core[busid].remote_wakeup_enabled) { + USB_LOG_ERR("device remote wakeup is not enabled\r\n"); + } + if (!g_usbd_core[busid].is_suspend) { + USB_LOG_ERR("device is not in suspend state\r\n"); + } + return -1; + } +} + int usbd_initialize(uint8_t busid, uint32_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event)) { int ret; diff --git a/core/usbd_core.h b/core/usbd_core.h index 87a386fe..202d4fc2 100644 --- a/core/usbd_core.h +++ b/core/usbd_core.h @@ -102,6 +102,7 @@ void usbd_add_endpoint(uint8_t busid, struct usbd_endpoint *ep); uint16_t usbd_get_ep_mps(uint8_t busid, uint8_t ep); uint8_t usbd_get_ep_mult(uint8_t busid, uint8_t ep); bool usb_device_is_configured(uint8_t busid); +int usbd_send_remote_wakeup(uint8_t busid); int usbd_initialize(uint8_t busid, uint32_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event)); int usbd_deinitialize(uint8_t busid); diff --git a/demo/hid_remote_wakeup_template.c b/demo/hid_remote_wakeup_template.c new file mode 100644 index 00000000..a1334245 --- /dev/null +++ b/demo/hid_remote_wakeup_template.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2024, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbd_core.h" +#include "usbd_hid.h" + +/*!< endpoint address */ +#define HID_INT_EP 0x81 +#define HID_INT_EP_SIZE 4 +#define HID_INT_EP_INTERVAL 1 + +#define USBD_VID 0xffff +#define USBD_PID 0xffff +#define USBD_MAX_POWER 100 +#define USBD_LANGID_STRING 1033 + +/*!< config descriptor size */ +#define USB_HID_CONFIG_DESC_SIZ 34 +/*!< report descriptor size */ +#define HID_MOUSE_REPORT_DESC_SIZE 74 + +/*!< global descriptor */ +const uint8_t hid_descriptor[] = { + USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01), + USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER), + + /************** Descriptor of Joystick Mouse interface ****************/ + /* 09 */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass: HID */ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0, /* iInterface: Index of string descriptor */ + /******************** Descriptor of Joystick Mouse HID ********************/ + /* 18 */ + 0x09, /* bLength: HID Descriptor size */ + HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ + 0x11, /* bcdHID: HID Class Spec release number */ + 0x01, + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ + 0x00, + /******************** Descriptor of Mouse endpoint ********************/ + /* 27 */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ + HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ + 0x00, + HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ + /* 34 */ + /////////////////////////////////////// + /// string0 descriptor + /////////////////////////////////////// + USB_LANGID_INIT(USBD_LANGID_STRING), + /////////////////////////////////////// + /// string1 descriptor + /////////////////////////////////////// + 0x14, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'C', 0x00, /* wcChar0 */ + 'h', 0x00, /* wcChar1 */ + 'e', 0x00, /* wcChar2 */ + 'r', 0x00, /* wcChar3 */ + 'r', 0x00, /* wcChar4 */ + 'y', 0x00, /* wcChar5 */ + 'U', 0x00, /* wcChar6 */ + 'S', 0x00, /* wcChar7 */ + 'B', 0x00, /* wcChar8 */ + /////////////////////////////////////// + /// string2 descriptor + /////////////////////////////////////// + 0x26, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + 'C', 0x00, /* wcChar0 */ + 'h', 0x00, /* wcChar1 */ + 'e', 0x00, /* wcChar2 */ + 'r', 0x00, /* wcChar3 */ + 'r', 0x00, /* wcChar4 */ + 'y', 0x00, /* wcChar5 */ + 'U', 0x00, /* wcChar6 */ + 'S', 0x00, /* wcChar7 */ + 'B', 0x00, /* wcChar8 */ + ' ', 0x00, /* wcChar9 */ + 'H', 0x00, /* wcChar10 */ + 'I', 0x00, /* wcChar11 */ + 'D', 0x00, /* wcChar12 */ + ' ', 0x00, /* wcChar13 */ + 'D', 0x00, /* wcChar14 */ + 'E', 0x00, /* wcChar15 */ + 'M', 0x00, /* wcChar16 */ + 'O', 0x00, /* wcChar17 */ + /////////////////////////////////////// + /// string3 descriptor + /////////////////////////////////////// + 0x16, /* bLength */ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ + '2', 0x00, /* wcChar0 */ + '0', 0x00, /* wcChar1 */ + '2', 0x00, /* wcChar2 */ + '2', 0x00, /* wcChar3 */ + '1', 0x00, /* wcChar4 */ + '2', 0x00, /* wcChar5 */ + '3', 0x00, /* wcChar6 */ + '4', 0x00, /* wcChar7 */ + '5', 0x00, /* wcChar8 */ + '6', 0x00, /* wcChar9 */ +#ifdef CONFIG_USB_HS + /////////////////////////////////////// + /// device qualifier descriptor + /////////////////////////////////////// + 0x0a, + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +#endif + 0x00 +}; + +/*!< hid mouse report descriptor */ +static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = { + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x02, // USAGE (Mouse) + 0xA1, 0x01, // COLLECTION (Application) + 0x09, 0x01, // USAGE (Pointer) + + 0xA1, 0x00, // COLLECTION (Physical) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x75, 0x01, // REPORT_SIZE (1) + + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x01, // INPUT (Cnst,Var,Abs) + + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x09, 0x38, + + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7F, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (2) + + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xC0, 0x09, + 0x3c, 0x05, + 0xff, 0x09, + + 0x01, 0x15, + 0x00, 0x25, + 0x01, 0x75, + 0x01, 0x95, + + 0x02, 0xb1, + 0x22, 0x75, + 0x06, 0x95, + 0x01, 0xb1, + + 0x01, 0xc0 // END_COLLECTION +}; + +/*!< mouse report struct */ +struct hid_mouse { + uint8_t buttons; + int8_t x; + int8_t y; + int8_t wheel; +}; + +/*!< mouse report */ +static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct hid_mouse mouse_cfg; + +#define HID_STATE_IDLE 0 +#define HID_STATE_BUSY 1 + +/*!< hid state ! Data can be sent only when state is idle */ +static volatile uint8_t hid_state = HID_STATE_IDLE; + +static void usbd_event_handler(uint8_t busid, uint8_t event) +{ + switch (event) { + case USBD_EVENT_RESET: + break; + case USBD_EVENT_CONNECTED: + break; + case USBD_EVENT_DISCONNECTED: + break; + case USBD_EVENT_RESUME: + break; + case USBD_EVENT_SUSPEND: + break; + case USBD_EVENT_CONFIGURED: + hid_state = HID_STATE_IDLE; + break; + case USBD_EVENT_SET_REMOTE_WAKEUP: + break; + case USBD_EVENT_CLR_REMOTE_WAKEUP: + break; + + default: + break; + } +} + +/* function ------------------------------------------------------------------*/ +static void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + hid_state = HID_STATE_IDLE; +} + +/*!< endpoint call back */ +static struct usbd_endpoint hid_in_ep = { + .ep_cb = usbd_hid_int_callback, + .ep_addr = HID_INT_EP +}; + +static struct usbd_interface intf0; + +void hid_mouse_init(uint8_t busid, uint32_t reg_base) +{ + usbd_desc_register(busid, hid_descriptor); + usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE)); + usbd_add_endpoint(busid, &hid_in_ep); + + usbd_initialize(busid, reg_base, usbd_event_handler); + + /*!< init mouse report data */ + mouse_cfg.buttons = 0; + mouse_cfg.wheel = 0; + mouse_cfg.x = 0; + mouse_cfg.y = 0; +} + +#define CURSOR_STEP 2U +#define CURSOR_WIDTH 20U + +void draw_circle(uint8_t *buf) +{ + static int32_t move_cnt = 0; + static uint8_t step_x_y = 0; + static int8_t x = 0, y = 0; + + move_cnt++; + if (move_cnt > CURSOR_WIDTH) { + step_x_y++; + step_x_y = step_x_y % 4; + move_cnt = 0; + } + switch (step_x_y) { + case 0: { + y = 0; + x = CURSOR_STEP; + + } break; + + case 1: { + x = 0; + y = CURSOR_STEP; + + } break; + + case 2: { + y = 0; + x = (int8_t)(-CURSOR_STEP); + + } break; + + case 3: { + x = 0; + y = (int8_t)(-CURSOR_STEP); + + } break; + } + + buf[0] = 0; + buf[1] = x; + buf[2] = y; + buf[3] = 0; +} + +/* https://cps-check.com/cn/polling-rate-check */ +void hid_mouse_test(uint8_t busid) +{ + static uint32_t count = 1000; + int ret; + + // if (gpio_read_pin(GPIO_PIN) == 1) { + // ret = usbd_send_remote_wakeup(busid); + // if (ret < 0) { + // return; + // } + // count = 5000; + // } + + while (count) { + draw_circle((uint8_t *)&mouse_cfg); + int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4); + if (ret < 0) { + return; + } + hid_state = HID_STATE_BUSY; + while (hid_state == HID_STATE_BUSY) { + } + + count--; + } +} diff --git a/port/aic/usb_dc_aic.c b/port/aic/usb_dc_aic.c index c6adfda6..46cbfea8 100644 --- a/port/aic/usb_dc_aic.c +++ b/port/aic/usb_dc_aic.c @@ -661,6 +661,11 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + return -1; +} + uint8_t usbd_get_port_speed(uint8_t busid) { uint8_t speed; diff --git a/port/bouffalolab/usb_dc_bl.c b/port/bouffalolab/usb_dc_bl.c index 6c9df09c..5ed0892d 100644 --- a/port/bouffalolab/usb_dc_bl.c +++ b/port/bouffalolab/usb_dc_bl.c @@ -613,6 +613,23 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + uint32_t regval; + + regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET); + regval |= USB_CAP_RMWAKUP; + putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET); + + bflb_mtimer_delay_ms(10); + + regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET); + regval &= ~USB_CAP_RMWAKUP; + putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET); + + return 0; +} + uint8_t usbd_get_port_speed(uint8_t busid) { uint8_t speed = 3; diff --git a/port/ch32/usb_ch58x_dc_usbfs.c b/port/ch32/usb_ch58x_dc_usbfs.c index 052d96f7..d0c943a9 100644 --- a/port/ch32/usb_ch58x_dc_usbfs.c +++ b/port/ch32/usb_ch58x_dc_usbfs.c @@ -223,6 +223,11 @@ int usbd_set_address(uint8_t busid, const uint8_t address) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + return -1; +} + uint8_t usbd_get_port_speed(uint8_t busid) { return USB_SPEED_FULL; @@ -543,7 +548,7 @@ USBD_IRQHandler(void) break; case UIS_TOKEN_OUT: EPn_SET_RX_NAK(epid); - + if (epid == 0) { /*!< ep0 out */ CH58x_USBFS_DEV->UEP0_CTRL ^= RB_UEP_R_TOG; diff --git a/port/ch32/usb_dc_usbfs.c b/port/ch32/usb_dc_usbfs.c index 4b4b72d4..7aabd411 100644 --- a/port/ch32/usb_dc_usbfs.c +++ b/port/ch32/usb_dc_usbfs.c @@ -101,6 +101,11 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + return -1; +} + uint8_t usbd_get_port_speed(uint8_t busid) { return USB_SPEED_FULL; diff --git a/port/ch32/usb_dc_usbhs.c b/port/ch32/usb_dc_usbhs.c index 758ffd77..a8d3036a 100644 --- a/port/ch32/usb_dc_usbhs.c +++ b/port/ch32/usb_dc_usbhs.c @@ -101,6 +101,11 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + return -1; +} + uint8_t usbd_get_port_speed(uint8_t busid) { return USB_SPEED_HIGH; diff --git a/port/dwc2/usb_dc_dwc2.c b/port/dwc2/usb_dc_dwc2.c index 9f7d493d..3bc9e052 100644 --- a/port/dwc2/usb_dc_dwc2.c +++ b/port/dwc2/usb_dc_dwc2.c @@ -571,6 +571,7 @@ int usb_dc_init(uint8_t busid) /* Enable interrupts matching to the Device mode ONLY */ USB_OTG_GLB->GINTMSK = USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT | + USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | USB_OTG_GINTMSK_IISOIXFRM | USB_OTG_GINTMSK_PXFRM_IISOOXFRM; #ifdef CONFIG_USB_DWC2_DMA_ENABLE @@ -678,6 +679,17 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + if (!(USB_OTG_DEV->DSTS & USB_OTG_DSTS_SUSPSTS)) { + return -1; + } + USB_OTG_DEV->DCTL |= USB_OTG_DCTL_RWUSIG; + usbd_dwc2_delay_ms(10); + USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_RWUSIG; + return 0; +} + uint8_t usbd_get_port_speed(uint8_t busid) { uint8_t speed; @@ -1188,9 +1200,11 @@ void USBD_IRQHandler(uint8_t busid) } if (gint_status & USB_OTG_GINTSTS_USBSUSP) { USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_USBSUSP; + usbd_event_suspend_handler(0); } if (gint_status & USB_OTG_GINTSTS_WKUINT) { USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_WKUINT; + usbd_event_resume_handler(0); } if (gint_status & USB_OTG_GINTSTS_OTGINT) { temp = USB_OTG_GLB->GOTGINT; diff --git a/port/dwc2/usb_dwc2_reg.h b/port/dwc2/usb_dwc2_reg.h index c3bd75d6..85512c08 100644 --- a/port/dwc2/usb_dwc2_reg.h +++ b/port/dwc2/usb_dwc2_reg.h @@ -1718,4 +1718,5 @@ typedef struct uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base); uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base); +void usbd_dwc2_delay_ms(uint8_t ms); #endif diff --git a/port/dwc2/usb_glue_at.c b/port/dwc2/usb_glue_at.c index d9c26261..137b1d87 100644 --- a/port/dwc2/usb_glue_at.c +++ b/port/dwc2/usb_glue_at.c @@ -12,7 +12,7 @@ * usbx->gccfg_bit.pwrdown = TRUE; * usbx->gccfg_bit.avalidsesen = TRUE; * usbx->gccfg_bit.bvalidsesen = TRUE; - * + * */ uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) @@ -49,4 +49,9 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) return ((1 << 16) | (1 << 21)); #endif #endif +} + +void usbd_dwc2_delay_ms(uint8_t ms) +{ + /* implement later */ } \ No newline at end of file diff --git a/port/dwc2/usb_glue_esp.c b/port/dwc2/usb_glue_esp.c index 8c63234e..660efa9b 100644 --- a/port/dwc2/usb_glue_esp.c +++ b/port/dwc2/usb_glue_esp.c @@ -118,3 +118,8 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) { return 0; } + +void usbd_dwc2_delay_ms(uint8_t ms) +{ + vTaskDelay(pdMS_TO_TICKS(ms)); +} \ No newline at end of file diff --git a/port/dwc2/usb_glue_gd.c b/port/dwc2/usb_glue_gd.c index bdc0d680..7121ac9d 100644 --- a/port/dwc2/usb_glue_gd.c +++ b/port/dwc2/usb_glue_gd.c @@ -10,7 +10,7 @@ /* you can find this config in function:usb_core_init, file:drv_usb_core.c, for example: * * usb_regs->gr->GCCFG |= GCCFG_PWRON | GCCFG_VBUSACEN | GCCFG_VBUSBCEN; - * + * */ uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) @@ -29,4 +29,9 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) #else return ((1 << 16) | (1 << 18) | (1 << 19) | (1 << 21)); #endif +} + +void usbd_dwc2_delay_ms(uint8_t ms) +{ + /* implement later */ } \ No newline at end of file diff --git a/port/dwc2/usb_glue_hc.c b/port/dwc2/usb_glue_hc.c index 9bebe6df..431b5db5 100644 --- a/port/dwc2/usb_glue_hc.c +++ b/port/dwc2/usb_glue_hc.c @@ -24,3 +24,8 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL; return 0; } + +void usbd_dwc2_delay_ms(uint8_t ms) +{ + /* implement later */ +} \ No newline at end of file diff --git a/port/dwc2/usb_glue_st.c b/port/dwc2/usb_glue_st.c index 94293d29..f73dc5e9 100644 --- a/port/dwc2/usb_glue_st.c +++ b/port/dwc2/usb_glue_st.c @@ -13,9 +13,11 @@ * USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; * USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN; * USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN; - * + * */ +extern void HAL_Delay(uint32_t Delay); + #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx) /** * @brief USB_HS_PHY_Registers @@ -201,3 +203,8 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) #endif #endif } + +void usbd_dwc2_delay_ms(uint8_t ms) +{ + HAL_Delay(ms); +} \ No newline at end of file diff --git a/port/fsdev/usb_dc_fsdev.c b/port/fsdev/usb_dc_fsdev.c index 556126bd..b2dd9cca 100644 --- a/port/fsdev/usb_dc_fsdev.c +++ b/port/fsdev/usb_dc_fsdev.c @@ -117,6 +117,11 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + return -1; +} + uint8_t usbd_get_port_speed(uint8_t busid) { return USB_SPEED_FULL; diff --git a/port/hpm/usb_dc_hpm.c b/port/hpm/usb_dc_hpm.c index 31ad5b72..1e2f32df 100644 --- a/port/hpm/usb_dc_hpm.c +++ b/port/hpm/usb_dc_hpm.c @@ -91,7 +91,7 @@ int usb_dc_init(uint8_t busid) } uint32_t int_mask; - int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | + int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | USB_USBSTS_SLI_MASK | USB_USBINTR_PCE_MASK | USB_USBINTR_URE_MASK); usb_device_init(g_hpm_udc[busid].handle, int_mask); @@ -116,6 +116,23 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + USB_Type *ptr; + + ptr = g_hpm_udc[busid].handle->regs; + + if (!usb_get_suspend_status(ptr)) { + return -1; + } + ptr->PORTSC1 &= ~USB_PORTSC1_PHCD_MASK; + usb_force_port_resume(g_hpm_udc[busid].handle->regs); + while (ptr->PORTSC1 & USB_PORTSC1_FPR_MASK) { + } + + return 0; +} + uint8_t usbd_get_port_speed(uint8_t busid) { uint8_t speed; @@ -314,7 +331,7 @@ void USBD_IRQHandler(uint8_t busid) transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes; } - if (p_qtd->next == USB_SOC_DCD_QTD_NEXT_INVALID){ + if (p_qtd->next == USB_SOC_DCD_QTD_NEXT_INVALID) { break; } else { p_qtd = (dcd_qtd_t *)p_qtd->next; diff --git a/port/musb/usb_dc_musb.c b/port/musb/usb_dc_musb.c index 28139fa1..845e583b 100644 --- a/port/musb/usb_dc_musb.c +++ b/port/musb/usb_dc_musb.c @@ -273,7 +273,7 @@ int usb_dc_init(uint8_t busid) } /* Enable USB interrupts */ - HWREGB(USB_BASE + MUSB_IE_OFFSET) = USB_IE_RESET; + HWREGB(USB_BASE + MUSB_IE_OFFSET) = USB_IE_RESET | USB_IE_SUSPND | USB_IE_RESUME; HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = USB_TXIE_EP0; HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0; @@ -296,6 +296,14 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_RESUME; + usbd_musb_delay_ms(10); + HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_RESUME; + return 0; +} + uint8_t usbd_get_port_speed(uint8_t busid) { uint8_t speed = USB_SPEED_UNKNOWN; @@ -726,9 +734,11 @@ void USBD_IRQHandler(uint8_t busid) } if (is & USB_IS_RESUME) { + usbd_event_resume_handler(0); } if (is & USB_IS_SUSPEND) { + usbd_event_suspend_handler(0); } txis &= HWREGH(USB_BASE + MUSB_TXIE_OFFSET); diff --git a/port/musb/usb_glue_bk.c b/port/musb/usb_glue_bk.c index 7eb987f9..2af1e361 100644 --- a/port/musb/usb_glue_bk.c +++ b/port/musb/usb_glue_bk.c @@ -277,6 +277,11 @@ void usb_dc_low_level_deinit(void) sys_drv_dev_clk_pwr_up(CLK_PWR_ID_USB_1, CLK_PWR_CTRL_PWR_DOWN); } +void usbd_musb_delay_ms(uint8_t ms) +{ + /* implement later */ +} + extern void USBH_IRQHandler(uint8_t busid); void USBH_IRQ(void) diff --git a/port/musb/usb_glue_es.c b/port/musb/usb_glue_es.c index adfc293c..b1a8f8eb 100644 --- a/port/musb/usb_glue_es.c +++ b/port/musb/usb_glue_es.c @@ -50,4 +50,9 @@ uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg) uint32_t usb_get_musb_ram_size(void) { return 4096; -} \ No newline at end of file +} + +void usbd_musb_delay_ms(uint8_t ms) +{ + /* implement later */ +} diff --git a/port/musb/usb_glue_sunxi.c b/port/musb/usb_glue_sunxi.c index 43392304..706a60c7 100644 --- a/port/musb/usb_glue_sunxi.c +++ b/port/musb/usb_glue_sunxi.c @@ -56,4 +56,9 @@ uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg) uint32_t usb_get_musb_ram_size(void) { return 8192; -} \ No newline at end of file +} + +void usbd_musb_delay_ms(uint8_t ms) +{ + /* implement later */ +} diff --git a/port/musb/usb_musb_reg.h b/port/musb/usb_musb_reg.h index 885bdd4a..17765372 100644 --- a/port/musb/usb_musb_reg.h +++ b/port/musb/usb_musb_reg.h @@ -3882,5 +3882,6 @@ struct musb_fifo_cfg { uint8_t usbd_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg); uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg); uint32_t usb_get_musb_ram_size(void); +void usbd_musb_delay_ms(uint8_t ms); #endif diff --git a/port/nuvoton/usb_dc_usbfs.c b/port/nuvoton/usb_dc_usbfs.c index affa5fae..3f1a8777 100644 --- a/port/nuvoton/usb_dc_usbfs.c +++ b/port/nuvoton/usb_dc_usbfs.c @@ -165,6 +165,11 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + return -1; +} + uint8_t usbd_get_port_speed(uint8_t busid) { return USB_SPEED_FULL; diff --git a/port/template/usb_dc.c b/port/template/usb_dc.c index 0aeea0c9..814a42f8 100644 --- a/port/template/usb_dc.c +++ b/port/template/usb_dc.c @@ -51,6 +51,11 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } +int usbd_set_remote_wakeup(uint8_t busid) +{ + return -1; +} + int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) { uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);