Forum: Mikrocontroller und Digitale Elektronik Pic24 MMC Karte Response Fehler


von Tobias (Gast)


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

von Tobias (Gast)


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.

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.