Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[SD Kaart] lowlevel aansturings/initialisatie problemen

Pagina: 1
Acties:
  • 286 views sinds 30-01-2008
  • Reageer

  • Wbdsgnr
  • Registratie: Maart 2002
  • Laatst online: 15-11 16:38

Wbdsgnr

Discombobulated?

Topicstarter
Ha Tweakers :)

Zoals de titel al verraad ben ik bezig een microcontroller (msp430f169) te interfacen met een SD Card (Sandisk 1GB Ultra II). Maar nu loop ik tegen een vrij hardnekkig probleem.

Ik probeer de kaart logischerwijs te initialiseren op de volgende manier:
Stuur een CMD0 met CRC 0x95.. -> SPI Modus (Krijg een R1 response van 0x01)
Stuuur een CMD55 gevolgt door ACMD41 net zolang tot de reply 0x00 wordt.. in iedergeval uit IDLE state.. maar dat gebeurt niet!

Als ik CMD55/ACMD41 vervang met CMD1 voor mmc Modus, blijft de reponse ook altijd 0x01

Op het moment als ik expres een fout commando stuur (zeg 99) dan krijg ik een 0x05 response.. wat dan weer duidt op een werkende SPI bus verbinding... en een illegal command en idle modus ;)

Heet iemand ervaring en/of tips hiermee? Ik heb zo'n beetje alle mogelijke codes en informatiebronnen uitgeput, maar ik kom er niet uit...
http://www.k9spud.com/sdcard
http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
http://www.maxim-ic.com/appnotes.cfm/appnote_number/3969
etc...

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 /* Put the card in the idle state */
  if (mmcSendCmd(sdc, CMD0, CMD0_R, response, argument) == 0){
    return 0;
  }
 

  /* Now wait until the card goes idle. Retry at most SD_IDLE_WAIT_MAX
  times */
  j = 0;
  do
  {
    j++;
/*
    // Flag the next command as an application-specific command 
    if (mmcSendCmd(sdc, CMD55, CMD55_R, response, argument) == 1)
    {
      // Tell the card to send its OCR
      mmcSendCmd(sdc, ACMD41, ACMD41_R, response, argument);
    }
    else
    {
      // No response, bail early
      j = SD_IDLE_WAIT_MAX;
    }
*/
    //mmcSendCmd(sdc, CMD58, R3, response, argument);
   mmcSendCmd(sdc, CMD1, CMD1_R, response, argument);
  }while ( ((response[0] & MSK_IDLE) == 0x01) && (j < SD_IDLE_WAIT_MAX) );
  
  /* As long as we didn't hit the timeout, assume we're OK. */
  if (j >= SD_IDLE_WAIT_MAX){
    return 0;
  }

i7 - GTX760 - triple boot


  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 29-10 06:07

Sprite_tm

Semi-Chinees

Tijdje terug dat ik SD/MMC-kaarten aan heb gestuurd... ik zal er even wat oude code bijpakken...

* Je initialiseert de kaart toch wel OK door er een flink aantal keer eerst FF heen te sturen? De meeste kaarten hebben een aantal kloktikken nodig voordat ze het goed doen.
* Ook tussen de requests in heb ik een aantal idle-kloktikken staan. Doe je dat wel in je mmcSendCmd-code?

Ter indicatie: dit is hoe ik mijn SD-kaart initte; deze routine doet het zowel voor MMCs als SDs voor zover ik me kan herinneren.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
;Init an SD/MMC-card
initsdcard:
        sbi portc,sdcs

        ldi temp2,0
initsdsend0:
        ldi temp,$ff
        rcall sdgetput
        dec temp2
        brne initsdsend0

        cbi portc,sdcs
        ldi temp,$ff
        rcall sdgetput
        ldi temp,$40
        rcall sdgetput
        ldi temp,$0
        rcall sdgetput
        ldi temp,$0
        rcall sdgetput
        rcall sdgetput
        ldi temp,$0
        rcall sdgetput
        ldi temp,$95
        rcall sdgetput
        
        ldi temp,1
        ldi temp2,1
        rcall sdgetresp

        rcall sdreadocr

        ret
;read the ocr register, to find out if the card is initted yet. If timeout,
;die with 129
sdreadocr:
        ldi temp3,20
sddoreadocr:
        dec temp3
        brne sddoreadocrok
        ldi temp,129
        ldi temp2,0
        rjmp die
sddoreadocrok:
        sbi portc,sdcs
        ldi temp,$ff
        rcall sdgetput
        cbi portc,sdcs
        ldi temp,$ff
        rcall sdgetput
        ldi temp,$41
        rcall sdgetput
        ldi temp,$0
        rcall sdgetput
        ldi temp,$0
        rcall sdgetput
        ldi temp,$0
        rcall sdgetput
        ldi temp,$0
        rcall sdgetput
        ldi temp,$95
        rcall sdgetput

        ldi temp,0
        ldi temp2,0
        rcall sdgetresp
        cpi temp,0
        brne sdreadocr

        ;ocr
        ldi temp,$ff
        rcall sdgetput
        push temp
        ldi temp,$ff
        rcall sdgetput
        ldi temp,$ff
        rcall sdgetput
        ldi temp,$ff
        rcall sdgetput
        ldi temp,$ff
        rcall sdgetput
        pop temp
        ret

Als je meer code, of verduidelijking, wilt hebben moet je maar ff een gil geven.

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • Wbdsgnr
  • Registratie: Maart 2002
  • Laatst online: 15-11 16:38

