Forum: Mikrocontroller und Digitale Elektronik STM32H745 I2S DMA (NUCLEO-STM32H745ZI-Q DualCore)


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von Torsten S. (torsten_s801)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe ein Projekt im Rahmen einer Weiterbildung, wo ich an meine 
Grenzen stoße und hoffe hier ein paar Lösungsansätze/Tips zu erhalten.

Worum geht es:

-STM32H745 DualCore

-CPU1 (Cortex-M7) erstmal nur so mitlaufen, später sollen hier FFT 
Berechnungen erfolgen

-CPU2 (Cortex-M4) 1xI2S mit DMA (RxTx Circular) hier wird extern ein 
A/D,D/A Wandler angeschlossen (Audio Abtastrate 48kHz, 16Bit)

Grundsätzlich hat das Projekt schonmal auf einem STM32F429 Single-Core 
funktioniert...

Was ist mir aufgefallen:

-Im Handler hi2s1 findet keine Aktualisierung statt (keine neuen Daten)

-Ich komme nicht in die ISR (weder TxRxHalfCpltCallback noch 
TxRxCpltCallback)

-I2S Takt usw. scheint zu funktionieren (mit Skope gemessen)

-Daten "txBuf" liegen im Bereich ab 0x10002050 (alles 0)

-Daten "rxBuf" liegen im Bereich ab 0x10000050 (alles 0)


Ich wäre also froh, wenn ich über den DMA Daten erhalte würde und in die 
ISR HalfCplt und Cplt käme, dann könnte ich weitermachen :-)

Im Zuge von Dual-Core merke ich , dass ich Defzite im Bereich Flash,RAM 
usw. habe.
Bei einem anderen Beispiel direkt von ST 
(..\STM32Cube_FW_H7_V1.8.0\Projects\NUCLEO-H745ZI-Q\Examples\SPI\SPI_Ful 
lDuplex_ComDMA)  ist mir schon aufgefallen, dass im Linker-Skript für 
den M7 ein andrer RAM Bereich angegeben ist, als durch die STM32CubeIDE
angelegt worden ist; hierzu gibt es auch schon ein Errata von ST. Nach 
Anpassung des RAM Bereichs lief dieses.

Ich bin für jede Hilfe dankbar,
beste Grüße
Torsten

PS.: Gerne stelle ich komplettes Projekt zur Verfügung, einfach Bescheid 
geben auch wenn Code Schnipsel zur Klärung erforderlich sind.

PPS.: Entschuldigt meine Formatierung...ist mein erster Post ;-)

von Kevin M. (arduinolover)


Lesenswert?

Torsten S. schrieb:
> -Daten "txBuf" liegen im Bereich ab 0x10002050 (alles 0)
>
> -Daten "rxBuf" liegen im Bereich ab 0x10000050 (alles 0)

Die Speicheradresse klingt nach einem Remap für den M7 da hat der M4 und 
eventuell der DMA keinen Zugriff drauf. Der RAM beginnt bei dem M4 idr. 
ab 0x3.......

Was auch gerne passiert ist das die Variablen im DTCM RAM liegen da 
haben die normalen DMA keinen Zugriff. Schau am besten mal ins Reference 
Manual, da gibt es eine Memory Map und eine Bus Matrix.

von Torsten S. (torsten_s801)


Angehängte Dateien:

Lesenswert?

Danke für die schnelle Antwort.
Die Vermutung hatte ich auch schon mit dem Mapping, habe mal Auszug vom 
RM beigefügt. Demnach sollte das passen...
Aber ich weiß nicht so genau wie sich der DMA hierzu verhält.

Mit DTCM RAM müsste ich mal schauen, wie bekäme ich das raus?
Besten Dank

von Kevin M. (arduinolover)


Lesenswert?

Dann würde ich dem DMA einfach mal einen Adressoffset mitgeben, sodass 
der Zeiger auf 0x30002050 und 0x30000050 zeigt. Ist schon länger her 
aber ich meine das der DMA mit am AHB Bus in D2 hängt und nicht am AXI 
wie der M7 in D1, daher kann der DMA mit der Adresse 0x1... nix 
anfangen.

