www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik @ SD & MMC Spezialisten


Autor: Black Sabbath (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich beschäftige mich im Moment mit dem Bau eines MP3 Players. Im 
wesentlichen hab ich mich ans Layout des Daisy MP3 gehalten und 
dementsprechend benutze ich auch dessen Code (Anhang), schreibe diesen 
für C18 um und füge noch ein GLCD ein.
Ich kann problemlos mit dem VS1011 komunizieren und ich kann die Details 
der SD auslesen. Das Programm soll dann aber etwas mir nicht 
nachvollziebares machen. Wichtig zum Verständnis sind folgende 4 
Funktionen:


void find_highest_song_number(void){
int32 clust_high;
int32 eocmark;
  root_ccl= BPB_RootClus;
  clust_high=0;
  do{
    root_p_cl=root_ccl;
    root_ccl=readfat(root_p_cl);
//    printf("cluster seek:%4LX   ",root_ccl);
    eocmark=root_ccl & 0x0FFFFFFF;
    clust_high++;
  }while(eocmark<0x0fffffef);
  highestsong=clust_high * BPB_SecPerClus;
  highestsong=  highestsong*16;
  highestsong--;
}


int32 readfat(int32 fatoffset){
int16 temp;
int32 tempb;
char los;

  temp=0;
  fatoffset=fatoffset*2;
  los = *(((char*)&fatoffset)+0);  //the bottom byte of the address goes directly to a word in the FAT
  fatoffset=fatoffset / 256; 
  fatoffset+=fatstart;
  if(mmc_open_block(fatoffset)==1){
    putc('^');
//    printf("fat retry...");
    if(mmc_open_block(fatoffset)==1){
      putc('&');
      mmc_init(0);
//      printf("fat RETRY...");
      if(mmc_open_block(fatoffset)==1){
        putc('*');
        mmc_init(0);
//        printf("fat LOOKS BAD...");
        if(mmc_open_block(fatoffset)==1){
          printf("problem reading fat table, quitting chain. Sorry!");
          return 0xffffffff;
          songkill=1;
        }
      }
    }
  }
  mmc_skip(los);
  mmc_read();
  temp = ((int16) data_hi * 256)+ (int16) data_lo;
  mmc_read();//for fat32, four bytes per entry
  tempb=0;
  tempb = ((int16) data_hi * 256)+ (int16) data_lo;
  tempb=tempb<<16;
  tempb=tempb+(int32) temp;
  mmc_skip(255-(los));//trouble???
  mmc_read();
  mmc_read();
  mmc_close_block();
  return tempb;
}


char mmc_open_block(int32 block_number){
char tries,i;
int32 block_number_temp;

  for(tries=0;tries<10;tries++){
    SSPCON1=throttle;
    block_number_temp=block_number*512;
//    PUTC(13);PUTC(10);
//    printf("opening boolach");
//    printf("try:%u",tries);
    SPI_WRITE(0xFF);
    SPI_WRITE(0xFF);
    MMCSS=0;                     // set MMCSS = 0 (on)
//    SPI_WRITE(0xFF);
//    SPI_WRITE(0xFF);
    SPI_WRITE(0x51);                // send mmc read single block command
    SPI_WRITE(*(((char*)&block_number_temp)+3)); // arguments are address
    SPI_WRITE(*(((char*)&block_number_temp)+2));
    SPI_WRITE(*(((char*)&block_number_temp)+1));
    SPI_WRITE(0x00);
    SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
    if((mmc_response(0x00))==0){//((mmc_response(0x00))==0){
      if((mmc_response(0xFE))==0){
        return(0);  
      }
  //    printf("NOFENOFE");
      for(i=0;i<255;i++){
        SPI_WRITE(0xFF);
        SPI_WRITE(0xFF);
      }
    }
    MMCSS=1;            // set MMCSS = 1 (off)
    SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
    SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
//    SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
//    SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off

//    printf("minorcrash%d",tries);
//    if((throttle==mmc_high_speed)&(tries>3)){throttle=mmc_med_speed; printf("now med speed");}
//    else if((throttle==mmc_med_speed)&(tries>5)){throttle=mmc_low_speed; printf("now low speed");}
//    mmc_init(0);
  }
//  puts("MMC crash in: mmc open block.\n\r");
  return 1;
}

void mmc_close_block(void){
//printf("close block");
  SPI_READ(0xFF);                 // CRC bytes that are not needed
  SPI_READ(0xFF);
  MMCSS=1;            // set MMCSS = 1 (off)
  SPI_WRITE(0xFF);                // give mmc the clocks it needs to finish off
       SPI_WRITE(0xff);
//       SPI_WRITE(0xff);
  //     SPI_WRITE(0xff);
}

void mmc_skip(char count){
  for (;count>0;count--){
    SPI_WRITE(0xFF);
    SPI_WRITE(0xFF);
  }
}




In Main wird die Funktion find_highest_song() aufgerufen. Diese ruft 
Funktion readfat() auf und übergibt ihr BPB_RootClus (welche den Wert 2 
hat). Dort wird der Wert verdoppelt, dann durch 256 dividiert und mit 
Fatstart summiert um dann mit dem Ergebnis die Funktion mmc_open_block 
aufzurufen. Dabei werd ich schon mal stutzig, wenn ich bedenke, dass 
2*2/256 berechnet wird... Das Ergebnis ist folglich 0, mit fatstart 
addiert 271. In Sector 271 werden dann durch "los" die ersten 8 Byte 
übersprungen und die nächsten 4 als 4byte Variabel übertragen. Secotor 
271 faängt so an: "øÿÿ.ÿÿÿÿÿÿÿ........" Da kann was nicht stimmen, hat 
jemand einen Plan?
Die Daten der SD aluten wie folgt:

 BPB_BytsPerSec:   512
 BPB_SecPerCluster:8
 BPB_RsvdSecCnt:   38
 BPB_NumFATs:      2
 fatstart:         271
 FirstDataSector:  1992
 Root_dir_cluster: 2
 BPB_FatSz32:      977
 datsec:           2225


Gruß
BS

Autor: Potter68 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

wenn man sich mit dem FAT-Dateisystem nicht auskennt, klingt das alles 
sehr verwirrend. Ich empfehle Dir, Dich mit FAT16/FAT32 auseinander zu 
setzen. Stichworte hierzu: Cluster, Sektor, FAT, MBR, VBR und ROOT.

Gruß Potter68

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.