www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SD-Card an MSP die 2te


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

Ich befasse mich seit einiger Zeit mit dem Anschluss einer SD-Card an 
den MSP. Wie in einigen anderen Threads besprochen, verwende ich die 
Appnote von TI.
Da es bei mir momentan hardwareseitig ein paar Probleme gibt, begnüge 
ich mich damit den Quelltext ein wenig durchzuarbeiten. Da mir das 
Programmieren nicht gerade in den Schoß gelegt wurde, kommen immer 
wieder ein paar Fragen auf, z.B. diese hier (ich weiß, ist recht 
speziell):

Die SD-Card wird mit HIGH deselektiert. Danach wird der Sendebefehl 
ausgeführt. Was genau soll das bewirken ? Dieser spiSendByte wird 
desöfteren an Stellen ausgeführt, wo ich das nicht nachvollziehen kann.
Ist er dafür da, dass man einfach das zuletzt gesendete Byte der SD-Card 
abfängt und in den RXBUF schreibt ?

 CS_HIGH();
    spiSendByte(0xff);


Hier noch die zugehörige Funktion:

 unsigned char spiSendByte(const unsigned char data)
{
  while ((IFG2&UTXIFG1) ==0); 
  TXBUF1 = data;               
  while ((IFG2&URXIFG1)==0);    
  return (RXBUF1);
}


Vielleicht findet sich ja ein Spezialist, der mir weiterhelfen kann.

Gruß

Sebastian

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, bei SPI muss der Master das Byte quasi beim Slave "abholen", es wird 
nur was empfangen, wenn was gesendet wird. Daher das Dummy-Bate 0xFF, 
damit schiebst du halt das von der SD-Karte bereitgestellte Byte in den 
RXBUF.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal,

@Chris: Sowas in der Art habe ich mir schon gedacht. Jetzt ist auf jeden 
Fall einiges klarer.

Habe da aber noch eine entscheidene Frage bzgl. des Quelltextes. Mir ist 
nicht ganz klar woher der MSP weiß was er auf die Karte schreiben muss. 
An welcher Stelle in der "WriteFunktion" werden die zu übertragenen 
Daten aus dem Buffer gezogen auf den der Zeiger pBuffer zeigt ?

char mmcWriteBlock (const unsigned long address, const unsigned long count, unsigned char *pBuffer)
{
//  unsigned long i = 0;
  char rvalue = MMC_RESPONSE_ERROR;         // MMC_SUCCESS;
  //  char c = 0x00;

  // Set the block length to read
  if (mmcSetBlockLength (count) == MMC_SUCCESS)   // block length could be set
  {
    // SS = LOW (on)
    CS_LOW ();
    // send write command
    mmcSendCmd (MMC_WRITE_BLOCK,address, 0xFF);

    if (mmcGetXXResponse(MMC_R1_RESPONSE) == MMC_R1_RESPONSE)
    {
      spiSendByte(0xff);
      // send the data token to signify the start of the data
      spiSendByte(0xfe);
      // clock the actual data transfer and transmitt the bytes
      // put CRC bytes (not really needed by us, but required by MMC)
      spiSendByte(0xff);
      spiSendByte(0xff);
      // read the data response xxx0<status>1 : status 010: Data accepted, status 101: Data
      //   rejected due to a crc error, status 110: Data rejected due to a Write error.
      mmcCheckBusy();
      rvalue = MMC_SUCCESS;
    }
    else
    {
      // the MMC never acknowledge the write command
      rvalue = MMC_RESPONSE_ERROR;   // 2
    }
  }
  else
  {
    rvalue = MMC_BLOCK_SET_ERROR;   // 1
  }
  // give the MMC the required clocks to finish up what ever it needs to do
  //  for (i = 0; i < 9; ++i)
  //    spiSendByte(0xff);

  CS_HIGH ();
  // Send 8 Clock pulses of delay.
  spiSendByte(0xff);
  return rvalue;
} // mmc_write_block


Ähnlich verhält es sich ja auch beim Lesen. Wo (Buffer?) und warum 
landen die Daten. Vielleicht steckt die Information auch in den 
SD-Befehlen ?

Danke schonmal für eure Hilfe.


Gruß

Sebastian


PS: Kann man den Thread vielleicht ins MSP-Forum verschieben ?

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>An welcher Stelle in der "WriteFunktion" werden die zu übertragenen
>Daten aus dem Buffer gezogen auf den der Zeiger pBuffer zeigt ?

