SPI zwischen MCUs

Als Neuling in der PIC-Programmierung suche ich nach einigen Gedanken, wie SPI zwischen einer Master- und Slave-MCU am effizientesten implementiert werden kann.

Der Zweck dieses Systems besteht darin, mithilfe einer softwarekonfigurierbaren „Matrix“ eine äußerst flexible Möglichkeit bereitzustellen, bis zu 32 einzelne Ausgangspins der Slave-MCU einem beliebigen der 32 Eingangspins der Master-MCU zuzuordnen.

Um die Dinge etwas klarer zu machen, habe ich unten eine Zeichnung hinzugefügt:

SPI-FLUSS

Eine andere MCU (nicht in der Zeichnung) verwaltet das Port-Mapping-Setup und überträgt diese Informationen als „Port-Matrix“ über I2C an die Slave-MCU.

Im Zeichnungsbeispiel sollte der Slave-Ausgangsport B, Bit 0 (B.0) dem Master-Eingangspin A, Bit 0 (A.0) zugeordnet werden. Außerdem sollte der Ausgang B.3 dem Eingang A.1 und dem Ausgang C zugeordnet werden .6 sollte Eingang B.6 zugeordnet werden

Wenn also Master-Pin A.1 hoch geht, sollte Slave-Pin B.3 auch hoch gehen. Aus Sicht der Anwendung sollte das einfach sein.

Aber was wäre der effizienteste Weg, um 32 Bits von 4 Ports auf dem Master zu lesen und sie auf dem Slave als 32-Bit-Ganzzahl darzustellen, damit die Anwendung die Zuordnung zu ihren Ausgangsports bereitstellen kann?

Der SPI-Takt sollte mindestens 2 MHz betragen, um funktional akzeptabel zu sein. Ist DMA hier eine Lösung? Kann eine solche Transportlösung unterbrechungs-/ereignisbasiert sein, um die CPU davon abzuhalten, Dinge abzufragen? Ziel-MCUs sind PIC32MX795.

Ich könnte definitiv einige Hinweise gebrauchen, um diese Kommunikation in Gang zu bringen.

Vielen Dank im Voraus!

Was haben Sie bisher gemacht und warum ist es nicht gut genug? Ich bräuchte mehr Informationen. Wie definieren Sie "effizienteste Methode"? ZB die geringste Nutzung der SPI-Bandbreite, die wenigsten CPU-Zyklen auf dem Slave, die wenigsten CPU-Zyklen auf dem Master, etwas anderes? Wie ändern sich die Eingangspins einzeln oder zufällige Mischungen von Pins? Was ist die minimale Eingangspin-Änderungsdauer, die erkannt und weitergegeben werden muss? Was ist eine akzeptable Latenz? Geringste Latenz zwischen einzelnen Pin-Eingangsänderungen und der darauffolgenden Ausgabe oder konsistente Latenz, egal wie viele Pins sich ändern? Was ist die maximale Latenz für One- und Multipin-Änderungen?
Dieses MCU-basierte Projekt befindet sich in der Konzeptionsphase. Die aktuelle Implementierung erfolgt in Hardware, ist aber nicht flexibel genug. Sein Zweck ist die Wiederverwendung von CNC-Maschinenimpulsen. Sie erscheinen zufällig gemischt auf allen Stiften. Die aktuelle maximale Pulsfrequenz beträgt 400 kHz. Impulsdauer um 1us. Die einzige Aufgabe des Masters besteht darin, Eingangspins + Transport abzutasten. Die Slave-Funktion ist auf die Einstellung von Ausgangsports gemäß der Konfigurationsmatrix beschränkt. Latenzen bis zu 10 us sind akzeptabel, wenn sie konsistent sind. Mit am effizientesten meinte ich das schnellste Setup, sei es DMA oder Code, immer noch etwas darüber zu lernen.
Im PIC32MX795 sind alle Portregister 32 -Bit, obwohl nur maximal 16 Bit implementiert sind. Sie zeigen nur 8 Bits für jeden Port. Okay, überspringen Sie einfach die Bits 8-15. Einige der Port-Pins sind jedoch nicht implementiert. Ich ignoriere Port A, da die fehlenden Pins im High-Byte sind. Aber die Pins RC0, RC5, RC6 und RC7 sind nicht verfügbar. Siehe Seite 28 des Datenblatts. Nur damit du es weißt.
Unter Verwendung Ihrer Latenzanforderungen benötigen 32 Bits, die in 10 usec vom Master zum Slave übertragen werden, einen SPI-Takt von nicht weniger als 3,2 MHz, und das ignoriert die für jegliche Verarbeitung erforderliche Zeit. Die Verwendung Ihrer 1-usec-Pulsdauerspezifikation führt zu einem 32-MHz-SPI-Takt ...
Tatsächlich sind die 32 Signale Teil eines größeren Satzes. Die 10 us-Latenz kommt von unseren Signalen, um mit anderen Signalen synchron zu bleiben, die nicht in den Anwendungsbereich der Lösung fallen. Wenn ich das Routing ändere und sicherstelle, dass alle kritischen Signale die Lösung passieren, wird die Latenz viel weniger streng, da 1 ms in Ordnung wäre.
tcrosley, ich weiß, die Ports in der Zeichnung sind keine echten Ports, sie dienen nur der Verdeutlichung ... danke!

