Forum: FPGA, VHDL & Co. CLK ür SD-Karte festlegen.


von Peter B. (funkheld)


Angehängte Dateien:

Lesenswert?

Hallo, guten Tag.
Ich habe hier ein Timingplan für die SD-Karte.
Da müssen ja bestimmte Clocks eingehalten werden.

Ich habe 50Mhz beim DE1, welche CLK-Länge muss ich jetzt bitte beim FPGA 
für ein Clocks nehmen?

Danke.
Gruss

: Bearbeitet durch User
von TriHexagon (Gast)


Lesenswert?

Du musst auch noch beachten, dass in der Initialisierung der SD Karte 
CLK max. 400 kHz betragen darf.

von Peter B. (funkheld)


Lesenswert?

JUp, danke.

Wie weit bleibt man unter 400Khz?

Danke.
Gruss

von TriHexagon (Gast)


Lesenswert?

400 kHz muss eigentlich funktionieren. Aber wenn du auf der sicheren 
Seite sein willst, nimmst du was darunter, z.B. 200 kHz oder 125kHz 
(habe ich mal verwendet).

von Peter B. (funkheld)


Lesenswert?

Hmm.., danke.
Wie kann ich die 400Khz oder darunter jetzt wirksam erzeugen von 50Mhz.
Das verstehe ich noch nicht.

Danke. Gruss

von CLock (Gast)


Lesenswert?

Teil halt durch 128 oder 256. Ist doch vollkommen egal, da Synchron.
Ob das nun 390kHz oder 195kHz sind...

von Peter B. (funkheld)


Lesenswert?

Jup danke.
Also gibt es keinen Wert der genau vorgeschrieben ist, als da unter 
400KHz bleiben.

Danke.
Gruss

von Michael (Gast)


Lesenswert?

Die Frage ist doch noch eine ganz andere. Was soll mit
der SD-Karte gemacht werden? Sollen hier etwas Daten
abgelegt werden die später auch noch mit dem PC gelesen
werden können?

Gruß,
Michael

von Peter B. (funkheld)


Lesenswert?

Ich möchte die Daten am PC lesen.
Ich möchte nur in 512 Byte-Blöcke lesen und schreiben weiter nicht.

GRuss

So wie hier:
1
//Routine zur Initialisierung der SD-Karte (SPI-MODE)
2
uint8_t sd_init(void)
3
{
4
  uint16_t sd_timeout = 0;
5
  uint16_t i;
6
7
  //Konfiguration des Ports, an den die SD-Karte angeschlossen wurde
8
    /*
9
     D6  (do) SS    = SD_Chip_Select
10
     B5  (do) MOSI  = SPI_DO
11
     B6  (di) MISO  = SPI_DI
12
     B7  (do) SCK   = SPI_Clock
13
    */
14
15
  DDRB |= (1<<7) | (1<<5) | (1<<4);              //SPI konfigurieren
16
  DDRD |= (1<<6);
17
  
18
  PORTD |= (1<<6);                  //Disable
19
20
  for(i = 0; i < 200; i++)
21
  {
22
    __asm__ __volatile__ ("nop" ::);               //Wartet eine kurze Zeit
23
  }
24
25
  //Aktivieren des SPI - Bus, Clock = Idle LOW
26
  //SPI Clock teilen durch 128 (Wir werden erst nach der Initialisierung richtig schnell)
27
  SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0) | (1<<SPR1);          //Enable SPI, SPI im Master Mode  
28
  SPSR = (0<<SPI2X);
29
30
  //Bringe SD-Karte in den SPI-Mode
31
  for (i = 0; i<10; i++)
32
  {                       //Sendet 20*8 Clocks an die SD-Karte
33
    sd_writeByte(0xff);
34
  }
35
36
  //Sendet Kommando CMD0 an SD-Karte
37
  uint8_t CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};          //CMD0
38
  while(sd_writeCommand(CMD) != 1)
39
  {
40
    if (sd_timeout++ > 300) return 1;              //Abbruch bei CMD0
41
  }
42
  
43
  for (i = 0; i<10; i++)
44
  {                       //Sendet 20*8 Clocks an die SD-Karte
45
    sd_writeByte(0xff);
46
  }
47
  
48
  //Sendet Kommando CMD1 an SD-Karte
49
  sd_timeout = 0;
50
  CMD[0] = 0x41;                  //CMD1
51
  CMD[5] = 0xFF;
52
  while(sd_writeCommand(CMD) != 0)
