2016-10-10 3:55 PM
I am looking for an USB HID example that the firmware would receives for example a command from the PC then based on the input command, would display a few LED.
Currently there are a few examples from STM but it seems like only a one way communication in which the mouse would SendReport() in a while() loop. But I am looking for an example in which the firmware would receive various commands from the PC then based on that, decides what to do in a 2-way communication. Thanks.2016-10-11 2:15 AM
Hi, can you specify the part you are using ?
You might want to look into the custom hid examples to have a 2 way communication. But even on the mouse example you saw, the device use the endpoint 1 to send data (mouse coordinates) to the PC, and the PC can send data to the device using the endpoint 0 (which is a bidirectional endpoint).2016-10-11 8:01 AM
Thanks for the reply. I am using the STM32F446ZE-Nucleo board.
First I am still new to USB HID so some of what I say may be obvious. The mouse example although it has 2-way communication, I think the communication from the PC is only for the STANDARD request such as such as get_descriptor, get_interface .... and so on. The main program has a while loop that it would loop and USBD_HID_SendReport() and beyond that it doesn't really process any custom information from the PC. I am also looking at the custom HID example, and there appears to be a fops which probably handles custom request (or CLASS request), but I am not quite sure. If you're familiar with this example, maybe you could point to some specifics. USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_fops = { CustomHID_ReportDesc, CustomHID_Init, CustomHID_DeInit, CustomHID_OutEvent, }; Eventually I am looking to build an HID application to communicate with the uC from the PC, then using the uC I/O to control other parts of the board which is mostly what it is used for in most cases I think.2016-10-12 3:57 AM
Unfortunately I'm using a F0 part, and the USB lib is slightly different.
Nevertheless, in the USB device lib for F0x2 that I'm using, there is a file called ''usbd_custom_hid_core.c'' which has a structure of callbacks a bit like your fops :USBD_Class_cb_TypeDef USBD_HID_cb =
{
USBD_HID_Init,
USBD_HID_DeInit,
USBD_HID_Setup,
NULL,
/*EP0_TxSent*/
USBD_HID_EP0_RxReady,
/*EP0_RxReady*/
/* STATUS STAGE IN */
USBD_HID_DataIn,
/*DataIn*/
USBD_HID_DataOut,
/*DataOut*/
NULL,
/*SOF */
USBD_HID_GetCfgDesc,
}; Here I can receive data from the PC with the callback USBD_HID_DataOut, and send data to it with USBD_HID_DataIn. There is a pdf explaining some of the internals of the lib on the ST download web page. It maybe be a good start for you.
Or maybe Tsuneo could help you with this...
2016-10-12 4:12 AM
Hello,
For more details, on how you use the STM32Cube USB device library, you can refer to this : STM32Cubeâ„¢ USB device library.Regards2016-10-18 8:00 AM
Thanks for the example. I'll look into that although I am still trying to understand the flow of the Data_In() and Data_Out().
I found the example in the DFU project that provides at least part of what I need. I don't think DFU is a HID but they are similar. In the DFU example, first the fobs is defined along with a set of functions that will be calling the fops. These will be part of the CLASS_REQUEST. In the custom HID example that you posted, the DataIn() and DataOut() are still of the standard request, so I am trying to see if we can define a set of custom request to make things a little easy. So in the DFU example, it has something similar to what I am looking for. USBD_DFU_MediaTypeDef USBD_DFU_Flash_fops= { (uint8_t *)FLASH_DESC_STR, Flash_If_Init, Flash_If_DeInit, Flash_If_Erase, Flash_If_Write, Flash_If_Read, Flash_If_GetStatus, }; static void DFU_Detach (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static void DFU_Download (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static void DFU_Upload (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); static void DFU_GetStatus (USBD_HandleTypeDef *pdev); static void DFU_ClearStatus (USBD_HandleTypeDef *pdev); static void DFU_GetState (USBD_HandleTypeDef *pdev); static void DFU_Abort (USBD_HandleTypeDef *pdev); static void DFU_Leave (USBD_HandleTypeDef *pdev); Then a set of enum is defined to match that fops and the corresponding functions. typedef enum { DFU_DETACH = 0, DFU_DNLOAD , DFU_UPLOAD, DFU_GETSTATUS, DFU_CLRSTATUS, DFU_GETSTATE, DFU_ABORT } DFU_RequestTypeDef; Then at the USBD_DFU_Setup() function, the switch statement will detect which is being request and call the corresponding function accordingly. static uint8_t USBD_DFU_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { uint8_t *pbuf = 0; uint16_t len = 0; uint8_t ret = USBD_OK; USBD_DFU_HandleTypeDef *hdfu; hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : switch (req->bRequest) { case DFU_DNLOAD: DFU_Download(pdev, req); break; case DFU_UPLOAD: DFU_Upload(pdev, req); break; case DFU_GETSTATUS: DFU_GetStatus(pdev); break; .......... The hard thing for me about USB is that not only you have to understand the codes which is quite a bit of work, you have to understand the standard which can take a lot of time, and you also have to know how to write the driver to test out your USB firmware (unless you know someone who can do it for you).We’re moving the ST Community to a new platform to give you a better and more reliable community experience.