STM32 USB HOST MSC

In this tutorial, we will see how to use STM32 USB as a host to interface any Mass Storage Device, for eg- flash drive, or a SD card. To do so, we need to use USB as a Mass Storage Class (MSC). We will also use FATFS (FAT File System) to create some directories, and files on the USB.

CubeMX Setup

First of all we need to select the USB_OTG_FS in Host Only mode. Also make sure you activate the VBUS, as the USB devices mostly don’t have the Power supply, and that’s why VBUS will provide the required power to such devices.


Next, select the USB_HOST and select the class as Mass Storage Class. Leave everything here to default.


Above is the Setup for the FATFS.
I have enabled the use of Long File names.
Increase the MAX sector size to 4096
I have also enabled the support for EXFAT File System.


And now we need to enable the voltage supply to the VBUS pin. To do that you need to look at the user manual for your board. I am using STM32F4 discovery board, and it have the following diagram for the USB

As you can see above, the VBUS is powered from the PC0 pin. But PC0 is connected to the EN Pin, which is an active Low pin. This means in order to supply the voltage to the VBUS, we must Pull down the PC0 Pin, or basically Set it LOW.


The final PINOUT is as shown above

  • UART2 is connected to PC, so that we can see the output for the debugging purpose
  • PC0 is set as output, to enable the voltage to the VBUS
  • USB Pins are automatically selected, when you select the USB HOST


Some Insight into the code

First of all we need to copy the file handling library files. This is just some FATFS functions arranged in some ways to make the interface a bit easier.

We need to write our program in the usb_host.c file. It is located in root->USB_HOST->App folder

static void USBH_UserProcess  (USBH_HandleTypeDef *phost, uint8_t id)
{
  /* USER CODE BEGIN CALL_BACK_1 */
  switch(id)
  {
  case HOST_USER_SELECT_CONFIGURATION:
  break;

  case HOST_USER_DISCONNECTION:
  Appli_state = APPLICATION_DISCONNECT;
  Unmount_USB();
  break;

  case HOST_USER_CLASS_ACTIVE:
  Appli_state = APPLICATION_READY;

  Mount_USB();

  Check_USB_Details();   // check space details

  Scan_USB("/");   // scan for files and directories

  Create_File("/ROOTFILE.txt");
  Write_File("/ROOTFILE.txt", "This data should be in root file\n");

  Create_Dir("/DIR1");
  Create_File("/DIR1/DIR1FILE.txt");
  Write_File("/DIR1/DIR1FILE.txt", "This data should be in DIR1 file\n");

  Create_Dir("/DIR2");
  Create_Dir("/DIR2/SUBDIR1");
  Create_File("/DIR2/SUBDIR1/DIR2FILE.txt");
  Write_File("/DIR2/SUBDIR1/DIR2FILE.txt", "This data should be in DIR2/SUBDIR1 file\n as i have nothing better to write/n so i just wrote this\n");

  Update_File("/ROOTFILE.txt", "This updated data must be in second line of Root File\n");
  break;

  case HOST_USER_CONNECTION:
  Appli_state = APPLICATION_START;
  break;

  default:
  break;
  }
  /* USER CODE END CALL_BACK_1 */
}

USBH_UserProcess is called at different states, for eg- when the USB Connects, or Disconnects, or When it is Ready for Communication. We will write our program once the Application is READY

The above program is self explanatory. We are creating some files, and Directories. Also we are writing some data inside those files.


Once you connect the USB, the UART output of the above program is shown below

Check out the Video Below




Info

You can help with the development by DONATING Below.
To download the project, click the DOWNLOAD button.

Subscribe
Notify of

16 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Aftaba
1 year ago

I can read the .txt files using above code but if I replace the file with .bin extension (with some binary data in it), the program gets stuck at:
fresult = f_read (&USBHFile, buffer, f_size(&USBHFile), &br);
Any solution for that?

Lucifer
1 year ago

Hello, I use your code on kit stm32f4 discovery
But when I plug in usb, my kit disconnect and usb is empty
i need your help to solve this problem. support me.

lllllllll
1 year ago

5:17
https://youtu.be/_bfROydrssA?t=317
Where can I get these files?
Should they be on my desktop like yours?

Ali
3 years ago

Hi
Thank you for this video. I need to run USB Host MSC with FREERTOS. can you help me?

Jose Luis Flores
Reply to  Ali
2 years ago
I also use FREERTOS, I made some changes to make it work. Do you still need it?
Zerg
Reply to  Jose Luis Flores
2 years ago

I would be grateful if you share the project!

NANDAKUMAR A S
4 years ago

Hi,
At the outset I thank you for the video and tutorial in detail. Simple and clear.
I need to update firmware using flash drive. Can you help me out with sample code. I am using STM32F446RC.
Regards,
NANDAKUMAR A S.

Dan
4 years ago

The code compiles and flashes ok, but when I plug in the USB I get no response via the Serial Monitor. How should I debug?

Dmitrij
Reply to  Dan
4 years ago

I have similar issue with STM32F407GDISC1 board.
According to user manual, Rx Tx is not connected to STLink, so you need connect UART adapter directly to PA2 (TX) and PA3 (RX). or solder flying wires to STL link. Check board User manual.

ABDURRAHMAN MUGHAL
4 years ago

Dear !
kindly define the pins clearly and show complete connections between them.

madhav
4 years ago

hi,
this is madhav. i have seen your project mentioned above. i am working on stm32f107vc. i followed your steps but i did not get any data written in file of the usb stick. file is opened but data is not written empty file is existing after complete the program. can you please tell me if you know the what is the problem i am facing.

f_close not completed successfully at f_write function.

madhav
Reply to  admin
4 years ago

thank you for response
i got below error and fresult is 01.
FR_DISK_ERR,       (1) A hard error occurred in the low level disk I/O layer */
ERROR!!! No. %d in closing file *%s* after writing it\n\n
i need your help to solve this problem. support me.

Jose Luis Flores
Reply to  madhav
2 years ago
I also got an error when using an SD Card with a USB adapter, but when using a regular USB stick it worked fine.