Dualer SPI-Master mit ATmega32u4

In meinem Design tauchte ein unerwarteter Bedarf auf, der darin besteht, 2 Slave-SPI-Geräte gleichzeitig zu steuern. Zuerst hatte ich natürlich vor, den SPI-Bus wie gewohnt zu verwenden und beide Geräte über die /CS-Pins zu steuern, damit alles in Ordnung schien.

Als ich heute das Datenblatt von Gerät A durchgesehen habe, ist mir aufgefallen, dass es alle Daten auf einmal erwartet, was bedeutet, dass ich das ursprünglich geplante Verfahren nicht durchführen kann:

1) Gerät B auswählen 2) Daten von B lesen 3) Gerät B abwählen 4) Gerät A auswählen 5) Daten von B schreiben 6) Gerät A abwählen 7) Wiederholen, bis alle Daten von B zu A gehen (ca. 1,1 Mbit)

Das Gerät A nimmt an, dass es das Ende des Datenstroms ist, wenn sein /CS hoch geht. Natürlich kann ich nicht alles von B in einem Durchlauf lesen und im MCU-RAM speichern, da die Daten viel größer sind.

Als nächstes kam mir natürlich in den Sinn, 2 separate Master-SPIs gleichzeitig zu verwenden: beide Chips auswählen, Byte von B einlesen und sofort A zuführen.

Also meine Fragen sind:

a) Ist das mit einem ATmega32u4 möglich? Es spielt eine entscheidende Rolle im Gesamtdesign und der Wechsel zu einer anderen MCU wäre ein Schritt zurück.

b) Ich habe gelesen, dass der USART als zweiter SPI-Master fungieren kann. Ist das praktikabel und zuverlässig? Wie schwer ist die Umsetzung?

c) Wenn das leider nicht möglich ist und ich die MCU wechseln muss, welche würden Sie empfehlen? Beachten Sie, dass die USB-Fähigkeit des ATmega32U4 unerlässlich ist.

d) Wird der neue Prozess (Lesen von B, Zuführen zu A) wahrscheinlich ein unerwartetes Verhalten hervorrufen? Scheint aus meiner Sicht nicht, ich frage nur für den Fall, da ich ein neuer Ingenieur bin.

Jede andere Idee oder Richtung ist willkommen! Vielen Dank im Voraus.

UPDATE Falls es eine bedeutende Rolle spielt, Gerät A ist ein FPGA, während B ein Flash-Speicher ist. Die MCU hat eine doppelte Rolle: Laden Sie den Bitstream vom PC über USB herunter und speichern Sie ihn auf dem Flash-ROM / verwenden Sie den gespeicherten Bitstream, um das FPGA beim Zurücksetzen/Einschalten zu konfigurieren. Sowohl FPGA als auch Flash verwenden SPI. Laut Datenblatt des FPGA (ice40-Familie, Lattice, „ iCE40-Programmierung und -Konfiguration “, S.26) muss das Bild ohne Unterbrechung programmiert werden.

