Forum: Mikrocontroller und Digitale Elektronik SD Karte nach Reset nicht mehr ansprechbar


von Sven S. (schwerminator)


Lesenswert?

Hallo,

ich nutze derzeit die MMC-/SD-Karten-Bibliothek von Elm Chan auf einem 
ATmega (5V, 16MHz). Die SD-Karte läuft unter 3V, die Pegelwandlung 
übernimmt ein HC4050. Alles funktioniert bestens, nur nach einem Reset 
egal welcher Art (WDT, Hard-Reset) kann die Karte nicht mehr 
initialisiert werden. Klemme ich dann die Stromversorgung der gesamten 
Schaltung ab und wieder an, funktioniert wieder alles tadellos.

Das Ganze macht den Eindruck, als wäre die SD-Karte in einem internen 
Status, aus dem sie nicht mehr initialisiert werden kann. Ist es möglich 
die SD-Karte per Kommando zu resetten? Das Ganze ließe sich natürlich 
lösen, indem man die Stromversorgung der Karte per Transistor/FET bei 
einem Reset ausschaltet. Diese Möglichkeit habe ich aber nicht. Hat 
jemand einen Tipp zur Problemlösung parat?

Gruß Sven
von holger (Gast)


Lesenswert?

>nur nach einem Reset
>egal welcher Art (WDT, Hard-Reset) kann die Karte nicht mehr
>initialisiert werden.

WDT und Hard-Reset sind eine super Idee bei einem
FAT Dateisystem. Da kannst du auch gleich die Karte
komplett formatieren. Das geht sowas von in die Hose;)

>Hat jemand einen Tipp zur Problemlösung parat?

Keine SD Karte mit FAT benutzen. Besser gar keine
SD Karte benutzen.
von Sven S. (schwerminator)


Lesenswert?

Es sind zum Zeitpunkt des Resets alle Dateien geschlossen, also sollte 
es keine Probleme geben.
von holger (Gast)


Lesenswert?

>Es sind zum Zeitpunkt des Resets alle Dateien geschlossen, also sollte
>es keine Probleme geben.

Und woher weisst du das? Deine Karte reagiert genervt. Da ist also
irgendwas nicht in Ordnung. Du hast den Schreib oder Lesevorgang
unterbrochen. Bei einem Hard-Reset kannst du eigentlich nur noch
beten das die Karte schon fertig war. Sonst gibt es Gurkensalat.
von einGast (Gast)


Lesenswert?

kommando zum resetten ist CMD0
von Sven S. (schwerminator)


Lesenswert?

holger schrieb:
>>Es sind zum Zeitpunkt des Resets alle Dateien geschlossen, also sollte
>>es keine Probleme geben.
>
> Und woher weisst du das? Deine Karte reagiert genervt. Da ist also
> irgendwas nicht in Ordnung. Du hast den Schreib oder Lesevorgang
> unterbrochen. Bei einem Hard-Reset kannst du eigentlich nur noch
> beten das die Karte schon fertig war. Sonst gibt es Gurkensalat.

Ich bin mir der Gefahren bewusst, darum soll es also hier nicht gehen. 
Ich kann GARANTIEREN, dass zum Reset-Zeitpunkt kein Zugriff auf die 
SD-Karte erfolgt und alle Dateien geschlossen sind.
von holger (Gast)


Lesenswert?

>Ich bin mir der Gefahren bewusst, darum soll es also hier nicht gehen.
>Ich kann GARANTIEREN, dass zum Reset-Zeitpunkt kein Zugriff auf die
>SD-Karte erfolgt und alle Dateien geschlossen sind.

Ok, das ist doch mal ne Aussage. Also ich kann zB einen
AVR per ISP programmieren und die SD Karte wird dann
ohne ausschalten nach dem programmieren nach Reset
des AVR wieder initialisiert. Keine Probleme.
Tja, wo ist jetzt dein Problem?
von Sven S. (schwerminator)


Lesenswert?

einGast schrieb:
> kommando zum resetten ist CMD0

