/***************************************************************************//**
 * @brief       Handle Endpoint 2 OUT transfer interrupt
 * @note        This function takes no parameters, but it uses the EP2OUT status
 *              variables stored in @ref myUsbDevice.ep2out.
 ******************************************************************************/
void handleUsbOut2Int(void)
{
  uint8_t count;

  USB_Status_TypeDef status;
  bool xferComplete = false;

  USB_SetIndex(2);

  if (USB_EpnOutGetSentStall())
  {
    USB_EpnOutClearSentStall();
  }
  else if (USB_EpnGetOutPacketReady())
  {
    count = USB_EpOutGetCount();

    // If USBD_Read() has not been called, return an error
    if (myUsbDevice.ep2out.state != D_EP_RECEIVING)
    {
      myUsbDevice.ep2out.misc.bits.outPacketPending = true;
      status = USB_STATUS_EP_ERROR;
    }
    // Check for overrun of user buffer
    else if (myUsbDevice.ep2out.remaining < count)
    {
      myUsbDevice.ep2out.state = D_EP_IDLE;
      myUsbDevice.ep2out.misc.bits.outPacketPending = true;
      status = USB_STATUS_EP_RX_BUFFER_OVERRUN;
    }
    else
    {
      USB_ReadFIFO(2, count, myUsbDevice.ep2out.buf);

      myUsbDevice.ep2out.misc.bits.outPacketPending = false;
      myUsbDevice.ep2out.remaining -= count;
      myUsbDevice.ep2out.buf += count;

      if ((myUsbDevice.ep2out.remaining == 0) || (count != SLAB_USB_EP2OUT_MAX_PACKET_SIZE))
      {
        myUsbDevice.ep2out.state = D_EP_IDLE;
        xferComplete = true;
      }

      status = USB_STATUS_OK;
      USB_EpnClearOutPacketReady();
    }
    if (myUsbDevice.ep2out.misc.bits.callback == true)
    {
      if (xferComplete == true)
      {
        myUsbDevice.ep2out.misc.bits.callback = false;
      }

      USBD_XferCompleteCb(EP2OUT, status, count, myUsbDevice.ep2out.remaining);
    }
  }
}
/***************************************************************************//**
 * @brief       Writes data to the USB FIFO
 * @param       fifoNum
 *              USB Endpoint FIFO to write
 * @param       numBytes
 *              Number of bytes to write to the FIFO
 * @param       dat
 *              Pointer to buffer hoding data to write to the FIFO
 * @param       txPacket
 *              If TRUE, the packet will be sent immediately after loading the
 *              FIFO
 *              If FALSE, the packet will be stored in the FIFO and the
 *              transmission must be started at a later time
 ******************************************************************************/
