SPI richtig konfiguriert für SD-Card??
Montag, 21. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  CCS Compiler  |  Schnittstellen (CCS)  |  SPI richtig konfiguriert für SD-Card?? « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: SPI richtig konfiguriert für SD-Card??  (Gelesen 2975 mal)
 
master2007
Newbie
*
Offline Offline

Beiträge: 5


Profil anzeigen
« am: Oktober 17, 2008, 13:45:16 »

Hallo zusammen,

ich möchte mit einem PIC24FJ256GB106 (CCS-Compiler) eine SD-Karte beschreiben (bzw. erstmal überhaupt mit der Karte kommunizieren) und ich bin mir nicht sicher, ob ich die Hardware-SPI dafür richtig konfiguriert habe.

Die Einstellungen im SPICON1 sehen so aus:

SPI1CON1 = 0x0178;   //SMP=0, CKE=1, CKP=1, MSTEN=1,SPRE=110, PPRE=00

Sind CKE und CKP richtig gesetzt um mit einer SD-Karte zu kommunizieren?

Dann habe ich noch eine zweite Frage: Ich möchte die CCS Funktionen spi_write und spi_read nutzen. Muss ich nach einem spi_write immer ein spi_read kommen?? Wenn ich 6 spi_write hintereinander ausführen will (um ein cmd zu senden) wird immer nur das erste byte gesendet.

Ich habe in diversen Foren gesehen das da im Code z.B. spi_write alleine (ohne spi_read) in einer Schleife verwendet wird oder ganz ganz einfach in dieser Form z.B.
     
spi_write(0x40);
spi_write(0x00);
spi_write(0x00);
spi_write(0x00);
spi_write(0x00);
spi_write(0x95);

Das funktioniert bei mir nur dann, wenn ich nach jedem spi_write ein spi-read einfüge. Hab ich da irgendwas falsch eingestellt??

Ich hoffe ich hab nicht irgendeinen Eintrag übersehen wo jemand schonmal das gleiche gefragt hat...

Schöne Grüße
master07
Gespeichert
Coltfisch
Sr. Member
****
Offline Offline

Beiträge: 496



Profil anzeigen WWW
« Antworten #1 am: Oktober 17, 2008, 15:08:48 »

Hallo,

der CCS C-Compiler und der PIC24 passen grundsätzlich (noch) nicht so recht zusammen. Aus diesem Grund würde ich die builtin-Funktionen des CCS Compilers soweit wie möglich meiden!

Soweit ich mich erinnere, sind SD-Karten in Bezug auf die Einstellung von CKP/CKE relativ genügsam, ich initialisiere meine Karten jedoch immer mit SPI Mode 3 (CKP = 1, CKE = 0) und kann Dir daher versichern, dass dieser Modus definitiv funktioniert!
Ein entscheidenderes Problem sehe ich bei der SPI-Taktrate. Diese sollte bei der Initialisierung der Karte <= 400 kHz betragen, je nachdem welchen CPU-Takt Du verwendest, liegst Du mit SPRE=110, PPRE=00 natürlich deutlich darüber! Also lieber SPRE=111, PPRE=11.

Zur zweiten Frage:
Nach einem spi_write muss für gewöhnlich kein weiteres spi_read ausgeführt werden. Das geschilderte Verhalten klingt in der Tat etwas merkwürdig. Wie ist denn Dein SPICON2 konfiguriert? Hast Du eventuell den Enhanced Buffer aktiviert?

Außerdem hat man bei den PIC24 deutlich mehr Möglichkeiten, falsche Einstellungen vorzunehmen, als bei den 8-Bit-PIC. Sicher, dass Du das PPS korrekt initialisiert hast und die SPI auf die richtigen Pins verteilt hast?

gruß
daniel


Gespeichert
master2007
Newbie
*
Offline Offline

Beiträge: 5


Profil anzeigen
« Antworten #2 am: Oktober 19, 2008, 12:50:11 »

Hi Daniel,

