Library 31- USB HID Host for STM32F4

USB HID (or Human Input Device) is a library, that allows you to read mouse or keyboard data with your STM32F4xx device. So you can use keyboard to write characters to STM32F4xx or use mouse for LCD or any other stuff.

Library

Features

  • Interface with USB mouse
    • 3 buttons and movement supported
  • Interface with USB keyboard
    • QWERTY or AZERTY supported

Dependencies

  • CMSIS
    • STM32F4xx
    • STM32F4xx RCC
    • STM32F4xx GPIO
    • STM32F4xx EXTI
    • MISC
  • TM
    • defines.h
  • USB
    • USB HID Host stack provided by STMicroelectronics (included in library)
USB FS MODE HS IN FS MODE DESCRIPTION
Data + PA12 PB15 USB Data+ line
Data – PA11 PB14 USB Data- line
ID PA10 PB12 USB ID pin
VBUS PA9 PB13 USB activate

Technically, Data+ and Data- are enough for USB communication in any way. But, STM32F4- and STM32F429- Discovery boards uses ID and VBUS pins for activate USB communication (STMPS2151 chip for USB). If you are using STM32F4 or STM32F429 Discovery boards, you need at least VBUS pin. If you are working on custom application, you can disable ID and VBUS pins. To disable pins, open project’s defines.h file and add lines below:

By default, USB FS mode is used, also used on STM32F4-Discovery board. If you want to enable USB HS in FS mode for STM32F429 Discovery board, open project’s defines.h file and add lines below:

By default, AZERTY keyboard format is in use. If you will work with QWERTY format, add lines below in defines.h file:

That’s all. You are now ready to work with USB HID devices.

Clock was set down to 168MHz for STM32F429 because you can not get 48MHz for USB from 180MHz core clock.

Functions and enumerations

Example

Example below works with USB mouse and USB keyboard:

  • If you connect USB mouse, RED led will be ON to indicate this
    • RED led will be always on.
    • If you move mouse, then GREEN led should BLINK
    • If you press left button, GREEN led will be ON
    • If you press right button, GREEN led will be OFF
  • If you connect USB keyboard, GREEN led will be ON to indicate this
    • If keyboard is inserted, then GREEN led will be ON
    • If you press lower b, RED led will be ON
    • If you press lower v, RED led will be OFF
  • If both leds blinks, then USB device is not recignized
  • If not leds on, then device is not inserted

Project is available on my Github account, download library below.

Icon
TM STM32F4 USB HID HOST Library