SPI-Master ist relativ einfach in reiner Software zu implementieren, indem nur GPIOs verwendet werden.
Es hat 2 SPI-Peripheriegeräte?
@LongPham Ja, der ATmega32u4 hat 2 SPI-Peripheriegeräte angeschlossen und die MCU nimmt die Daten von dem einen und leitet sie an den anderen weiter.
Klingt so, als ob Sie mehrere Übertragungen benötigen, um alle Daten von A nach B zu übertragen, wobei Sie die MCU als temporären Speicher für Daten verwenden, bevor Sie den Betrieb des SPI von "Lesen A" auf "Schreiben B" umschalten, und Sie sind durch die Speichermenge auf dem begrenzt MCU in Bezug auf eine vollständige Übertragung. Wenn Sie eine SPI-Lesetransaktion erneut ausgeben, um verbleibende Daten zu erhalten, weiß der Slave auf dem externen Gerät nicht, auf Daten von einem Ort im Speicher zuzugreifen, an dem Sie bei der vorherigen Übertragung angehalten haben (?). Was sind „Gerät A“ und „Gerät B“. "? Bei FPGAs können wir das leicht beheben. Können Sie eine Zeichnung mit den relevanten Details hinzufügen?
@CapnJJ Ja, es ist tatsächlich ein FPGA. Die MCU hat eine doppelte Rolle: Laden Sie den Bitstream vom PC über USB herunter und speichern Sie ihn auf dem Flash-ROM / verwenden Sie den gespeicherten Bitstream, um das FPGA beim Zurücksetzen/Einschalten zu konfigurieren. Sowohl FPGA als auch Flash verwenden SPI. Laut Datenblatt des FPGA (ice40-Familie, Lattice, "iCE40 Programming and Configuration" S.26) muss das Bild ohne Unterbrechung programmiert werden.
@CapnJJ Eine Zeichnung ist leider nicht ohne weiteres verfügbar.
Ich meinte, Sie könnten einfach etwas auf hohem Niveau zeichnen, aber ich glaube, ich verstehe. Sehen Sie, ob ich das verstehe ... PC -> FLASH, über MCU USB, keine Probleme, und jetzt sind Sie gut für das Zurücksetzen beim Einschalten, um das FPGA über FLASH (?) Zu programmieren, aber FLASH -> FPGA über MCU SPI nicht genug Speicher, um lokal auf der MCU zu speichern, um dann das FPGA ohne Unterbrechung zu programmieren? Haben Sie einen ausreichend großen MCU-verbundenen Speicher auf Ihrer Platine, der einen anderen Bus als SPI hat? Wenn ja, können Sie vielleicht FLASH -> FPGA in zwei Schritten machen. Wenn der SPI-Bus auf der Leiterplatte zwischen FPGA und FLASH geteilt wird, reicht ein separater Master nicht aus.
@CapnJJ Ja, du verstehst richtig. Im aktuellen Schema ist der Bus tatsächlich geteilt, aber ich könnte diese Linien umleiten.

Antworten (4)

Vielleicht möchten Sie einen ganz anderen Ansatz wählen. Anstatt sowohl das PROM als auch das FPGA als Slave-Geräte an den µC anzuschließen, schließen Sie das PROM direkt an das FPGA an und lassen Sie das FPGA im SPI-Master-Modus statt im SPI-Slave-Modus booten. Bonus: Das Booten geht schneller.

Sie können weiterhin vom µC aus auf das PROM zugreifen, nachdem das FPGA für Firmware-Updates oder Datenspeicherung gebootet hat, indem Sie die SPI-Schnittstellensignale des µC durch die FPGA-Logik leiten.

Dies ist eine sehr elegante Lösung und ich habe sie sorgfältig überlegt und bin schließlich zu einer "modifizierten" Version von Ihnen gekommen. Wenn man sich die FPGA- und MCU-Datenblätter ansieht, booten beide Geräte offensichtlich mit ihren I/Os in HiZ. Dies bedeutet, dass sie sowohl Master für das PROM sein als auch dieselben Leitungen teilen können, wenn auch nicht gleichzeitig. FPGA und MCU booten also beide mit den gemeinsamen Pins in HiZ, dann konfiguriert sich FPGA selbst und deaktiviert diese Pins wieder. Danach kann die MCU Updates durchführen: Aktivieren Sie das SPI, führen Sie das Update durch, deaktivieren Sie dann das SPI und geben Sie diese PINs an HiZ zurück. (Allerdings noch nicht getestet)
Ja, das geht auch. Der Hauptgrund, warum ich das Pass-Through vorgeschlagen habe, ist, dass es Ihnen die Möglichkeit gibt, dieselbe SPI-Schnittstelle auf dem uC zu verwenden, um auf Wunsch auch die Anwendungslogik im FPGA zu steuern.
Nun, die direkte Verbindung bedeutet, dass die MCU den Flash programmieren kann, wenn auf dem FPGA keine Konfiguration geladen ist. Wenn Sie dem FPGA eine separate Chipauswahlleitung bereitstellen, können sich das FPGA und der SPI-Flash wie zwei separate SPI-Slaves verhalten. Ich würde empfehlen, ein paar weitere Signale anzuschließen: Die MCU muss nämlich in der Lage sein, das FPGA zurückzusetzen und im Reset zu halten, damit sie ohne Konflikte auf den SPI-Flash zugreifen und das FPGA auslösen kann, um die neue Konfiguration zu laden , und die MCU sollte in der Lage sein zu wissen, wann das FPGA das Laden der Konfiguration abgeschlossen hat.
Für Xilinx sind diese Signale PROGRAM_B und DONE. Sieht so aus, als wären die äquivalenten Signale auf Lattice-Teilen CRESET_B und CDONE.

