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
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.
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
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
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!