Forum: Mikrocontroller und Digitale Elektronik @ SD & MMC Spezialisten


von Black Sabbath (Gast)


Angehängte Dateien:

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

von Potter68 (Gast)


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

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.