HAL Library 21- Multi purpose USB library for STM32Fxxx

This USB library is designed in a ways that can easily be used with different modes. That’s why I’ve made a single library for everything what I support now and which support I will add in future.

The main purpose of library is to support USB FS and HS modes on STM32Fxxx devices at the same time, without any problems.

So I designed a library, which allows users to have all these possibilities:

  • Use both USB modes as hosts
  • Use both USB modes as devices
  • Use one USB as host and another as device and vice-versa
  • Use one USB as device and/or host at the same time (needs switching)


Read more about new HAL libraries


  • Use USB on STM32Fxxx devices
  • Supports USB FS and HS ports
    • HS mode can use external PHY or embedded phy featuring USB HS in FS mode
  • Supports both USB modes at the same time
  • Supports different HOST or DEVICE modes at a time
  • Supports changing USB mode (host/device) on the fly on single USB FS or HS mode
  • Built on ST’s stack for USB Host/Device
  • Predefined support for different STM32F4/7xx Discovery boards for easily use
  • Supports different USB classes for host mode
    • MSC host for operating with USB flash memory
    • HID for reading external keyboard and mouse
  • Supports different USB classes for device mode
    • CDC device for acting like Virtual COM Port (VCP) to your computer
      • Requires ST’s Virtual COM port drivers
    • MSC device for acting like SDCARD reader when SDCARD is connected to SDIO port
  • Supports one USB class on both USB FS or HS ports at a time if needed
    • Example MSC: You can connect 2 flash drives at a time to make copy/paste files between them
    • Example HID: Read keyboard and mouse at the same time on both USB ports


  • HAL
  • TM
    • STM32Fxxx HAL
    • defines.h
    • ST USB Host stack
    • ST USB Device stack

USB Common settings

Both USB types (Host or Device) have some settings in common. These are at least defines for library use and GPIO pinouts for USB. For USB settings, you will have to make some defines before you will be able to run any example. Settings which can be defined are included below.

USB pinout can be found in table below for some different STM32F4xx and STM32F7 boards.

USB Common functions

To see all functions, which are common to all USB based libraries, check API description.

USB Host

USB Host library is a main library, to support Host mode of USB. It allows you to use FS, HS or both modes at the same time, if needed.

For detailed description about HOST library, you should look at API description.

USB MSC Host Class

USB MSC Host class is designed for operating with USB Flash memory based devices. It can read/write to flash memory using FATFS module.

For detailed implementation for USB HOST MSC, check API description.

For detailed explanation on how to use USB with FATFS, check my FATFS library.


For USB MSC Host class, I’ve made 2 examples, which shows how to use MSC on single USB port or on dual ports.

  • Example 1: DUAL MSC Host
    • Shows, how to use MSC Host on both USB FS and HS ports at the same time.
  • Example 2: MSC HOST and HID HOST at the same time
    • Shows, how to use USB MSC HOST and USB HID HOST at the same time. One port is for HID, another for MSC

Examples are available on my Github repository.

USB HID Host Class

USB HID Host class is designed for operating with HID keyboard or HID mouse. It allows you to use FS, HS or both modes at the same time, if needed.

For detailed implementation for USB HOST HID, check API documentation.


For USB HID Host class, I’ve made 4 examples, which shows how to use HID in different configurations

  • Example 1: DUAL HID Host
    • Shows how you can use HID Host on both USB ports, FS and HS at the same time. This allows you for example connecting mouse and keyboard at the same time if needed
  • Example 2: MSC HOST and HID HOST at the same time
    • Shows, how to use USB MSC HOST and USB HID HOST at the same time. One port is for HID, another for MSC
  • Example 3: HID Host and CDC Device
    • Example shows how you can have one USB port for CDC device mode and another for HID Host mode. This allows you to connect your board to computer and still reading keyboard/mouse on another USB port
  • Example 4: HID Host and CDC Device with dynamic change
    • Example shows how you can have single USB port (HS is used in example) for multi purposes. With button press, you can change active USB mode on the fly when needed

Examples are available on my Github repository.

USB Device

USB Device library is main library for USB Device support for STM32Fxxx device.

For detailed explanation about USB Device library, you should look API documentation.

USB CDC Device Class

USB CDC device class is mainly used for communication between computer and STM32Fxxx device over Virtual COM Port (VCP).

For detailed implementation for USB DEVICE CDC, check API documentation.