53
  {
54
    if (sd_timeout++ > 600)
55
    {
56
      sd_timeout = 0;
57
      CMD[0] = 0x77;                  //ACMD
58
      CMD[5] = 0x01;
59
      while(sd_writeCommand(CMD) != 0)
60
      {
61
      if (sd_timeout++ > 600) return 2;             //Abbruch bei CMD1 und ACMD
62
      }
63
    }
64
  }
65
  
66
  //SPI Bus auf maximale Geschwindigkeit  (Clk/2)
67
  SPCR &= ~((1<<SPR0) | (1<<SPR1));              //Clear SPR0+SPR1
68
  SPSR = SPSR|(1<<SPI2X);                //Set SPI2X
69
70
71
  PORTD |= (1<<6);                  //Disable
72
  return(0);                    //OK
73
}
74
75
76
77
//Sendet ein Kommando an die SD-Karte
78
uint8_t sd_writeCommand(uint8_t *cmd)
79
{
80
  uint8_t tmp = 0xff;
81
  uint16_t sd_timeout = 0;
82
  uint8_t i;
83
  //SD_Chip_Select high (SD-Karte Inaktiv) 
84
  PORTD |= (1<<6);                  //Disable
85
86
  //sendet 8 Clock Impulse
87
  sd_writeByte(0xFF);
88
89
  //SD_Chip_Select low (SD-Karte Aktiv)
90
  PORTD &= ~(1<<6);                  //Enable
91
92
  //sendet 6 Byte Commando
93
  for (i = 0; i<0x06; i++)                //sendet 6 Byte Kommando zur MMC/SD-Karte
94
  {
95
    sd_writeByte(*cmd++);
96
  }
97
98
  //Wartet auf ein gueltige Antwort von der MMC/SD-Karte
99
  while (tmp == 0xff)
100
  {
101
    tmp = sd_readByte();
102
    if (sd_timeout++ > 500)
103
    {
104
      break;                    //Abbruch da die MMC/SD-Karte nicht Antwortet
105
    }
106
  }
107
  return tmp ;
108
}
109
110
111
//Routine zum Empfangen eines Bytes von der SD-Karte 
112
uint8_t sd_readByte(void)
113
{
114
  uint8_t sd_Byte = 0;
115
  SPDR = 0xff;
116
  while(!(SPSR & (1<<SPIF)))
117
  {
118
    ;
119
  }
120
  sd_Byte = SPDR;
121
  return sd_Byte;
122
}
123
124
//Routine zum Senden eines Bytes zur SD-Karte
125
void sd_writeByte(uint8_t Byte)
126
{
127
  SPDR = Byte;   //Sendet ein Byte
128
  while(!(SPSR & (1<<SPIF)))                //Wartet bis Byte gesendet wurde
129
  ;
130
}
131
132
133
//Routine zum Schreiben eines Sektors
134
uint8_t sd_writeSektor(void)
135
{
136
  uint8_t cmd[6];
137
  uint32_t sd_l_sektor_index = sd_sektor_index * 512;  //die Adressierung der SD-Karte wird in Bytes angegeben, Sektor wird von Blocks in Bytes umgerechnet
138
139
140
  cmd[0] = 0x58;
141
  cmd[1] = ((sd_l_sektor_index & 0xFF000000) >>24 );
142
  cmd[2] = ((sd_l_sektor_index & 0x00FF0000) >>16 );
143
  cmd[3] = ((sd_l_sektor_index & 0x0000FF00) >>8 );
144
  cmd[4] = 0;
145
  cmd[5] = 0xFF;
146
147
  //Sende Kommando cmd24 an SD-Karte (Write 1 Block/512 Bytes)
148
  uint8_t sd_error = sd_writeCommand(cmd);
149
  if (sd_error != 0)
150
  {
151
    return(sd_error);
152
  }
153
154
  //einen Moment warten und Clock senden
155
  for(uint8_t i = 0; i < 100; i++)
156
  {
157
    sd_readByte();
158
  }
159
  
160
  
161
  //Sende Start Byte an SD-Karte
162
  sd_writeByte(0xFE);
163
  
164
  
165
  //Schreiben des Blocks (512Bytes) auf SD-Karte
166
  for(sd_data_index = 0; sd_data_index < 512; sd_data_index++)
167
  {
168
    //sd_writeByte(sd_data_buffer[sd_data_index]);      //Daten senden
169
    sd_writeByte(123);              //Der Einfachheit wegen testweise nur 123 als Muster schreiben
170
  }
171
172
  //Block schliessen:
173
  //CRC-Byte schreiben
174
  sd_writeByte(0xFF); //Schreibe Dummy CRC
175
  sd_writeByte(0xFF); //CRC Code wird nicht benutzt
176
177
  //Fehler beim schreiben? (Data Response XXX00101 = OK)
178
  sd_error = sd_readByte();
179
  if((sd_error & 0x1F) != 0x05)
180
  {
181
    PORTD |= (1<<6);                  //Disable
182
    return(sd_error);
183
  } 
184
185
  //Warte auf SD-Karte busy
186
  while (sd_readByte() != 0xff)
187
    ;
188
 
189
  //SD-Karte Inaktiv schalten (Chip Select auf high)
190
  PORTD |= (1<<6);                  //Disable
191
192
  //Wenn wir hier angekommen sind ist die Welt in Ordnung!
193
  return 0;
194
}
195
196
//Routine zum Lesen eines Sektors
197
uint8_t sd_readSektor(void)
198
{
199
  uint8_t cmd[6];
200
  uint32_t sd_l_sektor_index = sd_sektor_index * 512;  //die Adressierung der SD-Karte wird in Bytes angegeben, Sektor wird von Blocks in Bytes umgerechnet
201
  
202
  cmd[0] = 0x51;          //Sektoren Byteweise angeben
203
  cmd[1] = ((sd_l_sektor_index & 0xFF000000) >> 24);  //MSB isolieren und in Position rücken
204
  cmd[2] = ((sd_l_sektor_index & 0x00FF0000) >> 16);  //...   "
205
  cmd[3] = ((sd_l_sektor_index & 0x0000FF00) >> 8);  //LSB   "
206
  cmd[4] = 0;
207
  cmd[5] = 0xFF;
208
  
209
  //Sende Kommando an SD-Karte (Read 1 Block/512 Bytes)
210
  uint8_t sd_error = sd_writeCommand(cmd);
211
  if (sd_error) return sd_error;
212
  
213
  //Wartet auf Start Byte (0xFE) von der SD-Karte 
214
  uint16_t sd_timeout = 500;
215
  while ((sd_readByte() != 0xfe) && (sd_timeout))
216
  {
217
      if(sd_timeout-- == 0) return 2;              //War wohl nix...
218
  }      
219
  
220
  //Hole die Daten
221
  for(sd_data_index = 0; sd_data_index < 512; sd_data_index++)
222
  {
223
    sd_data_buffer[sd_data_index] = sd_readByte();
224
  }
225
  
226
  
227
  //CRC-Byte auslesen
228
  sd_readByte();  //CRC - Byte wird nicht ausgewertet
229
  sd_readByte();  //CRC - Byte wird nicht ausgewertet
230
  PORTD |= (1<<6);                  //Disable
231
  
232
  //Wenn wir hier angekommen sind ist die Welt in Ordnung!
233
  return 0;
234
}

