Library 29- USB MSC HOST for USB flash drive on STM32F4
Recently I made a library to read SD cards with FatFs by Chan. Today, I made a new library for USB MSC Host and connect both libraries together, so you can operate with USB flash drives and SD cards simultaneously with STM32F4xx device. USB MSC Host library is a separate library, to handle and do stuff with USB stack. You will also need my FatFS library for SD cards.
I will go here step by step, how to configure this library and FatFs together and show example, how to work with USB and SD card at the same time.
Library
Features
- Operate with USB flash drives
- Supported USB FS and USB HS in FS mode
- USB OTG is connected to USB FS mode on STM32F4-Discovery board
- USB OTG is connected to USB HS in FS mode on STM32F429-Discovery board
- FatFS by Chan supported
- FAT16 and FAT32 file formats supported
Dependencies
- CMSIS
- STM32F4xx
- STM32F4xx RCC
- STM32F4xx GPIO
- MISC
- TM
- FatFs
- defines.h
- FatFs
- USB
- USB MSC 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:
1 2 3 4 5 6 7 8 |
/* defines.h configuraion file */ /* Uncomment if you want to disable ID pin for USB MSC HOST library */ //#define USB_MSC_HOST_DISABLE_ID /* Uncomment if you want to disable VBUS pin for USB MSC HOST library */ /* If you do this, on F4 and F429 Discovery boards USB will not work */ //#define USB_MSC_HOST_DISABLE_VBUS |
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:
1 2 3 4 5 6 |
/* defines.h configuration file */ /* Uncomment if you want to enable USB HS in FS mode */ /* Used on STM32F429 Discovery board */ /* By default, USB FS mode is used */ //#define USE_USB_OTG_HS |
We are done now with settings for USB Host communication. We have now to add my FatFs library and configure it.
Enable FatFs for USB MSC Host
In dependencies section is link where you can download my FatFs library. I have updated it to set it up with USB MSC Host. To enable FatFs library with USB Host, you will have to add these lines in your defines.h file:
1 2 3 |
/* This line MUST BE ADDED in order to use FATFS with USB */ /* Otherwise you will have errors */ #define FATFS_USE_USB 1 |
When you activate line above, you automatically disable SDcard settings. If you want to enable SDcard communication too, you will have to also add these lines in your defines.h file:
1 2 3 4 5 6 7 8 9 |
/* By default, if you use USB, then SD card is disabled */ /* If you don't use USB, then SDIO is used by default! */ /* If you want to use both, USB and sdcard at the same time, */ /* then enable SD card communication below: */ /* Enable SDIO communication */ //#define FATFS_USE_SDIO 1 /* If you want SPI communication instead of SDIO, enable with */ //#define FATFS_USE_SDIO 0 |
Look at my SDcard FatFs library to properly set up SDcard communication.
FatFs files for USB MSC Host
You will need these files included for USB communication:
- tm_stm32f4_fatfs.h
- tm_stm32f4_fatfs.c
- fatfs/diskio.h
- fatfs/diskio.c
- fatfs/ff.h
- fatfs/ff.c
- fatfs/ffconf.h
- fatfs/integer.h
- fatfs/option/syscall.c
- fatfs/option/unicode.c
- fatfs/drivers/fatfs_usb.h
- fatfs/drivers/fatfs_usb.c
- USB MSC HOST Stack
- tm_stm32f4_usb_msc_host.h
- tm_stm32f4_usb_msc_host.c
USB FatFs settings
I’m using the same FatFs library files for USB and SD card. For that purpose, SDcard has partition 0: and USB device has partition 1:.
If you need real time clock for FatFs, check my SDcard library with FatFs how to configure it.
USB Host important notes
- Clock was set down to 168MHz for STM32F429 because you can not get 48MHz for USB from 180MHz core clock.
- When you format your USB flash drive, it can take some time to be recognized by STM32F4 USB MSC Host library.
- Some USB flash drives will not work with library. I got some of them that “device not supported”. This can be handled by library too. Check functions below.
- FAT16 and FAT32 devices supported.
- Tested with 4GB, 8GB and 2x 16GB USB flash drives.
USB Host functions
Almost everything is configured in FatFs communication library.
You have to use some functions to handle USB device:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
/** * Result enumeration * - TM_USB_MSCHOST_Result_Error * An error occured * - TM_USB_MSCHOST_Result_Connected * Device is connected and ready to use with FATFS * - TM_USB_MSCHOST_Result_Disconnected * Device is not connected * - TM_USB_MSCHOST_Result_DeviceNotSupported * Device is not supported * - TM_USB_MSCHOST_Result_WriteProtected * Device is write protected * - TM_USB_MSCHOST_Result_LibraryNotInitialized * Library is not initialized yet */ typedef enum { TM_USB_MSCHOST_Result_Error, TM_USB_MSCHOST_Result_Connected, TM_USB_MSCHOST_Result_Disconnected, TM_USB_MSCHOST_Result_DeviceNotSupported, TM_USB_MSCHOST_Result_WriteProtected, TM_USB_MSCHOST_Result_LibraryNotInitialized } TM_USB_MSCHOST_Result_t; /** * Initialize USB MSC HOST peripheral * * Returns current device status. A member of TM_USB_MSCHOST_Result_t typedef is returned */ extern TM_USB_MSCHOST_Result_t TM_USB_MSCHOST_Init(void); /** * This function has to be called periodically. * As fast as possible. * * It handles USB device * * Returns TM_USB_MSCHOST_Result_t typedef member */ extern void TM_USB_MSCHOST_Process(void); /** * Check device status. * * Returns current device status. A member of TM_USB_MSCHOST_Result_t typedef is returned * if TM_USB_MSCHOST_Result_Connected is returned, then you are ready to work */ extern TM_USB_MSCHOST_Result_t TM_USB_MSCHOST_Device(void); |
Example 1
Write first data to USB flash. This library was tested on STM32F429-Discovery board. But if you configure defines.h file to work in USB FS mode, you will be able to run this on STM32F4-Discovery too.
Possible leds:
- Only RED on: device is not recognized
- Only GREEN: Everything OK
- Both on: mounted OK, but file was not opened
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#ifndef TM_DEFINES_H #define TM_DEFINES_H /* Place your custom library settings here */ /* Uncomment if you want to disable ID pin for USB MSC HOST library */ //#define USB_MSC_HOST_DISABLE_ID /* Uncomment if you want to disable VBUS pin for USB MSC HOST library */ /* If you do this, on F4 and F429 Discovery boards USB will not work */ //#define USB_MSC_HOST_DISABLE_VBUS /* Uncomment if you want to enable USB HS in FS mode */ /* By default, FS mode is used */ #define USE_USB_OTG_HS /* STM32F429-Discovery */ /* This line MUST BE ADDED in order to use FATFS with USB */ /* Otherwise you will have errors */ #define FATFS_USE_USB 1 /* By default, if you use USB, then SD card is disabled */ /* If you don't use USB, then SDIO is used by default! */ /* If you want to use both, USB and sdcard at the same time */ /* Enable SD card communication below: */ /* Enable SDIO communication */ //#define FATFS_USE_SDIO 1 /* If you want SPI communication instead of SDIO, enable with */ //#define FATFS_USE_SDIO 0 #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
/** * Keil project for USB MSC HOST * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 * * Select your target right of the "Load" button, compile and download to your discovery board * Works with F4-Discovery in USB FS mode and on F429-Discovery with USB HS in FS mode * Also works on all STM32F4xx devices with USB built in */ #include "defines.h" #include "stm32f4xx.h" #include "tm_stm32f4_disco.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_usart.h" /* Include fatfs and usb libraries */ #include "tm_stm32f4_fatfs.h" #include "tm_stm32f4_usb_msc_host.h" #include <stdio.h> int main(void) { FATFS USB_Fs; FIL USB_Fil; char buffer[50]; uint8_t write = 1; uint32_t free, total; /* Initialize system */ SystemInit(); /* Initialize delay functions */ TM_DELAY_Init(); /* Leds init */ TM_DISCO_LedInit(); /* Initialize USB MSC HOST */ TM_USB_MSCHOST_Init(); while (1) { /* Host Task handler */ /* This have to be called periodically as fast as possible */ TM_USB_MSCHOST_Process(); /* Device is connected and ready to use */ if (TM_USB_MSCHOST_Device() == TM_USB_MSCHOST_Result_Connected) { /* If we didn't write data already */ if (write) { /* Try to mount USB device */ /* USB is at 1: */ if (f_mount(&USB_Fs, "1:", 1) == FR_OK) { TM_DISCO_LedOn(LED_GREEN); /* Mounted ok */ /* Try to open USB file */ if (f_open(&USB_Fil, "1:usb_file.txt", FA_READ | FA_WRITE | FA_OPEN_ALWAYS) == FR_OK) { /* We want to write only once */ write = 0; /* Get total and free space on USB */ TM_FATFS_USBDriveSize(&total, &free); /* Put data */ f_puts("This is my first file with USB and FatFS\n", &USB_Fil); f_puts("with USB MSC HOST library from stm32f4-discovery.net\n", &USB_Fil); f_puts("----------------------------------------------------\n", &USB_Fil); f_puts("USB total and free space:\n\n", &USB_Fil); /* Total space */ sprintf(buffer, "Total: %8u kB; %5u MB; %2u GB\n", total, total / 1024, total / 1048576); f_puts(buffer, &USB_Fil); /* Free space */ sprintf(buffer, "Free: %8u kB; %5u MB; %2u GB\n", free, free / 1024, free / 1048576); f_puts(buffer, &USB_Fil); f_puts("----------------------------------------------------\n", &USB_Fil); /* Close USB file */ f_close(&USB_Fil); /* Turn GREEN LED On and RED LED Off */ /* Indicate successful write */ TM_DISCO_LedOn(LED_GREEN); TM_DISCO_LedOff(LED_RED); } } /* Unmount USB */ f_mount(0, "1:", 1); } } else { /* Not inserted, turn on RED led */ TM_DISCO_LedOn(LED_RED); TM_DISCO_LedOff(LED_GREEN); /* Ready to write next time */ write = 1; } } } |
Example 2
This example works with SDcard and USB MSC Host flash drive.
USB Host in configured in USB HS in FS mode and SD card has SDIO communication.
Leds status:
- Led RED on: SDcard written OK
- Led GREEN on: flash drive written OK
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#ifndef TM_DEFINES_H #define TM_DEFINES_H /* Place your custom library settings here */ /* Uncomment if you want to disable ID pin for USB MSC HOST library */ //#define USB_MSC_HOST_DISABLE_ID /* Uncomment if you want to disable VBUS pin for USB MSC HOST library */ /* If you do this, on F4 and F429 Discovery boards USB will not work */ //#define USB_MSC_HOST_DISABLE_VBUS /* Uncomment if you want to enable USB HS in FS mode */ /* By default, FS mode is used */ #define USE_USB_OTG_HS /* STM32F429-Discovery */ /* This line MUST BE ADDED in order to use FATFS with USB */ /* Otherwise you will have errors */ #define FATFS_USE_USB 1 /* By default, if you use USB, then SD card is disabled */ /* If you don't use USB, then SDIO is used by default! */ /* If you want to use both, USB and sdcard at the same time */ /* Enable SD card communication below: */ /* Enable SDIO communication */ #define FATFS_USE_SDIO 1 /* If you want SPI communication instead of SDIO, enable with */ //#define FATFS_USE_SDIO 0 #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
/** * Keil project for USB MSC HOST * Data is saved into SD card via SDIO communication and into USB flash drive * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 * * Select your target right of the "Load" button, compile and download to your discovery board * Works with F4-Discovery in USB FS mode and on F429-Discovery with USB HS in FS mode * Also works on all STM32F4xx devices with USB built in */ #include "defines.h" #include "stm32f4xx.h" #include "tm_stm32f4_disco.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_usart.h" /* Include fatfs and usb libraries */ #include "tm_stm32f4_fatfs.h" #include "tm_stm32f4_usb_msc_host.h" #include <stdio.h> int main(void) { FATFS USB_Fs, SD_Fs; FIL USB_Fil, SD_Fil; char buffer[50]; uint8_t usb_write = 1, sd_write = 1; uint32_t free, total; /* Initialize system */ SystemInit(); /* Initialize delay functions */ TM_DELAY_Init(); /* Leds init */ TM_DISCO_LedInit(); /* Initialize USB MSC HOST */ TM_USB_MSCHOST_Init(); while (1) { /* Host Task handler */ /* This have to be called periodically as fast as possible */ TM_USB_MSCHOST_Process(); /* USB Device is connected and ready to use */ if (TM_USB_MSCHOST_Device() == TM_USB_MSCHOST_Result_Connected) { TM_DISCO_LedOn(LED_GREEN); /* If we didn't write data already */ if (usb_write) { /* Try to mount USB device */ /* USB is at 1: */ if (f_mount(&USB_Fs, "1:", 1) == FR_OK) { /* Mounted ok */ /* Try to open USB file */ if (f_open(&USB_Fil, "1:usb_file.txt", FA_READ | FA_WRITE | FA_OPEN_ALWAYS) == FR_OK) { /* We want to write only once */ usb_write = 0; /* Get total and free space on USB */ TM_FATFS_USBDriveSize(&total, &free); /* Put data */ f_puts("This is my first file with USB and FatFS\n", &USB_Fil); f_puts("with USB MSC HOST library from stm32f4-discovery.net\n", &USB_Fil); f_puts("----------------------------------------------------\n", &USB_Fil); f_puts("USB total and free space:\n\n", &USB_Fil); /* Total space */ sprintf(buffer, "Total: %8u kB; %5u MB; %2u GB\n", total, total / 1024, total / 1048576); f_puts(buffer, &USB_Fil); /* Free space */ sprintf(buffer, "Free: %8u kB; %5u MB; %2u GB\n", free, free / 1024, free / 1048576); f_puts(buffer, &USB_Fil); f_puts("----------------------------------------------------\n", &USB_Fil); /* Close USB file */ f_close(&USB_Fil); /* Turn GREEN LED On */ /* Indicate successful write for USB flash */ TM_DISCO_LedOn(LED_GREEN); } } /* Unmount USB */ f_mount(0, "1:", 1); } } else { /* Not inserted, turn off GREEN led */ TM_DISCO_LedOff(LED_GREEN); /* Ready to write next time */ usb_write = 1; } /* Try to mount SD card */ /* SD card is at 0: */ if (f_mount(&SD_Fs, "0:", 1) == FR_OK) { /* Mounted ok */ /* Write only once */ if (sd_write) { /* Try to open SD card file */ if (f_open(&SD_Fil, "0:sd_file.txt", FA_READ | FA_WRITE | FA_OPEN_ALWAYS) == FR_OK) { /* We want to write only once */ sd_write = 0; /* Get total and free space on SD card */ TM_FATFS_DriveSize(&total, &free); /* Put data */ f_puts("This is my first file with SD card and FatFs\n", &SD_Fil); f_puts("with SD card library from stm32f4-discovery.net\n", &SD_Fil); f_puts("----------------------------------------------------\n", &SD_Fil); f_puts("SD card total and free space:\n\n", &SD_Fil); /* Total space */ sprintf(buffer, "Total: %8u kB; %5u MB; %2u GB\n", total, total / 1024, total / 1048576); f_puts(buffer, &SD_Fil); /* Free space */ sprintf(buffer, "Free: %8u kB; %5u MB; %2u GB\n", free, free / 1024, free / 1048576); f_puts(buffer, &SD_Fil); f_puts("----------------------------------------------------\n", &SD_Fil); /* Close SD card file */ f_close(&SD_Fil); /* Turn RED LED On */ /* Indicate successful write for SD card */ TM_DISCO_LedOn(LED_RED); } } /* Unmount SD card */ f_mount(0, "0:", 1); } else { /* Not inserted, turn off RED led */ TM_DISCO_LedOff(LED_RED); /* Ready to write next time */ sd_write = 1; } } } |
Both projects are available on my Github account, where you can download it, download library below.
Recent comments