summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2021-09-14 11:40:55 +0700
committerGitHub <[email protected]>2021-09-14 11:40:55 +0700
commit6d3fb7eb98b6c0960be152b66b653a3062c7db5e (patch)
tree37860926a5d43158f51cc3b4aa6e6b0a8a66ff58 /src
parent43aac7074be0d14e72cb04eaddcddf1a926c6a74 (diff)
parentce5db06ba03f356b2049edc3b36aea398fa50036 (diff)
Merge pull request #1087 from HiFiPhile/nuc_wkp
NUC126: fix remote_wakeup
Diffstat (limited to 'src')
-rw-r--r--src/portable/nuvoton/nuc121/dcd_nuc121.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c
index 7edafe5d3..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)
@@ -252,10 +251,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)
@@ -367,14 +379,16 @@ 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 = (ep->CFG & ~USBD_CFG_DSQSYNC_Msk) | USBD_CFG_CSTALL_Msk;
}
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
@@ -505,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.