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