Dekodierung eines zweidrahtigen SPI-ähnlichen seriellen Protokolls

Ich arbeite an einem Projekt, das den optischen Sensor einer Maus beinhaltet. Ich habe die originale Steuerplatine (bis auf den optischen Sensor selbst noch bestückt) und den optischen Sensor auf meiner benutzerdefinierten Platine, der von einem nrf51822 gesteuert werden soll. Ich habe die Takt- und Datenpins (es ist eine Zweidrahtschnittstelle) mit beiden Platinen verbunden, die von der ursprünglichen Steuerplatine angesteuert werden (ich habe meine Takt- und Datenpins als Eingänge ohne Ziehwiderstände eingestellt).

Ich versuche, den Verkehr zu erfassen, um festzustellen, welche Signale gesendet werden, aber ich habe nicht viel Glück - ich vermute, dass meine Taktrate zu niedrig ist. So schnell wie möglich (nur innerhalb einer while trueSchleife) scanne ich meinen Uhr-Pin und meinen Daten-Pin und drucke sie dann beide über UART mit 1M Baud auf meine Konsolenausgabe. Wenn Sie diese Schleife 5 Sekunden lang leer laufen lassen, führt dies zu ~ 4000 Zyklen, was bedeutet, dass ich für jede Schleife eine Laufzeit von> 1 ms erhalte - was meiner Meinung nach mein Hauptproblem ist.

So wie es ist, nehme ich (in ungefähr 700 Scans) 100 Gruppen von abwechselnd "Uhr 1 und Daten 1" und "Uhr 0 und Daten 0" auf - jede Gruppe weist 4-9 Elemente (also 4-9 "1s" auf beide, gefolgt von 4-9 "0" auf beiden). Dann, ungefähr 400 Scans später (~ 0,5 Sekunden), bekomme ich dasselbe, aber 54 Gruppen. An diesem Punkt habe ich aufgehört zu scannen.

Gibt es eine Möglichkeit: A) meinen Scanzyklus zu beschleunigen, damit ich den Datenverkehr genauer erfassen kann? oder B) Entschlüsseln, was ich bereits habe (zweifelhaft)?

Muss ich eine alternative Route in Betracht ziehen? Ich habe keinen Zugang zu einem Oszilloskop gefunden, was ... bedauerlich ist.

Ich würde mich über jeden Rat freuen. Danke.

Welche MCU oder welchen Prozessor verwenden Sie, um die Pseudo-SPI CLK und DATA zu lesen? Ohne Oszilloskop arbeitet man wirklich blind. USB-Oskope sind ziemlich billig geworden und könnten in Ihrer Preisklasse liegen (z. B. Digilent Analog Discovery 2, zweikanalig, 100 Msps, 159 $ mit Studentenrabatt). Dies ist keine Empfehlungsseite, also einfach Google USB-Oszilloskop und Sie werden eine Menge finden. Wenn Sie dieses Protokoll bitbangen müssen, verwenden Sie am besten einen dedizierten Mikrocontroller, auf dem Bare Metal (C oder Assembler) ausgeführt wird. Möglicherweise müssen Sie sogar an der CLK-Flanke unterbrechen, den Zustand von DATA speichern und danach nachbearbeiten.
Sie brauchen dafür kein Oszilloskop, was Sie wahrscheinlich wollen, ist ein Logikanalysator. Diejenigen, die auf USB-Fifo-Chips basieren, sind ziemlich billig und können so etwas wie sigrok zur Analyse füttern. Bedenken Sie aber auch, dass Sie wahrscheinlich das PS/2-Mausprotokoll betrachten , das gut dokumentiert ist und nicht rückentwickelt werden muss.
Danke für die bisherigen Kommentare, Jungs! Ich verwende einen Nordic nrf51822, der mit 16 MHz arbeitet - also sollte ich eine Genauigkeit von bis zu ~ 62,5 ns haben, allerdings nur, wenn das, was ich versuche, in 1 Anweisung erreicht werden kann (was das Lesen ... möglicherweise kann ?) Ich werde einen Interrupt einrichten und die Verarbeitung später versuchen, damit die Schleife nicht durch das Senden der UART-Nachricht verlangsamt wird. Ich werde auch sehen, ob es lokale Hackerspaces oder etwas gibt, das ein Oszilloskop haben könnte ...
@ChrisStratton, ich kann noch einen Logikanalysator ausprobieren, aber ich bin ziemlich zuversichtlich, dass das auf diesem Chip verwendete Protokoll proprietär ist. Nachdem ich mir die PS/2-Spezifikation angesehen habe, glaube ich nicht, dass sie auf diesem Chip implementiert werden würde - sie wurde von einer drahtlosen Maus entfernt, und das drahtlose Modul in der Maus kümmerte sich um die Kommunikation mit dem Host-Computer. Die Pinbelegung scheint dem ADNS2620 ähnlich zu sein, aber ich werde die PS/2-Spezifikation genauer durchsehen und sehen, ob es möglich ist.
Eigentlich wäre es ganz logisch, dass eine kabellose Maus intern PS/2 ist. Dadurch können sie einen alltäglichen kabelgebundenen Mauschip und einen separaten Funk-/MCU-Chip verwenden, wobei keines der Teile kundenspezifisch / spezifisch für diesen Zweck sein muss, was dazu beitragen kann, die Kosten niedrig zu halten.
@Helpful - Kaufen Sie tatsächlich einen billigen Login-Analysator wie diesen ebay.com/itm/… und er wird Ihnen sehr helfen
@PeterJ, das reizt mich ehrlich gesagt ziemlich - der Versand schreckt mich ab, bis dahin bin ich aber mit der Schule sehr beschäftigt. :/ Ich schätze den Rat!

