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

📄 usb_standard_requests.c

📁 reference about wireless design which is helpful to everyone
💻 C
📖 第 1 页 / 共 2 页
字号:
/// \addtogroup module_usb_standard_requests
/// @{
#include "cc2511_usb_library_headers.h"


// Internal module data
__no_init static WORD __xdata status; ///< 16-bit buffer used with GET_STATUS




/** \brief Processes the \ref GET_STATUS request (returns status for the specified recipient)
 *
 * The recipient bits in \ref USB_SETUP_HEADER.requestType specify the desired recipient. This is either the
 * (one and only) device, a specific interface, or a specific endpoint. Some of the status bits can be
 * changed with the SET_FEATURE and CLEAR_FEATURE requests.
 *
 * <b>Parameters</b>:
 * - VALUE: Always 0
 * - INDEX: Depends upon the recipient:
 *     - DEVICE: Always 0
 *     - INTERFACE: Interface number
 *     - ENDPOINT: Endpoint address
 * - LENGTH: Always 2
 *
 * <b>Data (IN)</b>:
 * Depends upon the recipient (the bit field illustrations are MSB first, LSB last):
 * - DEVICE: <tt>00000000.000000RS</tt>, where R(1) = DEVICE_REMOTE_WAKEUP and S(0) = SELF_POWERED
 * - INTERFACE: <tt>00000000.00000000</tt> (all bits are reserved)
 * - ENDPOINT: <tt>00000000.0000000H</tt>, where H(0) = ENDPOINT_HALT
 */
void usbsrGetStatus(void) {
   UINT8 endpoint;

   // Common sanity check
   if (usbSetupHeader.value || HIBYTE(usbSetupHeader.index) || (usbSetupHeader.length != 2)) {
      usbfwData.ep0Status = EP_STALL;

   // Return status for device, interface, or endpoint
   } else {
      switch (usbSetupHeader.requestType) {

         // Device status:
         //     Bit 0: Self powered
         //     Bit 1: Remote wake-up allowed
      case RT_IN_DEVICE:

         // Sanity check
         if (LOBYTE(usbSetupHeader.index)) {
            usbfwData.ep0Status = EP_STALL;

         // Get the bit values from the USBFW_DATA struct
         } else {

            // Self powered?
            status = usbfwData.selfPowered ? 0x0001 : 0x0000;

            // Remote wakeup?
            if (usbfwData.remoteWakeup) status |= 0x0002;
         }
         break;

         // Interface status:
         //     All bits are reserved
      case RT_IN_INTERFACE:

         // Sanity check
         if (usbfwData.usbState != DEV_CONFIGURED) {
            usbfwData.ep0Status = EP_STALL;
         } else {
            status = 0x0000;
         }
         break;

         // Endpoint status:
         //     Bit 0: Endpoint halted
      case RT_IN_ENDPOINT:
         endpoint = LOBYTE(usbSetupHeader.index) & 0x7F;

         // Sanity check
         if ((usbfwData.usbState != DEV_CONFIGURED) || (endpoint > 5)) {
            usbfwData.ep0Status = EP_STALL;

         // Translate endpoint address to status index and return the status
         } else {

            // IN
            if (LOBYTE(usbSetupHeader.index) & 0x80) {
               status = (usbfwData.pEpInStatus[endpoint] == EP_HALT) ? 0x0001 : 0x0000;

            // OUT
            } else {
               status = (usbfwData.pEpOutStatus[endpoint] == EP_HALT) ? 0x0001 : 0x0000;
            }
         }
         break;

      default:
         usbfwData.ep0Status = EP_STALL;
         break;
      }

      if (usbfwData.ep0Status != EP_STALL) {

         // Let the application modify the status word
         usbsrHookModifyGetStatus(usbSetupHeader.requestType & RT_MASK_RECIP, LOBYTE(usbSetupHeader.index), &status);

         // Send it
         usbSetupData.pBuffer = (BYTE __xdata *) &status;
         usbSetupData.bytesLeft = 2;
         usbfwData.ep0Status = EP_TX;
      }
   }
} // usbsrGetStatus




/** \brief Internal function used for the very similar \ref SET_FEATURE and \ref CLEAR_FEATURE requests
 *
 * This function either sets or clears the specified feature on the specified recipient.
 *
 * \param[in]       set
 *     When TRUE, the feature is set. When FALSE, the feature is cleared.
 *
 * \return
 *     TRUE if the selected feature is supported by the USB framework. FALSE to indicate that
 *     \ref usbsrHookClearFeature() or \ref usbsrHookSetFeature() must be called.
 */
