Skip to main content
Visitor II
February 26, 2017
Solved

usb host

  • February 26, 2017
  • 14 replies
  • 16781 views
Posted on February 26, 2017 at 07:10

Hi Everyone,

I'm trying to read from the USB keyboard with a custom board STM32F205RCT6 MCU.

I am using USB FS host (host only) with HAL library.but it just works with some keyboards!

Other keyboards are detected by host but can not read data.

Can any one help me?

My Code:

int main(void) {  /* STM32F4xx HAL library initialization:  - Configure the Flash prefetch, instruction and Data caches  - Configure the Systick to generate an interrupt each 1 msec  - Set NVIC Group Priority to 4  - Global MSP (MCU Support Package) initialization  */  HAL_Init();    /* Configure the system clock to 120 MHz */  SystemClock_Config();  /* Init Host Library */  USBH_Init(&hUSBHost, USBH_UserProcess, 0);    /* Add Supported Class */  USBH_RegisterClass(&hUSBHost, USBH_HID_CLASS);    /* Start Host Process */  USBH_Start(&hUSBHost);    /* Run Application (Blocking mode) */  while (1)  {  /* USB Host Background task */  USBH_Process(&hUSBHost);     if(USBH_HID_GetDeviceType(&hUSBHost) == HID_KEYBOARD)  {   hid_demo.keyboard_state = HID_KEYBOARD_IDLE;   hid_demo.state = HID_DEMO_KEYBOARD; //HID_KeyboardMenuProcess();  HID_KEYBD_Info_TypeDef *k_pinfo;  char c; k_pinfo = USBH_HID_GetKeybdInfo(&hUSBHost);  if(k_pinfo != NULL) {  c = USBH_HID_GetASCIICode(k_pinfo);  char str[5]; sprintf(str,'%c',c); HAL_UART_Transmit(&huart2,k_pinfo->keys,6,10000);  }  } }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Result (only

detected Not read data

)

USB Device Attached PID: 1h VID: 258ah Address (#1) assigned. Manufacturer : SINO WEALTH Product : USB KEYBOARD Serial Number : N/A Enumeration done. This device has only 1 configuration. Default configuration set. Switching to Interface (#0) Class : 3h SubClass : 1h Protocol : 1h KeyBoard device found! HID class started.�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

#usb-host #usb-hid #usb-stm32f205

Note: this post was migrated and contained many threaded conversations, some content may be missing.
    This topic has been closed for replies.
    Best answer by Pavel A.
    Posted on January 17, 2018 at 19:21

    I'm seeing a similar issue with USB mice and STM32F446 and found kind of a workaround.

    Attachedis part of my patchfor usbh_hid.c

    The crucial point is tomove from state HID_INIT directly to state HID_SYNC, not to HID_IDLE.

    Note: I don't understand why this works for me. As the OP said, he is not specialist in USB and expected the library to Just Work. So did I...

    Regards,

    Pavel

    ________________

    Attachments :

    pach_usbh_hid_002.txt.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hy8B&d=%2Fa%2F0X0000000b4D%2FjH_j5xv3K1bU7H_4bTVEQeNqBQKujwCbPIybWCJzmKo&asPdf=false

    14 replies

    Visitor II
    May 15, 2017
    Posted on May 15, 2017 at 22:12

    Hello Friend!

    You solved this problem?

    I also do not work usb host hid keyboard...

    If you solve the problem, give the code.

    Visitor II
    May 26, 2017
    Posted on May 26, 2017 at 12:33

    Hi, I have the same problem!

    Some keyboard are OK, but some keyboard can be detected but can't get the data.

    I use STM32L496-NUCLEO board with STM32CUBEMX USB HID project.

    Someone help me!

    this GASIA keyboard can't read data:

    0690X00000603qxQAA.jpg

    ----------------------------------------------------------------------------------

    this SIGMACHIP keyboard can read data:

    0690X00000603r7QAA.jpg
    Visitor II
    November 9, 2017
    Posted on November 09, 2017 at 20:09

    Hi everyone,

    I've got the same problem, in my custom PCB (stm32f401) an microsoft keyboard worked as expected, but an leadership keyboard didn't.

    So, I've tryed an STM32F746G-DISCO, I run 4 examples:

    STM32Cube_FW_F7_V1.4.0\Projects\STM32746G-Discovery\Applications\USB_Host\HID_RTOS\SW4STM32\STM32746G-DISCOVERY_USBH-FS

    STM32Cube_FW_F7_V1.4.0\Projects\STM32746G-Discovery\Applications\USB_Host\HID_RTOS\SW4STM32\STM32746G-DISCOVERY_USBH-HS

    \STM32Cube_FW_F7_V1.4.0\Projects\STM32746G-Discovery\Applications\USB_Host\HID_Standalone\SW4STM32\STM32746G-DISCOVERY_USBH-FS

    \STM32Cube_FW_F7_V1.4.0\Projects\STM32746G-Discovery\Applications\USB_Host\HID_Standalone\SW4STM32\STM32746G-DISCOVERY_USBH-HS

    and same result.

    For me, it seems like a problem with USB HOST routines.

    Someone already did it work?

    I'm compiling with SW4STM32

    Graduate II
    January 17, 2018
    Posted on January 17, 2018 at 17:05

    >>For me, it seems like a problem with USB HOST routines.

    Or a lack of understanding of how random keyboard behave. One would need to go beyond the 'doesn't work' level of understanding and look at the signalling and protocol and its behaviour with respect to the class and Microsoft's implementation of the class on a PC

    Visitor II
    January 17, 2018
    Posted on January 17, 2018 at 17:20

    You are right, I don't understand how protocol works. But from starting point, I tried the examples above, without any modifications in de code. Hardware is a STM32F746G-DISCO. Shouldnt this be able to comunicate?

    Visitor II
    January 18, 2018
    Posted on January 18, 2018 at 15:41

    Hi,

    See

    https://deskthority.net/wiki/USB

    for some additional information about USB keyboard operation and boot protocol.

    Regards,

    Alex

    Visitor II
    February 8, 2018
    Posted on February 08, 2018 at 05:45

    Hi all, 

    i have a same problem with USB Host HID, my project generated form CubeMX, 

    when i debug  then case 'HOST_CLASS_REQUEST',  case 'ENUM_GET_SERIALNUM_STRING_DESC'

    case 'CMD_WAIT' and GetDeviceType = 'HID_UNKNOWN' not '

    Technical Moderator
    February 8, 2018
    Posted on February 08, 2018 at 15:22

    Then did you applied the suggested fix? Does it work for you?

    Technical Moderator
    May 21, 2018
    Posted on May 21, 2018 at 16:00

    Hello,

    I would like to share with you a patch containing some improvements to deal with some buggy HID devices during enumeration phase. This patch will be deployed in a new version of the USB host library once validated.

    If you can test it at your end using your failing devices, this will be helpful for us to validate the patch.

    1-

    STM32Cube_FW_F4_V1.0\Middlewares\ST\STM32_USB_Host_Library\Class\HID\Src\usbh_hid.c

    : replace the implementation of USBH_HID_Process by the following:

    static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
    {
     USBH_StatusTypeDef status = USBH_OK;
     HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
     
     switch (HID_Handle->state)
     {
     case HID_INIT:
     HID_Handle->Init(phost); 
     case HID_IDLE:
     status = USBH_HID_GetReport (phost, 0x01U, 0U, HID_Handle->pData, (uint8_t)HID_Handle->length);
     if (status == USBH_OK)
     {
     fifo_write(&HID_Handle->fifo, HID_Handle->pData, HID_Handle->length); 
     HID_Handle->state = HID_SYNC;
     }
     else if (status == USBH_BUSY)
     {
     HID_Handle->state = HID_IDLE;
     status = USBH_OK;
     }
     else if (status == USBH_NOT_SUPPORTED)
     {
     HID_Handle->state = HID_SYNC;
     status = USBH_OK;
     }
     else
     {
     HID_Handle->state = HID_ERROR;
     status = USBH_FAIL;
     }
    #if (USBH_USE_OS == 1U)
     osMessagePut ( phost->os_event, USBH_URB_EVENT, 0U);
    #endif
     break;
     
     case HID_SYNC:
    ...�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    2-

    STM32Cube_FW_F4_V1.0\Middlewares\ST\STM32_USB_Host_Library\Core\Src\usbh_ctlreq.c

    : replace the implementation ofUSBH_CtlReq by the following:

    USBH_StatusTypeDef USBH_CtlReq (USBH_HandleTypeDef *phost, 
     uint8_t *buff,
     uint16_t length)
    {
     USBH_StatusTypeDef status;
     status = USBH_BUSY;
     
     switch (phost->RequestState)
     {
     case CMD_SEND:
     /* Start a SETUP transfer */
     phost->Control.buff = buff; 
     phost->Control.length = length;
     phost->Control.state = CTRL_SETUP; 
     phost->RequestState = CMD_WAIT;
     status = USBH_BUSY;
    #if (USBH_USE_OS == 1)
     osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
    #endif 
     break;
     
     case CMD_WAIT:
     status = USBH_HandleControl(phost);
     if (status == USBH_OK) 
     {
     /* Commands successfully sent and Response Received */ 
     phost->RequestState = CMD_SEND;
     phost->Control.state =CTRL_IDLE; 
     status = USBH_OK; 
     }
     else if (status == USBH_NOT_SUPPORTED)
     {
     /* Commands successfully sent and Response Received */
     phost->RequestState = CMD_SEND;
     phost->Control.state = CTRL_IDLE;
     status = USBH_NOT_SUPPORTED;
     }
     else
     {
     if (status == USBH_FAIL)
     {
     /* Failure Mode */
     phost->RequestState = CMD_SEND;
     status = USBH_FAIL;
     }
     } 
     break;
     
     default:
     break; 
     }
     return status;
    }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    Waiting for your feedback.

    -Amel

    Super User
    May 21, 2018
    Posted on May 21, 2018 at 18:23

    Amel,

    With this patch both keyboard and mouse work, my hack no longer  needed.

    Thanks!

    In USBH_HID_Process() line 9, I'd like to add possibility of error return from the class handler.Init (if the device does not have good report descriptors, or blacklisted, and so on):

     case HID_INIT:

      if (USBH_OK != HID_Handle->Init(phost))

      {

         phost->gState = HOST_ABORT_STATE; 

         break;

       }

    (but still we have other unresolved problems with USB host. One is, immediately after unplugging keyboard or mouse, another (fake) attach event is received, and further real attachments are not detected).

    - Pavel

    Technical Moderator
    May 22, 2018
    Posted on May 22, 2018 at 10:37

    Thanks

    pavel_a

    ‌ for your feedback.

    (but still we have other unresolved problems with USB host. One is, immediately after unplugging keyboard or mouse, another (fake) attach event is received, and further real attachments are not detected).

    Are these problems described in separate discussion may be? If not, please do it in order to be able to follow the case efficiently?

    -Amel

    Visitor II
    June 18, 2018
    Posted on June 18, 2018 at 23:36

    Well, now I made that 1.7V turn to 4.5V, which I think is an acceptable voltage. But even with this and disabling all kinds of optimizaions, I couldn't make this project work. But I thank all of you guys who helped me in some way. 

    My project is in 

    https://github.com/kallilmiguel/USB-Host

     , if any of you guys could test this project to see if it's only in my board or not.

    If not, I am very grateful anyway.

    Thanks

    Kallil

    Super User
    June 18, 2018
    Posted on June 18, 2018 at 23:55

     ,

     ,

    4.5 V is much better than 1.7, but still not as good as 5.0 V ...

    Also,

    https://github.com/kallilmiguel/USB-Host/blob/5ef8582ace718810e5ea090d0adb73f733189b46/Src/usbh_conf.c ♯ L586

     ,pin C0 is used as output, but in the Cube file it is not configured at all.

    - pa

    Visitor II
    June 21, 2018
    Posted on June 21, 2018 at 12:09

    May be  

    https://community.st.com/0D70X000006SgELSA0

      cold help?

    Igor

    Super User
    January 13, 2019

    While writing my own host HID implementation I came across a stubborn keypad which I could not get working (it's not relevant to the story here but it turned out to be a slightly not standard one). So I took down from the shelf a STM3240G-EVAL, dug out a microA-to-A "OTG" cable, took STM32Cube_FW_F4_V1.21.0\Projects\STM324xG_EVAL\Applications\USB_Host\HID_Standalone\ and a bunch of "library" files it needs, hacked the eclipsoid's config file into a decent makefile, compiled, downloaded, and...

    It was... well... weird.

    Two of 4 tested keyboards/pads did not respond to the first setup due to delay between reset and first keepalive (https://community.st.com/s/question/0D50X00009yEQJZSA4/f4-otg-otghfir-handling second post)... and that was it. Finding: Cube does not retry setups... humm....

    Okay so I fixed that and then all 4 failed at the problem described here - after enumeration in the HID_IDLE state a Get_Report request is made, and the keyboards stalled it, and again that was it. Skipping HID_IDLE as PavelA hints above omits the Get_Report request, and then polling takes place and things appear to work somehow. So I took a closer look.

    The "library" seeks for boot keyboard but then sets it to report mode, and even requests the report descriptor for it. That's okay and bold, until one finds out that subsequently it ignores the report descriptor and processes data from the interrupt polls using fixed tables respective to the boot protocol... That's ehm uhm but does not explain the thing with the Get_Report request.

    Looking closer at the packets on the bus, the setup transaction for that request has wLength=2. Waitaminute. Even for the boot protocol it would be 8. Now we could argue whether USB2.0 9.3.5 applies here and the keyboards should reply to such request specifying shorter length than the data actually are, or they are OK to be conservative and stall a request which has surprising wLength value; nevertheless, what would be the reason for Cube to send such smaller wLength, especially if it comes from HID_Handle->length which was previously correctly parsed out from the respective endpoint descriptor's wMaxPacket in USBH_HID_InterfaceInit()?

    The real culprit is in USBH_HID_KeybdInit() where an array of 2 words i.e. 8 bytes (yes, that's no coincidence with the 8 byte long boot-protocol' report) is defined as a buffer, and then in

     if(HID_Handle->length > (sizeof(keybd_report_data)/sizeof(uint32_t)))

     {

       HID_Handle->length = (sizeof(keybd_report_data)/sizeof(uint32_t));

     }

    is the place where HID_Handle->length is restricted to 2 (i.e. 2 words, although all usages of HID_Handle->length are in bytes).

    (Read: the fix is to modify this to

     if(HID_Handle->length > sizeof(keybd_report_data))

     {

       HID_Handle->length = sizeof(keybd_report_data);

     }

    but the real solution is still... well... yes, the painful one.

    I've just noticed that this particular one was already reported in

    https://community.st.com/s/question/0D70X000006SgELSA0/bug-in-usb-hid-keyboard-code

    and maybe even fixed, since I did not check if there's a newer Cube around. Still,l it is just part of the whole story.

    )

    Now how comes that an incorrect report length results in (somewhat) working parsing of the polls, once the Get_Report request is skipped? By luckily written wrong code. The OTG machine is (according to manual) told to receive multiples of maxpacket bytes, regardless of real requested number of bytes from upper levels; so here 8 bytes are received in the interrupt poll. The interrupt poll request that data in HID_GET_DATA state to be stored into HID_Handle->pData. When they arrive, HID_Handle->length bytes (i.e. 2 bytes) are copied out from HID_Handle->pData to that weird fifo. Then, in USBH_HID_KeybdDecode(), again HID_Handle->length bytes (i.e. again 2 bytes) are copied from fifo into *the same* HID_Handle->pData (where the rest of data up to maxpacket still sits), and then all 8 bytes are duly processed...

    Enjoy.

    JW

    PS. Later I gathered all USB keyboards I could get hand on and also asked my colleagues to bring in from home theirs for a quick test - and yes, there are keyboards which are not prone to the late-keepalives issue, there are also FS keyboards where the late SOF won't occure; and also some keyboards don't stall the wLength=2 GetReport request, reponding by the expected 2 bytes. Oddly enough, all tested keyboards indeed used the same report format in the report protocol as is in the boot protocol, in the interface marked as boot keyboard, so this appears to be some defacto "standard"; still the "library" shouldn't rely on this.

    Visitor II
    January 14, 2019

    Dear @Community member​ thanks for your reply! 

    I did not understand very well: two issue that you describe (the "keyboards/pads did not respond to the first setup due to delay between reset and first keepalive" and the issue with "HID_Handle->length") are related?

    Can you explain better how you fixed the first bug? 

    About the second one I think your suggestion is correct and I noticed that the same error is present in the previous code rows where "keybd_report_data" is set to zero.

    To confirm that I noticied that in the USBH_HID_MouseInit function (in usbh_hid_mouse.c file) the code is correct.

    Thanks in advance.

    Luca G.