Antworten (2)

Wie Chris Stratton in seinen Kommentaren zur anderen Antwort angegeben hat, müssen Sie die Funktionsweise Ihrer Software ändern.

Es gibt zwei Möglichkeiten:

Option 1:
Ausführen in einer engen Schleife, Abfragen der Pins und Aufzeichnen eines Zeitstempels in einem Puffer, wenn sie ihren Status ändern. Wenn sich der Wert nicht geändert hat, tun Sie nichts.
Sobald der Puffer voll ist, geben Sie die aufgezeichneten Zeiten über die serielle Verbindung aus.

Option 2:
Verwenden Sie die seriellen und Taktleitungseingänge als Interrupts. Wenn sich die Pins ändern, wird ein Zeitstempel für den Übergang und den neuen Zustand des Pins in einen Puffer aufgenommen.
Lassen Sie eine Hintergrundschleife die protokollierten Daten an die serielle Schnittstelle senden, um so gut wie möglich mit den Daten Schritt zu halten, während angezeigt wird, ob der Puffer übergelaufen ist.

Beide lösen das große Problem, dass Sie versuchen, serielle Daten aus einem zeitkritischen Codestück auszugeben, printf ist langsam und serielle Ports laufen in einem rasanten Tempo, tun Sie sie niemals in einem Codeabschnitt, den Sie benötigen schnell laufen. Option 1 ist einfacher und wird wahrscheinlich mit etwas höheren Frequenzen zurechtkommen, nimmt aber nur so lange auf, wie Sie Platz zum Puffern haben, und könnte möglicherweise zwei sehr nahe beieinander liegende Kanten als in der falschen Reihenfolge melden. Option 2 gibt während des Betriebs aus und sollte daher länger laufen können (ob es 1 Kante mehr ist oder mithält und undefinierbar läuft, hängt von den Geschwindigkeiten der Kanten und der seriellen Schnittstelle ab), hat aber aufgrund des Interrupt-Overheads eine niedrigere Spitze Geschwindigkeit und ist komplexer zu codieren.

Die andere offensichtliche Lösung besteht darin, ein Oszilloskop oder einen Logikanalysator von jemandem zu leihen / zu mieten.

Ich markiere dies als akzeptierte Antwort, da es sinnvoll ist - ich hatte den Verdacht, dass das UART-Debugging ewig dauerte. Glaubst du, ein Array wäre ein Puffer, der schnell genug ist, oder sollte ich einfach einige bitweise Operatoren mit einem uint64_t oder so verwenden?
Ein uint32_t-Array sollte in Ordnung sein. Sie können einen Timer verwenden, um Ihnen die aktuelle Zeit als 32-Bit-Wert zu geben, der ziemlich schnell zu lesen sein sollte. Abhängig von der verwendeten Zeitauflösung können Sie möglicherweise das oberste Bit des 32-Bit-Werts verwenden, um die Richtung darzustellen.
Denken Sie darüber nach, wenn Sie die Polarität der Uhr kennen, dann können Sie einen Interrupt setzen, um die Daten an der entsprechenden Flanke der Uhr zu lesen und nur das zu protokollieren. Das würde Ihnen nicht das Timing geben, aber die gesendeten Daten in einer sehr kompakten Form. Und verwenden Sie niemals 64-Bit-Werte in einer 32-Bit-CPU, es sei denn, Sie müssen es unbedingt tun.

