/** * @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 Prepares for a receive transaction on an OUT endpoint. * @post The endpoint is ready for @p usbStartReceiveI(). * @note This function can be called both in ISR and thread context. * * @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 * * @special */ void usbPrepareReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) { USBOutEndpointState *osp = usbp->epc[ep]->out_state; osp->rxqueued = false; osp->mode.linear.rxbuf = buf; osp->rxsize = n; osp->rxcnt = 0; usb_lld_prepare_receive(usbp, ep); }
/** * @brief Prepares for a receive transaction on an OUT endpoint. * @post The endpoint is ready for @p usbStartReceiveI(). * @note This function can be called both in ISR and thread context. * @note The queue must have enough free space to accommodate the * specified transaction size rounded to the next packet size * boundary. For example if the transaction size is 1 and the * packet size is 64 then the queue must have space for at least * 64 bytes. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * @param[in] iqp input queue to be filled with incoming data * @param[in] n transaction size * * @special */ void usbPrepareQueuedReceive(USBDriver *usbp, usbep_t ep, input_queue_t *iqp, size_t n) { USBOutEndpointState *osp = usbp->epc[ep]->out_state; osp->rxqueued = true; osp->mode.queue.rxqueue = iqp; osp->rxsize = n; osp->rxcnt = 0; usb_lld_prepare_receive(usbp, ep); }