Forum: Mikrocontroller und Digitale Elektronik STM32: neuer SDRAM-IC läuft nicht


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von lars (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Auf einem selbst entwickeltes Board mit einem STM32F746 verwende ich 
einen SDRAM IC (4 Bänke, 16-Daten-Bits, 256Mb). Bisher habe ich einen 
MT48LC16M16A2 von Micron verwendet, nun möchte ich stattdessen einen 
NDS36PT5-20ET von Insignis benutzen.
(Datenblatt: http://insignis-tech.com/download/145)

Der Micron IC funktioniert (auf dem gleichen Board) problemlos, aber ich 
bekomme den Insignis IC einfach nicht zum Laufen. In meinem kleinen 
Testprogramm
1
uint32_t i;
2
for (i = 0; i < 16384; i += 2) {
3
  *(__IO uint16_t *) (SDRAM_BASE + i) = i & 0xffff;  //SDRAM_BASE=0xC000k
4
}
5
     
6
for (i = 0; i < 16384; i += 2) {
7
  uint16_t data = *(__IO uint16_t *) (SDRAM_BASE + i);
8
  if (data != (i & 0xffff)) {
9
    while (1);  // breakpoint here
10
  }
11
}

liefert der erste Lesezugriff 0x3ffe anstatt 0 zurück.

Der STM32F746 läuft mit 200 MHz, der FMC und das SDRAM daher mit 100 
MHz. Ein FMC-Zylkus dauert also 10 ns. Das SDRAM IC ist für 200 MHz 
ausgelegt. Ich habe dann die Zeitabgaben für 200 MHz aus dem Datenblatt 
(Bild 1) jeweils durch 10 ns geteilt und aufgerundet, um die Anzahl der 
FMC-Zyklen für CubeMX zu erhalten (Bild 2). Write recovery time müsste 1 
sein, wird aber von CubeMX auf 2 gesetzt.

Als CAS Latency habe ich 3 gewählt. Die Refresh-Rate ist (64 / 8192 * 
100) * 1000 - 20 (die *1000 ergeben sich durch den Einheitenfehler, den 
die Formel macht).

Das SDRAM wird mit diesem Code initialisiert, was dem Datenblatt (Bild 
3) entspricht.
1
static void SDRAM_Init()
2
{
3
  FMC_SDRAM_CommandTypeDef Command;
4
     
5
  __IO uint32_t tmpmrd =0;
6
  /* Step 3:  Configure a clock configuration enable command */
7
  Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
8
  Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
9
  Command.AutoRefreshNumber = 1;
10
  Command.ModeRegisterDefinition = 0;
11
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
12
     
13
  /* Step 4: Insert 100 us minimum delay */
14
  /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
15
  HAL_Delay(1);
16
     
17
  /* Step 5: Configure a PALL (precharge all) command */
18
  Command.CommandMode = FMC_SDRAM_CMD_PALL;
19
  Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
20
  Command.AutoRefreshNumber = 1;
21
  Command.ModeRegisterDefinition = 0;
22
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
23
     
24
  /* Step 6 : Configure a Auto-Refresh command */
25
  Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
26
  Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
27
  Command.AutoRefreshNumber = 2;  // Insignis SDRAM
28
  Command.ModeRegisterDefinition = 0;
29
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
30
     
31
  /* Step 7: Program the external memory mode register */
32
  tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |  // 0
33
                     SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |  // 0
34
                     SDRAM_MODEREG_CAS_LATENCY_3           |  // 0x30
35
                     SDRAM_MODEREG_OPERATING_MODE_STANDARD |  // 0
36
                     SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;    // 0x200
37
     
38
  Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
39
  Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
40
  Command.AutoRefreshNumber = 1;
41
  Command.ModeRegisterDefinition = tmpmrd;
42
  HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
43
     
44
  /* Step 8: Set the refresh rate counter: (64 ms / 8192 x Freq) - 20 */
45
  hsdram1.Instance->SDRTR |= ((uint32_t)761);  // 2HCLK, Insignis SDRAM
46
}

Wie gesagt, auf dem gleichen Board läuft ein SDRAM von Micron ohne 
Probleme, so dass ich Fehler im Layout eigentlich ausschließen möchte. 
Außerdem habe ich zwei Boards gelötet, was Lötfehler vermeiden sollte.

Aber welchen Fehler habe ich bei der Konfiguration gemacht? Wie könnte 
ich das Problem weiter einkreisen?

von lars (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Da ich nicht so recht weiß, wie man mit Timings für ein 200 MHz-IC 
umgeht, das nur mit 100 MHz betrieben wird, habe ich mal testweise alle 
Timings x2 gerechnet.

In CubeMX musste ich allerdings den Wert für Write recovery time von 2 
auf 5 Zyklen erhöhen, da sonst die internen logischen Bedingungen nicht 
mehr gelten.

Leider funktioniert es auch damit nicht; das Lesen an Adresse 0xc0000000 
liefert immer noch 0x3ffe statt 0 zurück.

Ich würde ja einen anderen Hersteller versuchen, aber ich sehe keinen 
wirklichen Unterschied in den Datenblättern.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.