mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Pic24 MMC Karte Response Fehler


Autor: Tobias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
void main(void)
{
  short i,f;
  
  // Configure Oscillator to operate the device at 80MHz
  // Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
  // Fosc= 4M*80(2*2)=80Mhz for 4M input clock
// RM_FJ

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

  Delay(10);  
//  OSCCONbits.NOSC = 1;  // Switch to PLL mode
    asm ("mov #0x01, w3");
    asm ("mov #0x78, w0");
    asm ("mov #0x9A, w1");
    asm ("mov #_OSCCON+1, w2");
    asm ("mov.b w0, [w2]");
    asm ("mov.b w1, [w2]");
    asm ("mov.b w3, [w2]");

    asm ("mov #0x46, w0");
    asm ("mov #0x57, w1");
    asm ("mov #_OSCCON, w2");
    asm ("mov.b w0, [w2]");
    asm ("mov.b w1, [w2]");
    asm ("mov.b w3, [w2]");
    
  while(OSCCONbits.OSWEN) {}; // Wait for PLL to lock
  
  RCONbits.WDTO = 0;    // Reset Watch Dog Timer Timeout Flag
  RCONbits.SWDTEN = 1; // Enable SW controlled Watch Dog Timer

  // SDO1 SDKARTE
  // Pin 29-32 SPI1  
  // Pin 29 ist CS: Output RB14 

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


    AD1PCFG = 0xFFFF; //Analoge Ports alle deaktiviert

  TRISB = 0;

  mmc_init();


  for(;;)
  {
    //CModulSDCard_sdGlue_PERM();
  }

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




int mmc_init()
{
int i;


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

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

SPI1CON1bits.SMP = 0;
SPI1CON1bits.CKE = 1;
SPI1CON1bits.MSTEN = 1;
SPI1CON1bits.CKP = 0;

SPI1CON1bits.SPRE2=1;
SPI1CON1bits.SPRE1=0;
SPI1CON1bits.SPRE0=0;

SPI1CON1bits.PPRE1 = 1;
SPI1CON1bits.PPRE0 = 1;

SPI1STATbits.SPIEN = 1;



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



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


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


SPI_WRITE(0x40);                        // send reset command
SPI_WRITE(0x00);                        // all the arguments are 0x00 for the reset command
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x95);                        // precalculated checksum as we are still in MMC mode


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

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

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


i = 0;

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

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

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


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

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

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


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

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

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

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

Bei while((i < 255) && (mmc_response(0x00)==1)) bricht das Programm ab. 
Es kommen nicht die richtigen Response Codes zurück

Autor: Tobias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
  SDCS = 1; // MMC deaktiviert
  SPI1CON1bits.SMP = 0;
  SPI1CON1bits.CKE = 1;
  SPI1CON1bits.MSTEN = 1;
  SPI1CON1bits.CKP = 0;
  SPI1STATbits.SPIEN = 1;
  
  // 80 mal takten
  for(i=0;i<10;i++) SPI(0xFF);  
  
  // RESET
  unsigned char rr=Command(CMD0,0);
  SDCS=1; // MMC Deaktiviert
  /*OK Response ist 1*/

  
  r=Command(CMD8,0); // Spannung testen_ MMC oder spec1: illegal command
  SDCS=1;
  /*
  Liefert  0xC1  zurück
  */


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

  unsigned char ocr1 = SPI(0xFF);
  unsigned char ocr2 = SPI(0xFF);
  unsigned char ocr3 = SPI(0xFF);
  unsigned char ocr4 = SPI(0xFF);
  unsigned char ocr5 = SPI(0xFF);

  /*
  zurück:
  r = 0xF8;
  ocr1 = 0x0F;
  ocr2 = 0xFF;
ocr3 = 0xFF;
ocr4 = 0xFF;
ocr5 = 0xFF;
  */

  SDCS=1;

  // INIT wiederholt senden
  unsigned char rrr = 0;
  i=10000;
  do
  {
    rrr=Command(55,0); // Nächster ist APP CMD
    SDCS=1;
    if(r)
      break;
  }while(--i>0);

  /* 
  OK funktioniert Response ist 1
  */


  // Jetzt APP CMD 41 zum Initialisieren mit OCR = 0x0F??
  // 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.