/** * @brief Default data received callback. * @details The application must use this function as callback for the OUT * data endpoint. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep OUT endpoint number */ void sduDataReceived(USBDriver *usbp, usbep_t ep) { uint8_t *buf; SerialUSBDriver *sdup = usbp->out_params[ep - 1U]; if (sdup == NULL) { return; } osalSysLockFromISR(); /* Signaling that data is available in the input queue.*/ chnAddFlagsI(sdup, CHN_INPUT_AVAILABLE); /* Posting the filled buffer in the queue.*/ ibqPostFullBufferI(&sdup->ibqueue, usbGetReceiveTransactionSizeX(sdup->config->usbp, sdup->config->bulk_out)); /* The endpoint cannot be busy, we are in the context of the callback, so a packet is in the buffer for sure. Trying to get a free buffer for the next transaction.*/ buf = ibqGetEmptyBufferI(&sdup->ibqueue); if (buf != NULL) { /* Buffer found, starting a new transaction.*/ usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out, buf, SERIAL_USB_BUFFERS_SIZE); } osalSysUnlockFromISR(); }
/** * @brief Default EP0 OUT callback. * @details This function is used by the low level driver as default handler * for EP0 OUT events. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number, always zero * * @notapi */ void _usb_ep0out(USBDriver *usbp, usbep_t ep) { (void)ep; switch (usbp->ep0state) { case USB_EP0_RX: /* Receive phase over, sending the zero sized status packet.*/ usbp->ep0state = USB_EP0_SENDING_STS; #if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) osalSysLockFromISR(); usbStartTransmitI(usbp, 0, NULL, 0); osalSysUnlockFromISR(); #else usb_lld_end_setup(usbp, ep); #endif return; case USB_EP0_WAITING_STS: /* Status packet received, it must be zero sized, invoking the callback if defined.*/ #if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) if (usbGetReceiveTransactionSizeX(usbp, 0) != 0U) { break; } #endif if (usbp->ep0endcb != NULL) { usbp->ep0endcb(usbp); } usbp->ep0state = USB_EP0_WAITING_SETUP; return; case USB_EP0_WAITING_SETUP: case USB_EP0_TX: case USB_EP0_WAITING_TX0: case USB_EP0_SENDING_STS: /* All the above are invalid states in the IN phase.*/ osalDbgAssert(false, "EP0 state machine error"); /* Falling through is intentional.*/ case USB_EP0_ERROR: /* Error response, the state machine goes into an error state, the low level layer will have to reset it to USB_EP0_WAITING_SETUP after receiving a SETUP packet.*/ usb_lld_stall_in(usbp, 0); usb_lld_stall_out(usbp, 0); _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED); usbp->ep0state = USB_EP0_ERROR; return; default: osalDbgAssert(false, "EP0 state machine invalid state"); } }