Forum: Projekte & Code MMC/SD-Karte mit FAT16 an AVR


von Mitrofanow (Gast)


Lesenswert?

Also ich nutz seit einiger Zeit ne Compactflash als Festplatte.
Und habe noch keine Probleme gehabt.
Ich denke der Wert 100.000 ist der Garantierte Wert, die FLashs kommen 
sicher noch höher.

Dank an Roland Riegel und die gesammte Open-Souce,
Mein Datenlogger funktionert endlich.

Was ich noch nicht verstehe ist, warum ich nach jedem ADC-Cannel wechsel 
ne Dummymessung machen muß.

von Michael U. (tolle)


Lesenswert?

Hallo Roland,

wie kann ich unter Windoes XP die SD-Karte als FAT16 formatieren?

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Michael,

Beim Formatieren sollte Windows für Karten <= 2GB meines Wissens nach 
automatisch FAT16 verwenden. Rechtsklick auf Laufwerk und 
"Formatieren..." wählen.

Ansonsten von einer Linux-CD booten und fdisk sowie mkdosfs verwenden.

Gruß,
Roland

von Michael U. (tolle)


Lesenswert?

Vielen Dank für Deine schnelle Antwort,Roland.
Ich werde es wohl mit Linux versuchen müssen, da ich mit Windows bisher 
wenig, oder keinen Erfolg erzielen konnte.
Gruss,Michael

von Roland R. (roland) Benutzerseite


Lesenswert?

Hmm, warum willst Du die Karte eigentlich neu formatieren? Die werden 
doch schon mit einem FAT16-Dateisystem ausgeliefert, welches einwandfrei 
mit dem sd-reader funktionieren sollte.

Roland

von Michael U. (tolle)


Lesenswert?

Hallo Roland,

Du hast vollkommen Recht. Jedoch sind meine SD-Karten bereits schon mit 
dem FAT 32 formatiert. Versuche jetzt deinen Vorschlag.

Viele Grüsse, Michael

von Hansl (Gast)


Lesenswert?

hallo,

hat jemand ein ein schema fuer mich? moechte das
ganze mit nem atmega16 ausprobieren, da sind die
boardlayouts leider nicht sehr hilfreich.

mal das ganze dann schnell mit eagle um/nach und
stells hier rein.

danke
 hansl

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Guido,

Guido Fischer wrote:
> Glückwunsch zum Source - funktioniert!
>

Danke!

> Ich hab mein Arthernet damit eben wiederbelebt da ich dort ja die MMC
> fest drauf habe. Chip Select über das CPLD funktioniert leider nicht,
> da das Programm nach Aktivierung des XMEM nicht mehr will.
>

Meinen Respekt für Arthernet. Eine Menge Arbeit und sehr professionell.

Zu XMEM kann ich Dir nicht viel sagen, da ich es zwar schonmal benutzt 
habe, die Schaltung jedoch keinen SD-Sockel hat. Was heißt, dass das 
Programm nicht mehr will?

> Ich habe eine günstige 1GB Karte die auf Anhieb läuft und eine 512MB
> Karte die sich nur durch zahlreiche Resets zur Antwort überreden lässt.
> Ich versuch gerade herauszufinden, woran's liegt, komme aber nicht
> weiter da mein JTAG streikt und das Arthernet Modul auch noch rumzickt.
>

Wie wird denn die Versorgungsspannung für die Karte bereitgestellt? Ich 
selbst habe die 3,3V mittels zweier Dioden erzeugt und hatte damit keine 
Probleme. Andere berichteten damit jedoch teils von immensen Problemen, 
da die Karten oft sehr hohe Spitzenströme von 100-200mA brauchen, bei 
denen die Spannung einbricht. Ein eigener Spannungsregler wäre am 
besten.

> Bei einer recht vollen Karte konnte ich keine Dateien mehr anlegen. Ich
> hatte drei Ordner mit zig mp3 Files und im Root versucht eine Datei
> anzulegen. Wurde ohne Fehler quittiert aber die Datei war nicht da.
> Sobald ich das reproduzieren kann, schicke ich Dir dazu passende Infos.
>

Ok, danke. Eventuell wäre auch ein Kartenimage sinnvoll.

> Jetzt guck ich erst mal, warum der JTAG nicht will :-/
>
> Gruß, Guido

Viele Grüße,
Roland

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von Roland R. (roland) Benutzerseite


Lesenswert?

Servus Guido,

Guido Fischer wrote:
>> Wie wird denn die Versorgungsspannung für die Karte bereitgestellt?
>
> Separater 3.3V Spannungsregler und SPI über 74LVX125 entkoppelt.
>

Ok, das sollte mehr als ausreichen. Vielleicht ist die Karte selbst 
etwas zickig und man sollte die Anzahl der Initialisierungsversuche oder 
die Wartezeiten innerhalb von sd_raw_init() nach oben setzen.

>> [Kartenimage]
>
> Bevor ich mir die Arbeit mache rauszufinden, wie ich das unter Windoof
> hinkriege, schick ich Dir die 2,99 EUR Karte eher per Post ;-)
>

Entweder so, oder mit dem Windows-Port von dd, siehe 
http://www.chrysocome.net/dd
Falls Du es auf diesem Weg machen willst, könnte ich Dir ein bisschen 
FTP-Platz bereitstellen.

> Btw. ich hab jetzt meinen RTC am rennen und wollte den Vorschlag
> machen, neue Dateien optional mit einem Datum zu versehen. Ich hab zwar
> schon mal versucht in den Structs die passenden Stelle zu finden, aber
> das ist mir zu abstrakt - da kennst Du Dich besser aus.
>

Bei mir im Code findest Du da nichts, weil ich das nicht vorgesehen 
habe. Es sollte aber relativ einfach möglich sein, das zu 
implementieren. Allerdings würde ich das wieder mit #defines 
konfigurierbar machen, da solch ein Feature für die meisten Anwendungen 
überflüssig sein dürfte.

Ich schau mir das bei Gelegenheit mal an. Allerdings würde ich darauf 
verzichten, auch noch die Zeiten des letzten Zugriffs oder der letzten 
Änderung aufzuzeichnen. Oder wüsstest Du eine vernünftige Anwendung 
dafür?

Grüße,
Roland

von Werner B. (Gast)


Lesenswert?

Wegen SD formatieren:

Gibts bei Panasonic

http://panasonic.jp/support/audio/sd/download/sd_formatter_e.html

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Guido,

Hmm, das ist merkwürdig. Ich habe hier ein mega128 ENC28J60-Board 
liegen, welches SPI und XMEM verwendet. Wenn Du magst, kann ich Dir ja 
mal ein abgespecktes Grundgerüst von meinem Code schicken.

Mittlerweile habe ich den sd-reader FAT16-Code so erweitert, dass das 
Erstellungsdatum und die -zeit gelesen und gesetzt werden kann. 
Durchgetestet habe ich das aber noch nicht.

Viele Grüße,
Roland

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von T.S. (Gast)


Lesenswert?

Auf die Erweiterung mit Datum/Uhrzeit bin ich auch gespannt...

Bei mir ist es so das der sd-reader in meinem eigenen Projekt seit 
geraumer Zeit erfolgreich läuft. Allerdings in einer älteren Version; 
das Problem mit Verzeichnissen unter m$ kann ich nachvollziehen wie hier 
gepostet wurde.

Nun habe ich etwas Angst alle Dateien mit denen von einer neueren 
Version mit einem Schlag einfach zu ersetzten. Möglicherweise sind 
eigene 'Anpassungen' drin die ich einfach vergessen habe.

Roland, könntest Du evtl. ein Diff zwischen den einzelnen Versionen mit 
veröffentlichen? Das wäre sehr hilfreich.

Danke noch einmal für alles,
Torsten

von Roland R. (roland) Benutzerseite


Lesenswert?

@Guido,

Naja, ob das gleich Genialität beweist ;-)

@Torsten,

Bei Gelegenheit (sprich: dem nächsten Release) werde ich das machen. Bis 
dahin kannst Du Dir auch selbst behelfen:
    diff -ur [sd-reader_verzeichnis]  [verzeichnis_mit_deinem_code] > 
deine_aenderungen.patch

Oder z.B. auch:
    diff -ur sd-reader_source_20061101 sd-reader_source_20070301 > 
sd-reader_diff_20061101_20070301.patch

Zurückspielen tust Du das dann in dem Verzeichnis, wo der zu patchende 
Code liegt:
    patch -p1 -i deine_aenderungen.patch
Du kannst obiges auch noch um --dry-run ergänzen, um zunächst nur mal zu 
sehen, ob es Konflikte geben wird.

Bei diesen Experimenten solltest Du vorher natürlich Backups machen...

Grüße,
Roland

von Michael O. (odiwan)


Lesenswert?

Hallo zusammen,

@Guido: Die Probleme sind mir seinerzeit bei der Anpassung von Rolands 
SD Library nicht aufgefallen.

Ich benutze auch dein Arthernet zusammen mit Rolands Library und einer 
32MByte NoName MMC Karte und einer 128MByte NoName SD Karte.

Die gehen beide problemlos. Ok, ich lese von der Karte.

Der entscheidende Teil der sd_raw_config.h sieht bei mir so aus:
1
#elif defined(__AVR_ATmega64__) || \
2
      defined(__AVR_ATmega128__)
3
  /* Attention: all pins must be defined for correct work */
4
    #define configure_pin_mosi() DDRB |= (1 << PB2)
5
    #define configure_pin_sck() DDRB |= (1 << PB1)
6
    #define configure_pin_ss() DDRB |= (1 << PB0)
7
    #define configure_pin_miso() DDRB &= ~(1 << PB3)
8
9
  #define select_card() *pSPI_CS &= ~(1 << SPIP4)
10
  #define unselect_card() *pSPI_CS |= (1 << SPIP4)
11
#else

Zu JTAG kann ich leider nichts sagen ich benutze nur den ISP Anschluss.

Tschau
Michael

von Michael O. (odiwan)


Lesenswert?

Hallo zusammen,

@Guido: Wieder mal zu schnell abgesendet.

Der Code geht ja noch weiter:
1
#elif defined(__AVR_ATmega64__) || \
2
      defined(__AVR_ATmega128__)
3
  /* Attention: all pins must be defined for correct work */
4
    #define configure_pin_mosi() DDRB |= (1 << PB2)
5
    #define configure_pin_sck() DDRB |= (1 << PB1)
6
    #define configure_pin_ss() DDRB |= (1 << PB0)
7
    #define configure_pin_miso() DDRB &= ~(1 << PB3)
8
9
  #define select_card() *pSPI_CS &= ~(1 << SPIP4)
10
  #define unselect_card() *pSPI_CS |= (1 << SPIP4)
11
#else
12
    #error "no sd/mmc pin mapping available!"
13
#endif
14
15
#define configure_pin_available()  DDRB &= ~(1 << PB7), PORTB |= (1<<PB7)    /* internen Pull-Up an PB7 aktivieren */
16
#define configure_pin_locked()  DDRB &= ~(1 << PB6), PORTB |= (1<<PB6)    /* internen Pull-Up an PB6 aktivieren */
17
18
#define get_pin_available() ((PINB >> PB7) & 0x01)
19
#define get_pin_locked() ((PINB >> PB6) & 0x01)

Der Pin available und locked funktionieren auf dem Arthernet auch.

Tschau
Michael

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von Roland R. (roland) Benutzerseite


Angehängte Dateien:

Lesenswert?

@Guido, Torsten und andere Interessierte,

Angehängt findet Ihr nun einen Patch, der das Erstellungsdatum von 
Dateien und Ordnern setzt. Er sollte funktionieren, allerdings konnte 
ich ihn nicht richtig testen, da
1. an meinem sd-reader keine RTC vorhanden ist und
2. mein kleiner mega168 durch die 5Byte größere fat16_dir_entry_struct 
mal wieder Platzprobleme im Stack bekommt.

Vielleicht könntet Ihr die Änderungen mal antesten. Bitte ändert in 
fat16_config.h das define fat16_get_datetime ab, sonst wird immer der 
01.01.2007 eingetragen.

Viele Grüße,
Roland

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von T.S. (Gast)


Lesenswert?

> was nehm ich da für ein Programm unter Windows?

... das gleichnamige. ;)

Wenn Du WinAVR installiert hast, guck mal unter utils\bin

Torsten

von Roland R. (roland) Benutzerseite


Lesenswert?

Oder guck einfach mal per Wordpad in die .patch-Datei. Das Format ist 
eigentlich selbsterklärend. Zur Not kannst Du es also per Hand mergen.

Bin schon gespannt auf Eure Ergebnisse...

Gruß,
Roland

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von T.S. (Gast)


Lesenswert?

Roland,

Offen gestanden hat es mich erhebliche Überwindung gekostet um den neuen 
Code auszuprobieren. Sachen die gut laufen sollte man eigentlich nicht 
mehr anfassen. ;)

Zuerst habe ich ein Update auf 20070301 gemacht. Per Hand so wie Guido, 
mit copy&paste nach dem diff zu der alten Version. 'patch' traue ich 
mich nicht auf meine Sourcen loszulassen.

Dabei ist mir aufgefallen, daß Du die GPL entfernt hast. Was bedeutet 
das jetzt genau?

Dann den neuen patch per Hand eingebaut. Aus Bequemlichkeit und/oder 
Vorsicht belasse ich erst einmal die Zeit so wie sie ist mit dem 
eingebauten #define fat16_get_datetime. Die Daten sind mir wichtig, ich 
möchte nichts riskieren. Das Datei-Datum jetzt vom RTC zu holen bedeutet 
einiges an meinem Proggi umzubauen.

Ich habe dann einige neue Dateien mit dem AVR erzeugt. Anschließend die 
Karte in XP's Card-Reader eingesteckt. Kein Datum im Explorer. :(

Cmd in XP ausprobiert: Ein 'dir' zeigt für eine Datei z.B.

01.01.1601  02:00 166.828 01.txt

Bestimmt habe ich irgendwo einen typo. Nur wo?
Kann ich evtl. an einer sinnvollen Stelle ein paar Bytes zur V24 
schicken zum gucken was los ist? Oder muß ich die Karte neu formatieren 
(was ich eigentlich nicht glaube)?

Hmm, bin etwas ratlos.

Torsten

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Torsten,

T.S. wrote:
> Roland,
>
> Offen gestanden hat es mich erhebliche Überwindung gekostet um den
> neuen Code auszuprobieren. Sachen die gut laufen sollte man eigentlich
> nicht mehr anfassen. ;)
>

Nun, gegen diese Ängste gibt es Versionskontrollsysteme oder, in der 
simpelsten Form, Backups :)

> Zuerst habe ich ein Update auf 20070301 gemacht. Per Hand so wie Guido,
> mit copy&paste nach dem diff zu der alten Version. 'patch' traue ich
> mich nicht auf meine Sourcen loszulassen.
>

Naja, ich denke die Wahrscheinlichkeit, dass Du per Hand einen Fehler 
machst, ist größer als die Wahrscheinlichkeit, dass "patch" etwas falsch 
abändert und keine Konflikte meldet.

> Dabei ist mir aufgefallen, daß Du die GPL entfernt hast. Was bedeutet
> das jetzt genau?
>

Was meinst Du mit "die GPL entfernt"? Welche Version hattest Du vorher 
genau?

Der Code ist und bleibt unter der GPL. Soweit ich mich erinnere, habe 
ich vor einigen Versionen lediglich mein Copyright und einen Vorspann zu 
jeder Datei hinzugefügt.

> Ich habe dann einige neue Dateien mit dem AVR erzeugt. Anschließend die
> Karte in XP's Card-Reader eingesteckt. Kein Datum im Explorer. :(
>
> Cmd in XP ausprobiert: Ein 'dir' zeigt für eine Datei z.B.
>
> 01.01.1601  02:00 166.828 01.txt
>

1601? Das kann FAT eigentlich gar nicht darstellen. Kontrolliere 
vielleicht nochmal nach, ob Du die Funktionen 
fat16_set_file_creation_date() und fat16_set_file_creation_time() 
korrekt übernommen hast.

> Bestimmt habe ich irgendwo einen typo. Nur wo?
> Kann ich evtl. an einer sinnvollen Stelle ein paar Bytes zur V24
> schicken zum gucken was los ist? Oder muß ich die Karte neu formatieren
> (was ich eigentlich nicht glaube)?
>

Du könntest innerhalb von fat16_create_file() nach dem Aufruf der beiden 
oben genannten Funktionen den Inhalt der Variablen 
dir_entry->creation_date und dir_entry->creation_time ausgeben lassen.

Wenn Du noch eine alte Version Deines Codes hast, könntest Du auch mal 
einen Patch gegen Deinen jetzigen Code erstellen und diesen mit meinem 
geposteten Patch vergleichen.

> Hmm, bin etwas ratlos.
>

Das wird schon ;-)

Gruß,
Roland

von T.S. (Gast)


Lesenswert?

Hallo Roland,

> Was meinst Du mit "die GPL entfernt"? Welche Version hattest Du vorher
> genau?

Eine ältere Version, welche genau habe ich vergessen.
Da habe ich etwas falsch verstanden. Bitte entschuldige.

Btw wenn Du CVS verwendest, könnte man $Id$ einfügen, das zeigt die 
letzte Änderung an.

Um Tippfehler auszuschließen habe ich jetzt auf die Version 20070301 
patch losgelassen:
patch -i sd-reader_fat16-time.patch.txt

Die 3 betroffenen Dateien habe ich in mein Projekt kopiert. Zusätzlich 
noch etwas debug-code in fat16_create_file und fat16_create_dir 
spendiert:

...
fat16_get_datetime(year, month, day, hour, min, sec);
fat16_set_file_creation_date(dir_entry, year, month, day);
fat16_set_file_creation_time(dir_entry, hour, min, sec);

printf_P((PSTR("%02d.%02d.%04d %02d:%02d:%02d\r\n")),
    day, month, year, hour, min, sec);
...

Auf der Konsole so wie es sein sollte:
01.01.2007 00:00:00
beim erzeugen von Dateien oder Verzeichnissen. Also arbeitet die 
Funktion soweit.

Trotzdem das gleiche wie gestern beschrieben.
Vielleicht geht's mit einer anderen Karte, mal sehen.

Torsten


von Roland R. (roland) Benutzerseite


Lesenswert?

Hi Torsten,

> Btw wenn Du CVS verwendest, könnte man $Id$ einfügen, das zeigt die
> letzte Änderung an.
>

Ich verwende Subversion, aber da geht das auch, ja.

> Um Tippfehler auszuschließen habe ich jetzt auf die Version 20070301
> patch losgelassen:
> patch -i sd-reader_fat16-time.patch.txt
>
> Die 3 betroffenen Dateien habe ich in mein Projekt kopiert. Zusätzlich
> noch etwas debug-code in fat16_create_file und fat16_create_dir
> spendiert:
>

Das heißt, im Prinzip verwendest Du jetzt meinen Original-Code? Schön.

> ...
> fat16_get_datetime(year, month, day, hour, min, sec);
> fat16_set_file_creation_date(dir_entry, year, month, day);
> fat16_set_file_creation_time(dir_entry, hour, min, sec);
>
> printf_P((PSTR("%02d.%02d.%04d %02d:%02d:%02d\r\n")),
>     day, month, year, hour, min, sec);
> ...
>
> Auf der Konsole so wie es sein sollte:
> 01.01.2007 00:00:00
> beim erzeugen von Dateien oder Verzeichnissen. Also arbeitet die
> Funktion soweit.

Alles was das aussagt ist, dass fat16_get_datetime() funktioniert, und 
das sind ja im Moment nur einfache Zuweisungen. Ich wollte explizit den 
Wert von dir_entry->creation_date/time wissen. Der sollte 0x3621 (für 
01.01.2007) bzw. 0x0000 (für 00:00:00 Uhr) sein. Nur die Werte innerhalb 
von dir_entry werden dann auch von fat16_write_dir_entry() auf die Karte 
geschrieben.

> Trotzdem das gleiche wie gestern beschrieben.
> Vielleicht geht's mit einer anderen Karte, mal sehen.
>

Ich glaube nicht, dass das an der Karte liegt. Das hat nichts mit der 
physikalischen Ebene zu tun.

Grüße,
Roland

von T.S. (Gast)


Lesenswert?

Hallo Roland,

> Das heißt, im Prinzip verwendest Du jetzt meinen Original-Code? Schön.

Yep.

> Alles was das aussagt ist, dass fat16_get_datetime() funktioniert, und
> das sind ja im Moment nur einfache Zuweisungen. Ich wollte explizit den
> Wert von dir_entry->creation_date/time wissen. Der sollte 0x3621 (für
> 01.01.2007) bzw. 0x0000 (für 00:00:00 Uhr) sein. Nur die Werte innerhalb
> von dir_entry werden dann auch von fat16_write_dir_entry() auf die Karte
> geschrieben.