Der NRF51822 verwendet einen ARM Cortex M0, der für Ihre Erfassungsaufgabe einzigartig ungeeignet erscheint. Der Cortex M0 verwendet alles von 1-4 Zyklen für die grundlegenden Anweisungen und viel länger, wenn Sie Dinge wie Multiplizieren verwenden. Der Prozessor kann nicht innerhalb einer grundlegenden Befehlsdecodierung unterbrochen werden.

Wenn Sie Daten erfassen möchten, wäre es mit einem kleinen 8-Bit-1-Zyklus-Prozessor wie dem ATMega328 viel besser. Sie sollten in der Lage sein, einen $ 3 Arduino Nano zu verdrahten, um die Daten zu serialisieren und über die serielle Schnittstelle auszugeben.

Da das Protokoll synchron ist, sollten Sie die SPI im Slave-Modus verwenden können, um die Daten zu empfangen. Sie sollten Nick Gammons hervorragende Berichterstattung über SPI lesen , um loszulegen.

Wenn Sie einen SPI-Slave verwenden, müssen Sie effektiv alle 8 Zyklen Ihrer Geräteuhr 8 Bits in die UART-Warteschlange stopfen. Denken Sie daran, dass diese Erfassungsmethode keine Lücken (ohne Takte) erfasst. Sie erhalten also einen dichten Dump (keine Leerzeichen) der Daten.

Um zu verstehen, warum der ARM Cortex M0 entweder bei Interrupt-Geschwindigkeit oder Bit-Bashing-Ports schlecht ist, lesen Sie this und this .

Das ist ein höchst irreführender Rat. Die CPU sollte schnell genug sein, wenn der Code intelligent geschrieben ist. Das Problem besteht darin, dass das Poster versucht, eine druckbare Ausgabe in Echtzeit zu erzeugen - das und der USB-Backup begrenzen die Abtastrate in der Größenordnung von tausend pro Sekunde. Mit ein wenig Sorgfalt ist eine 100-fache Geschwindigkeit wahrscheinlich ohne Änderung der Hardware erreichbar. Das heißt, wenn das BLE-Soft-Gerät oder ein Äquivalent oder ein anderer Planer oder Interrupts ausgeführt werden, werden sie Pausen in der Abtastung einschließen.
@ChrisStratton. Ich habe meiner Antwort einiges hinzugefügt, aber ich stehe zu der Tatsache, dass der M0 kein guter Prozessor für das ist, was der Op tun möchte. Wir haben auch keine Ahnung, was NordicSemi bei der Verwendung der M0-IP geändert oder modifiziert hat. Haben sie eine versiegelte Implementierung verwendet oder hatten sie eine Volllizenz und haben ihre eigenen Ergänzungen eingeführt?
Wenn das Poster den Unterschied zwischen 100 KSPS und 1 MSPS hervorheben würde, könnten Sie Recht haben - aber bei 1 KSPS ist das Problem nicht die Chipauswahl, sondern eher ein schlecht gestaltetes Programm und Berichtsschema. Es ist ein wirklich armer Programmierer, der auf neuer Hardware besteht, um einen eklatanten Software-Designfehler zu beheben.
@ChrisStratton. Da das OP keine einzige Codezeile bereitgestellt hat, ist es schwierig, seine Softwarefähigkeiten zu beurteilen. Jeder anständige Hardware-Ingenieur würde jedoch wissen, dass der M0 für diese Art von Aufgabe eine schlechte Wahl war. ....Wenn Sie MEINE Fähigkeit zu programmieren ausprobieren, dann ist das anders. Ich würde damit beginnen, sowohl die Software- als auch die Hardwarebeschränkungen des Prozessors zu verstehen, den ich verwenden möchte. Aber vielleicht sind Sie anders und würden Hardwarebeschränkungen nie in Betracht ziehen.......
Der M0 sollte in der Lage sein, etwa das 100-fache der Leistung zu erreichen, die das Poster erreicht hat. Die allgemeine Form des Grundes, der nicht realisiert wird, ist in der Frage und etwas, auf das ich bereits hingewiesen habe, offensichtlich: Der Versuch, zum Zeitpunkt der Probennahme eine serielle Ausgabe zu generieren, anscheinend in menschenlesbarer Form, pro Probe . Was sie tun sollten, ist eine kurze, schnelle, getriggerte Erfassung in einem Speicherpuffer, um ein Gefühl für das Timing zu bekommen, und dann dieses Verständnis zu verwenden, um Wörter einzutakten, die an der richtigen Flanke des bereitgestellten Takts abgetastet wurden.
Dies hat mir geholfen, einige der Geschwindigkeitsbeschränkungen zu verstehen, daher schätze ich den Rat - ich habe entwurzelt, obwohl ich eine andere als akzeptierte Antwort gewählt habe. Vielen Dank für Ihre Anregungen!