mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 SPI1 und DMA (für Rx und Tx)


Autor: el84 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich beschäftige mich jetzt schon eine gute Weile mit SPI/DMA auf dem 
STM32 und komme einfach nicht weiter. Die Initialisierung erledige ich 
wie in diesem Beitrag:

http://www.st.com/mcu/forums-cat-8238-23.html

allergings läuft Frameworkbedingt die SPI-Initialisierung vor der 
DMA-Initialisierung ab, sprich: SPI wird auch vor der 
DMA-Initialisierung auf enabled gesetzt. (Ist das problematisch?) Mein 
momentaner Code crasht immer ein paar Befehle nachdem ich DMA auf 
enabled gesetzt habe.

Die Initialisierten Werte finde ich auch so im Speicher wieder, soweit 
sollte das korrekt sein

(Abweichende Werte zum Link:

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) pReadBuffer;
DMA_InitStructure.DMA_BufferSize = wByteCount;

wobei pReadBuffer bzw. pWriteBuffer ein (Byte-)Pointer auf einen vorher 
schon existierenden Puffer ist und wByteCount dessen Anzahl an Bytes 
enthält).

Es funktioniert weder mit noch ohne initialisierte Interrupts (und 
DMA_IT_TC, ENABLE).

Leider habe ich keine Application Note zu SPI/DMA gefunden. In der 
AN2548 wird zwar in der Beschreibung erwähnt, dass für SPI1_RX DMA1 Ch2 
verwendet wird, im Code wurde das aber offensichtlich vergessen und nur 
der ADC mit DMA implementiert.

Hat eventuell jemand einen funktionierenden Codeausschnitt oder kann mir 
Tipps zur Fehlersuche geben? Ich kann auch gerne weiteren Code posten, 
allerdings ist meiner weitestgehend gleich dem im obigen Link.

Ich bin für jeden Tipp dankbar, da mich das Problem jetzt schon ein paar 
Tage aufhält.

Vielen Dank!

Autor: A. K. (prx)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Mein Testcode für SPI via DMA. Compilierbar ist er so nicht, weil etwas 
eigener Kram für Bitbanding und GPIO Konfiguration fehlt, ebenso ein 
paar Bezeichner für die I/O, aber vielleicht hilft es für's Prinzip.

Autor: Martin Thomas (mthomas) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
el84 schrieb:
>...
> Hat eventuell jemand einen funktionierenden Codeausschnitt...
>...

http://www.siwawi.arubi.uni-kl.de/avr_projects/arm...
--> [Download]
--> sd_spi_stm32.c

Autor: el84 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die Codebeispiele. Ich habe inzwischen den Code im 
Anhang daraus gebaut. Dieser ersetzt die vorher vorhandene 
Sende/Empfang-Funktion für SPI ohne DMA (das heißt: auch die 
SPI-Initialisierung steht wo anders). Momentan verwende ich nur SPI1. 
Ich sende erst den gesamten Tx-Puffer mit DMA, dann lese ich den 
gesamten Rx-Puffer mit DMA. Kann man das so machen oder habe ich da 
einen fatalen Denkfehler?

Leider bringt es auch noch nicht das erwartete Ergebnis, beim Lesen 
steht der Puffer voll mit FF. Außerdem crasht mein Projekt nach wie vor, 
aber da vermute ich Timing-Probleme. Im Single-Step-Betrieb per JTAG 
läuft es wenigstens problemlos durch.

Es wäre schön, wenn mir jemand einen Hinweis geben könnte, dass 
wenigstens mein angehängter DMA-Code läuft. Der andere Fehler ist 
vermutlich Projektbedingt und erstmal zweitrangig.

Autor: embedded-os (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schau Dir mal meinen Demo-Code zu SD-Karten unter SPI auf verschiedenen 
MCUs an (auch STM32).

http://www.embedded-os.de/index.html?pcfat_port.htm

Autor: el84 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, danke für die Antworten. Wollte mich nur mal zurückmelden und sagen, 
dass es inzwischen funktioniert. Da in meiner Routine wie gesagt 
gleichzeitig gelesen und geschrieben wird, konnte ich die 
Initialisierung noch kompakter gestalten:

    /* DMA configuration SPIx RX ------------------------*/
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)pReadBuffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_Init(DMA_Channel_SPIx_RX, &DMA_InitStructure);

    /* DMA configuration SPIx TX ------------------------*/
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)pWriteBuffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_Init(DMA_Channel_SPIx_TX, &DMA_InitStructure);

Danach werden die DMA-Kanäle enabled, SPI TX/RX request enabled, 
gewartet, bis die Übertragung abgeschlossen ist, die DMA-Kanäle wieder 
disabled und  SPI TX/RX request disabled. Wie im obigen Code auch. Das 
wars.

Mein Problem war ein ganz anderes und deswegen schreibe ich das jetzt 
hier auch nochmal so deutlich, da sicher etliche noch das selbe Problem 
haben werden:

!!!DER PUFFER ZUM LESEN UND SCHREIBEN _MUSS_ IM INTERNEN SRAM 
LIEGEN!!!

In meinem Fall also SPITxBuffer und SPIRxBuffer. Es funktioniert nicht, 
wenn er im externen RAM allokiert ist. Deswegen crashte mein Projekt 
regelmäßig, deswegen funktionierte nichts. Ich hoffe, dass das hiermit 
ausreichend für die Nachwelt festgehalten ist. ;)

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.