Achso. Schon wieder habe ich etwas falsch verstanden, ich bitte abermals 
um Entschuldigung.

Die beiden printf_P's habe ich nun geändert, sind noch an der gleichen 
Stelle:

printf_P((PSTR("date: 0x%04x time: 0x%04x\r\n")),
    dir_entry->creation_date, dir_entry->creation_time);

Ich hoffe das war richtig. Heraus kommt:

date: 0x3621 time: 0x0000

> Ich glaube nicht, dass das an der Karte liegt. Das hat nichts mit der
> physikalischen Ebene zu tun.

Wie Du richtig vermutet hast hat sich mit einer anderen Karte nichts 
geändert.

Debuging ist keine einfache Sache und kann evtl. länger dauern weil 
alles mögliche dafür in Frage kommen kann. Wir könnten versuchen der 
Sache auf den Grund zu gehen wie schon einmal per PM wenn Du möchtest. 
Es schreibt sich halt einfach leichter.

Torsten

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

da hier alle SD-Karten Kompetenzen versammelt sind trau ich mich mal 
eine frage zu stellen.
Ich bestreite gerade ein Projekt indem ich eine SD-Karte mit Fat16 
formatierung an ein Tricore 1130 µC anbinden soll.
Im wesentlichen hab ich die Sourcecodes von Ulrich Radig übernommen, 
will sagen ich hab sie an meinen µC angepasst.
Da mein µC auf 3,3V läuft hab ich die SD-Karte quasi Eins zu Eins an den 
Port geklemmt.
Ich habe jetzt allerdings ein problem bei der Initialisierung der Karte.
Nachdem ich die mind. 74 Clocks an die SD-Karte bei CS=High schick, 
sende ich ja das CMD 0 bei CS=LOW. Sämtliche Übertragungen der Bytes hab 
ich mit dem Oszi überprüft. Nach Plan sollte die Karte dann ja 0x01hex 
zurücksenden.
Die Antwort die ich bekom ist allerdings 0x3fhex.
Meine Frage lautet nun: Wie kann die SD-Karte mir z.b. einen Illigal 
Command Error zurücksenden, obwohl ich doch 6 Bytes für Commando 0 
hinschick.
Ich komm einfach nicht dahinter was mir die Karte damit sagen will.
Meinen Quellcode habe ich mal angehängt.

Für eine erleuchtende Antwort wäre ich euch dankbar.

von T.S. (Gast)


Lesenswert?

Mir fällt etwas auf in

while(sd_write_command(cmd)!=0x01)
{
    if(Timeout++ >= 10) <--- [*]
    {
        return (1);
    }
}

[*] Das Timeout ist auf jeden Fall zu kurz. Ich glaube irgendwo mal 
gelesen zu haben das das Aufwecken der Karte fast eine Sekunde dauern 
kann.

Torsten

von Matthias (Gast)


Lesenswert?

Also selbst wenn ich das Timeout von 10 auf 1000 erhöh kommt immernoch 
0x3f zurück.

von Günther F. (taraquedo)


Angehängte Dateien:

Lesenswert?

Hallo!

Frage nebenher: Hat hier schonmal jemand den Datendurchsatz für einen 
SCHREIBvorgang getestet?

Ich übertrage mit 38.400 baud (8N1) über uart eine binäre Datei. Das 
macht max. 3.840 Nutzbytes/s. Ohne auf die SD-Karte zu schreiben (im 
Quelltext, wenn MACHS_WIRKLICH nicht definiert ist) erreiche ich dieses 
Maximum auch tatsächlich fast. Bin ich maximal 1s drüber bei einer 64kB 
Datei.

Wenn ich nun aber auf die Karte schreibe sinkt die Übertragungsrate auf 
aller höchstens 120 Byte/s. Wohlgemerkt Byte - keine kB! Eine 20kB 
Firmwaredatei braucht plötzlich über 3 Minuten. Dabei habe ich den 
Schreibpuffer (s. Quelltext) auf satte 512 Byte eingestellt.

Habt ihr das Problem auch oder ist das normal, weil FAT aufwendig ist?

Grüße!

von T.S. (Gast)


Lesenswert?

Mathias

Schau Dir doch bitte einmal die Datei sd_raw.c vom sd-reader genauer an 
weil es sich in diesem Thread genau darum dreht ;)

Ob ein Timeout von 1000 für eine Zeit von rund ~1s reicht wage ich stark 
zu bezweifeln. Das geht nur bei den AVR's weil man jeden Takt zählen 
kann und somit die Ausführungszeit vorhersagbar ist.

Nur Vermutungen weil ich von dieser CPU/MPU noch nie etwas gehört habe:
- der Code wird in einem Cache ausgeführt
- der Compiler optimiert stark
... so das Deine Schleifen in einem 'Wimpernschlag' ausgeführt werden 
nicht aber in der Größenordnung die benötigt wird.

Möglicherweise hat der Tricore einen Timer. Wenn ja, verwende besser 
diesen für einen Timeout.

Torsten

von stefan richter (Gast)


Lesenswert?

Hallo Roland,

ich habe deine Schaltung nachgebaut, allerdings mit Mega64 und meine 
Kontrolle ober Karte gesteckt bzw schreibschutz liegen immer auf low, da 
ich keinen Sockel habe.

Problem ist aber, dass sich die Karte nicht (richtig) initialisieren 
lässt.
wenn ich die Karte n paar mal rausnehme und wieder reinstecke gehts mit 
viel glück.
Habe das Problem verfolgt und hab dann herrausgefunden dass er mir in 
der Funktion sd_raw_init da aussteigt:

   /* reset card */
    uint8_t response;
    for(uint16_t i = 0; ; ++i)
    {
        response = sd_raw_send_command_r1(CMD_GO_IDLE_STATE, 0);
        if(response == (1 << R1_IDLE_STATE))
            break;

        if(i == 0x1ff)
        {
            unselect_card();
            return 0;
        }
    }

woran könnte das liegen? hab schon verschiedene Karten ausprobiert und 
bei allen das selbe Syndrom.

Danke Stefan

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Stefan,

stefan richter wrote:
> [...] da ich keinen Sockel habe.
>

Was verwendest Du denn dann??

> Problem ist aber, dass sich die Karte nicht (richtig) initialisieren
> lässt.

- Welche Anbindung?
- Stromversorgung per Wandler oder mit Dioden?
- Extra Pegelwandler oder Spannungsteiler?

Vor allem die letzten zwei Punkte sind kritisch. Wenn dann noch lange 
Kabel oder Selbstbau-Sockel dazukommen, kann es durchaus Probleme geben.

Siehe dazu auch die Beiträge weiter oben im Thread.

Gruß,
Roland

von Joachim (Gast)


Lesenswert?

Hallo Stefan,

Habe auch mal das Filesystem von Roland auf einem Mega64 probiert.
Am Anfang hatte ich auch Probleme.
Eines davon war bei sd_raw_init:

/* card needs 74 cycles minimum to start up */
    for(uint8_t i = 0; i < 10; ++i)

Bei mir wurden komischerweise nur 5 Datenpakete ausgegeben (gemessen).
Weiss der Geier, warum..
Nachdem ich es geändert hatte in

/* card needs 74 cycles minimum to start up */
    for(uint8_t i = 0; i < 20; ++i)

lief es einwandfrei.
Es ist ja ein Minimumwert. Mehr 0xFF-Bytes zu senden, schadet nichts.
Wichtig ist auch, dass der SPI Takt bei Init nicht über 400KHz liegt.
Und selbstverständlich, dass der Chip-Select für die Karte richtig 
angesteuert wird.

Roland:
Welchen maximalen Lesedurchsatz hast Du hinbekommen?
Ich habe nur max. 250KBytes/Sek. geschafft. Für 512 Bytes, was einem 
Sektor entsprechen sollte:

/* load file contents for speed measurements */
            uint8_t buffer[512];
            while(fat16_read_file(fd, buffer, sizeof(buffer)) > 0)
            {
            }

Ich verwende keine SPI, sondern ein externes CPLD, welches eine SPI mit 
25MBits/Sek. enthält. Der Datenaustausch erfolgt rein über 
Speicherzugriffe und der Status der SPI wird über einen Portpin 
abgefragt, z.B. Senden:

void sd_raw_send_byte(uint8_t b)
{
    uint8_t *SDAddress;
    uint16_t i;
  if (Initcard == 1)
    i = 0x1101;  //write INIT Mode 400KBits/Sek.
  else i = 0x1102;  //write fast mode 25MBits/Sek.
  SDAddress = (uint8_t *) i;
  *SDAddress = b;  //write  Data
_asm__ __volatile_ ("nop");  //allow "Ready" to change
  while (PIND & (1<<PIND0)) //wait for "Ready"
  {
  }
}

Dein Filesystem ist sehr komfortabel. Bin zwar noch nicht ganz 
durchgestiegen, weil ich noch nicht solange in C programmiere, aber es 
funzt. Was ich noch gerne machen würde, wäre den Zeichenvergleich für 
den Dateinamenszugriff Case-unabhängig zu machen. So dass man beim 
Konsolenbetrieb nicht immer exakt auf Groß/Kleinschreibung achten muss.
Bin aber noch nicht durch Deine Strukturen durchgestiegen, bzw. wie die 
Eingabestrings mit den Dateinamen verglichen werden.
Auch will ich mal versuchen, komplette Sekoren oder gar Cluster komplett 
einzulesen, ohne die ständigen Bereichsabfragen, die (so wie es 
aussieht), das ganze ziemlich ausbremsen.
Aber sonst: Hohes Lob!

Joachim

von Roland R. (roland) Benutzerseite


Lesenswert?

Joachim wrote:
> Roland:
> Welchen maximalen Lesedurchsatz hast Du hinbekommen?
> Ich habe nur max. 250KBytes/Sek. geschafft. Für 512 Bytes, was einem
> Sektor entsprechen sollte:
> [...]

Mit diesem Wert bist Du recht gut dran. Konkrete Messungen habe ich bei 
mir allerdings noch nicht gemacht. Mein SPI läuft mit 8MHz, schon daher 
dürfte der Durchsatz um ein Vielfaches geringer sein.

Generell gilt, je größer die Blöcke sind, die Du auf einen Schlag liest, 
desto geringer ist der Overhead und desto schneller somit der Durchsatz. 
Versuch es, je nach RAM-Ausstattung Deines Controllers, also mal mit 
Blöcken von 1kB, 2kB oder mehr.

> Was ich noch gerne machen würde, wäre den Zeichenvergleich für
> den Dateinamenszugriff Case-unabhängig zu machen. So dass man beim
> Konsolenbetrieb nicht immer exakt auf Groß/Kleinschreibung achten muss.
> Bin aber noch nicht durch Deine Strukturen durchgestiegen, bzw. wie die
> Eingabestrings mit den Dateinamen verglichen werden.

Dazu ist es nicht unbedingt nötig, meinen Code zu ändern. Das kannst Du 
auf Applikationsebene machen, wenn Du alle Dateien entweder in Groß- 
oder in Kleinschreibung abspeicherst und alle Strings, die meinem 
FAT16-Layer übergeben werden, zuvor entsprechend in Groß- oder 
Kleinschreibung konvertierst.
Das hätte auch den Vorteil, dass Du meinen Code leichter auf neuere 
Versionen aktualisieren kannst.

> Auch will ich mal versuchen, komplette Sekoren oder gar Cluster
> komplett einzulesen, ohne die ständigen Bereichsabfragen, die (so wie
> es aussieht), das ganze ziemlich ausbremsen.

Welche Abfragen genau? Die Dateien müssen in Cluster aufgeteilt werden, 
da diese über den Datenträger verstreut liegen können. Die Aufteilung in 
Sektoren (bzw. Blöcke) ergibt sich durch die Struktur der SD-Karten.

Eine Beschleunigung kann man z.B. durch
- Vergrößerung des Blockpuffers,
- Zwischenpufferung der Verzeichniseinträge und
- Zwischenpufferung der FAT
erreichen. Das habe ich aber zwecks guter Einsetzbarkeit auf möglichst 
vielen verschiedenen Controllern und mangels RAM auf meinem mega168 
nicht implementiert.

Gruß,
Roland

von Peter (Gast)


Lesenswert?

hallöle,
funzt der code auch mit sehr grossen speicherkarten (ca. 10 GB oder so)?
sorry, aber ich wollt' mir nicht alle ~300 beiträge hier durchlesen...

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Peter,

FAT16 unterstützt nur Partitionsgrößen bis 2GB, dies gilt daher auch für 
meinen Code. Unterstützt werden Medien bis 4GB, welche mit mindestens 2 
Partitionen nutzbar sind.

Gruß,
Roland

von Roland R. (roland) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo an alle,

Nachdem ich von Torsten eine positive Rückmeldung für die Unterstützung 
der Modifikationszeit bekommen habe, hier ein neues Release.

Die Änderungen im einzelnen:
- Unterstützung für das Lesen und Setzen der Modifikationszeit neu 
angelegter oder geänderter Dateien und Ordner.
- Bugfix für einen Fehler in sd_raw_read() bei Benutzung des 
Blockpuffers.

Ab sofort stehen auf meiner Homepage auch Patches bereit, die nur die 
Änderungen seit des jeweils letzten Release enthalten. Diese sollten ein 
Update erleichtern, insbesondere wenn in der Zwischenzeit eigene 
Änderungen vorgenommen wurden.

Viele Grüße,
Roland

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von taraquedo (Gast)


Lesenswert?

Hallo!

Hatte oben mal geschrieben, dass der Schreibdurchsatz sehr gering sei. 
Das wollte ich hiermit mal klar stellen ging auf meine Kappe. Hatte 
schon vor ein paar Wochen rausgefunden, dass ich den sizeof falsch 
verwendet habe und eine Puffergröße von 2 Bytes statt 512 hatte. Aber da 
sieht man mal, wie entscheidend diese Puffergröße ist.

Vielen Dank für die Aufnahme meines Patches. Ist ja doch noch eine Menge 
Leben drin in den Routinen.

Grüße!

von August (Gast)


Lesenswert?

Hallo,
ich suche die Original-CID und -CSD der SD-Karten
Kingston Elite Pro 256MB
Platinum 1GB

Fragt mich nicht wie, aber mir ist es (unfreiwillig) gelungen,
die read-only-Register CID und CSD dieser Karten kaputt zu bekommen.
Bei der Kingston-Karte steckt eine halbe Kopie der CSD in dem CID-
Register.
Bei der Platinum-Karte stimmt die CRC7 bei CSD nicht. Was wieder
eine ganze Reihe von Fragen aufwirft. ;-)

Vielen Dank!
August

von Stefan (Gast)


Lesenswert?

Hallo Roland,

ich brauche für ein GPS-Fahrtenbuch Schreibzugriff auf eine MMC, also 
habe ich dein Projekt getestet:
-Mega16 auf das STK500 gesteckt
-Vtarget auf 3.3V konfiguriert
-MMC Sockel mit einem Stück Flachbandkabel an PORTB angesteckt
-Projekt kompiliert & geflasht
-> Funktionierte auf Anhieb wunderbar!

Wenn meine Platine da ist werde ich dann noch das NMEA Parsen & GPX 
schreiben (das Gerät soll direkt GPX Dateien auf die Karte schreiben) 
implementieren. Ich habe auf der Platine einen Goldcap mit 470.000 µF 
vorgesehen, mal sehen ob das reicht um die Daten noch gar auf die Karte 
zu schreiben wenn der Strom abgestellt wird...

Also vielen Dank für das Projekt,

Gruß
Stefan

von Slater (Gast)


Lesenswert?

Hi,

hab folgendes problem mit dem Code

sd_raw_init()
partition_open()
fat16_open()
fat16_get_dir_entry_of_path()
und fat16_open_dir()

sind erfolgreich. Wenn ich dann aber fat16_create_file() oder 
fat16_create_dir() benutzen will, hängt er sich auf oder hat den Fehler, 
dass er keinen freien Clsuter findet.

Die MMC wurde mit knoppix auf fat16 partitioniert (16 MB groß) und mit 
mkdosfs formatiert.

Bin echt am verzweifeln, weil ich keinen logischen Grund finde...

Grüße
Christian

von Hansl (Gast)


Lesenswert?

hallo,

ich hab grad laut anleitung von ulrich radigs webseite ein
brotbrett bestueckt.

http://www.ulrichradig.de/site/atmel/avr_mmcsd/gfx/MMCSDSCH.JPG

der aufbau ist:

ein stk500 mit atmega16 und 16MhZ quarz (laeuft).

die +5V beziehe ich vom VTG anschluss an portB.

sollten da beim mmc anschluss nach den 2 dioden nicht um die 3.7V
zu messen sein? bei mir ist es davor: 4.96V und nach den 2 1N418 4.32V.

jemand ne idee wo ich mich verbastelt haben koennte?

mfg
 Hansl

von Hansl (Gast)


Lesenswert?

btw. mit 4 dioden komm ich auf 3.7V

gibts unterschiedliche 1N4148er ?

von jemand (Gast)


Lesenswert?

RTFM.

Wenn du das Datenblatt gelesen hättest, wüsstest du, dass der 
Spannungsabfall vom Strom abhängig ist, der durch die Diode fliesst.

von Hansl (Gast)


Lesenswert?

jemand: merci, habs eben nachgemessen. stimmt.

von holger (Gast)


Lesenswert?

@ jemand

Genau. Die nächste Frage von Hansl kann man schon raten.
Wieso funktioniert SPI mit den Spannungsteilern
nicht bei 8MHz ;)

