STM32 usb_prop.c file analysis and some data definition analysis of usb_core.h

Publisher:创意火舞Latest update time:2016-12-20 Source: eefocusKeywords:STM32  usb_prop.c  usb_core.h Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

The usb_prop.c file is a very important file because many USB processing functions are defined here. Some processing in the USB establishment phase, data phase or status phase is in this file, and the USB standard function request function is also in this file.

usb_prop.c starts with a series of structures, as follows:

DEVICE Device_Table =

{

    EP_NUM, //Number of endpoints used

    1 //The number of endpoints that can be used

};


DEVICE_PROP Device_Property = //Register some CustomHID functions

{

    CustomHID_init, //CustomHID initialization function

    CustomHID_Reset, //CustomHID reset function

    CustomHID_Status_In, //CustomHID status input function

    CustomHID_Status_Out, //CustomHID status output function

    CustomHID_Data_Setup, //CustomHID processing has a special class request function in the data stage

    CustomHID_NoData_Setup, //CustomHID processing no data stage special class request function

    CustomHID_Get_Interface_Setting, //CustomHID gets the interface and backup interface settings (whether available)  

    CustomHID_GetDeviceDescriptor, //CustomHID gets the device descriptor

    CustomHID_GetConfigDescriptor, //CustomHID gets the configuration descriptor

    CustomHID_GetStringDescriptor, //CustomHID gets string descriptor

    0, //Current library is not used

    0x40 /*MAX PACKET SIZE*/ //The maximum packet length is 64 bytes

};


/*Register USB standard request implementation function*/

USER_STANDARD_REQUESTS User_Standard_Requests =

{

    CustomHID_GetConfiguration, //Get configuration request

    CustomHID_SetConfiguration, //Set configuration request

    CustomHID_GetInterface, //Get interface request

    CustomHID_SetInterface, //Set interface request

    CustomHID_GetStatus, //Get status request

    CustomHID_ClearFeature, //Clear attribute request

    CustomHID_SetEndPointFeature, //Set endpoint attribute request

    CustomHID_SetDeviceFeature, //Set device attribute request

    CustomHID_SetDeviceAddress //Set device address request

};


/*Register device descriptor information*/

ONE_DESCRIPTOR Device_Descriptor =  

{

    (uint8_t*)CustomHID_DeviceDescriptor, //Register device descriptor array

    CUSTOMHID_SIZ_DEVICE_DESC //The length of the device descriptor

};


/*Register device descriptor information*/

ONE_DESCRIPTOR Config_Descriptor =

{

    (uint8_t*)CustomHID_ConfigDescriptor, //Register configuration descriptor array

    CUSTOMHID_SIZ_CONFIG_DESC //Configuration descriptor length

};


/*Register report descriptor information*/

ONE_DESCRIPTOR CustomHID_Report_Descriptor =

{

    (uint8_t *)CustomHID_ReportDescriptor, //Register report descriptor array

    CUSTOMHID_SIZ_REPORT_DESC //The length of the report descriptor

};


/*Register HID descriptor information*/

ONE_DESCRIPTOR CustomHID_Descriptor =

{

    (uint8_t*)CustomHID_ConfigDescriptor + CUSTOMHID_OFF_HID_DESC, //Register HID descriptor array

    CUSTOMHID_SIZ_HID_DESC //The length of the HID array

};


/*Register string descriptors, including language ID, manufacturer, product, and serial number descriptors*/

ONE_DESCRIPTOR String_Descriptor[4] =

{

    {(uint8_t*)CustomHID_StringLangID, CUSTOMHID_SIZ_STRING_LANGID}, //Register language string descriptor array

    {(uint8_t*)CustomHID_StringVendor, CUSTOMHID_SIZ_STRING_VENDOR}, //Registered vendor string descriptor array

    {(uint8_t*)CustomHID_StringProduct, CUSTOMHID_SIZ_STRING_PRODUCT}, //Register product string descriptor array

    {(uint8_t*)CustomHID_StringSerial, CUSTOMHID_SIZ_STRING_SERIAL} //Register serial number string descriptor array

};


