/** * @brief Generic endpoint OUT handler. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * * @notapi */ static void otg_epout_handler(USBDriver *usbp, usbep_t ep) { stm32_otg_t *otgp = usbp->otg; uint32_t epint = otgp->oe[ep].DOEPINT; /* Resets all EP IRQ sources.*/ otgp->oe[ep].DOEPINT = epint; if ((epint & DOEPINT_STUP) && (otgp->DOEPMSK & DOEPMSK_STUPM)) { /* Setup packets handling, setup packets are handled using a specific callback.*/ _usb_isr_invoke_setup_cb(usbp, ep); } if ((epint & DOEPINT_XFRC) && (otgp->DOEPMSK & DOEPMSK_XFRCM)) { /* Receive transfer complete.*/ USBOutEndpointState *osp = usbp->epc[ep]->out_state; if (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); chSysLockFromIsr(); usb_lld_start_out(usbp, ep); chSysUnlockFromIsr(); } else { /* End on OUT transfer.*/ _usb_isr_invoke_out_cb(usbp, ep); } } }
/** * @brief Starts a receive transaction on an OUT endpoint. * @note This function is meant to be called from ISR context outside * critical zones because there is a potentially slow operation * inside. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * @param[out] buf buffer where to copy the received data * @param[in] n transaction size. It is recommended a multiple of * the packet size because the excess is discarded. * * @iclass */ void usbStartReceiveI(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) { USBOutEndpointState *osp; osalDbgCheckClassI(); osalDbgCheck((usbp != NULL) && (ep <= (usbep_t)USB_MAX_ENDPOINTS)); osalDbgAssert(!usbGetReceiveStatusI(usbp, ep), "already receiving"); /* Marking the endpoint as active.*/ usbp->receiving |= (uint16_t)((unsigned)1U << (unsigned)ep); /* Setting up the transfer.*/ /*lint -save -e661 [18.1] pclint is confused by the check on ep.*/ osp = usbp->epc[ep]->out_state; /*lint -restore*/ osp->rxbuf = buf; osp->rxsize = n; osp->rxcnt = 0; #if USB_USE_WAIT == TRUE osp->thread = NULL; #endif /* Starting transfer.*/ usb_lld_start_out(usbp, ep); }
/** * @brief Starts a receive transaction on an OUT endpoint. * @post The endpoint callback is invoked when the transfer has been * completed. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * * @return The operation status. * @retval false Operation started successfully. * @retval true Endpoint busy, operation not started. * * @iclass */ bool usbStartReceiveI(USBDriver *usbp, usbep_t ep) { osalDbgCheckClassI(); osalDbgCheck(usbp != NULL); if (usbGetReceiveStatusI(usbp, ep)) return true; usbp->receiving |= (1 << ep); usb_lld_start_out(usbp, ep); return false; }
/** * @brief Starts a receive transaction on an OUT endpoint. * @post The endpoint callback is invoked when the transfer has been * completed. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * * @return The operation status. * @retval FALSE Operation started successfully. * @retval TRUE Endpoint busy, operation not started. * * @iclass */ bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep) { chDbgCheckClassI(); chDbgCheck(usbp != NULL, "usbStartReceiveI"); if (usbGetReceiveStatusI(usbp, ep)) return TRUE; usbp->receiving |= (1 << ep); usb_lld_start_out(usbp, ep); return FALSE; }
/** * @brief Starts a receive transaction on an OUT endpoint. * @post The endpoint callback is invoked when the transfer has been * completed. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * * @return The operation status. * @retval false Operation started successfully. * @retval true Endpoint busy, operation not started. * * @iclass */ bool usbStartReceiveI(USBDriver *usbp, usbep_t ep) { osalDbgCheckClassI(); osalDbgCheck(usbp != NULL); if (usbGetReceiveStatusI(usbp, ep)) { return true; } usbp->receiving |= (uint16_t)((unsigned)1U << (unsigned)ep); usb_lld_start_out(usbp, ep); return false; }