>      // send the data token to signify the start of the data
>      spiSendByte(0xfe);
>      // clock the actual data transfer and transmitt the bytes

Die Stelle ist genau hier. Scheint aber von irgend jemand
gelöscht worden zu sein.

>      // put CRC bytes (not really needed by us, but required by MMC)
>      spiSendByte(0xff);
>      spiSendByte(0xff);

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
öhm ... ich habe da eigentlich nichts dran geändert. Was sollte denn 
dort stehen ?!

kramt nochmal nach dem ursprünglichen Quelltext

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>öhm ... ich habe da eigentlich nichts dran geändert. Was sollte denn
>dort stehen ?!

#ifndef withDMA
      for (i = 0; i < count; i++)
        spiSendByte(pBuffer[i]);
#else
      /* Get the block */
      /* DMA trigger is UART send */
      DMACTL0 &= ~(DMA0TSEL_15);
      DMACTL0 |= (DMA0TSEL_9);
      /* Source DMA address: the data buffer.  */
      DMA0SA = (unsigned short)pBuffer;
      /* Destination DMA address: the UART send register. */
      DMA0DA = U1TXBUF_;
      /* The size of the block to be transferred */
      DMA0SZ = count;
      /* Configure the DMA transfer*/
      DMA0CTL =
        DMAREQ  |                           /* start transfer */
        DMADT_0 |                           /* Single transfer mode */
        DMASBDB |                           /* Byte mode */
        DMAEN |                             /* Enable DMA */
        DMASRCINCR1 | DMASRCINCR0;          /* Increment the source 
address */
#endif

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast vollkommen Recht. :S

Mir fällt auch wieder ein warum ich den Teil mal rausgehauen hatte. 
Leider war ich beim Löschen etwas großzügig.
Wollte die Kommunikation ohne DMA-Modul realisieren.
Wenn ich das jetzt richtig verstanden habe, wird entweder der 
"withDMA"-Teil ausgeführt oder das was nach dem "else" kommt. Dabei 
sieht es eher so aus, dass letzterer Teil das DMA-Modul nutzt, oder ?


Ich würde eigentlich gerne Strom sparen und nicht das DMA-Modul nutzen.
(stellt höheren Datentransfer bereit, zieht aber auch mehr Strom, oder?)

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich würde eigentlich gerne Strom sparen und nicht das DMA-Modul nutzen.
>(stellt höheren Datentransfer bereit, zieht aber auch mehr Strom, oder?)

Keine Ahnung, aber am meisten Strom sparst du wenn du deine
SD Karte gar nicht erst anschliesst ;)

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Öhm, also man sollte schon wissen, was man löscht. Mit DMA kann es 
schneller gehen, wenn man große Blöcke übertragen will und der Prozessor 
noch andere Sachen zu tun hat. Einmal angestoßen läuft der DMA ohne 
Prozessorlast. Ansonsten gehts mit direkt auslesen genauso schnell. DMA 
sollte man nur benutzen, wenn man wirklich verstanden hat, wie der 
komplexe DMA-Controller funktioniert. Der kann viel, hat aber auch 
tausend Register, die man einstellen muss.

Autor: Seb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Chris: Ja, das mit dem Löschen war nicht sehr clever.

@Holger:

Da hast du natürlich recht  ;-)
Die SD-Karte strebe ich auch eher als Übergangslösung an. Eigentlich 
würde ich gerne einen "nackten" NAND Flash benutzen. Davon wurde mir 
jedoch bisher im Forum abgeraten, da die Ansteuerung nicht gerade 
trivial ist.
Ich lasse mich jedoch gerne vom Gegenteil überzeugen.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So,

Die Karte läuft nun am MSP. Ich kann wunderbar schreiben und mir das 
später in Winhex ansehen. Auch die Lesefunktion scheint zu klappen, 
wobei ich mir noch nicht ganz sicher bin wie ich überprüfen kann, ob er 
denn das richtige liest. Wie habt ihr das gemacht ?

Ich versuche gerade die gelesenen Daten erneut in einen anderen Sektor 
schreiben zu lassen. Klappt aber noch nicht ganz...

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, nun klappt die Sache. Meine Karte liest brav und schreibt diese 
Daten in einen gewünschten Sektor.

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.