/** * @brief Default data transmitted callback. * @details The application must use this function as callback for the IN * data endpoint. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number */ void sduDataTransmitted(USBDriver *usbp, usbep_t ep) { size_t n; SerialUSBDriver *sdup = usbp->param; (void)ep; chSysLockFromIsr(); chnAddFlagsI(sdup, CHN_OUTPUT_EMPTY); if ((n = chOQGetFullI(&sdup->oqueue)) > 0) { /* The endpoint cannot be busy, we are in the context of the callback, so it is safe to transmit without a check.*/ chSysUnlockFromIsr(); usbPrepareQueuedTransmit(usbp, ep, &sdup->oqueue, n); chSysLockFromIsr(); usbStartTransmitI(usbp, ep); } else if (!(usbp->epc[ep]->in_state->txsize & (usbp->epc[ep]->in_maxsize - 1))) { /* Transmit zero sized packet in case the last one has maximum allowed size. Otherwise the recipient may expect more data coming soon and not return buffered data to app. See section 5.8.3 Bulk Transfer Packet Size Constraints of the USB Specification document.*/ chSysUnlockFromIsr(); usbPrepareQueuedTransmit(usbp, ep, &sdup->oqueue, 0); chSysLockFromIsr(); usbStartTransmitI(usbp, ep); } chSysUnlockFromIsr(); }
/** * @brief Notification of data inserted into the output queue. * * @param[in] qp the queue pointer. */ static void onotify(io_queue_t *qp) { size_t n; SerialUSBDriver *sdup = qGetLink(qp); /* If the USB driver is not in the appropriate state then transactions must not be started.*/ if ((usbGetDriverStateI(sdup->config->usbp) != USB_ACTIVE) || (sdup->state != SDU_READY)) { return; } /* If there is not an ongoing transaction and the output queue contains data then a new transaction is started.*/ if (!usbGetTransmitStatusI(sdup->config->usbp, sdup->config->bulk_in)) { if ((n = oqGetFullI(&sdup->oqueue)) > 0U) { osalSysUnlock(); usbPrepareQueuedTransmit(sdup->config->usbp, sdup->config->bulk_in, &sdup->oqueue, n); osalSysLock(); (void) usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in); } } }
/** * @brief Default data transmitted callback. * @details The application must use this function as callback for the IN * data endpoint. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number */ void hidDebugDataTransmitted(USBDriver *usbp, usbep_t ep) { HIDDebugDriver *hiddp = usbp->in_params[ep - 1U]; size_t n; if(hiddp == NULL) { return; } osalSysLockFromISR(); /* rearm the flush timer */ chVTSetI(&hid_debug_flush_timer, MS2ST(DEBUG_TX_FLUSH_MS), hid_debug_flush_cb, hiddp); /* see if we've transmitted everything */ if((n = oqGetFullI(&hiddp->oqueue)) == 0) { chnAddFlagsI(hiddp, CHN_OUTPUT_EMPTY); } /* Check if there's enough data in the queue to send again */ if(n >= DEBUG_TX_SIZE) { /* The endpoint cannot be busy, we are in the context of the callback, * so it is safe to transmit without a check.*/ osalSysUnlockFromISR(); usbPrepareQueuedTransmit(usbp, ep, &hiddp->oqueue, DEBUG_TX_SIZE); osalSysLockFromISR(); (void)usbStartTransmitI(usbp, ep); } osalSysUnlockFromISR(); }
/** * @brief Notification of data inserted into the output queue. * * @param[in] qp the queue pointer. */ static void onotify(io_queue_t *qp) { size_t n; HIDDebugDriver *hiddp = qGetLink(qp); /* If the USB driver is not in the appropriate state then transactions * must not be started.*/ if((usbGetDriverStateI(hiddp->config->usbp) != USB_ACTIVE) || (hiddp->state != HIDDEBUG_READY)) { return; } /* If there is not an ongoing transaction and the output queue contains * enough data then a new transaction is started.*/ if(!usbGetTransmitStatusI(hiddp->config->usbp, hiddp->config->ep_in)) { if((n = oqGetFullI(&hiddp->oqueue)) >= DEBUG_TX_SIZE) { osalSysUnlock(); usbPrepareQueuedTransmit(hiddp->config->usbp, hiddp->config->ep_in, &hiddp->oqueue, DEBUG_TX_SIZE); osalSysLock(); (void)usbStartTransmitI(hiddp->config->usbp, hiddp->config->ep_in); } } }
/** * @brief Default data transmitted callback. * @details The application must use this function as callback for the IN * data endpoint. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number */ void sduDataTransmitted(USBDriver *usbp, usbep_t ep) { size_t n; SerialUSBDriver *sdup = usbp->in_params[ep - 1U]; if (sdup == NULL) { return; } osalSysLockFromISR(); chnAddFlagsI(sdup, CHN_OUTPUT_EMPTY); /*lint -save -e9013 [15.7] There is no else because it is not needed.*/ if ((n = oqGetFullI(&sdup->oqueue)) > 0U) { /* The endpoint cannot be busy, we are in the context of the callback, so it is safe to transmit without a check.*/ osalSysUnlockFromISR(); usbPrepareQueuedTransmit(usbp, ep, &sdup->oqueue, n); osalSysLockFromISR(); (void) usbStartTransmitI(usbp, ep); } else if ((usbp->epc[ep]->in_state->txsize > 0U) && ((usbp->epc[ep]->in_state->txsize & ((size_t)usbp->epc[ep]->in_maxsize - 1U)) == 0U)) { /* Transmit zero sized packet in case the last one has maximum allowed size. Otherwise the recipient may expect more data coming soon and not return buffered data to app. See section 5.8.3 Bulk Transfer Packet Size Constraints of the USB Specification document.*/ osalSysUnlockFromISR(); usbPrepareQueuedTransmit(usbp, ep, &sdup->oqueue, 0); osalSysLockFromISR(); (void) usbStartTransmitI(usbp, ep); } /*lint -restore*/ osalSysUnlockFromISR(); }
/** * @brief Notification of data inserted into the output queue. */ static void onotify(GenericQueue *qp) { size_t n; SerialUSBDriver *sdup = chQGetLink(qp); /* If the USB driver is not in the appropriate state then transactions must not be started.*/ if (usbGetDriverStateI(sdup->config->usbp) != USB_ACTIVE) return; /* If there is not an ongoing transaction and the output queue contains data then a new transaction is started.*/ if (!usbGetTransmitStatusI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP) && ((n = chOQGetFullI(&sdup->oqueue)) > 0)) { chSysUnlock(); usbPrepareQueuedTransmit(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP, &sdup->oqueue, n); chSysLock(); usbStartTransmitI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP); } }
/** * @brief Notification of data inserted into the output queue. */ static void onotify(GenericQueue *qp) { size_t n; BulkUSBDriver *bdup = chQGetLink(qp); /* If the USB driver is not in the appropriate state then transactions must not be started.*/ if ((usbGetDriverStateI(bdup->config->usbp) != USB_ACTIVE) || (bdup->state != BDU_READY)) return; /* If there is not an ongoing transaction and the output queue contains data then a new transaction is started.*/ if (!usbGetTransmitStatusI(bdup->config->usbp, bdup->config->bulk_in) && ((n = chOQGetFullI(&bdup->oqueue)) > 0)) { chSysUnlock(); usbPrepareQueuedTransmit(bdup->config->usbp, bdup->config->bulk_in, &bdup->oqueue, n); chSysLock(); usbStartTransmitI(bdup->config->usbp, bdup->config->bulk_in); } }