From de202dd376ea3109e21f535554647689dda23c7b Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 28 Dec 2015 11:16:40 +0000 Subject: New USB API finalized, updated OTGv1, USBv1 not yet updated. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8653 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/OTGv1/usb_lld.c | 80 +++++++++++++++------------------- os/hal/ports/STM32/LLD/OTGv1/usb_lld.h | 2 - 2 files changed, 34 insertions(+), 48 deletions(-) (limited to 'os/hal/ports/STM32/LLD/OTGv1') diff --git a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c index a4a784d2a..e0d817d05 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c +++ b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c @@ -369,7 +369,6 @@ static void otg_epin_handler(USBDriver *usbp, usbep_t ep) { cover the remaining.*/ isp->txsize = isp->totsize - isp->txsize; isp->txcnt = 0; - usb_lld_prepare_transmit(usbp, ep); osalSysLockFromISR(); usb_lld_start_in(usbp, ep); osalSysUnlockFromISR(); @@ -415,13 +414,14 @@ static void otg_epout_handler(USBDriver *usbp, usbep_t ep) { /* Receive transfer complete.*/ USBOutEndpointState *osp = usbp->epc[ep]->out_state; - if (osp->rxsize < osp->totsize) { + /* A short packet always terminates a transaction.*/ + if (((osp->rxcnt % usbp->epc[ep]->out_maxsize) == 0) && + (osp->rxsize < osp->totsize)) { /* In case the transaction covered only part of the total transfer then another transaction is immediately started in order to cover the remaining.*/ osp->rxsize = osp->totsize - osp->rxsize; osp->rxcnt = 0; - usb_lld_prepare_receive(usbp, ep); osalSysLockFromISR(); usb_lld_start_out(usbp, ep); osalSysUnlockFromISR(); @@ -476,7 +476,6 @@ static void otg_isoc_in_failed_handler(USBDriver *usbp) { * * @notapi */ - static void otg_isoc_out_failed_handler(USBDriver *usbp) { usbep_t ep; stm32_otg_t *otgp = usbp->otg; @@ -1135,38 +1134,57 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { } /** - * @brief Prepares for a receive operation. + * @brief Starts a receive operation on an OUT endpoint. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * * @notapi */ -void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep) { - uint32_t pcnt; +void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { + uint32_t pcnt, rxsize; USBOutEndpointState *osp = usbp->epc[ep]->out_state; /* Transfer initialization.*/ osp->totsize = osp->rxsize; - if ((ep == 0) && (osp->rxsize > EP0_MAX_OUTSIZE)) + if ((ep == 0) && (osp->rxsize > EP0_MAX_OUTSIZE)) osp->rxsize = EP0_MAX_OUTSIZE; - pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1) / - usbp->epc[ep]->out_maxsize; + /* Transaction size is rounded to a multiple of packet size because the + following requirement in the RM: + "For OUT transfers, the transfer size field in the endpoint's transfer + size register must be a multiple of the maximum packet size of the + endpoint, adjusted to the Word boundary".*/ + pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1U) / + usbp->epc[ep]->out_maxsize; + rxsize = (pcnt * usbp->epc[ep]->out_maxsize + 3U) & 0xFFFFFFFCU; + + /*Setting up transaction parameters in DOEPTSIZ.*/ usbp->otg->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) | - DOEPTSIZ_XFRSIZ(osp->rxsize); + DOEPTSIZ_XFRSIZ(rxsize); + + /* Special case of isochronous endpoint.*/ + 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; + } + /* Starting operation.*/ + usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_EPENA | DOEPCTL_CNAK; } /** - * @brief Prepares for a transmit operation. + * @brief Starts a transmit operation on an IN endpoint. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * * @notapi */ -void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) { +void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { USBInEndpointState *isp = usbp->epc[ep]->in_state; /* Transfer initialization.*/ @@ -1176,7 +1194,7 @@ void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) { usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0); } else { - if ((ep == 0) && (isp->txsize > EP0_MAX_INSIZE)) + if ((ep == 0) && (isp->txsize > EP0_MAX_INSIZE)) isp->txsize = EP0_MAX_INSIZE; /* Normal case.*/ @@ -1186,39 +1204,8 @@ void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) { usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_MCNT(1) | DIEPTSIZ_PKTCNT(pcnt) | DIEPTSIZ_XFRSIZ(isp->txsize); } -} - -/** - * @brief Starts a receive operation on an OUT endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { - - 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; -} - -/** - * @brief Starts a transmit operation on an IN endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep endpoint number - * - * @notapi - */ -void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { + /* Special case of isochronous endpoint.*/ 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) @@ -1227,6 +1214,7 @@ void usb_lld_start_in(USBDriver *usbp, usbep_t ep) { usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SODDFRM; } + /* Starting operation.*/ usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK; usbp->otg->DIEPEMPMSK |= DIEPEMPMSK_INEPTXFEM(ep); } diff --git a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h index c90424c36..85038a9e2 100644 --- a/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h +++ b/os/hal/ports/STM32/LLD/OTGv1/usb_lld.h @@ -540,8 +540,6 @@ extern "C" { usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep); usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep); void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf); - void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep); - void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep); void usb_lld_start_out(USBDriver *usbp, usbep_t ep); void usb_lld_start_in(USBDriver *usbp, usbep_t ep); void usb_lld_stall_out(USBDriver *usbp, usbep_t ep); -- cgit v1.2.3