Wbdsgnr

Discombobulated?

Topicstarter
Thanks! Vraagje:

code:
1
2
3
4
5
6
7
8
9
sddoreadocrok:
        sbi portc,sdcs
        ldi temp,$ff
        rcall sdgetput
        cbi portc,sdcs
        ldi temp,$ff
        rcall sdgetput
        ldi temp,$41
        rcall sdgetput


Waarom stuur je nog een FF nadat je de CS pin weer hebt gecleared?

Dat terzijde.. ik heb dus in mijn sendCmd even een 'pauze' ingebouwd die 2 bytes stuurt terwijl ChipSelect pin hoog is. Het lijkt te werken, ik krijg nu een 0x00 respond. Probeer ik na de CMD0 en CMD1 nu echter CMD58 te sturen om het OCR uit telezen, krijg ik ook alles 0... Of is dat weer een ander commando? Ik ben denk ik een beetje in de war met SD/SPI/MMC en alle andere modussen en bijbehorende commando's...
Is er een simpele manier om te checken of het nu correct werkt? Of is dat gewoon een block schrijven en lezen en hopen dat het het zelfde is :)

[EDIT]
Te vroeg gejuicht, ik had een aanpassing gemaakt aan het ontvangen van de response.. had echter een foutje gemaakt... De response blijft 0x01 :(

[EDIT2]
Krijg ineens een ingeving... Waarschijnlijk heb ik hier te maken met een High Capacity card.. dan moet je na CMD0 een CMD8 sturen met correcte argumenten en CRC... Ik krijg alleen niet voorelkaar de correcte crc te berekenen.. blijf een 0x09 response terugkrijgen... Hier nog tips voor? :) Dit is wat ik verstuur als CMD8:

01001000 00000000 00000000 00000001 10101010 01000011
0x48 | 0x00 | 0x00 | 0x01 | 0xAA | met als CRC 0x43

[ Voor 25% gewijzigd door Wbdsgnr op 08-05-2007 12:32 ]

i7 - GTX760 - triple boot


  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 29-10 06:07

Sprite_tm

Semi-Chinees

Ik meen me te herinneren dat ook dat moest: die SD-kaarten hebben op de meest vreemde momenten nog clocks nodig om goed te werken. Ik ben bang dat er niet een simpele manier is om het te checken: het makkelijkst zou nog zijn om de kaart in een PC vol te proppen met 0xDEADBEEF en te zien of je dat ook uitleest.

Wat je btw misschien ook wel helpt: ik weet dat er een SD/MMC-uitlees-routine voor de LPC21xx bestaat die iirc redelijk leesbaar is en iig getest is. Je zou de code daarin eens 1-op-1 kunnen proberen te kopieeren en kijken wat er gebeurt. Ik weet de urrel van die code niet meer uit mijn hoofd, tho', je zult even moeten googlen. Afaik was 't voor een LPC2106 gemaakt, mss dat je daarmee verder komt.

[ Voor 39% gewijzigd door Sprite_tm op 08-05-2007 12:34 ]

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • Wbdsgnr
  • Registratie: Maart 2002
  • Laatst online: 15-11 16:38

Wbdsgnr

Discombobulated?

Topicstarter
Hmm thanks.. Ik heb idd wel voorbeelden gevonden, ook voor de lpc serie.. Maar alles en iedereen doet hetzelfde, wat bij mij dus niet lijkt te werken... Ik zal morgen even een ander kaartje meenemen, misschien heb ik dan meer geluk...
Ik ben ook even verder gegaan met de kaart als een high capacity kaart te behandelen, of in iedergeval een SD V2.0 kaart.. nu stuur ik eerst een CMD0, vervolgens die CMD8, daarop krijg ik de verwachte response, dan een CMD58 met verwachte response en dan weer de ACMD41 reeks met de -niet- verwachte response :)
Dit volgens deze documentatie...

Ik hoop dat ik meer geluk heb met een andere sdkaart...

i7 - GTX760 - triple boot


  • Wbdsgnr
  • Registratie: Maart 2002
  • Laatst online: 15-11 16:38

Wbdsgnr

Discombobulated?

Topicstarter
Nou ik heb mijn werk voortgezet met een 128 mb sd kaartje van eFilm(???) maar die werkt perfect... :D zelfde code .. Schijnbaar verscheelt het toch wel of je een oud of nieuw kaartje hebt.. alleen wat :)
Het kan niet zoveel meer werk zijn om een 1GB kaartje aan de praat te krijgen.

i7 - GTX760 - triple boot


  • Wbdsgnr
  • Registratie: Maart 2002
  • Laatst online: 15-11 16:38

Wbdsgnr

Discombobulated?

Topicstarter
Al goed.. voor zij, die er ooit nog wat aan kunnen hebben :)
Een Ultra kaartje van Sandisk verbruikt meer stroom dan een doorsnee SD kaartje. Mijn development boordje was powered door de JTAG connectie, wat schijnbaar niet genoeg was. Na het aansluiten van een externe voeding wou de sandisk kaart wel initialiseren en werkt alles naar behoren :)
Sprite, bedankt voor de moeite!

i7 - GTX760 - triple boot


  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 29-10 06:07

Sprite_tm

Semi-Chinees

Graag gedaan :) Even voor mijn eigen kennis: enig idee hoeveel dat kaartje ongeveer vrat?

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog

Pagina: 1