From 8886de0d8a14daa70d1fcf4101e3fdeda12a1b26 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Fri, 10 Sep 2021 13:05:15 +0200 Subject: [PATCH 1/3] Fix remote_wakeup --- src/portable/nuvoton/nuc121/dcd_nuc121.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index 7edafe5d3..d101550b6 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -252,10 +252,23 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) // do it at dcd_edpt0_status_complete() } +static void remote_wakeup_delay(void) +{ + // try to delay for 1 ms + uint32_t count = SystemCoreClock / 1000; + while(count--) __NOP(); +} + void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; - USBD->ATTR = USBD_ATTR_RWAKEUP_Msk; + // Enable PHY before sending Resume('K') state + USBD->ATTR |= USBD_ATTR_PHYEN_Msk; + USBD->ATTR |= USBD_ATTR_RWAKEUP_Msk; + + // Per specs: remote wakeup signal bit must be clear within 1-15ms + remote_wakeup_delay(); + USBD->ATTR &=~USBD_ATTR_RWAKEUP_Msk; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) @@ -374,7 +387,8 @@ void dcd_int_handler(uint8_t rhport) { (void) rhport; - uint32_t status = USBD->INTSTS; + // Mask non-enabled irqs, ex. SOF + uint32_t status = USBD->INTSTS & (enabled_irqs | 0xffffff00); #ifdef SUPPORT_LPM uint32_t state = USBD->ATTR & 0x300f; #else From 22571ec98ef89a76239b27c86cbdac3db3c42f09 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Fri, 10 Sep 2021 16:04:47 +0200 Subject: [PATCH 2/3] reset PID to DATA0 on clear_stall. --- src/portable/nuvoton/nuc121/dcd_nuc121.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index d101550b6..5dfc77bb7 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -381,6 +381,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) (void) rhport; USBD_EP_T *ep = ep_entry(ep_addr, false); ep->CFG |= USBD_CFG_CSTALL_Msk; + ep->CFG &=~USBD_CFG_DSQSYNC_Msk; } void dcd_int_handler(uint8_t rhport) From ce5db06ba03f356b2049edc3b36aea398fa50036 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 13 Sep 2021 12:05:49 +0700 Subject: [PATCH 3/3] clear PID along with clear stall --- src/portable/nuvoton/nuc121/dcd_nuc121.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index 5dfc77bb7..dbc5cd18a 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -200,11 +200,10 @@ static void bus_reset(void) } /* centralized location for USBD interrupt enable bit mask */ -#if USE_SOF -static const uint32_t enabled_irqs = USBD_INTSTS_VBDETIF_Msk | USBD_INTSTS_BUSIF_Msk | USBD_INTSTS_SETUP_Msk | USBD_INTSTS_USBIF_Msk | USBD_INTSTS_SOFIF_Msk; -#else -static const uint32_t enabled_irqs = USBD_INTSTS_VBDETIF_Msk | USBD_INTSTS_BUSIF_Msk | USBD_INTSTS_SETUP_Msk | USBD_INTSTS_USBIF_Msk; -#endif +enum { + ENABLED_IRQS = USBD_INTSTS_VBDETIF_Msk | USBD_INTSTS_BUSIF_Msk | USBD_INTSTS_SETUP_Msk | + USBD_INTSTS_USBIF_Msk | (USE_SOF ? USBD_INTSTS_SOFIF_Msk : 0) +}; /* NUC121/NUC125/NUC126 TinyUSB API driver implementation @@ -226,8 +225,8 @@ void dcd_init(uint8_t rhport) usb_attach(); - USBD->INTSTS = enabled_irqs; - USBD->INTEN = enabled_irqs; + USBD->INTSTS = ENABLED_IRQS; + USBD->INTEN = ENABLED_IRQS; } void dcd_int_enable(uint8_t rhport) @@ -380,8 +379,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; USBD_EP_T *ep = ep_entry(ep_addr, false); - ep->CFG |= USBD_CFG_CSTALL_Msk; - ep->CFG &=~USBD_CFG_DSQSYNC_Msk; + ep->CFG = (ep->CFG & ~USBD_CFG_DSQSYNC_Msk) | USBD_CFG_CSTALL_Msk; } void dcd_int_handler(uint8_t rhport) @@ -389,7 +387,8 @@ void dcd_int_handler(uint8_t rhport) (void) rhport; // Mask non-enabled irqs, ex. SOF - uint32_t status = USBD->INTSTS & (enabled_irqs | 0xffffff00); + uint32_t status = USBD->INTSTS & (ENABLED_IRQS | 0xffffff00); + #ifdef SUPPORT_LPM uint32_t state = USBD->ATTR & 0x300f; #else @@ -520,7 +519,7 @@ void dcd_int_handler(uint8_t rhport) } /* acknowledge all interrupts */ - USBD->INTSTS = status & enabled_irqs; + USBD->INTSTS = status & ENABLED_IRQS; } // Invoked when a control transfer's status stage is complete.