void USB_WriteFIFO(uint8_t fifoNum, uint8_t numBytes, uint8_t *dat, bool txPacket)
{
  USB_EnableWriteFIFO(fifoNum);

  // Convert generic pointer to memory-specific pointer and call the
  // the corresponding memory-specific function, if possible.
  // The memory-specific functions are much faster than the generic functions.
#ifdef SI_GPTR

  switch (((SI_GEN_PTR_t *)&dat)->gptr.memtype)
  {
    case SI_GPTR_MTYPE_IDATA:
      USB_WriteFIFO_Idata(numBytes, dat);
      break;

    // For some compilers, IDATA and DATA are treated the same.
    // Only call the USB_WriteFIFO_Data() if the compiler differentiates between
    // DATA and IDATA.
#if (SI_GPTR_MTYPE_DATA != SI_GPTR_MTYPE_IDATA)
    case SI_GPTR_MTYPE_DATA:
      USB_WriteFIFO_Data(numBytes, dat);
      break;
#endif

    case SI_GPTR_MTYPE_XDATA:
      USB_WriteFIFO_Xdata(numBytes, dat);
      break;

    // For some compilers, XDATA and PDATA are treated the same.
    // Only call the USB_WriteFIFO_Pdata() if the compiler differentiates
    // between XDATA and PDATA.
#if (SI_GPTR_MTYPE_PDATA != SI_GPTR_MTYPE_XDATA)
    case SI_GPTR_MTYPE_PDATA:
      USB_WriteFIFO_Pdata(numBytes, dat);
      break;
#endif

    case SI_GPTR_MTYPE_CODE:
      USB_WriteFIFO_Code(numBytes, dat);
      break;

    default:
      break;
  }

#else
  USB_WriteFIFO_Generic(numBytes, dat);
#endif  // #ifdef SI_GPTR

  USB_DisableWriteFIFO(fifoNum);

  if ((txPacket == true) && (fifoNum > 0))
  {
    USB_SetIndex(fifoNum);
    USB_EpnSetInPacketReady();
  }
}
Ejemplo n.º 3
0
void USB_ActivateEp(uint8_t ep,
                    uint16_t packetSize,
                    bool inDir,
                    bool splitMode,
                    bool isoMode)
{
  uint8_t CSRH_mask = 0;
  uint16_t fifoSize;

  USB_SetIndex(ep);

  // Determine the available fifoSize for a given endpoint based on the
  // splitMode setting
  fifoSize = (splitMode == true) ? (16 << ep) : (32 << ep);

  if (packetSize <= fifoSize)
  {
    CSRH_mask |= EINCSRH_DBIEN__ENABLED;
  }

  if (isoMode == true)
  {
    CSRH_mask |= EINCSRH_ISO__ENABLED;
  }

  if (inDir == true)
  {
    CSRH_mask |= EINCSRH_DIRSEL__IN;

    if (splitMode == true)
    {
      CSRH_mask |= EINCSRH_SPLIT__ENABLED;
    }
    USB_WRITE_BYTE(EINCSRL, EINCSRL_CLRDT__BMASK);
    USB_WRITE_BYTE(EINCSRH, CSRH_mask);
  }
  else // OUT
  {
    USB_WRITE_BYTE(EOUTCSRL, EOUTCSRL_CLRDT__BMASK);
    USB_WRITE_BYTE(EOUTCSRH, CSRH_mask);

    if (splitMode == false)
    {
      USB_WRITE_BYTE(EINCSRH, 0);
    }
  }
}
/***************************************************************************//**
 * @brief       Handle Endpoint 2 IN transfer interrupt
 * @note        This function takes no parameters, but it uses the EP2IN status
 *              variables stored in @ref myUsbDevice.ep2in.
 ******************************************************************************/
void handleUsbIn2Int(void)
{
  uint8_t xferred;
  bool callback;

  USB_SetIndex(2);

  if (USB_EpnInGetSentStall())
  {
    USB_EpnInClearSentStall();
  }
  else if (myUsbDevice.ep2in.state == D_EP_TRANSMITTING)
  {
    xferred = (myUsbDevice.ep2in.remaining > SLAB_USB_EP2IN_MAX_PACKET_SIZE)
              ? SLAB_USB_EP2IN_MAX_PACKET_SIZE : myUsbDevice.ep2in.remaining;
    myUsbDevice.ep2in.remaining -= xferred;
    myUsbDevice.ep2in.buf += xferred;

    callback = myUsbDevice.ep2in.misc.bits.callback;

    // Load more data
    if (myUsbDevice.ep2in.remaining > 0)
    {
      USB_WriteFIFO(2,
                    (myUsbDevice.ep2in.remaining > SLAB_USB_EP2IN_MAX_PACKET_SIZE)
                      ? SLAB_USB_EP2IN_MAX_PACKET_SIZE
                      : myUsbDevice.ep2in.remaining,
                    myUsbDevice.ep2in.buf,
                    true);
    }
    else
    {
      myUsbDevice.ep2in.misc.bits.callback = false;
      myUsbDevice.ep2in.state = D_EP_IDLE;
    }

    if (callback == true)
    {
      USBD_XferCompleteCb(EP2IN, USB_STATUS_OK, xferred, myUsbDevice.ep2in.remaining);
    }

  }
}
/***************************************************************************//**
 * @brief       Handle Endpoint 3 OUT transfer interrupt
 * @details     Endpoint 3 OUT is the only OUT endpoint that supports
 *              isochronous transfers.
 * @note        This function takes no parameters, but it uses the EP3OUT status
 *              variables stored in @ref myUsbDevice.ep3out.
 ******************************************************************************/
