Been reading through the USB document and going through the codes but still having a bit of trouble grasping the concept of an interface. What would constitute an "interface"? Does it encapsulate a class with the associated class methods? Where in the code does it bind the "interface" to the class? When the host request for an "interface", what would it get in return or what would be the purpose of asking for an interface? For example, if a device declares that it has three interface, how does it associates each interface to the actual firmware codes? Thanks.
> What would constitute an "interface"? Does it encapsulate a class with the associated class methods?
Interface is as name suggest a way to communicate with a device regarding one specific data exchange. A class can contain multiple interfaces, for example CDC class contains communication and data interfaces, over communication interface status changes are reported and over data interface data are exchanged in both directions.
> Where in the code does it bind the "interface" to the class? >For example, if a device declares that it has three interface, how does it associates each interface to the actual firmware codes?
Depends on the code but each interface has an unique number inside of device and each class contains 1 or more interfaces, this is all described in configuration descriptor, then host when it parses the configuration descriptor finds out what your device consists of, which classes and which interfaces. This depends on firmware but usually by interface index, as each interface has unique index in a device (or more exactly in each device configuration as a device can have more than one configurations possible).
> When the host request for an "interface", what would it get in return or what would be the purpose of asking for an interface?
If you are talking about SetInterface that is a way of activating a particular interface, if you are talking about control request from/to interface, that is a way for host to control controllable functionality of interface.
Thanks both for the information. It was very helpful. I am currently using STM USB library as a way to learn how USB works.
Based on STM libraries, this is how a set of C codes functions that needs to be implemented by either a DFU, HID ... See codes below. USBD_ClassTypeDef is part of USBD_HandleTypeDef.
Would USBD_HandleTypeDef be considered an interface or a configuration? I guess I am a bit confused if a device supports more than one interfaces, which in the codes that needed to be implemented?
typedef struct _Device_cb { uint8_t (*Init) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); uint8_t (*DeInit) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); /* Control Endpoints*/ uint8_t (*Setup) (struct _USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req); uint8_t (*EP0_TxSent) (struct _USBD_HandleTypeDef *pdev ); uint8_t (*EP0_RxReady) (struct _USBD_HandleTypeDef *pdev ); /* Class Specific Endpoints*/ uint8_t (*DataIn) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); uint8_t (*DataOut) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); uint8_t (*SOF) (struct _USBD_HandleTypeDef *pdev); uint8_t (*IsoINIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); uint8_t (*IsoOUTIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum);
uint8_t *(*GetHSConfigDescriptor)(uint16_t *length); uint8_t *(*GetFSConfigDescriptor)(uint16_t *length); uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length); uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length); #if (USBD_SUPPORT_USER_STRING == 1) uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev ,uint8_t index, uint16_t *length); #endif
} USBD_ClassTypeDef;
typedef struct _USBD_HandleTypeDef { uint8_t id; uint32_t dev_config; uint32_t dev_default_config; uint32_t dev_config_status; USBD_SpeedTypeDef dev_speed; USBD_EndpointTypeDef ep_in[15]; USBD_EndpointTypeDef ep_out[15]; uint32_t ep0_state; uint32_t ep0_data_len; uint8_t dev_state; uint8_t dev_old_state; uint8_t dev_address; uint8_t dev_connection_status; uint8_t dev_test_mode; uint32_t dev_remote_wakeup;
USBD_SetupReqTypedef request; USBD_DescriptorsTypeDef *pDesc; USBD_ClassTypeDef *pClass; void *pClassData; void *pUserData; void *pData; } USBD_HandleTypeDef;
Did you read the below documentation?
UM1734 User manual STM32Cube USB device library www.st.com/.../jcr:content/translations/en.DM00108129.pdf (Not clickable, copy and paste.)
What kind of USB device are you trying to implement?
-> Would USBD_HandleTypeDef be considered an interface or a configuration? I believe they don't do things in this way.
Hi John,
Thanks for the link. I actually was reading the same document and reading the codes but it's taking awhile to digest all the information.
I am trying to use the STM32F4 in device mode with USB to interface to the PC. The STM32F4 will then be controlled from the PC to talk to other devices using either I2C or general purpose I/O. I am thinking of using HID interface because it seems like the driver is already part of the OS so a little less work. Currently I am using the STM USART to talk to the PC but I am trying to switch to USB because it's a better solution.
I was able to get some of the USB example such as the DFU, HID mouse ... to work but some of the concepts are still a little bit muddy.
I don't know much about USB, but Milorad Cvjetkovic knows USB very well. Back to your last question, -> Would USBD_HandleTypeDef be considered an interface or a configuration?
I believe USBD_HandleTypeDef represents an USB device.
/** * @brief USBD_SetClassConfig * Configure device and start the interface * @param pdev: device instance * @param cfgidx: configuration index * @retval status */ USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { USBD_StatusTypeDef ret = USBD_FAIL; if(pdev->pClass != NULL) { /* Set configuration and Start the Class*/ if(pdev->pClass->Init(pdev, cfgidx) == 0) { ret = USBD_OK; } } return ret; } /** * @brief USBD_ClrClassConfig * Clear current configuration * @param pdev: device instance * @param cfgidx: configuration index * @retval status: USBD_StatusTypeDef */ USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { /* Clear configuration and Deinitialize the Class process*/ pdev->pClass->DeInit(pdev, cfgidx); return USBD_OK; }