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

📄 f3xx_usb0_standard_requests.c

📁 用c8051做的usb鼠标(HID类)Firmware works with the Silicon Labs IDE v1.71 or later and the Keil C51 tool cha
💻 C
📖 第 1 页 / 共 2 页
字号:

//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include "c8051f3xx.h"
#include "F3xx_USB0_Register.h"
#include "F3xx_USB0_InterruptServiceRoutine.h"
#include "F3xx_USB0_Descriptor.h"
#include "F3xx_USB0_ReportHandler.h"

//-----------------------------------------------------------------------------
// Variables
//-----------------------------------------------------------------------------
extern device_descriptor DEVICEDESC;   // These are created in F3xx_USB0_Descriptor.h
extern unsigned char* STRINGDESCTABLE[];

// Additional declarations for HID:
extern hid_configuration_descriptor 	HIDCONFIGDESC;
extern hid_report_descriptor 			HIDREPORTDESC;

extern setup_buffer SETUP;             // Buffer for current device request
									   // information
extern unsigned int DATASIZE;
extern unsigned int DATASENT;
extern unsigned char* DATAPTR;

// These are response packets used for
code unsigned char ONES_PACKET[2] = {0x01, 0x00};
// communication with host
code unsigned char ZERO_PACKET[2] = {0x00, 0x00};

extern unsigned char USB0_STATE;       // Determines current usb device state

//-----------------------------------------------------------------------------
// Definitions
//-----------------------------------------------------------------------------
// Redefine existing variable names to refer to the descriptors within the
// HID configuration descriptor.
// This minimizes the impact on the existing source code.
#define ConfigDesc 		(HIDCONFIGDESC.hid_configuration_descriptor)
#define InterfaceDesc 	(HIDCONFIGDESC.hid_interface_descriptor)
#define HidDesc 		(HIDCONFIGDESC.hid_descriptor)
#define Endpoint1Desc 	(HIDCONFIGDESC.hid_endpoint_in_descriptor)
#define Endpoint2Desc 	(HIDCONFIGDESC.hid_endpoint_out_descriptor)

//-----------------------------------------------------------------------------
// Get_Status
//-----------------------------------------------------------------------------
//
// Return Value - None
// Parameters - None
//
// Standard request that should not change for custom HID designs.
//
// ----------------------------------------------------------------------------
void Get_Status (void)                 // This routine returns a two byte
{                                      // status packet to the host

   if (SETUP.wValue.c[MSB] || SETUP.wValue.c[LSB] ||
                                       // If non-zero return length or data
                                       // length not
   SETUP.wLength.c[MSB]    || (SETUP.wLength.c[LSB] != 2))
                                       // equal to 2 then send a stall
   {                                   // indicating invalid request
      Force_Stall ();
   }

   switch(SETUP.bmRequestType)         // Determine if recipient was device,
   {								   // interface, or EP
      case OUT_DEVICE:                 // If recipient was device
         if (SETUP.wIndex.c[MSB] || SETUP.wIndex.c[LSB])
         {
            Force_Stall ();            // Send stall if request is invalid
         }
         else
         {
			// Otherwise send 0x00, indicating bus power and no
			// remote wake-up supported
            DATAPTR = (unsigned char*)&ZERO_PACKET;
            DATASIZE = 2;
         }
         break;

      case OUT_INTERFACE:              // See if recipient was interface
         if ((USB0_STATE != DEV_CONFIGURED) ||
         SETUP.wIndex.c[MSB] || SETUP.wIndex.c[LSB])
                                       // Only valid if device is configured
                                       // and non-zero index
         {
            Force_Stall ();            // Otherwise send stall to host
         }
         else
         {
			// Status packet always returns 0x00
            DATAPTR = (unsigned char*)&ZERO_PACKET;
            DATASIZE = 2;
         }
         break;

      case OUT_ENDPOINT:               // See if recipient was an endpoint
         if ((USB0_STATE != DEV_CONFIGURED) ||
         SETUP.wIndex.c[MSB])          // Make sure device is configured
         							   // and index msb = 0x00
         {                             // otherwise return stall to host
            Force_Stall();
         }
         else
         {
			// Handle case if request is directed to EP 1
            if (SETUP.wIndex.c[LSB] == IN_EP1)
            {
               if (EP_STATUS[1] == EP_HALT)
               {                       // If endpoint is halted,
               						   // return 0x01,0x00
                  DATAPTR = (unsigned char*)&ONES_PACKET;
                  DATASIZE = 2;
               }
               else
               {
				  // Otherwise return 0x00,0x00 to indicate endpoint active
                  DATAPTR = (unsigned char*)&ZERO_PACKET;
                  DATASIZE = 2;
               }
            }
            else
            {
               Force_Stall ();         // Send stall if unexpected data
               				           // encountered
            }
         }
         break;

      default:
         Force_Stall ();
         break;
   }
   if (EP_STATUS[0] != EP_STALL)
   {
	  // Set serviced SETUP Packet, Endpoint 0 in transmit mode, and
	  // reset DATASENT counter
      POLL_WRITE_BYTE (E0CSR, rbSOPRDY);
      EP_STATUS[0] = EP_TX;
      DATASENT = 0;
   }
}