Der DTCM startet wohl bei 0x2..... und fällt somit raus.

von Rainer B. (katastrophenheinz)


Lesenswert?

Na, da hast du dir mit dual core ja gleich eine der komplizierteren MCU 
ausgesucht. Falls du Zugriff auf ein SingleCore-Brett hast, nimm auf 
jeden fall erst einmal das.

Bist du sicher, dass der CM4 losrennt? Vom Code her sieht es so aus, 
dass er sofort schlafen geht und auf ein Aufwecken ( via HSEM ) vom CM7 
wartet. Dazu fehlt dann der entsprechende CM7-Code und der 
HSEM-IRQ-Handler  für den CM4. Verifizier das Loslaufen des CM4 mal mit 
Debugger oder LED ein- ausschalten.

Ausserdem würde ich wg DMA, wie Kevin bereits schrieb, den originalen 
RAM Addressbereich des CM4 und nicht den Remap-Addressbereich verwenden 
(durch Abändern im ld-file für den CM4)

von Torsten S. (torsten_s801)


Lesenswert?

Hi,
und vielen Dank für die Rückmeldung.
Grundsätzlich lief schon alles auf einem STM32F429-disc1 Board.
Jetzt wollte ich alles (als nächsten Schritt) auf einen Dual-Core 
portieren, aber erstmal im Core M4 belassen. Wie Du richtig feststellst, 
ist das für mich eine riesen Herausforderung...

Der CM4 rennt los. In der while-Schleife habe ich HW-Breakpoint gesetzt 
bei:

-HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);

