Forum: Mikrocontroller und Digitale Elektronik FMC auf STM32F4 konfigurieren?


von lars (Gast)


Lesenswert?

Ich versuche erfolglos, den SDRAM-Baustein auf dem 
STM32F429-Discovery-Board zu verwenden.

Das Beispiel aus dem CubeHAL funktioniert erstmal. Ich habe dann ein 
Projekt von CubeMX erzeugen lassen, welches den FMC verwendet (SDRAM2, 
#0). Wenn ich nun main.c und main.h aus dem Beispiel-Projekt in mein 
Projekt kopiere (und minimal anpasse, z.B. Header), dann funktioniert 
das Beispiel plötzlich nicht mehr.

system_stm32f4xx.c sieht in meinem Projekt lediglich erweitert aus, das 
stm32f4xx_hal_conf.h ist im Wesentlichen gleich.

Hat jemand das Disco-Board schon einmal richtig konfiguriert? Ich nehme 
an, die Timing-Werte können erstmal auf 16 stehen bleiben? Meine 
Refresh-Rate ist vermutlich korrekt berechnet (1125 für 72 MHz).

Und wieso klappt das Übertragen der Sourcen vom Beispiel in mein Projekt 
nicht, wenn ich main.* komplett ersetze und die o.g. Dateien fast gleich 
sind?

von pegel (Gast)


Lesenswert?

lars schrieb:
> Wenn ich nun main.c und main.h aus dem Beispiel-Projekt in mein
> Projekt kopiere

Wer macht denn so etwas?
CubeMX hat dir doch schon alles zurecht gebaut.
Nur noch die Inits einfügen und vor allem verstehen was die paar Zeilen 
bedeuten.

von pegel (Gast)


Lesenswert?

Ich habe das Board nicht hier, aber kannst ja trotzdem mal dein ioc 
Datei anhängen.

von lars (Gast)


Lesenswert?

pegel schrieb:
> lars schrieb:
>> Wenn ich nun main.c und main.h aus dem Beispiel-Projekt in mein
>> Projekt kopiere
>
> Wer macht denn so etwas?
> CubeMX hat dir doch schon alles zurecht gebaut.
> Nur noch die Inits einfügen und vor allem verstehen was die paar Zeilen
> bedeuten.

Jo, das ist zu Testzwecken. Denn das, was CubeMX mir erzeugt, 
funktioniert nicht. Obwohl ich es prinzipiell verstehe.

Inzwischen scheine ich auch herausgefunden zu haben, woran es liegt: Die 
GPIO-Pins des FMC werden nicht konfiguriert. Ich dachte, das passiert 
automatisch irgendwo tief unten. Tatsächlich scheint das 
SystemInit_ExtMemCtl() in system_stm32f4xx.c zu erledigen, aber nur wenn 
DATA_IN_ExtSDRAM gesetzt ist?!

Welcher Programmteil konfiguriert normalerweise die GPIO-Pins? CubeMX 
setzt diese auf Alternate Function, genügt das?

von pegel (Gast)


Lesenswert?

Zeig mal deine ioc Datei, dann gucke ich mal.

von lars (Gast)


Angehängte Dateien:

Lesenswert?

pegel schrieb:
> Zeig mal deine ioc Datei, dann gucke ich mal.

Hier ist sie.

von pegel (Gast)


Lesenswert?

Wie ich sehe, benutzt du noch die alten Versionen.
CubeMX 4.22.1 und HAL 1.16.0

Hast du vor zu aktualisieren?
CubeMX 4.23.0 und HAL 1.18.0

Die alten Versionen habe ich schon gelöscht.
Sonst müsste ich wieder fast 1 GB runter laden.

Naja, ich gucke mal in die .ioc.

von pegel (Gast)


Angehängte Dateien:

Lesenswert?

Nach dem HAL Beispiel für das Board konfiguriert sieht das wie im 
rechten Teil aus. Siehe Bild.

Danach sollte HAL_SDRAM_Init fehlerfrei ausgeführt werden.

von pegel (Gast)


Lesenswert?

Des weiteren läuft dein Takt auf HSI -> 144MHz und Debug steht auf 
disable.

von lars (Gast)


Lesenswert?

Ich weiß nicht, ob mein Anliegen klar geworden ist: Das Beispiel 
funktioniert einwandfrei, aber jetzt will ich das selbst mit CubeMX (und 
z.B. einem anderen Takt) konfigurieren.

Das neue CubeMX wollte ich gerade installieren, aber dem Verzeichnis 
fehlen site.xml und features/, womit Eclipse das Plugin nicht sieht -> 
Murks.

von pegel (Gast)


Lesenswert?

lars schrieb:
> selbst mit CubeMX (und
> z.B. einem anderen Takt) konfigurieren.

Deshalt habe ich dir die CubeMX Einstellungen genannt bzw. gezeigt.

lars schrieb:
> womit Eclipse das Plugin nicht sieht

Was hälst du von dem SW4STM32 Plugin?

von C. W. (chefkoch)


Lesenswert?

Ich habe den Kampf in den letzten Wochen auch gekämpft. Offenbar ist 
neben der Initialisierung des FMC durch den CubeMX-Code auch die 
Initialisierug des SDRAMs selbst nötig. In der Datei 
*\STM32Cube_FW_F4_V1.18.0\Drivers\BSP\STM32F429I-Discovery\stm32f429i_di 
scovery_sdram.c  bin ich dann fündig geworden:
1
void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount)
2
{
3
  __IO uint32_t tmpmrd =0;
4
  
5
  /* Step 1:  Configure a clock configuration enable command */
6
  Command.CommandMode             = FMC_SDRAM_CMD_CLK_ENABLE;
7
  Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
8
  Command.AutoRefreshNumber       = 1;
9
  Command.ModeRegisterDefinition  = 0;
10
11
  /* Send the command */
12
  HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
13
14
  /* Step 2: Insert 100 us minimum delay */ 
15
  /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
16
  HAL_Delay(1);
17
18
  /* Step 3: Configure a PALL (precharge all) command */ 
19
  Command.CommandMode             = FMC_SDRAM_CMD_PALL;
20
  Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
21
  Command.AutoRefreshNumber       = 1;
22
  Command.ModeRegisterDefinition  = 0;
23
24
  /* Send the command */
25
  HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);  