Antworten (3)

Für die Datenübertragung: Am einfachsten geht das mit Schieberegistern. Sie brauchen sich weder um langsame Mikrocontroller noch um die Programmierung von Hardware in CPLDs zu kümmern.

Nehmen Sie zum Beispiel 74HC164 und 74HC166

Sie können vier 74HC166 kaskadieren, um ein 32-Bit-Parallel-In/Serial-Out-Schieberegister zu erstellen, und dann mit vier 74HC164 (32-Bit-Serial-In/Parallel-Out-Register) deserialisieren. Diese Chips können problemlos 100 MHz ausführen, kosten so gut wie nichts und erfordern nur minimale Schaltungen.

Problem ist, dass Sie die "Pin-Belegungsmatrix" verwenden wollten. Dies mit Toren zu bauen, wäre schmerzhaft.

Wenn Sie das Kommunikationsprotokoll selbst mit Bit-Banging versehen möchten, besteht der schnellste Weg möglicherweise darin, alle 4 Leitungen zum Senden der Pin-Zustände zu verwenden (Daten im Wert von 8 Pins pro Leitung).

Die Idee hier ist, grundsätzlich ein serielles Single-Wire-Protokoll zu verwenden. Da Sie keine Taktleitung haben, müssen Sie eine Art Startbit verwenden, um den Beginn der Übertragung zu identifizieren.

Nehmen wir an, die Datenleitungen werden im Leerlauf hoch gehalten und 0 ist das Startbit. Wenn Sie Pin-Daten im Wert von 0x12345678 (32 Bit) übertragen möchten, übertragen Sie 0x12 in der ersten Zeile, 0x34 in der zweiten Zeile und so weiter.

Das Bitmuster in der ersten Zeile sieht folgendermaßen aus:

0 0 0 0 1 0 0 1 0

^ ist das Startbit

In der zweiten Zeile erhalten Sie:

0 0 0 1 1 0 1 0 0

^ ist das Startbit

Sie können sehen, wohin ich damit gehe. Möglicherweise möchten Sie am Ende ein Prüfsummenbit hinzufügen, um sicherzustellen, dass keine Lesefehler aufgetreten sind. Um dies zu implementieren, müssen Sie warten, bis die Leitung niedrig wird (Sie können dafür einen Interrupt verwenden) und von diesem Punkt an im Wesentlichen jeden anderen seriellen Algorithmus implementieren - die Leitung mehrmals pro Bitperiode abtasten (maximale Dauer eines einzelnen Bits ) und vergewissern Sie sich, dass der Wert stabil ist, bevor Sie ihn aufnehmen.

Dann müssen Sie nur noch die von allen 4 Zeilen gesammelten Daten mit einigen Bitverschiebungen komprimieren und direkt in die Ausgabe schreiben.