Das wird in der Bibliothek von Elm Chan gemacht:
1
DSTATUS disk_initialize (
2
  BYTE drv    /* Physical drive nmuber (0) */
3
)
4
{
5
  BYTE n, cmd, ty, ocr[4];
6
7
8
  if (drv) return STA_NOINIT;      /* Supports only single drive */
9
  if (Stat & STA_NODISK) return Stat;  /* No card in the socket */
10
11
  power_on();              /* Force socket power on */
12
  FCLK_SLOW();
13
  for (n = 10; n; n--) rcvr_spi();  /* 80 dummy clocks */
14
15
  ty = 0;
16
  if (send_cmd(CMD0, 0) == 1) {      /* Enter Idle state */
17
[...]

und
1
static
2
BYTE send_cmd (    /* Returns R1 resp (bit7==1:Send failed) */
3
  BYTE cmd,    /* Command index */
4
  DWORD arg    /* Argument */
5
)
6
{
7
  BYTE n, res;
8
9
10
  if (cmd & 0x80) {  /* ACMD<n> is the command sequense of CMD55-CMD<n> */
11
    cmd &= 0x7F;
12
    res = send_cmd(CMD55, 0);
13
    if (res > 1) return res;
14
  }
15
16
  /* Select the card and wait for ready */
17
  deselect();
18
  if (!select()) return 0xFF;
19
20
  /* Send command packet */
21
  xmit_spi(0x40 | cmd);        /* Start + Command index */
22
  xmit_spi((BYTE)(arg >> 24));    /* Argument[31..24] */
23
  xmit_spi((BYTE)(arg >> 16));    /* Argument[23..16] */
24
  xmit_spi((BYTE)(arg >> 8));      /* Argument[15..8] */
25
  xmit_spi((BYTE)arg);        /* Argument[7..0] */
26
  n = 0x01;              /* Dummy CRC + Stop */
27
  if (cmd == CMD0) n = 0x95;      /* Valid CRC for CMD0(0) */
28
  if (cmd == CMD8) n = 0x87;      /* Valid CRC for CMD8(0x1AA) */
29
  xmit_spi(n);
30
31
  /* Receive command response */
32
  if (cmd == CMD12) rcvr_spi();    /* Skip a stuff byte when stop reading */
33
  n = 10;                /* Wait for a valid response in timeout of 10 attempts */
34
  do
35
    res = rcvr_spi();
36
  while ((res & 0x80) && --n);
37
38
  return res;      /* Return with the response value */
39
}

Allerdings gibt send_cmd(CMD0, 0) nach einem Reset nicht 1, nach Vcc 
off/on allerdings doch 1 zurück. Wie ist dieses zu erklären? Das hat ja 
auch nichts mit höheren Ebenen (FAT), sondern mit der Phy-Ebene zu 
tun...
von holger (Gast)


Lesenswert?

>Allerdings gibt send_cmd(CMD0, 0) nach einem Reset nicht 1,

Bla, bla.

Häng mal einen Pullup an CS der Karte und einen
Pullup an MISO.
von einGast (Gast)


Lesenswert?

wird die Card Select Leitung richtig angesteuert?
von Sven S. (schwerminator)


Angehängte Dateien:

Lesenswert?

holger schrieb:
>>Allerdings gibt send_cmd(CMD0, 0) nach einem Reset nicht 1,
>
> Bla, bla.

Auf solche Antworten kann ich gerne verzichten.

einGast schrieb:
> wird die Card Select Leitung richtig angesteuert?

Ich habe die entscheidende Sektion der Schaltung einmal angehängt. Wieso 
sollte ein Pullup an die /CS-Leitung, diese wird doch direkt von dem µC 
angesteuert?
von Turbo J (Gast)


Lesenswert?

Bei meiner änlich aussehenden Variante sieht das mit dem CMD0 so aus:
1
ty = 0;
2
ntries = 16; // try CMD0 at least 16 times..
3
while ((ty == 0) && ntries) {
4
    if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
5
    ...
6
  }
7
  release_spi();
8
  ntries--;
9
}

Die Function release_spi() macht nur ein dselect() gefolgt von 8 
Dummy-Clocks, also einem dummy SPI Zyklus.

Die SD Karte will u.U. einfach nur genug Daten via SPI haben, damit sie 
den vor dem Reset eventuell noch angefangenen Befehl abarbeiten kann.
von Sven S. (schwerminator)


Lesenswert?

Besten Dank für die Antworten. Ich habe jetzt einen anderen 
Busteilnehmer als Fehlerquelle ausmachen können. Das Problem hat sich 
hiermit erledigt.

Gruß Sven
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.