Forum: Mikrocontroller und Digitale Elektronik STM32L471 SPI3 mit DMA per HAL resetten (Byte Shift)


von Volker K. (vokuit00)


Lesenswert?

Hallo,

ich habe ein System mit einem bestimmten PIC-Controller, die Software 
auf diesem PIC ist nicht veränderbar, da sie zusammen mit anderen 
Systemen verwendet wird. Der PIC ist der SPI-Master und hat eine CS-, 
MOSI- und MISO-Verbindung zu einem STM32L471.

Als erste Information: Ich bin nur ein Hobby-Programmierer, der einem 
alten Kollegen hilft. Also benutze ich die STM32 HAL und habe keine 
Zeit, den Umgang mit einer SPI mit DMA via Registerzugriffen zu lernen. 
Ich weiß, dass die Verwendung der Register mir die volle Kontrolle geben 
würde, aber das würde im Moment einfach zu viel Zeit kosten.

Der STM32 ist der SPI-Slave (SPI3), der via CS getriggert wird (Active 
Low) und verwendet die DMA2-Kanäle 1 und 2 für SPI3_RX und SPI3_TX. Das 
CS liegt auf PC10 als SPI_SCK. Der NSS-Signaltyp wird in der Einstellung 
"Software" verwendet, da ich mit der Einstellung "Hardware NSS" nie eine 
korrekte Kommunikation zum laufen bekam.

Der Kommunikationszyklus vom PIC beginnt alle 6 ms und dauert 3 ms. Er 
beginnt mit einer fallenden Flanke auf CS und endet mit einer steigenden 
Flanke auf CS. Ich verwende einen IRQ auf die steigenden Flanke parallel 
zum HAL_SPI_TxRxCpltCallback(). Die übertragenen Daten haben eine 
Startsequenz und eine CRC am Ende, so dass ich überprüfen kann, ob die 
empfangenen Daten korrekt waren oder nicht, gleiches auf der PIC-Seite.

Ohne jegliche Störung funktioniert alles einwandfrei. 2017 habe ich mal 
ein paar Störungen getestet (SPI Kabel ausstecken/prellen etc.) und 
nachdem es danach auch Probleme mit geshifteten Bytes gab, dann 
Folgendes implementiert:

Wenn die Datenprüfung in HAL_SPI_TxRxCpltCallback() einen Fehler erkannt 
hat, dann wird "versucht" die SPI-Kommunikation im IRQ der steigenden 
CS-Flanke so zurückzusetzen:


HAL_SPI_Abort_IT(&hspi3);
HAL_SPI_Abort(&hspi3);
HAL_SPI_AbortCpltCallback(&hspi3);
HAL_SPIEx_FlushRxFifo(&hspi3);
HAL_SPI_DeInit(&hspi3);
MX_SPI3_Init();

Wie man sieht, habe ich einfach alles was mir eingefallen ist, 
abgebrochen oder resettet. Aber es scheint nicht generell zu helfen.

Denn diese Woche ruft mich mein Kollege mit neuen Problemen an. Manchmal 
scheint die SPI zu "hängen" und er hat einen Weg gefunden, die Störung 
Nachzustellen (Kurzschluss MOSI nach GND für kurze Zeit, dann den KS 
wieder entfernen). Ich habe heute versucht den Fehler einzugrenzen und 
festgestellt, dass nach dem Entfernen des Kurzschlusses die Funktionen 
oben korrekt aufgerufen werden, aber die Daten ab da im empfangenen 
Array um ein paar Bytes verschoben sind. Da ab hier in jedem 
Kommunikationszyklus die Startsequenz/CRC nicht mehr stimmt (weil 
verschoben), wird das am Ende jedes Kommunikationszyklusses wiederholt.

Im Jahr 2017 erhielt ich den Hinweis, dass 
HAL_SPIEx_FlushRxFifo(&hspi3); dieses Verhalten lösen sollte. Aber es 
scheint nicht zu funktionieren.

Ich habe keine Ahnung, wie man den SPI mit HAL-Möglichkeiten (SPI, FIFO 
und eventuell DMA) richtig "zurücksetzen" kann.

Hat jemand das Wissen über die richtigen HAL-Funktionen oder kann mir 
einen Code-Ausschnitt mit einem registerbasierten Reset geben, den ich 
in Kombination mit der HAL-Funktionalität verwenden kann?

Das wäre super.

Vielen Dank

Volker

von pegel (Gast)


Lesenswert?

Ich bin mir nicht zu 100% sicher, würde aber behaupten, dass:
1
__HAL_SPI_RESET_HANDLE_STATE(&hspix);

diese Aufgabe erfüllt, da jede HAL Funktion die irgend etwas mit dem SPI 
zu tun hat, zuerst:
1
if(hspi->State == HAL_SPI_STATE_READY) ...

abfragt.
Es muss also eine Funktion vorher wieder Ordnung schaffen und 
HAL_SPI_STATE_READY setzen.

von pegel (Gast)


Lesenswert?

Für DMA wird es ähnlich sein:
1
__HAL_DMA_RESET_HANDLE_STATE(&hdmax);

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.