Das würde nicht funktionieren - asynchrone Kommunikation. mit wortbasierter Synchronisation für eine 2-MHz-Rate wäre schwierig, selbst wenn sie in Hardware implementiert wäre. Aus diesem Grund ist RS-232 so langsam.
Nun, er sagte, es würde 2 MHz benötigen, wenn er SPI verwenden würde, um alle 32 Bit zu übertragen. Auf diese Weise müssen Sie nur 8 Bits gleichzeitig übertragen, sodass Sie möglicherweise länger pro Bit benötigen. Dies ist nur eine bitbasierte Synchronisation.
Dies ist nicht der Fall: Die Bitsynchronisierung erfordert, dass die PLL auf Phase/Frequenz des Senders einrastet. Die wortbasierte Synchronisation hingegen synchronisiert auf Phase in der mit dem Startbit erzeugten Flanke. Dann tastet er wenige Bits (8–10) in vordefinierten Intervallen später ab, in der Hoffnung, dass die Sendeuhr nahe an ihrer eigenen Uhr liegt. 2 MHz bedeutet eine Periode von 500 ns für ein bisschen, das ist viel zu schnell für den PIC.
Dieses Bild? Seine maximale Frequenz beträgt 80 MHz, die Pins können sogar bei dieser Frequenz umschalten. Das sollte machbar sein. Auch hier brauchen wir keine 2 MHz, wenn Sie nur 8 Bit übertragen müssen.
Sie müssen auf all diesen parallelen Leitungen eine Phasensynchronisation durchführen, was bedeutet, dass Sie jedes Bit an etwa 10 Stellen abtasten müssen. Anstelle von beispielsweise 500 kHz Abtastrate benötigen Sie also 5 MHz. Das bedeutet, dass Sie ein Fenster mit etwa 16 Anweisungen haben, um alle 4 Parallelkommunikationen zu handhaben. Linien. Fängst du an zu verstehen, warum das nicht gut ist? Jetzt können Sie Ihr Leben so viel einfacher machen, wenn Sie nur die 5. Zeile für die Synchronisierung hinzufügen, da dies die Phasensynchronisierung und Startbits usw. überflüssig macht.

Ihre Anforderungen sind ziemlich streng (2 MHz, 10 us Verzögerung), damit dies in einem PIC mit einigen Dutzend MIPS erfolgen kann. Davon abgesehen könnte es möglich sein. Aber es ist immer noch nicht das beste Werkzeug für den Job.

Kennen Sie FPGAs? Sie sind dafür zu groß und zu teuer, aber einige billige kleine CPLD können das auch. Anstatt Software zu schreiben, würden Sie SPI-Bit-Banging in VHDL oder Verilog auf der Master-Seite implementieren, und dann könnte der Slave Ihr CNC-Controller, PIC oder ein anderes CPLD sein.

Ich habe nichts über diese CPLDs gelernt. In der Tat eine interessante Alternative zum Anschauen. Danke!
Ich dachte an eine noch einfachere Möglichkeit, dies zu tun, und postete sie als weitere Antwort für Sie
Angenommen, wir ändern das Design und entscheiden uns für CPLDs, das würde das Abtastproblem auf dem Master lösen, die Implementierung eines beliebigen seriellen Protokolls ermöglichen und das Problem der Schaltausgänge als Matrix lösen. Das einzige, was mir unklar bleibt, ist, wie man ein gewisses Maß an Konfigurationsfreiheit in einem CPLD oder einem EEPROM oder einem umgebenden Flash aufbaut. Wir sollten in der Lage sein, Ausgänge spontan mit Eingängen zu verbinden, nicht zur Kompilierzeit?
Eine einfache Möglichkeit, es online zu konfigurieren, besteht darin, eine andere Kommunikationsschnittstelle zu erstellen (kann SPI, UART, 1-Draht oder sogar ein einfaches Schieberegister sein..), über die Sie Ihre Konfiguration in interne Register schreiben. Ihre Zustände bestimmen, wie die Signale geroutet werden. Stellen Sie nur sicher, dass die Konfiguration immer in einem Zustand durchgeführt wird, in dem das Gerät die parallelen Eingänge nicht liest - sonst sehen Sie möglicherweise falsche Impulse (sogenannte Gefahren) im serialisierten Ausgang.
Altera oder Xilinx? Was wäre der Rat für einen Neuling? Nicht nur das Silizium, sondern auch die Entwicklungsumgebung?
Ich bin nicht die richtige Person, um das zu beantworten - versuchen Sie, es hier auf EE zu suchen, oder stellen Sie eine neue Frage.
Ok Altera Max II Entwicklungsboards sind eingetroffen. Ich habe mir Crosspoint-Switches zur Inspiration angesehen, Referenzdesigns sind leicht verfügbar. Dies ist jedoch keine exakte Übereinstimmung. Was wäre aus architektonischer Sicht der beste Weg, um ein solches Konfigurationsregister zu implementieren?