Apr 16, 2024
DisplayPort: Tippen Sie auf den Altmodus
Tatsächlich ist die modernste Implementierung von DisplayPort der USB-C-DisplayPort-Altmodus, ein Synonym für „Video über USB-C“, und wir würden ihn verpassen, wenn ich ihn weglassen würde. Übrigens unsere letzten beiden Artikel
Tatsächlich ist die modernste Implementierung von DisplayPort der USB-C-DisplayPort-Altmodus, ein Synonym für „Video über USB-C“, und wir würden ihn verpassen, wenn ich ihn weglassen würde. Übrigens haben unsere letzten beiden Artikel über USB-PD einigen Leuten ein cooles neues Spielzeug zum Spielen gegeben – die Leute haben die Artikel kommentiert, mich um Hilfe beim Debuggen gebeten und ich habe sogar gesehen, wie Leute den FUSB302B eingebaut haben ihre Projekte! Lassen Sie uns im Anschluss an diese Errungenschaft noch einen Schritt weiter gehen und eine weitere USB-C-Funktion erobern – eine Funktion, die uns noch nicht offen zugänglich ist, obwohl sie es verdient hätte.
Für unsere langjährigen Leser ist es keine Überraschung, dass Hackern alltägliche Fähigkeiten verwehrt bleiben. Mittlerweile wissen wir alle, dass Sie bei vielen Laptops und Telefonen eine DisplayPort-Verbindung über einen USB-C-Anschluss erhalten können. Angesichts der Tatsache, dass die USB-C-Spezifikationen offen verfügbar sind und wir zuvor eine PD-Senke mit diesen Spezifikationen implementiert haben, würde man erwarten, dass wir DisplayPort genauso einfach realisieren können. Dennoch steht die DisplayPort-Altmode-Spezifikation hinter einer Paywall für VESA-Mitglieder, die einen hohen Preis hat – eine Praxis, die weithin kritisiert wurde, ihrem Zweck als Standardisierungsorganisation widerspricht und zum Scheitern einiger ihrer Standards geführt hat.
Aber keine Sorge – wir können leicht eine Auswahl an PDFs finden, die einen allgemeinen Überblick und einige Details zum DisplayPort-Altmodus bieten, und hier ist mein Favorit! Ich habe auch ein Gerät, auf dem MicroPython mit angeschlossenem FUSB302-Chip läuft, und einige meiner DisplayPort-Altmode-Geräte, die ich zerlegen kann. Es stellt sich heraus, dass dies mehr als genug ist, um uns den Weg in eine Open-Source-DisplayPort-Altmode-Bibliothek zurückzuentwickeln!
Der USB-C-Anschluss verfügt über vier High-Speed-Paare und ein zusätzliches Low-Speed-Paar (SBU). Dies passt hervorragend zu den DisplayPort-Anforderungen, mit bis zu vier Hochgeschwindigkeits-Datenübertragungspaaren und einem AUX-Konfigurationskanal. Eine kleine Besonderheit: Es gibt keinen Pin für das HPD-Signal. Stattdessen wird sein Status innerhalb von DisplayPort-Altmode-Nachrichten über den PD-Kanal weitergeleitet. Dadurch können Sie Ihr Gerät an einen DisplayPort-fähigen USB-C anschließen, ein paar magische Worte über PD schreiben und ein DisplayPort-Signal an den TX/RX-Pins des USB-C erhalten! Sie müssen sich überhaupt nicht mit den DisplayPort-Interna befassen; Sie müssen höchstens HPD als PD-Nachricht weiterleiten. Wenn Ihr Gerät eine USB-C-Buchse verwendet, können Sie die Signale entsprechend der Art und Weise, wie Ihr USB-C-Kabel eingesteckt ist, mit einem billigen Mux umdrehen.
Neben DisplayPort erhalten Sie auch USB 2.0 an den guten alten USB2-Pins – perfekt zum Anschließen einer Tastatur und einer Maus neben Ihrem Monitor. Das ist jedoch noch nicht alles, was Sie herausholen können – wenn Sie mit zweispurigem DisplayPort zufrieden sind, können Sie das Upstream-Gerät bitten, Ihnen zwei Spuren DisplayPort an einem Pin-Paar und einen USB3-Anschluss an einem anderen bereitzustellen! So funktionieren die meisten günstigen USB-C-Docks – sie verfügen über zwei DisplayPort-Spuren für VGA oder HDMI, USB3 für einen Hochgeschwindigkeitsanschluss oder ein paar Peripheriegeräte und USB2 für eine ganze Reihe anderer Dinge, die Ihren Strom verwalten Eingabe auf der Seite.
Dem PDF von ST nach zu urteilen, gibt es sieben Arten von PD-Nachrichten, die wir beantworten müssen, wenn wir ein DisplayPort-Gerät bauen wollen – das Diagramm auf Seite 13 zeigt sie alle. Im Artikel „Alles über USB-C: Antworten auf Low-Level-PD“ haben wir zwei Arten von Nachrichten kennengelernt – Source_Capabilities, eine Ankündigung des USB-C-Netzteil-Leistungsprofils, und die Anforderungsnachricht, die wir erstellt haben, um sie zu erhalten eines dieser Leistungsprofile und erhalten Sie eine höhere Spannung aus einem USB-C-Anschluss. Von zwei bis sieben – das ist für uns durchaus machbar!
Was müssen wir tun, um es zumindest zurückzuentwickeln? Ich würde sagen, das PDF scheint allein mehr als genug Informationen zu enthalten – der Kommunikationsablauf, verschiedene Befehlscodes und Inhalte werden dort beschrieben. Es wird jedoch viel komfortabler sein, wenn wir Paketerfassungen als Referenz haben!
USB-C-Kommunikationsschnüffeln ist ein noch wenig erforschtes Gebiet – insbesondere, wenn es sich um Hochgeschwindigkeitssignale handelt. Für diese benötigen Sie eine Interposer-Platine, die die Signalintegrität bewahrt und gleichzeitig den Zugriff auf die CC-Pins ermöglicht, und davon gibt es nicht gerade ein Dutzend. Wenn es um kommerzielle Tools zum USB-C-Sniffing geht, habe ich das Gefühl, dass die meisten davon teuer sind, was der Tatsache Rechnung trägt, dass viele Leute USB-C nicht verstehen. Es gibt jedoch durchaus Möglichkeiten, dies zu umgehen – im Kommentarbereich des ersten PD-Vortragsartikels hat uns [WF] auf eine Möglichkeit hingewiesen, beliebige USB-C-Pakete mit einem Logikanalysator und einer einfachen zusätzlichen Schaltung mithilfe von sigrok und aufzuspüren Pulseview! Wir stellen ein Gerät her, das mit dem DisplayPort-Altmodus kommunizieren und nicht nur schnüffeln kann, aber wenn Sie beim Lesen dieses Artikels ein Gerät von Ihnen anzapfen möchten, sollte dies ausreichen.
Allerdings gibt es möglicherweise eine noch einfachere Lösung. Wenn Sie mitgemacht haben, besitzen Sie möglicherweise einfach einen FUSB302B, bei dem es sich um einen USB-C-PHY-IC handelt. Seit der Veröffentlichung des Artikels „Replying PD“ habe ich langsam auf den Fähigkeiten meines persönlichen MicroPython USB-PD „Stacks“ aufgebaut – eher eine Auswahl an PD-Funktionen und Code, aber ich werde ihn bis dahin einen Stack nennen Der passende Name wurde gefunden. Zuerst habe ich die Fähigkeit zum Abhören von Paketen hinzugefügt – indem ich den FUSB302 in den Nur-Empfangsmodus schalte, seinen Eingangs-FIFO so schnell wie möglich liest und die Daten im laufenden Betrieb analysiert. Ich habe auch das Parsen von Paketinformationen hinzugefügt, sodass Sie die USB-C-Kommunikation in der seriellen Konsole sehen können, ohne sie zuerst lesen zu müssen.
Natürlich gibt es einen Vorbehalt: Ich kann USB-C-Pakete nicht einfach per Passthrough erfassen, da ich kein Open-Source-Passthrough-Board mit CC-Tapping-Funktion entwickeln wollte und diese Boards nicht ganz verfügbar sind. Trotzdem sollte das jemand tun – es ist ein bisschen schade, dass das USB-C-Thru-Gerät nie gefördert wurde! Stattdessen habe ich damit begonnen, Geräte mit unverlierbaren Kabeln, die ich besitze, zu zerlegen und dann den CC-Pin anzuzapfen – da bei einem Gerät mit unverlierbaren Kabeln nur ein CC-Pin möglich ist. Das bedeutet, dass ich die Rotation nicht automatisch erkennen muss, was sehr praktisch ist, denn angesichts der Zeit, die mein MicroPython-Code benötigen könnte, um die Rotation herauszufinden, könnte die USB-PD-Konversation zu diesem Zeitpunkt bereits beendet sein. Also, der CC1 meines Boards ist mit einem der CC-Pins meines USB-Docks verkabelt, CC1 ist als Abhörpin fest codiert – was sonst?
Sie sollten die FUSB-Pullups deaktivieren – sie werden hier kontraproduktiv sein, da wir auf eine bestehende Pullup/Pulldown-Anordnung zurückgreifen und die Einführung eines weiteren Pulldowns dazu führt, dass VBUS ausgeschaltet wird. Sie sollten auch GoodCRC-Antworten deaktivieren – FUSB302 führt sie automatisch durch, was hilfreich ist, wenn wir es als Senke verwenden, aber hier stehen sie im Konflikt mit GoodCRC-Antworten von beiden Seiten der USB-C-Konversation; Noch besser ist es, den Sender zu deaktivieren. Ich habe auch den SOP-Paketempfang aktiviert – diese Pakete werden für Emarker verwendet, und obwohl wir sie normalerweise nicht empfangen müssen, ist es gut, sie jetzt abhören zu können.
Jetzt sind wir bereit! Allerdings erfolgt die USB-C-Kommunikation sehr schnell. Mein MicroPython-Code ist auch nicht schnell – ich verwende MicroPython, weil ich Hackbarkeit der Ausführungsgeschwindigkeit vorgezogen habe. Dies hat jedoch zur Folge, dass ich Pakete bei ihrem Eintreffen nicht richtig analysieren kann – wenn ich das tue, verpasse ich Teile des USB-C-Gesprächs, denn denken Sie daran, dass selbst gedruckte Anweisungen etwas Zeit in Anspruch nehmen. Stattdessen lese ich den Inhalt des Eingabe-FIFO so schnell wie möglich, speichere Pakete im RAM und analysiere sie anschließend. Auf der anderen Seite bedeutet die Paketerfassung im RAM auch, dass ich PD-Gesprächsaufzeichnungen habe, die ich später problemlos speichern und wiedergeben kann, und Sie erhalten auch einige dieser Aufzeichnungen!
Natürlich gibt es auch Nachteile bei der Verwendung dieser Methode der Paketerfassung: Ich bin möglicherweise immer noch nicht in der Lage, zu schnelle Kommunikationen zu erfassen, ich erfasse nur Pakete mit gültigem CRC und übersehe alle verstümmelten Pakete, und ich habe keine Zeitstempel für die empfangenen Pakete; Die Verwendung eines Logikanalysators würde all dies zunichte machen. Für unsere DisplayPort RE-Zwecke ist es jedoch mehr als gut genug, und jeder Parsing-Code, den ich schreibe, wird beim Aufbau einer Bibliothek sehr hilfreich sein. CC-Pin verkabelt, Code läuft und fertig, los geht's!
Hier können Sie sehen, wie eine Leistungsprofilverhandlung stattfindet – Source_Capabilities, Request, Accept und PS_RDY, Dinge, die wir bereits zuvor gemacht haben. Diese sind erforderlich, wenn Sie zu irgendeinem Zweck über PD sprechen möchten, daher ist das keine große Überraschung. Allerdings gibt es auch eine ganze Reihe von Vendor_Defined-Meldungen, die Sie möglicherweise verunsichern. Aber haben Sie keine Angst – seien Sie stattdessen dem USB-C-Standard dankbar, denn durch die Art und Weise, wie er Anbieter anweist, herstellerspezifische Kommunikation zu implementieren, sind diese Meldungen besser dokumentiert, als Sie erwarten würden!
VDMs oder Vendor-Defined Messages sind für alle Altmode-Beschwörungen verantwortlich, die über die regulären „USB3-, USB2- und PD“-Dinge hinausgehen. Sie können VDMs für alles verwenden, was außerhalb des Standards liegt, von benutzerdefinierten Altmodes bis hin zu Firmware-Updates. Sie können sie unstrukturiert oder strukturiert haben – unstrukturierte Nachrichten sind grundsätzlich frei formuliert, während strukturierte Nachrichten eine Art Vorlage für eine typische Konversation sind, die ein Anbieter möglicherweise tatsächlich implementieren möchte. Bei der DisplayPort-Aushandlung werden strukturierte Nachrichten verwendet, und von den sieben Befehlen, die zum Einrichten des DisplayPort-Altmodus erforderlich sind, sind fünf Befehle, die bereits im USB-C-Standard definiert sind! Was die beiden verbleibenden betrifft, so werden in der PDF-Datei, die wir haben, die Codes auf Seite 8 sehr hilfreich erwähnt und auf den Seiten 10-12 ausführlicher beschrieben.
Diese Befehle sind etwas Besonderes – es ist nicht nur eine GoodCRC-Antwort erforderlich, der FUSB302B erledigt das sowieso für uns. Außerdem kann jeder Befehl entweder eine Anfrage oder eine Antwort sein und jede der Richtungen kann zusätzliche Daten übertragen, abhängig vom konkret verwendeten Befehl! Zum Glück sind alle diese optionalen Daten im PDF beschrieben – was sich mit zunehmender Tiefe als immer hilfreicher erweist.
Alles in allem müssen wir nicht so viel zurückentwickeln, insbesondere – das Hauptproblem wären meiner Einschätzung nach die Bitfelder. Da wir nicht über die vollständigen Spezifikationen verfügen, kann es außerdem sein, dass wir den einen oder anderen entscheidenden Fehler machen – zum Beispiel wissen wir nicht, wie schnell wir auf diese Befehle antworten müssen oder welche Besonderheiten die ordnungsgemäße Handhabung des DisplayPort-HPD-Signals hat. Wir können diese jedoch herausfinden, und ich habe eine ganze Reihe von USB-C-DisplayPort-Geräten, von denen ich Paketerfassungen erhalten kann!
Nun, jetzt haben wir DisplayPort-Konversationsbefehle, die von einem echten Gerät erfasst wurden – wenn wir jetzt einen DisplayPort-Sink machen wollten, können wir sie einfach wiedergeben und nur kleine Dinge wie die Nachrichten-ID anpassen! Tatsächlich ist hier ein Codestück, das genau das tut – die von uns erfassten Befehle zurücksendet, und ich habe es erfolgreich geschafft, den DisplayPort-Altmodus auf meinem eigenen Laptop aufzurufen! Nun habe ich den Hochgeschwindigkeits-DisplayPort-Ausgang nicht überprüft, aber ich habe Spannung an den SBU-Pins erhalten, was bedeutet, dass das AUX-Diffpair mit diesen verkabelt wurde – etwas, das nur passiert, nachdem der DisplayPort-Altmodus erfolgreich aufgerufen wurde.
Der grundlegende Teil des Wiedergabecodes ist die Anfrage-Antwort-Schleife, die zur Beantwortung eingehender Nachrichten auf unseren Parsing-Code angewiesen ist. Das ist großartig für uns – wir werden genau diese Art von Schleife brauchen, sobald wir tatsächlich unsere eigenen Antworten erstellen können, nur dass wir eine etwas ausgefeiltere Schleife brauchen. Bis dahin reicht mir das, wenn es um ein persönliches Projekt von mir geht.
Die nächsten Aufgaben bestehen darin, diese Befehle tatsächlich zu verstehen und eine sinnvolle DisplayPort-Bibliothek zu implementieren! Wir gehen die sieben erforderlichen Befehle durch, erklären jeden einzelnen, analysieren die, die wir erhalten, und implementieren die, die wir zurücksenden müssen. Anschließend werden wir sie alle in die bereits bestehende Schleife einbinden, die USB-C-Hochgeschwindigkeits-Lane-Rotation-Handhabung herausfinden und bereit sein, Open-Source-DisplayPort-Handhabungsgeräte für jeden geeigneten USB-C-Port in Sicht zu bauen . Schließlich kann heutzutage sogar ein PinePhone DisplayPort unterstützen!