void handleUsbOut3Int(void)
{
#if (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)
  uint16_t nextIdx;
#if (SLAB_USB_EP3OUT_MAX_PACKET_SIZE > 255)
  uint16_t count;
#else
  uint8_t count;
#endif // ( SLAB_USB_EP3OUT_MAX_PACKET_SIZE > 255 )
#else
  uint8_t count;
#endif // ( SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC )

  USB_Status_TypeDef status;
  bool xferComplete = false;

  USB_SetIndex(3);

  if (USB_EpnOutGetSentStall())
  {
    USB_EpnOutClearSentStall();
  }
  else if (USB_EpnGetOutPacketReady())
  {
    count = USB_EpOutGetCount();

    // If USBD_Read() has not been called, return an error
    if (myUsbDevice.ep3out.state != D_EP_RECEIVING)
    {
      myUsbDevice.ep3out.misc.bits.outPacketPending = true;
      status = USB_STATUS_EP_ERROR;
    }
#if  ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
    // Check for overrun of user buffer
    else if (myUsbDevice.ep3out.remaining < count)
    {
      myUsbDevice.ep3out.state = D_EP_IDLE;
      myUsbDevice.ep3out.misc.bits.outPacketPending = true;
      status = USB_STATUS_EP_RX_BUFFER_OVERRUN;
    }
#endif
    else
    {
#if  ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
      USB_ReadFIFO(3, count, myUsbDevice.ep3out.buf);

      myUsbDevice.ep3out.remaining -= count;
      myUsbDevice.ep3out.buf += count;

      if ((myUsbDevice.ep3out.remaining == 0) || (count != SLAB_USB_EP3OUT_MAX_PACKET_SIZE))
      {
        myUsbDevice.ep3out.state = D_EP_IDLE;
        xferComplete = true;
      }
#elif (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)
      nextIdx = count + myUsbDevice.ep3outIsoIdx;

      // In isochronous mode, a circular buffer is used to hold the data
      // If the next index into the circular buffer passes the end of the
      // buffer, make two calls to USB_ReadFIFOIso()
      if (nextIdx > myUsbDevice.ep3out.remaining)
      {
        USB_ReadFIFOIso(3, myUsbDevice.ep3out.remaining - myUsbDevice.ep3outIsoIdx, &myUsbDevice.ep3out.buf[myUsbDevice.ep3outIsoIdx]);
        myUsbDevice.ep3outIsoIdx = nextIdx - myUsbDevice.ep3out.remaining;
        USB_ReadFIFOIso(3, myUsbDevice.ep3outIsoIdx, myUsbDevice.ep3out.buf);
      }
      else
      {
        USB_ReadFIFOIso(3, count, &myUsbDevice.ep3out.buf[myUsbDevice.ep3outIsoIdx]);
        myUsbDevice.ep3outIsoIdx = nextIdx;
      }
#endif // ( ( SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK ) || ( SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR ) )

      myUsbDevice.ep3out.misc.bits.outPacketPending = false;
      status = USB_STATUS_OK;
      USB_EpnClearOutPacketReady();
    }
    if (myUsbDevice.ep3out.misc.bits.callback == true)
    {
      if (xferComplete == true)
      {
        myUsbDevice.ep3out.misc.bits.callback = false;
      }

#if  ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
      USBD_XferCompleteCb(EP3OUT, status, count, myUsbDevice.ep3out.remaining);
#elif (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)

      // In Isochronous mode, the meaning of the USBD_XferCompleteCb parameters changes:
      //   xferred is the number of bytes received in the last packet
      //   remaining is the current index into the circular buffer
      USBD_XferCompleteCb(EP3OUT, status, count, myUsbDevice.ep3outIsoIdx);
#endif
    }
  }
}
/***************************************************************************//**
 * @brief       Handle Endpoint 3 IN transfer interrupt
 * @details     Endpoint 3 IN is the only IN endpoint that supports isochronous
 *              transfers.
 * @note        This function takes no parameters, but it uses the EP3IN status
 *              variables stored in @ref myUsbDevice.ep3in.
 ******************************************************************************/
