SD-Karte, Probleme mit CMD1

Gast #1362527
Lesenswert?

Morgen,

Ich habe eine SD-Karte an einen Atmega128 mit Pegelwandler MAX3378 
angeschlossen und kann diese Karte nicht initialisieren(eine 32MB SD und 
eine microSD mit 2GB). Ich schicke via SPI das CMD0 und erhalte 0x01, 
das ist ja auch gut so ;-). Wenn ich nun die Karte Initialisieren möchte 
(CMD1) erhalte ich zuerst ein paar mal 0xff, dann einmal 0xfc und ein 
0x07 ab dann wieder 0xff.

Preudocode:
1
SPI_Init();
2
for i=0 to 15 //sync.
3
  SPI_put_char(0xff);
4
wait(5);//5s waiting
5
SPI_cs_enable(); //set cs low
6

7
SPI_put_char(0x40);
8
SPI_put_char(0x00);
9
SPI_put_char(0x00);
10
SPI_put_char(0x00);
11
SPI_put_char(0x00);
12
SPI_put_char(0x95);
13
do
14
{
15
  answer=SPI_get_char();
16
}while(answer==0xff)
17

18
rs232_send_byte(answer);//PC rec. 0x01
19

20
SPI_put_char(0x41);
21
SPI_put_char(0x00);
22
SPI_put_char(0x00);
23
SPI_put_char(0x00);
24
SPI_put_char(0x00);
25
SPI_put_char(0x01);
26
do
27
{
28
  answer=SPI_get_char();
29
  rs232_send_byte(answer);//PC rec. 0xff 0xff 0xff 0xfc 0x07 0xff 0xff (point of no return)
30
}while(answer!=0x00)

Hat jemand eine Idee? Was mache ich falsch?

glg,

Stefan
Gast #1362588
Lesenswert?

hallo,

@Rex: wo liegt dort der unterschied zu meinem code? Das einzige was ich 
gesehen: Ich sende das CMD1 mit crc=0 und das Beispiel mit crc=0x7F. 
Weiters hole ich nach dem Senden von CMD1 immer nur ein Byte ab, in dem 
beispiel wird solange das CMD1 geschickt bis die richtige antwort kommt, 
habe ich beides bei mir auch verändert, dann kommt prinzipiell immer 
0xff und hinundwieder 0xfc oder oxfe.

@Gast: Ja ich schicke 0xff bei SPI_get_char();

lg,

Stefan
Gast #1362612
Lesenswert?

Command 1 :

Deine Version :

SPI_put_char(0x41);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x01);


Version Captain.at :

SPI_put_char(0x41);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0xFF);
SPI_put_char(0xFF);

Gruß
Gast #1362621
Lesenswert?

> Wenn ich nun die Karte Initialisieren möchte (CMD1) erhalte
> ich zuerst ein paar mal 0xff, dann einmal 0xfc und ein
> 0x07 ab dann wieder 0xff.

Ich bin jetzt zu faul fuer dich das Datenblatt zu lesen, aber
soll es bei diesem Kommando denn zwei Bytes als Antwort geben?
Wenn nicht dann hast du wohl ein Problem auf niedrigstem Level,
also falscher SPI-Mode, Flankensteilheit, Reflexion auf dem Kabel.

Olaf
#1362623
Lesenswert?

Noch ein Vorschlag:


...
rs232_send_byte(answer);//PC rec. 0x01

SPI_cs_disable(); //set cs high

SPI_put_char(0xFF);

SPI_cs_enable(); //set cs low
SPI_put_char(0x41);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0x00);
SPI_put_char(0xFF);
do
{
  answer=SPI_get_char();
  rs232_send_byte(answer);//PC rec.
}while(answer!=0x00)
Gast #1362680
Lesenswert?

Hi,

Danke vielmals für die vielen antworten, es war eine Kombination aller 
Antworten.

Ich habe den Code so geändert:

do
{

  SPI_cs_disable(); //set cs high
  SPI_put_char(0xFF);
  SPI_cs_enable(); //set cs low

  SPI_put_char(0x41);
  SPI_put_char(0x00);
  SPI_put_char(0x00);
  SPI_put_char(0x00);
  SPI_put_char(0x00);
  SPI_put_char(0xFF);
  do
  {
    answer=SPI_get_char();
  }while(answer==0xff);
  rs232_send_byte(answer);//PC rec.
}while(answer!=0x00)

