Hallo, ich habe ein riesen Problem und brauch schlaue Ideen. Ich habe folgendes vor: Von einem FPGA (voraussichtlich Altera CycloneII oder III) soll ein serielles Signal synchron auf viele (bis zu über 30!) dsPIC Controller gebracht werden und von diesen weiter verarbeitet werden. Auch der Takt der dsPIC soll mit dem FPGA synchronisiert sein. Jetzt wird's tricky: alle dsPIC müssen sowohl untereinander als auch zum FPGA galvanisch getrennt sein. Einfache Optokoppler reichen auf grund des zu großen du/dt nicht aus. Die Übertragungsstrecke soll daher mit LWL Verbindungen realisiert werden. Die Datenrate soll deutlich über 1Mbit liegen. Bisher habe ich folgenden Ansatz verfolgt: Datenübertragung via SPI-Schnittstelle des dsPIC (Slave Mode, bidirektional). Das SPI-Clock Signal wird auch als Taktsignal für den gesamten Controller verwendet. Daher muss es permanent anliegen. Um eine 4. (bzw. insg 30) LWL Verbindung (für den Slave-Select)zu sparen habe ich mir überlegt die Pulsweite des Taktsignals (5 MHz!, also Datenübertragung mit 5Mbaud) zu Modulieren, und via Input-Capture --> DMA-Controller --> Output-Compare mir ein Chip-Select daraus zu gewinnen. Das hat auch soweit alles geklappt bis auf eins: Der Ausgang des Output Compare Moduls des dsPIC wird auf die Änderung des Timer-Registers TMR3 (oder 2, habe in diesem fall TMR3) synchronisiert. D.h. wenn ich den Timer wie geplant stehen lasse und in TMR3 den Referenzwert schreibe um den Wert der aktuellen Pulsbreite via DMA in das OC1R Register zu schreiben, passiert am Ausgang einfach nichts. Leider kann ich das nicht umgekehrt machen da sich TMR3 nicht via DMA schreiben lässt. Auch kann ich den Timer nicht einfach laufen lassen und so einstellen dass er nur ein kleines Stückchen zählt (oder gar auf der stelle tritt), da er keine Auto Reload Funktion hat. - Controller ist der dsPIC33FJ128MC804 - Taktung: EC Mode, PLL so eingestellt dass sich 40 MIPS bei 5MHz ergeben - daher zählt Timer2 auf 8 (0..7) und Input Capture erfasst bei neg. Flanke - der Timer2 ist mit seinem Reset auf die pos. Fl. des Takts synchronisiert - DMA Channel 0 nimmt IC1BUF und schreibt es in den RAM - DMA Channel 1 nimmt die Daten aus dem RAM und schreibt sie in OC1R - Entwicklungsumgebung MPLAB IDE v8.84 / Real ICE - Pulserzeugung zu Testzwecken mit einem Cyclone 1; 1,25..5 MHz; - Pulsbreite und Takt vom PC aus einstellbar. Das funktioniert alles soweit. Mit Real ICE zeigt sich dass alles da ankommt wo es hin soll. Aber der Output Compare gibt's nicht raus an den Pin (der mit dem Slave-Select verbunden ist). Wenn ich den Vergleich mit der CPU mache und mir auf einen Port mit LED gebe, dann funktioniert alles. Das ist jedoch im Betrieb leider absolut unmöglich, da ich nicht jeden 8. Maschienenzyklus einen vergleich mit der CPU machen kann, ich will ja auch noch was rechnen. Außerdem wäre die Verzögerung quasi willkürlich was eine Datenübertragung quasi unmöglich machen würde. Ich habe keine Lust das ganze Projekt in die Tonne zu klopfen (steckt Wochenlange Arbeit drin) und mit einem anderen Controller oder zusätzlicher externer Hardware (wofür ohnehin kein Platz wäre) von vorne zu beginne, hat jemand eine Idee? Wie ich das glatt gebüglet bekomme?
Bei Deinem konkreten Problem kann ich leider nicht helfen (ist ja auch echt High-End, Respekt!). Aber vielleicht wäre das noch eine Idee: Ich kenne herstellerspezifische ASICs, bei denen das erste Byte eines SPI-Frames die Adresse des zu aktivierenden Bausteins enthält. Diese ASICs entscheiden beim Empfang des ersten Bytes on the flight, ob sie aktiv werden oder nicht. Das kann der dsPIC natürlich nicht (und auch kein anderer µC, den ich kenne). Eventuell könntest Du dem dsPIC noch einen kleinen CPLD spendieren, der etwas ähnliches macht, d.h. das erste Byte herausfiltern und je nach Inhalt das SlaveSelect des dsPIC aktivieren.
Die Idee ist schon mal garnicht so verkehrt. Ich hab auch schon in die Richtung gedacht. Bisher hab ich da nicht angesetzt weil zusätzliche Hardware viel Aufwand Bedeutet, neue Platine, evt. zu knapper Platz etc. Aber die Diskussion deiner Antwort mit einem Komilitonen hat mich auf eine neue Idee gebracht, also dafür schonmal danke. Folgendes habe ich mir überlegt: Da ich aufgrund der Potentialtrennung ohnehin zu jedem Controller eine extra Leitung habe brauche ich den Chip Select nicht um ihn tatsächlich zu adressieren, sondern "nur" um mitzuteilen wann Daten anliegen und das SPI Register shiften soll. Den Takt kann ich wie beschrieben ja nicht anhalten, da er auch den Prozessor taktet. Also, warum nicht permanent senden, und immmer wenn Nullen kommen ignorieren? Das kam bissher nicht in frage, weil dann ein einziger versehentlicher Shift (zuviel oder auch zu wenig)mir die Kommunikation komplett lahm legt. Die Worte würden alle verschoben ankommen, und wären nichtmehr zu gebrauchen. Wenn ich jetzt aber keine Nullen sondern eine feste, eindeutige Sequenz sende, solange ich keine Daten zu übertragen habe, kann ich anhand der Sequenz erkennen, ob etwas verrutscht ist, und es korrigieren. Wenn ich das ganze jetzt nicht mit dem dsPIC, sondern im FPGA detektiere und dann in einem Steuerwort dem dsPIC mitteile dass er verrutscht ist kann ich sogar synchronisationsfehler, die die CPU betreffen (wenn z.B. die PLL aus dem Takt geraten ist da eine EMV-Störung eine Flanke zu viel am OSC1 erzeugt hat) erkennen und korrigieren, und das ohne gleich alles notabschalten zu müssen (das ganze wird die Steuerung eines sehr Leistungsfähigen Stromrichters, da darf nichts verrutschen, sonst geht ganz schnell, ganz viel schwarzer Rauch auf!). Ich werde mal versuchen das Prinzip an meinem Testaufbau umzusetzten, falls jemand noch ne Idee/Tips hat, immer her damit. Auch wenn jemandem einfällt warum meine Idee in die Hose gehen könnte, einfach posten. Nochmal jede Menge Arbeit für die Tonne würde ich gerne vermeiden.
Willst Du denn auch Daten vom dsPIC zum FPGA zurücksenden? Falls nicht könnte ja auch jeder dsPIC einfach mithorchen und sich seine Pakete heraussuchen.
Zitat aus meinem letzten Post: Da ich aufgrund der Potentialtrennung ohnehin zu jedem Controller eine extra Leitung habe brauche ich den Chip Select nicht um ihn tatsächlich zu adressieren, sondern "nur" um mitzuteilen wann Daten anliegen Zitat Ende Mit Leitung meinte ich eine LWL-Strecke, also Sender, Faser und Empfänger. Ja ich will auch zurücksenden, dass ist aber egal, alle ~30 Controller können gleichzeitig Fullduplex kommunizieren. Es geht um die Synchronisierung der Schieberegister der SPI. Wenn die beiden Register im Sender und Empfänger nicht synchron shiften (also nicht nur zur geleichen Zeit um eins weiter, was die Taktleitung ja erledigt, sondern auch mit dem selben Puls ein Wort vollständig), dann geht das ganze schief, auch das reine Empfangen.
Du meinst, Du hast 30 Punkt-zu-Punkt-Verbindungen, aber Du hast keine separate SlaveSelect-Leitung dabei? Und Du willst SlaveSelect nicht permanent aktiv halten, weil Du Angst hast, die Synchronisierung zu verlieren?
Richtig. Aber ich habe nicht nur Angst die Synchronisierung zu verlieren, ich muss sie erstmal irgendwoher haben. Woher soll das Programm im dsPIC die Information nehmen, wann die SPI loslaufen kann? Er weiss ja nicht wann der Master (im FPGA realisiert) anfängt das Senderegister zu schiften. Genau das ist das Problem. Zitat: aber Du hast keine separate SlaveSelect-Leitung dabei? Und Du willst SlaveSelect nicht permanent aktiv halten,.... Zitat Ende. Normal braucht man den Slave-Select ja nicht für eine Punkt-zu-Punkt Verbindung, da das clock-Signal der SPI ja nur dann überhaupt auftritt, wenn das Master-Register geschiftet wird. Damit ist man sicher Synchron. Da ich mein Clock Signal aber auch als "Taktgeber" am OSC1 Pin verwende würde dann ja der ganze Controller stehen bleiben (bzw. nach einer Weile auf den internen Oszillator umschalten). D.h. mein Clock signal liegt permanent an. Ich bin im Moment aber ganz zuversichtlich dass mein neuer Ansatz (mit Muster-Sequenz) hinhaut.
Wäre eine Uart Verbindung für dich nicht vielleicht einfacher? Habe kurz ins Datenblatt des 128GP804 geschaut. Dort steht bis 10Mbaud auf der Uart allerding nur bei 40mips. Dann hättest du auch Fullduplex und deine Taktleitung ist unabhängig davon. Adressierung brauchste ja anscheinend eh nicht da du mit jedem separat kommunizierst und die Fehlererkennung mittels CRC-16 oder so. Ich habe jetzt nur nicht nachgeschaut ob der dsPIC sich die benötigten 40mips aus deinem 5Mhz Taktsignal mittels PLL generieren kann. Frage am Rande. Der Master also der FPGA gibt die Sollwerte an die dsPICs und diese Liefern die Messwerte zurück? Also die dsPIC steuern die Leistungshalbleiter oder habe ich das falsch interpretiert ?
Du hast richtig interpretiert: Aussteuergrade hin, Messwerte zurück. Wenn du meinen ersten Post ganz liest, dann stellst du fest, dass der dsPIC bei mir im Moment bereits mit 40MPIS aus den 5MHz läuft. Das geht also. Aber... nein, das kommt nicht in Frage. Im Moment ist eben genau dieses Verfahren im Einsatz (UART) und es funktioniert auch. Erfahrungsgemäß ist damit bei 1Mbaud Schluss (zumindest für diese Anwendung). Außerdem hat diese Vorgehensweise auf die eigentliche Anwendung ein paar negative Auswirkungen (neben der zu-viel-Zeit-raubenden Übertragungsdauer), die (wenn möglich) vermieden werden sollen. Darum dieses Redesign mit SPI. Mehr wie 5MBaud sind mit der Aktuell verwendeten LWL-Technik höchst warscheinlich nicht drin. Und die 10Mbaud im Datenblatt der dsPIC33F sind wohl auch eher als sehr optimistischer Wert anzusehen. Hmmm, aber... naja ich muss die UART Hardware ja nicht als UART verwenden... Danke für den Denkanstoß, mir kommen da ein paar Ideen... da muss ich nochmal drüber grübeln, bevor ich über ungelegte Eier gackere.
Also, ich habe das ganze jetzt so realisiert, dass der FPGA anhand der erwähnten Mustersequenz erkennt in welchem Zustand sich das SPI Modul im dsPIC befindet, und sich daran anpasst. Das funktioniert echt prima. Später werde ich das ganze noch so erweiteren dass der FPGA mit einem Steuerbefehl dem dsPIC mitteilen kann, wenn dieser "verrutschen" soll, und wohin er "rutschen" soll. Aber da ich das im Moment nicht brauche, bin ich erst mal zufrieden. Danke für die Vorschläge.
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.