//-----------------------------------------------------------------------------
// Clear_Feature
//-----------------------------------------------------------------------------
//
// Return Value - None
// Parameters - None
//
// Standard request that should not change in custom HID designs.
//
//-----------------------------------------------------------------------------
void Clear_Feature ()                  // This routine can clear Halt Endpoint
{                                      // features on endpoint 1

   // Send procedural stall if device isn't configured
   if ( (USB0_STATE != DEV_CONFIGURED) ||
   // or request is made to host(remote wakeup not supported)
   (SETUP.bmRequestType == IN_DEVICE) ||
   // or request is made to interface
   (SETUP.bmRequestType == IN_INTERFACE) ||
   // or msbs of value or index set to non-zero value
   SETUP.wValue.c[MSB]  || SETUP.wIndex.c[MSB] ||
   // or data length set to non-zero.
   SETUP.wLength.c[MSB] || SETUP.wLength.c[LSB])
   {
      Force_Stall ();
   }

   else
   {
	   // Verify that packet was directed at an endpoint
      if ( (SETUP.bmRequestType == IN_ENDPOINT)&&
      // the feature selected was HALT_ENDPOINT
      (SETUP.wValue.c[LSB] == ENDPOINT_HALT)  &&
      // and that the request was directed at EP 1 in
      ((SETUP.wIndex.c[LSB] == IN_EP1) ) )
      {
         if (SETUP.wIndex.c[LSB] == IN_EP1)
         {
            POLL_WRITE_BYTE (INDEX, 1);// Clear feature endpoint 1 halt
            POLL_WRITE_BYTE (EINCSR1, rbInCLRDT);
            EP_STATUS[1] = EP_IDLE;    // Set endpoint 1 status back to idle
         }
      }
      else
      {
         Force_Stall ();               // Send procedural stall
      }
   }
   POLL_WRITE_BYTE (INDEX, 0);         // Reset Index to 0
   if (EP_STATUS[0] != EP_STALL)
   {
      POLL_WRITE_BYTE (E0CSR, (rbSOPRDY | rbDATAEND));
	                                   // Set Serviced Out packet ready and
                                       // data end to indicate transaction
                                       // is over
   }
}

