Mit dieser Library können normale USB-Sticks am USB-OTG-Port vom Discovery-Modul betrieben werden. Per FATFS-Library (die USB-Version) kann dann mit Filefunktionen darauf zugegriffen werden.
Hinweis : es gibt noch eine Library für SD-Karten per FATFS (Nr. 13) und eine kombinierte Library SD+USB (Nr. 87)
Die Library hat nur zwei Funktionen :
1. Eine “Init-Funktion”
Die muss beim start einmal aufgerufen werden.
2. Die “HOST_Do-Funktion”
Diese muss zyklisch, am besten in der while(1) aufgerufen werden. Sie liefert den Status vom Memory-Stick zurück. Dieser Status muss ausgewertet werden und erst wenn ein USB-Stick erkannt wurde, darf per FATFS darauf zugegriffen werden.
Hinweis : ich hab hier zwei USB-Sticks ausprobiert. Einmal ein 8GB-Stick von SanDisk. Mit diesem kommt es aber zu einem Fehler -> “DEVICE_NOT_SUPPORTED”. Mit dem zweiten Stick, einem 4GB Intenso kommt kein Fehler und das schreiben und lesen funktioniert ohne Probleme.
Es wird ein USB-Adapter mit Micro-USB-Stecker benötigt. (gibts bei EBay oder Amazon)
Beispielbild :
Benutzte Pins :
1 2 3 4 5 | PA9 -> USB_OTG_VBUS PA10 -> USB_OTG_ID PA11 -> USB_OTG_DM PA12 -> USB_OTG_DP PC0 -> USB_VBUS_Enable |
Voraussetzungen :
1 2 | Benutzte Module der CooCox-IDE : GPIO, MISC Benutzte Librarys : STM32_UB_FATFS (USB-Version) |
Enumerationen :
1 2 3 4 5 6 7 8 9 | typedef enum { USB_MSC_HOST_NO_INIT =0, // USB-Schnittstelle noch nicht initialisiert USB_MSC_DEV_DETACHED, // kein Device angeschlossen USB_MSC_SPEED_ERROR, // USB-Speed wird nicht unterstützt USB_MSC_DEV_NOT_SUPPORTED, // Device wird nicht untersützt USB_MSC_DEV_WRITE_PROTECT, // Device ist schreibgeschützt USB_MSC_OVER_CURRENT, // Überstrom erkannt USB_MSC_DEV_CONNECTED // Device verbunden und bereit }USB_MSC_HOST_STATUS_t; |
Funktionen :
1 2 | void UB_USB_MSC_HOST_Init(void); // zum init des USB-Host USB_MSC_HOST_STATUS_t UB_USB_MSC_HOST_Do(void); // zum check vom Device-Status |
Beispiel :
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 | //-------------------------------------------------------------- // File : main.c // Datum : 13.04.2013 // Version : 1.0 // Autor : UB // EMail : mc-4u(@)t-online.de // Web : www.mikrocontroller-4u.de // CPU : STM32F4 // IDE : CooCox CoIDE 1.7.0 // Module : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der USB-MSC-HOST-Library // Hinweis : Diese zwei Files muessen auf 8MHz stehen // "cmsis_boot/stm32f4xx.h" // "cmsis_boot/system_stm32f4xx.c" //-------------------------------------------------------------- #include "main.h" #include "stm32_ub_led.h" #include "stm32_ub_usb_msc_host.h" int main(void) { FIL myFile; // Filehandler uint8_t write_ok=0; SystemInit(); // Quarz Einstellungen aktivieren // Init der LEDs UB_Led_Init(); // Init vom USB-OTG-Port als MSC-HOST // (zum lesen/schreiben auf einen USB-Stick) UB_USB_MSC_HOST_Init(); while(1) { // pollen vom USB-Status if(UB_USB_MSC_HOST_Do()==USB_MSC_DEV_CONNECTED) { // wenn USB-Stick erkannt wurde UB_Led_On(LED_GREEN); // wenn File noch nicht geschrieben wurde if(write_ok==0) { write_ok=1; UB_Led_On(LED_RED); // Media mounten if(UB_Fatfs_Mount(USB_0)==FATFS_OK) { // File zum schreiben im root neu anlegen if(UB_Fatfs_OpenFile(&myFile, "USB_File.txt", F_WR_CLEAR)==FATFS_OK) { // ein paar Textzeilen in das File schreiben UB_Fatfs_WriteString(&myFile,"Test der WriteString-Funktion"); UB_Fatfs_WriteString(&myFile,"hier Zeile zwei"); UB_Fatfs_WriteString(&myFile,"ENDE"); // File schliessen UB_Fatfs_CloseFile(&myFile); } // Media unmounten UB_Fatfs_UnMount(USB_0); } UB_Led_Off(LED_RED); } } else { // wenn kein USB-Stick vorhanden UB_Led_Off(LED_GREEN); } } } |
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download :
Hey, der USB stick wird von mir soweit erkannt, das heisst es müsste auch alles korrekt initialisiert sein…jedoch bricht bricht mir der usb process immer bei der USBH_HandleEnum ab und weiss einfach nicht warum evtl kannst du mir weiterhelfen.
wie ich geschrieben habe, hab ich auch einen Stick der nicht funktioniert. Ich vermute der Code ist nicht ganz Fehlerfrei…aber ich suche da keine Fehler. Versuchs mal mit einem anderen Stick oder im Netz nach einer anderen implementation.
Hallo, bei mir funktioniert alles einwandfrei und der USB- Stick wird sofort erkannt. Allerdings frage ich mich, wie es möglich ist, dass man auf Dateien zugreifen kann, ohne ihren genauen Namen zu wissen. Ich möchte zum Beispiel die erste Datei, die auf dem Stick vorhanden ist öffnen, um daraus zum Beispiel einen mp3- Player zu realisieren. Ich bin noch ziemlicher Anfänger auf dem Gebiet, also wäre es super wenn mir jemand helfen könnte!
ich hab schon einen MP3-Player realisiert : Show-Prj-03. Da kannst du auch nachlesen wie man per “f_readdir()” ein Direktory-Eintrag ausließt. Oder ließ in der Doku von ChaN nach, da stehen auch Beispiele drinn.
Dieses Projekt hatte ich leider noch nicht gesehn. Es wird mir sicher sehr weiterhelfen. Danke!
Hello,
Very good code, i tried it with a OBD2 USB device.
Big thanks.
I will come back in few days to write report.
Hi,
ich wollte mal nachfragen, was alles beim zusammenführen von USB und SDIO zu tun ist?
Oder hast du es evtl. schon gemacht und nur vergessen upzudaten?
Über Hilfe würde ich mich freuen.
ich habe den Kombinierten-Mode jetzt fertig : siehe Dual_FATFS-Library (Nr. 87)
Hello.
I want use USB_CDC and USB_MSC in one program. When press user taster, usb mode change state. How to use usb_cdc and usb_msc at same time?
Best regards,
EI
you need functions to deinit USB_CDC and USB_MSC.
1. USB_MSC deinit
2. USB_CDC init
3. Button
4. USC_CDC deinit
5. USB_MSC init
6. Button
7. GOTO 1
OK. Problem is in identical name definition in MSC and CDC header files for functions. usb_bsp.c, usb_core.c. This is not possible a compiling.
Can you post a project with two modes when blue button (user button on discovery) changes state (cdc or msc) ?
Thanks.
thats very time-consuming…you must do this on your own.
Hallo,
bei mir erkennt das Programm meinen USB Stick nicht. Was kann es da haben? Die grüne LED leuchtet.
Danke
bg Christian
k.A.
Hi,
I used Google translate in my post and maybe it’s not so good, so I will write this one in english. Sorry for 2 posts!
By the way, thanks for writing and sharing your code, it makes it easier to help things started.
I have tested your code in my target application with the needed changes and it works OK! This was using your project in Coocox.
However, I am using Atollic, and as you know, it’s quite similar to Coocox. I added the directory “ub_lib” to my project, and then your test code in my “main.c” file. However, it doesn’t seem to work. It always returns “USB_MSC_DEV_DETACHED”.
Why would this work good in Coocox, but not in Atollic? Can you think of anything?
Gary
could be many things. check these two first :
1. CPU clock (must be 168 MHz and USB @48MHz)
2. Optimization should be : “O0 = none”
Hi, I’m having a problem, the demo works, I can write in the pen drive. But when I try to use the library in another project the status change to USB_MSC_DEV_DETACHED, could it be because a conflict with another libraries?
I’m using:
#include “stm32_ub_lcd_2x16.h”
#include “stm32f4xx.h”
#include “stm32f4xx_gpio.h”
#include “stm32f4xx_rcc.h”
#include “stm32f4xx_tim.h”
#include “stm32f4xx_usart.h”
#include “misc.h”
#include “stdio.h”
#include “stm32_ub_keymatrix.h”
#include “stm32_ub_led.h”
#include “stm32_ub_usb_msc_host.h”
Also I’m using a library from the DHT11 sensor that uses USART but anothers ports.
I created a function Copy that contains the code that it’s in the while from the demo (if(UB_USB_MSC_HOST_Do()==USB_MSC_DEV_CONNECTED) { ….)
When I need to copy something I call Copy (inside the main).
The clock it’s at 168MHz
Thanks
dont add 1000 lines of code and try to find a failure.
Make a running version und add a single new function.
Test the new function (and all old functions) and so on.
Thats the only way to handle big projects.
besides…the function “UB_USB_MSC_HOST_Do()”
must called the whole time
maybe you must use the Systick to do this
Yes, after I wrote this I get how it works to see if it’s connected or not.
My problem now is that it recognizes as connected, but says is unmounted. I guess I’m missing something
I mean, only writes once, after that nothing, just connected but not mounted (I read a sensor and save the data, in a loop)
try this flow :
Funktioniert aufs erste mal flashen einwandfrei.
Habe ebenfalls einen Intenso USB Stick mit 4GB verwendet.
Adapterkabel gibts günstig bei Amazon oder Ebay.
Wiedermal vielen Dank für deine Seite!
Hi,me again (I cant reply in your answer so I write here)
The flow you gave works, but, if I need to do something else,and then go back and write data in the stick,99% fails to mount it, it’s like 1st time mounting it works, but 2nd fails (keeps connected, but unmounted). What could be the problem?
Let’s supose in the file I have 5 lines of text, if I need to read line 1,then 2,then3,then 2 again, it’s that posible?
There’s a f_lseek in ff.h library, should use it?
Thanks!
I think I found the problem:
UB_Fatfs_Mount checks f_mount,f_mount checks chk_mounted. 1st time it’s ok, but after that chk_mounted returns FR_NO_FILESYSTEM ( No FAT volume is found).
I changed the return value to FR_OK and now everytime I want to mount the USB, it works, but it shouldn’t be like that, right?
maybe the drive needs a delay after plugin to be ready.
try a loop until mount is ok.
and you dont have to mount a allready mounted device.
yes, with fseek you can skip to a position you want. but you must know
the position. in the easiest way all lines have the same lenght.
if not, you have to search the “carriage return” or another special byte.
Hallo,
erstmal danke für Deine Librarys!
Ich möchte in das Textfile Werte von meinem ADC Wandler hineinschreiben.
Aber ich bekomm das einfach nicht hin :/ Könntest Du mir einen Tipp geben?
Ich wäre dafür sehr dankbar!!
UB_Fatfs_WriteString(&myFile, ADCWert);
Dazu hab ich versucht die Funktion anzupassen (ohne Erfolg):
FATFS_t UB_Fatfs_WriteString(FIL* fp, int Wert)
{
FATFS_t ret_wert=FATFS_PUTS_ERR;
int check=0;
check=f_puts(wert, fp);
if(check>=0) {
ret_wert=FATFS_OK;
// Zeilenendekennung hinzufügen
f_putc(‘\n’, fp);
}
else {
ret_wert=FATFS_PUTS_ERR;
}
return(ret_wert);
}
Hab es mit der Funktion UB_fatfs_writeblock hinbekommen.
wenn es ein Textfile ist, kannst du den Zahlenwert auch
in einen Text wandeln
Hi,
erstmal danke für Librarys.
Obwohl ich an dem Beispielprogramm nichts verändert habe, bekomme ich beim builden folgende Fehlermeldung:
“.\Objects\testusb.axf: Error: L6200E: Symbol USB_MSC_HOST_STATUS multiply defined (by stm32_ub_usb_msc_host.o and main.o).”
Hast du eine Idee, wie man das Problem lösen kann?
Danke im voraus!
benutzt du was anderes als CooCox oder OpenSTM als IDE ?
falls ja siehe Antwort unten bei Alex.
Dankeschön, es hat geklappt.
Ja, ich benutze wie Alex Keil
Hi,
danke für die Library.
Die Hex-Datei funktioniert super, möchte ich jedoch das Projekt mit uVision Keil builden bekomme ich den gleichen Fehler wie Timo.
Würde mich sehr über deine Hilfe freuen.
vermutlich mag er die initialisierung der Variable “USB_MSC_HOST_STATUS” im H-File nicht.
verschiebe mal die Zeile
USB_MSC_HOST_STATUS_t USB_MSC_HOST_STATUS;
von stm32_ub_usb_msc_host.h nach stm32_ub_usb_msc_host.c
compiliere dann nochmal und füge bei allen C-Files die dann eine
fehler zeigen wegen unbekannter variable diese zeile ein :
extern USB_MSC_HOST_STATUS_t USB_MSC_HOST_STATUS;