von CLock (Gast)


Lesenswert?

Softcore oder pures VHDL?

Mit Softcore kein Thema, mit VHDL wird es schon sportlicher.
Die Init und das Protokoll der SD ist ja nicht so einfach 
zusammengestrickt in VHDL.

von Peter B. (funkheld)


Lesenswert?

Hmm.., VHDL.

Gruss

von Michael (Gast)


Lesenswert?

Und hast Du dir auch schon mal überlegt wie Du am PC an die SD-Karte,
bzw. an die einzelnen Sektoren (512 Bytes) kommst?

von Peter B. (funkheld)


Lesenswert?

Ich habe den HXD-Editor, der kann die Datenblöcke lesen bzw sieht die 
SD-Karte auf der untersten Ebene.

Das hatte ich vor jahren mit einem Atmega32 und meinem Roboter gemacht.
Das Ding fuhr im Zimmer rum und habe mit einem Abstandssensor Daten 
eingescannt und am PC wieder ausgelesen mit HXD und einen Grafikumriss 
nach den Daten erstellt.

Gruss

: Bearbeitet durch User
von berndl (Gast)


Lesenswert?

hmmmm,

schreib' doch einfach das C-Programm in ein VHDL-Programm um. Ist doch 
eh' alles das selbe...

von Peter B. (funkheld)


Lesenswert?

Ja in NIOS wird es gehen.

Gruss

von Dirk (Gast)


Lesenswert?

Die Dateiendung von .c in .vhd ändern müßte doch schon reichen.

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.