Forum: Mikrocontroller und Digitale Elektronik [LPC2138] Suche fertige FAT Routine für SD-Card an SPI0 für IAR Kompiler


von Max Meidinger (Gast)


Lesenswert?

Hallo!

Ich suche händeringend nach einer fertigen Bibliothek für den IAR 
Embedded Workbench [ARM] zum erstellen und lesen von Dateien - FAT 
Dateisystem auf SD-Card, angeschlossen an SPI0 des LPC2138.

Da muss es doch schon etw. fertiges geben?

Für den GCC konnte ich hier etw. finden:
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/efsl_arm/index.html

jedoch scheitere ich an der Portierung...

Hat sich von euch zufällig schon jemand mit dem Thema auseinander 
gesetzt und kann entsprechende Routinen empfehlen / zur Verfügung 
stellen?

Vielen Dank!
Max

von Matthias (Gast)


Lesenswert?

ChanNs System is ganz nett, ist hier irgendwo verlinkt. Habs auf n 
LPC2378 portiert, läuft gut. Wenn du den link nicht findest, google mal 
FATFS. Aber vorher das ReadMe lesen, dann is die Portierung ziemlich 
einfach (musst nur 3 funktionen selber basteln).

von Max Meidinger (Gast)


Lesenswert?

Danke!

Über das Projekt bin ich inzwischen auch gestolpert!
http://elm-chan.org/fsw/ff/00index_e.html

Ist eine ANSI C umsetzung der FAT16...FAT32 Dateisystemzugriffe, macht 
einen guten Eindruck... nur richtig verstanden was in die besagten 3 
Funktionen hinein muss hab ich bisher noch nicht (zu viel gleichzeitig 
im Kopf).

Die meisten Projekte erfordern, dass man selbst die Zugriffe auf das 
jeweilige Speichermedium programmiert, dazu sehr hilfreich ist diese 
seite, die die Initialisierung der SD-Card ganz gut beschreibt:
http://elm-chan.org/docs/mmc/mmc_e.html

Nur klappen will das bei mir einfach nicht! Der Mikrocontroller sendet 
CS, CLK und MOSI Signale, jedoch kommt von der Speicherkarte nichts 
zurück. Das macht noch nicht einmal einen Unterschied ob die SD-Card 
eingeschoben ist oder nicht, die datenleitung bleibt immer auf LOW was 
dann zu 0x00 bytes führt...