Es ist doch immer wieder das gleiche leidige Thema :(

von Hansl (Gast)


Lesenswert?

holger:

pack deine kristallkugel wieder ein und entspann dich.

mcu ist geflasht. ausgabe am terminal is auch da.
nun brauch ich nur noch irgendwo die mmckarte fat16 formatieren.

mfg
 hansl

von T.S. (Gast)


Lesenswert?

SPI funktioniert bei mir sehr wohl mit den Spannungsteilern, auch bei 
14,x MHz. Die 3,3V Spannungsversorgung mit der Diodenlösung dagegen 
nicht. Unbedingt, das wurde mehrfach erwähnt, einen eigenen Regler dafür 
verwenden.

VORSICHT mit dem LM317 und einigen 3,3V Festspannungsreglern: Manche 
brauchen eine Mindestlast von einigen mA!

Eine SD-Karte braucht nur Strom wenn darauf zugegriffen wird. Bei einem 
ungeeigneten Regler könnte die Spannung auf unzulässige Werte 
hochlaufen.

Sehr gute Erfahrungen habe ich mit einem "LP 2950 CZ-3,3" gemacht.

Meinen 5V-Regler (78L05) habe ich wegen der guten Erfahrungen durch 
einen "LP 2950 CZ-5,0" aus der gleichen Familie ersetzt. Ein feines Teil 
btw, der Ruhestrom liegt im µA Bereich. Das kann wichtig für 
Batterie-Betrieb sein: der Ruhestrom ist ca. 5mA geringer pro Regler. 
Beide gibt es für 60 Cent bei Segor.

Torsten

von Hansl (Gast)


Lesenswert?

Hallo,

torsten: danke, hab diese fehlerquelle mal enfernt.

Hab nun anstelle der moeglicherweise wackeligen diodenloesung genau
wie stefan ein paar posts weiter oben beschrieben hat die VTARGET
konfigurationsmoeglichkeit des stk500 benutzt.

Leider ist alles was in der console zu sehen ist dies hier:
"MMC/SD initialization failed"

jemand ne idee woranns liegen koennte? oder kommt die meldung
auch wenn kein-oder ein ungueltiger partitiontable oder fat
gefunden wurde?


hier noch ein paar details zum setup:

SPI ist enabled (0)

die konfiguration der Anschluesse beim Atmega16:
PORTB4(SS)   - MMC CS *via spannungsteiler
PORTB5(MOSI) - MMC DI *via spannungsteiler
PORTB6(MISO) - MMC DO
PORTB7(SCK)  - MMC CLK *via spannungsteiler

uisp -dprog=stk500 -dserial=/dev/ttyS0 -dspeed=115200 -dpart=atmega16 
--rd_aref --rd_vtg --rd_fuses
Firmware Version: 1.14
VTarget = 3.3 V
ARef = 3.3 V
Atmel AVR ATmega16 is found.
Firmware Version: 1.14

Fuse Low Byte      = 0xff
Fuse High Byte     = 0xd9
Cannot read extended fuse bits on this device. Returning 0xff
Fuse Extended Byte = 0xff
Calibration Byte   = 0xbf  --  Read Only
Lock Bits          = 0xff
    BLB12 -> 1
    BLB11 -> 1
    BLB02 -> 1
    BLB01 -> 1
      LB2 -> 1
      LB1 -> 1


achja, die karte ist ne 128MB MMC - takeMS. die hab ich noch
nie benutzt, weis also weder ob noch wenn womit die formatiert ist.


mfg
 hansl

von Joachim (Gast)


Lesenswert?

> jemand ne idee woranns liegen koennte? oder kommt die meldung
> auch wenn kein-oder ein ungueltiger partitiontable oder fat
> gefunden wurde?

Ähem - wenn Du die Sourcen durchlesen würdest, wüsstest Du, dass bei 
DIESER Meldung noch gar kein Partitionseintrag eingelesen wurde.
Diese Meldung bezieht sich rein auf sd_raw_init().
Die Karte sendet also keine gültigen Response-Daten.

Also zu 90% Hardware- oder Interface-Fehler.
Musst halt mal anzeigen lassen, was die Karte überhaupt antwortet. Wenn 
sie denn überhaupt antwortet.

NEUE Karten in der Größe <=2GB sollten ab Werk ausschließlich mit FAT16 
formatiert sein. Ich habe noch niemals eine andere gesehen und schon ca. 
300 Stück verschiedener Karten "verbaut".
Vorsicht bei gebrauchten aus Ebay: Da wurde oft schon drauf 
rumgepfuscht.
Wenn die Karte unter Windows neu formatiert wird, macht Windows in 
vielen Fällen FAT12 draus, wenn die Karte relativ klein ist (z.B. 64MB).

Bei ersten Versuchen würde ich Billigkarten vermeiden.
Manche haben ein Problem mit dem SPI-Modus, obwohl sie in Kameras oder 
Cardreadern problemlos laufen. Will hier keine Schleichwerbung machen, 
aber Karten von SanDisk oder Kingston waren bei mir immer problemlos.

Zum Thema "Spannungsteiler mit Widerständen" wollte ich noch sagen, dass 
die allseits bekannte Schaltung bis 4MHz funktioniert. Bei meinem M16C 
Kontroller geht das sogar noch bei 8MHz SPI-Takt. Allerdings liefen 
manche Kartenfabrikate nicht, vor allem irgendwelcher Noname-schrott ala 
"extreme-memory". Billige Karten reagieren recht sensibel auf allzu 
"verwaschene" Signale.
Sichere 8 MHz mit AVR erreicht man mit niederohmigeren Widerständen. 
Also nicht im Bereich 1,8/3,3 KOhm, sondern zum Beispiel 330/620 Ohm.
Bedeutet natürlich eine höhere Strombelastung, aber die Flanken werden 
wieder steiler und somit ist eine höhere Frequenz möglich.
Auf "wundersame" Weise funktionierten danach auch Karten, die sich 
vorher niemals haben ansprechen lassen ;-)
Bei 12Mhz ist mit der Spannungsteilerlösung so ziemlich Schluss.
Aber die werden mit einem AVR eh nicht erreicht.
Wenns also billig sein muss und der AVR unbedingt an 5V laufen muss, 
dann funktioniert diese Lösung in jedem Fall.
Mittlerweile arbeite ich mit ARM und da tritt das Problem 
glücklicherweise nicht mehr auf :-)


Joachim

von Hansl (Gast)


Lesenswert?

joachim: danke fuer die ausfuehrungen. werd mal mit dem hardwareaufbau
herumexperimentieren.

den code hab ich mir natuerlich angesehen != verstanden.

bei elm chans software blick ich leider noch weniger durch.

mfg
 Hansl

von Wolfgang (Gast)


Lesenswert?

Hat noch jemand die ursprünglichen AtMega8 Sourcen für ein FAT 
Filesystem und
kann er die Hier im Forum zur Verfügung stellen?
Das Ganze soll als Basis für einen kompakten Datenlogger dienen.
Schon im Voraus vielen Dank.

von Joachim (Gast)


Lesenswert?

Hansl:
Jetzt muss ich aber nochmal fragen: Du hast die Versorgung des Boards 
auf 3,3V gesetzt und die Spannungsteiler dringelassen???
So interpretiere ich jedenfalls Dein vorletztes Posting.

Joachim

von Hansl (Gast)


Lesenswert?

joachim:
jepp, hab ich. nach ein wenig gruebeln war mir dann klar das das topfen
ist :) und habs rausgenommen. mittlerweile hab ich die MMC karte bei
nem freund getestet und es hat sich herausgestellt das weder dessen
cardreader noch sein palm pilot mit dem ding was anzufangen weiss.

der palm meldet eine fehlerhafte karte, der windoofpc aeussert sich
nicht dazu.

hab heute um 5 euronen ne 128mb RS-MMC karte von Lexar, was auch immer
RS sein soll, gekauft und nen LT1086 CM-3.3 von nem fibrechanneladapter
gebrutzelt.

werde des naechtesns wenns klima wieder passt einen 2. versuch starten 
:)

dann wieder mit spannungsteiler am SPI und 5V VTARGET.

mfg
 Hansl





von Hansl (Gast)


Lesenswert?

es ist verhext. immer noch die MMC/SD initialization failed
fehlermeldung :(

elektrisch sollte alles korrekt sein. mmc wird durch nen LT1086 CM-3.3
versorgt.

habs nun mal mit 330 und 650 Ohm widerstaneden als spannungsteiler
probiert aendert auch nichts. gestern hat die karte in nem cardreader
aufjedenfall einwandfrei funktioniert. also wenn ich die karte nciht
irgendwie beim aufbauen geschrottet hab sollte die nun funktionieren.

folgendes habe ich messen koennen(mieses multimeter):
CS       (MMC PIN1, MCU PB4)   3.24V
DATA IN  (MMC PIN2, MCU PB5)   3.24V
VCC      (MMC PIN4)            3.27V
DATA OUT (MMC PIN7, MCU PB6)   4.74V

hab keinen schimmer woranns liegen koennte :(

achja, ISP kabel abziehen bringt auch nix.

weitere debuggingtips?

mfg
 Hansl

von Werner B. (Gast)


Lesenswert?

Hast du einen 100nF C über die 3,3V direkt am Kartenslot?

Bei mir läuft seit fast zwei Jahren die folgende Beschaltung.
Der interne PULL-UP am MISO ist deaktiviert

Für Signale vom uC an die Karte (CS, MOSI, SCK)

        3v3 ^
            |
           | |
           | | 47k
           | |       2k2
            |     _____
MMC/SD -----O-----_______------  uC (out)
            |
           | |
           | | 3k9
           | |
            |
           GND

Data-Out der Karte (MISO)

        3v3 ^
            |
           | |
           | | 47k
           | |      330
            |     _____
MMC/SD -----O-----_______------ uC (MISO)

von Hansl (Gast)


Lesenswert?

werner:
hab nun auch deine schaltung aufgebaut, und in Rolandscode
noch ein PORTB &= ~_BV(PB6); ergaenzt um den pullup des MISO
PORTS zu deaktivieren. ergebnis unveraendert.

ich vermute das irgendwo am stk500 der hund begraben liegt...
nur wo?

dies ist nun der dritte aufbau. diesmal sogar mit 8Mhz internem takt!
und 100nf C am mmc. sicher ist sicher :)

anbei nochmal meine aktuellen fusesettings:

Fuse Low Byte      = 0xd4
Fuse High Byte     = 0xd9

Atmega16 @ 8MhZ, JTAG DISABLED

die mmckarte funktioniert. aufjedenfall hab ich das dintg gestern
nochmal getestet. leider aber nur mit einem palm :(

jemand irgendeine idee? ich tippe auf das stk500, denn das
ist das einzige an dem ich ausgenommen von "spi-programmingkabel
trennen" nix geaendert habe..

mfg
 Hansl


aus dem, hey das guck ich mir schnell mal an ist mittlerweile ein
jahresziel geworden ;)

von Joachim (Gast)


Lesenswert?

Tips hast Du bekommen, nur ob Du die umsetzt, ist fraglich.
Beim Lesen Deiner Beschreibungen kommt es einem so vor, als ob Du 
"wahllos drin rumstocherst".

1. Besorg Dir ein Oszi und mess die SPI Leitungen. Gib dazu ein Muster 
an SPI aus z.B. 0x5A und schau Dir die Signale SCLK und Data direkt an 
der SD Karte an. Messe auch den Chip select.
Denk dran: Im Initmode darf die SD Karte maximal 400KHz bekommen.
Multimeter kasste vergessen. Man kann Hardware solange "blind" 
programmieren, wie man Glück hat, dass alles klappt. Wenn aber der Wurm 
drin ist, kommt man ohne das richtige Messzeug nicht weiter.
Wenn Du gar keine Chance hast, ein Oszi zu bekommen, dann bastel Dir 
eine verbindung zwischen den Anschlüssen Data In und Data Out der 
SD-Karte (natürlich solange diese NICHT eingesteckt ist :-) und mach 
einen Loopback-test der SPI-Schnittstelle. Also ob das Byte, welches Du 
sendest auch wieder reinkommt.

2. Gebe nach JEDEM Schritt ALLE empfangenen Daten der SD-Karte auf Dein 
Terminal aus. Wenn gar nichts kommt, dann erzeuge zusätzliche 
Hilfsmeldungen und sieh nach, WO in den Funktionen ein Timeout erfolgt.
Roland hat ja schon die UART implementiert, also wo ist das Problem?

Es geht nur Schritt für Schritt. Und immer nur EINE Sache ändern bzw. 
testen, niemals MEHRERE gleichzeitig. Das ist extrem wichtig.
Und um Himmels Willen - besorg Dir irgendein billiges Oszi ;-)

Joachim



von Hansl (Gast)


Lesenswert?

joachim:

zu 1:
oszi hab ich keins, kenn niemanden mit einem und kann ich mir auch
dieses jahr wohl sicher keines leisten.

loopbacktest, klingt einleuchtend, mal sehn ob ich dazu code finden
kann.

zu 2:
das mit dem code aendern ist ja nicht so einfach wenn man nicht
versteht was da genau passiert. vorallem besteht bei mir eher die
gefahr das der code wenn ich drinn ein wenig rumruehre ploetzlich
nichtmehr tut und dann faengt das "wahllos herumstochern" erst an.

ein paar printfs in "uint8_t sd_raw_init()" waern schon praktisch.
mal gucken wie ich das angehen koennte. das Jahr ist ja noch lang :)


hab wohl immer eine sache geaendert :) mal die widerstaende 
ausgetauscht.
dann mal den takt geaendert, dann mal nen kondensator dazu, dann mal ne
neue MMC karte ran.....worauf willst DU HINAUS? (caps konnt ich mir ned
verkneifen ;))

mfg
 Hansl


von Joachim (Gast)


Lesenswert?

> loopbacktest, klingt einleuchtend, mal sehn ob ich dazu code finden
> kann.

Wirst Du kaum. Musst Du selber programmieren.
Aber es gibt sicher irgendwo Basisroutinen zum Schreiben und Lesen eines 
Wertes an/von SPI.
Um möglichst die originale Initialisierungssequenz zu nehmen, müsstest 
Du den Loopbacktest hier einfügen (in der Main.c):

 /* setup sd card slot */
    if(!sd_raw_init())
    {
#if DEBUG
        uart_puts_p(PSTR("MMC/SD initialization failed\n"));
#endif
        // HIER DEN LOOPBACK TEST
        return 1;
    }

Da beim betrieb ohne Karte und gebrücktem DIN/DOUT die Fehlermeldung 
natürlich vorprogrammiert ist, muss der Test genau hinter der 
Fehlermeldung rein. Der Vorteil: Du kannst die vorhandene SPI-Init 
nehmen.

> das mit dem code aendern ist ja nicht so einfach wenn man nicht
> versteht was da genau passiert.

Du sollst ja nicht sehr viel ändern, sondern nur ergänzen!
Der Trugschluss bei solchen Fremdprojekten ist, dass man sich die Arbeit 
sparen kann. Das geht, wenn man Glück hat und alles funktioniert (was in 
den seltensten Fällen so ist).
Wenn man aber hängt, braucht man viel Zeit, durchzusteigen.
Da solche Projekte meist schon sehr weit gediehen und optimiert sind, 
und mit allen möglichen Features ausgestattet, ist es sehr schwer, die 
relevanten Punkte herauszulesen. Man braucht oft lange, herauszufinden, 
WO WAS und WARUM definiert ist.
Geht mir auch nicht anders. Da muss man durch.
Ich mache es aber so: Wenn etwas absolut nicht laufen will, dann 
schreibe ich mir erstmal ein paar eigene Testprogramme für die Hardware. 
Erst wenn diese erfolgreich verlaufen, kehre ich wieder zum Projekt 
zurück.

Ich würde vorschlagen, Du vergisst erst mal die Sd-Karte und beginnst 
damit, die SPI-Schnittstelle selber mal zu programmieren (einen besagten 
Loopbacktest zu schreiben).
Wenn das dann funktioniert, kannst Du wieder zur SD-Karte zurückkehren.

Joachim

von Hansl (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

hab nun ein wenig herumkopiert und sende nun 0XFE als testwert.

scheine es aber nie zu empfangen.

hab ich da einen offensichtlichen fehler drinne?

oder ist meine hw total hinueber?

mfg
 Hansl


anbei das gaenderte main.c aus sd-reader_source_20070603
dabei handelt sichs eiegentlich nur um einwenig copy&paste
aus sd_raw.c.

von Hansl (Gast)


Lesenswert?

zur hardware... hab einfach mosi und miso verbunden.
ansonst, alles beim alten, atmega16@8Mhz(interner taktgeber), stk500
fuses:Fuse Low Byte = 0xd4, Fuse High Byte = 0xd9

mfg
 Hansl

von Hansl (Gast)


Lesenswert?

ok, klappt doch,

hab vergessen das ueberfluessige zeug auszukommentieren :)

nungut. also spi funktioniert also grundsaetzlich.


aendeurng in main.c von zuvor:

uint8_t sd_raw_rec_byte()
{
    /* send dummy data for receiving some */
//    SPDR = 0xff;
//    while(!(SPSR & (1 << SPIF)));
//    SPSR &= ~(1 << SPIF);
    return SPDR;
}


mfg
 Hansl

von Joachim (Gast)


Lesenswert?

> hab vergessen das ueberfluessige zeug auszukommentieren

Ahaaa ;-)

Na also, nachdem Deine SPI nun sendet und empfängt, musst Du sehen, ob 
das Chipselect signal für die Karte anliegt.
Das kann man leider nicht simulieren sondern nur messen.
Checke auch, ob Du den richtigen Port für das Selectsignal eingestellt 
hast.
Das Select ist definiert in der sd_raw_config.h für die verschiedenen 
Kontrollertypen:

#define select_card() PORTB &= ~(1 << xxxx)
#define unselect_card() PORTB |= (1 << xxxx)

Desweiteren würde ich für den Anfang die hohe Taktrate für die SPI 
abschalten und folgende Zeilen auskommentieren (in sd_raw_init() in der 
sd_raw.c). Das kannst Du gleich tun. Es beeinflusst die Gesamtfunktion 
nicht, schützt Dich aber vor weiteren möglichen Hardwareproblemen.

/* switch to highest SPI frequency possible */
    SPCR &= ~((1 << SPR1) | (1 << SPR0)); /* Clock Frequency: f_OSC / 4 
*/
    SPSR |= (1 << SPI2X); /* Doubled Clock Frequency: f_OSC / 2 */

Erst wenn die Karte komplett läuft, gibst Du dies wieder frei.
Läuft die Karte DANN nicht mehr, kannst Du sicher sein, dass Dein 
Interface den hohen Takt nicht veträgt und die Signale "verwaschen".

Tja - viel mehr fällt mir dann auch nicht mehr ein.

Joachim

von Hansl (Gast)


Lesenswert?

Immer noch kein Licht am Ende des Tunnels :(

Hab nun fogendes Setup:
 STK500 auf 3.3V konfiguriert, Atmega16 @ 8MhZ, JTAG deaktiviert
 ISP KABEL abgesteckt!

Hardwaresetup:
 PORTB4 ------- CARDSELECT, PIN1       (gemessen 3.3V)
 PORTB5 ------- DATAOUT,    PIN7
 PORTB6 ------- DATAIN,     PIN2
 PORTB7 ------- CLOCK,      PIN5
 VTG ---------- VCC,        PIN4       (gemessen 3.3V)
 GND ---------- GND,        PIN3 & PIN6

Software anbei. (Mit den von Jochaim empfohlenen Aenderungen)

falls irgendjemand noch ne idee hat worans liegen koennte...bitte 
schreien!

werd mir falls da nix mehr zu debuggen geht wohl oder uebel ne
platine aetzen und das ganze mal ohne stk500 probieren.

mfg
 Hansl

von Hansl (Gast)


Angehängte Dateien:

Lesenswert?

....

von Joachim (Gast)


Lesenswert?

Du weiss aber schon, dass bei dem Projekt 2 weitere Leitungen verwendet 
werden, mit denen die GESTECKTE Karte (SD_available) und der 
SCHREIBSCHUTZ (SD_Locked) abgefragt werden?
Der Schreibschutz ist erstmal unnötig.

In der sd_raw_config.h ist der Port fürs Erkennen der Karte definiert:
1
#define configure_pin_available() DDRC &= ~(1 << DDC4)
2
#define get_pin_available() ((PINC >> PC4) & 0x01)

In der sd_raw.c wird dies überall abgefragt.
Die Funktion dazu:
1
* \ingroup sd_raw
2
 * Checks wether a memory card is located in the slot.
3
 * \returns 1 if the card is available, 0 if it is not.
4
 */
5
uint8_t sd_raw_available()
6
{
7
    return get_pin_available() == 0x00;
8
}

Ich habe die bei mir geändert, weil ich auch keine Kartenerkennung 
benutze und dies zur Fehlermeldung geführt hätte:
1
uint8_t sd_raw_available()
2
{
3
    return 1; //get_pin_available() == 0x00;
4
}

Probier das mal.
Leider hast Du die konkrete Verdrahtung der Karte erst jetzt gepostet, 
sonst wäre mir das schon eher aufgefallen.

Joachim

von Hansl (Gast)


Lesenswert?

joachim:
 noe hatte ich tatsaechlich uebersehn.
 hab deine vorschlage alle ausprobiert.

 der hund ist leider immer noch drinn. die lexar karte funtioniert
 hier garnicht. eine 32mb nonamekarte eines freundes ergibt alle
 heiligen zeiten mal die meldung "opening partition failed".
 (power on, power off, power on, reset, reset....in irgendeiner
 reihenfolge und so oft man lust dazu hat)

 allerdings nur dann wenn ich PORTB &= ~_BV(PB6); also den internen
 pullup des MISO aktiviert habe. wenn ich das rausnehme bekomme
 ich die klassische..NIX DRANN meldung.

 ich werd wohl wie geplant demnaechst ne platine aetzen und das
 stk500 als fehlerquelle eliminieren.

mfg
 hansl

von Joachim (Gast)


Lesenswert?

Tja, dann bin ich auch am Ende meiner Weisheit.
Sorry.

Joachim

von Richard Brose (Gast)


Lesenswert?

Sehe ich das richtig? Ist die Standard Port-Belegung genau so wie bei 
dem ISA-Ctrl Webserver? Kann ich das so auf der Platine nutzen ohne 
irgendwelche Änderungen?

von Andreas W. (Gast)


Lesenswert?

@roland riegel

hi
ich habe dein testprogramm kompiliert und auf einen ATMega128 
geschrieben. Ich kann damit auf anhieb eine 64 MMC karte auf anhieb 
ansprechen, beschreiben und lesen.
Ich danke dir für so ein tolles programm, jetzt muss ich mir es nurnoch 
genauer angucken und verstehen.


Testbedingungen:
ATMega128 mit 6MHz, noname 64 MB MMC an Hardware-SPI

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Ich verwende Rolands (Danke!) Code als Basis für eine eigene extrem 
resourcengeizige MMC/SD-Anbindung an einen Mega8.
Die MMC-Karten sind noch unterwegs, in der Zwischenzeit habe ich mit 
Transcend 1GB miniSDcards (lagen noch von einem anderen Projekt herum) 
angefangen.
Folgende Zugriffe auf die Karte funktionieren: Init (modifiziert, nun 
ohne sd_raw_available und CMD_SET_BLOCKLEN==16) / 
CMD_SEND_CID/CMD_SEND_CSD.

Folgende Probleme treten auf
1) Single-Block Lesezugriff funktioniert auf volle Sektorvielfache 
(512byte). Bei Blockzugriffen auf Startadressen die nicht & ~0x1FF  sind 
hängt sich die Karte auf, keine Fehlermeldung.

