Exemplo n.º 1
0
/** \brief Processes the \ref GET_DESCRIPTOR request (returns the specified USB descriptor)
 *
 * The \ref module_usb_descriptor_parser module is used to locate device, configuration and string
 * descriptors. Note that configuration descriptors also include interface, endpoint and other
 * "similar" descriptor types (e.g. HID descriptor), with the total descriptor length specified by
 * the \ref USB_CONFIGURATION_DESCRIPTOR.wTotalLength field.
 *
 * Other descriptor types that are not returned with the configuration descriptor, must be defined in
 * the usbDescriptorMarker.pUsbDescLut lookup-table. This table specifies the values of the VALUE and INDEX fields, and
 * gives a pointer to the descriptor along with it's length.
 *
 * <b>Parameters</b>:
 * - VALUE.MSB: Descriptor type
 * - VALUE.LSB: Descriptor index
 * - INDEX: 0, or language ID for string descriptors (currently not supported)
 * - LENGTH: Descriptor length (either the requested number of bytes, or the length of the descriptor,
 *           whichever is the smallest)
 *
 * <b>Data (IN)</b>:
 * The descriptor(s)
 */
void usbsrGetDescriptor(void)
{
   uint8 n;

   // Which descriptor?
   switch (HI_UINT16(usbSetupHeader.value)) {

   // Device descriptor
   case DESC_TYPE_DEVICE:
      usbSetupData.pBuffer = (uint8 __code*) usbdpGetDeviceDesc();
      usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX];
      break;

   // Configuration descriptor
   case DESC_TYPE_CONFIG:
      usbSetupData.pBuffer = (uint8 __code*) usbdpGetConfigurationDesc(0, LO_UINT16(usbSetupHeader.value));
      usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_CONFIG_LENGTH_LSB_IDX] +
                               usbSetupData.pBuffer[DESC_CONFIG_LENGTH_MSB_IDX] * 256;
      break;

   // String descriptor
   case DESC_TYPE_STRING:
      // OPT: Implement language ID
      usbSetupData.pBuffer = (uint8 __code*) usbdpGetStringDesc(LO_UINT16(usbSetupHeader.value));
      usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX];
      break;

   // Other descriptor type
   default:
      // Perform a table search (on index and value)
      usbSetupData.pBuffer = NULL;
      for (n = 0; n < ((uint16)usbDescriptorMarker.pUsbDescLutEnd - (uint16)usbDescriptorMarker.pUsbDescLut) / sizeof(DESC_LUT_INFO); n++) {
         if ((usbDescriptorMarker.pUsbDescLut[n].valueMsb == HI_UINT16(usbSetupHeader.value))
             && (usbDescriptorMarker.pUsbDescLut[n].valueLsb == LO_UINT16(usbSetupHeader.value))
             && (usbDescriptorMarker.pUsbDescLut[n].indexMsb == HI_UINT16(usbSetupHeader.index))
             && (usbDescriptorMarker.pUsbDescLut[n].indexLsb == LO_UINT16(usbSetupHeader.index)) )
         {
            usbSetupData.pBuffer = usbDescriptorMarker.pUsbDescLut[n].pDescStart;
            usbSetupData.bytesLeft = usbDescriptorMarker.pUsbDescLut[n].length;
         }
      }
   }

   // Stall EP0 if no descriptor was found
   if (usbSetupData.pBuffer == NULL) usbfwData.ep0Status = EP_STALL;

   if (usbfwData.ep0Status != EP_STALL) {

      // Limit the returned descriptor size (the PC wants to know about sizes before
      // polling the complete descriptors)
      if (usbSetupData.bytesLeft > usbSetupHeader.length) {
         usbSetupData.bytesLeft = usbSetupHeader.length;
      }

      usbfwData.ep0Status = EP_TX;
   }

} // usbsrGetDescriptor
Exemplo n.º 2
0
/** \brief Initializes the USB framework
 *
 * This function should be called when the microcontroller is ready to accept USB traffic. It enables the
 * USB peripheral unit and enables the pull-up resistor on the D+ line. Endpoint status, current
 * configuration value, etc. are initialized and evenetually re-initialized in the
 * \ref usbfwResetHandler() function.
 */
