Ejemplo n.º 1
0
/**
 * @brief   Starts a receive transaction on an OUT endpoint.
 * @note    This function is meant to be called from ISR context outside
 *          critical zones because there is a potentially slow operation
 *          inside.
 *
 * @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. It is recommended a multiple of
 *                      the packet size because the excess is discarded.
 *
 * @iclass
 */
void usbStartReceiveI(USBDriver *usbp, usbep_t ep,
                      uint8_t *buf, size_t n) {
  USBOutEndpointState *osp;

  osalDbgCheckClassI();
  osalDbgCheck((usbp != NULL) && (ep <= (usbep_t)USB_MAX_ENDPOINTS));
  osalDbgAssert(!usbGetReceiveStatusI(usbp, ep), "already receiving");

  /* Marking the endpoint as active.*/
  usbp->receiving |= (uint16_t)((unsigned)1U << (unsigned)ep);

  /* Setting up the transfer.*/
  /*lint -save -e661 [18.1] pclint is confused by the check on ep.*/
  osp = usbp->epc[ep]->out_state;
  /*lint -restore*/
  osp->rxbuf  = buf;
  osp->rxsize = n;
  osp->rxcnt  = 0;
#if USB_USE_WAIT == TRUE
  osp->thread = NULL;
#endif

  /* Starting transfer.*/
  usb_lld_start_out(usbp, ep);
}
/**
 * @brief   Notification of data removed from the input queue.
 *
 * @param[in] qp        the queue pointer.
 */
static void inotify(io_queue_t *qp) {
  size_t n, maxsize;
  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 in the queue enough space to hold at least one packet and
     a transaction is not yet started then a new transaction is started for
     the available space.*/
  maxsize = sdup->config->usbp->epc[sdup->config->bulk_out]->out_maxsize;
  if (!usbGetReceiveStatusI(sdup->config->usbp, sdup->config->bulk_out)) {
    if ((n = iqGetEmptyI(&sdup->iqueue)) >= maxsize) {
      osalSysUnlock();

      n = (n / maxsize) * maxsize;
      usbPrepareQueuedReceive(sdup->config->usbp,
                              sdup->config->bulk_out,
                              &sdup->iqueue, n);

      osalSysLock();
      (void) usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out);
    }
  }
}
Ejemplo n.º 3
0
/**
 * @brief   Notification of data removed from the input queue.
 */
static void inotify(GenericQueue *qp) {
  size_t n, maxsize;
  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 in the queue enough space to hold at least one packet and
     a transaction is not yet started then a new transaction is started for
     the available space.*/
  maxsize = bdup->config->usbp->epc[bdup->config->bulk_out]->out_maxsize;
  if (!usbGetReceiveStatusI(bdup->config->usbp, bdup->config->bulk_out) &&
      ((n = chIQGetEmptyI(&bdup->iqueue)) >= maxsize)) {
    chSysUnlock();

    n = (n / maxsize) * maxsize;
    usbPrepareQueuedReceive(bdup->config->usbp,
                            bdup->config->bulk_out,
                            &bdup->iqueue, n);

    chSysLock();
    usbStartReceiveI(bdup->config->usbp, bdup->config->bulk_out);
  }
}
Ejemplo n.º 4
0
/**
 * @brief   Notification of data removed from the input queue.
 */
static void inotify(GenericQueue *qp) {
  size_t n, maxsize;
  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 in the queue enough space to hold at least one packet and
     a transaction is not yet started then a new transaction is started for
     the available space.*/
  maxsize = sdup->config->usbp->epc[USB_CDC_DATA_AVAILABLE_EP]->out_maxsize;
  if (!usbGetReceiveStatusI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP) &&
      ((n = chIQGetEmptyI(&sdup->iqueue)) >= maxsize)) {
    chSysUnlock();

    n = (n / maxsize) * maxsize;
    usbPrepareQueuedReceive(sdup->config->usbp,
                            USB_CDC_DATA_AVAILABLE_EP,
                            &sdup->iqueue, n);

    chSysLock();
    usbStartReceiveI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP);
  }
}
Ejemplo n.º 5
0
/**
 * @brief   Stalls an OUT endpoint.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 * @param[in] ep        endpoint number
 *
 * @return              The operation status.
 * @retval false        Endpoint stalled.
 * @retval true         Endpoint busy, not stalled.
 *
 * @iclass
 */
bool usbStallReceiveI(USBDriver *usbp, usbep_t ep) {

  osalDbgCheckClassI();
  osalDbgCheck(usbp != NULL);

  if (usbGetReceiveStatusI(usbp, ep))
    return true;

  usb_lld_stall_out(usbp, ep);
  return false;
}
Ejemplo n.º 6
0
/**
 * @brief   Stalls an OUT endpoint.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 * @param[in] ep        endpoint number
 *
 * @return              The operation status.
 * @retval FALSE        Endpoint stalled.
 * @retval TRUE         Endpoint busy, not stalled.
 *
 * @iclass
 */
bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {

  chDbgCheckClassI();
  chDbgCheck(usbp != NULL, "usbStallReceiveI");

  if (usbGetReceiveStatusI(usbp, ep))
    return TRUE;

  usb_lld_stall_out(usbp, ep);
  return FALSE;
}
Ejemplo n.º 7
0
/**
 * @brief   Starts a receive transaction on an OUT endpoint.
 * @post    The endpoint callback is invoked when the transfer has been
 *          completed.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 * @param[in] ep        endpoint number
 *
 * @return              The operation status.
 * @retval FALSE        Operation started successfully.
 * @retval TRUE         Endpoint busy, operation not started.
 *
 * @iclass
 */
bool usbStartReceiveI(USBDriver *usbp, usbep_t ep) {

  osalDbgCheckClassI();
  osalDbgCheck(usbp != NULL);

  if (usbGetReceiveStatusI(usbp, ep))
    return TRUE;

  usbp->receiving |= (1 << ep);
  usb_lld_start_out(usbp, ep);
  return FALSE;
}
Ejemplo n.º 8
0
/**
 * @brief   Starts a receive transaction on an OUT endpoint.
 * @post    The endpoint callback is invoked when the transfer has been
 *          completed.
 *
 * @param[in] usbp      pointer to the @p USBDriver object
 * @param[in] ep        endpoint number
 *
 * @return              The operation status.
 * @retval false        Operation started successfully.
 * @retval true         Endpoint busy, operation not started.
 *
 * @iclass
 */
bool usbStartReceiveI(USBDriver *usbp, usbep_t ep) {

  osalDbgCheckClassI();
  osalDbgCheck(usbp != NULL);

  if (usbGetReceiveStatusI(usbp, ep)) {
    return true;
  }

  usbp->receiving |= (uint16_t)((unsigned)1U << (unsigned)ep);
  usb_lld_start_out(usbp, ep);
  return false;
}
Ejemplo n.º 9
0
/**
 * @brief   Notification of empty buffer released into the input buffers queue.
 *
 * @param[in] bqp       the buffers queue pointer.
 */
static void ibnotify(io_buffers_queue_t *bqp) {
  SerialUSBDriver *sdup = bqGetLinkX(bqp);

  /* 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;
  }

  /* Checking if there is already a transaction ongoing on the endpoint.*/
  if (!usbGetReceiveStatusI(sdup->config->usbp, sdup->config->bulk_out)) {
    /* Trying to get a free buffer.*/
    uint8_t *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);
    }
  }
}