2) die Adressierung auf der Karte hat einen Offset von 0x1FE00. D.h. der 
MBR erscheint bei 0x1FE00, der Rest ist entsprechend verschoben, aber 
sektorweise korrekt lesbar.

In der SanDisk MMC Doku habe ich auf dieses Verhalten keinen Hinweis 
gefunden, die Karte kann laut CSD bit79 partielle Zugriffe 
(READ_BL_PARTIAL).

Frage: hat jemand eine Idee ob das mit dem Offset an der SD liegt? Ich 
benötige die partiellen Zugriffe, um mit ganz weng SRAM schnell ein paar 
Bytes zu bekommen (waveform von SPI-MMC abspielen, über SPI-DAC, 
22050kHz Samplerate).

von Joachim (Gast)


Lesenswert?

> ..und CMD_SET_BLOCKLEN==16)

Wo gibts das? Ich sehe nur:
#define CMD_SET_BLOCKLEN 0x10
und das bedeutet nichts anderes, als dass der Kommandocode für 
SET_BLOCKLEN 0x10 (CMD16) ist. Und das schmeisst Du raus???

> 1) Single-Block Lesezugriff funktioniert auf volle Sektorvielfache
> (512byte). Bei Blockzugriffen auf Startadressen die nicht & ~0x1FF  sind
> hängt sich die Karte auf, keine Fehlermeldung.

Es sind gemäß Grundeinstellung keine Lesezugriffe kleiner als 512 Bytes 
erlaubt. Siehe:
1
/* set block size to 512 bytes */
2
    if(sd_raw_send_command_r1(CMD_SET_BLOCKLEN, 512))
Wenn Du die Startadresse nicht auf den Sektorstart legst, jedoch eine 
Blockgröße von 512 eingestellt ist, kommt es zu einem Sektorüberlauf
(Read Block Misalignment).

> Frage: hat jemand eine Idee ob das mit dem Offset an der SD liegt?
Nein.
Der Offset ist eine Eigenschaft des FAT-Filesystems.
Der MBR liegt nie gleich am Anfang der Karte.

In der Partitionstabelle ist der Offset angegeben, z.B.
"Sectors preceding partition 1: 237"
Der MBR liegt also in diesem Fall bei 0x1DA00



Joachim

von Andreas W. (Gast)


Angehängte Dateien:

Lesenswert?

Hi

ich habe mal eine kleine zusammenfassung geschrieben für Roland Riegels 
MMC/SD FAT16 code.

hoffendlich hat Roland Riegel nichts dagegen. und vieleicht hilf das ja 
einen weiter.

von michi (Gast)


Lesenswert?

Hallo,

ich verwende Rolands Code auf einem ATmega32 und möchte sehr viele Daten 
in vielen Dateien auf einer MMC schreiben - möglichst schnell.

Ich habe eine Testroutine erzeugt, welche 1000 Dateien mit der Größe 1kB 
erzeugt, alle im Root-Verzeichnis. Zum Debuggen lasse ich mit 
ausfühliche Infos per UART zum PC senden. Mir ist aufgefallen, dass 
schon nach ein paar Dateien das Erstellen und Öffnen der Dateien sehr 
lange (1 bis 5 Sekunden) Dauert. Ist das normal? Kann man das ganze 
beschleunigen? Würde es schneller gehen, wenn man Unterordner anlegt und 
darin die Datei schreibt?

michi

von holger (Gast)


Lesenswert?

>Ich habe eine Testroutine erzeugt, welche 1000 Dateien mit der Größe 1kB
>erzeugt, alle im Root-Verzeichnis.

Bei FAT12 und FAT16 kann man maximal 512 Dateien im RootDir anlegen.
Wenn sie nur 8.3 DOS Dateinamen haben jedenfalls. Mit
langen Dateinamen sind es höchstens noch die Hälfte. Eher weniger.
Wenn du 1000 Dateien anlegen willst musst du ein
Unterverzeichnis anlegen und dort die Dateien schreiben.

von michi (Gast)


Lesenswert?

Das mit den 512 Dateien ist klar, aber die Geschwindigkeit wurde schon 
nach 50 bid 80 Dateien im Root-Verzeichnis beachtlich langsam. Wo müsste 
man denn ansetzen um den Code von Roland zu optimieren?

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von michi (Gast)


Lesenswert?

Ich habe mehrere tausend Messungen mit unterschiedlichen Datensätzen und 
Längen.
Diese sollen direkt weiter verarbeitet werden können, ohne den Umweg 
über ein Tool, was eine große Datei erst wieder auseinander nehmen muss.

Eventuell erstelle ich schon vorher leere Dateien und lasse sie 
geöffnet. Das sollte doch problemlos möglich sein, auch wenn der 
Controller zwischendurch im Powerdown-Mode und die Karte ausgeschaltet 
wird oder?

von holger (Gast)


Lesenswert?

>Eventuell erstelle ich schon vorher leere Dateien und lasse sie
>geöffnet.

Wo merkst du dir für ein paar tausend offene Dateien z.B.
den Startcluster ? Der ist mindestens 16 Bit. Bei 1000
Dateien brauchst du also schon mal min. 2kB RAM. Dann musst du dir
noch merken an welcher Dateiposition du bei jeder Datei bist.
Pro Position 32 Bit. Bei 1000 Dateien noch mal 4kB.

Das war aber noch nicht alles was du dir merken musst :(

Dein Konzept ist nicht realisierbar.

von michi (Gast)


Lesenswert?

>Wo merkst du dir für ein paar tausend offene Dateien z.B.
>den Startcluster ? Der ist mindestens 16 Bit. Bei 1000
>Dateien brauchst du also schon mal min. 2kB RAM. Dann musst du dir
>noch merken an welcher Dateiposition du bei jeder Datei bist.
>Pro Position 32 Bit. Bei 1000 Dateien noch mal 4kB.
>
>Das war aber noch nicht alles was du dir merken musst :(

>Dein Konzept ist nicht realisierbar.

Doch, es sind nur ca. 10 Dateien gleichzeitig offen, eben 10 für jede 
Messung. Es werden pro Messung also 10 Dateien erstellt und es gibt 
später einige 1000 Messungen.
Ich hatte mich etwas unglücklich ausgedrückt, sorry.

Blöderweise bekomme ich sehr viele Daten in kurzer Zeit, so dass ich für 
jede geöffnete einen Buffer von min. 512 Byte brauche, damit es 
überhaupt mit dem Schreiben voran geht. Bei 4kB geht aber auch das 
nicht.... ich brauch ein neues Konzept.

Aber nebenbei mal: Rolands Code ist wirklich klasse!

von Niklas Eriksson (Gast)


Lesenswert?

Hello!

I hope that it is OK to post questions in English. I have a Atmega16 and 
STK500 evaluation board, using the software generated clock at 3.68Mhz, 
all is operating at 5V.
I haved used Rolands hardware connections and source code for 
interfacing SD card. UART working fine, but it is not possible to get 
any SD card to be accepted. 3 different types of SD cards has been 
tested, Toshiba 16MB, Kingston 1GB and RiData 512MB. The code is stopped 
at different positions depending on which card is used. 16MB cards is 
stopped when setting the block size to 512b, 512MB card stops after the 
verifing the FAT parameters, data_cluster_count is always larger than 
65525. 1GB card stops in this loop
1
while(sd_raw_rec_byte() != 0xfe)
 located in SD_RAW.C anyonelse got similar problems?

I think the problem for this is the partition table or what do you 
think?,
I have used FDISK to create partitions for "06 FAT16" should it be 
primary or logic? and then format it in which way?

Regards
Niklas

von Andreas W. (beinhartplus)


Lesenswert?

Hallo, hab das Filesystem in den Griff, hab nur probleme mit dem 
Stromverbrauch.
Wenn die Karte in den Schacht geschoben wird ist alles ok.
Jetzt wird die SD Karte initialisiert, beschrieben, gelesen, usw.
Dafür brauche ich so ca. 40 mA, alles ok.
Nachdem allerdings alle Vorgänge beendet sind, bleibt der Stromverbrauch 
bestehen.
Gibt es einen Befehl, eine Möglichkeit, die SD Karte zurück in den 
Standby Modus zu bringen ?

von Werner B. (Gast)


Lesenswert?

IIRC geht nach Spezifikation jede SD Karte nach einiger Zeit der 
Inaktivität automatisch in den Standby. Man muss nur den Chip-Select 
wegnehmen (und den Takt?). Eventuell liest du die Karte nicht 
vollständig aus (Dummy-CRC etc.)
Ich schicke der SD Karte in meinen Programmen am Ende immer noch ein 
Dummy-0xFF, nehme den Chipselect weg und schicke noch ein 0xFF um der 
Karte einen Takt zum "Runterfahren" zu geben.

von Robero (Gast)


Lesenswert?

Hallo,
Super Projekt!!!
ist es irgendwie möglich das es auch auf nem Atmega8 Funktioniert?
Gruß Robert

von Karl (Gast)


Lesenswert?

@ Niklas Eriksson,

I got similar problems, I use a different Compiler (CrossStudio for AVR)

I made some wrong settings (Datastacksize - was too small, and I used 
some Compiler-Optimization (10 hours of my life 4 nothing :-) ))

best regards

KL

von ptiszai (Gast)


Lesenswert?

I used the roland-riegel sd/mmc AVR source with atmel128, 16 Mhz.
(version 2007.01.20)
http://www.roland-riegel.de/sd-reader/index.html
It is good 512Mb SD/MMC cards, but 64 Mb and 128Mb is bad.
Why?
best regards
Istvan Tiszai from Budapest

von Steffen-SD (Gast)


Lesenswert?

Hallo,
bin neu hier. Habe ein SD-Projekt welches seid jahren läuft. Jetzt tritt 
bei einem neuen Typ SD-Card (256MB PLATINUM) das Problem auf das beim 
lesen eines Blocks (Sektors Byte 0-511 +2CRC) an Stelle Byte5 immer die 
0x04 gelesen und beim lesen vom MBR an Stelle Byte4 0x0F im Root bei 
Byte4 die 0x3F und im Bootsektor bei Byte4 die 0x5F gelesen werden. Das 
ist mit allen Karten diesen typs so. Mit Cardreader gelesen ist aber 
alles ok. Bei anderen Karten wie EXTREMEMORY habe ich das Problem nicht!
Hat jemand ne Ide??

von Joachim Müller (Gast)


Lesenswert?

Es kann am SPI-Signal selbst liegen. Manche Karten reagieren 
empfindlicher auf langsame Flanken. Ich hatte so ein Problem auch bei 
einer Serie von SanDisk Karten. Die waren (mit dem 
Spannungsteileraufbau) nicht zu gebrauchen. Bei einem neuen Design mit 
3,3V Logik (steile Flanken) funktionierten die plötzlich auch. Bei hoher 
Taktrate kann es passieren, dass die Pegel nicht mehr ganz auf VCC bzw. 
GND gehen, sondern irgendwo "in der Luft hängen". Manche Karten vetragen 
das besser als andere.
Ich würde mir mal die SPI-Signale anschauen. Wenn die "verwaschen" sind, 
die Widerstandswerte für den Spannungsteilen reduzieren. Dann werden die 
Flanken steiler und es könnte wieder klappen.

Joachim

von Karoly K. (koka55)


Lesenswert?

Hallo Roland,

Habe Dein Programm getestet.
Erste Erfahrugen waren ausreichend, grösseren Dateien zu SCHREIBEN ist 
es aber wahnsinnig langsam.

(Habe beim Schreiben eines Datenblock zum UART ein '.' gesendet. :))) )

Mit 1Mbyte Dateigrösse geht es so: am Anfang laufen die Punkte 
blitzschnell, am Ende kommen nur "Schrittweise".
Eine Datei von 50-100kByte geht es in ca. 10 Sekunden, 1Mbyte zu 
schreiben dauert aber ca. 4(!) Minuten! Das ist gar nicht linear (u. 
akzeptabel).

Habe ein bisschen im Programm nachgeforscht, es sieht so, dass bei der 
Clusterallokation ist was irgendwie zu langsam.
Oder?

Kannst Du mir was dazu sagen?

Vielen Dank,
Karoly

von Gast (Gast)


Lesenswert?

Hallo Leute

Wie kann man 2 Dateien gleichzeitig öffnen?

Danke und Gruss


So geht es nicht....
1
struct fat16_file_struct* fd1 = open_file_in_dir(fs, dd, "temp.txt");
2
if(!fd1)
3
{
4
 uart_puts_p(PSTR("error opening1 "));
5
}
6
7
//search file in current directory and open it 
8
struct fat16_file_struct* fd2 = open_file_in_dir(fs, dd, "temp2.txt");
9
if(!fd2)
10
{
11
 uart_puts_p(PSTR("error opening2 "));
12
}

von Gast (Gast)


Lesenswert?

Muss ich etwa 2 Partitionen machen und jedes File aus einer anderen 
Partionion auslesen? (geht doch sicherlich auch noch einfacher)

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo,

Kurz gesagt: RTFM!

In fat16_config.h:
  #define FAT16_FILE_COUNT 2

Gruß,
Roland

von Christian S. (stephanc)


Lesenswert?

Hallo,

auch ich bin derzeit ein wenig am probieren. Grundsätzlich funktioniert 
auch alles (eher selten bei mir) - solange es in der Hauptschleife läuft 
(main).

Jetzt wollte ich mir ein paar Funktionen anlegen, um etwas Struktur in 
den Code zu bringen.

Bis jetzt ist es mir nicht gelungen, die Dateioperationen, in einer 
Funktion zum Laufen zu bewegen.

Ausgehend vom beiliegend Beispiel main.c -> sd-reader.hex habe ich den 
Part print_disk_info(fs) in eine Funktion geschrieben und selbige im 
main auskommentiert.

Original:
1
int main()
2
{...
3
/* print some card information as a boot message */
4
print_disk_info(fs);
5
...}

Versuch:
1
void test(void);
2
int main()
3
{...
4
/* print some card information as a boot message */
5
//print_disk_info(fs);
6
test();
7
...}
8
9
void test()
10
{
11
print_disk_info(fs);
12
}

Hoffe, es ist einigermaßen verständlich.

Als Fehlermeldung erhalte ich :
error: 'fs' undeclared (first use in this function)

Im Moment trete ich auf der Stelle und weiß nicht so recht, wo ich 
ansetzen kann/soll.

Viele Grüße
 Stephan

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Stephan!

Schaue bitte in jedes beliebige Buch oder Online-Tutorial, welches eine 
Einführung in C liefert. In Deinem Fall ist da insbesondere der 
Abschnitt über den Gültigkeitsbereich von Variablen interessant.

Die Fehlermeldung des Compilers sagt eigentlich schon alles. Kurz 
gesagt: Die Variable fs, die Du der Funktion print_disk_info() 
übergibst, muss in der aufrufenden Funktion test() oder zumindest im 
globalen Gültigkeitsbereich auch existieren.

Gruß,
Roland

von Karoly K. (koka55)


Lesenswert?

Hallo Roland,

Kónntest Du bitte evtl. meine Frage auch beantworten? (Siehe 20.11.2007 
09:33)

Danke,
Karoly

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Karoly!

Nun, FAT16 ist insgesamt relativ ineffizient, vor allem mit wenig 
Pufferspeicher. Das nur vorweg.

Ansonsten solltest Du bzgl. meines Codes auf mehrere Dinge achten:
- SD_RAW_WRITE_BUFFERING unbedingt auf 1 stellen.
- Wenn reichlich RAM bereitsteht, den Schreib-/Lesepuffer vergrößern 
(nur mit manuellen Codeänderungen möglich).
- Der Datenblock, der fat16_write_file() übergeben wird, sollte 
möglichst groß sein.
- Statt immer an das Ende der Datei zu schreiben, zu Beginn 
fat16_resize_file() aufrufen, danach ab Position 0 die Datei füllen. Das 
sollte die abwechselnden Schreibzugriffe auf die FAT, die Datei-Cluster 
sowie den Verzeichniseintrag unterbinden, so dass SD_RAW_WRITE_BUFFERING 
wesentlich besser greifen kann.

So, ich denke das sollte Dir erst mal weiterhelfen.

Gruß,
Roland

von Micha (Gast)


Lesenswert?

Hallo,
ich versuche mich auch gerade bei der SD-Ansteuerung an einen 
ATmega324P. Als Levelshifter dient der MAX3378E, die 3.3V liefert ein 
extra Spannungsregler.
Bei der SD Karte handelt es sich um eine SanDisk 1GB Standard (Rd/Rw: 
3MB/s)

Die Funktion sd_raw_init() funktioniert fehlerfrei, es wird jedoch nicht 
das Filesystem (FAT16) der SD-Karte erkannt. Nach dem Einlesen des FAT16 
Headers springt er zurück, da sectors_per_fat = 0.
Nun habe ich schon vielerlei Formatierungen ausprobiert, über die 
Datenträgerverwaltung (Format mit "FAT") und mkdosfs sowie eine 
Low-Level-Formatierung mit dem Panasonic SD Formatter und anschließender 
Windows-Formatierung. Auslesen der SD Karte mit WinHex zeigte, dass in 
allen Fällen ein FAT16-System erfolgreich angelegt wurde. Nur der 
Controller will dies nicht so recht glauben.

Noch etwas: Lasse ich alle Initalisierungsroutinen in der Endlosschleife 
laufen, erkennt er im zweiten Durchlauf auch nicht mehr die Partition. 
Direkt  nach dem Controllerreset versucht er zumindest, das Filesystem 
zu öffnen.

Woran kann das liegen?

Danke im Voraus
Gruß Micha

von Kai Bankett (Gast)


Lesenswert?

Ich habe mich letzte Nacht auch mit dem Anschluß von SD-Karten bespasst, 
daher sind meine Erfahrungswerte noch recht frisch ;)
sectors_per_fat = 0 konnte ich dadurch beheben, daß ich erst die 
Partition -1 versuche und dann 0 - in umgekehrter Reihenfolge zu dem 
Beispiel-main.c
Das Problem mit den mehreren Durchläufen hatte ich auch. Du mußt die 
verschiedenen Pointer wieder freigeben (partition_close, fat16_close 
etc.), dann klappt es auch mit den mehrfachen Durchläufen.

Gruß,

Kai

von Micha (Gast)


Lesenswert?

Hallo Kai,

danke für deine schnelle Hilfe, mein Initialisierungsproblem ist auch 
fast gelöst. Tatsächlich lässt sich Partition 0 nicht öffnen, folglich 
versucht er Partition -1 (Originalcode), was dann auch klappt. Danach 
lässt sich jedoch nicht das Filesystem öffnen. Lasse ich jedoch die 
Initalisierung erneut ablaufen (nach Pointerfreigabe, also 
partition_close() und fat16_close()) liest er plötzlich Partition 0 
erfolgreich und erkennt auch ein FAT16 Dateisystem! Was ist denn nun 
passiert?

Kehre ich die Partitionsreihenfolge um, wie du vorgeschlagen hast, 
öffnet er das FAT16 nicht (nicht mal nach mehreren Durchläufen).

Gruß Micha

von Roland R. (roland) Benutzerseite


Lesenswert?

Einige Anmerkungen:

Partition -1 zu öffnen klappt immer. Das liegt aber daran, dass er die 
Karte in diesem Fall als Superfloppy (d.h. als einziger Datenbereich 
ohne Partitionstabelle) behandelt und deshalb auch keine Überprüfungen 
bzgl. der Existenz der Partition machen kann.

Es ist also kein Zeichen von "Erfolg", wenn Partition -1 geöffnet werden 
kann. Auf dieser ein Dateisystem zu öffnen klappt aber hingegen nur, 
wenn die Karte auch wirklich als Superfloppy formatiert ist.

Wenn also schon das Öffnen der Partition 0 scheitert, liegt dies nur 
an der Partitionstabelle, entweder weil die Partition nicht existiert, 
die Partitionstabelle fehlerhaft ist oder diese nicht existiert.

Unter Linux klappt die Formatierung einer Karte so:

1. Karte einlegen.
2. Im Syslog nachschauen, unter welchem Namen sie eingebunden wurde.
   Annahme für die weiteren Schritte: /dev/sdc.
3. fdisk /dev/sdc
   o (Partitionstabelle löschen)
   n (neue Partition)
   p (primäre Partition)
   1 (<-- eine Eins; erster Eintrag in Partitionstabelle)
   <Enter>
   <Enter> (Partition über gesamte Karte)
   t (Partitionstyp ändern)
   6 (Typ: FAT16)
   p (Partitionierung ausgeben; überprüfen!)
   w (Partitionstabelle schreiben)