Anscheinend muss das Commando immerwieder an die Karte geschickt werden 
und davor jedesmahl das CS auf High - ein 0xff schicken - und wieder CS 
wieder auf Low, dann das Commando schicken und auf die Anwort warten, 
die ist bei den ersten 2x 0x01 und beim dritten mal dann 0x00, also 
initialisiert. Warum das so ist, weiß ic nicht, lt. Datenblatt sollte es 
anders gehen, vieleicht hab ichs auch falsch verstanden. Egal.

Ich werd dann mal versuchen Daten zu schreiben und zu lesen, wenns nicht 
geht melde ich mich wieder ;-)

lg,

Stefan
Gast #1362707
Lesenswert?

Schön dass es funktioniert :)

Anbei noch 2 Anmerkungen.


Stefan_h wrote :

>Anscheinend muss das Commando immerwieder an die Karte geschickt werden

Richtig , was der captain.at Code ja auch beinhaltet ?!
1
st: // if there is no MMC, prg. loops here
2
  if (Command(0x41,0,0,0xFF) !=0) goto st;

>und davor jedesmahl das CS auf High - ein 0xff schicken - und wieder CS
>wieder auf Low

Laut code (und eigener zurückliegender Erfahrung) ist es wichtig die 
clock Leitung am Anfang EINMAL high und dann wider low zu ziehen.
Das Timing was im code angegeben ist, muss eingehalten werden..also 80 
Clockzyklen:
1
  PORTB |= (1 << SPICS); // disable MMC
2
  // start MMC in SPI mode
3
  for(i=0; i < 10; i++) SPI(0xFF); // send 10*8=80 clock pulses
4
  PORTB &= ~(1 << SPICS); // enable MMC

Gruß
Gast #1368134
Lesenswert?

Hallo,

mein Status ist im Moment folgender:

- Karte in Idle setzen geht
- Karte dann initialisieren geht auch

das wars dann schon :-(

Habe dann versucht 512 Bytes auf die Karte zu schreiben:
1
do
2
{
3
   SPI_put_char(0xFF);
4
   SPI_put_char(0x58);
5
   SPI_put_char(0x00);
6
   SPI_put_char(0x00);
7
   SPI_put_char(0x02);
8
   SPI_put_char(0x00);
9
   SPI_put_char(0xFF);
10
   answer=SPI_get_char();
11
}while(answer==0xFF);//CMD write block
12

13
rs232_send_hex(answer);//PC rec. 0x00
14
SPI_put_char(0xff);
15
SPI_put_char(0xff);
16
SPI_put_char(0xfe);//start block
17
for(i=0;i<512;i++)
18
{
19
  SPI_put_char(0xAA);//block
20
}
21
SPI_put_char(0xff);//dummy
22
SPI_put_char(0xff);//dummy
23
do
24
{
25
  answer=SPI_get_char();
26
  rs232_send_hex(answer);
27
}while(answer==0xFF);
28

29
answer&=0x1f;
30
rs232_send_hex(answer);//should be 0x05
31
do
32
{
33
  answer=SPI_get_char();
34
}while(answer!=0xFF);

Statt den zu erwartenden 0x05 kommt meist was anderes konnte kein Muster 
erkennen. Hatte aber schon einmal 0x05!

habe einmal versucht die Bocklänge zu setzen, erhalte als antwort nie 
0x00, meist 0x03 oder 0x01 ...:
1
SPI_Disable();
2
SPI_PutChar(0xFF);
3
SPI_Enable();
4
do
5
{
6
  SPI_put_char(0x50);
7
  SPI_put_char(0x00);
8
  SPI_put_char(0x00);
9
  SPI_put_char(0x00);
10
  SPI_put_char(0x00);
11
  SPI_put_char(0xFF);
12
  do
13
  {
14
    answer=SPI_get_char();
15
  }while(answer==0xFF);
16
}while(answer!=0x00);

Habe auch schon viele codebeispiele(http://www.captain.at, 
http://www.captain.at, uvm) ausprobiert, CMD1 geht weiter komme ich 
nicht.

Ideen?

glg,

Stefan

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren