cancel
Showing results for 
Search instead for 
Did you mean: 

USB HID - Get Feature Report Asynchronous

doctorseus
Associate
Posted on December 02, 2014 at 14:14

Hello guys,

I am working with the new CubeMX lib on a STM32F4 platform and altough I worked a lot with the ST USB HID implementation/stack it still gives me headaches. I am still new to USB.

I am developing an HID device which has custom Feature Reports which indicate the device peripherie status or reporting configuration results etc. Because some of this Feature Report requests need interaction with peripherie, and this peripherie could be in use while the interrup occurs, I can not answer these requests directly in the USB interrupt. I wanted to answer the requests on the control endpoint in the main loop, but my test application on the usb host side does not receive any data.

Answering the GetFeatureReport in the interrupt works perfectly well, but answering it delayed in the main loop does not. I guess its because the interrupt cleans up the endpoint at the end of the interrupt, but how can i prevent this, what is the correct why to do this? 

http://pastebin.com/rfwr4wFu

  1. uint8_t

     reportBuffer

    [

    4

    ]

     

    =

     

    {

    0

    }

    ;

  2. uint8_t

     asyncReport 

    =

     

    0

    ;

  3. void

     MainLoop_Tick

    (

    )

    {

  4.         

    if

    (

    asyncReport 

    !=

     

    0

    )

    {

  5.                 

    if

    (

    asyncReport 

    ==

     STATUS_REPORT_ID

    )

    {

  6.                         

    //DO SENSOR STUFF

  7.                         reportBuffer

    [

    0

    ]

     

    =

     STATUS_REPORT_ID

    ;

  8.                         USBD_CtlSendData 

    (

    &

    USB_DEVICE

    ,

     reportBuffer

    ,

     

    4

    )

    ;

  9.                 

    }

  10.         

    }

  11. }

  12. void

     USBD_HID_ProcessGetFeatureEvent

    (

    uint8_t

     report_id

    )

    {

  13.         

    switch

    (

    report_id

    )

    {

  14.                 

    case

     STATUS_REPORT_ID

    :

  15.                         asyncReport 

    =

     STATUS_REPORT_ID

    ;

  16.                         

    break

    ;

  17.                 

    default

    :

  18.                         reportBuffer

    [

    0

    ]

     

    =

     report_id

    ;

  19.                         USBD_CtlSendData 

    (

    &

    USB_DEVICE

    ,

     reportBuffer

    ,

     

    4

    )

    ;

  20.                         

    break

    ;

  21.         

    }

  22. }

#stm32 #usb #usb-hid
2 REPLIES 2
tsuneo
Senior
Posted on December 04, 2014 at 18:10

Looks like almost fine,

but you need to drop the flag, ''asyncReport = 0;'', in the ''if'' clause which examines asyncReport, so that the Tick routine puts the DATA stage just once 😉

void MainLoop_Tick(){
if(asyncReport != 0){
if(asyncReport == STATUS_REPORT_ID){
asyncReport = 0; // <------------
//DO SENSOR STUFF
reportBuffer[0] = STATUS_REPORT_ID;
USBD_CtlSendData (&USB_DEVICE, reportBuffer, 4);
}
}
}

Tsuneo
doctorseus
Associate
Posted on December 15, 2014 at 16:43

Hi Tsuneo,

thank you for your hint, I fixed that problem but I still can not send my data buffer to the host.

If I remove USBD_CtlSendData out of the main loop I get an timeout on the host because no data gets transfered. But my USB device behaves correctly and answers all follow up requests.

If I run it like in the post, I get an STATUS_SUCCESS on the host, but with an TransferBufferLength of 0x00. So it seems the transfer runs trough but no data gets transfered altough the length it is set to 0x04 in USBD_CtlSendData.

Additonal to that, my USB device is in an unkown state and the USB host reports errors until I send a SetFeatureReport. Thats really weird and it seems that it is not possible to call any functions outside of (or after) the USB interrupt except USBD_CUSTOM_HID_SendReport.

Debugging the usb stack helped me to get more insight into the procedure, but I found no way to solve me problem and I am still stuck here... There has to be something I overlooked.