It should be clear that this series of structures is to register some processing functions. Let's analyze them one by one.

Let's talk about the DEVICE Device_Table structure first. The DEVICE structure type is defined in usb_core.h:

typedef struct _DEVICE

{

  uint8_t Total_Endpoint; /*Number of endpoints used*/

  uint8_t Total_Configuration;/*Number of endpoints that can be used*/

}

DEVICE;


This structure type is very simple. It defines the endpoints that have been used and the endpoints that have not been used. Putting the two together facilitates query and management.




Next, let’s talk about DEVICE_PROP

 Device_Property is a structure of this type. The first 10 elements of this structure are all function pointer types. Some commonly used functions are placed here, and the function definitions are defined after this structure. Do you feel like a key sentence in Chinese? The outline of the entire file is condensed in this structure. Just by looking at this structure, you can understand what the entire file does. This structure is also very convenient to use. For example, if I want to use the CustomHID_init function, I just need to write Device_Property.CustomHID_init. We must learn this method.

The DEVICE_PROP structure type is still defined in usb_core.h:

typedef struct _DEVICE_PROP

{

  void (*Init)(void); /*Initialize device*/

  void (*Reset)(void); /*Reset the device*/


  /* There are three processes in control transmission: 1. Establishment process, 2. Optional data process, 3. Status process*/

  /* Device dependent process after the status stage */

  void (*Process_Status_IN)(void);/*Processing IN token packet*/

  void (*Process_Status_OUT)(void);/*Processing OUT token packet*/


  /*During the establishment phase, there will be many special class request data stages */

  /*All special class requests in the data phase are handled in the Class_Data_Setup() function

   Class_Data_Setup() will respond to all special class requests and fill in the ENDPOINT_INFO structure information according to the request

If the IN token packet is the expected token packet, the wLength and wOffset fields are filled with the total number of bytes to be sent and the position to start the transmission, respectively. 

If the OUT token packet is the expected token packet, rLength and rOffser will be filled with the total number of bytes to be received and the starting address of the buffer to receive the data, respectively.

    If the request is valid, Class_Data_Setup returns SUCCESS, otherwise it returns UNSUPPORT


    Notice:

Because the GET_CONFIGURATION and GET_INTERFACE requests are closely related to individual classes, they will be checked and processed in this function*/

  RESULT (*Class_Data_Setup)(uint8_t RequestNo);


  /*During the establishment process, there will be many data-free stages for special class requests*/

  /*All special requests without data phase are handled in the Class_NoData_Setup function 

   Class_NoData_Setup() 

   Will respond to check all special class requests and execute the requests

   Notice:

   Because the two requests SET_CONFIGURATION and SET_INTERFACE are closely related to individual classes, they will be checked and processed in this function*/

  RESULT (*Class_NoData_Setup)(uint8_t RequestNo);


  /*Class_Get_Interface_Setting()

   This function is called in the usb_core.c file to test whether the application supports the selected interface and the alternate interface.

   This function is written by the user. If the application supports the interface and the alternate interface, it must return "SUCCESS", otherwise, it returns "UNSUPPORT"*/


  RESULT  (*Class_Get_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting);


  uint8_t* (*GetDeviceDescriptor)(uint16_t Length);

  uint8_t* (*GetConfigDescriptor)(uint16_t Length);

  uint8_t* (*GetStringDescriptor)(uint16_t Length);


  /* This field is not used in the current library version. It is only kept for compatibility with previous versions */

  void* RxEP_buffer;

   

  uint8_t MaxPacketSize;


}DEVICE_PROP;





Next is the USER_STANDARD_REQUESTS User_Standard_Requests structure, which mainly registers the implementation functions of USB standard requests. Of course, these functions are also defined after this structure.

 The Device_Property structure is similar, so I won’t go into details.

The USER_STANDARD_REQUESTS structure is also defined in usb_core.h:

typedef struct _USER_STANDARD_REQUESTS