static BOOL ChangeFeature(BOOL set) {
   BYTE endpoint;

   // Sanity check
   if (usbSetupHeader.length || (usbfwData.usbState != DEV_CONFIGURED) && (usbSetupHeader.index != 0)) {
      usbfwData.ep0Status = EP_STALL;

      // Handle based on recipient
   } else {
      switch (usbSetupHeader.requestType & RT_MASK_RECIP) {

      // Device
      case RT_RECIP_DEV:

         // Sanity check
         if (LOBYTE(usbSetupHeader.value) != DEVICE_REMOTE_WAKEUP) {
            return FALSE;
         } else {
            usbfwData.remoteWakeup = set;
            usbsrHookProcessEvent(set ? USBSR_EVENT_REMOTE_WAKEUP_ENABLED : USBSR_EVENT_REMOTE_WAKEUP_DISABLED, 0);
         }
         break;

      // Endpoint
      case RT_RECIP_IF:
         return FALSE;

      // Endpoint
      case RT_RECIP_EP:
         endpoint = LOBYTE(usbSetupHeader.index) & 0x7F;

         // Sanity check
         if (LOBYTE(usbSetupHeader.value) != ENDPOINT_HALT) {
            return FALSE;
         } else if (endpoint > 5) {
            usbfwData.ep0Status = EP_STALL;
         } else {
            USBFW_SELECT_ENDPOINT(endpoint);

            // IN
            if (LOBYTE(usbSetupHeader.index) & 0x80) {
               USBCSIL = set ? USBCSIL_SEND_STALL : USBCSIL_CLR_DATA_TOG;
               usbfwData.pEpInStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE;
               usbsrHookProcessEvent(set ? USBSR_EVENT_EPIN_STALL_SET : USBSR_EVENT_EPIN_STALL_CLEARED, endpoint);

            // OUT
            } else {
               USBCSOL = set ? USBCSOL_SEND_STALL : USBCSOL_CLR_DATA_TOG;
               usbfwData.pEpOutStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE;
               usbsrHookProcessEvent(set ? USBSR_EVENT_EPOUT_STALL_SET : USBSR_EVENT_EPOUT_STALL_CLEARED, endpoint);
            }
            USBFW_SELECT_ENDPOINT(0);
         }
         break;

      default:
         usbfwData.ep0Status = EP_STALL;
         break;
      }
   }
   return TRUE;
} // ChangeFeature




/** \brief Processes the \ref CLEAR_FEATURE request (clears or disables a specific feature)
 *
 * The feature selector value must be appropriate to the recipient.
 *
 * <b>Parameters</b>:
 * - VALUE: Feature selector:
 *     - \c DEVICE_REMOTE_WAKEUP(1): Enable remote wakeup
 *     - \c ENDPOINT_HALT(0): Clear the halt feature for the specified endpoint (not endpoint 0!)
 * - INDEX: Depends upon the recipient:
 *     - DEVICE: Always 0
 *     - INTERFACE: Interface number
 *     - ENDPOINT: Endpoint address
 * - LENGTH: Always 0
 */
void usbsrClearFeature() {
   if (!ChangeFeature(FALSE)) {
      usbsrHookClearFeature();
   }
} // usbsrClearFeature




/** \brief Processes the \ref SET_FEATURE request (sets or enables a specific feature)
 *
 * The feature selector value must be appropriate to the recipient.
 *
 * <b>Parameters</b>:
 * - VALUE: Feature selector:
 *     - \c DEVICE_REMOTE_WAKEUP(1): Enable remote wakeup
 *     - \c ENDPOINT_HALT(0): Set the halt feature for the specified endpoint (not endpoint 0!)
 * - INDEX: Depends upon the recipient:
 *     - DEVICE: Always 0
 *     - INTERFACE: Interface number
 *     - ENDPOINT: Endpoint address
 * - LENGTH: Always 0
 */
void usbsrSetFeature(void) {
   if (!ChangeFeature(TRUE)) {
      usbsrHookSetFeature();
   }
} // usbsrSetFeature




/** \brief Processes the \ref SET_ADDRESS request (sets the device address for all future device
 * accesses)
 *
 * If the value is between 1 and 127 and the device is in the default state, it will enter the address
 * state. If it already is in the address state, it starts to use the newly-specified address.
 *
 * If the value is 0 and the device is in the address state, it will enter the default state. If it
 * already is in the default state, nothing happens.
 *
 * <b>Parameters</b>:
 * - VALUE: The device address (0-127)
 * - INDEX: Always 0
 * - LENGTH: Always 0
 */
void usbsrSetAddress(void) {

   // Sanity check
   if (usbSetupHeader.index || usbSetupHeader.length || HIBYTE(usbSetupHeader.value) || (LOBYTE(usbSetupHeader.value) & 0x80)) {
      usbfwData.ep0Status = EP_STALL;

   // Update the device address
   } else {
      USBADDR = LOBYTE(usbSetupHeader.value);
      if (LOBYTE(usbSetupHeader.value) != 0) {
         if (usbfwData.usbState == DEV_DEFAULT) usbfwData.usbState = DEV_ADDRESS;
      } else {
         if (usbfwData.usbState == DEV_ADDRESS) usbfwData.usbState = DEV_DEFAULT;
      }
   }

} // usbsrSetAddress




/** \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 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 (HIBYTE(usbSetupHeader.value)) {

   // Device descriptor

⌨️ 快捷键说明

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