Forum: Mikrocontroller und Digitale Elektronik STM32F103: Problem mit ChanFat und SD karte


von Chris J. (Gast)


Angehängte Dateien:

Lesenswert?

Moin,

eigentlich ist "nichts klappt " öfter ein gutes Zeichen und ein Hinweis 
auf einen Fehler, der sich oft mit einem Handgriff beheben lässt. Ob es 
hier auch so ist?

Ich habe die sog. ChanFat (mmcstmf1.c = diskio) auf mich lesbare SPL Lib 
umgeschrieben, wie angehängt. Das Beispiel ist für den F100 und so nicht 
kompilierbar für F103, da hat sich einiges geändert. (Bluepill Board). 
Daher alle Basisroutinen für diskio mal angefasst und diese 
Register-Geschichten rausgeworfen, durch API Fkt ersetzt. Habe ich in 
anderen Projekten auch so gemacht, da lief es auch.

Eine SD karte verbinden ist auch kein Hexenwerk, die 4 Leitungen sind am 
Board angelötet: CS, SCK, MISO, MOSI (SPI-1, PA4 bis PA7). Card Detect 
und Card_WRIE sind auf 1 gesetzt, immer, da es keinen Auswerfschalter 
gibt und die Karte eh immer steckt.

Karte ist 2GB Class 8, formatiert auf FAT16 unter Windows.

Der China LA sagt mir das was im Bild ist. Es tut sich was aber die 
Karte reagiert nicht, nach 500ms bricht er mit Timeout ab.

Und nun? Wo fängt man da an zu suchen? Der Adapter ist eines dieser 
Dinger vom Arduino, 5V Pegel-Wandler mit drauf. Müssten mit 3.3V aber 
klarkommen mit der Threasholdspannung.

jemand eine idee? Sieht das wenigstens normal aus, was man so sieht? 
f=125 khz für Init Sequenz

von temp (Gast)


Lesenswert?

Was soll die Karte auch senden wenn du nur lauter 0xff ausgibst?
Ich finde deinen Ansatz gelinde gesagt Mist. Entweder du bleibst bei den 
Registern oder du machst alles über die HAL oder SPL. Am schlechtesten 
ist beides zu vermischen.

von Chris J. (Gast)


Lesenswert?

Das ist schon alles richtig so, das Beispiel läuft nicht auf einem F103. 
Vermischt ist da nichts, alles auf SPL jetzt.  Und in der uarlten MMC 
Spec steht auch was drin. Neue habe ich nicht, die kosten Geld.

Trotzdem ist da noch der Wurm drin..... wie klingelt man denn nun die 
Karte aus dem Schlaf? Das macht doch alles die ChanFat dachte ich.

von Chris J. (Gast)


Lesenswert?

Code von mir von 2007 (abstaub) für einen PIC
1
/ *********************************************************************************
2
// Initialisieren der MMC Karte nach Power On
3
// Rückgabe: 1 = ok, 0 = Fehler
4
// *********************************************************************************
5
6
uint8_tmmc_init()
7
{
8
  byte i;
9
10
    mmc_InitSPI(SPI_SPEED);
11
    ChipSelect(devSD,0);    // MMC Karte ausschalten
12
13
  for(i=0;i<100;i++)           // initialise the MMC card into SPI mode by sending clks on
14
     SPIMMC(0xFF);
15
16
  ChipSelect(devSD,1);    // MMC ein
17
18
  // Sende CMD0 an die Karte
19
  restart_wdt();
20
  i=0;
21
22
  do {
23
    SPIMMC(0xFF);
24
    SPIMMC(0x40);           // Sende Reset command
25
    SPIMMC(0x00);
26
    SPIMMC(0x00);
27
    SPIMMC(0x00);
28
    SPIMMC(0x00);
29
    SPIMMC(0x95);  
30
    if(++i >= 50)
31
    {
32
      f_mmc_Error   = TRUE;
33
      mmc_ErrorCode = MMC_ERR_INIT;
34
      ChipSelect(devSD,0);
35
            return (0);              // Timeout, Fehler!
36
          }  
37
  } while(!mmc_response(0x01));
38
39
  SPIMMC(0xFF);
40
  SPIMMC(0xFF);
41
  SPIMMC(0xFF);
42
  
43
  // Sendet CMD1 wiederkehrend an die Karte
44
  i = 0;
45
  restart_wdt();
46
  do  {
47
    SPIMMC(0xFF);
48
        SPIMMC(0x41);            // sende mmc Kommando um Idle Mode zu beenden
49
        SPIMMC(0x00);            // Alle Parameter sind 0x00
50
        SPIMMC(0x00);
51
        SPIMMC(0x00);
52
        SPIMMC(0x00);
53
        SPIMMC(0xFF);            // Checksumme ist immer 0xff
54
    if(++i >= 50)
55
    {
56
      f_mmc_Error = TRUE;
57
      mmc_ErrorCode = MMC_ERR_INIT1;
58
      ChipSelect(devSD,0);
59
         return (0);              // Timeout, Fehler!
60
       }
61
  } while(!mmc_response(0));
62
63
  ChipSelect(devSD,0);
64
  f_mmc_Error = FALSE;
65
  mmc_ErrorCode = NO_ERROR;
66
67
  return (1);
68
}

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Chris J. schrieb:
> Daher alle Basisroutinen für diskio mal angefasst und diese
> Register-Geschichten rausgeworfen, durch API Fkt ersetzt. Habe ich in
> anderen Projekten auch so gemacht, da lief es auch.

