diff options
Diffstat (limited to 'os/hal')
| -rw-r--r-- | os/hal/ports/STM32/LLD/OTGv1/usb_lld.c | 35 | ||||
| -rw-r--r-- | os/hal/src/usb.c | 19 | 
2 files changed, 41 insertions, 13 deletions
diff --git a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c index 00ada1203..a4a784d2a 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c @@ -511,6 +511,19 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) {    sts &= otgp->GINTMSK;
    otgp->GINTSTS = sts;
 +  /* Reset interrupt handling.*/
 +  if (sts & GINTSTS_USBRST) {
 +
 +    /* Resetting pending operations.*/
 +    usbp->txpending = 0;
 +
 +    /* Default reset action.*/
 +    _usb_reset(usbp);
 +
 +    /* Preventing execution of more handlers, the core has been reset.*/
 +    return;
 +  }
 +
    /* Wake-up handling.*/
    if (sts & GINTSTS_WKUPINT) {
      /* If clocks are gated off, turn them back on (may be the case if
 @@ -529,13 +542,11 @@ static void usb_lld_serve_interrupt(USBDriver *usbp) {    /* Suspend handling.*/
    if (sts & GINTSTS_USBSUSP) {
 -    _usb_suspend(usbp);
 -  }
 -
 -  /* Reset interrupt handling.*/
 -  if (sts & GINTSTS_USBRST) {
 +    /* Resetting pending operations.*/
 +    usbp->txpending = 0;
 -    _usb_reset(usbp);
 +    /* Default suspend action.*/
 +    _usb_suspend(usbp);
    }
    /* Enumeration done.*/
 @@ -920,18 +931,18 @@ void usb_lld_reset(USBDriver *usbp) {    /* Flush the Tx FIFO.*/
    otg_txfifo_flush(usbp, 0);
 +  /* Endpoint interrupts all disabled and cleared.*/
 +  otgp->DIEPEMPMSK = 0;
 +  otgp->DAINTMSK   = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0);
 +
    /* All endpoints in NAK mode, interrupts cleared.*/
    for (i = 0; i <= usbp->otgparams->num_endpoints; i++) {
      otgp->ie[i].DIEPCTL = DIEPCTL_SNAK;
      otgp->oe[i].DOEPCTL = DOEPCTL_SNAK;
 -    otgp->ie[i].DIEPINT = 0xFF;
 -    otgp->oe[i].DOEPINT = 0xFF;
 +    otgp->ie[i].DIEPINT = 0xFFFFFFFF;
 +    otgp->oe[i].DOEPINT = 0xFFFFFFFF;
    }
 -  /* Endpoint interrupts all disabled and cleared.*/
 -  otgp->DAINT = 0xFFFFFFFF;
 -  otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0);
 -
    /* Resets the FIFO memory allocator.*/
    otg_ram_reset(usbp);
 diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c index 2075cd7a2..b6813c381 100644 --- a/os/hal/src/usb.c +++ b/os/hal/src/usb.c @@ -380,6 +380,19 @@ void usbDisableEndpointsI(USBDriver *usbp) {    usbp->transmitting &= ~1U;
    usbp->receiving    &= ~1U;
    for (i = 1; i <= (unsigned)USB_MAX_ENDPOINTS; i++) {
 +#if USB_USE_WAIT == TRUE
 +    /* Signaling the event to threads waiting on endpoints.*/
 +    if (usbp->epc[i] != NULL) {
 +      osalSysLockFromISR();
 +      if (usbp->epc[i]->in_state != NULL) {
 +        osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET);
 +      }
 +      if (usbp->epc[i]->out_state != NULL) {
 +        osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET);
 +      }
 +      osalSysUnlockFromISR();
 +    }
 +#endif
      usbp->epc[i] = NULL;
    }
 @@ -638,12 +651,14 @@ void _usb_reset(USBDriver *usbp) {  #if USB_USE_WAIT == TRUE
      /* Signaling the event to threads waiting on endpoints.*/
      if (usbp->epc[i] != NULL) {
 +      osalSysLockFromISR();
        if (usbp->epc[i]->in_state != NULL) {
          osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET);
        }
        if (usbp->epc[i]->out_state != NULL) {
          osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET);
        }
 +      osalSysUnlockFromISR();
      }
  #endif
      usbp->epc[i] = NULL;
 @@ -671,7 +686,7 @@ void _usb_reset(USBDriver *usbp) {  void _usb_suspend(USBDriver *usbp) {
    /* State transition.*/
 -  usbp->state         = USB_SUSPENDED;
 +  usbp->state = USB_SUSPENDED;
    /* Notification of suspend event.*/
    _usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND);
 @@ -683,12 +698,14 @@ void _usb_suspend(USBDriver *usbp) {      for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) {
        if (usbp->epc[i] != NULL) {
 +        osalSysLockFromISR();
          if (usbp->epc[i]->in_state != NULL) {
            osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_TIMEOUT);
          }
          if (usbp->epc[i]->out_state != NULL) {
            osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_TIMEOUT);
          }
 +        osalSysUnlockFromISR();
        }
      }
    }
  | 