void usbfwInit(void)
{
    // Set default values
    usbfwData.selfPowered = (usbdpGetConfigurationDesc(1, 0)->bmAttributes & 0x40) ? TRUE : FALSE;
    usbfwData.remoteWakeup = FALSE;

    HAL_USB_ENABLE();

    // Enable Resume Interrupt
    HAL_USB_RESUME_INT_ENABLE();

} // usbfwInit
/** \brief	Locates an interface descriptor
*
* The function will first go to the configuration descriptor that matches the supplied configuration
* value, and then locate the interface descriptor that matches the given interface number and alternate
* setting.
*
* \note It is not necessary to call \ref usbdpInit() before this function.
*
* \param[in]       cfgValue
*     The configuration value (\ref USB_CONFIGURATION_DESCRIPTOR.bConfigurationValue)
* \param[in]       intNumber
*     The interface number (\ref USB_INTERFACE_DESCRIPTOR.bInterfaceNumber)
* \param[in]       altSetting
*     The alternate setting (\ref USB_INTERFACE_DESCRIPTOR.bAlternateSetting)
*
* \return
*     A pointer to the \ref USB_INTERFACE_DESCRIPTOR, or \c NULL if it was not found.
*/
USB_INTERFACE_DESCRIPTOR __code* usbdpGetInterfaceDesc(uint8 cfgValue, uint8 intNumber, uint8 altSetting)
{
   USB_INTERFACE_DESCRIPTOR __code *pInterfaceDesc;

   // First get to the correct configuration
   usbdpGetConfigurationDesc(cfgValue, 0);

   // Then find a match on the interface
   while (pInterfaceDesc = usbdpFindNext(DESC_TYPE_INTERFACE, DESC_TYPE_CONFIG)) {
      if ((pInterfaceDesc->bInterfaceNumber == intNumber) && (pInterfaceDesc->bAlternateSetting == altSetting)) {
         break;
      }
   }

   return pInterfaceDesc;
} // usbdpGetInterfaceDesc
/** \brief Initializes the USB framework
 *
 * This function should be called when the microcontroller is ready to accept USB traffic. It enables the
 * USB peripheral unit and enables the pull-up resistor on the D+ line.
 */
void usbfwInit(void)
{
    //
    // Set default values
    //
    usbfwData.selfPowered = (usbdpGetConfigurationDesc(1, 0)->bmAttributes & 0x40) ? true : false;
    usbfwData.remoteWakeup = false;
    usbfwResetHandler();

    //
    // Enable the USB peripheral unit
    //
    UsbEnable();

    //
    // Allow the USB pad IP to to enter standby
    //
    HWREG(CCTEST_USBCTRL) = CCTEST_USBCTRL_USB_STB_M;

}
Exemplo n.º 5
0
/** \brief Processes the \c GET_DESCRIPTOR request (returns the specified USB descriptor)
 *
 * The descriptors are retrieved using either the \ref module_usb_descriptor_parser module's automatic
 * parsing functions (for device and configuration descriptors), or the manually generated
 * \ref pUsbDescriptorLut[] lookup table (for string and non-standard formatted descriptors). When the
 * USB host requests the configuration descriptor, this includes also the interface descriptors and their
 * sub-descriptors, with a total length specified by \ref USB_CONFIGURATION_DESCRIPTOR.wTotalLength.
 *
 * The \ref pUsbDescriptorLut[] lookup table takes the expected VALUE and INDEX fields for each
 * descriptor, and returns pointer and length.
 *
 * <b>Parameters</b>:
 * - VALUE.MSB: Descriptor type
 * - VALUE.LSB: Descriptor index
 * - INDEX: 0, or language ID for string descriptors (currently not supported)
 * - LENGTH: Descriptor length (either the requested number of bytes, or the length of the descriptor,
 *           whichever is the smallest)
 *
 * <b>Data (IN)</b>:
 * The descriptor(s)
 */
void usbsrGetDescriptor(void)
{
    const USB_DESCRIPTOR_LUT* pUsbDescriptorLutEntry;

    //
    // Which descriptor?
    //
    switch(usbSetupHeader.valueMsb)
    {

    case USB_DESC_TYPE_DEVICE:
        //
        // Device descriptor
        //
        usbSetupData.pBuffer   = (void*) usbdpGetDeviceDesc();
        usbSetupData.bytesLeft = ((USB_DEVICE_DESCRIPTOR*) usbSetupData.pBuffer)->bLength;
        break;

    case USB_DESC_TYPE_CONFIG:
        //
        // Configuration descriptor
        //
        usbSetupData.pBuffer   = (void*) usbdpGetConfigurationDesc(0, usbSetupHeader.valueLsb);
        usbSetupData.bytesLeft = ((USB_CONFIGURATION_DESCRIPTOR*) usbSetupData.pBuffer)->wTotalLength;
        break;

    default:
        //
        // String or other type descriptor
        //
        pUsbDescriptorLutEntry = usbdpGetDescByLut(usbSetupHeader.value, usbSetupHeader.index);
        if(pUsbDescriptorLutEntry)
        {
            usbSetupData.pBuffer   = (void*) pUsbDescriptorLutEntry->pDesc;
            usbSetupData.bytesLeft = pUsbDescriptorLutEntry->length;
        }
        else
        {
            //
            // Not found, so stall below
            //
            usbSetupData.pBuffer   = NULL;
        }
    }

    //
    // Stall EP0 if no descriptor was found
    //
    if(!usbSetupData.pBuffer)
    {
        usbfwData.ep0Status = EP_STALL;
    }

    if(usbfwData.ep0Status != EP_STALL)
    {
        //
        // Limit the returned descriptor size (the PC wants to know about sizes before
        // polling the complete descriptors)
        //
        if(usbSetupData.bytesLeft > usbSetupHeader.length)
        {
            usbSetupData.bytesLeft = usbSetupHeader.length;
        }

        usbfwData.ep0Status = EP_TX;
    }

}