Tja, wenn du meinst...

Also mal grundsätzlich: Chan's Fat File System wird eigentlich auf eine 
Lowlevel-Schicht draufgesetzt - und die muß zunächst erstmal 
funktionieren. Dazu gehört, daß die Karte richtig angesprochen, erkannt 
und hochgefahren werden muß, bevor irgend etwas mit dem Filesystem 
gemacht werden kann.

Also laß erstmal das ganze Filesystem beiseite und kümmere dich um das 
artgerechte Ansprechen der Karte. Aber was schreibst du da von einem 
BluePill-Board? Damit eine SD-Karte betreiben wollen?

Ich hänge dir mal einen steinalten Treiber zur Ansicht dran. Der kommt 
logisch noch weit unterhalb der Block-I/O Ebene von Chans FF. Ob der 
heutige Kartentypen versteht, mußt du selber nachschauen.

W.S.

von Jim M. (turboj)


Lesenswert?

Guck mal nach ob MOSI korrekt auf "Alternate Function" für SPI steht.

Ich sehe aber leider nicht ob das ein Kommando oder die 
Erstinitialisierung ist, letztere hat eine verdammt lange 0xFF Sequenz 
Host->Card am Anfang - allerdings mit CS=HIGH - was hier schenbar der 
Fall ist.

Bei CS=LOW muss danach eigentlich am Anfang ein Kommando Byte kommen, 
das fängt mit einem Low Bit gefolgt von einem High Bit an (0x40). Das 
sehe ich hier nicht.

[Nachschau im Code]

Jup, Du wartest beim Senden von CMD0 auf einen Wert != 0xFF von der 
Karte, die vor dem Senden des Kommandos aber gar nicht im SPI Modus ist:
1
/* Select the card and wait for ready except to stop multiple block read */
2
  if (cmd != CMD12) {
3
    deselect();
4
    if (!select_card()) return 0xFF;
5
  }

Hier müsste man eine weitere Ausnahme für CMD0 machen. Das schaltet die 
Karte erst in den SPI Mode um.

von Chris J. (Gast)


Lesenswert?

Jim M. schrieb:
> Jup, Du wartest beim Senden von CMD0 auf einen Wert != 0xFF von der
> Karte, die vor dem Senden des Kommandos aber gar nicht im SPI Modus ist:

Muss ich jetzt mal gucken.... dauert etwas..... dieser Code war schon 
fertig, ich habe nur die LL Routinen angefasst, die Plattformabhängig 
sing.

Mosi steht richtig:
1
/*-------- SCK (PA5 Out), MOSI (PA7 Out), MISO (PA6 In) -------------*/
2
    GPIO_StructInit (&GPIO_InitStructure);
3
    GPIO_InitStructure.GPIO_Pin    = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
4
    GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF_PP;
5
    GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_50MHz;
6
    GPIO_Init(GPIOA, &GPIO_InitStructure);

von Chris J. (Gast)


Lesenswert?

Jim M. schrieb:
> Ich sehe aber leider nicht ob das ein Kommando oder die
> Erstinitialisierung ist, letztere hat eine verdammt lange 0xFF Sequenz
> Host->Card am Anfang - allerdings mit CS=HIGH - was hier schenbar der
> Fall ist.

Ja, ist links abgeschnitten, das sind über 100 Clocks am Anfang, ist 
auch ok so meine. War früher auch so, damit die in den SPI Mode kam. Die 
LL Routinen spielen wohl glaube ich, aber die ff.c, die das alles 
steuert.... naja, Fehler liegt wohl bei mir.

von temp (Gast)


Lesenswert?

