Hallo Leute. Ich habe im Netz einen freien, für mich recht einfachen und gut implimentierten Code eines I2C_Slaves gefunden. In der Simulation lief alles einwandfrei. Nun habe ich diesen auf einem Virtex4(XC4VFX12) implementiert und versuche jetzt mit meinem Master mehr als ein Byte zu senden und zu empfangen. Das Senden läuft tadellos. Leider empfängt der Master nur 1 Byte und danach nur noch ('FFFFFF'). Ich kann nicht erkennen wo der Fehler liegen könnte, da der master mit anderen Slaves bis jetzt funktioniert hat. Kann eventuell wer einen Blick auf den Code werfen oder diesen sogar mal testen. Für jeden Hilfe bin ich sehr dankbar. MfG
1 | -- check for edges (this concept is used to filter spikes)
|
2 | sda_falling_edge <= true when sda_sampled = b"1100" else false; |
3 | sda_rising_edge <= true when sda_sampled = b"0011" else false; |
4 | scl_falling_edge <= true when scl_sampled = b"1100" else false; |
5 | scl_rising_edge <= true when scl_sampled = b"0011" else false; |
Das ist in der Theorie schön entprellt, in der Praxis aber ein zweischneidiges Schwert. Was ist, wenn du z.B. folgende Signalfolge am sda-Pin hast (z.B. ein kleiner Umschalt-Spike): 111111111010000000000101111111 Dann wirst du niemals eine sda_falling_edge oder eine sda_rising_edge erkennen :-o Und der Witz dabei es funktioniert eigentlich. Nur ab und zu gehts schief. Besser ist es in der Art:
1 | -- check for edges (this concept is used to filter spikes)
|
2 | sda_falling_edge <= true when sda_sampled = b"1110" else false; |
3 | sda_rising_edge <= true when sda_sampled = b"0111" else false; |
4 | scl_falling_edge <= true when scl_sampled = b"1110" else false; |
5 | scl_rising_edge <= true when scl_sampled = b"0111" else false; |
Ok, danke schon mal für diesen Tip, habs intigriert. Nur hat das, glaube ich, nicht viel mit meinem Hauptproblem zu tun. Denn ich kann ja Daten hin und her verschicken nur halt auf dem Weg vom Slave zum Master nicht mehr als 1 Byte. Hast du den Code eventuell schon simuliert oder sogar auf einem realen Board implementiert und ein anderes Ergebnis erhalten? MfG
> Nur hat das, glaube ich, nicht viel mit meinem Hauptproblem zu tun. Nein, das glaube ich auch nicht. Aber wenn ich beim bloßen Drüberschauen schon sowas sehe, ist das für mich ein Grund, das ganze Design zu hinterfragen :-/ > Hast du den Code eventuell schon simuliert ... Nein, ich habe leider gerade keine Zeit dafür.
Ganz wichtig, die SDA Leitung (und eigentlich auch die Clockleitung) muss als Opendrain mit Pullup am FPGA ausgeführt sein. Ist ein häufiger Fehler, dass kein Opendrain benutzt wird. Viele Grüße Arndt
> die SDA Leitung (und eigentlich auch die Clockleitung) > muss als Opendrain mit Pullup am FPGA ausgeführt Die SDA-Leitung ist Open-Drain:
1 | sda <= sda_out when sda_out = '0' else 'Z'; |
Die SCL-Leitung muß nur dann Open-Drain sein, wenn der Slave den Master ausbremsen will (was aber angesichts der kursierenden zwielichtigen selbstprogrammierten Software-Master keine gute Idee ist). Sowas:
1 | sda_in <= '1' when sda /= '0' else '0'; |
schreibt sich so kürzer:
1 | sda_in <= sda; |
Was allerdings meine Zweifel an der Qualität dieses Codes nur bestärkt ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.