SPI Ethernet und Interrupts auf einem Bus möglich?

Hallo und guten Abend,
ich stehe hier gerade etwas auf dem Schlauch und hoffe ihr könnt mir helfen.

Habe einen RP2040 mit W5500 Ethernet Modul an SPI0 angeschlossen. /CS auf GPIO6. Funktioniert wunderbar. Jetzt möchte ich 3 Drehgeber mittels eines MCP23S17 an den SPI0 Bus, /CS auf GPIO7 anschließen. Der MCP löst bei Level Änderung eines Portpins einen Interrupt aus. In der Interrupt Service Routine wird dann per SPI der Inhalt aller Portpins gelesen, und verarbeitet.

Wie kann ich verhindern, das während einer Übertragung zum Ethernet Modul oder zu/von anderer SPI Hardware der Interrupt der Drehgeber auf die SPI Schnittstelle zugreift? Zu dieser Zeit wäre ja die CS - Leitung der Ethernet Verbindung ggf. aktiv. Ein warten auf das beenden der gerade aktiven Übertragung würde mir noch nicht die gerade aktive CS Leitung deaktivieren.

Wollte vermeiden, vor dem Aufruf der Ethernet Routinen generell alle Interrupts zu sperren. Auch möchte ich nicht in die Ethernet Routinen selbst eingreifen müssen, da die bei weitem mein Verständnis übersteigen :wink:

Alternativ müsste ich noch irgendwie Leitungen frei machen, um die Drehgeber auf die SPI1 Schnittstelle umzubiegen. Wollte das aber wenn irgendwie möglich verhindern.

Gibt es hierfür eine Elegante Lösung?

Viele Grüße,
Horst

Gar nicht.
Deaktiviere den Interrupt, der die ISR für die MCP bedient, solange der Ethernetzugriff erfolgt.

Eigentlich sollte das aber auch ganz gechillt ohne Probleme parallel laufen ohne sich da Sorgen machen zu müssen.

Lass das Verarbeiten aus der ISR raus und lies nur die Ports in eine Variable. Auf die kannst Du dann im loop atomar in Ruhe zugreifen.

Gruß Tommy

Erstmal vielen Dank für die Antorten!

Das habe ich befürchtet. Einzige Möglichkeit, ist dann nicht in den Ethernet Routinen, sondern vor / nach dem gesamten Aufruf. Da werden auch u.a. eine kleine Webseite für Status Meldungen übertragen und im Sekundentakt eine Verbindung mit einem weiteren RP2040. Da gehen dann Schritte verloren.

Um die Ports zu lesen, benötige ich Zugriff auf die SPI Schnittstelle. Wird hier während des Interrupts gerade etwas übertragen, kommt es zur Kollision.

Bin jetzt gerade dabei, irgendwie die 2. SPI Schnittstelle frei zu machen. Dafür muss diese dann ohne /CS auskommen.

Dafür habe ich jetzt keine "Notfall" I²C mehr übrig - ist eh lahm :wink:

Viele Grüße,
Horst

imho sollte in einer ISR keine SPI Kommunikation stattfinden.

Dann setze in der ISR ein Flag, dass sich etwas geändert hat und lese den MCP im loop aus.

Gruß Tommy

Da der µC 2 Kerne hat, kann man doch sowas wie SoftSPI auf den 2ten Kern verlagern und schon läufts voll parallel, ohne sich auf irgendeinem Bus ins Gehege zu kommen.

Darum.mach Dir keine Sorgen. In 1 Sekunde passiert mehr, als Du denkst :grinning:
Der intPin des MCP bleibt solange aktiv, bis Du den ausliest.
Ich würde auf eine ISR verzichten und bei jedem Umlauf schaun ob da was ansteht und drauf reagieren.

Das ist die Lösung! Den 2. Kern hatte ich zwar im Hinterkopf, jedoch als Arduino-Umsteiger und der Geschwindigkeitssteigerung noch gar nicht für solch einen Zweck in Betracht gezogen. Ich werde erstmal versuchen, bei anliegen des INT Signals durch den MCP die CS Leitungen der restlichen Teilnehmer zu überwachen. Sind alle Leitungen inaktiv, wird der erste CPU-Kern kurz angehalten, das benötigte Byte per SPI eingelesen und weiter geht es.

Sollte das nicht sauber funktionieren, kann ich immer noch alles um verdrahten und die 2. SPI Schnittstelle hierzu verwenden.

Habt vielen Dank für eure Antworten! Sie haben mir sehr weiter geholfen!

Viele Grüße,
Horst

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.