STM32 USB HOST MSC

Description

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.

Setup

Let’s see the CubeMX setup

usb msc seup

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.


usb host setup

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


FATFS setup

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

vbus pin

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.


usb msc host pinout

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

usb msc output
Check out the VIDEO Below

100%
100%

DOWNLOAD

You can buy me a coffee sensor ūüôā

Download the CODE Below

100%
100%
Subscribe
Notify of
guest
6 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Menu
6
0
Would love your thoughts, please comment.x
()
x