Пример #1
0
/**
 * @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);
    }
  }
}
Пример #2
0
/**
 * @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);
}
Пример #3
0
/**
 * @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);
}