@ SD & MMC Spezialisten

Gast #1397614
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:
1
void find_highest_song_number(void){
2
int32 clust_high;
3
int32 eocmark;
4
  root_ccl= BPB_RootClus;
5
  clust_high=0;
6
  do{
7
    root_p_cl=root_ccl;
8
    root_ccl=readfat(root_p_cl);
9
//    printf("cluster seek:%4LX   ",root_ccl);
10
    eocmark=root_ccl & 0x0FFFFFFF;
11
    clust_high++;
12
  }while(eocmark<0x0fffffef);
13
  highestsong=clust_high * BPB_SecPerClus;
14
  highestsong=  highestsong*16;
15
  highestsong--;
16
}
17

18

19
int32 readfat(int32 fatoffset){
20
int16 temp;
21
int32 tempb;
22
char los;
23

24
  temp=0;
25
  fatoffset=fatoffset*2;
26
  los = *(((char*)&fatoffset)+0);  //the bottom byte of the address goes directly to a word in the FAT
27
  fatoffset=fatoffset / 256; 
28
  fatoffset+=fatstart;
29
  if(mmc_open_block(fatoffset)==1){
30
    putc('^');
31
//    printf("fat retry...");
32
    if(mmc_open_block(fatoffset)==1){
33
      putc('&');
34
      mmc_init(0);
35
//      printf("fat RETRY...");
36
      if(mmc_open_block(fatoffset)==1){
37
        putc('*');
38
        mmc_init(0);
39
//        printf("fat LOOKS BAD...");
40
        if(mmc_open_block(fatoffset)==1){
41
          printf("problem reading fat table, quitting chain. Sorry!");
42
          return 0xffffffff;
43
          songkill=1;
44
        }
45
      }
46
    }
47
  }
48
  mmc_skip(los);
49
  mmc_read();
50
  temp = ((int16) data_hi * 256)+ (int16) data_lo;
51
  mmc_read();//for fat32, four bytes per entry
52
  tempb=0;
53
  tempb = ((int16) data_hi * 256)+ (int16) data_lo;
54
  tempb=tempb<<16;
55
  tempb=tempb+(int32) temp;
56
  mmc_skip(255-(los));//trouble???
57
  mmc_read();
58
  mmc_read();
59
  mmc_close_block();
60
  return tempb;
61
}
62

63

64
char mmc_open_block(int32 block_number){
65
char tries,i;
66
int32 block_number_temp;
67

68
  for(tries=0;tries<10;tries++){
69
    SSPCON1=throttle;
70
    block_number_temp=block_number*512;
71
//    PUTC(13);PUTC(10);
72
//    printf("opening boolach");
73
//    printf("try:%u",tries);
74
    SPI_WRITE(0xFF);
75
    SPI_WRITE(0xFF);
76
    MMCSS=0;                     // set MMCSS = 0 (on)
77
//    SPI_WRITE(0xFF);
78
//    SPI_WRITE(0xFF);
79
    SPI_WRITE(0x51);                // send mmc read single block command
80
    SPI_WRITE(*(((char*)&block_number_temp)+3)); // arguments are address
81
    SPI_WRITE(*(((char*)&block_number_temp)+2));
82
    SPI_WRITE(*(((char*)&block_number_temp)+1));
83
    SPI_WRITE(0x00);
84
    SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
85
    if((mmc_response(0x00))==0){//((mmc_response(0x00))==0){
86
      if((mmc_response(0xFE))==0){
87
        return(0);  
88
      }
89
  //    printf("NOFENOFE");
90
      for(i=0;i<255;i++){
91
        SPI_WRITE(0xFF);
92
        SPI_WRITE(0xFF);
93
      }
94
    }
95
    MMCSS=1;            // set MMCSS = 1 (off)
96
    SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
97
    SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
98
//    SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
99
//    SPI_WRITE(0xFF);// give mmc the clocks it needs to finish off
100

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

110
void mmc_close_block(void){
111
//printf("close block");
112
  SPI_READ(0xFF);                 // CRC bytes that are not needed
113
  SPI_READ(0xFF);
114
  MMCSS=1;            // set MMCSS = 1 (off)
115
  SPI_WRITE(0xFF);                // give mmc the clocks it needs to finish off
116
       SPI_WRITE(0xff);
117
//       SPI_WRITE(0xff);
118
  //     SPI_WRITE(0xff);
119
}
120

121
void mmc_skip(char count){
122
  for (;count>0;count--){
123
    SPI_WRITE(0xFF);
124
    SPI_WRITE(0xFF);
125
  }
126
}


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
Angehängte Dateien:
Gast #1398107
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

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.