void handleUsbIn3Int(void)
{
#if SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC
  uint16_t xferred, nextIdx;
#else
  uint8_t xferred;
  bool callback;
#endif

  USB_SetIndex(3);

  if (USB_EpnInGetSentStall())
  {
    USB_EpnInClearSentStall();
  }
  else if (myUsbDevice.ep3in.state == D_EP_TRANSMITTING)
  {
#if  ((SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_INTR))
    xferred = (myUsbDevice.ep3in.remaining > SLAB_USB_EP3IN_MAX_PACKET_SIZE)
              ? SLAB_USB_EP3IN_MAX_PACKET_SIZE : myUsbDevice.ep3in.remaining;
    myUsbDevice.ep3in.remaining -= xferred;
    myUsbDevice.ep3in.buf += xferred;
#endif

#if  ((SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_INTR))

    callback = myUsbDevice.ep3in.misc.bits.callback;

#elif (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC)
    if (myUsbDevice.ep3in.misc.bits.callback == true)
    {
      // In Isochronous mode, the meaning of the USBD_XferCompleteCb parameters changes:
      //   xferred is ignored
      //   remaining is the current index into the circular buffer
      //   the return value is the number of bytes to transmit in the next packet
      xferred = USBD_XferCompleteCb(EP3IN, USB_STATUS_OK, 0, myUsbDevice.ep3inIsoIdx);
      if (xferred == 0)
      {
        myUsbDevice.ep3in.misc.bits.inPacketPending = true;
        return;
      }
    }
#endif
    // Load more data
#if  ((SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_INTR))
    if (myUsbDevice.ep3in.remaining > 0)
    {
      USB_WriteFIFO(3,
                    (myUsbDevice.ep3in.remaining > SLAB_USB_EP3IN_MAX_PACKET_SIZE)
                      ? SLAB_USB_EP3IN_MAX_PACKET_SIZE
                      : myUsbDevice.ep3in.remaining,
                    myUsbDevice.ep3in.buf,
                    true);
    }
    else
    {
      myUsbDevice.ep3in.misc.bits.callback = false;
      myUsbDevice.ep3in.state = D_EP_IDLE;
    }

    if (callback == true)
    {
      USBD_XferCompleteCb(EP3IN, USB_STATUS_OK, xferred, myUsbDevice.ep3in.remaining);
    }
#elif (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC)
    nextIdx = xferred + myUsbDevice.ep3inIsoIdx;
    myUsbDevice.ep3in.misc.bits.inPacketPending = false;

    // Check if the next index is past the end of the circular buffer.
    // If so, break the write up into two calls to USB_WriteFIFOIso()
    if (nextIdx > myUsbDevice.ep3in.remaining)
    {
      USB_WriteFIFOIso(3, myUsbDevice.ep3in.remaining - myUsbDevice.ep3inIsoIdx, &myUsbDevice.ep3in.buf[myUsbDevice.ep3inIsoIdx]);
      myUsbDevice.ep3inIsoIdx = nextIdx - myUsbDevice.ep3in.remaining;
      USB_WriteFIFOIso(3, myUsbDevice.ep3inIsoIdx, myUsbDevice.ep3in.buf);
    }
    else
    {
      USB_WriteFIFOIso(3, xferred, &myUsbDevice.ep3in.buf[myUsbDevice.ep3inIsoIdx]);
      myUsbDevice.ep3inIsoIdx = nextIdx;
    }
#endif // ( ( SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_BULK ) || ( SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_INTR ) )
  }
}
/***************************************************************************//**
 * @brief       Processes Standard Request (Chapter 9 Command)
 * @return      Status of request (type @ref USB_Status_TypeDef)
 * @note        This function takes no parameters, but it uses the setup command
 *              stored in @ref myUsbDevice.setup.
 ******************************************************************************/
USB_Status_TypeDef USBDCH9_SetupCmd(void)
{
  USB_Status_TypeDef status = USB_STATUS_OK;

  switch (myUsbDevice.setup.bRequest)
  {
    case GET_STATUS:
      status = GetStatus();
      break;

    case CLEAR_FEATURE:
      status = ClearFeature();
      break;

    case SET_FEATURE:
      status = SetFeature();
      break;

    case SET_ADDRESS:
      status = SetAddress();
      break;

    case GET_DESCRIPTOR:
      status = GetDescriptor();
      break;

    case GET_CONFIGURATION:
      status = GetConfiguration();
      break;

    case SET_CONFIGURATION:
      status = SetConfiguration();
      break;

    case GET_INTERFACE:
      status = GetInterface();
      break;

    case SET_INTERFACE:
      status = SetInterface();
      break;

//    case GET_MS_DESCRIPTOR:
//    	status = HandleMsRequest();
//    	break;

    default:
      status = USB_STATUS_REQ_ERR;
      break;
  }

  // Reset index to 0 in case one of the above commands modified it
  USB_SetIndex(0);

  // If the command resulted in an error, send a procedural stall
  if (status == USB_STATUS_REQ_ERR)
  {
    SendEp0Stall();
  }

  return status;
}
/***************************************************************************//**
 * @brief       Clears the requested feature
 * @details     Supports CLEAR_FEATURE for Remote Wakeup and Endpoint Halt
 * @return      Status of request (type @ref USB_Status_TypeDef)
 * @note        This function takes no parameters, but it uses the setup command
 *              stored in @ref myUsbDevice.setup.
 ******************************************************************************/