Nun heißt es Fehlersuche :( Spinnt die Karte? Ist die MISO Leitung 
irgendwo unterbrochen oder kommen andere Signale nicht an der Karte an? 
Sind Pins an der Karte vertauscht? Oder gitbs doch einen Softwarefehler?


Das wäre nun halt auch wieder ein enormer vorteil, wenn sich eine 
fertige Funktion finden würde, die getestet ist so dass ich weiß wo ich 
den fehler zu suchen habe... sitzte hier nun auch schon wieder einen Tag 
davor und dreh mich im Kreis grr...


Nunja, vllt. fällt euch in den Codesequenzen etw. auf:

*SPI0 des LPC2138 initialisieren*
1
S0SPCCR = 0xF0;                                                                 // muss gerade zahl und >= 8 sein
2
3
S0SPCR = 0x0020;                                                                //    0:1 = nicht benutzen
4
                                                                                //      2 = '0' für 8Bit Modus
5
                                                                                // [0h] 3 = CPHA '0' fuer SD Cards
6
                                                                                //      4 = CPOL '0' fuer SD Cards
7
                                                                                //      5 = '1' damit Master
8
                                                                                //      6 = '0' erst MSB übertragen
9
                                                                                // [2h] 7 = '0' Keine Interrupts
10
                                                                                // 8:11 = '0' 
11
                                                                                //  12:15 = reserved
µC läuft mit 48MHz, damit sollte der SPI Tackt bei 200kHz liegen.


schreiben eines Bytes auf SPI0
1
char SSEL_SD(char ch)
2
{
3
  S0SPDR = ch;                                                                  // Byte ch schreiben
4
  for (int i=0; i<500000 && ((S0SPSR&0x8)!=0); i++);                  // warten bis daten gesendet sind oder zähler abgelaufen...
5
  
6
  return S0SPDR&0xFF;                                                           // empfangene Daten zurück geben
7
}
das liegt in einem eingenen Unterprogramm, was jetzt wie folgt 
aufgerufen wird:
1
  SSEL_SD(1);                                                                // SDC CS auf high
2
  for (int j=0; j<10; j++) sd_Send(0xFF);                                       // SD auf datenempfang vorbereiten
3
4
5
  SSEL_SD(0);  // SDC CS auf Low für Datenempfang
6
7
// GO_IDLE_STATE senden
8
  sd_Send(GO_IDLE_STATE);                                                   
9
  sd_Send(0x00);                                                            
10
  sd_Send(0x00);                                                            
11
  sd_Send(0x00);                                                            
12
  sd_Send(0x00);                                                            
13
  tmp=sd_Send(0x95);                                                            
14
         
15
  tmp=sd_Send(0xFF);    // Fuer Debugger, schauen was zurück kommt                                                            
16
  tmp=sd_Send(0xFF);                                                                 
17
  tmp=sd_Send(0xFF);                                                               
18
  tmp=sd_Send(0xFF);    // erhalte aber nur 0x00 und nicht wie angegeben 0x01 oder 0xFF
19
  tmp=sd_Send(0xFF);    // & Oszi zeigt keine aktivitäten auf MISO                               Leitung 
20
  tmp=sd_Send(0xFF);                                                            
21
  tmp=sd_Send(0xFF);                                                            
22
23
  SSEL_SD(1);  // SDC CS auf high

Nunja - wär ganz lieb wenn jemand einen Blick auf die Zeilen werfen 
könnte, ob hier schon fehler auffallen, oder ob das so laufen sollte...

Achso, Portpins (PINSEL0) sollten richtig initialisiert sein; sonst 
würde auch nichts beim Senden auf MOSI & CLK erscheinen!?

LG
Max

von Markus (Gast)


Lesenswert?


von Matthias (Gast)


Lesenswert?

Richtig, das System von ChanN erfordert in den erwaehnten 3 Funktionen, 
dass du Zugriffe auf das Medium selber schreibst. Er gibt dir allerdings 
sogar schon Namen und Parameter der Funktion vor. Ich hab einfach eine 
Funktion geschrieben, die einen Block (512 Byte) auf die Karte schreibt, 
und eine, die einen Block von der Karte liesst. Die dritte Funktion ist 
nicht absolut zwingend notwendig, aber dennoch sinnvoll; Und zwar die 
FAT_gettime (oder so aehnlich). Die muss ebenfalls an die RTC des LPCs 
angepasst werden, damit veraendernde Zugriffe im FAT auch mit 
ordentlichen Zeitangaben gespeichert werden.

von Max Meidinger (Gast)


Lesenswert?

FATfs ist vom Entwickler schön dokumentiert und ich durchblicke das auch 
weitestgehend...

Nur scheitere ich noch immer an der Initialisierung der SD-Card grr

Den SPI Tackt habe ich momentan auf mit Prescaler 0xFF auf ~188kHz 
stehen, komme Messtechnisch auf ~200kHz - also das ist im Rahmen der 
angegebenen 100-400kHz die bei der Initialisierung verwendet werden 
sollten.


Zwischenzeitlich hatte ich die Karte soweit mit mir zu sprechen - hatte 
einige 0xFF und einiges Wirres in der Richtung 0xFE 0xF0 0x0B usw. 
auslesen können, aber nie das erforderliche 0x01 nach GO_IDLE_STATE 
zurückgegeben werden sollte. Nachdem ich die Karte dann aber vom Strom 
getrennt hatte und wieder neu anschloss bleibt sie wieder schweigsam. 
Ich tippe mal drauf, dass diese sich eher zufällig irgendwie 
initialisiert hat und dann anfing zu kommunizieren...

Hardwarefehler mit falscher Verdrahtung kann ich damit eigentlich 
ausschließen. Hab vorhin noch einmal die Verbindungen überprüft & die 
zwischenzeitlichen 0xFF Bytes sahen auch relativ gut aus...

Die SD-Card hängt übrings direkt an SPI0, ohne andere Komponenten die 
dazwischen funken könnten.


@Matthias
Du hast momentan nicht zufällig Möglichkeit mit einen Einblick in deine 
Funktionen zu geben damit ich meinen Fehler finden kann?

THX!
Max

von Max Meidinger (Gast)


Lesenswert?

Frage am Rande, kann es sein, dass die SD-Card am MISO Pin (DAT/DO) 
einen Pull-Up Widerstand benötigt?

Gruß!
Max

von holger (Gast)


Lesenswert?

>Frage am Rande, kann es sein, dass die SD-Card am MISO Pin (DAT/DO)
>einen Pull-Up Widerstand benötigt?

Nein.

von Max Meidinger (Gast)


Lesenswert?

hmm... soetw. wäre jetzt mein Verdacht gewesen...

Bei den ATmegas hantieren die Meisten ja mit Spannungsteilern herum, da 
könnte das nicht auffallen, dass Pull-Ups notwendig sind.

Ich habe meine Karte direkt mit den SPI Pins verbunden:
SSEL -> pin1 CS
MOSI -> Pin2 CMD/DI
3.3V -> Pin4 VCC
SCK -> Pin5 CLK/SCLK
MISO -> Pin7 DAT/DO

& GNS an Pins 3 und 6

Lediglich zwischen GND & VCC liegt noch ein 100nF Kondensator...


Im Web finden sich auch die unmöglichsten Konstruktionen. 
http://www.cs.ucr.edu/~amitra/sdcard/Additional/sdcard_appnote_foust.pdf 
[seite 3] zeigt z.B. 50K Widerstände an allen Datenpins der SD-Card, nur 
CLK wird direkt verbunden...

Dann gibts noch dieses Dokument, was darauf verweist, dass nur die 
Datenleitungen mit Pull-Up widerständen beschaltet werden sollen:
http://www.ifas.htwk-leipzig.de/easytoweb/download/D&E_11_2006_Anbindung_von_SD-Karten.pdf


An MISO habe ich testweise einen 10K Pull-Up hängen, einmal davon 
abgesehen, dass nun immer 0xFF anstelle von 0x00 eingelesen wurde - was 
ja uach verständlich ist - hat sich die Karte noch immer nicht 
gemeldet...


Hat wirklich keiner eine Idee woher das Problem kommen könnte?

Gruß!
Max

von Max Meidinger (Gast)


Lesenswert?

TAGE SPÄTER!

Hab nun endlich meine 0x01 Antwort!

Fehler:
1
S0SPSR&0x8

Muss heißen:
1
S0SPSR&0x80

Hoch gelobt sei die Erfindung des digitalen Speicher Oszis!!!! aber auch 
das muss man sich erstmal organisieren...

Gruß!
Max

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.