4. mkdosfs -F 16 /dev/sdc1 (<-- auf die Eins am Ende achten)

Windows erzeugt meines Wissens nach eine Superfloppy.

Grüße,
Roland

von Joachim (Gast)


Lesenswert?

> Windows erzeugt meines Wissens nach eine Superfloppy.

Nee, macht auch ne Partition.

Joachim

von Karoly K. (koka55)


Lesenswert?

@Roland: Danke für die Hilfe, ich werde es unbedingt austesten!

Karoly

von Kai Bankett (Gast)


Lesenswert?

Ich habe gestern auf jeden Fall meinen Code derart erweitert, daß ich 
erst Partition 0 öffne und versuche auf das FAT16 zuzugreifen. Schlägt 
dies fehl, dann close ich Partition 0 und versuche es mit Partition -1. 
Erst wenn dies fehlschlägt, dann gibt es einen Fehler.
Damit konnte ich erfolgreich alle (10 verschiedene) SD-Karten, derer ich 
habhaft werden konnte und die auf verschiedenen Geräten/OSen formatiert 
wurden, lesen.
Ich habe aber noch ein paar Modifikationen an Roland's Code durchgeführt 
:
- Software SPI - umschaltbar HW SPI / SoftSPI per #define im Header-File
- An ein paar Stellen while (result = 0xfe); ersetzt durch eine 
Schleife, welche ein definiertes Ende hat
- FAT32-Support angefangen zu implementieren (auch Header-File Option)

Werde Roland mal einen Patch zukommen lassen - mal sehen, ob er die 
Änderungen gebrauchen kann.

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Kai,

> Ich habe gestern auf jeden Fall meinen Code derart erweitert, daß ich
> erst Partition 0 öffne und versuche auf das FAT16 zuzugreifen. Schlägt
> dies fehl, dann close ich Partition 0 und versuche es mit Partition -1.
> Erst wenn dies fehlschlägt, dann gibt es einen Fehler.

Nun, das ist doch genau das Vorgehen, welches ich in meinem Code 
verwende?

> - FAT32-Support angefangen zu implementieren (auch Header-File Option)
>
> Werde Roland mal einen Patch zukommen lassen - mal sehen, ob er die
> Änderungen gebrauchen kann.

Schön. Dazu dann alles weitere per Mail.

Gruß,
Roland

von Torsten S. (tse)


Lesenswert?

> Schön. Dazu dann alles weitere per Mail.

Hhm. Interessiert wäre ich auch, schade das ihr das nicht öffentlich 
macht.

Btw: Mein modifizierter SD-Reader funktioniert seit knapp einem Jahr im 
Dauereinsatz tadellos.

:-)

Torsten

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Torsten,

>> Schön. Dazu dann alles weitere per Mail.
>
> Hhm. Interessiert wäre ich auch, schade das ihr das nicht öffentlich
> macht.
>

Nunja, das wird eh kaum in näherer Zukunft in meinen Code kommen, weil 
mein kleiner mega168 eh schon mit knappem Speicher kämpft, und von dem 
braucht FAT32 schon ein gutes Stück mehr. Da müsste ich mir also einen 
anderen Aufbau z.B. mit mega32 oder gleich einem ARM überlegen.

Aber ich denke, Kai ist auch bereit den Patch hier im Forum zu posten...

> Btw: Mein modifizierter SD-Reader funktioniert seit knapp einem Jahr im
> Dauereinsatz tadellos.
>

Schön zu hören!

Gruß,
Roland

von Kai Bankett (Gast)


Lesenswert?

Sollte den Code nicht größer machen, wenn man FAT32_SUPPORT 0 setzt.
Root-Directory klappt schon.
Freier Speicher auch fertig.
Werde mich nun gleich noch einmal kurz an die 
Cluster-FAT32-Verkettungsroutinen setzen. War wohl gestern zu blind um 
den Fehler zu sehen 8)
Nevertheless, ja, klar kann (und werde) ich den Patch dann hier auch 
veröffentlichen.

von Kai Bankett (Gast)


Lesenswert?

Anbei der angekündigte Patch. Ist leider doch etwas mehr Modifikation 
geworden ...
Auf jeden Fall sollten SDHC-Karten und FAT32 funktionieren. Die 
SDHC-Initialisierung habe ich derzeit nicht Präprozessorgesteuert 
gemacht. FAT32 support kann im Header-File deaktiviert werden.
Ich hoffe ich habe den Code soweit gut genug aufgeräumt - es waren doch 
intensivere Debug-Sessions nötig, welche einige debug()-Calls nach sich 
gezogen haben.
Sollte aber alles "DEBUG_FAT16, DEBUG_SD, DEBUG_PARTITION" bzw. 
"VERBOSE_FAT16, VERBOSE_SD, VERBOSE_PARTITION" geklammert sein und daher 
bei nicht existenten Defines sauber kompilieren.
Im partition.c habe ich außerdem die Partitionserkennung/-prüfung 
erweitert.

Mit den Berechnungen (block >> 9), (block_offset) beim Aufrufen der 
sd_raw_* void*-Funktionspointer, bin ich noch nicht ganz glücklich. Wenn 
jemand eine bessere Idee hat ... der Code ist ja nun passend zu den 
Feiertagen ...

Viel Spaß! :)

Kai

von Kai Bankett (Gast)


Angehängte Dateien:

Lesenswert?

Hier nun hoffentlich mit Attachment ...

von Torsten S. (tse)


Lesenswert?

Wow, exzellente Arbeit!

Ich habe mir das diff-file nur kurz angeschaut. Mehr als 3400 Zeilen, 
einige neue Dateien. Unmöglich das per Hand in mein Projekt fehlerfrei 
einzubauen um das mal auszuprobieren.

Deswegen meine Frage: Wenn es Dir nichts ausmacht, kannst Du vielleicht 
den SD-Reader inklusive der neuen Sachen in ein .zip packen und hier 
veröffentlichen?

Der Patch ist ein richtig dicker Brocken... Welche MCU hattest Du zum 
debuggen, wegen Ram etc.?

Torsten

von Kai Bankett (Gast)


Lesenswert?

Danke für das positive Feedback :)
Ich wollte Roland eigentlich erst einmal die Entscheidung zum Einbau 
überlassen.
Kann aber sonst auch gerne mal ein komplettes Zip-File als 
"FAT32-Version" hochladen.
Neue Files sollten eigentlich nicht drin sein. Habe gerade auch noch 
einmal in den Patch gesehen und konnte keine finden. Welche neuen Files 
versucht er denn bei dir zu erstellen?
Zum debuggen habe ich ein m2561 mit S65-Display verwendet. Den 
zusätzlichen Speicherverbrauch habe ich auch noch nicht überprüft - 
hatte hierbei auch auf Roland gehofft, da er ja wohl eine passende 
Referenz-Plattform zur Verfügung hat und die Werte daher auch einfacher 
mit seinen vergleichen könnte. (ich hoffe der Code ist nicht zu groß für 
die von ihm verwendete CPU geworden)
Grundsätzlich sollte man natürlich auch die Nachteile von FAT32 
bedenken. Der deutlich größere FAT-Table verursacht natürlich einiges an 
Kosten auf der CPU und auf dem SD-Interface.  Die Überprüfung auf freien 
Speicherplatz (FAT16/FAT32) verdeutlicht dies auch eindrucksvoll.
Mit mehr Speicher sähe die Situation anders aus - nicht für den 
Speicher, aber für die Performance ;)
Vielleicht komme ich ja noch dazu einen Patch für 32 oder 64k zu machen. 
64k (56k nutzbar)  wären für mich sehr elegant, da man dann auch über 
ein performates .png deflate nachdenken könnte, was für mein Projekt 
sehr nett wäre. Schaue mir gerade mal die zlib an ...

von Torsten S. (tse)


Lesenswert?

Kai Bankett wrote:
> Danke für das positive Feedback :)

Gerne. Kein Anfängerwerk btw.

> Neue Files sollten eigentlich nicht drin sein. Habe gerade auch noch
> einmal in den Patch gesehen und konnte keine finden. Welche neuen Files
> versucht er denn bei dir zu erstellen?

Oops, Du hast recht. Ich habe mich nur durch "-FAT32" irritieren lassen:
--- SD-Card/fat16.c
+++ SD-Card-FAT32/fat16.c
Wobei der Dateiname nun nicht mehr passt.

> Zum debuggen habe ich ein m2561 mit S65-Display verwendet. Den
> zusätzlichen Speicherverbrauch habe ich auch noch nicht überprüft -

Mit diesem Monster sollte es keine Speicher-Probleme geben. ;)

> hatte hierbei auch auf Roland gehofft, da er ja wohl eine passende
> Referenz-Plattform zur Verfügung hat und die Werte daher auch einfacher
> mit seinen vergleichen könnte. (ich hoffe der Code ist nicht zu groß für
> die von ihm verwendete CPU geworden)

Er ist mit Sicherheit zu groß. In einen M168 passt das nicht mehr rein.

> Grundsätzlich sollte man natürlich auch die Nachteile von FAT32
> bedenken. Der deutlich größere FAT-Table verursacht natürlich einiges an
> Kosten auf der CPU und auf dem SD-Interface.  Die Überprüfung auf freien
> Speicherplatz (FAT16/FAT32) verdeutlicht dies auch eindrucksvoll.
> Mit mehr Speicher sähe die Situation anders aus - nicht für den
> Speicher, aber für die Performance ;)

Das ist ganz klar. Alles hat seinen Preis.
Nun mache ich mir Sorgen ob das auch in einen M644 noch rein paßt. Einen 
M32 mußte ich schnell ersetzen. Der hat zwar noch für den reinen 
SD-Reader gereicht aber nicht mehr für Erweiterungen.

> Vielleicht komme ich ja noch dazu einen Patch für 32 oder 64k zu machen.
> 64k (56k nutzbar)  wären für mich sehr elegant, da man dann auch über
> ein performates .png deflate nachdenken könnte, was für mein Projekt
> sehr nett wäre. Schaue mir gerade mal die zlib an ...

Ähm, was meinst Du mit 32 oder 64k, SRAM oder Cluster-Größe etwa?

Ein paar typos habe ich auf die Schnelle gefunden:
1
+debug(S_PSTR("CHAOSMAN D0"));
2
+#ifdef DEBuG_FAT16

von Kai B. (chaosman)


Lesenswert?

Torsten S. wrote:
> Oops, Du hast recht. Ich habe mich nur durch "-FAT32" irritieren lassen:
> --- SD-Card/fat16.c
> +++ SD-Card-FAT32/fat16.c
> Wobei der Dateiname nun nicht mehr passt.

Du mußt patch mit der Option -pX aufrufen, je nachdem in welchem 
Verzeichnis du dich befindest. Sollte funktionieren, wenn du den Patch 
in das Verzeichnis legst, in dem sich auch die zu patchenden Files 
befinden und -p0 verwendest.
Auf jeden Fall ist es beim GNU-patch unter Unix so. Ich weiß ja nicht, 
ob du diesen benutzt hast, sonst mußt du schauen, wie die Option zum 
abschneiden des 1. Directories bei der von dir verwendeten Applikation 
benutzt wird.

>
> Er ist mit Sicherheit zu groß. In einen M168 passt das nicht mehr rein.
>

Hm. Das ist schade. Man könnte natürlich noch Ballast rauswerfen. SDHC 
z.B., wobei FAT32 dann natürlich nicht mehr wirklich Sinn macht.

> Das ist ganz klar. Alles hat seinen Preis.
> Nun mache ich mir Sorgen ob das auch in einen M644 noch rein paßt. Einen
> M32 mußte ich schnell ersetzen. Der hat zwar noch für den reinen
> SD-Reader gereicht aber nicht mehr für Erweiterungen.

Wie gesagt, eindampfen kann man sicherlich noch. Ich müßte nur wissen, 
wieviel fehlt. So viel ist nun auch wieder nicht dazu gekommen. Man 
könnte sich natürlich nur auf FAT32 beschränken. Dann spart man sich 
einen Teil dessen, was dazu gekommen ist.

> Ähm, was meinst Du mit 32 oder 64k, SRAM oder Cluster-Größe etwa?

War auf die Menge an RAM bezogen. Mit mehr Speicher kann man mehr 
cachen. Den FAT komplett, oder auch nur teilweise, zu cachen würde eine 
Menge bringen.

> Ein paar typos habe ich auf die Schnelle gefunden:
>
1
+debug(S_PSTR("CHAOSMAN D0"));
2
> +#ifdef DEBuG_FAT16

Ja, danke! Ist korriegiert.

Kai

von Martin (Gast)


Lesenswert?

Hallo zusammen,

ich versuche mich gerade daran, mit einem ATmega324P eine SD-Karte 
anzusteuern; dabei verwende ich allerdings das USART im SPI-Modus 
anstelle des regulären SPI, da ich dieses in meiner Schaltung 
anderweitig benutze.

Schreiben und Lesen funktioniert im Prinzip: in einem ersten Versuch 
habe ich mit sd_raw_write()/sd_raw_sync() 250 Byte auf die Karte 
geschrieben und konnte die mit sd_raw_read() auch wieder lesen.

In meinem derzeitigen Programm rufe ich zunächst die Funktionen auf:
  sd_raw_init();
  partition_open(...);
  fat16_open(...);
  fat16_get_dir_entry_of_path(...);
  fat16_open_dir(...);
dabei treten keine Fehler auf.

Dann versuche ich, eine Datei zu erzeugen und etwas hineinzuschreiben:
  fat16_create_file(dd,"datei.tst",&dir_entry);
  fd = fat16_open_file(fs,&dir_entry);
//  fat16_resize_file(fd,1500);
  fat16_write_file(fd,"Hallole!",8);
  fat16_close_file(fd);
  sd_raw_sync();

Die Datei wird zwar angelegt, sie wird beim Schreiben aber nicht 
vergrößert. Kontrolle am PC zeigt eine Datei der Länge 0. Wenn ich die 
nun am PC beschreibe, kann auch der Controller den String 
hineinschreiben.

Der Aufruf von fat16_resize_file() hilft nicht weiter, da bleibt das 
Programm hängen beim Aufruf von device_write() in 
fat16_write_dir_entry() (Zeile 1764 in fat16.c)


Hat da jemand eine Idee, was da schiefläuft?

Danke im voraus
Martin

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Martin,

Könntest Du bitte genauer sagen, wo sd_raw_write() hängen bleibt?

Des weiteren könntest Du versuchen herauszufinden, warum es nicht hängen 
bleibt, wenn fat16_write_dir_entry() aus fat16_create_file() oder 
fat16_write_file() heraus aufgerufen wird. Schalte doch mal für Deine 
Tests SD_RAW_WRITE_BUFFERING aus, dann treten mögliche Schreibprobleme 
sofort auf und nicht erst dann, wenn der Puffer geschrieben wird.

Ehrlich gesagt vermute ich eher ein Hardwareproblem. Aber mal sehen...

Gruß,
Roland

von Martin (Gast)


Lesenswert?

Hallo Roland,

das Problem tritt bereits bei fat16_create_file(), nur nicht so 
offensichtlich. Ich habe gestern abend noch folgendes ausprobiert:

  uint8_t result = 0;
  if ( !fat16_create_file(dd,"datei.1",&dir_entry) ) result++;
  if ( !fat16_create_file(dd,"datei.2",&dir_entry) ) result++;
  if ( !fat16_create_file(dd,"datei.3",&dir_entry) ) result++;
  if ( !fat16_create_file(dd,"datei.4",&dir_entry) ) result++;
  if ( !fat16_create_file(dd,"datei.5",&dir_entry) ) result++;
  if ( !fat16_create_file(dd,"datei.6",&dir_entry) ) result++;
  if ( !fat16_create_file(dd,"datei.7",&dir_entry) ) result++;
  if ( !fat16_create_file(dd,"datei.8",&dir_entry) ) result++;
  if ( !fat16_create_file(dd,"datei.9",&dir_entry) ) result++;
  sd_raw_sync();
  if ( !result ) for (;;) PORTB ^= 0x0E;    // alles ok
  else for (;;);                            // Fehler!

Wenn ich SD_RAW_WRITE_BUFFERING eingeschaltet habe, wird nur datei.1 
angelegt. Schalte ich dagegen SD_RAW_WRITE_BUFFERING aus, werden datei.1 
bis  datei.4 oder datei.5 erzeugt, außerdem datei.9. Aber nur unter 
Linux sind die Dateien auch zu sehen, manchmal wird eine Datei auch 
doppelt angezeigt! Windows zeigt nur ein leeres Verzeichnis an.

Da ich in Deinem Code die Funktionen sd_raw_init(), sd_raw_send_byte() 
und sd_raw_send_byte() geändert habe, könnte natürlich auch hier irgend 
etwas passieren, obwohl ich das weniger glaube, da ich das doppelt und 
dreifach gegen das Datenblatt verglichen habe.

Ich habe mir gestern noch ein STK500 und eine Handvoll Controller 
bestellt, die sind vorhin angekommen. Mal sehen, ob ich Deinen 
Originalcode da zum Laufen bringe und da zu irgendeiner Erkenntnis 
komme.

Gruß
Martin

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Martin,

Mir fehlen einige Infos, um selbst irgendwas testen zu können.

1. Was ist denn der Wert von result in Deinem Test?
2. Kannst Du mir ein Karten-Image zukommen lassen?
3. Werden die Dateien im Wurzelverzeichnis oder in einem 
Unterverzeichnis angelegt?
4. Wie hast Du denn die Karte formatiert? Du solltest die Karte nach 
jedem Test löschen, so dass evtl. kaputte FAT-Strukturen nicht weitere 
Effekte auslösen können.
5. Wie stark ausgelastet ist der Controller sonst? Besteht die 
Möglichkeit von Stack-Überläufen?

Gruß,
Roland

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Roland,

> 1. Was ist denn der Wert von result in Deinem Test?
Bei ausgeschaltetem SD_RAW_WRITE_BUFFERING hat result den Wert 0, obwohl 
nicht alle Dateien angelegt werden. Im Fall von Doppeleinträgen, d.h. 
wenn derselbe Dateiname zweimal angezeigt wird, erhalte ich den Wert 4.
Schalte ich SD_RAW_WRITE_BUFFERING ein, erhalte ich ebenfalls den Wert 
0, wenn ich fat16_create_file() einmal aufrufe. Rufe ich die Funktion 
zweimal oder öfter auf, bleibt das Programm hängen und ich komme erst 
gar nicht zu meiner Endlosschleife, die erste Datei (datei.1) wird aber 
angelegt.
Für die Tests habe ich die Karte jedesmal formatiert.

> 2. Kannst Du mir ein Karten-Image zukommen lassen?
Ich habe 1MB-Images von drei verschiedenen Karten angehängt, jeweils mit 
(*-mb) und ohne (*-ob) Buffering.

> 3. Werden die Dateien im Wurzelverzeichnis oder in einem
> Unterverzeichnis angelegt?
Die Dateien stehen im Wurzelverzeichnis.

> 4. Wie hast Du denn die Karte formatiert?
Mit mkdosfs -F16 /dev/sda1 unter Linux.

> 5. Wie stark ausgelastet ist der Controller sonst?
Im Moment dreht er nur Däumchen, d.h. ich setze lediglich ein paar 
Port-Pins und versuche dann, die Karte anzusprechen, sonst passiert noch 
nichts.

Gruß
Martin

von Bernhard S. (bernhard)


Lesenswert?

Hallo,

ein ATmega8 bedient eine SD-Karte (FAT16), ist allerdings nur Assembler:

Beitrag "SD-Karte Initialisierung Read Write FAT ATmega8 (Assembler)"


Gruß

Bernhard

von Roland R. (roland) Benutzerseite


Lesenswert?

Servus Martin,

Nach kurzem Überfliegen der Images kann ich schonmal soviel sagen:
1. Das was Windows und Linux anzeigen, ist plausibel und durch 
geringfügig andere FAT-Implementationen erklärbar.
2. Ohne Pufferung fehlen die LFN-Verzeichniseinträge bzw. sind leer. Mit 
Pufferung sind sie vorhanden.
3. Der Platz für die Verzeichniseinträge der fehlenden Dateien ist zwar 
vorhanden, enthält aber auch nur Nullen.
4. Die doppelt vorhandenen Dateien sind so tatsächlich auch im 
Verzeichnis eingetragen.

Da stimmt irgendetwas überhaupt nicht. Entweder die SD-Routinen geben 
Erfolg zurück, obwohl nichts geschrieben wurde, oder es gibt einen Bug 
an anderer Stelle. Wie machst Du denn die Stromversorgung und das 
Level-Shifting für die Speicherkarte?