For USB CDC Device, I’ve made 4 examples, which shows how to use CDC in different configurations.

  • Example 1: Basic CDC example
    • Shows how to use CDC in simple configuration for first time
  • Example 2: HID Host and CDC Device with dynamic change
    • Example shows how you can have single USB port (HS is used in example) for multi purposes. With button press, you can change active USB mode on the fly when needed
  • Example 3: HID Host and CDC Device
    • Example shows how you can have one USB port for CDC device mode and another for HID Host mode. This allows you to connect your board to computer and still reading keyboard/mouse on another USB port
  • Example 4: USB to UART converted
    • Shows, how you can init USART based on user selected values from terminal on computer

Examples are available on my Github repository.

USB MSC Device Class

USB MSC device class is mainly used for communication between SDCARD and PC. STM32Fxxx acts like SDCARD reader and sends/receives data to/from PC. Device is shown to user as Mass Storage Device on computer.

For detailed explanation for USB DEVICE MSC, check API documentation.


  • Example 1: Basic MSC example
    • SDCARD is connected to SDIO port on STM32Fxxx, and on USB HS port, device is shown to computer as Mass Storage Device.

Compiled ALL examples

I’ve precompile all examples which can also be found and download from my github account for those, who don’t have Keil uVision or can’t compile it. Download is available below.

USB Compiled examples

Download all libraries below.

TM STM32 Libraries