-if (callback_state != 0) {

...der hält auch an den Stellen an.

Hinweis: Der Code, den ich angehangen habe, ist nur der vom CM4...in CM7 
befindet sich nur die Init für den Systemclock, mehr nicht.

Die Linker-Skripts habe ich beide oben angehangen. Ich habe aber auch 
mal (wie Kevin schrieb) die Adressbereiche angepasst.
Zuletzt CM7:
MEMORY
{
FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
RAM (xrw)      : ORIGIN = 0x24000000, LENGTH = 128K
ITCMRAM (xrw)      : ORIGIN = 0x00000000, LENGTH = 64K
}

Zuletzt CM4:
MEMORY
{
FLASH (rx)      : ORIGIN = 0x08100000, LENGTH = 1024K
RAM (xrw)      : ORIGIN = 0x30000000, LENGTH = 256K
}

Gestern Abend ist mir aufgefallen, dass sich die Register des I2S (SPI1) 
nicht ändern. Also auch nicht SR(Status Reg) und DR(Data Reg)...
Heißt das, dass der I2S überhaupt nicht läuft?
Viele Grüße,Torsten

von Torsten S. (torsten_s801)


Lesenswert?

...obwohl ich mit Oszilloskop alle Clocks messen konnte

von Rainer B. (katastrophenheinz)


Lesenswert?

Torsten S. schrieb:
> Gestern Abend ist mir aufgefallen, dass sich die Register des I2S (SPI1)
> nicht ändern. Also auch nicht SR(Status Reg) und DR(Data Reg)...

Das deutet darauf hin, dass die Komponente SPI1 nicht getaktet wird. Das 
Einschalten der SPI1-Clock erfolgt in "HAL_I2S_MspInit". Diese Fn wird 
aufgerufen? Da du die SPI1-Clocksource nicht explizit setzt, ist das 
PLL1Q als default. So gewollt?

Ansonsten: Was macht der CM7 derweil? Rennt der weiterhin oder ist der 
in Sleep oder Stop-Mode? Poste doch mal das gesamte Projekt, also auch 
den CM7-Code.

> obwohl ich mit Oszilloskop alle Clocks messen konnte
Welche?

von Torsten S. (torsten_s801)


Angehängte Dateien:

Lesenswert?

Rainer B. schrieb:
> aufgerufen? Da du die SPI1-Clocksource nicht explizit setzt, ist das
> PLL1Q als default. So gewollt?

Habe mit CubeMX die Clockkonfig gemacht (Screenshot im Anhang). Demnach 
sollte das ok sein... Funktioniert auch in meinem Referenzprojekt 
STM32H745 mit 2xSPI und 2x DMA (von ST Cube Examples)

> Ansonsten: Was macht der CM7 derweil? Rennt der weiterhin oder ist der
> in Sleep oder Stop-Mode? Poste doch mal das gesamte Projekt, also auch
> den CM7-Code.

Der CM7 läuft weiter, soll er auch. In einer weiteren Ausbaustufe sollen 
Berechnungen (Filter, FFT o.ä.) dahin ausgelagert werden.

>> obwohl ich mit Oszilloskop alle Clocks messen konnte
> Welche?

MCLK ca.12,2MHz
WS ca.47kHz
SCK ca. 3MHz

UPDATE:
Im beigefügten Projekt habe ich ein wenig aufgeräumt. Der FIR Filter 
soll herkömmlich arbeiten (ohne CMSIS math). Macht das auch ein wenig 
übersichtlicher. Zudem habe ich Initialisierung in die main.c (gemäß 
Referenzprojekt 2xSPI,2xDMA) gepackt.
Im DMA1 Stream 0/1 ändern sich jetzt Register im Debugging.
Auszug main.c:

...

HAL_I2SEx_TransmitReceive_DMA (&hi2s1, txBuf, rxBuf, 4);

  while (1)

  {
    HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
  }

Meine Led LD1 toggelt nicht mehr, ich bleibe im HAL-DMA_IRQHandler 
(stm32h7xx_hal_dma.c) hängen...
Ich denke das ist aber ein kleiner Fortschritt?

Viele Grüße, Torsten.

von Rainer B. (katastrophenheinz)


Lesenswert?

>ich bleibe im HAL-DMA_IRQHandler (stm32h7xx_hal_dma.c) hängen...

Du hast zwei Instanzen von
1
DMA_HandleTypeDef hdma_spi1_tx;
2
DMA_HandleTypeDef hdma_spi1_rx;

Einmal in main.c und dann als static in ...hal_msp.c. Initialisiert 
werden letztere, verwendet dann erstere. Das geht schief.

Ändere die Deklarationen in ..hal_msp.c ab in
1
extern DMA_HandleTypeDef hdma_spi1_tx;
2
extern DMA_HandleTypeDef hdma_spi1_rx;
Dann gibt's nur noch eine Instanz von denen.

Und zum LED-Toggle in der main-loop würde ich zumindest noch ein delay 
von ca 100ms spendieren, sonst siehst du das Blinken nicht.

: Bearbeitet durch User
von Torsten S. (torsten_s801)


Lesenswert?

Rainer B. schrieb:
>>ich bleibe im HAL-DMA_IRQHandler (stm32h7xx_hal_dma.c) hängen...
> Ändere die Deklarationen in ..hal_msp.c ab in
>
1
> extern DMA_HandleTypeDef hdma_spi1_tx;
2
> extern DMA_HandleTypeDef hdma_spi1_rx;
3
>
> Dann gibt's nur noch eine Instanz von denen.
>
> Und zum LED-Toggle in der main-loop würde ich zumindest noch ein delay
> von ca 100ms spendieren, sonst siehst du das Blinken nicht.

Ohhh...da hast du natürlich Recht.
Habe ich abgeändert und jetzt komme ich auch in die beiden Callbacks 
"HAL_I2SEx_TxRxCpltCallback" und "HAL_I2SEx_TxRxHalfCpltCallback" :-)

Jetzt muss ich nur noch schauen, woran das fehlende Toggeln der LED 
liegt (habe Delay von 100ms eingebaut)...
Und: Alle Daten habe "0" als Wert (rxBuf, txBuf, ...). Ich begebe mich 
weiter auf die Suche.

Vielen Dank Rainer für den Support.

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.