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?
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.
Ich habe das Board nicht hier, aber kannst ja trotzdem mal dein ioc Datei anhängen.
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?
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.
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.
Des weiteren läuft dein Takt auf HSI -> 144MHz und Debug steht auf disable.
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.
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?
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.
Genau so wird es im Beispiel auch gemacht. Dazu findet sich die Funktion SDRAM_Initialization_Sequence in der main.c.
Das wäre der nächste Schritt nach erfolgreichem HAL_SDRAM_Init gewesen.
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.
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.
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.
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.
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.
Ach ja, solltest du das mit den .c/.h Einstellungen ändern, ein Index Rebuild nicht vergessen.
Halleluja, das war das Problem! Ich verstehe zwar nicht, wieso das nicht standardmäßig aktiv ist, aber nun funktioniert es.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.