tilz0R

Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Joaquin

    I am having problems using your libraries and my PWM signals. The signals are generated with the same method you use in your tutorial. The libraries I am using is this one and the L3GD20 in separated programs. I am using TIM4 at a 20KHz freq.

    Also I would like to say that you have an awesome website.

    • Hi.

      What actually is the problem? Is the PWM not working or?

      Thanks btw 😉

      • Joaquin

        The problem is that if I use one of those libraries, the PWM outputs give readings completely different from what they should. Although the rest of the outputs (LCD and logic) work normaly.

        • is there a pin problem?
          Are you trying to use a pin which is already used with LCD?

          • Joaquin

            No, sorry, my fault. After 3 hours checking what was wrong I have just seen that I forgot to init the timer in the main function.

            Thanks a lot for your time!

  • Felipe Cassenote Gehrke

    Hey,

    Please put the hex file for download. I want to test it and i don’t have Keil installed.

    May u put it here ? I need it for STM32F4 Discovery. Do you have it ?

    • it’s available on github.

      • Felipe Cassenote Gehrke

        Thank you ! It really works ! I’m trying to port it to IAR. Do you have any tip ?

        • I’m not using it, no idea how to set up everything.
          Basically, just copy necessary libs, set include paths and copy/paste example from here.

          • Felipe Cassenote Gehrke

            Do you know if your library works with 2 USB ports at the same time ?

          • It does not. Hid supports only keyboard and mouse.

  • Artur

    is anybody tried to read joystick or gamepad?

  • fatih

    can you convert it to iar ?If so can you post me iar codes

  • fatih

    Hello.I load hex code and see it is working. I setup keil 5 but could operate your source code.if (Keyboard_Data.ButtonStatus == TM_USB_HIDHOST_Button_Pressed) compiler could not pass this line.I select stm32f429 from the toolbar and rebuid . ı am new to keil.I did not change any option.Can you help me?

    • What’s the error??

      • fatih

        I can compile in both cases(both iar and keil) but when I run the run button nothing happens.in keil5 program counter does not go to main loop.It was running in a undefined assembler code.

  • fatih

    I have port it to iar .In keil it can not even go to main code, in iar compiler can not pass if (Keyboard_Data.ButtonStatus == TM_USB_HIDHOST_Button_Pressed) line

  • oattao

    Dear Majerle Tilen,

    Can you please write a tutorial about connecting between an Android phone and STM32F4 board via USB?

    • I can’t guarantee you that 🙂

      • oattao

        I hope you will.

  • Tesung Mao Fang

    Hi, thanks for your example!

    But I have one question.
    I click left button of mouse, and then do not release left button. It will get a left button click data(value = 0) only one time, and then it will receive the left button release button (value =1 -> I think it means release). But actually I do not release the left button.

    Could anyone explain this question for me?
    or It is impossible that it is something wrong with my code.
    Thanks

    • Show your code. Copy main.c to pastebin.com.

      • Tesung Mao Fang

        Hi, I updated main.c file on http://pastebin.com/6geqX0db.

        This is my first time to using this website. If you can not see my code, just tell me. Thanks!

        This main.c code is modified from your example.

        1. I got the mouse signals data from TM_USB_HIDHOST_ReadMouse(&Mouse_Data); -> Mouse data.

        2. I need to ensure the now signals between prev data is different signals by diff function. Because I found the same mouse signals will be keep producing when I don’t do anything on mouse.

        3. I will transfer data(nowbuff) to usart2.

        If you can’t understand my code, just contact to me. Thanks for your help.

        • Ok, I see now.

          That’s because after read first time, variables are set to 0 back.

          You can open my tm_stm32f4_usb_hid_host.c file and remove lines (102):

          /* Buttons are not pressed anymore */
          TM_USB_HIDHOST_INT_Mouse.LeftButton = TM_USB_HIDHOST_Button_Released;
          TM_USB_HIDHOST_INT_Mouse.MiddleButton = TM_USB_HIDHOST_Button_Released;
          TM_USB_HIDHOST_INT_Mouse.RightButton = TM_USB_HIDHOST_Button_Released;

          • Tesung Mao Fang

            Ok, I tried it. And it is work!!

            You gave me great help. Thank you!

            But I have another question after you gave me advice.

            In tm_stm32f4_usb_hid_host.c file

            Why TM_USB_HIDHOST_ReadMouse(TM_USB_HIDHOST_Mouse_t* Mouse) need to reset
            diff value when I call TM_USB_HIDHOST_ReadMouse function?

            /* Difference from last call is 0 */
            TM_USB_HIDHOST_INT_Mouse.DiffX = 0;
            TM_USB_HIDHOST_INT_Mouse.DiffY = 0;

            Does it have any reason?

          • Diff variables are meant to be used as “Difference” of mouse movement after last check.

            For example. If you have LCD screen and mouse pointer. You call ReadMouse… and you must update mouse pointer on LCD for diff values. If I wouldn’t clear diff variables, then after every call, you will move your mouse on LCD, even if you didn’t physically move it.

            Do you understand?

            Diff is just a variable which stores data, “How mouse was moved between 2 ReadMouse calls.
            If you need to know exact X and Y values on LCD, you can use Absolute variables.

          • Tesung Mao Fang

            Ok, I can understand what you say.

            Thanks for your explaining.
            It’s really useful for me.

  • Nishu

    Hi,
    Sir i am new on stm32f427 controller and also don’t have an idea about usb.

    i used your library in my code. But it’s always satisfying the case of no device connected.

    i connected the mouse with my usb port.

    the connection i used is –

    V-Bus => 5 Volt supply.
    USB D+ connected with PA12 pin of controller.
    USB D- connected with PA11pin of controller.
    USD ID is connected to ground.

    Please help me to comeout from this issue.

    Please Check my main.c at http://pastebin.com/W90dFySr.

    Thanks.

    • Hi,

      Can you make sure, you have correct PLL settings for your device?
      Make sure about these settings:

      PLL_M = 8 (system_stm32f4xx.c)
      HSE_VALUE = 8000000 (stm32f4xx.h)
      These settings applies for 8MHz crystal. If you have other crystal, then use other settings.
      In case you don’t have external clock, use HSE_VALUE = 16000000 and PLL_M = 16.

      Try and report.

      • Vinh Phan

        I also have a same problem. I don’t change any settings in your project. I use stm32f407 and run in Keil

        • Vinh Phan

          Sorry, the problem is unstable connection of USB OTG cable

  • Nishu

    Thanks for replying sir.

    sir i am using 26 mhz crystal.
    and my system clock is running at 104Mhz (26*4).

    • Why 104?
      You STM can go up to 180MHz.

      Set PLL_M to 26 and HSE_VALUE to 26000000. Then you will have 180MHz and USB will also work correct.

      • Nishu

        Sir By doing these setting i am getting 168mhz clock. if i change PLL_N to 180 then compiler’s Go button becomes unvisible. and at 168mhz the problem not solved.

        /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
        #define PLL_M 13
        #define PLL_N 168

        /* SYSCLK = PLL_VCO / PLL_P */
        #define PLL_P 2

        /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
        #define PLL_Q 9

        Thanks

        • Change only PLL_M parameter, leave others as they are.

          • Nishu

            if i change the PLL_M only to 26 and other setting remains same than my clock becomes 84 mhz.

            Sir i checked the datasheet then it is mentioned.

            Features
            ■ Core: ARM 32-bit Cortex™-M4 CPU with FPU,
            Adaptive real-time accelerator (ART
            Accelerator™) allowing 0-wait state execution
            from Flash memory, frequency up to 168 MHz,
            memory protection unit, 210 DMIPS/
            1.25 DMIPS/MHz (Dhrystone 2.1), and DSP
            instructions.

          • It’s look like datasheet problem.
            BTW..don’t tell me Sir 😉

            Ok, from my head, do this:
            HSE_VALUE = 26000000
            PLL_M = 26
            PLL_N = 360
            PLL_P = 2
            PLL_Q = 7

            You will have 180MHz.

      • Nishu

        My controller stm32f427vi supports till 168mhz clock.

        Thanks

  • Nishu

    Hi Majerle,
    As we have discussed i changed my clock to 168 mhz (180 does not support) and usb clock is running at 48mhz. i did it using (STM32F4xx_Clock_Configuration_V1.1.0) tool provided by st microelectronics. This tool is also not support for the 180 mhz. but yes i am sure that my usb is running at 48mhz. but still i am stuck in no device connected case. Please help.

    • Send me your project.
      In the meantime, try another keyboard or mouse to connect there. Maybe mouse is a problem.

      Send me project and tell me exact input frequency of your crystal.
      And again…F427 works on 180MHz!

      • Nishu

        Could i have your email ID.

        • It is posted everywhere on my site, including each example header 😉

          • Nishu

            Code is posted to u by mail.

          • Nishu

            Sir please check the mail.

          • Nishu

            Mr Tilen! i hope that my workspace in iar is not a big issue for you.

  • Nishu

    yes ! The problem is solved now, Now i am able to operate keyboard and mouse with my STM32 board. Thanks for such a kind of help.

    Thanks again 🙂

    • It would be nice if you tell how you fix your problem and what was going wrong.

      • Nishu

        I don’t know exactly what was the problem, i just downloaded all the files which is to be added in my project, but that time it was not working . Than i used your files from your keil project, then it started working. May be a file was missing in first time. It was my fault, your library is perfect.

        Thanks.

  • Nishu

    Hi Mr Tilen !
    I want to use both USE_USB_OTG_HS mode (For Mouse) and USE_USB_OTG_FS mode (For Keyboard). Both are separately running proper, but when i am trying to run both simultaneously by defining->

    1) #define USE_USB_OTG_FS (defines.h)
    #define USE_USB_OTG_HS

    2) By commenting
    // #else //USE_USB_OTG_HS (usb_bsp.c)

    3) created one more function in (usb_bsp.c)

    void USB_OTG_BSP_EnableInterrupt_2 (USB_OTG_CORE_HANDLE *pdev)
    {
    NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = USB_HID_HOST_NVIC_PRIORITY;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = USB_HID_HOST_NVIC_SUBPRIORITY;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    }

    4) i called the above function in

    void USBH_Init(USB_OTG_CORE_HANDLE *pdev,
    USB_OTG_CORE_ID_TypeDef coreID,
    USBH_HOST *phost,
    USBH_Class_cb_TypeDef *class_cb,
    USBH_Usr_cb_TypeDef *usr_cb)
    {
    USB_OTG_BSP_EnableInterrupt_2(pdev); // In Last Line.
    }

    5) make one more function in (usb_bsp.c)

    void OTG_HS_IRQHandler(void) {
    USBH_OTG_ISR_Handler(&USB_OTG_Core);
    }

    But after all these changes both are not running simultaneously.

    Please help!!

    • Both won’t work at the same time!

      • Nishu

        Does Controller not support ??

  • Peter Mather

    Majerle

    Apologies for the question – probably stupid

    I’m trying to run this code on the STM32407Discovery board. Can I plug the keyboard into the microUSB port with a suitable adapter or do I need to connect directly to the processor pins? I’ve put a ground on PC0 to turn on the USB power with the STMPS2141STR and that lights the USB power LED on the Discovery board.
    However, the code isn’t seeing the attached keyboard. I’m unclear what the EM1F02-USB03F2 chip on the discovery board is doing.

    Help appreciated

    Thanks

    Peter

    • If you use my lib with default settings (USB FS mode) then you can plug it into F4-discovery without problems.
      No need for additional configuration.

      • Peter Mather

        I’m always getting disconnected status and the USB power light doesn’t come on unless I force it on by grounding PC0 or connecting VBus to 5V. Even then I still get disconnected status.

        I’m compiling under CoIDE 1.7.8

        I’ve tried both with and without defining USB_HID_HOST_DISABLE_ID

        • Ok, send me a project to my email, will take a look 🙂

          • Peter Mather

            Will do – thanks. It is part of a huge codeset so I will take some time to strip it down first

  • user

    works on laptop keyboard?

    • Hello to you too,

      how you have in mind to connect laptop keyboard to STM?

      • user

        Hi,
        I want to connect the STM to my laptop and read keyboard input from it , can it be done with this library?

        • No, you can’t read laptop’s keyboard with STM with this lib.
          Why would someone do that.

          • user

            Why not?I’m playing around with it.

  • Giovanni Goncalves Migon

    Hi, I’m trying to use the USB sample from CubeMX to connect a peripheral that use 2 endpoints, then an error of STALL is detected from internal protocol, and I don’t know much about that. How can I use that peripheral in native USB from the stm32f429 kit?

    • Hi

      I have pretty much NO idea how CubeMX software looks like.
      And that’s because of problems all of you have, because nothing is working 😀

      • Giovanni Goncalves Migon

        Sorry, I was wrong. I’m using this code, and this works very well and simply. But I want to use a barcode scanner with 2 endpoints that enter in case of “DeviceNotSupported”, with an internal error of STALL. I’m using the stm32f429 kit. Could you help me to make the software works with a barcode scanner?

        • this lib supports only hid descriptors for mouse and keyboards.
          For barcode scanner you will need additional descriptor, which is not supported here and that’s the reason you get “DeviceNotSupported” response.

          • Giovanni Goncalves Migon

            This barcode is used like a keyboard and has 2 endpoints(like 2 USB_HID in same connector). I tried to use the ST code but it only support one endpoint. How many endpoints your code support?

            And once again, I’m sorry for my mistake.

          • Chính Nguyễn Trần

            i’m writing that scanner lib but i get a lot of trouble. the KIT accept the scanner but couldnt receive data… can you help me to write that lib ?
            please

  • Johnny Dreher

    Hello Majerle. I’m trying to connect a gamepad to my board to control a robot, but till now I’m very confused. Can you help me with some tips?
    Thanks for now…

    • Hi,

      When STM is in host mode, you can connect mouse and keyboard only. There is no descriptor reader for gamepad.

  • Diep Gepa

    Hi Majerle Tilen !
    I only want to job as video: http://www.youtube.com/watch?v=ab-BHV03DQU
    How???

    • The best solution for you would be to ask author of this video to give you code.

      • Diep Gepa

        Thanks