Example #1
0
/**
 * @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();
}
Example #2
0
/**
 * @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");
  }
}