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