Created
August 8, 2015 11:45
-
-
Save ObKo/a08174a1a2446ea6a208 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -Naur ChibiOS-svn/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h ChibiOS-iso/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h | |
--- ChibiOS-svn/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h 2015-07-15 20:18:40.000000000 +0600 | |
+++ ChibiOS-iso/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h 2015-07-31 16:08:43.768582531 +0600 | |
@@ -671,6 +671,8 @@ | |
SOF mask. */ | |
#define DSTS_FNSOF(n) ((n)<<8) /**< Frame number of the received | |
SOF value. */ | |
+#define DSTS_FNSOF_ODD (1U<<8) /**< Frame parity of the received | |
+ SOF value. */ | |
#define DSTS_EERR (1U<<3) /**< Erratic error. */ | |
#define DSTS_ENUMSPD_MASK (3U<<1) /**< Enumerated speed mask. */ | |
#define DSTS_ENUMSPD_FS_48 (3U<<1) /**< Full speed (PHY clock is | |
diff -Naur ChibiOS-svn/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c ChibiOS-iso/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c | |
--- ChibiOS-svn/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c 2015-07-15 20:18:40.000000000 +0600 | |
+++ ChibiOS-iso/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c 2015-08-07 14:40:19.698220001 +0600 | |
@@ -614,6 +614,69 @@ | |
} | |
/** | |
+ * @brief Isochronous IN transfer failed handler. | |
+ * | |
+ * @param[in] usbp pointer to the @p USBDriver object | |
+ * | |
+ * @notapi | |
+ */ | |
+static void otg_isoc_in_failed_handler(USBDriver *usbp) { | |
+ usbep_t ep; | |
+ stm32_otg_t *otgp = usbp->otg; | |
+ | |
+ for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) { | |
+ if (((otgp->ie[ep].DIEPCTL & DIEPCTL_EPTYP_MASK) == DIEPCTL_EPTYP_ISO) && | |
+ ((otgp->ie[ep].DIEPCTL & DIEPCTL_EPENA) != 0)) { | |
+ /* Endpoint enabled -> ISOC IN transfer failed */ | |
+ /* Disable endpoint */ | |
+ otgp->ie[ep].DIEPCTL |= (DIEPCTL_EPDIS | DIEPCTL_SNAK); | |
+ while (otgp->ie[ep].DIEPCTL & DIEPCTL_EPENA) | |
+ ; | |
+ | |
+ /* Flush FIFO */ | |
+ otg_txfifo_flush(usbp, ep); | |
+ | |
+ /* Prepare data for next frame */ | |
+ _usb_isr_invoke_in_cb(usbp, ep); | |
+ | |
+ /* Pump out data for next frame */ | |
+ osalSysLockFromISR(); | |
+ otgp->DIEPEMPMSK &= ~(1 << ep); | |
+ usbp->txpending |= (1 << ep); | |
+ osalThreadResumeI(&usbp->wait, MSG_OK); | |
+ osalSysUnlockFromISR(); | |
+ } | |
+ } | |
+} | |
+ | |
+/** | |
+ * @brief Isochronous OUT transfer failed handler. | |
+ * | |
+ * @param[in] usbp pointer to the @p USBDriver object | |
+ * | |
+ * @notapi | |
+ */ | |
+ | |
+static void otg_isoc_out_failed_handler(USBDriver *usbp) { | |
+ usbep_t ep; | |
+ stm32_otg_t *otgp = usbp->otg; | |
+ | |
+ for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) { | |
+ if (((otgp->oe[ep].DOEPCTL & DOEPCTL_EPTYP_MASK) == DOEPCTL_EPTYP_ISO) && | |
+ ((otgp->oe[ep].DOEPCTL & DOEPCTL_EPENA) != 0)) { | |
+ /* Endpoint enabled -> ISOC OUT transfer failed */ | |
+ /* Disable endpoint */ | |
+ /* FIXME: Core stucks here */ | |
+ /*otgp->oe[ep].DOEPCTL |= (DOEPCTL_EPDIS | DOEPCTL_SNAK); | |
+ while (otgp->oe[ep].DOEPCTL & DOEPCTL_EPENA) | |
+ ;*/ | |
+ /* Prepare transfer for next frame */ | |
+ _usb_isr_invoke_out_cb(usbp, ep); | |
+ } | |
+ } | |
+} | |
+ | |
+/** | |
* @brief OTG shared ISR. | |
* | |
* @param[in] usbp pointer to the @p USBDriver object | |
@@ -644,6 +707,16 @@ | |
_usb_isr_invoke_sof_cb(usbp); | |
} | |
+ /* Isochronous IN failed handling */ | |
+ if (sts & GINTSTS_IISOIXFR) { | |
+ otg_isoc_in_failed_handler(usbp); | |
+ } | |
+ | |
+ /* Isochronous OUT failed handling */ | |
+ if (sts & GINTSTS_IISOOXFR) { | |
+ otg_isoc_out_failed_handler(usbp); | |
+ } | |
+ | |
/* RX FIFO not empty handling.*/ | |
if (sts & GINTSTS_RXFLVL) { | |
/* The interrupt is masked while the thread has control or it would | |
@@ -868,12 +941,16 @@ | |
otgp->DIEPMSK = 0; | |
otgp->DOEPMSK = 0; | |
otgp->DAINTMSK = 0; | |
+ | |
if (usbp->config->sof_cb == NULL) | |
otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM /*| GINTMSK_USBSUSPM | | |
- GINTMSK_ESUSPM |*/; | |
+ GINTMSK_ESUSPM */ | GINTMSK_IISOIXFRM | | |
+ GINTMSK_IISOOXFRM; | |
else | |
otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM /*| GINTMSK_USBSUSPM | | |
- GINTMSK_ESUSPM */ | GINTMSK_SOFM; | |
+ GINTMSK_ESUSPM */ | GINTMSK_IISOIXFRM | | |
+ GINTMSK_IISOOXFRM | GINTMSK_SOFM; | |
+ | |
otgp->GINTSTS = 0xFFFFFFFF; /* Clears all pending IRQs, if any. */ | |
#if defined(_CHIBIOS_RT_) | |
@@ -1196,7 +1273,9 @@ | |
/* Normal case.*/ | |
uint32_t pcnt = (isp->txsize + usbp->epc[ep]->in_maxsize - 1) / | |
usbp->epc[ep]->in_maxsize; | |
- usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(pcnt) | | |
+ /* DIEPTSIZ_MCNT is for isochronous IN transfers */ | |
+ /* TODO: Support more than one packet per frame for isochronous transfers */ | |
+ usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_MCNT(1) | DIEPTSIZ_PKTCNT(pcnt) | | |
DIEPTSIZ_XFRSIZ(isp->txsize); | |
} | |
} | |
@@ -1210,8 +1289,15 @@ | |
* @notapi | |
*/ | |
void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { | |
- | |
- usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_CNAK; | |
+ if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) { | |
+ /* Odd/even bit toggling for isochronous endpoint */ | |
+ if (usbp->otg->DSTS & DSTS_FNSOF_ODD) | |
+ usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SEVNFRM; | |
+ else | |
+ usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SODDFRM; | |
+ } | |
+ | |
+ usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_EPENA | DOEPCTL_CNAK; | |
} | |
/** | |
@@ -1223,7 +1309,14 @@ | |
* @notapi | |
*/ | |
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { | |
- | |
+ if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) { | |
+ /* Odd/even bit toggling */ | |
+ if (usbp->otg->DSTS & DSTS_FNSOF_ODD) | |
+ usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SEVNFRM; | |
+ else | |
+ usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SODDFRM; | |
+ } | |
+ | |
usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK; | |
usbp->otg->DIEPEMPMSK |= DIEPEMPMSK_INEPTXFEM(ep); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi. Is this working well? And maybe somehow related to your KDAC project?