static USB_Status_TypeDef ClearFeature(void)
{
  USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;

  if (myUsbDevice.setup.wLength == 0)
  {
    switch (myUsbDevice.setup.bmRequestType.Recipient)
    {
  #if SLAB_USB_REMOTE_WAKEUP_ENABLED
      case USB_SETUP_RECIPIENT_DEVICE:
        if ((myUsbDevice.setup.wIndex == 0)
            && (myUsbDevice.setup.wValue == USB_FEATURE_DEVICE_REMOTE_WAKEUP)
            && (myUsbDevice.state >= USBD_STATE_ADDRESSED))
        {
          // Remote wakeup feature clear
          myUsbDevice.remoteWakeupEnabled = false;
          retVal = USB_STATUS_OK;
        }
        break;
  #endif // SLAB_USB_REMOTE_WAKEUP_ENABLED
      case USB_SETUP_RECIPIENT_ENDPOINT:
        if (myUsbDevice.setup.wValue == USB_FEATURE_ENDPOINT_HALT)
        {
          // Device does not support halting endpoint 0, but do not return
          // an error as this is a valid request
          if (((myUsbDevice.setup.wIndex & ~USB_EP_DIR_IN) == 0)
              && (myUsbDevice.state >= USBD_STATE_ADDRESSED))
          {
            retVal = USB_STATUS_OK;
          }
          else if (((myUsbDevice.setup.wIndex & ~USB_SETUP_DIR_D2H) < SLAB_USB_NUM_EPS_USED)
                   && (myUsbDevice.state == USBD_STATE_CONFIGURED))
          {
            retVal = USB_STATUS_OK;
            USB_SetIndex((myUsbDevice.setup.wIndex & 0xFF) & ~USB_SETUP_DIR_D2H);

#if (SLAB_USB_EP1IN_USED || SLAB_USB_EP2IN_USED || SLAB_USB_EP3IN_USED)
            if ((myUsbDevice.setup.wIndex & 0xFF) & USB_EP_DIR_IN)
            {
              USB_EpnInEndStallAndClearDataToggle();
            }
#endif
#if (SLAB_USB_EP1OUT_USED || SLAB_USB_EP2OUT_USED || SLAB_USB_EP3OUT_USED)
            if (((myUsbDevice.setup.wIndex & 0xFF) & USB_EP_DIR_IN) == 0)
            {
              USB_EpnOutEndStallAndClearDataToggle();
            }
#endif

            switch (myUsbDevice.setup.wIndex & 0xFF)
            {
#if SLAB_USB_EP1OUT_USED
              case (USB_EP_DIR_OUT | 1):
                if (myUsbDevice.ep1out.state != D_EP_RECEIVING)
                {
                  myUsbDevice.ep1out.state = D_EP_IDLE;
                }
                break;
#endif
#if SLAB_USB_EP2OUT_USED
              case (USB_EP_DIR_OUT | 2):
                if (myUsbDevice.ep2out.state != D_EP_RECEIVING)
                {
                  myUsbDevice.ep2out.state = D_EP_IDLE;
                }
                break;
#endif
#if SLAB_USB_EP3OUT_USED
              case (USB_EP_DIR_OUT | 3):
                if (myUsbDevice.ep3out.state != D_EP_RECEIVING)
                {
                  myUsbDevice.ep3out.state = D_EP_IDLE;
                }
                break;
#endif
#if SLAB_USB_EP1IN_USED
              case (USB_EP_DIR_IN | 1):
                if (myUsbDevice.ep1in.state != D_EP_TRANSMITTING)
                {
                  myUsbDevice.ep1in.state = D_EP_IDLE;
                }
                break;
#endif
#if SLAB_USB_EP2IN_USED
              case (USB_EP_DIR_IN | 2):
                if (myUsbDevice.ep2in.state != D_EP_TRANSMITTING)
                {
                  myUsbDevice.ep2in.state = D_EP_IDLE;
                }
                break;
#endif
#if SLAB_USB_EP3IN_USED
              case (USB_EP_DIR_IN | 3):
                if (myUsbDevice.ep3in.state != D_EP_TRANSMITTING)
                {
                  myUsbDevice.ep3in.state = D_EP_IDLE;
                }
                break;
#endif
            }
          }
        }
    }
  }
  return retVal;
}
Ejemplo n.º 9
0
void usbIrqHandler(void)
#endif
{
  uint8_t statusCommon, statusIn, statusOut, indexSave;

#if SLAB_USB_HANDLER_CB
  // Callback to user before processing
  USBD_EnterHandler();
#endif

  // Get the interrupt sources
  statusCommon = USB_GetCommonInts();
  statusIn = USB_GetInInts();
  statusOut = USB_GetOutInts();

#if SLAB_USB_POLLED_MODE
  if ((statusCommon == 0) && (statusIn == 0) && (statusOut == 0))
  {
    return;
  }
#endif

  // Save the current index
  indexSave = USB_GetIndex();

  // Check Common USB Interrupts
  if (USB_IsSofIntActive(statusCommon))
  {
#if SLAB_USB_SOF_CB
    USBD_SofCb(USB_GetSofNumber());
#endif // SLAB_USB_SOF_CB

    // Check for unhandled USB packets on EP0 and set the corresponding IN or
    // OUT interrupt active flag if necessary.
    if (((myUsbDevice.ep0.misc.bits.outPacketPending == true) && (myUsbDevice.ep0.state == D_EP_RECEIVING)) ||
        ((myUsbDevice.ep0.misc.bits.inPacketPending == true) && (myUsbDevice.ep0.state == D_EP_TRANSMITTING)))
    {
      USB_SetEp0IntActive(statusIn);
    }
    // Check for unhandled USB OUT packets and set the corresponding OUT
    // interrupt active flag if necessary.
#if SLAB_USB_EP1OUT_USED
    if ((myUsbDevice.ep1out.misc.bits.outPacketPending == true) && (myUsbDevice.ep1out.state == D_EP_RECEIVING))
    {
      USB_SetOut1IntActive(statusOut);
    }
#endif
#if SLAB_USB_EP2OUT_USED
    if ((myUsbDevice.ep2out.misc.bits.outPacketPending == true) && (myUsbDevice.ep2out.state == D_EP_RECEIVING))
    {
      USB_SetOut2IntActive(statusOut);
    }
#endif
#if SLAB_USB_EP3OUT_USED
    if ((myUsbDevice.ep3out.misc.bits.outPacketPending == true) && (myUsbDevice.ep3out.state == D_EP_RECEIVING))
    {
      USB_SetOut3IntActive(statusOut);
    }
#endif
#if (SLAB_USB_EP3IN_USED && (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC))
    if ((myUsbDevice.ep3in.misc.bits.inPacketPending == true) && (myUsbDevice.ep3in.state == D_EP_TRANSMITTING))
    {
      USB_SetIn3IntActive(statusIn);
    }
#endif
  }

  if (USB_IsResetIntActive(statusCommon))
  {
    handleUsbResetInt();

    // If VBUS is not present on detection of a USB reset, enter suspend mode.
#if (SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)
    if (USB_IsVbusOn() == false)
    {
      USB_SetSuspendIntActive(statusCommon);
    }
#endif
  }

  if (USB_IsResumeIntActive(statusCommon))
  {
    handleUsbResumeInt();
  }

  if (USB_IsSuspendIntActive(statusCommon))
  {
    handleUsbSuspendInt();
  }

#if SLAB_USB_EP3IN_USED
  if (USB_IsIn3IntActive(statusIn))
  {
    handleUsbIn3Int();
  }
#endif  // EP3IN_USED

#if SLAB_USB_EP3OUT_USED
  if (USB_IsOut3IntActive(statusOut))
  {
    handleUsbOut3Int();
  }
#endif  // EP3OUT_USED

#if SLAB_USB_EP2IN_USED
  if (USB_IsIn2IntActive(statusIn))
  {
    handleUsbIn2Int();
  }
#endif  // EP2IN_USED

#if SLAB_USB_EP1IN_USED
  if (USB_IsIn1IntActive(statusIn))
  {
    handleUsbIn1Int();
  }
#endif  // EP1IN_USED

#if SLAB_USB_EP2OUT_USED
  if (USB_IsOut2IntActive(statusOut))
  {
    handleUsbOut2Int();
  }
#endif  // EP2OUT_USED

#if SLAB_USB_EP1OUT_USED
  if (USB_IsOut1IntActive(statusOut))
  {
    handleUsbOut1Int();
  }
#endif  // EP1OUT_USED

  // Check USB Endpoint 0 Interrupt
  if (USB_IsEp0IntActive(statusIn))
  {
    handleUsbEp0Int();
  }

  // Restore index
  USB_SetIndex(indexSave);

#if SLAB_USB_HANDLER_CB
  // Callback to user before exiting
  USBD_ExitHandler();
#endif
}
Ejemplo n.º 10
0
/***************************************************************************//**
 * @brief       Send a procedural stall on Endpoint 0
 ******************************************************************************/
