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!
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.
el84 schrieb: >... > Hat eventuell jemand einen funktionierenden Codeausschnitt... >... http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html#stm32_memcard --> [Download] --> sd_spi_stm32.c
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.
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
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. ;)
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.