Danke für die Antwort! Das die builtin-Funktionen vom CCS nicht so so ganz mit dem PIC24 zusammenpassen habe ich auch schon bemerkt :-(

Zur SD-Karte:

Ein entscheidenderes Problem sehe ich bei der SPI-Taktrate. Diese sollte bei der Initialisierung der Karte <= 400 kHz betragen, je nachdem welchen CPU-Takt Du verwendest, liegst Du mit SPRE=110, PPRE=00 natürlich deutlich darüber! Also lieber SPRE=111, PPRE=11.

Der Takt sollte mit SPRE=110 (2:1) und PPRE=00 (64:1) unter 400kHz liegen. Laut Tabelle 14-1 aus dem Datenblatt vom Pic24 ergibt das eine Frequenz von 125kHz (bei Fcy = 16 MHz). Lässt sich mit dem Oszi auch korrekt messen.

Mit CKE=0 und CKP = 1 bekomme ich jetzt auch eine Antwort von der Karte.

Allerdings beendet die Karte die Initialisierung von ACMD41 nicht. Ich bekomme auf ACMD41 immer die Antwort 0x01. Wenn die Initialisierung erfolgreich war sollte auf ACMD41 doch eigentlich 0x00 von der Karte zurückkommen oder?

Der code zur Initialisierung sieht bei mir bis jetzt so aus (cmd0 -> cmd8 -> cmd55 -> acmd41):

...
if (sd_command(cmd0,0x00,0x00,0x00,0x00,0x95) ==1 ){           //if R1 is received without errors
        Timer1 = 100;
        cmd41_res = 1;
   if(sd_command(cmd8,0x00,0x00,0x01,0xaa,0x87) ==1){   //if no errors in first byte(=R1) of R7
         for (n = 0; n < 4; n++) ocr[n] = MMCIn();      //receive 4 bytes of OCR-Card info
        if (ocr[2] == 0x01 && ocr[3] == 0xaa) {   //the card can work at vdd range of 2.7-3.6V and check pattern is echoed back correctly
               while(timer1!=0 &&   cmd41_res !=0 ){
         if (sd_command(cmd55,0x00,0x00,0x00,0x00,0x01) <= 1) {
             cmd41_res=sd_command(cmd41,0x00,0x40,0x00,0x00,0x01);   // ACMD41 with HCS bit    
             timer1--;
         }
         else   
               return MMC_ERROR;
                  }
...

Woran kann es liegen, wenn die Karte auf ACMD41 nie mit 0x00 antwortet?


Schöne Grüße
Flo

Gespeichert
Coltfisch
Sr. Member
****
Offline Offline

Beiträge: 496



Profil anzeigen WWW
« Antworten #3 am: Oktober 19, 2008, 13:36:38 »

Der Takt sollte mit SPRE=110 (2:1) und PPRE=00 (64:1) unter 400kHz liegen. Laut Tabelle 14-1 aus dem Datenblatt vom Pic24 ergibt das eine Frequenz von 125kHz (bei Fcy = 16 MHz). Lässt sich mit dem Oszi auch korrekt messen.
Sorry, hatte mich verlesen. Hast natürlich Recht.

Der code zur Initialisierung sieht bei mir bis jetzt so aus (cmd0 -> cmd8 -> cmd55 -> acmd41):

Die Sequenz entspricht soweit der Spec., sollte also funktionieren. Dumme Frage: Bist Du sicher, dass die Karte ACMD41 überhaupt unterstützt? Handelt es sich um eine SDHC-Karte?
Bitte versuche die Karte zunächst einmal mit dem CMD1 zu initialisieren, welches von jeder Karte akzeptiert werde sollte. Hast Du damit Erfolg?

Noch ein Punkt, über den ich anfangs gestolpert bin:
Wenn Du die CCS-Builtins spi_read(...) zur Kommunikation mit der Karte verwendest, wie sieht Dein Aufruf aus?
Es muss unbedingt spi_read(0xFF) lauten, andernfalls ist es ein Glücksspiel, ob die Karte die Kommandos akzeptiert.

gruß
daniel
Gespeichert
master2007
Newbie
*
Offline Offline

Beiträge: 5


Profil anzeigen
« Antworten #4 am: Oktober 23, 2008, 09:53:53 »

Hi,

also inzwischen bin ich ein großes Stück weiter (dank Daniel!). Die Initialisierung mit Unterscheidung von SD V1.X, SD V2.0 und SDHC V2.0 Karten läuft. Register auslesen (CSD,...) funktioniert auch einwandfrei. Soweit so gut. Jetzt gehts ans Lesen und Schreiben. Lesen sollte meiner Meinung nach auch schon funktionieren, beim Schreiben hab ich allerdings das Problem, dass ich durch die Adressierung der Blöcke noch nicht ganz durchgestiegen bin.

Ich möchte erstmal kein Filesystem nutzen (kommt später) und einfach nur Daten auf der Karte (SD2/4GB,Kingston,SDHC) speichern. Die Blockgröße ist ja auf 512 bytes festgelegt. Wenn ich einen Block schreiben will, dann geb ich die Blockadresse von dem Block den ich schreiben will im Argument von CMD24 (oder CMD25 für Multi-Block-write) an.Richtig?

Frage: Bei welchem Block kann ich das Beschreiben der Karte beginnen? Gibt es am Beginn des Speicherbereichs den ich mit CDM24/25 erreiche irgendwelche Blöcke die ich nicht nutzen kann/sollte? Bzw. welche Bereiche sind für das FAT32-Filesystem (mit dem die Karte formatiert ist) reserviert. Es wäre ja schlau das Beschreiben der Karte von Beginn an nur ab dem Bereich zu erlauben, der auch mit Filesystem erlaubt ist um eine nachträgliche Implementierung zu erleichtern.
Ich hab jetzt ne Weile gegoogelt, bin aber aus dem gefundenen nicht so recht schlau geworden, ab welcher Blockadresse ich die Karte beschreiben kann/sollte.

Hat damit jemand Erfahrung?

Danke schonmal und Gruß
Flo
Gespeichert
Coltfisch
Sr. Member
****
Offline Offline

Beiträge: 496



Profil anzeigen WWW
« Antworten #5 am: Oktober 23, 2008, 12:02:21 »

Freut mich, dass Du Fortschritte machst!

Dein weiteres geplantes Vorgehen halte ich allerdings für etwas unorthodox.
Theoretisch kannst Du das Beschreiben der Karte bei Sektor 0 beginnen. Damit bügelst Du aber logischerweise den Bootsektor sowie alle Partitions- und Dateisysteminformationen platt.
Der Bereich, den Du beschreiben willst, befindet sich hinter der FAT-Tabelle des Dateisystems. Die Berechnung der Blockadresse, an der dieser Bereich startet ist nicht trivial, kann von Karte zu Karte variieren und kann nur bestimmt werden, indem Du die entsprechenden Informationen aus den Sektoren des Dateisystems extrahierst.
Mit anderen Worten: Du findest den Bereich nur, wenn Du das bestehende Dateisystem auf den Datenträger interpretieren kannst.

Da Du ohnehin später ein Dateisystem implementieren willst, würde ich Dir vorschlagen, von Anfang an das FAT32 zu nutzen. Fokussiere Dich dabei zunächst auf das Lesen von Dateien. Als hervorragende Informationsquelle für die Entwicklung einer eigenen FAT12/16/32-Implementierung kann ich Dir das folgende PDF von Microsoft empfehlen:
http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx. Da steht alles drin, was Du brauchst! (dort sind übrigens auch die Formeln zur Berechnung der Adresse des Datenbereichs aufgeführt, für den Fall, dass Du Dich nicht von Deinem Plan abbringen lässt  Zwinkernd )

Viel Erfolg!

daniel
Gespeichert
Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.047 Sekunden mit 19 Zugriffen.
 
Top! Top!