void SendEp0Stall(void)
{
  USB_SetIndex(0);
  myUsbDevice.ep0.state = D_EP_STALL;
  USB_Ep0SendStall();
}
Ejemplo n.º 11
0
/***************************************************************************//**
 * @brief       Handles Endpoint 0 transfer interrupt
 ******************************************************************************/
static void handleUsbEp0Int(void)
{
  USB_SetIndex(0);

  if (USB_Ep0SentStall() || USB_GetSetupEnd())
  {
    USB_Ep0ClearSentStall();
    USB_ServicedSetupEnd();
    myUsbDevice.ep0.state = D_EP_IDLE;
    myUsbDevice.ep0.misc.c = 0;
  }
  if (USB_Ep0OutPacketReady())
  {
    if (myUsbDevice.ep0.misc.bits.waitForRead == true)
    {
      myUsbDevice.ep0.misc.bits.outPacketPending = true;
    }
    else if (myUsbDevice.ep0.state == D_EP_IDLE)
    {
      myUsbDevice.ep0String.c = USB_STRING_DESCRIPTOR_UTF16LE;
      USB_ReadFIFOSetup();

      // Vendor unique, Class or Standard setup commands override?
#if SLAB_USB_SETUP_CMD_CB
      if (USBD_SetupCmdCb(&myUsbDevice.setup) == USB_STATUS_REQ_UNHANDLED)
      {
#endif
      if (myUsbDevice.setup.bmRequestType.Type == USB_SETUP_TYPE_STANDARD)
      {
        USBDCH9_SetupCmd();
      }
      else
      {
        SendEp0Stall();
      }
#if SLAB_USB_SETUP_CMD_CB
    }
    else
    {
      // If in-packet but callback didn't setup a USBD_Read and we are expecting a data byte then
      // we need to wait for the read to be setup and nack packets till USBD_Read is called.
      if ((myUsbDevice.setup.bmRequestType.Direction == USB_SETUP_DIR_OUT)
          && (myUsbDevice.ep0.state != D_EP_RECEIVING)
          && (myUsbDevice.setup.wLength)
          )
      {
        myUsbDevice.ep0.misc.bits.waitForRead = true;
      }
    }
#endif
    }
    else if (myUsbDevice.ep0.state == D_EP_RECEIVING)
    {
      handleUsbEp0Rx();
    }
    else
    {
      myUsbDevice.ep0.misc.bits.outPacketPending = true;
    }
  }
  if ((myUsbDevice.ep0.state == D_EP_TRANSMITTING) && (USB_Ep0InPacketReady() == 0))
  {
    handleUsbEp0Tx();
  }
}
Ejemplo n.º 12
0
int8_t USBD_UnStallEp(uint8_t epAddr)
{
  bool usbIntsEnabled;

  USB_SaveSfrPage();

  // Verify the endpoint address is valid and not Endpoint 0.
  if ((epAddr == EP0) || (epAddr >= SLAB_USB_NUM_EPS_USED))
  {
    SLAB_ASSERT(false);
    return USB_STATUS_ILLEGAL;
  }
  else
  {
    DISABLE_USB_INTS;

    // End the stall condition and set the endpoint state to idle.
    switch (epAddr)
    {
#if SLAB_USB_EP1IN_USED
      case (EP1IN):
        myUsbDevice.ep1in.state = D_EP_IDLE;
        USB_SetIndex(1);
        USB_EpnInEndStall();
        break;
#endif
#if SLAB_USB_EP2IN_USED
      case (EP2IN):
        myUsbDevice.ep2in.state = D_EP_IDLE;
        USB_SetIndex(2);
        USB_EpnInEndStall();
        break;
#endif
#if SLAB_USB_EP3IN_USED
      case (EP3IN):
        myUsbDevice.ep3in.state = D_EP_IDLE;
        USB_SetIndex(3);
        USB_EpnInEndStall();
        break;
#endif
#if SLAB_USB_EP1OUT_USED
      case (EP1OUT):
        myUsbDevice.ep1out.state = D_EP_IDLE;
        USB_SetIndex(1);
        USB_EpnOutEndStall();
        break;
#endif
#if SLAB_USB_EP2OUT_USED
      case (EP2OUT):
        myUsbDevice.ep2out.state = D_EP_IDLE;
        USB_SetIndex(2);
        USB_EpnOutEndStall();
        break;
#endif
#if SLAB_USB_EP3OUT_USED
      case (EP3OUT):
        myUsbDevice.ep3out.state = D_EP_IDLE;
        USB_SetIndex(3);
        USB_EpnOutEndStall();
        break;
#endif
    }

    ENABLE_USB_INTS;
    USB_RestoreSfrPage();
  }

  return USB_STATUS_OK;
}
Ejemplo n.º 13
0
int8_t USBD_StallEp(uint8_t epAddr)
{
  bool usbIntsEnabled;

  USB_SaveSfrPage();

  // Verify the endpoint address is valid and not Endpoint 0.
  if ((epAddr == EP0) || (epAddr >= SLAB_USB_NUM_EPS_USED))
  {
    SLAB_ASSERT(false);
    return USB_STATUS_ILLEGAL;
  }

  DISABLE_USB_INTS;

  // Halt the appropriate endpoint by sending a stall and setting the endpoint
  // state to Halted (D_EP_HALT).
  switch (epAddr)
  {
#if SLAB_USB_EP1IN_USED
    case (EP1IN):
      myUsbDevice.ep1in.state = D_EP_HALT;
      USB_SetIndex(1);
      USB_EpnInStall();
      break;
#endif
#if SLAB_USB_EP2IN_USED
    case (EP2IN):
      myUsbDevice.ep2in.state = D_EP_HALT;
      USB_SetIndex(2);
      USB_EpnInStall();
      break;
#endif
#if SLAB_USB_EP3IN_USED
    case (EP3IN):
      myUsbDevice.ep3in.state = D_EP_HALT;
      USB_SetIndex(3);
      USB_EpnInStall();
      break;
#endif
#if SLAB_USB_EP1OUT_USED
    case (EP1OUT):
      myUsbDevice.ep1out.state = D_EP_HALT;
      USB_SetIndex(1);
      USB_EpnOutStall();
      break;
#endif
#if SLAB_USB_EP2OUT_USED
    case (EP2OUT):
      myUsbDevice.ep2out.state = D_EP_HALT;
      USB_SetIndex(2);
      USB_EpnOutStall();
      break;
#endif
#if SLAB_USB_EP3OUT_USED
    case (EP3OUT):
      myUsbDevice.ep3out.state = D_EP_HALT;
      USB_SetIndex(3);
      USB_EpnOutStall();
      break;
#endif
  }

  ENABLE_USB_INTS;
  USB_RestoreSfrPage();

  return USB_STATUS_OK;
}
Ejemplo n.º 14
0
void USB_AbortOutEp(uint8_t fifoNum)
{
  USB_SetIndex(fifoNum);
  USB_EpnOutFlush();
  USB_EpnOutFlush();
}
Ejemplo n.º 15
0
void USB_AbortInEp(uint8_t fifoNum)
{
  USB_SetIndex(fifoNum);
  USB_EpnInFlush();
  USB_EpnInFlush();
}