{

  void (*User_GetConfiguration)(void); /*Get configuration*/

  void (*User_SetConfiguration)(void); /*Set configuration*/

  void (*User_GetInterface)(void); /*Get interface*/

  void (*User_SetInterface)(void); /*Set interface*/

  void (*User_GetStatus)(void); /*Get status*/

  void (*User_ClearFeature)(void); /*Clear feature*/

  void (*User_SetEndPointFeature)(void); /*Set endpoint features*/

  void (*User_SetDeviceFeature)(void); /*Set device features*/

  void (*User_SetDeviceAddress)(void); /*Set device address*/

}

USER_STANDARD_REQUESTS;



Structures like ONE_DESCRIPTOR Device_Descriptor, ONE_DESCRIPTOR Config_Descriptor, ONE_DESCRIPTOR CustomHID_Report_Descriptor, ONE_DESCRIPTOR CustomHID_Descriptor, and ONE_DESCRIPTOR String_Descriptor[4] are not explained in detail. Here are the definitions of each structure, which are still in usb_core.h:

typedef struct OneDescriptor

{

  uint8_t *Descriptor;

  uint16_t Descriptor_Size;

}

ONE_DESCRIPTOR, *PONE_DESCRIPTOR;



Next, paste the functions registered by each structure above:

/*******************************************************************************

* Function Name  : CustomHID_init.

* Description: CustomHID Mouse init routine. Initialization

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void CustomHID_init(void)

{


  /* Update the serial number string descriptor with the data from the unique

  ID*/

  Get_SerialNum(); //Get the serial number


  pInformation->Current_Configuration = 0;

  /* Connect the device */

  PowerOn(); //Power on


  /* Perform basic device initialization operations */

  USB_SIL_Init(); //Perform basic initialization operations, such as initialization of device IP and endpoint 0


  bDeviceState = UNCONNECTED; //Set the state to unconnected

}


/*******************************************************************************

* Function Name  : CustomHID_Reset.

* Description    : CustomHID Mouse reset routine.复位

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void CustomHID_Reset(void)

{

  /* Set CustomHID_DEVICE as not configured */

  pInformation->Current_Configuration = 0; //Set the current configuration to 0, indicating that it has not been configured

  pInformation->Current_Interface = 0; //Default interface


  /* Current Feature initialization */

  pInformation->Current_Feature = CustomHID_ConfigDescriptor[7]; //Current attributes, bmAttributes: some characteristics of the device, 0xc0 means self-powered, does not support remote wake-up


#ifdef STM32F10X_CL   

  /* EP0 is already configured in DFU_Init() by USB_SIL_Init() function */

  

  /* Init EP1 IN snd EP1 OUT as Interrupt endpoint */

  OTG_DEV_EP_Init(EP1_IN, OTG_DEV_EP_TYPE_INT, EP1_SIZE);

  OTG_DEV_EP_Init(EP1_OUT, OTG_DEV_EP_TYPE_INT, EP1_SIZE);

#else 


  SetBTABLE(BTABLE_ADDRESS);


  /* Initialize Endpoint 0 */

  SetEPType(ENDP0, EP_CONTROL); //Set endpoint 1 as the control endpoint

  SetEPTxStatus(ENDP0, EP_TX_STALL); //Set endpoint 0 send delay

  SetEPRxAddr(ENDP0, ENDP0_RXADDR); //Set the receive buffer address of endpoint 0

  SetEPTxAddr(ENDP0, ENDP0_TXADDR); //Set the send buffer address of endpoint 0

  Clear_Status_Out(ENDP0); //Clear the status of endpoint 0

  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); //Set the receive count of endpoint 0

  SetEPRxValid(ENDP0); //Enable receiving status


  /* Initialize Endpoint 1 */

     SetEPType(ENDP1, EP_INTERRUPT); //Set endpoint 1 as interrupt control endpoint

     SetEPRxAddr(ENDP1, ENDP1_RXADDR); //Set the receive buffer address of endpoint 1

     SetEPRxCount(ENDP1, REPORT_COUNT); //Set the receive count of endpoint 1

     SetEPRxStatus(ENDP1, EP_RX_VALID); //Set endpoint 1 to receive valid

     //SetEPTxStatus(ENDP1, EP_TX_DIS);


  /* Initialize Endpoint 2 */

     SetEPType(ENDP2, EP_INTERRUPT); //Set endpoint 2 as interrupt control endpoint

     SetEPTxAddr(ENDP2, ENDP2_TXADDR); //Set the receive buffer address of endpoint 2

     SetEPTxCount(ENDP2, REPORT_COUNT); //Set the receive count of endpoint 2

    // SetEPTxStatus(ENDP2, EP_TX_DIS);

     SetEPTxStatus(ENDP2, EP_TX_NAK); //Set endpoint 2 to receive no response


     bDeviceState = ATTACHED; //Set the device state to ATTACHED state

  /* Set this device to response on default address */

  SetDeviceAddress(0); //Set the device to the default address

