Skip to content

Commit

Permalink
re-apply local changes
Browse files Browse the repository at this point in the history
  • Loading branch information
tlyu committed Nov 30, 2022
1 parent e518c2c commit 07821c4
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ struct _usb_dev

__IO uint8_t cur_status;
__IO uint8_t backup_status;
__IO uint8_t nreset;
__IO uint8_t nsusp;
__IO uint8_t nresume;
__IO uint8_t nsuspsusp;
__IO uint8_t nerror;

usb_pm pm;
#ifdef LPM_ENABLED
Expand Down Expand Up @@ -219,6 +224,7 @@ struct _usb_handler
void (*suspend) (void);
void (*suspend_leave) (void);
void (*resume) (usb_dev *udev);
void (*err) (uint8_t len);

void (*ep_reset) (usb_dev *udev);
void (*ep_setup) (usb_dev *udev, uint8_t buf_kind, uint32_t buf_addr, const usb_desc_ep *ep_desc);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ static usb_reqsta _usb_std_getdescriptor (usb_dev *udev, usb_req *req)
break;

case USB_DESCTYPE_STR:
if (desc_index < STR_IDX_MAX) {
if (desc_index < USB_STRING_COUNT) {
transc->xfer_buf = std_desc_get[desc_type - 1U](udev, desc_index, &transc->xfer_len);
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ void _usb_setup_transc (usb_dev *udev, uint8_t ep_num)
uint16_t count = udev->drv_handler->ep_read((uint8_t *)(&udev->control.req), 0U, (uint8_t)EP_BUF_SNG);

if (count != USB_SETUP_PACKET_LEN) {
udev->drv_handler->err(count);
usb_stall_transc(udev);

return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ static void usbd_suspend (void);
static void usbd_leave_suspend (void);
static uint16_t usbd_ep_status (usb_dev *udev, uint8_t ep_addr);

void usbd_err(uint8_t len) { (void)len; }

struct _usb_handler usbd_drv_handler =
{
.dp_pullup = usbd_dp_pullup,
Expand All @@ -83,6 +85,7 @@ struct _usb_handler usbd_drv_handler =
.suspend = usbd_suspend,
.suspend_leave = usbd_leave_suspend,
.resume = usbd_resume,
.err = usbd_err,
.set_addr = usbd_address_set,
.ep_reset = usbd_ep_reset,
.ep_disable = usbd_ep_disable,
Expand Down Expand Up @@ -158,7 +161,7 @@ static void usbd_core_reset (void)
#endif /* LPM_ENABLED */

/* enable all interrupts mask bits */
USBD_CTL |= CTL_STIE | CTL_WKUPIE | CTL_SPSIE | CTL_SOFIE | CTL_ESOFIE | CTL_RSTIE;
USBD_CTL |= CTL_STIE | CTL_ERRIE | CTL_WKUPIE | CTL_SPSIE | CTL_SOFIE | CTL_ESOFIE | CTL_RSTIE;
}

/*!
Expand Down Expand Up @@ -418,7 +421,7 @@ static void usbd_ep_stall_clear (usb_dev *udev, uint8_t ep_addr)
udev->transc_in[ep_num].ep_stall = 0U;

/* clear endpoint stall status */
USBD_EP_TX_STAT_SET(ep_num, EPTX_VALID);
USBD_EP_TX_STAT_SET(ep_num, EPTX_NAK);
}
} else {
/* don't change status of a disabled endpoint */
Expand All @@ -429,7 +432,7 @@ static void usbd_ep_stall_clear (usb_dev *udev, uint8_t ep_addr)
udev->transc_out[ep_num].ep_stall = 0U;

/* clear endpoint stall status */
USBD_EP_RX_STAT_SET(ep_num, EPRX_VALID);
USBD_EP_RX_STAT_SET(ep_num, EPRX_NAK);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,15 @@ void usbd_isr (void)
}
}

if (INTF_ERRIF & int_flag) {
udev->drv_handler->err(0xff);
udev->nerror++;
CLR(ERRIF);
}
if (INTF_WKUPIF & int_flag) {
/* clear wakeup interrupt flag in INTF */
CLR(WKUPIF);

/* restore the old cur_status */
udev->cur_status = udev->backup_status;
udev->nresume++;

#ifdef LPM_ENABLED
if ((0U == udev->pm.remote_wakeup_on) && (0U == udev->lpm.L1_resume)) {
Expand All @@ -187,6 +190,9 @@ void usbd_isr (void)
resume_mcu(udev);
}
#endif /* LPM_ENABLED */

/* clear wakeup interrupt flag in INTF */
CLR(WKUPIF);
}

if (INTF_SPSIF & int_flag) {
Expand Down Expand Up @@ -234,6 +240,7 @@ void usbd_isr (void)
CLR(RSTIF);

udev->drv_handler->ep_reset(udev);
udev->nreset++;
}

#ifdef LPM_ENABLED
Expand Down Expand Up @@ -261,8 +268,35 @@ void usbd_isr (void)
*/
static void usbd_int_suspend (usb_dev *udev)
{
/* store the device current status */
udev->backup_status = udev->cur_status;
/* store the device current status, but only if not already suspended */
/*
* During remote wakeup, the suspend interrupt can fire while already
* suspended, corrupting backup_status if this check isn't done.
*
* Details:
*
* usbd_remote_wakeup_active() calls resume_mcu(), which is a wrapper
* around usbd_leave_suspend(), which clears SETSPS. Clearing SETSPS
* re-enables ESOF detection, and also the SPSIF interrupt. ESOF
* detection and the SPSIF interrupt don't respect USB line states, so
* they can activate during a remote wakeup scenario. The remote wakeup
* process relies on this to count the 15ms duration for sending the
* remote wakeup signal upstream.
*
* The SPSIF handling code defers calling usbd_int_suspend() while
* RSREQ is set (during the remote wakeup signaling), but once that
* countdown is over, the suspend interrupt will fire again while
* the the upstream port is driving a resume signal downstream
* (typically for another 5ms). It might actually be necessary to
* call the suspend handler during remote wakeup, because WKUPIF
* detection might only work if SETSPS is set.
*/
if (udev->cur_status != USBD_SUSPENDED) {
udev->backup_status = udev->cur_status;
} else {
udev->nsuspsusp++;
}
udev->nsusp++;

/* set device in suspended state */
udev->cur_status = (uint8_t)USBD_SUSPENDED;
Expand Down

0 comments on commit 07821c4

Please sign in to comment.