Moin!
Hier ist mal mein neuer C Code für das ansprechen von MMC/SD Cards.
Neuigkeiten in der Version 2.0:
- Protokoll verbessert, so dass nun auch recht "zickige" Karten
unterstützt werden
- Read/Write Commandos wurden aufgesplittet in Start,
read_buffer/write_buffer und stop, so dass man nun auch in kleineren
Häppchen lesen und schreiben kann (weniger RAM verbrauch)
- Untersützung nun auch von SD Karten
- Beschreibung und Beispiele der Funktionen im Header File
- Unterschiedliche SPI Geschwindigkeiten für schreiben und lesen
- Macros um die Felder des CSD Registers extrahieren zu können
- u.a.
Viel Spaß beim Testen,
Stefan
Hi,
da ich gearde selber eine SD/MMC Karten Ansteuerung in assembler
schreibe, und ich aber nur eine 9 Polige SD Karte wie eine 7Polige MMC
angeschlossen habe, wuerde mich interessieren, ob es hier unterschiede
bei der Ansteuerung ( CMD0) gibt, da ich meine SD Karte nicht mich mit
CMD0 eine $01 entlocken kann.
gruß, Mirko
Hallo Mirko,
auch die SD Karte schickt ein $01 zurück, allerdings war es bei mir so
dass die SD länger gebraucht hat, musste die Anzahl der versuche etwas
hochdrehen. Schau mal in meinen Code in die Funktion mmc_init.
Stefan
Hallo,
Ich probiere schon seit einigen Wochen vergebens eine MMC-Karte
anzusteuern. Versuche mit verschiedenen LIBs haben leider nicht zum
Erfolg geführt. Das Problem ist immer das gleiche: Ich bekomme die
MMC-Karte nicht initialisiert. Scheint offenbar an der Hardware zu
liegen. Ich setze einen ATmega128 ein, der mit 16 MHz getaktet wird.
Spannungsversorgung: 3,3V
Die MMC-Karte habe ich auch schon ausgetauscht - was aber nicht
geholfen hat. Folgende 2 Karten habe ich schon ausprobiert:
Hama 128MB
Transcend 128MB
So langsam verzweifle ich. Mittlerweile ist schon der dritte
Anschlussadapter für die MMC-Karte in Verwendung. Die Kabellänge ist
jetzt auf 7cm reduziert - nichts geht.
Heute habe ich mal die MMC_LIB Version 2.0 verwendet. Die
Initialisierung bricht ab mit dem Rückgabewert: MMC_INIT().
Also klappt schon der Reset nicht. In ganz seltenen Fällen funktioniert
das Initialisieren mal, aber das scheint eher Zufall zu sein. Beim
Versuch einen Sektor zu lesen wird dann nämlich sofort wieder mit
Fehler abgebrochen.
Woran kann das liegen ? Einen Wackelkontakt kann ich ausschließen -
daran liegt es definitiv nicht.
Was kann ich noch versuchen um die MMC-Karte zum Arbeiten zu überreden
? Die Karte ist definitiv nicht defekt, da sie im PC-Cardreader
funktioniert.
Mir gehen langsam die Ideen aus. Ich bin für jeden Tip sehr dankbar.
Gruß,
Jogi
@ Joachim: Die SPI Geschwindigkeitseinstellungen hab ich mit einem
7.3728 MHz Quarz ausprobiert, also teste mal einen kleinern Quarz,
Deiner ist ja über doppelt so schnell !!
Und auf die Stromversorgungen achten, alle Vcc Anschlüsse schön mit
100nF Keramik abblocken. Wie erzeugst du die 3.3 Volt für die MMC ? Wie
wandelst du die Pegel MMC<-> AVR um ?
Und wie dave schon sagte: Zwischen Betriebsspannung EIN und mmc_init
aufruf etwas warten!
Stefan
Hallo,
Vielen Dank für die Tips. Ich habe jetzt eine kleine Wartepause zu
Beginn eingebaut. Das hat schonmal ein wenig geholfen. Die
Initialisierung klappt jetzt öfter als vorher. Das Hauptproblem ist
allerdings wohl tatsächlich die hohe Taktfrequenz. Diesen Aspekt hatte
ich bisher total vergessen. Klar: 16 MHz ist wohl etwas zu schnell.
Außerdem habe ich sowohl die MMC-Karte als auch den ATmega128 mit 3,3V
versorgt, um mir das Level-Shifting sparen zu können. Die 3,3V erzeuge
ich mit einem Linear-Regler: LM1086-IT3.3. Allerdings ist die Paarung
16 MHz Takt und 3,3V Spannungsversorgung ja laut Datenblatt auch nicht
gerade zulässig :-)
Ich denke mal hier sollte ich jetzt als erstes mal ansetzen. Ich werde
gleich mal einen anderen Quarz einlöten und sehen wie es dann aussieht.
Wahrscheinlich sind dann auch die sporadischen Abstürze weg, die immer
wieder zu beobachten waren. Die 100nF Blockkondensatoren hatte ich auf
meinem Testboard auch vergessen. Habe sie jetzt nachträglich
drangelötet.
Gruß,
Jogi
Hallo,
Also ich habe jetzt den Quarz ausgewechselt (16 MHz Osc raus, 8 MHz Osc
rein) und nochmals einige Tests durchgeführt. Leider immer noch das
gleiche Problem: Die Karte rührt sich nicht: Initialisierung klappt
nicht. Da ist absolut der Wurm drin. Ich habe nun mittlerweile 4
verschiedene LIBs ausprobiert, diverse Anschlussadapter gebaut - nichts
hilft. Auch mit dem Anschlussadapter mit Pegelwandler (Spannungsteiler:
1,5k, 2,7k)) und 5V Betrieb des ATmega128 tauchen die gleichen Probleme
auf. Ich gebe jetzt auf. Mit dieser Hardware ist das nicht zu machen -
ich muss ein neues Testboard bauen. Vielleicht diesesmal mit ATmega32.
Evtl. habe ich damit mehr Erfolg.
Der ATmega128 läuft ja sehr instabil - zumindest auf diesem Board.
Vielleicht ist die Platine schuld. Ich weiß es nicht. Es ist jedenfalls
extrem frustrierend. Ich zähle die verlorenen Stunden schon gar nicht
mehr ...
Gruß,
Jogi
Also, bei mir klappt es auch nicht,
nachdem ich nun die komplette Schaltung mit 3,3V laufen lasse, um mir
das level shifting zu spraren, klappt gar nicht mehr.
Ich bekomme die SD Karte nicht initialisiert.
Nach meiner Beschaltung habe ich folgende Pins in mmc_lib.h
eingetragen:
#define MMC_PORT PORTB
#define MMC_DDR DDRB
#define SPI_MISO PB6 //DataOut of MMC
#define SPI_MOSI PB5 //DataIn of MMC
#define SPI_CLK PB7 //Clock of MMC
#define MMC_CS PB3 //ChipSelect of MMC
Leider bleibt das ganze programm in der routine mmc_init() haengen,
wenn keine SD Karte drann ist, kommt nach c.a. 2 Minuten die
Fehlermeldung: MMC_INIT.
Die 8515 CPU ist okay, schon gegen eine andere getauscht. Tja, weis
nicht mehr weiter :(
Okay, so einfach gebe ich nicht auf,
in der Funktion spi_send_byte(unsigned char data)
bei dem Aufruf von:
loop_until_bit_is_set(SPSR, SPIF);
wartet er sich zu tode. Das Bit wird nie gesetzt, was koennte das
bedeuten ?
Hi,
@Mirko:
Ich bin gerade auch ein wenig mit einer MMC-Karte am spielen.
Bei mir ging die Init auch erst nicht und er hat sich beim
loop_until_bit_is_set(SPSR, SPIF);
totgewartet.
Ursache war bei mir, dass ich das CS von der Karte nicht auf den SS-Pin
vom SPI gelegt hab. Dann habe ich den SS-Pin explizit als Ausgang
konfiguriert und auf 0 gelegt, da gings prima... Vielleicht hilft Dir
das weiter.
Zur Zeit sitze ich dabei und versuche ein paar Daten zu schreiben, mal
schauen ob das klappt...
MfG
Daniel Jelkmann
Jo richtig, SS Pin muss auf Ausgang geschaltet werden, sonst hängt der
SPI. Also möglichst die Pins nehmen die in der lib schon vordefiniert
sind und bei anderen Controllern als den Mega128 SINNGEMÄßE Pins
verwenden (also MISO->MISO, MOSI->MOSI, SS->SS, SCK->SCK.
Viel Spaß weiterhin beim spielen.
Nun würde mich noch was interessieren: Unterstützen euere Karten das
lesen/schreiben von "gebrochenen" Blöcken, also <> 512 Bytes ? Das
kann man einfach mit den Makros MMC_CSD_READ_BLK_PARTIAL und
MMC_CSD_WRITE_BLK_PARTIAL rausfinden. Alle Karten die MIT bisher
untergekommen sind können partielles Lesen, aber kein partielles
Schreiben...
Stefan
Hi Stefan & Rest,
meine Karte (ist eine 128MB von extreme-memory) kann auch nur partiell
lesen. Schreiben geht auch nur per 512-Byte-Blöcken.
Allerdings hapert es bei mir gerade beim Lesen und Schreiben noch
gewaltig. Ich habe vom Rechner Daten auf die Karte kopiert und mir auch
den Karteninhalt als Rohdaten von der Karte kopiert (mit dem Befehl dd
unter Linux ;)).
Wenn ich nun per AVR lesen möchte, kriege ich aber nur andere Daten
(Schrott) raus. Initialisierung der MMC geht einwandfrei, die CID und
CSD kann ich auch problemlos auslesen. Der Lese-Befehl wird ohne Fehler
von der MMC-Karte bestätigt, aber die Daten stimmen nicht...
Beim Schreiben klappts garnicht. Ich kann zwar Schreiben, und der
Befehl wird auch wieder ohne Fehler von der Karte angenommen. Aber wenn
ich nun 512 Bytes geschrieben habe, wartet er ja nach einem 0xFE darauf,
dass die Karte nicht mehr busy ist. Und genau da hängt das Teil bei mir
in einer Endlosschleife fest...
Direkt nach dem 0xFE bekomme ich von der Karte ein dezimales 229, was
eigentlich sagt, dass alles ok ist (afaik). Aber es wird nichts
geschrieben und hängt in der Abfrage danach fest...
Hat jemand eine Idee, was das sein könnte? Wie sieht das mit externer
Beschaltung aus, muss an die MISO (Datenausgang aus Sicht der Karte)
ein Pull-Down oder sowas dran? Bin hier echt langsam am Verzweifeln.
Hab auch schon den Code von Ulrich Radig ausprobiert, same problem :(
MfG
Daniel Jelkmann
Hi,
Danke für den Tip mit /SS-Pin. Bei mir war das ebenfalls die Ursache
dafür, dass nichts funktioniert hat. Ich hatte auch einen anderen Pin
als Chip-Select für die MMC Karte verwendet. Außerdem war der 16 MHz
Quarz zu schnell. Hab jetzt, wie von Stefan vorgeschlagen, einen
langsameren Quarz (8 MHz) draufgepackt. Heute konnte ich nun endlich
mal die Partitionstabelle der MMC-Karte auslesen. Bisher kam da nur
Schrott.
Gruß,
Jogi
Jo, wenn du die SPI Teiler hochsetzt (also SPI Takt runter) sollte es
auch mit nem 16 MHZ Quarz gehen. Im Header File findest du
//Clockrate while initialisation reading writing
#define SPI_INIT_CLOCK 1<<SPR1 | 1<<SPR0
#define SPI_READ_CLOCK 0<<SPR1 | 0<<SPR0
#define SPI_WRITE_CLOCK 1<<SPR1 | 0<<SPR0
Dann mal das Datenblatt befragen was man nehmen muss damit man die
Geschwindigkeiten halbiert (bei doppeltem Quarz Takt). Die Werte sind
aber evtl noch keine "Grenzwerte", ich hab die einfach mal so
eingestellt und meine Karte ging. Man kann das auch aus einem Register
der Karten auslesen, hab mich damit aber noch nicht befasst...
Stefan
Weiß nicht was du gelesen hast, auf jeden Fall ist die Karte beim
schreiben immer langsamer! Wenn Deine Karte nun mit 4MBit/s lesen kann
kannst du den SPI Teiler bei einem 16 MHz Quarz einfach auf 4 setzten.
Vorsicht auch mit der INIT Geschwindigkeit, da können viele Karten auch
keine so hohe Geschwindigkeit ab!
Stefan
Soweit ich weiß muss man bei der SPI Geschwindigkeit nur beim Init
aufpassen, danach kann man ruhig auf volle Geschwindigkeit gehen. Takte
meinen AVR mit 18,432MHz, SPI mit F_CPU/2 und hatte da selbst mit son
paar uralten 32MB Karten keine Probleme.
Also einfach SPI Speed fürs Init ordentlich langsam machen und danach
maximale Geschwindigkeit.
Hi,
ich habe mein Problem jetzt endlich gelöst :-)
Es lag an den drei Dioden, die ich benutzt hatte, um von 5V auf um die
3 Volt zu kommen... Das scheint eine ganz wackelige Geschichte zu sein,
das Lesen ging damit manchmal, das Schreiben aber so gut wie nie...
Jetzt mit einem LM317 läuft alles perfekt.
Danke an Stefan für seinen Code (und alle anderen Beteiligten natürlich
auch)!
MfG
Daniel Jelkmann
Hi,
zu Testzwecken eignen sich dafür alte IDE-Kabel fürs Floppy (ich glaub
für die 5,25-Zoll-Laufwerke).
Der Pinabstand der Floppy-Buchse stimmt genau mit dem Abstand der
Kontakte an der MMC überein.
Ansonsten gibt es beispielsweise bei Reichelt passende Connectoren
(z.B. Artikelnr. CONNECTOR SD 21), sind aber nicht ganz billig.
Für Testzwecke klappt das mit dem Floppy-Kabel aber ganz gut, zumindest
werkel ich momentan damit rum.
MfG
Daniel Jelkmann
@ape
Wegen der SPI Geschwindigkeit, jo, INIT sollte auf jeden Fall recht
langsam sein, aber bei den ganzen Karten die ich hier rumliegen habe
muss auch das Schreiben langsamer als das lesen sein, sonst geht
nix...
@pebsoft
Sockel für MMC/SD Karten gibts sehr günstig bei farnell, die Preise bei
Reichelt sind etwas wucher...
Stefan
hallo, vielen dank. ich nehme den von reichelt, bevor ich durch
basteleien die mmc/sd-karte abfackele. bin nämlich anfänger in sachen
platine löten und anpassen.habe den spannungswandler gleich
mitgenommen
mfg pebisoft
Hallo,
verfolge die Diskussion mit der MMC/SD Ansteuerung schon eine ganze
weile, habe aber selbst noch nicht damit angefangen.
Meine Frage ist wie schnell die MMC/SD karte ausgelesen/beschrieben
werden kann.
Hatte gelesen das die Initialisierung etwas langsamer von statten gehen
muß, und man danach mit "full speed" lesen bzw. schreiben kann.
Meine Frage ist : Mit welcher Freq. kann ich max. die Karte auslesen
bzw. beschreiben ? Wenn ich mit 18 Mhz Takte, müsste ich doch etwa
einen durchsatz von über 1MB/sek haben oder ?
Das Schreiben eines Blockes braucht doch sicherlich mehr zeit als das
lesen, oder ?
Wie oft kann ich die MMC/SD Karte beschreiben ? Flash speicher lässt
sich ja ca 100000 mal beschreiben.
Sorry wenn die Fragen etwas wirr gestellt sind. Es sind auch eher
allgemeine Fragen, da ich die MMC/SD Karte auf mehreren Systemen
ansprechen möchte (MSP430/ARM7/FPGA) und erst beim FPGA wirds ja
richtig interessant von wegen Geschwindikeitsgrenzen.
Danke schonmal vorab.
Schau mal in ein Datenblatt einer MMC/SD Karte, da steht drin in welchen
Registern die max. Schreib- und Leserate ausgelesen werden kann. Die
maximal Geschwindigkeit ist also nicht fest, sondern hängt von der
jeweiligen Karte ab. Und bei allen die ich bisher in den Fingern hatte
geht schreiben nicht so schnell wie auslesen.
MfG
Stefan
Ich klink mich mal hier mit ein. Erstmal danke für die super Routinen,
nur leider funktioniert das bei mir nicht so ganz. Habe Probleme
einzelne Sectoren auszulesen. Wenn ich CMD17 sende kriege ich nicht mal
ein Startbit, bei CMD18 schon. Nur wenn ich dem Target dann Adresse 0
schicke, bekomme ich Sector 7 der Karte zurück.
Würde mich freuen wenn mich da jemand unterstützen könnte.
gruß Taylor.
Hi....
ich stehe erst am Anfang und möchte eine SD-Karte mit dem AtMega128
ansteuern. Wo gibs denn im Netz entsprechende Datenblätter zu
SD-Karten?
Vielen Dank für eure Mühe.
@Stefan,
was mir aufgefallen ist....
Du schreibst
<Zitat>
... auf jeden Fall ist die Karte beim
schreiben immer langsamer!
</Zitat>
In deinem sourcecode machst Du es aber genau umgekehrt!
<Cut>
#define SPI_INIT_CLOCK 1<<SPR1 | 1<<SPR0
#define SPI_READ_CLOCK 1<<SPR1 | 1<<SPR0
#define SPI_WRITE_CLOCK 1<<SPR1 | 0<<SPR0
</Cut>
Denn nach datenblatt des Mega128 Seite 167 Tabelle 72 (jetzt mal ganz
ohne SPI2X)
SPR1 + SPR0 gesetzt bedeutet oszilatorfrequenz/128
und nur SPR1 gesetzt ist oszilatorfrequenz/64.
Damit ist als schreiben doppelt so schnell wie das lesen?!
Hoppla, hab ich wohl das read und write vertauscht. Also am besten dann
mal selber rumprobieren. Da Clk/64 bei mir zum Schreiben funktioniert
kann man wohl noch wesentlich schneller lesen als ich im moment habe
:-)
Stefan
Hallo,
ich habe hier eine Schaltung mit MMC die ich in Assembler schon mal
programmiert hatte. Ich will jetzt das Ding in C haben.
Ich habe jetzt folgendes Problem:
Ich benutze WinAVR und bekomme beim compilieren immer diese Fehler:
mmc_lib.c: In function `mmc_init':
mmc_lib.c:45: error: `SPI2X' undeclared (first use in this function)
mmc_lib.c:45: error: (Each undeclared identifier is reported only once
mmc_lib.c:45: error: for each function it appears in.)
Hab ich da irgendwas mit dem makefile falsch gemacht?
Ich weiß jetzt das es daran liegt, dass der AT90S8535 kein SPI2X Flag
hat. Aber was muss ich jetzt an dieser Zeile ändern damit es
funktioniert?
SPSR = SPI_DOUBLE_SPEED << SPI2X;
(in der Funktion MMC_Init)
Danke
Maik
Hallo Stefan,
ich schreibe einen Block der größe 512 byte folgendermaßen an die
Stelle 1024:
unsigned char mmc_buf[128];
mmc_set_blocklen(512);
mmc_start_write_block(1024, 7);
mmc_write_buffer(&mmc_buf[0], 128);
mmc_write_buffer(&mmc_buf[0], 128);
mmc_write_buffer(&mmc_buf[0], 128);
mmc_write_buffer(&mmc_buf[0], 128);
mmc_stop_write_block();
Jetzt hab ich mit einem Kartenlesegerät und einem Hexeditor geschaut ob
alles stimmt.
Jedoch verstehe ich nicht warum er an die Stelle
1C000 - 1C1FF (in Dezimal 114688-115199) schreibt?
Macht es einen Unterschied ob ich mmc_start_write_block(1024, 7); oder
mmc_start_write_block(1024, 0); schreibe?
Vielen Dank
Grüße Tommy
Ich hab den Fehler gefunden. Ich hab die MMC jetzt im Hexeditor Physisch
geöffnet und siehe da, alles tut so wie es soll!
Danke für die schnelle Antwort per Mail ;)
Grüße Tommy
Hallo!
Ich habe die SD-Karte wie bei Ulrich Radig beschrieben, angeschlossen.
Die Karte wird gefunden, initialisiert und ich kann Blöcke/Sektoren
auslesen.
Eine Sache macht mir jedoch kopfzerbrechen:
Beispiel: Ich will Sektor 0 auslesen, bekomme nur 512x0 zurück. Das ist
ungleich des in Windows gelesenen Sektor 0. Wenn ich sektor 25 auslese,
erhalte ich genau Sektor 0, wie er in Windows ist.
(Ich lese den Sektor direkt von der Disk mit einer Software Namens
Runtime DiskExplorer, habe aber auch eine zweite versucht)
Beispiel: Ich lasse Sektor 512 mit 512x1F beschreiben.... in Windows
ist Sektor 487 mit 1F beschrieben, ich habe also sowohl beim Lesen
eines Sektor als auch beim Schreiben ein Offset von 25 sektoren....
Wo kommt diese Differenz her?
Hat jemand eine Idee?
Ich habe schon den Code von Ulrich Radig und diesen hier ausprobiert
und komme zu gleichem Ergebnis.
mfG
Moment, da ist jetzt aber etwas durcheinander oder lese ich das
richtig?
AVR WINDOWS
Sektor 0 -> 25 => Offset +25
Sektor 512 -> 487 => Offset -25
Ist das richtig gelesen/interpretiert?
@Tommy:
Vorsicht, wenn du 512er Blöcke verwendest musst du
mmc_start_write_block(1024, 9);
(also adrshift auf 9) nehmen! Mit 7 würdest du 128 Bytes größe Blöcke
ansprechen.
Stefan
Hallo Werner,
teilweise richtig:
AVR WINDOWS
Sektor 0 -> ???
Sektor 25 -> 0 => Offset 25
Sektor 512 -> 487 => Offset 25
Sektor 513 -> 488 => Offset 25
Also ich habe immer 25 Sektoren verschub.
Ich hoffe, mir kann das jemand erklären. Leider habe ich nur eine
SD-Karte von JVC zum testen.
mfG
Die Sektoren, die du mit dem AVR liest, beginnen beim Sektor 0 (also den
MBR).
Die Sektoren, die du mit dem "Windows" liest, beginnen nicht beim MBR
sondern beim Volume Boot Sector (VBR), also 25 Sektoren weiter.
Das passiert, weil deine Windows-Software anscheinend nur Partitionen
ausliest, und die beginnen mit dem VBR.
Um auch den MBR lesen zu können, muss anstelle der Partition der ganze
Massenspeicher als "Gerät" gelesen werden.
Hi,
ich muss mich hier auch mal melden :) Ich versuche nun seit Stunden
meine Sd Karten zum laufen zu brinen aber irgendwie wills nicht recht.
An dem Punkt an dem die Karte 0x01 zurück geben sollte kriege ich:
Pretec 64mb : 0x00
Sandisk 512mb : 0x00
Sandisk 1gb : 0xff
Immerhin ist die Antwort der verschieden Karten immer dieselbe,
desshalb also kein Wackelkontakt oder derartiges ;-)
Hat irgend jemand noch eine Idee?
mfg Nik
Mist, hab noch vergessen zu sagen:
GCC 3.4.3, Atmega8, Schaltung nach Ulrich Radig, mmc_lib.h bearbeitet,
und eine Timingproblem kanns kaum sein, ich verwende die internen
1mhz,
zudem Warte ich vor mmc_init() ungefähr 100ms.
Lieferst du der Karte vernünftigen Strom ? Bei mir wollten einige auch
nicht mit dem Diodenkraftwerk arbeiten, das taugt nix. Bitte LM317 oder
anderen Festspannungsregler verwenden!
Stefan
Oh ja das hatte ich vergessen, das ist die einzige Veränderung die ich
gemacht habe, Regler mit 2 Kondis ist drann. Mit "Nach Ulrich Radig"
meinte ich nur die Widerstände. Hab auch noch mal nachgemessen, da
kommen in etwa 3.34 Volt raus:)
Ich hab nun meine Zweite 1gb Sandisk angehängt und es ist genau dasselbe
mit ihr, ich bekomm da auch 0xff zurück. Naja, wenigstens ein
Lebenszeichen von den Dingern. Dennoch, laut dem Datenblatt müsste bit
7 immer 0 sein bei der R1 Response, folglich sollte ich auch kein 0xff
bekommen...verflixt :(
Langsam gehen mir echt die Ideen aus, ich hab nun praktisch alle mmc
sourcen ausprobiert, die ich finden konnte. Die von Ulrich, Holger
Klabunde, die von mikrocontroller.net und auch noch
http://www.captain.at/electronic-atmega-mmc.php
Bei letzterem scheint es zu funktionieren(sollte einen Sektor auf die
Karte schreiben), allerdings wenn ich mir die Karte mit Winhex
anschaue, dann ist da gar nichts passiert. Scheint fast, als ob alle
meine Karten einfach nicht funktionieren würden. Die 256mb von Sandisk
gehen ja anscheinend, aber weiss jemand über die 512mb und 1gb
Bescheid?
Hast du denn mal eine kleinere Karte getestet ?
Ansonsten was mir gerade so einfällt:
Hardware sauber (Blockkondensatoren etc)
Fusebits ok ? (JTAG usw)
SS Pin für CS benutzt, oder zumindest SS auf Ausgang gestellt ?
SPI Clock langsamer stellen ?
Versorgungsspannung für die Karte stabil (Oszi !) Ich hatte mal einen
LM317 verkehrt angeschlossen, die 3.3V waren zwar da, aber sobald die
Karte initialisiert wurde ist die Spannung eingebrochen...
ISP Programmer der hochohmig ist wenn nicht programmiert wird! (Hängt
mit der MMC am SPI Bus)
Mach vielleicht mal ein Bild von dem Testaufbau, vielleicht sieht man
da was...
Stefan
Danke für deine Antwort
Hab zuerst auch gedacht es sei Jtag, allerdings benutze ich einen
atmega8, musste feststellen, dass der das sowiso nicht hat:(
Den SS Pin hab ich auch als CS und die spi geschwindigkeit sollte
eigentlich genug langsam sein(interner 1mhz takt + Vorteiler aus deinen
mmc funktionen) Ob die Versorgungspannung stabil ist kann ich leider
nicht überprüfen, da ich kein Oszi besitze. Allerdings verwende ich
keinen lm317, sondern einen 'Ba033', der macht die 3.3V direkt und
benötigt bloss zwei elkos. Den Isp zieh ich sowiso meist ab wenn ich
teste-ich hab die version mit 3 widerständen.
Deshalb hab ich nun mal ein paar Fotos gemacht, vielleicht erkennt man
in dem Getummel ja etwas :). Sorry die Qualität ist leider teilweise
mies, da es so dunkel ist, ich mach dann morgen evtl neue...
mfg Nik
Das wird langsam echt extrem deprimierend. Ich habe nun alles noch mit
einem atmega32 von Neuem aufgebaut, immer noch geht rein gar nichts.
Ich glaube langsam mit meiner sd-beschaltung ist was nicht in
Ordnung.Ich hab mal ein Bild nur von der SD Beschaltung gemacht,
irgendwie meine letze Hoffnung das da noch was geht, vielleicht kann
mir ja jemand helfen.
mfg Nik
p.s. unter den grünen(1.8k) widerständen ist die Leiterbahn getrennt.
Hi ich bin gerade dabei eine MMC karte an meinen ARM an zu schließen und
benutze dafür deinen code als Referenz.
Warum benutzt du nicht CMD16 um die block size zu setzen? Ist die block
size nach der initialisierung standardmäßig 512 oder wie?
@Nik,
Gegenprüfen:
Anschluss 1 der MMC/SD (nach Foto) ist /CS (ChipSelect)(ATmega32-PB4)
Anschluss 2 ist SI (Serial In) muss an MOSI des MCU (ATmega32-PB5)
Anschluss 3 ist GND
Anschluss 4 ist Vcc (3,3V)
Anschluss 5 ist SCK - an SCK (ATmega32-PB7)
Anschluss 6 ist GND
Anschluss 7 ist SO (Serial Out) muss an MISO des MCU (ATmega32-PB6)
ATmega32 -
MOSI = PB5 (Pin 6 bei PDIP, 1 sonst) - Anschluss 7 der MMC/SD (Foto)
MISO = PB6 (Pin 7 bei PDIP, 2 sonst) - Anschluss 2
SCK = PB7 (Pin 8 bei PDIP, 3 sonst) - Anschluss 5
SS = PB4 (Pin 5 bei PDIP, 44 sonst) - Anschluss 1
PB6 MUSS als Output definiert werden, auch wenn ein anderer Pin am
MMC/SD den CS erledigt.
Danke für die Bemühungen :-)
Ich bin mir nun nicht ganz sicher was richtig ist, du widersprichst dir
ja in gewisser Weise:
Anschluss 7 ist SO (Serial Out) muss an MISO des MCU (ATmega32-PB6)
Anschluss 2 ist SI (Serial In) muss an MOSI des MCU (ATmega32-PB5)
und
MOSI = PB5 (Pin 6 bei PDIP, 1 sonst) - Anschluss 7 der MMC/SD (Foto)
MISO = PB6 (Pin 7 bei PDIP, 2 sonst) - Anschluss 2
PB6 MUSS als Output definiert werden, auch wenn ein anderer Pin am
MMC/SD den CS erledigt.
Ich habs so wie in der oberen der beiden Beschreibungen, also
SO -> Miso
SI <- Mosi
Den Pin SS setze ich auch auf Ausgang, obwohl ich für /Cs einen anderen
pin verwende. Im Zweifelsfalle werde ich einfach mal SI an mosi und so
an Miso anschliessen und sehen was dann passiert...
Mittlerweilen konnte ich noch eine 'normale' Mmc anstatt einer Sd
karte testen. Dabei handelte es sich um eine 32mb grosse noname mmc,
die normalerweise bei nokia mitgeliefert werden. Hat allerdings auch
nicht geklappt damit :(
ja also ich hab nochmals alles nachgemessen.
mit Karte ein / ausgesteckt beide Male exakt 3.34V. Dann bei wenn ich
z.B. SCK am uC manuell auf 1 schalte dann hab ich hinter dem
spannungsteiler auch ~3.3V. Auch die Kontakte vom Kartenhalter bis zur
Platine hab ich durchgemessen, nirgends ein Wackelkontakt. Was noch
sein könnte ist, das die Kontakte bei eingesteckter Karte nicht
wirklich Kontakt zur Karte kriegen. Leider kann ich das bei eingelegter
Karte nicht sehen... Nun wenn bei dir die Nokia Karte geht dann weiss
ich wirklich nicht mehr was sonst noch falsch sein könnte. Mittlerweile
hab ich wieder Ulrich's Code angeworfen, da da gleich noch eine main.c
dabei ist, um auch dies als Fehlerquelle ausschliessen zu können.
Beinahe unvorstellbar aber möglich wäre auch meine Taktquelle für den
Atmega. Ich verwende immer noch den internen 1mhz R/C oszilator. Ich
werd mal nen 8mhz Quarz ranschnallen, vielleicht hilfts, obwohls doch
schon sehr merkwürdig wäre. Nach den SD specs kann man ja so langsam
auf die Karte zugreifen, wie man will ;)
MOSI (PB5, Pin 6 bei PDIP, 1 sonst) muss an Anschluss 2 (Serial IN der
MMC/SD), denn der AVR ist der Master. Master Out -> Slave IN.
und
MISO (PB6, Pin 7 bei PDIP, 2 sonst) muss an - Anschluss 7 (Serial Out)
der MMC/SD (Slave Out -> Master In).
Immer "Master Out" des Master and "Master IN" des Slave und
"Master IN" des Masters an "Slave out" des Slave.
So funktioniert es zumindest (Reproduzierbar) bei meiner Schaltung
hier.
HAMA SD 128MB. Gab es einmal hier bei einen lokalen Händler als
Sonderangebot. Hatte aber auch schon so ein billigts 512MB SD
(CnMemory) aus meinem Palm ohne Probleme in Betrieb.
Eine 512MB HAMA SD aus der Kamera tut aber leider nicht :(
hmm ich glaub ich bin wirklich nicht gerade ein glückspilz
512mb sandisk > geht nicht
1gb sandisk > geht nicht
64mb pretec > geht nicht
32mb nokia dinger > geht nicht
Fehler in der schaltung kann ich mitlerweiler echt 100%-ig
ausschliessen und an der Software kanns ja auch keim liegen, diese
scheint ja zu funktionieren :-). Hab gestern ne 256mb hama gesehen, ich
werd mal so eine 128mb suchen, wenns die dann auch nicht tut...
also vielleicht ist das nun was...Ich hab kein Oszi, deshalb kann ich
das auch nicht genauer prüfen. Das einzige was ich kann ist eine
Frequenz messen(Metex M-3660D hab ich). Diese wird ungefähr alle 500ms
gemessen und angezeigt. Nun, wenn ich messe während der uC über spi
programmiert wird, dann kriege ich in etwa 3.5khz. Wenn ich allerdings
messe, ob der uC überhaupt was macht auf dem spi(ohne spi adapter
angeschlossen!), dann gibts da gar nichts. Klar, könnte sein dass das
ganze so schnell ist, dass mein messgerät davon gar nichts mit
bekommt.
Ich finde es allerdings doch relativ merkwürdig, da das Programm ja
durch etliche while Schleifen läuft. Und selbst bei 1mhz prozzi takt
sehe ich auf der Clk Leitung beim spi einfach gar nichts. Nun gibts
beim mega32 ja auch kein fusebit, welches den spi deaktivieren
könnte?!
Und die Sourcen sind diejenigen von Ulrich, woraus Stefans sourcen
abgeleitet sind-sprich die sollten mit einem mega32 ja
funktionieren...irgendwie ist da einfach total der Wurm drinn:(
Hat einer mal versucht das CID aus zu lesen?
Bei meiner Nokia karte ist "product name" einfach "000000" - wie
langweilig ;(
Weiss einer wie das Datum da gespeichert wird? in der hitachi doc
steht, dass das Datum irgendwie in einen byte drin ist (wie das???).
Ach hab noch was vergessen... Bei meiner karte scheinen die ersten 64
sektoren standardmäßig leer zu sein (teilweise steht da irgendwas
drin), also die ersten 32768 bytes auf der Karte. Ist das normal? was
ist das für ein Bereich? Oder hat windows das gemacht? Danach fängt
scheinbar die Partition an mit "MSDOS5.0" usw....
Ich hab mir das gerade mal angeschaut und mit zwischen hd/sd die
Unterscheide angeschaut.
Der MBR auf der Hd hat den Bootloader (erste 446 bytes) drauf, die sd
irgendwie nicht. Mir erschien der erste Sektor deshalb auch beinahe
leer, allerdings ist da die Partitionstabelle dennoch drauf, wobei der
erste Beitrag mich dann auf sektor 249 verwiesen hat. Dort beginnt
auf meiner SD auch tatsächlich die erste Partition in der Art wie du
das beschrieben hast. Bei mir waren alle Sektoren dazwischen auch leer.
Nun bei der meiner Festplatte beginnt die erste Partition bei Sektor
63(oder 64, je nach dem ob man den ersten als 0 oder 1 zählt. Somit
kanns sehr gut sein, dass bei deiner Karte in den ersten 64 Sektoren
nichts, oder beinahe nichts drinn ist ;-). Zum Thema master boot Record
und Fat hab ich mir übrigens diese Seite mal angeschaut, ist wirklich
wunderbar(und mit grafiken) erklärt
http://www.pjrc.com/tech/8051/ide/fat32.html
Ich hab damit schon für eine ata platte die Fat funktionen selbst
geschrieben, nun möchte ich es auch mit einer Sd versuchen(zwecks
lerneffekt)
mfg und gute Nacht :)
@Nik Bamert,
Sind denn SS, SCK und MOSI auf Output und MISO auf Input programmiert?
Das macht SPI nicht (vollständig) automatisch.
DDRDB |= (1<<PB7)|(1<<PB5)|(1<<PB4);
DDRB &= ~(1<<PB6);
@Lupin
Nein, die will leider immer noch nicht :-(
@Werner B.
Ja sind sie alle,
MMC_Direction_REG &=~(1<<SPI_DI);
MMC_Direction_REG |= (1<<SPI_Clock);
MMC_Direction_REG |= (1<<SPI_DO);
MMC_Direction_REG |= (1<<MMC_Chip_Select);
MMC_Direction_REG |= (1<<SPI_SS);
Dazu im Header :
#if defined (_AVR_ATmega32_)
#define SPI_DI 6
#define SPI_DO 5
#define SPI_Clock 7
#define MMC_Chip_Select 3
#define SPI_SS 4
#endif
Sollte so eigentlich alles hinhauen, ist direkt aus Ulrichs Sourcecode.
Allerdings hab ich wider was neues beobachtet...Ich hab mir einfach mal
alle Antworten der Karte über die Serielle rausgelassen. Nun bei der
Pretec und der 512mb Sandisk kommen da nur 0x00. Bei der 1gb Sandisk
allerdings andauernd 0xff (?) Das 0x00 dürfte aber erst nach cmd1
kommen und ich hänge damit schon nach cmd0 fest(antwort auf cmd0 ist
immer 0x00 oder 0xff). Mein Programmieradapter ist immer abgezogen wenn
ich die Karte teste, daher kanns nicht kommen:( Ich versuchs nun nochmal
mit Stefans Code, werde dann berichten ;)
geh mit der betriebsspannung auf 3.3v und nimm deine teiler weg. wenn es
dann immer noch nicht funktioniert weisst du wenigstens das es nicht
daran gelegen hat
ok daran lags leider auch nicht :(
Karte ists nicht-deine Nokia geht ja(?)
Spannungsteiler ist es nun auch nicht mehr
Stromversorgung auch nicht
Software auch nicht(benutze nun wider Stefans Version)
Ich hab mal maine main.c zu Stefans Lib angehängt...
Ja die Funktion gibt zwar schon nur ein 0x00, 0x01 oder ähnliches aus,
aber mein Terminal zeigt sowiso alles auch noch im hex format an, aber
danke für den Tipp, mit +'0' kriege ich die Zahl nun auch im ascii
format, ist schon besser lesbar so :)
Könnte es evtl noch an der Kabellänge liegen? Sind etwa 5cm mmc<->uc...
OH MANN!!
Ich war doch tatsächlich 2 Tage in dem Glauben das Teil würde nicht
funktionieren, da die Response 0x00 war! Doch Stefans mmc_lib.h sagt
ja
// Result Codes
#define MMC_OK 0
#define MMC_INIT 1
#define MMC_NOSTARTBYTE 2
#define MMC_CMDERROR 3
#define MMC_TIMEOUT 4
ARGHHH!!
Naja ich denke es sollte klappen, nur geht das mit dem Auslesen eines
Sektors noch nicht ganz... Vielen Dank dennoch an alle die mir geholfen
haben, nicht zulezt hat mich
>Liefert denn mmc_init() einen ASCII-character zurück?
dies dazu bewegt die mmc_init(); von Stefan mal genauer zu
untersuchen... :)
Habt ihr eine idee wie weit "partial reads" verbreitet sind? Ich hab
die Erklärungen im hitachi datenblatt so verstanden, das ich durch
partial reads einen teil eines sektors auslesen kann (auch nur 1 byte
wenn ich das will) aber man darf nicht in einen anderen Sektor "rein
lesen".
Unterstützen alle MMC karten partial reads oder eher weniger?
Das Partial Read geht bei den meisten Karten, allerdings kann man nicht
über die 512er Grenzen hinweg lesen. Ich nutze z.B. eine Blockgröße von
32 Bytes für einen MP3 Player mit dem VS1011, der will nämlich immer 32
Byte-Stückchen haben.
Das Schreiben von Blöcken <> 512 Bytes unterstützen allerdings die
allerwenigsten Karten!
Wegen der Formatierungsgeschichte:
Hier ist ein Tool, das einen MBR-Block erzeugt.
http://www.mikrocontroller.net/forum/read-4-256520.html#new
Damit kann man bis zu 4 Partitionen auf einer Karte anlegen (wobei die
meisten Kartenleser aber nur die erste lesen können). Ich benutze bei
einem Gerät eine MMC die eine FAT Partition hat, dahinter ist dann noch
ein anderes propriäteres Dateisystem, in das ich mit dem AVR schreibe.
Stefan
Mir ist gerade was komisches aufgefallen... Ich habe bis jetzt ein
einfaches FAT16 implementiert und von der MMC eine 8 bit sound datei
bei 44100 Hz ausgegeben, also schon ein recht hoher Datendurchsatz. Bei
meiner 32 mb karte funktioniert das wunderbar (die aus meinem nokia
handy), bei einer 512 mb karte hört sich der sound aber leicht
verzögert an!?
Ich betreibe die SPI schnittstelle nur mit 7.5 Mhz (weil der 2106 nicht
mehr macht). Die einzigste Stelle wo die Karte mein programm ausbremsen
kann ist ja wenn man die lese-operation startet und auf das start
zeichen wartet.
Bei einer MP3 müssen doch auch ziemlich viele Daten transferiert
werden, wie hattest du da schon mal probleme mit langsamen MMC karten?
Ich hab irgendwo mal gelesen das jemand meinte auf einen LPC könnte man
die MP3 auch in software decoden... wenn mein test schon so lahm ist
wird das wohl nix -_-
Ich bin mir nicht sicher wie man das mit der 8 bit sound datei genau
berechnet aber wenn ich das recht sehe:
falls sie mono ist 8bit ->1byte 44.1khz * 8 -> 352.8kbit/s, wenn sie
stereo ist sogar doppelt so viel FALLS ich das richtig rechne so.
So eine standard mp3 ist ja meist irgendwo zweischen 128...240kbits,
sollte also kein Problem sein denke ich mir.
Belehrt mich eines besseren, wenn ich falsch gerechnet habe :)
Soo, ich hab nun etwas gebastelt :-)
MP3 Player mit einem mega8 und vs1001k. Ich hab im Anhang mal ein Bild
angehängt. Die Sourcen möchte ich noch nicht posten, da ich noch null
und nix von einer Navigation programmiert habe. Im moment muss ich noch
im sourcecode angeben welche Datei geöffnet werden soll. Werde es in der
nächsten woche wenn möglich verfeinern und falls dann jemand Interesse
am Code hat, kann ihn hier oder in einem neuen Thread auch gerne
Posten. In diesem Sinne vielen Dank an alle die mir hier geholfen
haben. Nicht zuletz natürlich Stefen, danke für die super lib :P.
Vorerst wollte es nicht ganz klappen, nun läuft die Karte bei mir 16
mal schneller als sie im .h File zuerst eingestellt war. /8 clock
divider und double speed.
Läuft nun allerdings mit der Geschwindigkeitserhöung super :-)
mfg Nik
Hi nik, das ist ja echt süß! Das hast du ja echt schön zusammengefaltet
:)
Welche FAT firmware benutzt du denn? Und wo hast du die Platine mit den
vs1001k her?
Jetzt hab ich auch irgendwie lust einen mp3 player zu machen, ich würde
den dann aber in smd only bauen :)
danke :)
Die Fat Sourcen habe ich selbst geschrieben und die Platine habe ich
von Andreas Auer(auch hier im Forum). Er hatte letztes Jahr eine übrig
und hat mir diese darauf verkauft :) Vielen Dank auch an ihn, ohne das
Platinchen gienge schliesslich gar nichts;-)
Smd only fände ich eigentlich auch hübsch, nur habe ich bis jetzt noch
keinen Ort gefunden, wo man Platinen in der Schweiz zu vernünftigen
Preisen ätzen lassen kann. Aber in den nächsten Ferien hab ich mal
wieder ein bisschen Zeit, um die Toner methode mit dem Bügeleisen aus
zu probieren:P Dann kann ich auch endlich meine ersten Gehversuche mit
Smd löten machen hehe.
Eine weitere Beszugsquelle für die Platine wäre übrigens www.jelu.se.
Habe aber mit dem Shop allerdings noch keine Erfahrungen...
Hallo
ich habe ein system fertig mit einem ATMEGA8 un eine 128MB SD-Karte
Ich kann Schreiben und lesen mit einem eigenem Dateisystem
nun brauche ich, um die vom mikrokontroller gespeicherten werte
verwenden zu können ein Dateisystem
den ich muss für meine schule ein messgerät entwickeln welches werte
auf eine sd/mmc karte speichert
hat jemand vorschläge bzw. ein Beispielprogramm??
MFG
Manuel Plainer
Von microsoft gibt es eine sehr gute Dokumentation über das FAT
dateisystem, wenn du das implementierst solltest du mit jedem Computer
der einen Kartenlese hat die Karte auslesen können.
Wenn du das nicht selber machen willst findest du bestimmt einige
fertige implementationen...
Ja, ich wäre auch interessiert mir den code mal an zu schauen, ich
schreibe momentan selber FAT code, ich würde gerne wissen ob/wie du das
mit der FAT tabelle gelöst hast... Bei meinem code wird eine
"komprimierte" FAT tabelle (nur den Teil der Datei die geöffnet
werden soll) beim Öffnen der Datei in den RAM geladen so das man nicht
immer bei einem cluster wechsel den entsprechenden Sektor aus der FAT
tabelle lesen muss (mit partial reads wäre das wohl noch einigermaßen
erträglich, aber ich weiss nicht wie ich meinen code anpassen soll, so
das er wirklich alle features der Karte ausnutzt, das wären ja einiges
an if-abfragen und 1000 mal den gleichen code in unterschiedlichen
Versionen -_-)
Also ich mache das im Moment so, dass ich jedesmal in der Fat Tabelle
den gewünschten Wert hole. Für meine Applikation als Mp3 player reicht
das anscheinend bei weitem. 320kbits mp3's gehen noch, also scheint
das Ding mit min. 40kbyte/s lesen zu können. Ich hab dazu nun mal meine
fat.c und .h angehängt. Allerdings, wie gesagt es ist noch nicht fertig
das nette Dateichen :). Ordnerwechsel geht, Dateien mit fopen öffnen
auch, allerdings sollte ein Ordner dabei nicht länger als ein Cluster
sein...werde ich später noch korrigieren. Ausserdem stimmt irgendwas
bei meiner Rechnung mit fread nicht. Bis zu einer Dateigrösse/position
in einer datei von 32768 geht alles noch gut. Es liegt allerdings nicht
daran, wie ich die Clusterkette ablaufe, sondern irgendwie an der
Berechnung am Anfang. Werde ich alles korrigieren wenn ich mal Zeit
habe. Im Moment gehen leider auch noch keine langen Dateinamen und man
muss den Namen einer Datei kennen, um sie zu öffnen. Ich habe eine
kleine Funktion getentry(), mit welcher man sich die Einträge mit Namen
zuerst holen kann, damit gienge es auch 'ohne' den dateinamen zu
wissen. Sprich lies datei1 2 3 .. etc.
Handelt es sich bei der selektrierten Datei um eine gelöschte oder
oder einen langen Dateieintrag, dann sollte sie 0 zurückgeben,
ansonsten den Cluster. Wie gesagt noch alles ein bisschen 'verbuggt'
aber zum Durschauen sicherlich nicht schlecht, da ich teilweise auch
Kommentare reingeschrieben habe.
Im zip ist auch noch eine main.c und einige Uart funktionen, damit
>sollte< es auf einem atmega8 eigentlich laufen :-)
Und ja, nicht erschreken, avrgcc macht immer so schön bunte Warnings,
teilweise weis ich nicht wie ich diese beheben soll. Allerdings geht
das Prog so wie es ist bei mir ;) der SS-pin ist bei meinem code /cs
der mmc...
musst du den SS pin nicht dem SPI zuweisen damit der SPI überhaupt
funktioniert? Dann kannst du den ja nicht mehr als GPIO pin für /cs
benutzen... oder?
Der SS Pin muss einfach als Ausgang eingestellt sein, damit der spi im
master mode läuft. Aber den kann man ruhig für /cs verwenden :), klappt
bei mir einwandfrei. Was ich noch sagen wollte...
mein Ziel ist es am Ende eine schöne fat.c zu haben mit fopen();
fread(); etc, in leicht abgewandelter Form. Meine main vom Testprogramm
für meinen mp3 player ist jetzt schon sehr simpel:
[c]
.
.
.
int main(void){
uint32_t handle;
mmc_init() //sd init
fat_init();//Fat Init
vs1001_init_io();//mp3 decoder init
vs1001_init_chip();//nochmals
handle = fopen("SONGNAMEMP3");//file öffnen
fplay(handle);//abspielen
while(1){
}
}
Warum ist dein fopen() funktion so komisch? Ich mach das so, das ich mir
eine position (sektor nummer) speichere die auf das momentane
verzeichnis zeigt das geöffnet ist und dann einfach durch browse... hab
die fopen() funktion von dir nicht ganz kapiert.
Aber bei fread() ist ein Fehler, am Anfang addierst du zwar die start
position aber folgst dann nicht der cluster chain.
Dein code scheint ziemlich anders von meinen zu sein... meiner ist
irgendwie viel länger :-(
Bei meinem gehen bisher FAT tabelle für lesen, aber nicht fürs
directory browsing (da hab ich bis zu deinem posting gar nicht dran
gedacht :)), dann hab ich noch stream funktionen mit denen ich einen
stream öffnen kann und dann mit einer Funktion jeweils ein byte lesen
kann.
Beim öffnen der Datei speichere ich die Segmente der Datei in den RAM
(ein array von: cluster begin + anzahl der darauf folgenden cluster
werten).
Ich glaube mein Code könnte auch ohne 512 byte buffer auskommen... nur
geöffnete Dateien verbrauchen viel Platz. Demnächst werde ich auch mal
meinen Code hier veröffentlichen.
Die ist eigentlich ganz einfach: Man übergibt ihr einen Dateinamen mit
11 Zeichen (8byte kurz name wie bei dos früher + 3 byte endung, und
OHNE den punkt, also eigentlich genau so wie sie in den file einträgen
drin sind) Dann gibt einem die funktion entweder einen Startcluster
oder eine null zurück.(wenn die Datei nicht gefunden wurde).
Und doch, der Clusterchain folge ich auch dort. Zeile 150:
Cluster = followClusterChain(Cluster);
Irgendwie muss der Fehler woanders liegen...
Also, ich muss zur Schule :-(
verstehe ich nicht, das sieht nicht so aus als ob du der cluster chain
folgst:
uint32_t ClusterToReadFrom = handle +
((start/512)/sectors_per_cluster); //Wird benötigt um weiter zu zählen
Wenn du die funktionen nach den stdio definitionen definierst kannst du
bei anderen Compilern probleme bekommen... WinARM meckert da rum weil
ich standard funktionen neu definieren will :-(
Arggh :D Ja klar ich Idiot :D Ich folge zwar beim reinen Einlesen der
Daten schon der Cluster chain, allerdings nicht am Anfang bei der
Berechnung des ersten Sektors. Warscheinlich könnte man dies mit einer
kleinen For schleife erledigen. Denn ClusterToReadFrom enthält ja den
Cluster als Zahl, 'erster cluster, zweiter cluster..' Somit müsste
man nur FollowClusterChain entsprechend viele Male aufrufen. Muss ich
mal schauen wie ich das hinkrieg :-)
"Wenn du die funktionen nach den stdio definitionen definierst kannst
du
bei anderen Compilern probleme bekommen..."
falls du das uint32_t meinst, ich habs irgendwie einfach nicht kapiert,
warum ein long nicht 32 bit hatte, das war für mich einfach irgendwie
nicht logisch...wenn bei WinARM unsigned long 32 bit hat sollte es so
klappen, aber bei WinAvr scheint man für die 32bit ja einen unsinged
long long zu brauchen...komische Sache.
Ich dachte mir immer:
char - 8 bit
short - 16 bit
long - 32 bit
long long - 64 bit
Naja, scheint nach der inttypes.h alles ein wenig anders zu sein, daran
kann ich mich schlicht nicht gewöhnen :-)
Hallo alle zuammmen!
Im bin im Zuge meines Projektes (µP System speichert auf SD-Karte) in
dieses Forum gekommen. Ich stehe vor einem Problem, mit dem ich alleine
anscheinend nicht fertig werde. Ich schaffe es nicht, mehr als 32MB der
Karte (128MB größe) zu verwenden und kann somit pro Cluster (2k) nur
512byte ansprechen. Kannst mir bitte jemnand bei der Lösung des
Problems weiterhelfen, kann diese nötigen Infos über die Adressierung
aus den bereits vorhanden Programmen (Ulrichs, Seegel) nicht rausfinden
konnte. (Programmiere in C)
Ein paar erklärenden Sätze wären echt super!
Danke, Hannes
>Ich schaffe es nicht, mehr als 32MB der>Karte (128MB größe) zu verwenden und kann somit pro Cluster (2k) nur>512byte ansprechen.
Du musst eine Karte generell in 512er Blöcken lesen! Der jeweils zweite
Parameter in den Startread/startwrite Funktionen meiner lib sollte daher
immer auf 9 stehen. Warum du über 32MB nicht lesen kannst weiß ich
nicht, wenn du als Blocknr. z.B. 65536 nimmst und Shift auf 9, sollte
das genau an der Stelle von 32MB sein.
Vielleicht gibst du noch ein paar mehr Informationen, benutzt du FAT ?
Welche FAT ? Sourcecode ?
Stefan
@Stefean
Hallo. Danke für deine Antwort. Ich hatte ein Problem mit dem shiften.
Ich wusste nicht genau warum 9 weitershiften, hab alles noch einmal
durchgedacht und jetzt ist es klar (die 521 pro sektor!) Ich habe
deswegen dann auch Fehler bei der Adressierung gemacht. Jetzt klappt es
und ich kann endlich ans FAT-DAteisystem ran.
Danke für die Hilfe,
Grüße, Hannes
Hallo,
ich versuche eine SD-Card auszulesen. Das Initialisieren und das CID
und CSD auslesen funktioniert.
Meine Frage jetzt: Wenn ich jetzt keine FAT-Unterstützung haben möchte
und die Karte sequentiell auslesen möchte (ein Byte nach dem anderen)
wie muss ich dann die Karte adressieren?
Auszug:
...
mov cmd_0, #51h
mov cmd_1, r3
mov cmd_2, r2
mov cmd_3, r1
mov cmd_4, #00h
mov cmd_5, #FFh
...
acall SD_WRITE_COMMAND
...
inc r1
if (r1==0) inc r2 und so weiter...
stimmt das?
Eine Menge interessanter Informationen, die ich hier gefunden habe -
auch wenn ich (bisher) gar kein Problem mit meiner SD-Card hatte. Aber
vielelicht treten die ersten Probleme aus, sowie ich ne andere Karte
ausprobiere. Dann habe ich eine Menge Anhaltspunkte.
Also Danke und von mir meine Erfahrungen zurueck ans Board:
Konfiguration:
ATMega128 mit 14.7456MHz (CharonII-Modul, falls das jemand kennt, hat 4K
EEprom, 10MBit Netzwerkkontroller und 32K Ram)
1.0GB SD-Card von Toshiba
Die SPI läuft mit halbem Prozessortakt (also theoretisch fast 8MHz =1
MB/s)
Die Karte laesst sich ansprechen und auch beim Datentransfer scheint es
keinerlei Probleme zu geben.
Effektive Lesedauer von 1MB sind 2.2s, beim Schreiben 5.7s.
Sooo schnell scheint das aber auch nicht zu sein, sonst wuerden haetten
die alten Digitalkameras zum Speichern von nem kleine JPG ja Ewigkeiten
gebraucht. Wuerde mich wundern, wenn eine halbwegs aktuelle Karte nicht
mit 8MHz-Takt zurechtkaeme.
Verwendet habe ich als Ausgangsbasis den Code von Ti fuer ne MMC am
MSP430F1232 Prozessor - lediglich die Init- und Sendroutine musste ich
austauschen.
Damit dauerten die Transfers allerdings noch 5.7s und 9.6s
Inwieweit die Schreibfunktionen allerdings wirklich stabil laufen, kann
ich nicht sagen, ich sitze erst seit einem Tag dran. Ausswr den
RAW-Routinen existiert noch nix (das Filesystem wird proprietaer, da als
lineare Datenbank verwendet) und da das Layout anscheinend okay ist,
muessen weitere Basteleien/Codereien erstmal warten.
Zur Hardware: der ATMega laeuft an 5V, die Karte an 3.3V. Die
Datenleitungen gehen jeweils über eine BAT42-Diode und haben an der
Input-Seite nen Pullup zur jeweiligen Betriebsspannung. Das trennt die
Spannungen sauber.
Der SS-Pin (ich benutze ihn auch wirklich als CS) muss im Masterbetrieb
des SPI entweder als Ausgang geschaltet sein, oder muss auf high bleiben
(also nicht als Input verwendbar), da die SPI automatisch in den
Slavemode wechselt, wenn der Pin Input ist und auf Low geht.
Ich habe in den Block-Transferroutinen vom TI-Originalcode die Befehle
zum Senden/Lesen von Bytes fuer reines sequenzielles Lesen/Schreiben
optimiert, so dass quasi Schleifencode und Transfercode verschachtelt
werden, anstatt immer erst das Ende der Uebertragung abzuwarten, bevor
es weiter geht in der Schleife. Hat den Overhead (tatsaechliche minus
theoretische Uebertragungsdauer) effektiv halbiert.
Dazu kamen weitere Optimierungen (z.B. Blocksize nicht neu setzen, wenn
sie mit dem letzten Transfer uebereinstimmt, Entfernen der Karte im
Timer-Interrupt feststellen und gespeicherte Blocksize annullieren, beim
Einsetzen automatisch initialisieren etc.)
Den TI-Code gibt es bei Texas Instruments unter den ApplicationExamples
zu den MSP430-Prozessoren.
Wer Fragen hat, kann mir gerne ne Mail schicken. Ich weiss nicht, ob ich
dazu komme, hier nochmal reinzuschauen.
Ahoi,
hat jemand nen Tip was man noch probieren kann wenn die Karte auf Init,
Reset und Set Blocklength reagiert, sowie CSD und CID rüberschickt, aber
auf ein Lese-Kommando nur mit FFs reagiert?
Das eigentliche Lese-Kommando mit der Adresse wird zunächst korrekt mit
0x00 quittiert, aber danach kommt kein Data-Start sondern nur noch FFs.
Bzw der Port bleibt ganz auf high.
MMC ist eine 256MB von Kingston an einem Atmega 2561.
Eine Frage zu dem Code von Ulrich:
Und zwar ruft er einige Funktionen mit der Übergabe &Variable auf.
Zum Beispiel "SearchFile(13,&Clustervar,&Size,&Dir_Attrib,Buffer);"
Mit &Variable übergebe ich doch die Adresse der Variable und nicht den
Inhalt.
Da verstehe ich den Sinn nicht, kann mir das evtl. mal jemand erklären?
Zwei (verschachtelte) reichen doch völlig:
Eine (innere) zum Einlesen eines z.B. 512 Byte Blockes, der danach auf
die Karte geschrieben wird.
Und die Äußere, die die innere Schleife 20x (bzw. bis die Kamera leer
ist) aufruft...
Damit reichen dann 512 Byte Puffer - den hat auch ein Mega8.
Ahoi, Martin
Die Schleife in der geschrieben wird,setzt nach dem Schreiben das Array
zurück,so dass das mit 512Byte SRAM funktionieren sollte (;
Ich brauch mir erstmal um den SRAM keine Sorgen zu machen,ich habe
2Kbyte SRAM!
Ich habe da aber noch Probleme:
Wie und wo ist denn pict definiert?
Mir sind diese Ausdrücke:
1
pict.=wert;
2
pict=;
in einem C-Programm nicht geläufig...
Ansonsten (Pseudocode)
1
charpict[512];/* Puffer für Bilddaten */
2
inti,j;
3
4
for(j=0,j<20;j++){/* 20 Blöcke zu 512 Byte */
5
for(i=0;i<512;i++){
6
pict[i]=read_camera_value(j*512+i);
7
}
8
write_card_buffer(pict);
9
clear_buffer(pict);/* evtl. notwendig */
10
}
So etwa stelle ich mir das vor..
Ahoi, Martin
PS: Einrücken verbessert die Lesbarkeit deutlich
PS2: Dein Beitrag hat in diesem Thread eigentlich nix zu suchen -
er gehört in die Rubrik "Controller"