OK, der Betreff mag verwirren, mein Problem ist folgendes: Ich bekomme seriell 16-Bit-Daten in einem sehr eigenwilligen Format gesendet. Faktisch sieht es so aus, dass 20 Bit übertragen werden, darin sind 3 zu ignorierende sowie ein Prüfsummenbit enthalten. Das Ende eines solchen Frames wird über einen Puls auf einer Sync-Leitung gekennzeichnet und jedes Bit wird über eine Clock-Leitung mit jeweils einer fallenden Flanke als gültig markiert. Ich suche jetzt eine preiswerte Lösung, dieses Signal zu decodieren und die 16 Bit Nutzlast in einen Analogwert umzuwandeln. Das Empfangen und der DAC sind kein Problem. Wo ich jetzt Ideen benötigen würde, wäre der Teil mit der Decodierung: wie macht man das am cleversten und preiswertesten? Ach ja, Datenleitungen (also die, auf denen die Datenbits übertragen werden) gibt es drei Stück. FPGA-Programmierung kann ich gar nicht, C/C++ und ähnliches ist hingegen kein Problem. Der Clock läuft mit 2 MHZ, es kommen als 100000 Datenpakete pro Sekunde rein. Ich bin für jeden Denkanstoß dankbar :-)
Hm, bei 20 Datenbits ist es ein bisschen blöd mit Hardware-SPI-Empfang, können meist nur vielfache von 8bit. Könnte man per Software-SPI machen, Interrupt auf fallende clk-Flanke, Daten sortieren, per Hardware-SPI auf den D/A-Wandler. Da fängt aber rel. schnell an, CPU-Takte zu zählen, sollte aber mit nem 16MHz-AVR machbar sein. Reine (einfache) Hardware wäre auch denkbar, wenn die Daten in einem sinnvollen Format vorliegen (24bit-Schieberegister, 16bit-parallel-D/A-Wandler an die passenden Ausgänge anschliessen, Übernahme mit dem Synch-Signal.
@ H.Joachim Da dürften die AVRs bis 20 MHz mächtig ins Schwitzen kommen. Flanke detektieren, Wert speichern und schieben, Prüfbits auswerten, gelegentlich D/A-Wandler (???) programmieren. Und das während 10 Tacktzyklen...
H.Joachim Seifert schrieb: > Hm, bei 20 Datenbits ist es ein bisschen blöd mit Hardware-SPI-Empfang, > können meist nur vielfache von 8bit. Das würde ich so nicht unterschreiben. Zumindest bei Atmel im SPI-Slave-Modus wird der SPI-Interrupt sowohl ausgelöst, wenn das Schieberegister "voll" ist, als auch wenn SS high geht. Somit gäbe es hier schon schön alle 8 bit sowie am Ende der Übertragung (Sync-Leitung auf SS) einen Interrupt. So ein xMega A1 oder A3 bietet schon von Haus aus 4 SPI-Interfaces und interne 32MHz, womit ggüber den 3x2MHz (+output) noch einiges an Luft bleibt, insbesondere da der komplette Empfang bis auf gelegentliches Empfangsregister kopieren in Hardware geschieht. Eventuell könnte hier durch Nutzung des DMA-Controllers nochmal Rechenzeit gespart werden. Aber so wie ich den OP verstehe geht es ihm nicht um den Empfang, sondern um das dekodieren des ganzen. Es wäre schon einmal interessant, wo sich das Prüfsummen- und die zu ignorierenden Bits befinden. Sind das die vier letzten, oder ist das erste Byte nur zur Hälfte Nutzdaten? Leider hast du auch nicht verraten, wie dein DAC seine Daten gerne hätte. Sofern dir hier eine Auflösung von 12bit reicht, könntest du auch gleich die im XMega nehmen, der hat 2 DAC mit je 2 Buffern (also 4 Kanäle), jeder DAC kann 1MSPS bei von dir geforderten 0.1MSPS pro Kanal.
Moritz A. schrieb: > Aber so wie ich den OP verstehe geht es ihm nicht um den Empfang, > sondern um das dekodieren des ganzen. Mit Empfang meine ich den elektrischen Teil, d.h. das Signal von der Leitung popeln und in einen Logikpegel für die CPU umwandeln. Das Einlesen dieser Signale hätte ich jetzt schon bei "decodieren" eingeordnet. > Es wäre schon einmal interessant, wo sich das Prüfsummen- und die zu > ignorierenden Bits befinden. Sind das die vier letzten, oder ist das > erste Byte nur zur Hälfte Nutzdaten? Die drei zu ignorierenden Bits liegen vorne, das Prüfsummen- bzw. Paritätsbit kommt zum Schluss. > Leider hast du auch nicht verraten, wie dein DAC seine Daten gerne > hätte. Sofern dir hier eine Auflösung von 12bit reicht, könntest du auch > gleich die im XMega nehmen, der hat 2 DAC mit je 2 Buffern (also 4 > Kanäle), jeder DAC kann 1MSPS bei von dir geforderten 0.1MSPS pro Kanal. Nö, es muss schon ein 16Bit DAC sein, d.h. so wie ich das bisher sehe, müssen für jeden Zyklus 24 Bit in selbigen geschoben werden (zumindest habe ich bisher keinen reinen 16-Bit-DAC gefunden, der nicht zusätzlich noch ein paar Steuerbits haben will und nicht horrend teuer ist).
Um ehrlich zu sein, dann sehe ich da das riesige Problem nicht. Nutze wie beschrieben 3xHardware-SPI für die Eingänge, shifte die Daten passend zurecht, und schicke das ganze zum Hardware-SPI raus. Wenn du für das ganze jetzt die vier DMA-Kanäle mit entsprechendem Source/Destination-Increment verwendest, brauchst du wohl neben der Initialisierung nur noch 4 Interrupt-Routinen die dir mitteilen wenn einer der vier DMA-Transfers fertig ist. Somit hast du das Lesen von dreimal je 3Byte sowie verschicken von 3x3=9Byte komplett asynchron aufs DMA ausgelagert, und brauchst nur noch passende Statusflags in deiner main ob neue Daten ankamen, musst da die Daten evtl. überprüfen und dann passend für den DAC bereitmachen. Sinnvollerweise würde ich für den Ausgang den Speicher doppelt vorhalten, eine Region zum darauf arbeiten und auf der anderen arbeitet der DMA-Controller. Damit kann es dir nicht passieren, dass du gerade im Senden befindliche Daten aus versehen bearbeitest.
Die Frage mag jetzt vieleicht zwar dumm klingen, denn so ein Parity-bit wird ja nicht nur zum Spaß übertragen... Soll das Parity-bit ausgewertet werden? Und wenn ja: Gehören die zu ignorierenden 3 bits mit zur Berechnung dessen? Was soll passieren wenn ein Paritätsfehler auftritt? Frame einfach verwerfen und gut ist?
Moritz A. schrieb: > Um ehrlich zu sein, dann sehe ich da das riesige Problem nicht. > > Nutze wie beschrieben 3xHardware-SPI für die Eingänge, shifte die Daten > passend zurecht, und schicke das ganze zum Hardware-SPI raus. Ich sehe das Problem im Sync-Signal. Bei SPI ist dieses während der ganzen übertragung aktiv, richtig? In dem Fall ist das Sync aber nur auf das letzte Bit aktiv, es ist halt wirklich ein Synchronisationsignal und nicht wie bei SPI ein Schreibsignal.
Bernhard F. schrieb: > Was soll passieren wenn ein Paritätsfehler auftritt? Frame einfach > verwerfen und gut ist? Ja
Kirkenes schrieb: > Ich sehe das Problem im Sync-Signal. Bei SPI ist dieses während der > ganzen übertragung aktiv, richtig? In dem Fall ist das Sync aber nur auf > das letzte Bit aktiv, es ist halt wirklich ein Synchronisationsignal und > nicht wie bei SPI ein Schreibsignal. Du musst aufpassen, was Aktiv heißt. CS ist Aktiv-Low. Ich verstand das Ausgabeformat so, dass die Quelle immer 20 Bit schickt, und daraufhin Sync einmal hoch-pulst. Wenn keine Daten kommen, steht auch die Clock-Leitung still. Ansonsten ließen sich ja keine Daten nicht von Null-Daten unterscheiden. Was passiert bei SPI? Für eine Übertragung wird CS Low-gesetzt, über MOSI/CLK die Daten auf die Taktflanken synchronisiert ausgegeben, am Ende der Übertragung wird CS High gezogen. Also entspricht das ganze wirklich 1:1 SPI, auch wenn die Daten anders heißen. Falls Sync wirklich mit dem letzten Bit und nicht erst danach hochgeht, lässt sich hier über ein Schieberegister (74HC4015 o.ä.) an der Clock-Leitung die Weitergabe des Sync-Impulses wunderbar um ein Takt verzögern.
:
Bearbeitet durch User
Da ich ein PSoC-Fan bin, wuerde ich einen PSoC verwenden, und dort in der erhaltenen programmierbarne Logik das Schiebe-Register (mit sync - Signal) implementieren. PSoC 3 oder 4 reicht wahrscheinlich, die PSoC 4 sind gerade sehr guenstig. Andreas
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.