Forum: FPGA, VHDL & Co. FPGA als SPI Slave


von Tobias B. (tobiasz80)


Lesenswert?

Hallo,

ich implementiere in meinem FPGA (Digilent CMOD7 mit einem Artix7 35) 
eine Hardware, die ich als ein SPI Slave ansteuern will. Dazu benutze 
ich dieses Modul 
https://github.com/nandland/spi-slave/blob/master/Verilog/source/SPI_Slave.v
Als Master benutze ich ein Nucleo Board mit einem STM32L552. Mein 
Problem ist, das ich zwischen FPGA und MCU keine zuverlässige Verbindung 
aufbauen kann. Ständig passieren Übertragungsfehler (nach ~100kB an 
Daten). Bei Debug Versuchen haben ich mir die Clock von dem SPI Slave im 
always Block ausgeben lassen, mit diesem Testcode:
1
  always @(posedge i_SPI_Clk or posedge i_SPI_CS_n)
2
  begin
3
    if (i_SPI_CS_n)
4
    begin
5
      o_SPI_DBG <= 0;
6
    end
7
    else
8
    begin
9
      o_SPI_DBG <= ~o_SPI_DBG;
10
    end
11
  end
und dabei festgestellt, das manchmal auch zur fallenden Flanke von 
i_SPI_Clk getacktet wird. Gemessen habe ich alles über einen Logic 
Analyzer. Das ist nicht immer der Auslöser von Übertragungsfehlern, aber 
sehr oft.
Dabei ist auch kurrios: SPI Frequenzen von unter 1MHz scheinen 
problemlos zu funktionieren, dadrüber bekomme ich ziemlich sicher 
Übertragungsfehler. Auch Kurios: Mit einem RPi Pico funktioniert es 
problemlos, auch bei Frequenzen um die 30MHz.
Die SPI Verbindung ist über Jumper Wires auf einem Breadboard 
ausgeführt. Kabellängen sind ca 20cm.
Der i_SPI_Clk benutzt einen clock eingang im FPGA.

Ich muss ehrlich sagen, ich bin gerade ziemlich Ratlos was hier schief 
läuft und hoffe, hier ein paar Ideen zu bekommen, was ich ausprobieren 
könnte. Leider habe ich kein Oszi um mir die Clockleitung genau 
anzuschauen. Ich kann sie nur mit 50MHz mit dem Logic Analyzer 
absamplen. Das reicht sicherlich um eine Idee von dem Signal zu 
bekommen, aber reicht wohl bei weitem nicht für eine Analyse.
Ein weiterer Versuch war ein Serienwiderstand in die Clockleitung rein 
zu setzen. Das hat ein wenig geholfen, habe werte von 22-39Ohm 
ausprobiert, aber der große Schuss wars jetzt nicht. Bei den Versuchen 
habe ich den Widerstand direkt ins Nucleoboard gesteckt und bin dann 
über ein Jumperwire zum FPGA.

So, nun bitte ich um Hilfe, was könnte hier schief laufen? Mache ich 
hier was grundsätzlich falsch? Wie sieht es z.B. aus, das der SPI Slave 
das Clock Signal vom SPI als Clock benutzt? Wäre es besser den SPI 
direkt mit dem FPGA Clock zu samplen?

Vielen Dank
Tobias

von Jens W. (jensw)


Lesenswert?

Hallo,

deine Infos sind noch ein bisschen dürftig für eine Vermutung, aber ich 
versuche es mal.
Wie hoch ist denn dein Clock für das FPGA? Und wie hoch ist dein 
angestrebter SPI clock?

Welchen Mode hast du bei der SPI gewählt? Da gibt es ja vier 
verschiedene, je nachdem wie und wo geshiftet und gesampled werden soll.
Und ist das auch der gleiche Mode wie bei deinem SPI Master?

Ohne Oszi wird es schwer. Dein Loigc Analyser kann nur digitale Werte 
anzeigen, du müsstest dir aber die Signalqualität anschauen. Erreichst 
du die richtigen Pegel für high und low?

Da du schreibst, dass nach etwa 100kB Fehler auftreten könnte es auch 
gar nichts mit deinen Signalen zu tun haben, sondern damit, wie die 
Daten weiter verarbeitet werden. Vielleicht gibt es ja da ein Problem?

Grüße

von Martin S. (strubi)


Lesenswert?

Als erstes waeren die CPHA/CPOL Einstellungen interessant, klingt eher 
nach Abtastungsproblem als eingestreutes Rauschen bei langsamer Slew 
Rate (was ungewollte Flanken provozieren koennte), da es ja offenbar bei 
langsamen Frequenzen tut und der Widerstand das Verhalten noch 
verbessert. Grundsaetzlich wuerde ich mal den externen, im Verhaeltnis 
langsamen Clock abtasten und eine Entprell-Option im SPI-Core vorsehen, 
damit hat man auch die Slew-Rate-Probleme vom Tisch und die 
Moeglichkeiten, Glitches auf lange Zeit zu detektieren.

von Tobias B. (tobiasz80)


Angehängte Dateien:

Lesenswert?

Hallo,

vielen Dank für die Antworten. Das Design läuft mit 100MHz. SPI soll so 
schnell wie möglich betrieben. Aktuell wird er im Mode 0 und mit ~14MHz 
betrieben, hoffe aber das ich mich noch auf 25MHz steigern kann. Je 
schneller, um so besser.
Mit ein paar weiteren Experimenten konnte ich das Problem weiter 
eingrenzen. Meine ursprüngliche Annahme mit dem Clock ist falsch, ganz 
offensichtlich ist es die der Chip Select der das Problem verursacht. 
Dabei folgender Test Code:
1
  always @(posedge i_SPI_Clk or posedge i_SPI_CS_n)
2
  begin
3
    if (i_SPI_CS_n)
4
    begin
5
      debug <= 0;
6
    end
7
    else
8
    begin
9
      debug <= 1;
10
    end
11
  end
Ein Serien Widerstand in der Chip Select Leitung erzeugt einen deutlich 
besseres Ergebniss, und auch das mit dem Logic Analyzer gemessene 
Rauschen ist deutlich geringer, trotzdem passiert es ab und zu, das 
während dem SPI Transfer der CS gezogen wird und dadurch der Slave nicht 
mehr im Sync mit dem Master ist, wie in dem glitch Bild zu sehen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.