#endif /* STM32F10X_CL */


  bDeviceState = ATTACHED;

}

/*******************************************************************************

* Function Name  : CustomHID_SetConfiguration.

* Description: Update device configuration status

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void CustomHID_SetConfiguration(void)

{

  DEVICE_INFO *pInfo = &Device_Info;


  if (pInfo->Current_Configuration != 0)

  {

    /* Device configured */

    bDeviceState = CONFIGURED;

  }

}

/*******************************************************************************

* Function Name  : CustomHID_SetConfiguration.

* Description: Update the addressing status of the device

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void CustomHID_SetDeviceAddress (void)

{

  bDeviceState = ADDRESSED;

}

/*******************************************************************************

* Function Name  : CustomHID_Status_In.

* Description: Status input function

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void CustomHID_Status_In(void)

{}


/*******************************************************************************

* Function Name  : CustomHID_Status_Out

* Description: Status output function

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void CustomHID_Status_Out(void)

{}


/*******************************************************************************

* Function Name  : CustomHID_Data_Setup

* Description: Process special type requests with data phase

* Input          : Request Nb.

* Output         : None.

* Return         : USB_UNSUPPORT or USB_SUCCESS.

*******************************************************************************/

RESULT CustomHID_Data_Setup(uint8_t RequestNo)

{

  uint8_t *(*CopyRoutine)(uint16_t); //Define a pointer to a function pointer


  CopyRoutine = NULL;

  if ((RequestNo == GET_DESCRIPTOR) //It is a GET_DESCRIPTOR request, see circle P75

      && (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) //The request type is a standard request, and the recipient of the request is an interface

      && (pInformation->USBwIndex0 == 0)) //Other descriptors other than language ID string descriptors

  {


    if (pInformation->USBwValue1 == REPORT_DESCRIPTOR) //It is the report descriptor

    {

      CopyRoutine = CustomHID_GetReportDescriptor; //CopyRoutine points to the function pointer to get the report descriptor

    }

    else if (pInformation->USBwValue1 == HID_DESCRIPTOR_TYPE) // is the HID descriptor

    {

      CopyRoutine = CustomHID_GetHIDDescriptor; //CopyRoutine points to the function pointer to get the HID descriptor

    }


  } /* End of GET_DESCRIPTOR */


  /*** GET_PROTOCOL ***/

  else if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) //The request type is a class request and the recipient is an interface request

           && RequestNo == GET_PROTOCOL) //Get the protocol

  {

    CopyRoutine = CustomHID_GetProtocolValue; //Get the value of the protocol

  }



  if (CopyRoutine == NULL) //If the length is 0, CopyRoutine=NULL

  {

    return USB_UNSUPPORT; //USB is not connected

  }


  pInformation->Ctrl_Info.CopyData = CopyRoutine; //注册CopyData函数

  pInformation->Ctrl_Info.Usb_wOffset = 0; //Data offset

  (*CopyRoutine)(0); //Call CopyData() function

  return USB_SUCCESS;  //返回 USB_SUCCESS

}


/*******************************************************************************

* Function Name  : CustomHID_NoData_Setup

* Description: Handle special class requests without data phase

* Input          : Request Nb.

* Output         : None.

* Return         : USB_UNSUPPORT or USB_SUCCESS.

*******************************************************************************/

RESULT CustomHID_NoData_Setup(uint8_t RequestNo)

{

  if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) //Class request, interface reception

      && (RequestNo == SET_PROTOCOL)) //Set the protocol

  {

    return CustomHID_SetProtocol();

  }


  else

  {

    return USB_UNSUPPORT;

  }

}


