Pic24 MMC Karte Response Fehler

Gast #1710742
Lesenswert?
• ▲
▼
Ich versuche mit einem Pic 24 eine MMC Karte anzusprechen, bekomme 
jedoch Fehler als Response Codes zurück. Etwa "Illegal Command".
Der Code für die MMC Karte ist von 
http://www.microchipc.com/sourcecode/#mmc
1
void main(void)
2
{
3
  short i,f;
4
  
5
  // Configure Oscillator to operate the device at 80MHz
6
  // Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
7
  // Fosc= 4M*80(2*2)=80Mhz for 4M input clock
8
// RM_FJ
9

10
  CLKDIV = 0;    // Teilung durch 1
11
  OSCTUN = 0; // Tune FRC oscillator, if FRC is used
12

13
  Delay(10);  
14
//  OSCCONbits.NOSC = 1;  // Switch to PLL mode
15
    asm ("mov #0x01, w3");
16
    asm ("mov #0x78, w0");
17
    asm ("mov #0x9A, w1");
18
    asm ("mov #_OSCCON+1, w2");
19
    asm ("mov.b w0, [w2]");
20
    asm ("mov.b w1, [w2]");
21
    asm ("mov.b w3, [w2]");
22

23
    asm ("mov #0x46, w0");
24
    asm ("mov #0x57, w1");
25
    asm ("mov #_OSCCON, w2");
26
    asm ("mov.b w0, [w2]");
27
    asm ("mov.b w1, [w2]");
28
    asm ("mov.b w3, [w2]");
29
    
30
  while(OSCCONbits.OSWEN) {}; // Wait for PLL to lock
31
  
32
  RCONbits.WDTO = 0;    // Reset Watch Dog Timer Timeout Flag
33
  RCONbits.SWDTEN = 1; // Enable SW controlled Watch Dog Timer
34

35
  // SDO1 SDKARTE
36
  // Pin 29-32 SPI1  
37
  // Pin 29 ist CS: Output RB14 
38

39
  // Pin 30 ist SDO SPI1 Data out also RP29 RPOR14 high auf 7 einstellen
40
  RPOR14 = 0x0700; // RP29 Pin 30
41
  
42
  // Pin 31 ist SDA also RP10 auf INPUT SPI1 einstellen
43
  // vorher: //RPINR19 = 0x000A;//10;    // UART2 RX : RP10 für U2RX gewählt ist Pin 31
44
  RPINR20 = 10; // RP10 ist SDI1 ist Pin 31
45
  // Pin 32 ist SCL also RP17 RPnR auf 8 einstellen
46
  RPOR8  = 0x0800;  // SPI1 Clock: Pins RP17=Pin32
47

48

49
    AD1PCFG = 0xFFFF; //Analoge Ports alle deaktiviert
50

51
  TRISB = 0;
52

53
  mmc_init();
54

55

56
  for(;;)
57
  {
58
    //CModulSDCard_sdGlue_PERM();
59
  }
60

61
  // if code, behind this line, is executed, something went wrong ...
62
}
63

64

65

66

