Forum: Mikrocontroller und Digitale Elektronik LPC4357 mit eMMC größer 2GB


von Daniel H. (dustbox)


Lesenswert?

Hallo,

ich nutze einen ARM LPC4357 Mikrocontroller mit welchen ich über die 
SDIO-Schnittstelle(4Bit)einen eMMC Speicher betreibe.
Zum Programmieren nutze ich die Keil MDK Version 5.

Um den eMMC testen zu können habe ich mir das Standard Beispiel 
(MC4300\RL\FlashFS\SD_File ) von Keil genommen und dort die 
SDIO_LPC43xx.c Datei angepasst.
Bei eMMC Speicher bis 2GB Größe klappt das auch ganz gut, die Probleme 
kommen erst bei über 2GB.
Bei z.B. einen 8GB Speicher muss extra beim Extended CSD Feld der Wert 
im SEC_COUNT Register ausgelesen werden um auf die richtige Anzahl der 
Blöcke zu kommen, welcher bei mir 0x00EA0000 groß ist.
Dadurch ergibt sich eine Partitionsgröße von:
0x00EA0000 * 512B = 7.851.737.088 Bytes
Das passt also so weit zum 8GB Speicher.
Jetzt das Problem, die Keil MDK kennt aber keine eMMC Speicher größer 
2GB sodass ich ihn über CMD9 vortäuschen muss das die Karte doch größer 
ist.

Intern scheint die Berechnung so zu funktionieren:
1
  /* Total Number of blocks */
2
  switch ((rval[0] >> 30) & 3) {        /* Bits 126..127      */
3
    case 0:                             /* SD card,  CSD v1.0 */
4
    case 2:                             /* MMC card, CSD v1.2 */
5
      v = ((rval[1] << 2) | (rval[2] >> 30)) & 0x0FFF;
6
      m =  (rval[2] >> 15) & 0x07;
7
      cfg->blocknr = (v + 1) << (m + 2);      // <------------
8
      break;
9
    case 1:                             /* SD card,  CSD v2.0 */
10
      v = ((rval[1] << 16) | (rval[2] >> 16)) & 0xFFFF;
11
      cfg->blocknr = (v + 1) << 10;           // <------------
12
      break;
13
    default:
14
      return (__FALSE);
15
  }

Standard wird zum berechnen der blocknr die CSD Version 1.2 geschalten.
Ich gaukle jetzt durch ändern der Register bei CMD9 der internen Routine 
vor das es sich um die CSD Version 2.0 mit der richtigen Blockgröße 
handelt.
1
  /* Read MCI response registers */
2
  rp[0] = LPC_SDMMC->RESP0;
3
  if (resp_type == RESP_LONG) {
4
    rp[0] = LPC_SDMMC->RESP3;
5
    rp[1] = LPC_SDMMC->RESP2;
6
    rp[2] = LPC_SDMMC->RESP1;
7
    rp[3] = LPC_SDMMC->RESP0;
8
                  if(cmd == 0x09){
9
                         rp[0] &= 0x3FFFFFFF;
10
                         rp[0] |= 0x40000000;                     //CSD Structure "CSD Version No. 2.0"
11
                         rp[2] &= 0x0000FFFF;
12
                         rp[2] |= 0x3A7F0000;                    //Size for 8GB eMMC
13
                               }
14
  }

Wenn ich mir im Debugmode über den Disassembler die Interne FlashFS 
Funktion anschaue verarbeitet er sie richtig.

Starte ich jetzt das Programm, wird erkannt das ich den Datenträger 
Formatieren muss.
Formatire ich den Speicher dann wird mir die richtige Speichergröße 
Angezeigt und ich kann Dateien Speichern und lesen.
Starte ich mein Evalboard neu, wird nicht mehr erkannt das der Speicher 
bereits Formatiert wurde und möchte ihn erneut Formatieren.
Führe ich keine Formatierung aus wird mir der Datenträger als leer 
angezeigt. Führe ich aber wiederum eine Formatierung aus, dann sehe ich 
meine vorher erstellten Dateien wieder.
Eine komplette Formatierung mit Hilfe des Zusatzes /WIPE schlägt aber 
auch fehl.

Ich vermute, das die Adressierung des Speichers noch nicht richtig 
funktioniert!?

Hat jemand (am besten mit der Keil MDK) einen eMMC Speicher an einen ARM 
Prozessor schon zum laufen bekommen und kann mir mal ein Beispielcode 
zusenden?

Gruss,
Daniel

von Daniel H. (dustbox)


Lesenswert?

Bin wieder ein Schritt weiter!

Wenn ich die lese/schreib Adresse durch 512 teile, sodass er statt 
Byteadressierung Sektorweise adressiert wird, funktioniert der Speicher.
Nur kann ich dann den Speicher auch nur bis 4GB Größe nutzen.
Das Hauptproblem ist, dass die FlashFS Funktion von Keil keine MMC 
Speicher Sektorweise adressieren möchte.
Hat jemand eine Idee, wie ich die interne FlashFS Funktion dazu bekomme 
meinen Speicher nicht Byteweise sondern Sektorweise zu Adressieren?

Gruss,
Daniel

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.