/** * @brief Configures and activates the USB peripheral. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ void usb_lld_start(USBDriver *usbp) { if (usbp->state == USB_STOP) { /* Enables the peripheral.*/ #if AVR_USB_USE_USB1 == TRUE if (&USBD1 == usbp) { uint8_t i; /* * Workaround: disable pad drivers as first step in case bootloader left * it on. Otherwise VBUS detection interrupt will not trigger later. */ USBCON &= ~(1 << OTGPADE); /* Enable the internal 3.3V pad regulator */ UHWCON |= (1 << UVREGE); /* Reset and disable all endpoints */ UERST = 0x7f; UERST = 0; for (i = 0; i < USB_MAX_ENDPOINTS; ++i){ UENUM = i; UEIENX = 0; UEINTX = 0; UECFG1X = 0; UECONX &= ~(1 << EPEN); } } #endif /* Reset procedure enforced on driver start.*/ _usb_reset(usbp); } }
/** * @brief Configures and activates the USB peripheral. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ void usb_lld_start(USBDriver *usbp) { if (usbp->state == USB_STOP) { /* Clock activation.*/ #if STM32_USB_USE_USB1 if (&USBD1 == usbp) { /* USB clock enabled.*/ rccEnableUSB(FALSE); /* Powers up the transceiver while holding the USB in reset state.*/ STM32_USB->CNTR = CNTR_FRES; /* Enabling the USB IRQ vectors, this also gives enough time to allow the transceiver power up (1uS).*/ #if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER nvicEnableVector(STM32_USB1_HP_NUMBER, STM32_USB_USB1_HP_IRQ_PRIORITY); #endif nvicEnableVector(STM32_USB1_LP_NUMBER, STM32_USB_USB1_LP_IRQ_PRIORITY); /* Releases the USB reset.*/ STM32_USB->CNTR = 0; } #endif /* Reset procedure enforced on driver start.*/ _usb_reset(usbp); } /* Configuration.*/ }
/** * @brief Configures and activates the USB peripheral. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ void usb_lld_start(USBDriver *usbp) { if (usbp->state == USB_STOP) { /* Clock activation.*/ /* Reset procedure enforced on driver start.*/ _usb_reset(usbp); } /* Configuration.*/ }
/* * Handles the USB driver global events. */ static void usb_event(USBDriver *usbp, usbevent_t event) { extern SerialUSBDriver SDU2; switch (event) { case USB_EVENT_RESET: return; case USB_EVENT_ADDRESS: return; case USB_EVENT_CONFIGURED: chSysLockFromISR(); /* Enables the endpoints specified into the configuration. Note, this callback is invoked from an ISR so I-Class functions must be used.*/ usbInitEndpointI(usbp, USBD2_DATA_REQUEST_EP, &ep1config); usbInitEndpointI(usbp, USBD2_INTERRUPT_REQUEST_EP, &ep2config); /* Resetting the state of the CDC subsystem.*/ sduConfigureHookI(&SDU2); chSysUnlockFromISR(); return; case USB_EVENT_SUSPEND: if (usbp->state == USB_ACTIVE) { // USB cable unplugged chSysLockFromISR(); _usb_reset(usbp); // Reset queues and unlock waiting threads chIQResetI(&SDU2.iqueue); chOQResetI(&SDU2.oqueue); chSysUnlockFromISR(); } return; case USB_EVENT_WAKEUP: return; case USB_EVENT_STALLED: return; } return; }
/** * @brief OTG shared ISR. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ static void usb_lld_serve_interrupt(USBDriver *usbp) { stm32_otg_t *otgp = usbp->otg; uint32_t sts, src; sts = otgp->GINTSTS & otgp->GINTMSK; otgp->GINTSTS = sts; /* Reset interrupt handling.*/ if (sts & GINTSTS_USBRST) { _usb_reset(usbp); _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET); } /* Enumeration done.*/ if (sts & GINTSTS_ENUMDNE) { (void)otgp->DSTS; } /* SOF interrupt handling.*/ if (sts & GINTSTS_SOF) { _usb_isr_invoke_sof_cb(usbp); } /* RX FIFO not empty handling.*/ if (sts & GINTSTS_RXFLVL) { /* The interrupt is masked while the thread has control or it would be triggered again.*/ chSysLockFromIsr(); otgp->GINTMSK &= ~GINTMSK_RXFLVLM; usb_lld_wakeup_pump(usbp); chSysUnlockFromIsr(); } /* IN/OUT endpoints event handling.*/ src = otgp->DAINT; if (sts & GINTSTS_IEPINT) { if (src & (1 << 0)) otg_epin_handler(usbp, 0); if (src & (1 << 1)) otg_epin_handler(usbp, 1); if (src & (1 << 2)) otg_epin_handler(usbp, 2); if (src & (1 << 3)) otg_epin_handler(usbp, 3); #if STM32_USB_USE_OTG2 if (src & (1 << 4)) otg_epin_handler(usbp, 4); if (src & (1 << 5)) otg_epin_handler(usbp, 5); #endif } if (sts & GINTSTS_OEPINT) { if (src & (1 << 16)) otg_epout_handler(usbp, 0); if (src & (1 << 17)) otg_epout_handler(usbp, 1); if (src & (1 << 18)) otg_epout_handler(usbp, 2); if (src & (1 << 19)) otg_epout_handler(usbp, 3); #if STM32_USB_USE_OTG2 if (src & (1 << 20)) otg_epout_handler(usbp, 4); if (src & (1 << 21)) otg_epout_handler(usbp, 5); #endif } }