a) Afaik der Atmega hat nur 1 SPI-Bus.

b) Keine Erfahrung (aber ich bin Anfänger)

c) Ich verwende meistens STM#2. Diese haben 2 SPI-Busse und wenn Sie mehr benötigen, gibt es Versionen mit 3 (oder möglicherweise sogar mehr). Der billigste (kostet weniger als ein Arduino) STM32F103C8T6 hat 2 SPI-Busse.

d) Die SPI-Busse auf dem STM32 (und wahrscheinlich anderen UCs) sind unabhängig, daher sollte es keine Probleme mit dem Prozess geben. Da STM32 jedoch über DMA verfügt, können Sie dies möglicherweise "direkt" tun, dh eingehende SPI-Daten sofort an das ausgehende SPI senden.

Vielen Dank für Ihre Antwort, sie sehen interessant aus. Ich werde sie im Hinterkopf behalten, falls mit der aktuellen nichts zu tun ist.
Viel Glück (übrigens können Sie einige STM32s auch mit Arduino-Code verwenden). Beachten Sie jedoch, dass der STM32 im Prinzip auch eine Steigerung der Komplexität darstellt (ich lerne immer noch, da ich ein Anfänger bin).

Sie geben an, dass das FPGA das Ende der Konfigurationsdaten annimmt, wenn CS deaktiviert wird. Gibt es auch ein Timeout? Das heißt, wenn Sie eine unbestimmte Verzögerung haben können, während Sie CS aktiv lassen, wird sich das Gerät dann richtig verhalten?

Wenn einfach verhindert werden muss, dass das FPGA-Gerät die Transaktion schließt, kann das Problem dahingehend vereinfacht werden, dass CS ausgewählt bleibt, während nicht zugelassen wird, dass Befehle an den Flash als Datenmüll eingelesen werden. Dafür ist ein zweiter SPI-Master vielleicht zu viel des Guten

Ich würde vorschlagen, ein Puffergerät zwischen MCU und FPGA für die MISO, MOSI, und SCLKLeitung zu verwenden und dieses zu verwenden, um die SPI-Signale zu deaktivieren, indem der Reset/Enable-Pin am Puffergerät verwendet wird.

Die Transaktion würde aussehen

  1. CS für FPGA asynchron behaupten
  2. Puffergerät deaktivieren
  3. FLASH-Gerät wie gewohnt auslesen
  4. Puffergerät aktivieren
  5. FPGA-Transaktion (CS bereits bestätigt)
  6. GOTO 2 bis fertig
  7. CS für FPGA asynchron deaktivieren
Gemäß dem bereitgestellten Dokument zur Konfiguration gibt es ein Timeout (S. 25), aber es ist nicht ganz klar, ob es sich nur auf den Master-Modus oder sowohl auf den Master- als auch auf den Slave-Modus bezieht. Außerdem habe ich das gesamte Datenblatt durchgesehen, konnte aber die tatsächliche Zeit nicht finden. Trotzdem würde ich es vorziehen, keine zusätzliche Hardware in diesem speziellen Design zu installieren, aber ich würde es für zukünftige Designs im Hinterkopf behalten, danke!

USART als SPI-Master

Wie das Datenblatt in Kapitel 19 sagt,

Der universelle synchrone und asynchrone serielle Empfänger und Sender (USART) kann auf einen Master-SPI-kompatiblen Betriebsmodus eingestellt werden.

So können Sie zwei unabhängige SPI (Master)-Ports haben, um Daten zwischen den Slaves zu übertragen.

Verwendung eines externen I 2 C-EEPROM

Anstelle eines SPI-Flashs können Sie ein I 2 C-EEPROM an den TWI-Port (PD0, PD1) der MCU anschließen. I 2 C wird in Atmel-esisch TWI oder 2-wire Serial Interface genannt , aber sie sind im Wesentlichen dasselbe. Nachteil: EEPROMs sind im Allgemeinen teurer als Flash-Speicher.

Ich würde einen FRAM-Teil vorschlagen, der ein ähnlicher Teil ist und normalerweise dasselbe I2C-Protokoll verwendet, aber Zugriffszeiten von <100 us anstelle der typischen 5-10 ms für EEPROM hat.