⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_standard_requests.c

📁 reference about wireless design which is helpful to everyone
💻 C
📖 第 1 页 / 共 2 页
字号:
   case DESC_TYPE_DEVICE:
      usbSetupData.pBuffer = (BYTE __xdata*) usbdpGetDeviceDesc();
      usbSetupData.bytesLeft = usbSetupData.pBuffer[DESC_LENGTH_IDX];
      break;

   // Configuration descriptor
   case DESC_TYPE_CONFIG:
      usbSetupData.pBuffer = (BYTE __xdata*) usbdpGetConfigurationDesc(0, LOBYTE(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:
      // TODO: Implement language ID
      usbSetupData.pBuffer = (BYTE __xdata*) usbdpGetStringDesc(LOBYTE(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)pUsbDescLutEnd - (UINT16)pUsbDescLut) / sizeof(DESC_LUT_INFO); n++) {
         if ((pUsbDescLut[n].valueMsb == HIBYTE(usbSetupHeader.value)) && (pUsbDescLut[n].valueLsb == LOBYTE(usbSetupHeader.value)) &&
             (pUsbDescLut[n].indexMsb == HIBYTE(usbSetupHeader.index)) && (pUsbDescLut[n].indexLsb == LOBYTE(usbSetupHeader.index))) {
            usbSetupData.pBuffer = pUsbDescLut[n].pDescStart;
            usbSetupData.bytesLeft = 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



/** \brief Internally used function that configures all endpoints for the specified interface
 *
 * The new endpoint setup overwrites the old, without any warning. Unused endpoints keep their current
 * setup. The user is responsible for ensuring that no endpoint buffers overwrite each other, and that
 * interfaces do not cause conflicts. The pUsbDblbufLutInfo table must contain an entry for each
 * interface descriptor to define endpoint double-buffering.
 *
 * \param[in]       *pInterface
 *     A pointer to the interface descriptor
 */
static void ConfigureEndpoints(USB_INTERFACE_DESCRIPTOR __xdata *pInterface) {
   UINT8 n;
   WORD maxpRegValue;
   BYTE csRegValue;
   UINT8 endpoint;
   USB_ENDPOINT_DESCRIPTOR __xdata *pEndpoint;
   DBLBUF_LUT_INFO __code *pUsbDblbufLutInfo;

   // Locate the double buffer settings
   if (pInterface->bNumEndpoints) {
       pUsbDblbufLutInfo = (DBLBUF_LUT_INFO __code*) pUsbDblbufLut;
       while (pUsbDblbufLutInfo->pInterface != pInterface) {
          pUsbDblbufLutInfo++;
       }
   }

   // For each endpoint in this interface
   for (n = 0; n < pInterface->bNumEndpoints; n++) {
      if (pEndpoint = usbdpFindNext(DESC_TYPE_ENDPOINT, 0)) {

         // Get the endpoint index
         endpoint = pEndpoint->bEndpointAddress & 0x0F;
         USBFW_SELECT_ENDPOINT(endpoint);

         csRegValue = 0x00;
         maxpRegValue = (pEndpoint->wMaxPacketSize + 7) >> 3;

         // For IN endpoints...
         if (pEndpoint->bEndpointAddress & 0x80) {

            // Clear data toggle, and flush twice (due to double buffering)
            USBCSIL = USBCSIL_CLR_DATA_TOG | USBCSIL_FLUSH_PACKET;
            USBCSIL = USBCSIL_FLUSH_PACKET;

            // USBCSIH
            if ((pEndpoint->bmAttributes & EP_ATTR_TYPE_BM) == EP_ATTR_ISO) csRegValue |= USBCSIH_ISO;  // ISO flag
            if (pUsbDblbufLutInfo->inMask & BM(endpoint)) csRegValue |= USBCSIH_IN_DBL_BUF;             // Double buffering
            USBCSIH = csRegValue;

            // Max transfer size
            USBMAXI = maxpRegValue;

            // Endpoint status
            usbfwData.pEpInStatus[endpoint - 1] = EP_IDLE;

         // For OUT endpoints...
         } else {

            // Clear data toggle, and flush twice (due to double buffering)
            USBCSOL = USBCSOL_CLR_DATA_TOG | USBCSOL_FLUSH_PACKET;
            USBCSOL = USBCSOL_FLUSH_PACKET;

            // USBCSOH
            if ((pEndpoint->bmAttributes & EP_ATTR_TYPE_BM) == EP_ATTR_ISO) csRegValue |= USBCSOH_ISO;  // ISO flag
            if (pUsbDblbufLutInfo->outMask & BM(endpoint)) csRegValue |= USBCSOH_OUT_DBL_BUF;           // Double buffering
            USBCSOH = csRegValue;

            // Max transfer size
            USBMAXO = maxpRegValue;

            // Endpoint status
            usbfwData.pEpOutStatus[endpoint - 1] = EP_IDLE;
         }
         USBFW_SELECT_ENDPOINT(0);
      }
   }
} // ConfigureEndpoints




/** \brief Processes the \ref GET_CONFIGURATION request (returns the current device configuration value)
 *
 * If the returned value is 0, the device is not configured (not in the configured state)
 *
 * <b>Parameters</b>:
 * - VALUE: Always 0
 * - INDEX: Always 0
 * - LENGTH: Always 1
 *
 * <b>Data (IN)</b>:
 * The non-zero \ref USB_CONFIGURATION_DESCRIPTOR.bConfigurationValue of the currently selected
 * configuration.
 */
void usbsrGetConfiguration(void) {

   // Sanity check
   if (usbSetupHeader.value || usbSetupHeader.index || (usbSetupHeader.length != 1)) {
      usbfwData.ep0Status = EP_STALL;

   // Return the current configuration
   } else {
      usbSetupData.pBuffer = &usbfwData.configurationValue;
      usbSetupData.bytesLeft = 1;
      usbfwData.ep0Status = EP_TX;
   }

} // usbsrGetConfiguration




/** \brief Processes the \ref SET_CONFIGURATION request (sets the device configuration)
 *
 * The configuration value must either be 0, in which case the device enters the address state, or it
 * must match a configuration value from one of the USB configuration descriptors. If there is a match,
 * the device enters the configured state.
 *
 * This request resets all interfaces to alternate setting 0, and uses the \c ConfigureEndpoints()
 * function to automatically setup all endpoint registers.
 *
 * <b>Parameters</b>:
 * - VALUE: The configuration value (0-255)
 * - INDEX: Always 0
 * - LENGTH: Always 0
 */
void usbsrSetConfiguration(void) {
   UINT8 n;
   USB_CONFIGURATION_DESCRIPTOR __xdata *pConfiguration;
   USB_INTERFACE_DESCRIPTOR __xdata *pInterface;

   // Sanity check
   if ((usbfwData.usbState == DEV_DEFAULT) || usbSetupHeader.index || usbSetupHeader.length || HIBYTE(usbSetupHeader.value)) {
      usbfwData.ep0Status = EP_STALL;

   // Default endpoint setup
   } else {
      usbsrHookProcessEvent(USBSR_EVENT_CONFIGURATION_CHANGING, 0);

      // Configure relevant endpoints
      if (LOBYTE(usbSetupHeader.value)) {

         // Find the correct configuration descriptor...
         pConfiguration = usbdpGetConfigurationDesc(LOBYTE(usbSetupHeader.value), 0);

         // If it exists...
         if (pConfiguration) {
            usbfwData.usbState = DEV_CONFIGURED;
            usbfwData.configurationValue = LOBYTE(usbSetupHeader.value);

            // For each interface...
            for (n = 0; n < pConfiguration->bNumInterfaces; n++) {
               usbfwData.pAlternateSetting[n] = 0x00;

               // Look only for alternate setting 0
               do {
                  pInterface = usbdpFindNext(DESC_TYPE_INTERFACE, 0);
               } while (pInterface->bAlternateSetting != usbfwData.pAlternateSetting[n]);

               // Configure all endpoints in this interface
               ConfigureEndpoints(pInterface);
            }

         // If not, then stall the endpoint
         } else {
            usbfwData.ep0Status = EP_STALL;
         }

      // Unconfigure endpoints
      } else {
         usbfwData.usbState = DEV_ADDRESS;
         usbfwSetAllEpStatus(EP_HALT);
      }
      usbsrHookProcessEvent(USBSR_EVENT_CONFIGURATION_CHANGED, 0);
   }

} // usbsrSetConfiguration




/** \brief Processes the \ref GET_INTERFACE request (returns the selected alternate setting for the
 * specified interface)
 *
 * Some USB devices have configurations with mutually exclusive interface settings. This request allows
 * the host to determine the currently selected alternate setting.
 *
 * <b>Parameters</b>:
 * - VALUE: Always 0
 * - INDEX: Interface number
 * - LENGTH: Always 1
 *
 * <b>Data (IN)</b>:
 * The alternate setting for the selected interface
 */
void usbsrGetInterface(void) {

   // Sanity check
   if ((usbfwData.usbState != DEV_CONFIGURED) || (usbSetupHeader.requestType != RT_IN_INTERFACE) || usbSetupHeader.value || (usbSetupHeader.length != 1)) {
      usbfwData.ep0Status = EP_STALL;

   // Return the current alternate setting
   } else {
      usbSetupData.pBuffer = &usbfwData.pAlternateSetting[usbSetupHeader.index];
      usbSetupData.bytesLeft = 1;
      usbfwData.ep0Status = EP_TX;
   }

} // usbsrGetInterface




/** \brief Processes the \ref SET_INTERFACE request (selects an alternate setting for the specified
 * interface)
 *
 * Some USB devices have configurations with mutually exclusive interface settings. This request allows
 * the host to select the desired alternate setting.
 *
 * This function uses the \c ConfigureEndpoints() to automatically setup the relevant endpoint
 * registers.
 *
 * <b>Parameters</b>:
 * - VALUE: Alternate setting
 * - INDEX: Interface number
 * - LENGTH: Always 0
 */
void usbsrSetInterface(void) {
   USB_INTERFACE_DESCRIPTOR __xdata *pInterface;

   // Sanity check
   if ((usbfwData.usbState != DEV_CONFIGURED) || (usbSetupHeader.requestType != RT_OUT_INTERFACE) || usbSetupHeader.length) {
      usbfwData.ep0Status = EP_STALL;

   // Verify that the desired alternate setting is available, and then make the switch
   } else {
      if (pInterface = usbdpGetInterfaceDesc(usbfwData.configurationValue, usbSetupHeader.index, usbSetupHeader.value)) {
         usbsrHookProcessEvent(USBSR_EVENT_INTERFACE_CHANGING, usbSetupHeader.index);
         usbfwData.pAlternateSetting[usbSetupHeader.index] = usbSetupHeader.value;

         // Configure all endpoints in this interface
         ConfigureEndpoints(pInterface);
         usbsrHookProcessEvent(USBSR_EVENT_INTERFACE_CHANGED, usbSetupHeader.index);

      // This interface does not exist
      } else {
         usbfwData.ep0Status = EP_STALL;
      }
   }

} // usbsrSetInterface

//@}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -