mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32F7 und SDRAM


Autor: A. F. (elagil)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe Probleme bei der Nutzung von SDRAM mit dem STM32F7.

Es handelt sich um ein selbst entworfenes Board mit 256Mbit SDRAM von 
ISSI:

IS42S16160J
http://www.issi.com/WW/pdf/42-45S83200J-16160J.pdf

Das ist SDRAM mit 13 bit Adressen und 16 bit Daten.

Die Initialisierungsvorschriften für den SDRAM habe ich mit dem CubeMX 
Programm erzeugt. Die Initialisierung verläuft ohne Fehlermeldungen 
(returns).

Ich kann Daten auf den Speicher schreiben und lesen, allerdings nur bis 
zu einer bestimmten Adresse:
  uint32_t adr = 0xC0000000;
  volatile uint32_t a[32];

  for(uint32_t k=0; k<16; k++) {
    *(uint32_t *)(adr + 4 * k) = k;
    a[k] = *(uint32_t *)(adr + 4 * k);
  }

Für k bis 16 funktioniert schreiben und lesen ohne Probleme. Dann stehen 
in a[k] am Ende die Werte von 0 bis 15. Wenn ich k größer werden lasse 
als 16, friert der debugger ein (Blackmagic Probe GDB Server).

Woran kann das liegen? Ich tippe auf ein Hardwareproblem, weiß aber 
nicht wo ich suchen soll.

Vielen Dank im Voraus

Autor: A. B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lässt sich das RAM ohne BusError komplett auslesen (unabhängig ob der 
Inhalt wirklich ausgelesen wird, oder einfach Schrott zurückkommt)?

Das RAM ist doch mehr oder minder passiv, selbst wenn es komplett falsch 
angesteuert würde, könnte es doch schlimmstenfalls Unsinn zurückliefern, 
wenn man von einer Kollision infolge falscher Ansteuerung von WE mal 
absieht? Es hat doch keinerlei Ausgang, über den ein Fehler signalisiert 
oder ein Buszyklus verzögert werden kann.

Das "Einfrieren" muss dann doch auf Controller-Seite seinen alleinigen 
Ursprung haben. Da hilft wohl nur, per Hand alle FMC-Register zu 
kontrollieren.

Dass von der Initialisierungsroutine kein Fehler zurückkommt, heisst 
nichts, es können da unmöglich alle mit der tatsächlichen Hardware nicht 
möglichen Parameterkonfigurationen abgefangen werden.

Vielleicht auch mal ST-Link oder J-Link ausprobieren, vielleicht ist's 
ja auch der Debug-Adapter? Oder GDB?

Stack oder Heap landen nicht zufällig im SDRAM? Das wär' ja fatal.

Wenn das alles nicht hilft, bleibt wohl nur LA oder Scope und erst 
einmal nur Lese- oder nur Schreibzugriffe, am besten in Assembler in 
'ner Endlos-Scheife, am besten durch den gesamten Adressraum der SDRAMs. 
Ob das, was man reinschreibt, auch an richtiger Stelle wieder 
herauskommt, käme dann VIEL später.

Autor: drm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Die Initialisierungsvorschriften für den SDRAM habe
>ich mit dem CubeMX Programm erzeugt.

Dann hast du den SDRAM Controller in der CPU konfiguriert.
Wie sieht es mit dem SDRAM Controller im SDRAM aus ?
Die Einstellungen müssen zu den Einstellungen in CubeMX passen.

Vielleicht schreibst du nur in den Cache der CPU, und so bald er das 
SDRAM
ansprechen will gibt es einen HardFault, weil das SDRAM gar nicht läuft, 
sondern nur der SDRAM Controller in der CPU.

Autor: A. F. (elagil)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Hinweise!

Zuerst einmal: Ich teste jetzt mit dem ST-Link V2 und Eclipse (System 
Workbench).

A. B. schrieb:
> Lässt sich das RAM ohne BusError komplett auslesen (unabhängig ob der
> Inhalt wirklich ausgelesen wird, oder einfach Schrott zurückkommt)?

Nein, ich kann scheinbar gar nicht mehr lesen. Wenn ich einen 
Lesezugriff durchführe (diesmal mit HAL_SDRAM_Read_32b(...)), dann 
endete diese Zeile:
*pDstBuffer = *(__IO uint32_t *)pSdramAddress;

im "Infinite_Loop" des startup-files. pSdramAddress zeigt hier auf 
0xc0000000.
Default_Handler:
Infinite_Loop:
  b  Infinite_Loop
  .size  Default_Handler, .-Default_Handler

Was bedeutet das?

A. B. schrieb:
> Das "Einfrieren" muss dann doch auf Controller-Seite seinen alleinigen
> Ursprung haben. Da hilft wohl nur, per Hand alle FMC-Register zu
> kontrollieren.

Ja, sieht so aus. Die Konfigurationsregister vom FMC sind zumindest so, 
wie ich es gerne hätte. Anbei ein paar Screenshots.

A. B. schrieb:
> Stack oder Heap landen nicht zufällig im SDRAM? Das wär' ja fatal.

Ich denke, die liegen im RAM. Hier alle Definitionen aus dem 
Linker-file, die mit stack/heap zu tun haben.
/* Highest address of the user mode stack */
_estack = 0x20050000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */
...
MEMORY
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 1024K
}
...
/* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM

drm schrieb:
> Dann hast du den SDRAM Controller in der CPU konfiguriert.
> Wie sieht es mit dem SDRAM Controller im SDRAM aus ?

Wie ist das gemeint?

Es gibt einen Aufruf
HAL_SDRAM_Init(&hsdram1, &SdramTiming)

im Quelltext, der den FMC mit den gewünschten Timings initialisiert.
/**
  * @brief  Performs the SDRAM device initialization sequence.
  * @param  hsdram: pointer to a SDRAM_HandleTypeDef structure that contains
  *                the configuration information for SDRAM module.
  * @param  Timing: Pointer to SDRAM control timing structure 
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SDRAM_Init(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_TimingTypeDef *Timing)
{   
  /* Check the SDRAM handle parameter */
  if(hsdram == NULL)
  {
    return HAL_ERROR;
  }
  
  if(hsdram->State == HAL_SDRAM_STATE_RESET)
  {  
    /* Allocate lock resource and initialize it */
    hsdram->Lock = HAL_UNLOCKED;
    /* Initialize the low level hardware (MSP) */
    HAL_SDRAM_MspInit(hsdram);
  }
  
  /* Initialize the SDRAM controller state */
  hsdram->State = HAL_SDRAM_STATE_BUSY;
  
  /* Initialize SDRAM control Interface */
  FMC_SDRAM_Init(hsdram->Instance, &(hsdram->Init));
  
  /* Initialize SDRAM timing Interface */
  FMC_SDRAM_Timing_Init(hsdram->Instance, Timing, hsdram->Init.SDBank); 
  
  /* Update the SDRAM controller state */
  hsdram->State = HAL_SDRAM_STATE_READY;
  
  return HAL_OK;
}

Autor: tzhgfhgrhzfghz6453454353453534534533453453 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nutzt du den I und D Cache?
bitte den mal weglassen am anfang

oder mach ein __DMB(); nach der Anweisung rein

der cache ist gut, versaut aber bei solchen sachen das timing ...

Autor: A. B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Adrian F. schrieb:
>
> *pDstBuffer = *(__IO uint32_t *)pSdramAddress;
> 
>
> im "Infinite_Loop" des startup-files. pSdramAddress zeigt hier auf
> 0xc0000000.
>
>
> Default_Handler:
> Infinite_Loop:
>   b  Infinite_Loop
>   .size  Default_Handler, .-Default_Handler
> 
>

Ist wohl einer der Exception-Vektoren, der nicht (sinnvoll) belegt ist 
und deshalb auf diese Endlos-Schleife zeigt. Da wäre wichtig zu wissen, 
welche Exception das war (HardFault, Interrupt, ...). Der erste Zugriff 
aufs RAM triggert also gleich irgendwas?!

Was steht im RCC_AHB3ENR (Clock für FMC) und im RCC_AHB3RSTR (Reset für 
FMC)? Die sollten zwar bei der Initialisierung automatisch ein- bzw. 
ausgeschaltet werden, aber ...

Außerdem: Tut sich überhaupt irgendwas am RAM (CLK, CKE, DQML, DQMH)?

Autor: A. F. (elagil)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tzhgfhgrhzfghz6453454353453534534533453453 schrieb:
> nutzt du den I und D Cache?
> bitte den mal weglassen am anfang
>
> oder mach ein __DMB(); nach der Anweisung rein
>
> der cache ist gut, versaut aber bei solchen sachen das timing ...

I und D Cache benutze ich nicht.

Neuigkeiten:
Ich habe den RAM zum Laufen gebracht. Lesen und schreiben von zufälligen 
32 bit Werten geht. Im Moment habe ich aber nur getestet, 4096 Werte an 
den Speicheradressen (Offsets) 0x800 und 0x10000 zu lesen/schreiben.

Allerdings benutze ich dafür im Moment nicht den Code, den CubeMX 
generiert, sondern das Beispiel von ST für das Discovery 746 board. 
Wichtig war die Anpassung der Timings, bis keine Fehler mehr aufgetreten 
sind. Die Werte im Datenblatt haben teilweise abweichende Namen von 
denen, die der STM32 erwartet.

Falls jemand den gleichen RAM benutzt, diese Timings funktionieren bei 
CL=2 und 100 MHz.
  SDRAM_Timing.LoadToActiveDelay    = 3;
  SDRAM_Timing.ExitSelfRefreshDelay = 7;
  SDRAM_Timing.SelfRefreshTime      = 4;
  SDRAM_Timing.RowCycleDelay        = 8;
  SDRAM_Timing.WriteRecoveryTime    = 2;
  SDRAM_Timing.RPDelay              = 2;
  SDRAM_Timing.RCDDelay             = 2;

Jetzt versuche ich noch, das mit der CubeMX Vorlage lauffähig zu 
bekommen.

A. B. schrieb:
> Was steht im RCC_AHB3ENR (Clock für FMC) und im RCC_AHB3RSTR (Reset für
> FMC)? Die sollten zwar bei der Initialisierung automatisch ein- bzw.
> ausgeschaltet werden, aber ...
>
> Außerdem: Tut sich überhaupt irgendwas am RAM (CLK, CKE, DQML, DQMH)?

Das prüfe ich gleich.

: Bearbeitet durch User
Autor: dasrotemopped (Gast)
Datum:
Angehängte Dateien:

Bewertung
1 lesenswert
nicht lesenswert
>> Wie sieht es mit dem SDRAM Controller im SDRAM aus ?
>Wie ist das gemeint?
>Es gibt einen Aufruf
>HAL_SDRAM_Init(&hsdram1, &SdramTiming)
das ist die Initialisierung des SDRAM COntrollers im STM32F7

In den Board Support Packages wird beides gemacht, uC und SDRAM 
Initialisierung. CubeMX macht nur die Initialisierung des STM32.
Ich habe mal den zusätzlichen Code aus dem BSP in eine eigene Funktion 
extrahiert, so das die CubeMX HAL_SDRAM_Init() und meine Funktionen 
zusammen wieder die Funktion des BSP haben. Hier das Beispiel zu dem 
STM32F746G-Disco. Im Code sind hoffentlich genug Kommentare als 
Erläuterung. Da du aber anderes SDRAM als auf dem Disco Board benutzt, 
musst du wahrscheinlich ein paar Werte ändern.

Gruß,
dasrotemopped.

Autor: A. F. (elagil)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die Mühe! Das funktioniert ausgezeichnet.

dasrotemopped schrieb:
> In den Board Support Packages wird beides gemacht, uC und SDRAM
> Initialisierung.

Jetzt habe ich es begriffen.

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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