Chris J. schrieb:
> Vermischt ist da nichts, alles auf SPL jetzt
1
void SPI_16Bit()
2
{
3
    /* SPI abschalten */
4
    SPI_Cmd(SPI1, DISABLE);
5
    /* Setze Bit für 16 Bit Worte */
6
    SPI1->CR1 |= SPI_CR1_DFF;
7
    /* SPI wieder einschalten */
8
    SPI_Cmd(SPI1, ENABLE);
9
}

Was ist das sonst?

von Chris J. (Gast)


Angehängte Dateien:

Lesenswert?

Da stimmt was nicht.....
1
SPI_8Bit();
2
    FCLK_SLOW();
3
    CS_LOW();
4
    xchg_spi(0x11);
5
    xchg_spi(0x22);
6
    xchg_spi(0x33);
7
    xchg_spi(0x44);
8
    CS_HIGH();
9
    CS_HIGH();

ergibt

von Chris J. (Gast)


Angehängte Dateien:

Lesenswert?

temp schrieb:
> Was ist das sonst?

Ausnahme, dafür gibt es nichts Besseres... zumindest nicht in der Kürze.
edit: Erschlag mich bitte keiner, aber da ist ein Draht am falschen 
Pin..... au weia, wie peinlich :-(

So, das sieht doch schon ganz anders aus.... immerhin kriege ich jetzt 
ne Meldung von fopen "FR_NO_FILESYSTEM" oder "FR_NOT_READY".

Leider aber nicht das was sein soll.
1
 /* Register work area to the default drive */
2
   FRESULT fr;
3
   fr = f_mount(&FatFs, "", 0);
4
   fr =  f_open(&Fil,"test.txt",FA_WRITE);
5
   fr =  f_write(&Fil,buf,sizeof(buf),&res);
6
   fr =  f_close(&Fil);

f_mount wird zwar mit OK bestätigt aber danach steht nichts in FatFs 
drin. Nur Nullen. f_open erzeugt Fehlermeldung FR_NOT_READY".

von Chris J. (Gast)


Angehängte Dateien:

Lesenswert?

Keine eine Idee, was da noch falsch sein könnte?

- Karte reagiert, sie gibt Daten aus
- SPI hat zwei Geschwindigkeiten 500khz und 8 Mhz

aber ständig die Meldung FR_NO_FILESYSTEM oder FR_NOT_READY.

Habe beide Karten 2gb und 16Gb auf alle möglichen Arten formatiert, die 
im Manual der Chat Fat angeben waren. FAT32 mit 4096 Sector Size und 
einmal die kleine Karte auch mit FAZT16.

disk_initialize bricht dann mit dem jeweiligen Fehlercode ab.

Nüscht... :-((

von temp (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab die lib gerade mal getestet weil ich das demnächt auch nochmal 
brauche. Ich hänge dir mal meine mmc_stmf1.c dran. Die ist aber komplett 
ohne STL ö.ä.

Damit konnte ich mit diesem Code das root-Verzeichnis auslesen:
1
FATFS Fatfs; 
2
DIR aDir;
3
int ReadDir()
4
{
5
  int frc=disk_initialize(0);
6
  if (frc!=0)
7
    return -1;
8
9
  frc=f_mount(&Fatfs, "/", 1);
10
  if (frc!=0)
11
    return -2;
12
13
  frc=f_opendir(&aDir, "/");
14
  if (frc!=0)
15
    return -3;
16
17
  while (frc==0)
18
    {
19
    FILINFO aFi;
20
    frc=f_readdir (&aDir, &aFi);
21
    char *pc=aFi.fname;
22
    if (*pc==0)
23
      break;
24
25
    debug_printf("foud: %s\n", pc);
26
    }
27
  return 0;
28
}

von Chris J. (Gast)


Angehängte Dateien:

Lesenswert?

Deine initialize funzt auf einer 16GB Karte, auf der 2 GB kommt ein 
FR_DISK_ERROR (egal ob mit Fat32 oder Fat formatiert). Die weiteren 
Funktionen werden mit "NO Filesystem" abgebrochen..... wir sind dran.... 
boah, ne. Bei Arduino lief das alles sofort, out of the box.

Dass die karten im PC einwandfrei lesebar und bechreibar sind brauche 
ich nicht zu erwähnen...

von Chris J. (Gast)


Angehängte Dateien:

Lesenswert?

Erledigt.... und ich auch! ;-(

Erstens war die Stromversorgung nicht stabil, die SD karte war zuviel 
für den 100mA Regler. Darauf musste man auch erstmal kommen. Jetzt ist 
ein AMS1171 3.3V drin, der 1A kann. Und ich habe bei der Umsetzung der 
SPI LowLevel Routinen zwei Fehler gemacht in dem ich vergessen habe vor 
dem Beschreiben der SPI das Busy Flag abzufragen. Eingefügt und jetzt 
läuft es. Uhrzeit des Files stimmt auch mit der RTC überein. Wenigstens 
das auf Anhieb richtig gemacht.

von Jim M. (turboj)


Lesenswert?

Chris J. schrieb:
> Erstens war die Stromversorgung nicht stabil, die SD karte war zuviel
> für den 100mA Regler. Darauf musste man auch erstmal kommen.

Spec lesen: SD Karten im SPI Mode dürfen 100mA im Schnitt saugen. Wenn 
da noch der µC mit am 100mA Regler hängt (oder bei zuviel Voltage drop) 
reichts nicht.

Übrigens sind 500kHz bei der Initialisierung 100kHz zuviel. Das muss 
nicht bei jedem Karten Typ gut gehen.

von Chris J. (Gast)


Lesenswert?

Jim M. schrieb:
> Übrigens sind 500kHz bei der Initialisierung 100kHz zuviel. Das muss
> nicht bei jedem Karten Typ gut gehen.

Ja, habs auch gesehen. Tiefer gehts aber nicht runter, dazu muss ich den 
AHB Clock ändern und dazu bin ich jetzt zu müde.....

von Dr. Sommer (Gast)


Lesenswert?

Warum überhaupt MMC? Man kann die aktuelle SD-Spezifikation gratis 
herunterladen ("simplified" - reicht aber).
Warum SDSC (2 GB) - da ist doch das Handling der Block-Größe voll 
kompliziert. Das ist bei den SDHC-Karten (2-32 GB) einfacher, da sind 
die Blöcke immer 512B.

von Chris J. (Gast)


Lesenswert?

Das Fass mach ich dan erst auf, wenn ich den Code morgen aufgeräumt habe 
und den ganzen Test Scheiss wieder raus habe und das was ich machen will 
funktioniert. Die 2Gb tuts es jetzt erstmal, alles andere dann später... 
nicht alles auf einmal wollen. Die Geburt heute war schwer genug.

von Dr. Sommer (Gast)


Lesenswert?

Chris J. schrieb:
> Habe beide Karten 2gb und 16Gb auf alle möglichen Arten formatiert, die
> im Manual der Chat Fat angeben waren. FAT32 mit 4096 Sector Size und
> einmal die kleine Karte auch mit FAZT16.

SD-Karten darf man nur auf genau eine Art formatieren, damit es Betrieb 
innerhalb der Spezifikation ist und maximale Performance & Lebensdauer 
erreicht wird. Das erledigt dieses Tool:
https://www.sdcard.org/downloads/formatter_4/index.html

von Chris J. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> SD-Karten darf man nur auf genau eine Art formatieren, damit es Betrieb
> innerhalb der Spezifikation ist und maximale Performance & Lebensdauer
> erreicht wird.

Datei Explorer, Rechte Maustaste, Formatieren.....warten, fertig.
Oder nicht?

von Jim M. (turboj)


Lesenswert?

Chris J. schrieb:
> Datei Explorer, Rechte Maustaste, Formatieren.....warten, fertig.
> Oder nicht?

Ich hatte hier -zugegeben billige- Karten die nach dieser Behandlung 
innerhalb weniger Wochen nur noch Elektroschrott waren. Entweder nur 
noch les- oder gar nicht mehr ansprechbar. YMMV.

von Chris J. (Gast)


Lesenswert?

In meiner Canon EOS 6D benutze ich Karten die das Stück ca 100 Euro 
kosten..... hat auch seinen Grund :-) zb den nach 1 Woche mit 800 
Bildern nach Hause zu kommen aber keine mehr zu finden, weil die Karte 
Fratze ist.
Und man nie wieder zurück kann, da wo sie gemacht wurden. Schon gehabt..

 Gute Nacht...

von Dr. Sommer (Gast)


Lesenswert?

Chris J. schrieb:
> Datei Explorer, Rechte Maustaste, Formatieren.....warten, fertig.
> Oder nicht?

Nö. Windows hält hier nicht die von der SD Spezifikation vergebene 
Struktur ein (Größe der FAT, Anzahl reservierter Sektoren usw.). Daher 
kann das Wear Leveling eventuell nicht optimal arbeiten. Das Tool von 
sdcard.org macht's korrekt.

von Dr. Sommer (Gast)


Lesenswert?

Chris J. schrieb:
> In meiner Canon EOS 6D benutze ich Karten die das Stück ca 100 Euro
> kosten..

Das beste Produkt nützt nix wenn man es nicht nach Spezifikation 
benutzt.

von Chris J. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Das beste Produkt nützt nix wenn man es nicht nach Spezifikation
> benutzt.

Dr. Sommer.. (Dr.?)... die Cam ist ein Arbeitswerkzeug. Die muss einfach 
laufen, laufen, laufen und zwar in Höhlen genauso wie in der Karibik. Da 
frage ich nicht nach Spec, das muss das Boot einfach abkönnen! Genauso 
ie meine Taschenlampe. Nicht auszudenken, wenn die in einem Bunker oder 
einer Höhle ausfallen würde. (Ok, ich habe 2 dabei :-)

;-)

von Dr. Sommer (Gast)


Lesenswert?

Chris J. schrieb:
> Da frage ich nicht nach Spec, das muss das Boot einfach abkönnen!

Mach was du willst, wenn es dir ein besonderes Bedürfnis ist lieber den 
Windows Formatter zu nutzen und du den Empfehlungen der SD Card 
Association - und wer soll es wissen, wenn nicht die - nicht glaubst. 
Ich bemühe mich immer zu erfahren was meine Werkzeuge können und was 
nicht, um sie geeignet einzusetzen. Gerade bei besonders teuren 
Exemplaren fände ich es schade, wenn durch fehlerhafte Formatierung die 
Lebensdauer leidet.

von Chris J. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Mach was du willst, wenn es dir ein besonderes Bedürfnis ist lieber den
> Windows Formatter zu nutzen und du den Empfehlungen der SD Card
> Association - und wer soll es wissen, wenn nicht die - nicht glaubst.

Ich glaube mal, dass Du der Einzige bist der sich darüber Gedanken 
macht, denn 99% nehmen die Methode wie ich sie mache und da diese Karten 
die Zielgruppe "Hinz & Kunz" haben, sollte das auch das Ziel der 
Hersteller sein. Man kann von niemandem erwarten, dass er überhaupt 
weiss, dass es einen Formatter dafür gibt. Das machen die geräte selbst 
oder er macht es auf einem PC. Und ich habe mein ganzes Leben noch 
niemals eine Karte verloren durch "Geht nicht mehr". Keine einzige...

So, probiere Deinen Formatter grad mal aus....

von Dr. Sommer (Gast)


Lesenswert?

Chris J. schrieb:
> sollte das auch das Ziel der
> Hersteller sein. Man kann von niemandem erwarten, dass er überhaupt
> weiss, dass es einen Formatter dafür gibt.

Das steht bestimmt in der Anleitung.

Chris J. schrieb:
> Und ich habe mein ganzes Leben noch
> niemals eine Karte verloren durch "Geht nicht mehr". Keine einzige...
Ich hab hier eine Karte, wenn man die in einen Windows-PC steckt bleibt 
Windows stehen. Elektrisch ist sie i.O., sie reagiert nur auf manche 
Befehle nicht...

Es ist doch so:
Du hast eine SD-Karte. Die SD-Karte entspricht der SD-Spezifikation. Die 
SD-Spezifikation verlangt eine bestimmte Formatierung. Es kann natürlich 
sein, dass manche Karten auch mit anderer Formatierung genauso gut 
funktionieren. Aber solange man das nicht schwarz auf weiß vom 
Hersteller hat, gilt a priori die Spezifikation. Und es ist jetzt auch 
wirklich kein gigantischer Aufwand, das Tool von sdcard.org zu nutzen - 
warum da lang diskutieren und argumentieren, dass es vielleicht auch 
anders geht/"gehen sollte"? Fährst du mit deinem Auto auch 
ausschließlich rückwärts, weil das Getriebe das ja eigentlich aushalten 
sollte?

von Dr. Sommer (Gast)


Lesenswert?

Chris J. schrieb:
> So, probiere Deinen Formatter grad mal aus....
Das ist nicht mein Formatter, das ist der von den Erfindern der 
SD-Karten. Die sollten wissen wie das geht.

von Chris J. (Gast)


Lesenswert?

Jetzt habe ich den Zirkus wieder, dass die Debug Version läuft (O0) und 
die Release Version (-Os) vergeigt, weil da was mit der SPI anders 
ist.... boaaah. Hatte ich schonmal, bloss wie ich das gelöst habe weiss 
ich nicht mehr.

Geht nur so, ohne die pragmas nicht.. da hat ChaN nen Fehler gemacht. Es 
muss nicht das BUSY Flag dr SPI abgefragt werden, sondern das RXNE Bit. 
Dan läuft es wieder.
1
/* Receive multiple byte */
2
#pragma GCC push_options
3
#pragma GCC optimize ("-O0")
4
static void rcvr_spi_multi ( uint8_t *buff,    /* Pointer to data buffer */
5
                             uint32_t btr)      /* Number of bytes to receive (even number) */
6
{
7
  uint16_t d;
8
9
  SPI1->CR1 &= ~_BV(6);
10
  SPI1->CR1 |= (_BV(6) | _BV(11));  /* Set SPI to 16-bit mode */
11
  SPI1->DR = 0xFFFF;
12
13
  btr -= 2;
14
  do {          /* Receive the data block into buffer */
15
        /* Wait for RF_SPI Busy Flag cleared */
16
    while (SPI1->SR & _BV(7)) ;
17
    d = SPI1->DR;
18
    SPI1->DR = 0xFFFF;
19
    buff[1] = d;
20
    buff[0] = d >> 8;
21
    buff += 2;
22
  } while (btr -= 2);
23
24
    /* Wait for RF_SPI Busy Flag cleared */
25
  while (SPI1->SR & _BV(7)) ;
26
  d = SPI1->DR;
27
28
  buff[1] = d;
29
  buff[0] = d >> 8;
30
31
  SPI1->CR1 &= ~(_BV(6) | _BV(11));  /* Set SPI to 8-bit mode */
32
  SPI1->CR1 |= _BV(6);
33
}
34
#pragma GCC pop_options

Beitrag #5358324 wurde vom Autor gelöscht.
von temp (Gast)


Lesenswert?

Das mit den Flags habe ich auch schon bemerkt. Auf Seite 690 im Manual 
steht:

Note: Do not use the BSY flag to handle each data transmission or 
reception. It is better to use the
TXE and RXNE flags instead.

Deshalb finde ich es nicht besonders klug zusätzlich auf das BSY-Flag zu 
warten wie in deinem zu letzt geposteten Code in diesem Thread:

Beitrag "STM32F103 diskio.c für Chan FatFs SD Karten Treiber"

Dann hatte ich auch mal den Effekt dass das Programm beim Warten auf das 
RXNE Flag hing. Ich halte es deshalb an der Stelle für wichtig da noch 
einen Notfalltimeout zu implementieren.


Chris J. schrieb:
> Ja, habs auch gesehen. Tiefer gehts aber nicht runter, dazu muss ich den
> AHB Clock ändern und dazu bin ich jetzt zu müde.....

Das habe ich bei mir auch noch geändert.
Der größte Vorteile ist 256 mit 0x7 in CR1_BR. Damit kriege ich bei 
72MHz 281kHz für die Initialisierung. Das habe ich auch gemessen und 
passt gut.

von STM Apprentice (Gast)


Lesenswert?

temp schrieb:
> Deshalb finde ich es nicht besonders klug zusätzlich auf das BSY-Flag zu
> warten

Auf dieses Flag muss man aber zwingend warten um einen
vorhandenen und gerade aktiven Soft-Chipselect wieder zu
deaktivieren sonst zieht man dem Datenstrom den Boden
unter den Füssen weg.

von Chris J. (Gast)


Lesenswert?

temp schrieb:
> Deshalb finde ich es nicht besonders klug zusätzlich auf das BSY-Flag zu
> warten wie in deinem zu letzt geposteten Code in diesem Thread:

Das ist aktuell geprüft und lauffähig bei maximaler Optimierung. Ich 
arbeite aber noch dran und lese grad das Manual Seite für Seite durch. 
Ist noch nicht am Ende das alles.... werde noch Messungen machen und mir 
das genau anschauen auf dem LA.

Das BSY muss immer am Ende eines Frames abgefragt werden. Auch wenn man 
die SPI nicht abschaltet aber auf jeden Fall bevor man CS=Inaktiv setzt.

>>Ich halte es deshalb an der Stelle für wichtig da noch
>>einen Notfalltimeout zu implementieren.

Nicht wirklich. Wie willlst du denn reagieren? ich habe den WDT und wenn 
was hängt bootet es neu und beschwert sich mit ner Meldung.

Überdies ist es GENERELL, ob SPI, I2C etc problematisch, wenn 2 
Statemachines in einer verzahnt sind und mal ein Zahn durchrutscht, Mir 
schmiert auch alle 2-3 Wochen mein "Wand Brett" (Wetterstation auf 
Lochraster) ab, weil I2C und das EE sich nicht mehr verstehen. Nur 
an/aus hilft da noch. Da reicht ein elektrischer Funke in der Umgebung. 
Es ist nicht verkehrt eine SD abschaltbar zu machen über die 
Stromversorgung, da auch diese keinen Reset Pin hat

von temp (Gast)


Lesenswert?

Chris J. schrieb:
> Das BSY muss immer am Ende eines Frames abgefragt werden. Auch wenn man
> die SPI nicht abschaltet aber auf jeden Fall bevor man CS=Inaktiv setzt.

Wenn man auf nach dem eigenen Senden auf das RXNE Flag wartet kann es 
niemals vor dem Ende der Übertragung der Fall sein. Zu dieser Zeit kann 
CS gefahrlos deaktiviert werden. Hab gerade mal in meinen anderen Sachen 
nachgesehen, das BSY Flag habe ich nie gebraucht. Weder bei enc28j60 
noch beim Wiznet5500.

In der select() Methode gibt es im übrigen meiner Meinung nach auch noch 
was zum Optimieren:
1
static
2
int select (void) /* 1:OK, 0:Timeout */
3
{
4
  CS_LOW();   /* Set CS# low */
5
  
6
  // xchg_spi(0xFF); /* Dummy clock (force DO enabled) */
7
  if (wait_ready(500)) 
8
    return 1;  /* Wait for card ready */
9
10
  deselect();
11
  return 0; /* Timeout */
12
}

das xchg_spi(0xFF) vor dem wait_ready ist eigenlich nicht nötig, da in 
wait_ready auch als erstes das xchg_spi(0xff) gemacht wird. Es soll ja 
nur dazu dienen um fest zu stellen ob das auch wieder die 0xff liefert. 
Wenn das beim ersten Vergleich schon der Fall ist, ist das 2. Byte an 
der Stelle überflüssig.

von Chris J. (Gast)


Angehängte Dateien:

Lesenswert?

temp schrieb:
> In der select() Methode gibt es im übrigen meiner Meinung nach auch noch
> was zum Optimieren:

Ist mir auch aufgefallen, fasse ich aber noch nicht an. Er schiebt immer 
einen Rohrputzer mit raus, bevor er abschaltet. Macht man übrigens bei 
einer Panzerhaubitze auch, so einen Watteklumpen durchs Rohr jagen :-) 
Ich habe mal den Code mit angehängt, nur im Kopf verändert, testen geht 
erst heute abend.

von STM Apprentice (Gast)


Lesenswert?

temp schrieb:
> Wenn man auf nach dem eigenen Senden auf das RXNE Flag wartet kann es
> niemals vor dem Ende der Übertragung der Fall sein. Zu dieser Zeit kann
> CS gefahrlos deaktiviert werden.

Das ist nur richtig wenn die SPI-Maschine die CS-Steuerung
übernimmt. Sobald du CS selbst in Software bedienst passiert
das was ich hier beschrieben habe:

Beitrag "[STM32F4xx] SPI Optimierung"

(der erste Screenshot des Eröffnungs-Beitrages)

Nochmal zum Mitlesen: Bei Soft-CS-Handling muss auf das
Busy-Bit gewartet werden sonst bekommt der Slave nicht
alle Datenbits mit!

von Chris J. (Gast)


Lesenswert?

STM Apprentice schrieb:
> Nochmal zum Mitlesen: Bei Soft-CS-Handling muss auf das
> Busy-Bit gewartet werden sonst bekommt der Slave nicht
> alle Datenbits mit!

Sag ich doch! Die Denkweise eines sequentiellen Ablaufes ist eben 
falsch, da wird eine SM gefüttert, die nebenbei läuft. Und dass der ChaN 
Code versagt wenn man Os einschaltet liegt eben daran, dass da vorher 
genug Takte zwischen waren und dann nicht mehr, so dass etwas verloren 
ging.

Lieber einmal mehr abfragen als einmal zu wenig.

von temp (Gast)


Lesenswert?

STM Apprentice schrieb:
> Nochmal zum Mitlesen: Bei Soft-CS-Handling muss auf das
> Busy-Bit gewartet werden sonst bekommt der Slave nicht
> alle Datenbits mit!

Und wenn du es noch so laut in die Welt pustest. Wenn nach dem Senden 
auf das RXNE gewartet wird (und nicht auf TXE wie in deinem Thread), 
dann ist die Übertragung sehr wohl zu Ende, oder wo sollen die 
Eingagsbits herkommen?. Du hast in deinem Code nur schnell Senden wollen 
ohne das DR Register zu lesen. Das ist hier aber anders. So ungefähr wie 
in deiner Funktion2().

von temp (Gast)


Lesenswert?

Chris J. schrieb:
> Und dass der ChaN
> Code versagt wenn man Os einschaltet liegt eben daran

Das nur auf das BSY gewartet wurde ohne das RXNE zu kontrolieren. Und zu 
dem Zeitpunkt stand da Müll im DR.

Das was ins DR Register beim Empfangen geschoben wird ist genau das was 
der Slave auch bekommt. Wieso soll da zum Zeitpunkt RXNE nichts gültiges 
drin stehen?

von Chris J. (Gast)


Lesenswert?

temp schrieb:

> Das nur auf das BSY gewartet wurde ohne das RXNE zu kontrolieren. Und zu
> dem Zeitpunkt stand da Müll im DR.
>
> Das was ins DR Register beim Empfangen geschoben wird ist genau das was
> der Slave auch bekommt. Wieso soll da zum Zeitpunkt RXNE nichts gültiges
> drin stehen?

Ich kann Dir nur sagen, dass der Code so wie er war nicht mehr lief, 
sobald O3 gesetzt war. Und dass das an einer Stelle lag, die ich sehr 
genau einkreisen konnte. Sobald ich das auf meine Denke geändert hatte 
oder mal testweise O0 gesetzt habe war es weg. Ich habe daher das ganze 
BSY Bit Geraffel rausgeworfen, bzw nur vor CS=HIGH eingefügt und schon 
läuft alles richtig und prächtig, die Bits schnurren wie die Motten ums 
Licht in die Karte.

von Chris J. (Gast)


Lesenswert?

Moin,

da die ChaN Fat nun spielt (ja.... die Software funktioniert wirklich!), 
und vermutlich der langsamste SD Kartenleser der Welt ist, ich die 
vielen Format Strings schreibe für die Logfiles auf Karte mal eine 
Frage:

Muss man nach jedem fertigen Schreibzugriff eigentlich ein f_close 
machen? Oder kann man ein File getrost auch länger offen lassen? (15 
Minuten). Ist das tragisch, wenn die Platine dann mal stromlos wird? 
Aktuell setze ich immer wieder mit FA_OPEN_APPEND neue Daten hinten an.

von Dr. Sommer (Gast)


Lesenswert?

Chris J. schrieb:
> Oder kann man ein File getrost auch länger offen lassen? (15
> Minuten).
Ja.

Chris J. schrieb:
> Ist das tragisch, wenn die Platine dann mal stromlos wird?
Ja! Du musst vor Abschalten der Karte auf jeden Fall alle Dateien 
schließen, und das Dateisystem unmounten. Sonst sind die Daten 
inkonsistent und können ggf. nicht mehr gelesen werden 
(Dateisystemfehler).

von Chris J. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Ja! Du musst vor Abschalten der Karte auf jeden Fall alle Dateien
> schließen, und das Dateisystem unmounten. Sonst sind die Daten
> inkonsistent und können ggf. nicht mehr gelesen werden

Ist das wirklich so? Hat die FatFs einen Cache? Beim PC mag das sein.... 
hier müsste ich schon überzeugt sein und werden. Was sagt denn die SD 
Spec dazu?

von Dr. Sommer (Gast)


Lesenswert?

Chris J. schrieb:
> hier müsste ich schon überzeugt sein und werden

Dann schau halt in den Code. Wenn FatFs nach jedem einzelnen 
Schreibzugriff den Verzeichnis Eintrag aktualisieren würde, wäre sie 
schon enorm ineffizient.

Chris J. schrieb:
> Was sagt denn die SD Spec dazu?

Die sagt nur dass unterbrochene Schreibzugriffe kaputte Daten 
produzieren  können. Aber auch wenn nie einer unterbrochen wird, können 
die FAT-Daten inkonsistent sein, da ja mehrere Zugriffe nötig sind, um 
ein Dateisystem in einen konsistenten Zustand zu bringen.

von Chris J. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Dann schau halt in den Code. Wenn FatFs nach jedem einzelnen
> Schreibzugriff den Verzeichnis Eintrag aktualisieren würde, wäre sie
> schon enorm ineffizient.

Das überzeugt schon absolut! Und es gibt ja noch 2 Fat Tabellen. Evtl. 
arbeite ich da mit Timeout, erfolgen x Sekunden keine weiteren Zugriffe 
schließe ich die Datei ab, eröffne sie später dann wieder neu.

von Dr. Sommer (Gast)


Lesenswert?

Alternativ verwendest du einen Puffer-Kondensator/Batterie, sodass du 
beim Abschalten der Spannungsversorgung noch genug Zeit hast, die Datei 
zu schließen und das Dateisystem zu unmounten. Oder der Ausschalter 
schaltet nur "soft" ab, sodass der Controller die tatsächliche 
Abschaltung erst später besorgt.

von Leo C. (rapid)


Lesenswert?

Statt die Daei regelmäßig zu schließen und gleich wieder mit 
f_open(...OPEN_APPEND) zu öffnen, tut es auch f_sync().

http://elm-chan.org/fsw/ff/doc/sync.html

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.