SD-Karte Sektor löschen R1B CMD38 ?
Dienstag, 22. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  PIC Mikrocontroller Allgemein  |  Schnittstellen (Allgemein)  |  SD-Karte Sektor löschen R1B CMD38 ? « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: SD-Karte Sektor löschen R1B CMD38 ?  (Gelesen 2039 mal)
 
prinzenrolle
Gast
« am: Juni 29, 2009, 11:42:02 »

Hallo,
ich habe hier ein Problem mit dem SD-Karten Befehl CMD38.
Ich schreibe "roh" auf die SD-Karte.
Lesen und schreiben funktioniert soweit.
Ich nutze zum Schreiben auf die Karte die Funktionen der MDDLibrary
Code:
BYTE MDD_SDSPI_SectorRead(DWORD sector_addr, BYTE* buffer);
BYTE MDD_SDSPI_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero);
Jetzt würde ich gerne bestimmte Sektoren löschen, dies ist der befehl cmd38.
vorher muss cmd32 und cmd33 mit Start- und End -Adresse gesendet werden.
leider bekomme ich als Antwort immer eine ungleich 0 zurück.
der Antworttyp ist r1b.
hat jemand schon mal so etwas gemacht oder weiß
was ich falsch mache?

Code:
BYTE MDD_SDSPI_Sector_Erase(DWORD sect_start,DWORD sect_end)
{
MMC_RESPONSE response;

response = SendMMCCmd(TAG_SECTOR_START,sect_start << 9);
if(response.r1._byte != 0x00)
return 0;

response = SendMMCCmd(TAG_SECTOR_END,sect_end << 9);
if(response.r1._byte != 0x00)
return 0;
response = SendMMCCmd(ERASE,0x00);
if(response.r1._byte != 0x00)
return 0;

return 1;
}

Code:
MMC_RESPONSE SendMMCCmd(BYTE cmd, DWORD address)
{
    WORD timeout = 0x8;
    BYTE index;
    MMC_RESPONSE    response;
    CMD_PACKET  CmdPacket;
   
    SD_CS = 0;                           //Card Select
   
    // Copy over data
    CmdPacket.cmd        = sdmmc_cmdtable[cmd].CmdCode;
    CmdPacket.address    = address;
    CmdPacket.crc        = sdmmc_cmdtable[cmd].CRC;       // Calc CRC here
   
    CmdPacket.TRANSMIT_BIT = 1;             //Set Tranmission bit
   
    WriteSPIM(CmdPacket.cmd);                //Send Command
    WriteSPIM(CmdPacket.addr3);              //Most Significant Byte
    WriteSPIM(CmdPacket.addr2);
    WriteSPIM(CmdPacket.addr1);
    WriteSPIM(CmdPacket.addr0);              //Least Significant Byte
    WriteSPIM(CmdPacket.crc);                //Send CRC
   
    // see if we are going to get a response
    if(sdmmc_cmdtable[cmd].responsetype == R1 || sdmmc_cmdtable[cmd].responsetype == R1b)
    {
        do
        {
            response.r1._byte = MDD_SDSPI_ReadMedia();
            timeout--;
        }while(response.r1._byte == MMC_FLOATING_BUS && timeout != 0);
    }
    else if(sdmmc_cmdtable[cmd].responsetype == R2)
    {
        MDD_SDSPI_ReadMedia();
       
        response.r2._byte1 = MDD_SDSPI_ReadMedia();
        response.r2._byte0 = MDD_SDSPI_ReadMedia();
    }

    if(sdmmc_cmdtable[cmd].responsetype == R1b)
    {
        response.r1._byte = 0x00;
       
        for(index =0; index < 0xFF && response.r1._byte == 0x00; index++)
        {
            timeout = 0xFFFF;
           
            do
            {
                response.r1._byte = MDD_SDSPI_ReadMedia();
                timeout--;
            }while(response.r1._byte == 0x00 && timeout != 0);
        }
    }

    mSend8ClkCycles();                      //Required clocking (see spec)

    // see if we are expecting data or not
    if(!(sdmmc_cmdtable[cmd].moredataexpected))
        SD_CS = 1;

    return(response);
}
Gespeichert
Coltfisch
Sr. Member
****
Offline Offline

Beiträge: 496



Profil anzeigen WWW
« Antworten #1 am: Juni 29, 2009, 12:34:21 »