26
  
27
  /* Step 4: Configure an Auto Refresh command */ 
28
  Command.CommandMode             = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
29
  Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
30
  Command.AutoRefreshNumber       = 4;
31
  Command.ModeRegisterDefinition  = 0;
32
33
  /* Send the command */
34
  HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
35
  
36
  /* Step 5: Program the external memory mode register */
37
  tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |
38
                     SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
39
                     SDRAM_MODEREG_CAS_LATENCY_3           |
40
                     SDRAM_MODEREG_OPERATING_MODE_STANDARD |
41
                     SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
42
  
43
  Command.CommandMode             = FMC_SDRAM_CMD_LOAD_MODE;
44
  Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
45
  Command.AutoRefreshNumber       = 1;
46
  Command.ModeRegisterDefinition  = tmpmrd;
47
48
  /* Send the command */
49
  HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
50
  
51
  /* Step 6: Set the refresh rate counter */
52
  /* Set the device refresh rate */
53
  HAL_SDRAM_ProgramRefreshRate(&SdramHandle, RefreshCount); 
54
}

Danach war das SDRAM ansprechbar. Die "richtigen" Timingparameter sind 
übrigens auch in der Datei bzw. teilweise im dazugehörigen H-File.

von pegel (Gast)


Lesenswert?

Genau so wird es im Beispiel auch gemacht.
Dazu findet sich die Funktion SDRAM_Initialization_Sequence
in der main.c.

von pegel (Gast)


Lesenswert?

Das wäre der nächste Schritt nach erfolgreichem HAL_SDRAM_Init gewesen.

von lars (Gast)


Lesenswert?

Diese Initialisierungssequenz aus dem Beispiel ("Steps 3-8") habe ich in 
meinem Programm auch, mit angepaßtem Timing und Refresh Rate.

Da ich einen bei mir funktionierenden LL-Schnipsel habe, konnte ich 
ermitteln, welche Schritte bei mir offenbar fehlen:

1. Das Setzen der FMC-Pins auf Alternate Function
2. RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN;

Im Datenblatt steht auch noch, dass ggf. der andere FMC-Controller noch 
gesetzt werden muß:

3. FMC_Bank5_6->SDCR[0] = ...;

Wenn ich mir die HAL-Dateien (oberflächlich) anschaue, dann finde ich 
keinen der Punkte.

von pegel (Gast)


Lesenswert?

Punkte 1 und 2 sind definitiv im erstellten Projekt.
Ich fürchte, du machst noch grundlegende Fehler bei der 
Projekterstellung aus CubeMX, bzw. bei der Bedienung von CubeMX.

Probier doch erst mal eine einfache Peripherie mit CubeMX, wie zum 
Beispiel den UART zum laufen zu bekommen.

von lars (Gast)


Angehängte Dateien:

Lesenswert?

GPIO, SDIO und RCC funktionieren, es fehlt mir nur noch der FMC.

Anbei sind meine Einstellungen in CubeMX, vielleicht erkennst Du ja, was 
ich falsch mache. Die Timing-Werte habe ich auf 16 gelassen, mehr tut ja 
nicht weh, oder?

Das CubeMX-Projekt habe ich nochmal in der aktuellen Version angehängt.

von lars (Gast)


Lesenswert?

Das neue CubeMX erzeugt übrigens einige .tmp Dateien in meinem Src/ 
Verzeichnis, darunter auch mx_fmx_MSP.tmp, welches im Prinzip die 
Pin-Definitionen für den FMC enthält. Allerdings finde ich den 
entsprechenden Code nicht in meinem main.c wieder.

von pegel (Gast)


Angehängte Dateien:

Lesenswert?

Genau das scheint das Problem zu sein.
Ob das nun durch Übernahme aus der alten Version, oder durch einen Bug 
passiert ist, weiß ich nicht.

Ich erstelle Projekte immer mit extra .c/.h Dateien siehe Bild.

Damit ist alles schön gegliedert.

Übrigens ist SWD immer noch nicht aktiv.

von pegel (Gast)


Lesenswert?

Ach ja, solltest du das mit den .c/.h Einstellungen ändern, ein
Index Rebuild nicht vergessen.

von lars (Gast)


Lesenswert?

Halleluja, das war das Problem!

Ich verstehe zwar nicht, wieso das nicht standardmäßig aktiv ist, aber 
nun funktioniert es.

von lars (Gast)


Lesenswert?

Danke für Deine Mühen, bis zum Ende durchzuhalten. :)

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.