Magst Du mir vielleicht Dein Testprogramm inklusive der von Dir 
durchgeführten Änderungen an sd_raw.c schicken? Evtl. fällt mir da noch 
irgendwas auf.

Vielleicht finde ich morgen etwas Zeit, um Deinen Test nachzubauen und 
evtl. den Fehler zu reproduzieren.

Viele Grüße,
Roland

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Roland,

meine Schaltung läuft mit 3,3V; damit sollte die Karte eigentlich 
zufrieden sein. Der externe Takt ist 18MHz, den internen Systemtakt habe 
ich sicherheitshalber auf die Hälfte reduziert.
Mein Testprogramm habe ich angehängt, die Hauptänderungen sind in 
sd_raw_init(), sd_raw_send_byte() und sd_raw_rec_byte() (s. 
aenderungen).

Gruß
Martin

von Roland R. (roland) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo Martin,

Gestern konnte ich Deine Probleme teilweise reproduzieren. Bei mir 
scheiterte allerdings nur das korrekte Anlegen der achten Datei. Nach 
viel erfolglosem Debugging hat sich rausgestellt, dass (zumindest bei 
mir) tatsächlich der Stack in den statisch allokierten Heap 
reingewachsen ist.

Sobald ich nicht so viel Speicher verbraucht habe, indem ich z.B. die 
Dateien nur noch einstellig benannt habe, lief alles so wie es sollte.

Ich habe mir mal Dein Programm bzgl. des benutzten Speichers angeschaut:
- Puffer
512+5 Bytes
- Handles für Partition, Dateisystem, Dateien, Verzeichnisse
17+26+51+94 Bytes
- Stack in main():
ca. 95 Bytes
(zumindest mein Compiler optimiert die insgesamt 252 Bytes großen aber 
unbenutzten Variablen weg)
- Zeichenfolgen in main():
72 Bytes
- Stack für FAT-Aufrufe:
schätzungsweise ca. 60 Bytes

Insgesamt sind das knapp 940 Bytes. Dein Controller hat 2 kBytes, es 
sollte also nicht zu Problemen kommen. Dennoch könntest Du mal 
versuchen, mit den folgenden Änderungen Speicher zu sparen:
- Dateien nur mit einem Buchstaben benennen.
- Für das Öffnen des Wurzelverzeichnisses und das Anlegen der Dateien 
den selben dir_entry verwenden (fat16_open_dir() macht intern eine 
Kopie, die im Handle abgelegt wird).
- Die unbenutzten Variablen buffer und fd zur Sicherheit entfernen.

Mein Testprogramm findest Du angehängt. Zur Laufzeit gibt es hier 
folgendes aus:
1
manuf:  0x06
2
oem:    RK
3
prod:   SD
4
rev:    00
5
serial: 0x000004b1
6
date:   12/5
7
size:   127139840
8
copy:   0
9
wr.pr.: 0/0
10
format: 0
11
free:   126644224/126693376
12
1: success1
13
2: success2
14
3: success3
15
4: success4
16
5: success5
17
6: success6
18
7: success7
19
8: success8
20
9: success9

Linux zeigt dann an:
1
drwxr-xr-x  2 root root  16K 1970-01-01 01:00 ./
2
drwxr-xr-x 24 root root 4,0K 2007-10-15 09:04 ../
3
-rwxr-xr-x  1 root root    0 1980-01-01 01:00 1*
4
-rwxr-xr-x  1 root root    0 1980-01-01 01:00 2*
5
-rwxr-xr-x  1 root root    0 1980-01-01 01:00 3*
6
-rwxr-xr-x  1 root root    0 1980-01-01 01:00 4*
7
-rwxr-xr-x  1 root root    0 1980-01-01 01:00 5*
8
-rwxr-xr-x  1 root root    0 1980-01-01 01:00 6*
9
-rwxr-xr-x  1 root root    0 1980-01-01 01:00 7*
10
-rwxr-xr-x  1 root root    0 1980-01-01 01:00 8*
11
-rwxr-xr-x  1 root root    0 1980-01-01 01:00 9*

Falls Du Dich mit der Struktur der Verzeichniseinträge einigermaßen 
auskennst, die sehen dann korrekt z.B. so aus:
1
00048c00  41 31 00 00 00 ff ff ff  ff ff ff 0f 00 6c ff ff  |A1...........l..|
2
00048c10  ff ff ff ff ff ff ff ff  ff ff 00 00 ff ff ff ff  |................|
3
00048c20  31 20 20 20 20 20 20 20  20 20 20 00 00 00 00 00  |1          .....|
4
00048c30  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
5
00048c40  41 32 00 00 00 ff ff ff  ff ff ff 0f 00 2c ff ff  |A2...........,..|
6
00048c50  ff ff ff ff ff ff ff ff  ff ff 00 00 ff ff ff ff  |................|
7
00048c60  32 20 20 20 20 20 20 20  20 20 20 00 00 00 00 00  |2          .....|
8
00048c70  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
9
00048c80  41 33 00 00 00 ff ff ff  ff ff ff 0f 00 ec ff ff  |A3..............|
10
00048c90  ff ff ff ff ff ff ff ff  ff ff 00 00 ff ff ff ff  |................|
11
00048ca0  33 20 20 20 20 20 20 20  20 20 20 00 00 00 00 00  |3          .....|
12
00048cb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
13
...

Beim Debuggen ist mir zwar noch etwas anderes aufgefallen, dies betrifft 
jedoch nur das Auslesen von (sehr großen) Verzeichnissen und hat nichts 
mit Deinen Problemen zu tun. Wahrscheinlich gebe ich dazu dann später 
eine neue Release raus.

Viele Grüße,
Roland

von stucmath (Gast)


Lesenswert?

Guten Tag zusammen

Ich möchte für ein späteres Projekt (GPS-Logger) ein SD Karte Testmässig 
ansteuern.
Nun habe ich mit einem Atmega48 die Testschaltung aufgebaut. Die 
Speisung der SD Karte erfolgt über einen 3.3V Spannungsregler. Die 
Pegelanpassung der Datenleitungen erfolgt über Spannungsteiler.
Die SD Karte ist eine Panasonic 256MB.

Der Grund warum ich hier schreibe ist, dass ich bis jetzt das 
Initialisieren der Karte noch nicht hinbekommen habe. Ich hoffe ihr 
könnt mir irgendwelche Tipps geben welche ich noch zu beachten habe. 
Falls ihr noch Infos bezüglich der Hardware oder sonstigem braucht werde 
ich das natürlich nachliefen. Mir fällt momentan nichts relevantes mehr 
ein.

Die Software habe ich soweit anpassen müssen das sie in den Atmega48 
passt, das heisst es ist nur noch fast das Init mit fast allen 
benötigten Funktionen vorhanden. sd_raw_read() konnte ich aufgrund des 
Platzmangels nicht mehr implementieren.

Aufgrund des Platzproblems stelle ich noch eine weiter Frage. Ist es 
normal das die Programme so gross sind?

Programmgrösse ohne FAT Unterstützung : ca 9kb
Programmgrösse mit FAT Unterstützung: ca 40kb

Ich danke euch schon jetzt für eure Mühe.

Gruss

von Martin (Gast)


Lesenswert?

Hallo Roland,

hast Du bei Deinem Test das Original-SPI oder das USART im SPI-Modus 
benützt? Ich habe vorhin meinen Kartensockel auf das Original-SPI 
umgelötet, und damit funktionert alles; ich kann die Dateien anlegen, 
eine öffnen und etwas einschreiben, die Datei wird dabei automatisch 
vergößert.

Das Ergebnis sieht folgendermaßen aus:
1
0000b000  41 64 00 61 00 74 00 65  00 69 00 0f 00 ae 2e 00  |Ad.a.t.e.i......|
2
0000b010  31 00 00 00 ff ff ff ff  ff ff 00 00 ff ff ff ff  |1...............|
3
0000b020  64 61 74 65 69 20 20 20  31 20 20 00 00 00 00 00  |datei   1  .....|
4
0000b030  00 00 00 00 00 00 00 00  00 00 02 00 08 00 00 00  |................|
5
0000b040  41 64 00 61 00 74 00 65  00 69 00 0f 00 6f 2e 00  |Ad.a.t.e.i...o..|
6
0000b050  32 00 00 00 ff ff ff ff  ff ff 00 00 ff ff ff ff  |2...............|
7
0000b060  64 61 74 65 69 20 20 20  32 20 20 00 00 00 00 00  |datei   2  .....|
8
0000b070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
9
(...)
10
0000b1c0  41 64 00 61 00 74 00 65  00 69 00 0f 00 b0 2e 00  |Ad.a.t.e.i......|
11
0000b1d0  38 00 00 00 ff ff ff ff  ff ff 00 00 ff ff ff ff  |8...............|
12
0000b1e0  64 61 74 65 69 20 20 20  38 20 20 00 00 00 00 00  |datei   8  .....|
13
0000b1f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
14
0000b200  41 64 00 61 00 74 00 65  00 69 00 0f 00 f0 2e 00  |Ad.a.t.e.i......|
15
0000b210  39 00 00 00 ff ff ff ff  ff ff 00 00 ff ff ff ff  |9...............|
16
0000b220  64 61 74 65 69 20 20 20  39 20 20 00 00 00 00 00  |datei   9  .....|
17
0000b230  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
18
*
19
0000f000  48 61 6c 6c 6f 6c 65 21  00 00 00 00 00 00 00 00  |Hallole!........|
20
0000f010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

Da scheint bei meinen Versionen von sd_raw_send_byte() und 
sd_raw_rec_byte() der Wurm drin zu sein!

Gruß Martin

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Martin,

Schön zu hören, dass Du es zumindest mit dem normalen SPI am Laufen 
hast. Meine Tests waren wie immer auch mit der normalen Schnittstelle, 
meine Platine sieht gar nichts anderes vor.

Habe mir in Deinem Code auch die Initialisierung sowie das Senden und 
Empfangen über den USART-SPI angeschaut, es ist mir aber nichts 
aufgefallen.
Vielleicht hat es etwas mit der zusätzlichen Pufferung im Vergleich zum 
normalen SPI zu tun (s. Datenblatt Kap. 19.7)? Oder es gibt ein 
Timing-Problem mit dem Chip-Select? Naja, das ist eher unwahrscheinlich.

Viele Grüße,
Roland

von Roland R. (roland) Benutzerseite


Lesenswert?

@stucmath

Was machst Du mit einer SD-Kartenunterstützung, in der Du sd_raw_read() 
weglässt?!?

Deine Codegrößen sind nicht normal, Du solltest einmal die Einstellungen 
Deines Compilers überprüfen und dort eine Größenoptimierung einstellen.
Aber selbst mit der Größenoptimierung wirst Du auf dem ATmega48 nicht 
glücklich. Meine Beispielanwendung braucht für Nur-Lese-Unterstützung 
mindestens einen mega8/88, mit Schreibunterstützung einen mega16/168.

Gruß,
Roland

von stucmath (Gast)


Lesenswert?

Na ja das bringt eigentlich wirklich nichts. Aber ich wollte nur für 
denn anfang erreichen das ich die SD Karte Initialisieren kann. Das 
sollte doch auch ohne sd_raw_read() klappen?
Ich kompiliere meine Projekte immer über eine build.bat Datei. Die 
Optimierung habe ich auf -Os gestellt. Sollte doch eigentlich in Ordnung 
sein.
Mit Lese- Schreibunterstützung meinst du mit oder ohne FAT?
Ich werde mir also am besten einmal ein Testboard mit einem Atgema32 
aufbauen.

Danke für deine Hilfe

Gruss

von Roland R. (roland) Benutzerseite


Lesenswert?

Ja klar, für die Initialisierung selbst brauchst Du nur sd_raw_init(). 
Die Optimierung ist so auch in Ordnung.

Wo liest Du denn Deine Codegrößen ab? Doch nicht an der Größe der 
Ausgabe des Linkers? Benutze (am Beispiel des sd-readers)
  avr-size -A sd-reader.out
In der Ausgabe entspricht der Flash dem Segment .text und das statisch 
allokierte RAM wird in die Segmente .data und .bss ausgegeben.

Die Angabe der Controllergrößen bezog sich auf meine Anwendung, also mit 
FAT-Unterstützung und der Mini-Shell über UART.

Gruß,
Roland

von Martin (Gast)


Lesenswert?

Hallo Roland,

RTFM kann ich da nur sagen! Deine Vermutung, es könnte mit der 
zusätzlichen Pufferung beim USART-SPI zu tun haben, war goldrichtig.

Meine Sendefunktion sah so aus:
1
void sd_raw_send_byte(uint8_t b)
2
{
3
    while ( !(UCSR0A & (1<<UDRE0)) );
4
    UDR0 = b;
5
}
Dies scheint zunächst richtig zu sein, hat aber tatsächlich einen 
gravierenden Fehler. Da mit dem Sendebyte auch ein Byte empfangen wird, 
bleibt bzw. wird das UDRE0-Bit gelöscht, und beim nächsten 
Funktionsaufruf bleibt das Programm in der while-Schleife hängen. Um 
dieses Bit zu setzen, muß ich das Empfangsbyte lesen.

Das habe ich nun ergänzt:
1
void sd_raw_send_byte(uint8_t b)
2
{
3
    while ( !(UCSR0A & (1<<UDRE0)) );
4
    UDR0 = b;
5
    while ( !(UCSR0A & (1<<RXC0)) );
6
    b = UDR0;
7
}
Mit diesen zwei zusätzlichen Zeilen läuft jetzt alles einwandfrei!


Herzlichen Dank für Deine Unterstützung und viele Grüße!

Martin

von stucmath (Gast)


Lesenswert?

Hmm da habe ich doch wieder einmal etwas gelernt. Habe die .hex grösse 
direkt am file gelesen. Mit avr-size -A sd_reader.hex zeigt es mir 14470 
byte an also 14.1kbyte. Ich denke so ist alles in Ordnung. Danke für den 
Tipp.

Habe nun auf einen Atmega32 umgestellt. Leider funktioniert das Init 
dort auch nicht. Die Serielle Schnittstelle meldet nur:

MMC/SD initialization failed

Ich gehe mal schwer davon aus das dies ein Hardware Fehler sein wird.
Aber was könnte das sein? Wie schon gesagt für die Speisung verwende ich 
einen Spannungsregler (3.3V). Als Pegelwandler sind Widerstände 
zuständig. Diese könnten durch die Toleranzen so zwischen 3.0 - 3.2V 
liegen.
Nun da ich keine noch keine Erfahrung mit SD-Karten habe frage ich hier 
wo könnten denn Fehler aufgetaucht sein? Ich hoffe du (ihr) könnt mir 
weiterhin hilfreiche Tipps geben.

Gruss

von Malte (Gast)


Lesenswert?

Hallo,

mir geht es da ähnlich. Anbindung der MMC ist nach dem einfachen Schema 
von Ullrich Radig erfolgt. Am Oszi sehe ich das sich auf CS, DI und CLK 
etwas tut. Auf DO ist aber schweigen. VCC der Karte liegt bei 3.29V. Das 
gleiche Verhalten habe ich mit zwei Karten (1GB Kingston, 2GB no-name).

Softwareseitig geht dann natürlich das reset Kommando schief, da dies 
einen definierten Rückgabewert von der Karte erwartet.

Tipps wären hochwillkommen.

Gruß
Malte

von Roland R. (roland) Benutzerseite


Lesenswert?

@Malte, stucmath

Hmm, mehr als auf meinen Schaltplan zu verweisen kann ich leider nicht. 
Der funktioniert bei mir ohne Probleme.
Die Dioden-Lösung ist allerdings nicht optimal. Bei Zugriffen auf die 
Karte sackt die Versorgungsspannung durch den Stromfluss von ca. 3,7 
Volt auf Werte um die 3,3 Volt ab. Mag sein, dass das die ein oder 
andere Karte stört, meine laufen glücklicherweise problemlos.

Gruß,
Roland

von Ing. (Gast)


Lesenswert?

Hallo Roland,

danke für die schnelle Antwort. Bei mir kommt statt der Dioden ein LM317 
zum Einsatz der die 3,3V bereitstellt.
Komisch...


Gruß
Malte

von stucmath (Gast)


Lesenswert?

Hallo Roland und Malte

Bei mir funktioniert es mittlerweile. Der Fehler war das ich aus mir 
unbekannten Gründen (Dummheit) die MISO Leitung auch über einen 
Spannungsteiler geschalten habe.

@Roland
Ich danke dir vielmals für deine Hilfe und auch für die Software. Die 
ist einfach nur Klasse.

@Malte
Roland hatte hier einmal geschrieben das wenn man mit einem 
Spannungsregler arbeitet muss darauf geachtet werden, dass die ein wenig 
unter den 3.3V liegen. Deshalb habe ich meinen Spannungsteiler 
folgendermassen gewählt:

3.3K
2K

Ergibt dann etwa eine Spannung von 3.1V

Gruss

von Malte (Gast)


Lesenswert?

Danke, werde ich mir mal ansehen.

von Malte (Gast)


Lesenswert?

Also, ich habe das eben durchgemessen. DI, CS, CLK liegen alle bei 3,2V. 
Versorgungspannung bei 3,29V)

Bin reichlich ratlos...

Malte

von Torsten S. (tse)


Lesenswert?

Malte

Das tut ja richtig weh Dich leiden zu sehen. ;)

Nur so ein paar Tips:

Der LM317 ist ca. 20 Jahre alt und eher ungeeignet um 3.3V für eine 
SD-Karte bereit zu stellen weil er ständig eine Mindestlast von einigen 
mA zum funktionieren benötigt. Wenn Du das sicher stellen kannst ist das 
o.k. - sonst aber kein Beitrag zum Thema Energie sparen. Es gibt 
modernere IC's dafür.

Du kannst an jeder beliebigen Stelle in Roland's SD-Reader ein paar 
zusätzliche printf's einbauen um zu beobachten an welcher Stelle es 
genau hakt. Diese kannst Du Dir ganz in Ruhe via Hyperterminal etc. am 
PC angucken.

Besonders spannend sind die Sachen die in "sd_raw.c" in "sd_raw_init()" 
passieren. Guck Dir genau an ob Du auch einen Karten-Slot hast der 
Kontakte für configure_pin_available() (=SD-Card eingesteckt) und 
configure_pin_locked() (=SD-Card schreibgeschützt) bereitstellt.

Wenn das nicht der Fall ist muß der Original-Code angepaßt werden!

Viel Glück,
Torsten

von Reinhard N. (rn-cologne)


Lesenswert?

Hallo,
nach ich mit einer "billigen" SD-Karte von Reichelt Probleme hatte, hab 
ich's jetzt mit einer etwas teureren Karte vom Conrad fast hinbekommen.
Ich habe die letzte Version von Roland auf einem ATMega168 laufen, 
einzige Änderung zum Orginal Source Code ist, dass ich die Abfragen 
locked und available folgendermassen geändert habe:

in sd_raw_config.h
1
#define get_pin_available() 1   // Change ((PINC >> PC4) & 0x01)
2
#define get_pin_locked() 1      // Change ((PINC >> PC5) & 0x01)

und in sd_raw.c
1
uint8_t sd_raw_available()
2
{
3
    return 1;  // change get_pin_available() == 0x00;
4
}
5
6
7
uint8_t sd_raw_locked()
8
{
9
    return 0;  // change get_pin_locked() == 0x00;
10
}
Jetzt zu meinem Problem: alle Shell Befehle funktionieren, bis auf cat 
<file> und write <file> <offset>, beim Aufruf dieser Funktionen hängt 
das Programm sich auf oder kommt mit der Initialisierung wie nach einem 
Reset zurück.
Kennt jemand das Problem ?
Gruss Reinhard

von Martin (Gast)


Lesenswert?

Hallo Reinhard,

in Deiner sd_raw_config.h sollte folgendes stehen (s.a. weiter oben):
1
#define configure_pin_available()
2
#define configure_pin_locked()
3
#define get_pin_available() 0
4
#define get_pin_locked() 0
Damit kannst Du die originalen sd_raw_locked() und sd_raw_available() 
unverändert lassen. Mit Deinem:
1
#define get_pin_locked() 1
wird sd_raw_write() nie ausgeführt (s. sd_raw.c).

Gruß
Martin

von Roland R. (roland) Benutzerseite


Lesenswert?

Servus Reinhard,

Wie Martin schon korrekt ausgeführt hat, musst Du das #define auf 1 
ändern, sonst nimmt meine Software an, dass der Schreibschutz aktiviert 
ist. Das liegt daran, dass in meiner Schaltung die Port-Pins gegen Masse 
geschaltet werden, wenn der Schutz aktiv ist.