/*******************************************************************************

* Function Name  : CustomHID_GetDeviceDescriptor.

* Description: Get device descriptor

* Input          : Length

* Output         : None.

* Return         : The address of the device descriptor.

*******************************************************************************/

uint8_t *CustomHID_GetDeviceDescriptor(uint16_t Length)

{

  return Standard_GetDescriptorData(Length, &Device_Descriptor);

}


/*******************************************************************************

* Function Name  : CustomHID_GetConfigDescriptor.

* Description: Get configuration descriptor

* Input          : Length

* Output         : None.

* Return         : The address of the configuration descriptor.

*******************************************************************************/

uint8_t *CustomHID_GetConfigDescriptor(uint16_t Length)

{

  return Standard_GetDescriptorData(Length, &Config_Descriptor);

}


/*******************************************************************************

* Function Name  : CustomHID_GetStringDescriptor

* Description: Get the character descriptor according to the index

* Input          : Length

* Output         : None.

* Return         : The address of the string descriptors.

*******************************************************************************/

uint8_t *CustomHID_GetStringDescriptor(uint16_t Length)

{

  uint8_t wValue0 = pInformation->USBwValue0;

  if (wValue0 > 4)

  {

    return NULL;

  }

  else

  {

    return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);

  }

}


/*******************************************************************************

* Function Name  : CustomHID_GetReportDescriptor.

* Description: Get report descriptor

* Input          : Length

* Output         : None.

* Return         : The address of the configuration descriptor.

*******************************************************************************/

uint8_t *CustomHID_GetReportDescriptor(uint16_t Length)

{

  return Standard_GetDescriptorData(Length, &CustomHID_Report_Descriptor);

}


/*******************************************************************************

* Function Name  : CustomHID_GetHIDDescriptor.

* Description: Get HID descriptor

* Input          : Length

* Output         : None.

* Return         : The address of the configuration descriptor.

*******************************************************************************/

uint8_t *CustomHID_GetHIDDescriptor(uint16_t Length)

{

  return Standard_GetDescriptorData(Length, &CustomHID_Descriptor);

}


/*******************************************************************************

* Function Name  : CustomHID_Get_Interface_Setting.

* Description: Test whether the interface and its backup interface are available

* Input          : - Interface : interface number.

*                  - AlternateSetting : Alternate Setting number.

* Output         : None.

* Return         : USB_SUCCESS or USB_UNSUPPORT.

*******************************************************************************/

RESULT CustomHID_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)

{

  if (AlternateSetting > 0) //The alternate number is greater than 0

  {

    return USB_UNSUPPORT;

  }

  else if (Interface > 0) //The interface number is greater than 0

  {

    return USB_UNSUPPORT;

  }

  return USB_SUCCESS;

}


/*******************************************************************************

* Function Name  : CustomHID_SetProtocol

* Description: Set the protocol request function used by the interface

* Input          : None.

* Output         : None.

* Return         : USB SUCCESS.

*******************************************************************************/

RESULT CustomHID_SetProtocol(void)

{

  uint8_t wValue0 = pInformation->USBwValue0; //Get the USBwValue value in the device information

  ProtocolValue = wValue0;  

  return USB_SUCCESS;

}


/*******************************************************************************

* Function Name  : CustomHID_GetProtocolValue

* Description: Get the value of the protocol

* Input          : Length.

* Output         : None.

* Return         : address of the protcol value.

*******************************************************************************/

uint8_t *CustomHID_GetProtocolValue(uint16_t Length)

{

  if (Length == 0) //Length is 0

  {

    pInformation->Ctrl_Info.Usb_wLength = 1; //The length to be sent is 1

    return NULL;

  }

  else

  {

    return (uint8_t *)(&ProtocolValue); //Return the value of the protocol

  }

}


Keywords:STM32  usb_prop.c  usb_core.h Reference address:STM32 usb_prop.c file analysis and some data definition analysis of usb_core.h

Previous article:STM32 USB related registers
Next article:STM32 usb_pwr.c file analysis

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号