hat jemand schon mal so etwas gemacht oder weiß
was ich falsch mache?
Nein, denn mir erschließt sich der Sinn nicht so ganz. Wenn Du schon den Sektor löschen willst, warum schreibst Du dann nicht einfach Nullen oder meinetwegen 0xFF in den Sektor. Was soll denn da nach dem Löschen sonst anderes drinstehen?
Den für auf Flash basierende Speichermedien typischen Erase-Cycle musst Du jedenfalls nicht manuell durchführen, diese Aufgabe übernimmt der Controller in der Speicherkarte.

Gruß
Daniel
Gespeichert
prinzenrolle
Gast
« Antworten #2 am: Juni 29, 2009, 13:05:51 »

hallo,
nachdem ich einen Datensatz gelesen habe möchte ich diesen löschen.

Den 1kByte großen internen Buffer (feld) kann ich nicht nutzen da dieser noch wichtige Daten beinhaltet.
Also dachte ich lösche den Sektor mit dem Befehl.
Gespeichert
Coltfisch
Sr. Member
****
Offline Offline

Beiträge: 496



Profil anzeigen WWW
« Antworten #3 am: Juni 29, 2009, 13:19:03 »

Verstehe.
Wenn man mal nach dem CMD38 googelt, häufen sich Aussagen darüber, das CMD38 nicht akzeptiert wird. Womöglich ist es auf manchen Karten einfach nicht implementiert. Denn wofür braucht man das wirklich?
Gut, Du kannst zwar den Buffer nicht nutzen, aber Du kannst ja eine Dummy-Sektorschreibfunktion basteln, in der Du an Stelle von realen Daten aus einem Buffer einfach nur Nullen per SPI an die SD-Karte sendest. Schon ist der Sektor leer, Dein Buffer bleibt erhalten, CMD38 wird nicht gebraucht und Du kannst sicher sein, dass es mit jeder Karte zuverlässig funktioniert.
Gespeichert
prinzenrolle
Gast
« Antworten #4 am: Juni 29, 2009, 13:52:11 »

Hallo,
vielen dank für die erneute Antwort Zwinkernd
ich war/bin mir nicht sicher ob microchip die abfrage der r1b Antwort korrekt eingebunden hat. ich habe nun mit einem im ROM festen Feld gelöst.
deine lösung klingt auch gut.

vielen dank
Gespeichert
prinzenrolle
Gast
« Antworten #5 am: Juli 02, 2009, 12:46:03 »

Verstehe.
Wenn man mal nach dem CMD38 googelt, häufen sich Aussagen darüber, das CMD38 nicht akzeptiert wird. Womöglich ist es auf manchen Karten einfach nicht implementiert. Denn wofür braucht man das wirklich?
Gut, Du kannst zwar den Buffer nicht nutzen, aber Du kannst ja eine Dummy-Sektorschreibfunktion basteln, in der Du an Stelle von realen Daten aus einem Buffer einfach nur Nullen per SPI an die SD-Karte sendest. Schon ist der Sektor leer, Dein Buffer bleibt erhalten, CMD38 wird nicht gebraucht und Du kannst sicher sein, dass es mit jeder Karte zuverlässig funktioniert.

das löschen über cmd38 geht vielfach schneller als schreiben
Gespeichert
Coltfisch
Sr. Member
****
Offline Offline

Beiträge: 496



Profil anzeigen WWW
« Antworten #6 am: Juli 02, 2009, 13:07:12 »

das löschen über cmd38 geht vielfach schneller als schreiben
Ja, davon gehe ich auch aus, sonst hätte man diesen Befehl wohl kaum implementiert. Es ist natürlich auch für dem Mikrocontroller bequemer einen einzelnen Löschbefehl an Stelle von 512 Dummybytes zu senden.

Aber Dein Fall ist schon eine sehr spezielle Spezialanwendung, wo man diesen Befehl tatsächlich brauchen könnte.
Wird die Karte von einem Betriebssystem mit FATxx-Dateisystem verwaltet, ist das gezielte Löschen eines ganzen Sektors jedenfalls überflüssig (denn eine Datei wird ausschließlich durch das Freigeben der Cluster-Nummern in der FAT-Tabelle gelöscht). Ich kann mir daher gut vorstellen, dass aktuelle Speicherkarten diesen Befehl einfach ignorieren. Aber wie gesagt, das ist nur eine Vermutung.

Gruß
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.037 Sekunden mit 18 Zugriffen.
 
Top! Top!