cancel
Showing results for 
Search instead for 
Did you mean: 

Looking for USB HID project example that receives command from PC then display LED?

Vu.Andy
Associate III
Posted on October 11, 2016 at 00:55

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.
5 REPLIES 5
Kraal
Senior III
Posted on October 11, 2016 at 11:15

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).

Vu.Andy
Associate III
Posted on October 11, 2016 at 17:01

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.

Kraal
Senior III
Posted on October 12, 2016 at 12:57

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...
slimen
Senior
Posted on October 12, 2016 at 13:12

Hello,

For more details, on how you use the STM32Cube USB device library, you can refer to this 

http://www.st.com/content/ccc/resource/technical/document/user_manual/cf/38/e5/b5/dd/1d/4c/09/DM00108129.pdf/files/DM00108129.pdf/jcr:content/translations/en.DM00108129.pdf

: STM32Cubeâ„¢ USB device library.

Regards

Vu.Andy
Associate III
Posted on October 18, 2016 at 17:00

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).