67
int mmc_init()
68
{
69
int i;
70

71

72
//SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_4 | SPI_SS_DISABLED);
73

74
//*0x94 |= 0x40;                          // set CKE = 1 - clock idle low
75
//*0x14 &= 0xEF;                          // set CKP = 0 - data valid on rising edge
76
SPI1CON1 = 0x00;
77

78
SPI1CON1bits.SMP = 0;
79
SPI1CON1bits.CKE = 1;
80
SPI1CON1bits.MSTEN = 1;
81
SPI1CON1bits.CKP = 0;
82

83
SPI1CON1bits.SPRE2=1;
84
SPI1CON1bits.SPRE1=0;
85
SPI1CON1bits.SPRE0=0;
86

87
SPI1CON1bits.PPRE1 = 1;
88
SPI1CON1bits.PPRE0 = 1;
89

90
SPI1STATbits.SPIEN = 1;
91

92

93

94
//OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
95
SDCS = 1; // MMC deaktiviert
96

97

98

99
for(i=0;i<10;i++)                       // initialise the MMC card into SPI mode by sending clks on
100
{
101
        SPI_WRITE(0xFF);
102
}
103

104

105
//OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on) tells card to go to spi mode when it receives reset
106
SDCS = 0; // MMC aktiviert
107

108

109
SPI_WRITE(0x40);                        // send reset command
110
SPI_WRITE(0x00);                        // all the arguments are 0x00 for the reset command
111
SPI_WRITE(0x00);
112
SPI_WRITE(0x00);
113
SPI_WRITE(0x00);
114
SPI_WRITE(0x95);                        // precalculated checksum as we are still in MMC mode
115

116

117
//puts("Sent go to SPI\n\r");
118

119
if(mmc_response(0x01)==1) return 1;     // if = 1 then there was a timeout waiting for 0x01 from the mmc
120

121
//puts("Got response from MMC\n\r");
122

123

124
i = 0;
125

126
while((i < 255) && (mmc_response(0x00)==1))     // must keep sending command if response
127
{
128
        SPI_WRITE(0x41);                // send mmc command one to bring out of idle state
129
        SPI_WRITE(0x00);                // all the arguments are 0x00 for command one
130
        SPI_WRITE(0x00);
131
        SPI_WRITE(0x00);
132
        SPI_WRITE(0x00);
133
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
134
        i++;
135
}
136

137
if(i >= 254) 
138
  return 1;                   // if >= 254 then there was a timeout waiting for 0x00 from the mmc
139

140
//puts("Got out of idle response from MMC\n\r");
141

142

143
//OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
144
SDCS = 1; // MMC deaktiviert
145

146
SPI_WRITE(0xFF);                        // extra clocks to allow mmc to finish off what it is doing
147

148
//OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on)
149
SDCS = 0; // MMC aktiviert
150

151

152
        SPI_WRITE(0x50);                // send mmc command one to bring out of idle state
153
        SPI_WRITE(0x00);
154
        SPI_WRITE(0x00);
155
        SPI_WRITE(0x02);                // high block length bits - 512 bytes
156
        SPI_WRITE(0x00);                // low block length bits
157
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
158

159
if((mmc_response(0x00))==1) return 1;
160

161
//OUTPUT_HIGH(PIN_C2);            // set SS = 1 (off)
162
SDCS = 1; // MMC deaktiviert
163

164
//puts("Got set block length response from MMC\n\r");
165
return 0;
166
}

Bei while((i < 255) && (mmc_response(0x00)==1)) bricht das Programm ab. 
Es kommen nicht die richtigen Response Codes zurück
Gast #1713990
Lesenswert?
• ▲
▼
Nochmal mit anderem Code und anderer SD Karte
Den obigen Code braucht ihr nicht mehr beachten
Ich bekomme fehlerhafte Response Codes beim Initialisieren 
(CMD8,CMD55,CMD41).

Routine zum Initialisieren:
1
  SDCS = 1; // MMC deaktiviert
2
  SPI1CON1bits.SMP = 0;
3
  SPI1CON1bits.CKE = 1;
4
  SPI1CON1bits.MSTEN = 1;
5
  SPI1CON1bits.CKP = 0;
6
  SPI1STATbits.SPIEN = 1;
7
  
8
  // 80 mal takten
9
  for(i=0;i<10;i++) SPI(0xFF);  
10
  
11
  // RESET
12
  unsigned char rr=Command(CMD0,0);
13
  SDCS=1; // MMC Deaktiviert
14
  /*OK Response ist 1*/
15

16
  
17
  r=Command(CMD8,0); // Spannung testen_ MMC oder spec1: illegal command
18
  SDCS=1;
19
  /*
20
  Liefert  0xC1  zurück
21
  */
22

23

24
  r = Command(CMD58,0);  // READ_OCR Test
25

26
  unsigned char ocr1 = SPI(0xFF);
27
  unsigned char ocr2 = SPI(0xFF);
28
  unsigned char ocr3 = SPI(0xFF);
29
  unsigned char ocr4 = SPI(0xFF);
30
  unsigned char ocr5 = SPI(0xFF);
31

32
  /*
33
  zurück:
34
  r = 0xF8;
35
  ocr1 = 0x0F;
36
  ocr2 = 0xFF;
37
ocr3 = 0xFF;
38
ocr4 = 0xFF;
39
ocr5 = 0xFF;
40
  */
41

42
  SDCS=1;
43

44
  // INIT wiederholt senden
45
  unsigned char rrr = 0;
46
  i=10000;
47
  do
48
  {
49
    rrr=Command(55,0); // Nächster ist APP CMD
50
    SDCS=1;
51
    if(r)
52
      break;
53
  }while(--i>0);
54

55
  /* 
56
  OK funktioniert Response ist 1
57
  */
58

59

60
  // Jetzt APP CMD 41 zum Initialisieren mit OCR = 0x0F??
61
  // Hängt sich auf!
Ich habe die Rückgabewerte im Code angegeben

Kann der Rückgabewert zu CMD8 0xC1 sein? Bit 7 soll doch 0 sein?
und der Inhalt vom OCR Register, kann der so stimmen?
Vielleicht ein Hardware-Fehler? Als Spannung liegen 3,3V an.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.