(Der Schreibschutz bei den MMC/SD-Karten ist allein durch die Software 
realisiert. Der Schalter an der Karte ist nur ein Kunststoffnippel, von 
dem der Kartencontroller nichts weiß. Erst die Host-Software kann über 
einen Schalter im Sockel die Position des Schreibschutzschalters 
feststellen und verweigert gegebenenfalls den Schreibzugriff.)

Viele Grüße,
Roland

von Reinhard N. (rn-cologne)


Lesenswert?

Hallo Martin, hallo Roland
ich habe eure vorgeschlagene Änderung durchgeführt. Das führt jetzt zu 
einer "sauberen" Programmierung, wenn die Schalter für Locked und 
Available fehlen, beseitigt aber nicht das beschriebene Problem mit 
"cat" und "write". Schreiben konnte ich ja auch schon vorher, "touch", 
"rm" und "mkdir" als Shell Befehle funktionieren ja.
Hier mal ein Abdruck des Terminals:
1
> manuf:  0x1b
2
oem:    SM
3
prod:   SMI
4
rev:    10
5
serial: 0x099da84f
6
date:   7/7
7
size:   1017643008
8
copy:   0
9
wr.pr.: 0/0
10
format: 0
11
free:   1016758272/1017249792
12
> ls
13
abc/                                 0
14
file.txt                             16
15
a/                                   0
16
>
17
> cat file.txt
ab hier hängt's. Ein weiteres Beispiel, wenn der File in einem 
Unterverzeichnis ist:
1
manuf:  0x1b            
2
oem:    SM          
3
prod:   SMI           
4
rev:    10          
5
serial: 0x099da84f                  
6
date:   7/7           
7
size:   1017643008                  
8
copy:   0         
9
wr.pr.: 0/0
10
format: 0
11
free:   1016758272/1017249792
12
> cd abc
13
>
14
> ls
15
./                                   0
16
../                                  0
17
abc.txt                              24
18
>
19
> cat abc.txt
20
manuf:  0x1b
21
oem:    SM
22
prod:   SMI
23
rev:    10
24
serial: 0x099da84f
25
date:   7/7
26
size:   1017643008
27
copy:   0
28
wr.pr.: 0/0
29
format: 0
30
free:   1016758272/1017249792
31
>
Hier springt das Programm an den Anfang.
Ich hoffe, dass der Fehler jetzt klarer beschrieben ist und ihr helfen 
könnt.
Gruss  Reinhard

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Reinhard,

Nachdem Du (bis auf die zwei besprochenen Änderungen) genau den gleichen 
Code benutzt wie ich und auch den gleichen Controller, tippe ich jetzt 
einfach mal auf die Hardware. Könntest Du diesen bitte schildern oder 
einen Schaltplan posten? Interessant ist insbesondere die Anbindung der 
Karte an den Controller und die Stromversorgung.

Falls das alles unverdächtig ist, könntest Du vielleicht auch bitte ein 
Karten-Image erstellen und mir zuschicken. Eventuell finde ich am 
Donnerstag Zeit, um mal wieder eine Debugging-Sitzung einzulegen...

Gruß,
Roland

von Reinhard N. (rn-cologne)


Lesenswert?

Hallo Roland,
erst mal Danke für deine super-schnelle Reaktion.
Zu meiner HW: ich benutze das Development Board von myavr.de, allerdings 
abweichend von der Ursprungsversion mit einem ATMega168. Schaltplan dazu 
unter http://myavr.de/download/techb_myavr_board_lpt.pdf. Getaktet wird 
das Board mit 3,6864 MHz. Eine Besonderheit ist vielleicht, dass das 
Board aufgrund des 6V Spannungsreglers und der Reihendiode mit ca. 5,3V 
betrieben wird. Die SD-Karte ist wie in deinem Schaltplan mit 
Spannungsteiler (3,3k gegen Masse, 1,8k in Reihe) an die Datenports 
angebunden. DATA OUT direkt an MISO. Die SD-Karte wird mit einem LM317 
mit 3,3V versorgt. Da der Spannungsteiler die Datenports geringfügig 
über 3,3V zieht, habe ich auch mit einer Versorgungsspannung von 3,5V 
probiert, was aber keine Veränderung zeigte. Die SD-Karte ist eine 1GB 
von Transcend, gleiches Verhalten aber auch bei einer 2GB Karte.
Ich denke eher, dass der Fehler in der SW zu suchen ist. Ich habe 
zumindest den Fehler durch Debug-Ausgaben auf dem Terminal soweit 
eingrenzen können, dass sich dass Programm bei Eingabe von "cat <file>" 
in folgender IF Abfrage aufhängt (Funktion: uint8_t 
fat16_read_root_dir_entry(const struct fat16_fs_struct* fs, uint16_t 
entry_num, struct fat16_dir_entry_struct* dir_entry))  -  ca. Zeile 398 
in fat16.c
1
    if(!device_read_interval(header->root_dir_offset,
2
                             buffer,
3
                             sizeof(buffer),
4
                             header->cluster_zero_offset - header->root_dir_offset,
5
                             fat16_dir_entry_seek_callback,
6
                             &arg) ||
7
       arg.entry_offset == 0
8
      )
Leider hören da meine C-Kenntnisse bei der Fehlersuche auf. Aber 
vielleicht hilft dir das ja, den Fehler einzugrenzen.
Wenn du glaubst mit einem Karten-Image weiterzukommen, schick ich dir 
das gerne zu, kommt dann separat per Mail.
Ich danke dir nochmals für deine freundliche Hilfe
Gruss Reinhard

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Reinhard,

Die Variable device_read_interval ist ein Funktionspointer auf 
sd_raw_read_interval(), welche wiederum sd_raw_read() mehrfach aufruft. 
Wenn er also in der von Dir zitierten if-Abfrage hängen bleibt, müsstest 
Du in den genannten Funktionen in sd_raw.c weiterforschen.

An dieser Stelle können durchaus Hardware-Probleme eine Rolle spielen, 
etwa wenn die Karte nicht korrekt antwortet. Wenn ich Dein Karten-Image 
habe, werde ich dieses auf meine Karte schreiben und sehen, ob 
vielleicht bestimmte Parameter des Dateisystems meinem Code 
Schwierigkeiten machen.

Gruß,
Roland

von Kai F. (kai-) Benutzerseite


Lesenswert?

Hallo Roland & Rest,
ich habe vor eine Micro SD Karte auf meiner neuen Propellerclock (50 RGB 
LEDs) mitdrehen zu lassen.
Erst dachte ich an externes flash rom, auf das die Bilder beim 
Bootvorgang zwischengespeichert werden, jetzt ist es mir aber gelungen 
die CPU Last auf unter 30% für die Ansteuerung der LED Treiber zu 
reduzieren und ich denke drüber nach den Flash Rom komplett wegzulassen.
Die Sache ist nur, dass ich jede Sekunde 687kByte brauche und das Holen 
dieser Daten am Besten innerhalb von 50% CPU Last bewältigen möchte.
Unterm Strich komme ich auf eine benötigte Lesegeschwindigkeit von knapp 
1,4 MByte/s
Meine Frage an euch wäre jetzt ob das mit dem Code überhaupt möglich 
ist. SPI Frequenz wäre 8MHz, als Controller hatte ich wegen der 
benötigten I/Os eigentlich den mega128 eingeplant, vielleicht ginge 
jetzt ja auch ein mega32?

Gruß
Kai

von Kai F. (kai-) Benutzerseite


Lesenswert?

habe gerade nochmal den Taschenrechner bemüht und dabei ist mir 
aufgefallen, dass eine 8MHz Taktfrequenz dafür gar nicht ausreichen 
würde...
Habe also ein wenig umstrukturiert, brauche jetzt auch etwas über 30% 
CPU, komme aber "nur" noch auf 430kByte in einer Sekunde, bei 50% CPU 
wären das dann 860kByte/s oder 6880kBit/s, was mit 8MHz SPI schaffbar 
wäre.
Wo es der AVR jetzt schafft, geht das dann auch mit dem Programm oder 
wird zuviel Rechenzeit für den Empfang/Pufferung verbraten?

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Kai,

Aufgrund meiner Erfahrungen denke ich nicht, dass Du das hinbekommen 
wirst. Zumindest nicht mit FAT und ohne viel(!) Pufferspeicher, den Du 
Dir ja eigentlich sparen wolltest.

Wenn Du die Karte ohne Dateisystem benutzt, und ein Interrupt-basiertes 
Lesen der SD-Karte implementierst, könnte es vielleicht gehen. Doch 
selbst dann ist Dein Vorhaben sehr knapp am Limit der maximalen 
ISP-Frequenz. Die Ansteuerung der Karte benötigt viele Wartezyklen und 
die Übertragung vieler Dummy-Bytes, die die Netto-Datenrate weit unter 
das theoretische SPI-Limit drücken. Von dem Overhead eines Dateisystems 
ganz zu schweigen...

Du müsstest also Deine Anforderungen an die Datenrate noch erheblich 
drücken...

Viele Grüße,
Roland

von Kai F. (kai-) Benutzerseite


Lesenswert?

Hi Roland,
das ist aber doof :(
weiter drücken geht leider nicht ohne die Bildwiederholfrequenz 
(momentan 20/s) zu senken.
Was ich mir vorstellen könnte wäre die Frequenz auf 10 Bilder/s zu 
drücken und damit einen Faktor 2 rauszuholen. Dann würde ich ein Bild 
eben zweimal anzeigen... allerdings brauche ich dann auch einen Puffer, 
in den ein ganzes Bild reinpasst, welches aber 43kByte groß ist...
Da ich sowieso schon länger vorhabe eine SD Karte anzusteuern und die 
Sockel auch schon länger habe, bin ich gerade dabei eine Schaltung auf 
Lochraster aufzubauen (ja, mein Sockel passt auf Lochraster).
Als µC benutze ich einen mega8.
Da ich aber ein fauler Codevision User bin, werde ich deinen Code wohl 
in Codevision übersetzen müssen :(
Werde hoffentlich nicht der einzige sein, der davon profitiert^^

Gruß
Kai

von Roland R. (roland) Benutzerseite


Lesenswert?

@ Reinhard

Habe jetzt mal Dein Image auf meine Karte gespielt:
1
manuf:  0x06
2
oem:    RK
3
prod:   SD
4
rev:    00
5
serial: 0x000004b1
6
date:   12/5
7
size:   127139840
8
copy:   0
9
wr.pr.: 0/0
10
format: 0
11
free:   1016758272/1017249792
12
> ls
13
abc/                                 0
14
file.txt                             16
15
a/                                   0
16
> cat file.txt
17
00000000: 61 62 63 64 65 66 67 0a
18
00000008: 31 32 33 34 35 36 37 0a
19
> cd abc
20
> ls
21
./                                   0
22
../                                  0
23
abc.txt                              24
24
> cat abc.txt
25
00000000: 31 32 33 34 35 36 37 38
26
00000008: 39 30 0a 61 62 63 64 65
27
00000010: 66 67 68 69 6a 0a 20 0a

Es funktioniert also prinzipiell. Ich hatte aber hin und wieder Probleme 
mit dem Wechsel in das Verzeichnis. Nach ein bisschen Debugging denke 
ich, dass dieses Problem, genauso wie Deines, an der Speicherknappheit 
liegt. Ich würde Dir empfehlen, meine Mini-Shell einfach mal durch ein 
kleines Demo-Programm zu ersetzen, welches wirklich nichts anderes 
macht, als eine Datei anzulegen, in sie zu schreiben und wieder zu 
schließen. Das sollte dann funktionieren.

Gruß,
Roland

von Reinhard N. (rn-cologne)


Lesenswert?

Hallo Roland,
habe deinen Vorschlag befolgt und aus main.c alles aus der Minishell 
gelöscht bis auf "cat", "sync" und "write". Nur mit diesen Befehlen 
funktionierts, wie das Beispiel zeigt:
1
manuf:  0x1b
2
oem:    SM
3
prod:   SMI
4
rev:    10
5
serial: 0x099da84f
6
date:   7/7
7
size:   1017643008
8
copy:   0
9
wr.pr.: 0/0
10
format: 0
11
free:   1016709120/1017249792
12
> cat 2.txt
13
00000000: 20 0a 02 00 00 00 00 00
14
> write 2.txt 0
15
< jetzt funkt's
16
< danke an Roland
17
<
18
> cat 2.txt
19
00000000: 6a 65 74 7a 74 20 66 75
20
00000008: 6e 6b 74 27 73 64 61 6e
21
00000010: 6b 65 20 61 6e 20 52 6f
22
00000018: 6c 61 6e 64 6e 20 52 6f
23
>
Sobald ich einen weiteren Shell Befehl, egal ob "ls" oder "touch" 
zusätzlich rein nehme, hängt sich das Prog wieder auf. Vielleicht liegts 
wirklich an der Grösse des Programms und dem Füllgrad des Flash obwohl 
AVR Studio nur 13.812 Byte und 84,3% meldet. Im Moment komm ich hier 
nicht weiter.
Werd mich mal dran machen, Werte aus dem A/D Wandler in eine Datei zu 
schreiben, mal sehen, ob das klappt.
Gruss Reinhard

von holger (Gast)


Lesenswert?

>Sobald ich einen weiteren Shell Befehl, egal ob "ls" oder "touch"
>zusätzlich rein nehme, hängt sich das Prog wieder auf. Vielleicht liegts
>wirklich an der Grösse des Programms und dem Füllgrad des Flash obwohl
>AVR Studio nur 13.812 Byte und 84,3% meldet. Im Moment komm ich hier

Jungs, nehmt doch einfach einen ATMega32. Nicht das Flash
ist am Ende, es ist das RAM !

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Reinhard,

Wie Holger schon angemerkt hat, geht es nicht ums Flash, da sind ja noch 
ein paar Kilobyte frei. Das RAM ist komplett belegt, und sobald der 
Stack in den Heap bzw. in den statisch allokierten Bereich reinwächst, 
gibt es Probleme. Dann kann alles passieren, vom merkwürdigen Verhalten 
bis zum Absturz.

Zum Testen mag Dein Controller reichen, für die eigentliche Anwendung 
wirst Du aber ein Modell mit mehr RAM brauchen.

Gruß,
Roland

von Torsten S. (tse)


Lesenswert?

holger wrote:
> Jungs, nehmt doch einfach einen ATMega32. Nicht das Flash
> ist am Ende, es ist das RAM !

Wohl wahr, das ist der wunde Punkt.

2k SRAM reichen zwar für Roland's Beispiel mit dem SD-Reader, für mehr 
aber nicht. Programmiert man eigene Sachen dazu erlebt man die gleichen 
merkwürdigen Effekte. Erst mit einem ATmega644 (4k SRAM) lief alles in 
meinem Fall so wie es sein sollte.

Torsten

von Reinhard N. (rn-cologne)


Lesenswert?

Hallo,
gibt's denn keine Möglichkeit das zu kontrollieren - entweder beim 
Compilieren/Linken vorher oder zur Laufzeit ?
(btw. - der ATMega168 hat nur 1k !)
Gruss
Reinhard

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Reinhard!

Nein, das geht in der Regel nicht, dazu wäre eine Laufzeitanalyse 
notwendig. Nur wenn das statisch allokierte RAM (also die Gesamtgröße 
aller globalen Variablen) bereits zu groß ist, kann das der Linker 
feststellen. Das hilft aber nichts, weil das RAM meist schon vorher 
durch den Stack (also lokale Variablen und die Parameter bei 
Funktionsaufrufen) und den Heap (sprich malloc()/free()) aufgebraucht 
wird.

Ja, der mega168 hat nur 1kB, deshalb ist er ja so sehr am Limit.

Gruß,
Roland

von Mathias S. (stucmath)


Lesenswert?

Hallo zusammen

Hat jemand schon mit Roland Riegel's SD/MMC Software eine Micro SD Karte 
angesteuert?
Versuche dies nämlich gerade. Die Initialisierung ist wahrscheinlich 
erfolgreich (muss ich noch genau untersuchen) aber es werden dann keine 
Disk Infos angezeigt.

Gruss

von Kai B. (chaosman)


Lesenswert?

Hi Matthias,

Ja, ich habe bei meiner Entwicklung sowohl Micro-SD (über Adapter) als 
auch normale SD-Karten benutzt.
Eigentlich sollte es auch keine Unterschied, mal abgesehen von den 
üblichen Inkompatibilitäten, geben. Eine Micro-SD ist eine normale SD - 
halt nur kleiner.

Gruß,

Kai

von Mathias S. (stucmath)


Lesenswert?

Wunderbar dann sollte das also klappen. Dann habe ich wieder einmal ein 
Fehler in meiner Schaltung :-)
Danke für deine Hilfe dann werde ich noch ein bisschen weiter probieren.

Gruss und schönes Wochenende

von EDAconsult Udo Kuhn (Gast)


Angehängte Dateien:

Lesenswert?

@Roland Riegel,

feine Sache, habe ATmega8L mit Miniversion ohne Probleme zum laufen 
gebracht. Jetzt bestehen ja richtige Möglichkeiten durch diese Software.

Besten Dank

Udo

von Gast (Gast)


Lesenswert?

Hallo,

Das sieht ja Prima aus. Moecht ich gerne auch ausprobieren!

Könnte freundlicherweise jemand einen link zur Miniversion
fuer Atmega8L posten.

Irgendwie ist der Thread bezueglich Uebersichtlichkeit an
seine Grenzen gestossen :)

danke
 Gast

von EDAconsult Udo Kuhn (Gast)


Lesenswert?

Hallo Gast,

ganz oben als erstes steht sie, vom Entwickler selbst. Dann nur noch 
alles genau lesen und schon geht es los.

von Roland R. (roland) Benutzerseite


Lesenswert?

@Udo, Gast

Bitte beachtet bitte, das in der allerersten Version diverse Fehler 
enthalten sind, die in dem neuesten Release behoben sind. Für möglichst 
kleinen Code also bitte nicht veraltete Ausgaben nutzen, sondern die 
jeweils neueste entsprechend abspecken. In den letzten fast zwei Jahren 
hat sich schließlich einiges getan...

Gruß,
Roland

von EDAconsult Udo Kuhn (Gast)


Angehängte Dateien:

Lesenswert?

@Gast,

als Anhang das Programm für ATmega8L.

@R. Riegel,

es ging aber um den Link und nicht um die Versionen. Zum Hardwareaufbau 
hat bestimmt jeder so seine eigenen Vorstellungen, ich finde es 
einfacher gleich alles mit 3,3V zu betreiben deswegen der ATmega8L, 
andere haben vielleicht schon Hardware mit 5V und wollen dann aber diese 
SD-Karten betreiben.

Die letzte Version der Software steht doch bestimmt auf Deiner Webseite, 
habe jetzt aber auch nicht da nachgeschaut, gehe aber davon aus dass so 
etwas selbstverständlich ist.

Dann finde ich es sehr wichtig so viel zu Lesen wie es geht um auch 
selbst zu entscheiden ob dass so alles stimmt wie es gerade beschrieben 
wird, wer weiß schon alles. Dann sind die eigenen Fehler sowieso die 
schlimmsten und dass geht nur mit Ausdauer am Projekt.

Wie soll ich dass alles beschreiben?


Udo

von Jan (Gast)


Lesenswert?

Hi,

ich bin endlich dazu gekommen an meiner Cocktailmaschine zu werkeln. Ich 
habe bereits ein rudimentäres Programm mit 3 Tastern, LCD-Display zur 
Auswahl auf  Basis eines Atmega16 am laufen. 2 komplette 8 Bit Ports 
wollte ich wohl für die Pumpen bzw. Magnetventile reservieren. Leider 
reicht mir der EEPROM zum speichern von Rezepten nicht aus, da bekomm 
ich maximal 20 Rezepte untergebracht weil ich speichere die Namen der 
Cocktails als Strings mit maximal 18 Zeichen für das 4*20 LCD. Zur Zeit 
nutze ich den Programmspeicher dafür, was ich aber sehr unfexibel finde. 
Ich ich will nicht bei jeder Änderung den Chip neu programmieren und da 
bin ich über diesen Beitrag gestolpert.

Ich finde die Idee mit der SD Karte recht gut, weil dann kann ich die 
Rezepte am PC zusammenfriemeln und darauf speichern, der Atmega muss sie 
dann nur lesen können. Jedoch benötige ich nich wirklich ein Dateisystem 
wie FAT16 ... ich bräuchte auch nur eine Datei mit meinem eigenem 
Datenformat. Ich würde dann also nur die SW_RAW routinen verwenden und 
quasi mein eigenes Dateisystem, d.h. einfach nur ein datenstream in 
einem bestimmtem Format darauf speichern und auf dem PC ein Programm 
schreiben welches die Daten auf der SD karte in diesem Format speichert.