STM32 libraries based on STM32Fxxx HAL drivers.


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!
  • Pingback: HAL Library 20- FATFS for STM32Fxxx - STM32F4 Discovery()

  • Pingback: All STM32 HAL libraries - STM32F4 Discovery()

  • Herbert

    Hi Tilen, first of all thanks for sharing this library! I get a stable USB connection and the previous hard faults (with another lib) are gone. I have a question about the usage of your RX and TX buffer especially in CDC and FS mode. In tm_stm32_usb_device_cdc.c you always call TM_UCBD_CDC_INT_GetRXBuffer() to get the buffer pointer no matter if the function is for “put” or “get”. And in TM_UCBD_CDC_INT_GetRXBuffer() you return the address of the TX buffer. I would have expected that TM_UCBD_CDC_INT_GetRXBuffer() returns the RX buffer address and that there would be another function TM_UCBD_CDC_INT_GetTXBuffer() which returns the TX buffer address. Further I would have expected, that in the “put” functions the TM_UCBD_CDC_INT_GetTXBuffer() function and in the “get” functions the TM_UCBD_CDC_INT_GetRXBuffer() is called. Am I right or is there something I totally misunderstood in using the two buffers?

    Best regards

    • You are definetely right. I missed this for some reason.
      Library is updated and ready to use.

      Thanks for reporting this.

  • Ilya

    Hi Tilen, I’m using you project ( USB MSC Device ). I got about 850 kbps maximum writting speed via USB -> SDIO. Is it possible to increase writting speed ? Thanks)

    • If you have F4 disco, then you are probably using USB FS mode.
      There are restrictions using card reading and also FS mode communicaiton up to 12Mbit.

      • Ilya

        Yes. I’m using FS-Mode. Reading speed is about 3 – 3.5 Mbps. It’s enough for my task. But writting speed is too slow…

        • Try to write BIG amount of data at a time. If it is possible, do it with multiply of 512 bytes as this is sector size.

          PS: First you said 3Mbps, now only 1Mbps?

          • Ilya

            Sorry… There were 2 USB devices connected to my PC. I checked speed of USB FLASH Device instead of DISCOVERY Board. It’s my fault. Real reading speed is 0.9 – 1.1 Mbps. I tried to write big file (560 MB). Writting speed is 877 Kbps.

          • Mahmoud Ramadan

            hello llya , could you please tell me how did you calculate reading/writing speed.

          • Ilya

            Hello Mahmoud. Data transfer rate – the amount of data transmitted per unit time. You need to pinpoint the time with a timer and measure the amount of bytes that were transferred. This can be done as a hardware timer (USB device side) and software on the host side.

          • Ilya

            I increased speed by changing HEAP size and MEDIA_PACKET_SIZE to 32 kb. Now writing speed is 975 Kbps. I’ll try to increase it more.

  • Oğuzhan Uyğun

    First of all your library is great. I wanna use usb port as hid devices. But your all examples about host devices. So, I wanna use my board as a keyboard. How can I do this?

    • I know, it is not supported yet. I must upgrade lin to support that 🙂

      For now, my usb hid device can be used. Library 36 or something like that. Check all std libs.

      • Arif Balık

        Can I use your old std lib for stm32f7 devices? ls there any std lib for f7 microcontrollers?

        • It might works, but probably won’t work with my standard peripheral drivers for F4.
          There is no STD drivers for F7.

          • Arif Balık

            But I can use hal library for hid devices. Cant I?

          • Sure.

  • Marc

    Hello Tilen. Thanks for sharing awesome libraries. I’m studying stm32f4 with stm32f429-discovery board and your blogs. MY problem is… USB_DEVICE_MSC library is not working(I can hear the connection sound but it doesn’t appear in my PC.). However the hex file of USB_DEVICE_MSC you uploaded is working well. Do you have any clue of this kind of problem? Thank you so much!!!

    • Hi, i will ask you. Do you have PLL set correct? USB needs 48MHz with internal phy.

      • Marc

        Thanks for your fast reply. 🙂 I checked it and it had set correctly. I tried to solve this problem by myself today. However I couldn’t find the solution yet. Do you have any other ideas? Thank you so much Tilen!

        • Without seen code, im unable to do anything.

          • Marc

            Oh I used your Library(21-STM32Fxxx_USB_DEVICE_MSC) and I didn’t change anything. 🙂 The Hex file you uploaded works well. Are there any differences? Also FAFTS library(20-STM32Fxxx_FAFTS_SDCARD) works well too. Thanks again! 🙂

  • Luca

    Hi Tilen,

    I am trying to develop a VCP application on a 32F429IDISCOVERY boar. As a first try I downloaded the .hex file and loaded on the board. Then I installed PC drivers, version 1.3.1 64-bit. I am using Windows 7 on a 64-bit machine. The PC sees correctly the COM port (this did not work with 1.4 driver version), but the char echo did not work.

    So I tried compiling the sources. I ported the project to IAR, compiled everything and loaded on the board, but the PC does not see the port anymore. Is it possible to obtain more details on how the sources are compiled? There is something I don’t understand. For example, in “project.build_log.htm” for the .hex file I read a reference to “22-STM32Fxxx_USB_TO_UART”, but on latest library version it is number 21, so is it possible that this .hex is related to an old library version? Has the latest version been tested? This is to be sure i do not have to make changes to sources before compiling to make it work. My objective now is not have the echo application, but just be sure i compile the sources correctly.
    Thank you very much,

    • Hello,

      I recently made a mistake in folder name (project name) so I renamed it just. Nothing else.

      VCP UART example sends data from VCP to UART.
      What you send to UART, you will see on VCP.

      If you want to get back what you send on your temirnal, then use normal VCP example or load HEX files.

      If it does not work, do you have properly set clock for PLL? I have some defines in keil options for target defines section which are needed there.

      • Luca

        I checked that if these macros are not added the default values are used, from tm_stm32_rcc.h, that should set the clock to 168 MHz

        • If you use compiled version HEX file for project “21-STM32Fxxx_USB_DEVICE_CDC”, is there a sound on computer about detected USB?

          If so, then it works ok.

          • Luca

            yes, I hear the sound, but the echo does not work if I connect with a terminal

          • Which example you used to upload?

          • Luca


          • Ok, I see the problem.

            F429 disco uses HS mode for usb. And I have set in example, that fro hs usb, it receives strings and sends them back.

            So for test, send you string and then 0x0D at the end (n) and it will return entire string back to you.

            Go to my github and check how this example is done, here:

            Last if statement.

          • Luca

            Thanks Tilen, I was completely wrong because I understood that the board used FS on the micro-USB connector. Now I get the echo.
            I hope to solve my problems with compiled sources too, now.

          • Have you enabled some defines in your compilation?


          • Luca

            Yes, I did it, but I was enabling FS mode only. Now I will try again without modifying the source code (excetp for the macros needed).

          • Luca

            I confirm that now everything works, thanks for the assistance. I just want to warn you of something. In the “defines.h” files in many USB related projects the PLLN is set to 360 in a commented line. This could be misleading.

          • Im doing this in keil global defines.

            Btw..without external phy, you cant use 180MHz clock, but max 168, because of pll configuration for usb which must be 48MHz.

            So plln should be set to 336 when using usb.

  • Miloš Lovrić

    Hi Tilen,

    I need to transfer data (JPEG images) at 1-2 Mbit/s speed from STM32F429 Discovery external RAM to Java application running on Windows. Can you suggest me the best way to do this, is it possible to do this using this driver?


    • Use UART at > 2Mbits or you can also use this. UART is easier 🙂

      I suggest you custom HID descriptor (OK, maybe this with VCP could also go).

      • Miloš Lovrić

        Sorry, I meant 1-2 MB/s. You think this is achievable with the driver, considering USB FS speed is 12Mbits/s? I can reduce JPEG quality to fit not more than 1MB/s.

      • divum

        Hi Majerle,

        I need help Regarding STM32L0538 DISCO.
        Please kindly let me know the debugging process,i need to print the data (like serial monitor of ARDUINO).

        • USB VCP.

          • divum

            for this i need to use any libraries in source code….

          • Totally true.

          • divum

            Do you have any predefined libraries for STM32L0538 DISCO MCU?

          • I dont.

  • macgeorge

    Hi there,
    I have been checking your 21-STM32Fxxx_USB_DEVICE_CDC example via github and I have run on a strange error, using a F746 Discovery and latest Keil v5. The example works correctly in HS and FS mode, but when I change in the target options to not use MicroLIB (uncheck the box), the microcontroller does not start (no connection with PC, debugger hangs).
    Do you confirm this? Is there a way to run the library without MicroLIB?

    • Right now i cant confirm. Is there a reason why microlib is not ok for you?

      • macgeorge

        Thanks for the quick reply. I had the opposite problem on another project I was building, the microcontroller was not running if I was using MicroLIB. Trying to merge those projects, I am stuck. Anyway, I wanted to know if you have already encountered it. I will try to modify the other code to be able to use MicroLIB. Thanks!

  • Gabriel

    I’m using STM32F4-Discovery and I’m having a difficult time to put your example with USB_DEVICE_MSC to work. I’ve already changed the PPLs to obtain 48MHz for USB and I’ve been able run your example SDCARD with SDIO without any problems, so this is not the issue.
    The code smoothly compiles without any errors but the PC does not recognise the board as a MSC device at all. I’ve tried different PCs, different cables but nothing happens. Any ideias?

  • Abhinav Kumar

    Hi Tilen,

    I am using the STM32F4 for USB VCP in device mode for communicating to my mobile as host.Is there a way to detect the disconnection of the host?Will there be any interrupt generated…


  • Abhinav Kumar

    Hi Tilen,

    I used your TM library functions in my stml4discovery board for USB VCP in device mode.
    None of these functions are showing error:
    but still its not detecting the com port .
    Can you please suggest the possible cause?

    • Hi,

      L4xx series discovery you have? This works for F4 and F7 for now only.

      Btw..if I’m wrong, and you are using F4 disco, then make sure you have:
      1. Using FS port properly (Enabled FS port in my library)
      2. You have clock config and PLL properly set.

      For first, check my USB library HAL API. Link is available on top of page. Check API for configuration settings.

      • Abhinav Kumar

        Hi Tilen,

        I used your TM library function for USB CDC program in STM32L4 Discovery. It’s working fine.The User Manual says to Close two switches which i didn’t follow earlier.
        Thanks for your Library.
        Also i have one more clarification to make. I understand that TM_USBD_Init() will initialize the USB and after that OTG_FS_IQ_Handler() interrupt is generated which makes the USB to be detected as Virtual com port.

        My query is what triggers this interrupt.As I tried to port the same STM32L4 discovery code into a Stm32L4 development board,but it’s not detecting the USB

  • Mahmoud Ramadan

    Hello Tilen, Thanks for those libraries.
    i’m using stm32f4 discovery board and trying to run USB_DEVICE_MSC.
    working in full speed mode, SDIO 1 bit mode and PLL is set correctly.
    the problem is that device is shown to my computer as Mass Storage Device but with yellow triangle and ” device driver software wasn’t successfully installed ” message.

    thanks in advance.

    • Mahmoud Ramadan

      I solved it. The problem was the heap size. i increased it and it is OK. but the problem now if i made any write operation on SD Card such as creating new file or sending file from my PC to SD or just change the name of SD Card and re-enter it again, the changes will be lost !

  • Pingback: Library 24- Virtual COM Port (VCP) for STM32F4 - STM32F4 Discovery()

  • Jeremy

    Hey Tilen, this library goes a long way to making USB easier on the STM32 chipset! I have a question though, do you think you will add USB DFU mode support to your library to give built-in access to the DFU bootloader? It would awesome to have all supported USB modes in the same library and be able to program a DFU file through USB as well in the same library. Great job with this lib though!

    • You don’t need a library to program STM32 with native USB bootloader. Just set up boot pins and reset MCU, it will jump to bootloader for DFU.

  • joristip

    Hi Majerle, I’m using a STM32F407VG discovery board, I tried to use the 21-STM32Fxxx_USB_HOST_MSC_DUAL example and compiled it with GCC and I used these settings: PLLM=8, PLLN=336, PLLP=2, PLLQ=7, HSE=8000000.
    I do only use USB FS.
    The board detects the USB flash disk, but when it comes to the f_mount part, I’m always getting a FR_DISK_ERR. I tried 4 different flash disks which worked at the STD libraries.What could be the problem?

    • 1. How you mount card? What path you use for mount
      2.Try to increase HEAP in your linker for malloc allocation.

      • joristip

        1. I’m using your example, so after the checks TM_USBH_IsConnected(TM_USB_FS), TM_USBH_MSC_IsConnected(TM_USB_FS) and TM_USBH_MS_IsReady(TM_USB_FS) I try to mount the USB with this command: if ((fres = f_mount(&FATFS_USB_FS, “USBFS:”, 1)) == FR_OK). This Always returns FR_DISK_ERR. When I look deeper in the firmware, at the function “USBH_MSC_Read()” in usbh_msc.c the MSC_Handle->unit[lun].state is always MSC_INIT and that’s why this function returns USBH_FAIL.

        2. I don’t know how to increase the HEAP size, can’t find a good turorial for that as well. but what I tried was increase the IRAM1 size from 0x00020000 to 0x00040000 but that didn’t help

        • For gcc you have special commands, but for keil uvision is simple variable for linker.

          Iram has no sense here, heap is important.

  • Phạm Minh Quân

    Hi Majerle,

    I’m using a STM32F429 Discovery board. I want to use USB host MSC libs to save data to a pendrive and it is alright now. I also try to create PWM signals to control motors but I can not start the timers to create PWM signals. Could you please explain me about this problem? Is there any confliction between timer modules and USB module?

    Thank you so much!

    • No limitations here.

      • Phạm Minh Quân

        Got it, thank Majerle!

  • Jerry

    Tilen, Here I am again. I got my code ported to the 407 disco and it is working perfectly, thanks to your libraries. I am now trying to port it to the STM32F7 Discovery board. I am starting with the USB functions using your HAL example. When the code enters the TM_RCC_InitSystem(); routine and calls HAL_RCC_ClockConfig, at line 670 in stm32f7xx_hal_rcc.c where it does __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource); it branches to 0x00 and crashes. I’ve been all over the code and can’t figure it out. Any ideas?

    Do you have a project using USB device as a VCP specific for the F7 board?

    Thanks. I’ll get out of your hair soon…


    • Check init function where crashes and remove cache for data and instr. There are 2 functions.

      I have. Github.

      • Jerry

        I found one define that enables cache and tried it both ways. I’ll keep looking.

        • Disable cache.

          • Jerry

            Tried disabling cache with no luck. I don’t see the cache referenced before the crash so I don’t think it is getting that far. Tried making other projects. The issue is I am using the openstm32 workbench. In those projects, there is assembler startup code that I think sets the clock, not sure, only an assumption. But any project that I make that calls your RCC Init crashes the same way. if I leave that out, then the code runs somewhat but USB doesn’t connect and I tried the LCD module and I get a green screen with text that is out of sync. So something isn’t getting initialized properly without calling your rcc init function.

            I am now updating my older Eclipse workbench to include the F7 project templates. I am going to copy your code into one of those projects and see what happens.

            I was able to convert my project from the 8051 to the 407 board which cuts the cost from $50 to $10. If I can get the F7 board working then I can expand the project using the larger LCD in conjunction with the PC interface or without for stand alone operation. The screen on the 429 board was too small and only one DAC is available.

            Thanks. I’ll post if this other toolchain works.

  • Alex Amaral

    Hi Tilen, thanks for the awesome libraries! I’m having an issue with the “21-STM32Fxxx_USB_DEVICE_MSC” example from your libraries on the STM32F429-Discovery where the device is picked up by the PC but never enumerates properly and I get a Windows error 43 saying that the device reported an error and stopped. I’m using your library un-edited so the PLL settings are all fine. I see that another user had this problem here about a year ago and I’m wondering if it was ever solved or you have any idea what the problem is?



    • I did not work anything about that problem since then, so I’m unable to tell it now.

      • Alex Amaral

        Hi Tilen sorry to bother again, if I loaded the pre-compiled “21-STM32Fxxx_USB_DEVICE_MSC” and the “21-STM32Fxxx_USB_DEVICE_CDC” examples for my board that you provided using the STM32 ST-Link Utility and it still gave me the same “device not recognized” error in Windows, I’m assuming this means that the USB HS on my board is broken as your other examples like the basic DISCO LED example works fine. Or is there something I might be doing wrong with loading the hex onto my board?

        I see that with the hex code is also a Windows Script Component (.sct) file, is there anything I need to do with this?

        I thought that maybe I was missing something in the code but if your pre-compiled examples don’t work then surely it must be the hardware?


        • For cdc problem might be on drivers on pc. Win10 has some problems.

          For msc Im not sure about cause.