//-----------------------------------------------------------------------------
// Set_Feature
//-----------------------------------------------------------------------------
//
// Return Value - None
// Parameters - None
//
// Standard request that should not change in custom HID designs.
//
//-----------------------------------------------------------------------------
void Set_Feature (void)                // This routine will set the EP Halt
{                                      // feature for endpoint 1

   // Make sure device is configured, SETUP data
   if ((USB0_STATE != DEV_CONFIGURED) ||
   // is all valid and that request is directed at an endpoint
   (SETUP.bmRequestType == IN_DEVICE) ||
   (SETUP.bmRequestType == IN_INTERFACE) ||
   SETUP.wValue.c[MSB]  || SETUP.wIndex.c[MSB] ||
   SETUP.wLength.c[MSB] || SETUP.wLength.c[LSB])
   {
      Force_Stall ();                  // Otherwise send stall to host
   }

   else
   {
	  // Make sure endpoint exists and that halt
      if ( (SETUP.bmRequestType == IN_ENDPOINT)&&
      // endpoint feature is selected
      (SETUP.wValue.c[LSB] == ENDPOINT_HALT) &&
      ((SETUP.wIndex.c[LSB] == IN_EP1)        ||
      (SETUP.wIndex.c[LSB] == OUT_EP2) ) )
      {
         if (SETUP.wIndex.c[LSB] == IN_EP1)
         {
            POLL_WRITE_BYTE (INDEX, 1);// Set feature endpoint 1 halt
            POLL_WRITE_BYTE (EINCSR1, rbInSDSTL);
            EP_STATUS[1] = EP_HALT;
         }
      }
      else
      {
         Force_Stall ();               // Send procedural stall
      }
   }
   POLL_WRITE_BYTE (INDEX, 0);
   if (EP_STATUS[0] != EP_STALL)
   {
      POLL_WRITE_BYTE (E0CSR, (rbSOPRDY | rbDATAEND));
                                       // Indicate SETUP packet has been
                                       // serviced
   }
}

//-----------------------------------------------------------------------------
// Set_Address
//-----------------------------------------------------------------------------
//
// Return Value - None
// Parameters - None
//
// Standard request that should not change in custom HID designs.
//
//-----------------------------------------------------------------------------
void Set_Address (void)                // Set new function address
{
   // Request must be directed to device
   if ((SETUP.bmRequestType != IN_DEVICE) ||
   // with index and length set to zero.
   SETUP.wIndex.c[MSB]  || SETUP.wIndex.c[LSB]||
   SETUP.wLength.c[MSB] || SETUP.wLength.c[LSB]||
   SETUP.wValue.c[MSB]  || (SETUP.wValue.c[LSB] & 0x80))
   {
     Force_Stall ();                   // Send stall if SETUP data invalid
   }

   EP_STATUS[0] = EP_ADDRESS;          // Set endpoint zero to update
   									   // address next status phase
   if (SETUP.wValue.c[LSB] != 0)
   {
      USB0_STATE = DEV_ADDRESS;        // Indicate that device state is now
      								   // address
   }
   else
   {
      USB0_STATE = DEV_DEFAULT;        // If new address was 0x00, return
   }                                   // device to default state
   if (EP_STATUS[0] != EP_STALL)
   {
      POLL_WRITE_BYTE (E0CSR, (rbSOPRDY | rbDATAEND));
                                       // Indicate SETUP packet has
                                       // been serviced
   }
}

//-----------------------------------------------------------------------------
// Get_Descriptor
//-----------------------------------------------------------------------------
//
// Return Value - None
// Parameters - None
//
// Standard request that should not change in custom HID designs.
//
//-----------------------------------------------------------------------------
void Get_Descriptor (void)             // This routine sets the data pointer
{                                      // and size to correct descriptor and
                                       // sets the endpoint status to transmit

   switch(SETUP.wValue.c[MSB])         // Determine which type of descriptor
   {                                   // was requested, and set data ptr and
      case DSC_DEVICE:                 // size accordingly
         DATAPTR = (unsigned char*) &DEVICEDESC;
         DATASIZE = DEVICEDESC.bLength;
         break;

      case DSC_CONFIG:
         DATAPTR = (unsigned char*) &ConfigDesc;
                                       // Compiler Specific - The next statement
                                       // reverses the bytes in the configuration
                                       // descriptor for the compiler
         DATASIZE = ConfigDesc.wTotalLength.c[MSB] +
                    256*ConfigDesc.wTotalLength.c[LSB];
         break;

	  case DSC_STRING:
         DATAPTR = STRINGDESCTABLE[SETUP.wValue.c[LSB]];
		                               // Can have a maximum of 255 strings
         DATASIZE = *DATAPTR;
         break;

      case DSC_INTERFACE:
         DATAPTR = (unsigned char*) &InterfaceDesc;
         DATASIZE = InterfaceDesc.bLength;
         break;

      case DSC_ENDPOINT:
         if ( (SETUP.wValue.c[LSB] == IN_EP1) )

⌨️ 快捷键说明

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