Soweit so gut. Grad mal geguckt es gibt ja fasst nur noch Karten die 
mindestens 1GB Speicherkapazität haben, soviel brauche ich nun auch 
wieder nicht, mir würde sogar 1MB dicke reichen. Jetzt wollte ich mal 
fragen ob es da nicht eine bessere Lösung gibt. Außerdem meine ich hier 
gelesen zu haben, dass man die Daten nur in 512byte Blöcken lesen kann, 
heißt das jetzt das ich immer mindestens 512byte in einem rutsch lesen 
muss?

Danke im Vorraus.

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Jan,

Ob du SD-Karten nutzt oder nicht, musst letzten Endes Du entscheiden. 
Beachte allerdings, dass der Hardwareaufwand relativ gering ist und der 
Speicher pro MB unschlagbar billig, verglichen mit externen EEPROMs oder 
Flash-Chips.

In der Regel werden die SD-Karten 512-Byte-weise angesprochen, ja. Wenn 
Du meine sd_raw-Routinen verwendest, ist das aber wurscht, da diese 
einen wahlfreien Zugriff mit beliebiger Blockgröße ermöglichen.

Gruß,
Roland

PS: Wenn Du die Strings mit dynamischer Länge ablegst und mit einem 
Null-Byte abschließt, kannst Du auch ein bisschen Platz sparen.

von Malte (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe meine Schaltung jetzt auch ans laufen bekommen, ein kleines 
Verstänissprob. bleibt. Wenn ich mit

...
  uint8_t buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
0x08};
  fat16_write_file(fd, buffer, 9);
  ...
  fat16_close_file(fd);
...
Auf die Karte schreibe werden 2 Byte und nicht 9 geschrieben. Rufe ich 
vorher:

  fat16_resize_file(fd, 9);

auf passt es.

Ist das ein zu erwartendes Verhalten?

An dieser Stelle auch mal ein herzliches Dankeschön an Roland für die 
klasse lib.

Gruß
Malte

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Malte,

Normalerweise sollten da schon neun Bytes geschrieben werden. Was gibt 
denn fat16_write_file() zurück? Immer den Rückgabewert mit der Anzahl zu 
schreibender Bytes vergleichen! Sonst kann man sich nie sicher sein, 
dass wirklich alle Bytes geschrieben wurden. [1]

Ansonsten: Benutzt Du SD_RAW_WRITE_BUFFERING? Wenn ja, musst Du vor dem 
Entfernen der Karte sd_raw_sync() ausführen! [2]

Gruß,
Roland

[1] 
http://www.roland-riegel.de/sd-reader/doc/group__fat16__file.html#g4f0c785a47b1cf070839b5edec2c6f65
[2] 
http://www.roland-riegel.de/sd-reader/doc/group__sd__raw.html#gd4d9ff40a7ea50c65cfa47927b35b735

von Malte (Gast)


Lesenswert?

Hallo Roland,

ich gebe die anzahl der geschriebenen Bytes auf dem Display aus. Das 
passt soweit. Ich dachte sd_raw_sync() ist nicht erforderlich wenn ich 
die Datei mit vor dem Entfernen mit fat16_close_file(...) schliesse. 
Dann hatte ich gestern aber noch weitere seltsame Effekte. Bin jetzt 
aber nicht ganau in der lage diese richtig zu beschreiben.
Ich denke ich schau mal ob da nicht der Stack zu gross wird.

Gruß
Malte

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Malte,

Doch, in den bisherigen sd-reader-Versionen ist der Aufruf von 
sd_raw_sync() immer manuell auszuführen. Am besten beispielsweise vor 
längeren Zugriffspausen, wenn die Wahrscheinlichkeit hoch ist, dass die 
Karte abgezogen wird.

Ich hatte auch schon dran gedacht, sd_raw_sync() beim Aufruf einiger 
FAT-Funktionen automatisch auszuführen. Vielleicht werde ich das mal 
implementieren. Wenngleich das in einigen Zugriffsszenarien den 
Puffereffekt zumindest teilweise zunichte machen könnte...

Nebenbei bemerkt glaube ich nicht, dass sd_raw_sync() bei Dir das 
Problem ist, da die ersten zwei Bytes ja geschrieben werden. Die 
restlichen sieben sollten dann ja gleichzeitig in dem gleichen Sektor 
landen.

Zu Deinem Fehlerbild fällt mir im Moment außer dem von Dir erwähnten 
RAM-Mangel auch nichts passendes ein. Welchen AVR nutzt Du eigentlich?

Gruß,
Roland

von Malte (Gast)


Lesenswert?

Hi Roland,

ich verwende einen ATMEGA128. Der ist allerdings mit knapp 3500 bytes 
sram recht gut gefüllt. Stack muss dann noch in die verbleibenen 500 
bytes passen.
Dynamischen Speicher über malloc oder die builtin Funktionen verwende 
ich nicht. Am Anfang der oben angehängten Routine habe ich noch 187 
bytes Speicher frei.

Mit sd_raw_sync() scheint es jetzt soweit zu funktionieren. Danke

Gruß
Malte

von pito (Gast)


Lesenswert?

Hi,
as I see there is a lot of expertise (which I am lacking) in this forum 
I would kindly ask you whether it would be possible to write a simple 
"user fiendly library" based on Roland's code which is easy to use by 
beginners as well - e.g.:
sd_init()
sd_open(&filename)(if it does not exist than create)
sd_date(&filename,year,day,..min,sec) (time stamp)
sd_write(&filename,*buffer)
sd_read(&filename,*buffer)
sd_append(&filename,*buffer)
sd_delete(&filename)
sd_close(&filaname)...
...
where buffer is a string[40] etc., so you printf(string,"%u...",temp).
filename is a string ( e.g. "\temp\new\measure1.txt")

So one can easily open a file and write data there.
I would say it is a half hour work for an expert to make this great 
fat16 library available for an "standard" user who wants just write 
temperature or some data into files..

pito

von Roland R. (roland) Benutzerseite


Lesenswert?

@pito,

I will not provide you with code, because all you need is more or less 
already available with the main.c example application from the sd-reader 
source. You just have to write up some wrapper functions into which you 
put the example code:

sd_init:   sd_raw_init(), partition_open(), fat16_open()
sd_open:   fat16_get_dir_entry_of_path(), fat16_open_file()
sd_date:   fat16_get_file_modification_date/time()
sd_write:  fat16_write_file()
sd_read:   fat16_read_file()
sd_append: fat16_seek_file(), fat16_write_file()
sd_close:  fat16_close_file()
sd_delete: fat16_delete_file()

That would be it. You might also want to look at the mega-eth project 
(http://www.roland-riegel.de/mega-eth/), where I reused the sd-reader 
code and wrote something which equals your sd_init().

Greetings,
Roland

von Thomas B. (froms)


Lesenswert?

Hallo,

ich bin seit einiger Zeit dabei Daten auf einer Speicherkarte abzulegen.
Meine ersten Versuche liefen ohne FAT Dateisystem und nur mit 
ansteuerung der Sektoren. Ich habe dafür das Beispiel von Ulrich Radig 
genutzt.
Ich konnte damit ohne Probleme speichern.

Nun wollte ich jedoch etwas mehr probieren und mal das FAT16 System von 
Roland Riegel testen.
Jedoch hab ich da so ein paar Probleme.

Ich nutze das Pollin-Board mit einem ATmega32 (mit internem Takt [8MHz]) 
und die Speicherkartenansteuerung ist eine Komplettlösung der Firma 
E-LAB.
Des Weiteren nutze ich MMC-Speicherkarten, weil in den Slot keine 
SD-Karten passen.

Es treten schon Probleme auf, wenn die "Fabrikdaten" ausgelsen werden. 
Beim letzten Punkt, wo der freie und belegte Speicherplatz angezeigt 
werden soll, hängt sich das Programm auf und es geht nicht weiter.
Kommentiere ich diese Zeile aus, läuft es erstmal.
Ich kann auch ohne Porbleme den Inhalt mit dem Befehl "ls" auslesen. 
Jedoch kann ich keine neuen Dateien erstellen oder in vorhandene 
Textdateien hineinschreiben.

Ich wollte das ganze System als eine Art Datenlogger nutzen.

Was mir auch noch aufgefallen ist, das manche Karten gar nicht erst 
erkannt werden.

Ich hoffe ihr könnt mir bei diesem Problem weiter helfen.

gruß
Thomas

von Torsten S. (tse)


Lesenswert?

Roland Riegel wrote:

..
> (http://www.roland-riegel.de/mega-eth/

Wow. Gratuliere zum neuen Projekt! Sieht sehr gut aus.
BTW: Hast es hier ja garnicht vorgestellt.. ;)

Torsten

von Roland R. (roland) Benutzerseite


Lesenswert?

@Torsten,

Danke, aber vorgestellt habe ich es doch :)
Beitrag "Erweiterbares Ethernetboard mit MMC/SD-Slot und USB"

Gruß,
Roland

von Thomas B. (froms)


Lesenswert?

Guten Morgen,

ich hab gestern noch ziemlich lange probiert das Problem zu finden. Hab 
noch mehr Speicherkarten getestet und sogar mal ne SD-Micro + Adapter 
ausprobiert.
Irgendwie komme ich da nicht weiter.

Hab hier nochmal den Link von dem Speicherkartenmodul:

http://www.e-lab.de/components/cf_and_co.html

Es handelt sich dabei um das "MMC Card Interface for MINI-SD".

Das Pollinboard sollte, so denke ich, einigermaßen bekannt sein:

http://www.pollin.de/shop/shop.php

Am Quellcode kann es ja eigentlich nicht liegen. Und meine 
Speicherkarten waren alle 128MB groß oder kleiner. Damit sollten also 
auch keine Probleme entstehen.

Was mich am meisten wundert ist, dass bei den Karten, die funktionieren, 
nur die Lesebefehle ohne Probleme klappen. Bei den Schreibbefehlen 
bleibt er immer hängen.
Nutze zum Testen WindosXP mit Hyperterminal bzw. Hterm.

Vielleicht hat ja jemand schon so ein ähnliches Problem gehabt?!

gruß
Thomas

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Thomas,

Mit den paar Angaben die Du machst kann man nur raten.

Überprüfe Deine Konfiguration in sd_raw_config.h. Finde auch mal selbst 
heraus, wo genau er hängen bleibt. Füge vor und hinter jeden zu 
untersuchenden Funktionsaufruf Debug-Ausgaben ein, ebenso in den 
aufgerufenen Funktionen selbst. Versuche so einzukreisen, bis wo er 
kommt.

Versuche doch erst mal den Sektorzugriff über sd_raw_read() und 
sd_raw_write() zum Laufen zu bringen, erst dann solltest Du über FAT16 
nachdenken.

Gruß,
Roland

von Thomas B. (froms)


Lesenswert?

@ Roland:
Also die Sende und Empfangsfunktionen ohne FAT16 funktionieren ohne 
Probeme. Diese gingen ja auch schon, als ich das Projekt von Ulrich 
Radig verwendet hatte.
Um zu überprüfen, wo er hängen bleibt, lass ich mir vor den Funktionen 
immer Meldungen über die Uart ausgeben.

Und wie gesagt, er bleibt ja schon dann hängen, wenn er den freien 
Speischerplatz angeben soll.

Aber ich werde jetzt erst einmal alle anderen, auch nicht genutzen 
Funktionen überprüfen und nochmal testen, was passiert, wenn ich den 
Code nur auf die Schreibfunktion begrenze.

Was mich aber mal noch interessiert, ist die Frage zu den 
Speicherkarten. Sind da schon Probleme bekannt, dass es mit einigen 
Typen Probleme gibt?
Ich habe sie ja alle unter Windows mit FAT formatiert.

gruß
Thomas

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Thomas,

Selbst habe ich meinen Code nur mit SD-Karten ausprobiert, von anderen 
habe ich aber auch noch nichts über Probleme mit MMC-Karten gehört.

Zum Hängen: Vermutlich hängt er in einer der while(1)-Schleifen in 
sd_raw.c fest, weil die Karte aus irgendeinem Grund nicht mehr (richtig) 
antwortet. Du könntest mal die Datei sd_raw.c aus mega-eth verwenden, da 
habe ich diese Warteschleifen zeitlich schon begrenzt. Überhaupt sind 
noch einige Rückportierungen von mega-eth nach sd-reader in der 
Warteschleife.

Gruß,
Roland

von Torsten S. (tse)


Lesenswert?

Roland Riegel wrote:

> Danke, aber vorgestellt habe ich es doch :)
> Beitrag "Erweiterbares Ethernetboard mit MMC/SD-Slot und USB"

Opps. Das habe ich irgendwie übersehen...

Torsten

von Thomas B. (froms)


Lesenswert?

Hallo allerseits,

ich wollte jetzt mal wieder meinen neuen Stand posten.
Also, ich kann jetzt auf die Speicherkarten schreiben und lesen mit FAT.
Das Problem liegt dabei an dem Root-Verzeichnis. Dort hängt er sich 
immer auf. Erstelle ich jedoch Unterordner, läuft alles ohne Probleme. 
Dort kann ich dann, wie von mir gewünscht,Ordner erstellen, Dateien 
erstellen, dort hinein schreiben und die Dateien dann auf einem PC 
öffnen.
Das Problem liegt jetzt aber daran, dass ich sie nur unter Linux lesen 
kann. Windows gibt immer sie Fehlermeldung, dass die Datei beschädigt 
ist.
Ich erstelle .txt dateien und habe es mit Notepad und Editor probiert. 
Beides ohne Erfolg.

Hat jemand auch so etwas bemerkt? Woran könnte das liegen? Damit wär mir 
schon gut geholfen.

Vielen Dank.
gruß
Thomas

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Thomas,

Du hast schon die neueste sd-reader-Version? Ältere Ausgaben hatten 
Fehler wie von Dir beschrieben, die aktuellste eigentlich nicht. Führst 
Du vor dem Entfernen der Karte ein sd_raw_sync() ("sync" auf der 
Kommandozeile) aus?

(Hoffentlich komme ich demnächst endlich mal dazu, einige 
Aktualisierungen zu veröffentlichen.)

Gruß,
Roland

von Roland R. (roland) Benutzerseite


Angehängte Dateien:

Lesenswert?

So, heute habe ich die versprochenen Verbesserungen auf meiner Homepage 
veröffentlicht und hänge sie jetzt auch wieder an dieses Posting an.

Die Änderungen u.a.:
- Neuer Befehl "init" initialisiert und öffnet die Karte neu.
- Viel höhere Geschwindigkeit beim Durchsuchen bzw. Auflisten von
  Verzeichnisinhalten.
- Suche in Verzeichnissen mit mehr als einem Cluster korrigiert.
- Lesen von Verzeichniseinträgen korrigiert, die über eine Clustergrenze
  reichen.
- Breche bei zu langen Dateinamen nicht den ganzen LFN-Eintrag ab,
  sondern lasse nur einzelne Zeichen weg.
- Reduktion der Codegröße durch zentralisierte Berechnung der
  Clusteradressen.
- Einige andere Korrekturen und Optimierungen.

Viele Grüße,
Roland

von Mathias S. (stucmath)


Lesenswert?

Guten Tag zusammen

Ich habe eine kurze Frage zur File Erstellung bei bei Rolands Sd-Reader.
Ist es normal das ich ein File z.B test.txt nur in einem Ordner ablegen 
kann?
Zuerst wollte ich es direkt auf der root Partition ablegen aber dies 
funktionierte leider nie. Also habe ich einen Ordner erstellt, in diesem 
anschliessend das File abgelegt und siehe da es funktioniert.

Ich bin mir ziemlich sicher das ich irgendwo noch einen Fehler mache. 
Aber ich weis leider momentan nicht wo.
Ich hoffe jemand kann mir ein paar Tipps geben.

Gruss Mathias

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Mathias,

Doch, das Anlegen von Dateien im Wurzelverzeichnis sollte ohne Probleme 
funktionieren, schließlich kann man dort ja auch Verzeichnisse anlegen 
und das ist im Prinzip auch nichts anderes.

Wie hast Du es denn probiert, von der UART-Kommandozeile aus oder mit 
einem eigenen Programm? Kannst Du im letzten Fall den Quelltext bzw. 
einen Ausschnitt davon posten?

Gruß,
Roland

von Mathias S. (stucmath)


Lesenswert?

Ja da hast du recht, ich habe bereits selbst einmal eine Datei im 
Wurzelverzeichnis angelegt. Dies war allerdings mit dem 
UART-Kommandozeilen Programm.
Nun habe ich ein eigenes Programm versucht zu erstellen und dort hatte 
ich allerdings Probleme.
Was allerdings komisch ist, ist das ich einen Ordner anlegen kann aber 
keine Datei.

Hier ein kleiner Teil des Codes:
1
struct fat16_dir_struct* dir = 0;
2
3
while (1)
4
{
5
  if (Taster_Enter_pos_F)
6
  {
7
    struct fat16_dir_entry_struct file_entry;
8
    fat16_create_file(dir, "test.kml", &file_entry);
9
    sd_raw_sync();
10
  }
11
}
Ich danke dir für deine Hilfe, wirklich klasse Support.

Gruss

von Roland R. (roland) Benutzerseite


Lesenswert?

Das kann so auch nicht funktionieren, da Du fat16_create_file() mit dem 
ersten Argument einen Null-Pointer übergibst.

Schau mal in der main.c vom sd-reader nach, dort wird das 
Wurzelverzeichnis geöffnet. Dieses Handle auf das Wurzelverzeichnis 
übergibst Du dann fat16_create_file(), dann funktioniert es auch. Woher 
sonst sollte die Funktion sonst wissen, in welchem Verzeichnis Du die 
Datei erzeugen willst?

Gruß,
Roland

von Pito (Gast)


Lesenswert?

Hi Roland,
does the cd command in the newest sd-reader_source_20080608 work?

> mkdir rrr
> ls
rrr/                                 0
> cd rrr
directory not found: rrr

Gruss,
Pito

von Pito (Gast)


Lesenswert?

Hi,
cd works until you provide "init". Than cd stops to work..
Pito

von MarkusW (Gast)


Lesenswert?

Hallo!

Ich habe hier eine sagenhafte 8 MB(!)-SD Karte.
Erst funktionierte sie nicht, bis ich die Abfrage auf
1
 if(data_cluster_count < 4085 || data_cluster_count >= 65525)

gefunden und das entsprechende "< 4085" auskommentiert habe. So viele 
Cluster gibt es anscheinend auf einer 8MB-Karte nicht.


Jetzt habe ich aber das Problem, dass ich auf der frisch formatierten 
Karte eine Datei anlegen will (und dort auch etwas reinschreibe) und die 
Datei dann in Windows aber nicht gelesen werden kann (über das 
UART-Interface geht´s aber).
Ich führe dann ein CheckDisk ("Auf Fehler überprüfen") durch, was die 
Datei (meistens) wieder herstellt.
Danach kann ich auch weitere Dateien anlegen, die dann problemlos 
gelesen werden können.

Hier noch die Karteninfo:
1
manuf:  0x01
2
oem:    PA
3
prod:   S008B
4
rev:    41
5
serial: 0x39d181e1
6
date:   9/3
7
size:   6799360
8
copy:   0
9
wr.pr.: 0/0
10
format: 0
11
free:   6725632/6760448

Könnte das Problem nur an der geringen Größe der Karte liegen?

Gruß
Markus

von Roland R. (roland) Benutzerseite


Lesenswert?

Hallo Markus,

Wie formatierst Du die Karte denn? Vielleicht legt Windows bei der 
geringen Größe ein FAT12- und kein FAT16-Dateisystem an. Das würde auch 
erklären, warum Du die Bedingung bzgl. der Clusteranzahl auskommentieren 
musstest (die ja durchaus ihren Sinn hat, denn bei FAT12 kann es netto 
eben bis zu 4084 Cluster geben).

Gruß,
Roland

von MarkusW (Gast)


Lesenswert?

Hallo Roland!

Hast Recht.

Windows legt eine FAT12 an (hab ich mir mit "WinHex" angeschaut).

Nur: Wie kann ich trotzdem ne FAT16 formatieren?

Hab mittlerweile eine größere Karte (256MB) geliehen, jedoch bleibt 
diese in der Initialisierung (fat16_open.... partition/device_read 
irgendwo hängen).
Muss das nochmal genauer analysieren, wo es hakt.

Gruß & Danke für deine Hilfe
Markus

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.