Jump to content

18F4550 Silicon Bug?


pico
 Share

Recommended Posts

Hallo,

ich arbeite zur Zeit mit dem PIC18F4550 an eine USB Midicontroller/Schnittstelle.

Ich habe im Vorfeld die Problem mit diesen PIC gelesen.Das er beim senden einfach Zeichen

auf die Schnittstelle packt.

Trotzdem habe ich es ausprobiert und bis jetzt habe ich noch keine Probleme mit dem Senden

gehabt. (Teste seit 3 Wochen)

Ich vermute das der SiliconBug von Microchip behoben wurde ohne eine neue Rev. anzulegen.

Da sie diesen Bug ja auch nicht dokumentiert haben.

Den PIC habe ich direkt von Microchip als Samples bekommen.

MfG

Pico

 

Link to comment
Share on other sites

Hallo Pico,

nein, der Bug existiert nach wie vor, er tritt jedoch nur unter bestimmten Umstaenden auf. Der Code, den ich im Microchip Forum gepostet habe, provoziert den Fehlerfall indem kuenstliche Delays zwischen Empfangen und Senden eines Bytes eingefuegt werden.

Wenn Du das Interface nur in einer Richtung testest, wird der Fehler niemals auftreten. Mach mal einen Hardware-Loopback (MIDI Out->MIDI In) und sende einen laengeren Sysex Stream (bspw. aus 1500 Bytes), der keine 00-en enthaelt. Wenn Du diesen String nun 20..30 mal sendest, kann es passieren, dass 1 oder 2 zusaetzliche Bytes gesendet werden, und zwar 00en (die ja eigentlich nicht im SysEx Dump enthalten sind).

Wenn Du Glueck hast, wird der Fehler auch nicht auftreten - es haengt von der USB Firmware ab. Wenn Du dann an irgendeiner sensiblen Stelle (bspw. im Interrupt Handler) ein paar zusaetzliche Befehle einfuegst, wird er wieder auftauchen.

Oder wenn Du mit einem anderen MIDI Interface, einen anderen Computer oder ae. Daten austauschst, koennte der Fehler ebenfalls auftauchen

Was mich interessieren wuerde (es geht hier um ein anderes undokumentiertes Problem mit "blocked pipes"): ist es mit Deiner USB Firmware moeglich, groessere SysEx Dumps mit Bloecken >10000 Bytes (zwischen F0 und F7) ueber den oben beschrieben Hardware-Loopback ohne Datenverlust zu uebertragen?

Gruss,

        Thorsten (aus einem Internetcafe in Mailand ;-)

Link to comment
Share on other sites

Hallo Thorsten,

ich habe meine Examensarbeit mit dem PIC18F4550 und USB gemacht...

Was mich interessieren wuerde (es geht hier um ein anderes undokumentiertes Problem mit "blocked pipes"): ist es mit Deiner USB Firmware moeglich, groessere SysEx Dumps mit Bloecken >10000 Bytes (zwischen F0 und F7) ueber den oben beschrieben Hardware-Loopback ohne Datenverlust zu uebertragen?

Geht es Dir hierbei um Senden über USB oder um die serielle Schnittstelle?

Falls USB:

Mir sind eigenartige Effekte aufgefallen gerade in Hinsicht auf Daten Senden in Verbindung mit IRQ's. Waren IRQ's während der Übertragung erlaubt, fehlte hin und wieder etwas... (USB-Framework von Microchip und C18-Compiler). Ich habe das allerdings nicht als MIDI-Geräteklasse gemacht, sondern einfach nur für Datenblöcke...

Frage 2: was sind "blocked pipes"?

auf jeden Fall kennt Microchip schon eine Menge Silicon Bugs..., fast zuviele meines Erachtens *g*

Viele Grüsse, Claudio

Link to comment
Share on other sites

Hallo Claudio,

"pipes" sind die logischen Datenpfade zwischen USB host und slave, jeder "Endpoint" bietet zwei Pipes, eine fuer eingehende, eine andere fuer ausgehende Daten.

Mir sind eigenartige Effekte aufgefallen gerade in Hinsicht auf Daten Senden in Verbindung mit IRQ's. Waren IRQ's während der Übertragung erlaubt, fehlte hin und wieder etwas... (USB-Framework von Microchip und C18-Compiler)

es koennte sich hier um den gleichen Effekt handeln, er hat jedoch nichts mit Interrupts zu tun - ich habe die USB Firmware ja mittlerweile komplett in Assembler programmiert, nicht zuletzt, um vom C18 loszukommen (dessen Demo-Lizenz nach 3 Monaten ausgelaufen war), und natuerlich um die Performance zu verbessern.

Nach wie vor koennen jedoch Daten verloren gehen, wenn die OUT pipe nicht sofort bedient wird, und etwas durch die IN pipe geschickt werden soll. Die IN pipe ist manchmal (schlecht reproduzierbar) fuer > 40 mS blockiert, dies fuehrt dann zu einem Buffer Overrun auf der Empfangsseite der MIDI Schnittstelle. Das alles laesst sich sehr einfach mit einem Oszilloskop debuggen, wenn man die EP*B*.UOWN flags auf IO pins legt, und sich eine Triggerbedingung schafft (Buffer Full) - dadurch kann ich auch einen Softwarefehler ausschliessen.

Leider tritt der Effekt auch dann auf, wenn OUT und IN pipe auf verschiedene Endpoints liegen. Ob es mit dem Ping Pong Modus besser funktioniert, weiss ich nicht (ist mir zu umstaendlich, und hilft wahrscheinlich nicht weiter). Der einzige Workaround, der mir bisher eingefallen ist, waere die Programmierung eines neuen USB MIDI Drivers fuer Windows, der dieses Szenario vermeidet, und hierum kuemmert sich gerade Synapsys.

Ich bin mir nicht 100% sicher (da ich auch nicht unnoetig viel Aufwand ins Debuggen stecken moechte), aber es koennte sich hierbei entweder um ein undokumentiertes Performance Problem handeln, oder gar um einen weiteren Silicon Bug im USB Peripheral. Mit der EZ-USB basierenden MBHP_USB Firmware tritt dieses Problem naemlich nicht auf, selbst wenn die Buffer fuer die seriellen Schnittstellen nur 8 byte gross sind!

Hast Du die SysEx Transfers nun mal mit Deiner Firmware ausprobiert?

Gruss,

        Thorsten.

Link to comment
Share on other sites

Moin Thorsten,

"pipes" sind die logischen Datenpfade zwischen USB host und slave, jeder "Endpoint" bietet zwei Pipes, eine fuer eingehende, eine andere fuer ausgehende Daten.

*g*, jup, aber, "blocked" wunderte mich. 40ms sind natürlich eine recht lange Blockade im Verhältnis zum 1ms Framing. Ich habe mich mit der MIDI-USB Klasse noch nicht so wirklich auseinandergesetzt, daher hab ich die SysEx Geschichte noch nicht probiert. Im Laufe von 1-2 Monaten wird das aber auch noch akut werden für mich, je nachdem wie ich mit meinem Projekt vorankomme.

Aber Fragen weiter:

1. Wie gross sind die Datenpakete, die du sendest, in Bytes (also die Endpunktpuffer)?

2. Wieviele Pakete gehen pro Frame in welchem Modus (iso, bulk ... ) rüber?

3. Wird dein Gerät als Teil der MIDI-Geräteklasse verwendet?

Es klingt aber so, als ob das Problem tatsächlich auf der Controllerseite liegt. Hast du jemals unter Windows einen "Error 30" bekommen? Meines Wissens werden die Pipes unter Windows als Streams oder Filehandles gehandhabt. Bei mir brachten Versuche, 0 Bytes von der Hostapplikation aus der Pipe zu lesen (wenn eben keine Daten anlagen) einen Abriss der Verbindung oder erzeugten wahrscheinlich auf Kernelebene (da das System ausgelastet war) diese Timeouts. Auf dem Controller selbst hatte ich keine Probleme.

Nach wie vor koennen jedoch Daten verloren gehen, wenn die OUT pipe nicht sofort bedient wird, und etwas durch die IN pipe geschickt werden soll. Die IN pipe ist manchmal (schlecht reproduzierbar) fuer > 40 mS blockiert, dies fuehrt dann zu einem Buffer Overrun auf der Empfangsseite der MIDI Schnittstelle.

Abgesehen von der Control-Pipe (EP0) darf pro Endpunkt nur entweder IN oder OUT Übertragung aktiv sein. IN/OUT an einem Endpunkt geht eigentlich nicht?! Wie sieht denn dein Device Deskriptor dafür aus? (oder wo bekomme ich denn die aktuelle Firmware, an der du arbeitest?)

Das alles laesst sich sehr einfach mit einem Oszilloskop debuggen, wenn man die EP*B*.UOWN flags auf IO pins legt, und sich eine Triggerbedingung schafft (Buffer Full) - dadurch kann ich auch einen Softwarefehler ausschliessen.

Die UOWN Flags garantieren offenbar nicht, dass der Puffer nach Wechsel des Zugriffsrechts auch übertragen worden ist, das musste ich feststellen. Wie ich eine erfolgreiche Übertragung von der SIE überprüfe, hab ich noch nicht herausgefunden. Was sich mir auch nicht erklärt ist, wie ich abfange, dass -während- des Pufferkopierens an den EP* eben die UOWN Bits nicht gesetzt werden. Microchip lässt sich da nur sehr dürftig drüber aus...

Ist während des Timeouts denn generell gar keine USB Kommunikation mit dem Controller mehr möglich (hängt die SIE?)?

Vielleicht kommen wir ja weiter :)

Viele Grüsse, Claudio

Link to comment
Share on other sites

1. Wie gross sind die Datenpakete, die du sendest, in Bytes (also die Endpunktpuffer)?

die Anzahl der Buffer, sowie die Puffergroesse habe ich flexibel gehalten.

Ich habe verschiedene Konfigurationen ausprobiert, momentan verwende ich

folgende Einstellungen (in usbcls.asm)

  o 4 IN Buffer je 64 Bytes, Transferlaenge 64 Bytes

  o 2 OUT Buffer je 64 Bytes, Transferlaenge jedoch nur 8 Bytes

Die Buffer koennen noch waehrend eines laufenden Transfers vorbereitet/abgearbeitet werden - das steigert vor allem auf der IN Seite die Performance. Die Pufferadresse wird von der Software gesteuert (kein Ping Pong Modus)

Die Transferlaenge (welche im Endpoint Descriptor definiert ist -> usbdsc.c) habe ich reduziert, da hiermit der besagte Effekt im Loopback seltener auftritt (ich habe es einfach mal ausprobiert)

2. Wieviele Pakete gehen pro Frame in welchem Modus (iso, bulk ... ) rüber?

Die Zahl habe ich nicht mehr im Kopf, doch ich kann sie bei gelegenheit ermitteln. USB MIDI unterstuetzt nur Bulk Transfers

3. Wird dein Gerät als Teil der MIDI-Geräteklasse verwendet?

Denke schon, Windows ist nicht so mein Thema. ;-)

Es klingt aber so, als ob das Problem tatsächlich auf der Controllerseite liegt. Hast du jemals unter Windows einen "Error 30" bekommen? Meines Wissens werden die Pipes unter Windows als Streams oder Filehandles gehandhabt. Bei mir brachten Versuche, 0 Bytes von der Hostapplikation aus der Pipe zu lesen (wenn eben keine Daten anlagen) einen Abriss der Verbindung oder erzeugten wahrscheinlich auf Kernelebene (da das System ausgelastet war) diese Timeouts. Auf dem Controller selbst hatte ich keine Probleme.

das klingt interessant! Gibt es unter Windows so etwas wie /var/log/messages unter Unix, also ein systemweites Logfile, in dem solche Ereignisse hinterlegt werden?

Abgesehen von der Control-Pipe (EP0) darf pro Endpunkt nur entweder IN oder OUT Ãœbertragung aktiv sein. IN/OUT an einem Endpunkt geht eigentlich nicht?!

Das wuerde mich wundern, denn mit dem EZ-USB funktioniert diese Konfiguration problemlos.

Steht das irgendwo in der USB Spec?

Vor ein paar Tagen hatte ich mal temporaer die Konfiguration "IN auf EP1, OUT auf EP2" ausprobiert, der IN Buffer wurde weiterhin sporadisch (ohne erkennbares Schema) blockiert.

Wie sieht denn dein Device Deskriptor dafür aus? (oder wo bekomme ich denn die aktuelle Firmware, an der du arbeitest?)

Ich habe mal einen aktuellen Snapshot nach http://www.ucapps.de/tmp/mbhp_usb_pic_snapshot.zip gelegt.

Der interessante Code steht unter usbcls.asm und usbdsc.c

Die UOWN Flags garantieren offenbar nicht, dass der Puffer nach Wechsel des Zugriffsrechts auch übertragen worden ist, das musste ich feststellen. Wie ich eine erfolgreiche Übertragung von der SIE überprüfe, hab ich noch nicht herausgefunden. Was sich mir auch nicht erklärt ist, wie ich abfange, dass -während- des Pufferkopierens an den EP* eben die UOWN Bits nicht gesetzt werden. Microchip lässt sich da nur sehr dürftig drüber aus...

Ich sehe die UOWN Bits als Semaphore fuer den RAM Bereich: wenn beim OUT Buffer UOWN geloescht ist, weiss man, dass ein neues Packet angekommen ist. Man holt es sich ab, und setzt das Flag wieder (+ DTS Handshake).

Beim IN Buffer geht man davon aus, dass er beschrieben werden darf, solange UOWN geloescht ist. Die SIE wird solange nicht darauf zugreifen, bis man UOWN wieder setzt.

Solange man also die Regeln einhaelt, auf den Memory Bereich niemals zu schreiben, wenn UOWN gesetzt ist, und UOWN niemals via Software zu loeschen, kann nichts schieflaufen.

Ist während des Timeouts denn generell gar keine USB Kommunikation mit dem Controller mehr möglich (hängt die SIE?)?

Scheinbar, ansonsten wuerde die Uebertragung ueber einen anderen EP funktionieren.

Vielleicht kommen wir ja weiter

Es ist immer gut, wenn man mal darueber spricht :)

Gruss,

        Thorsten.

Link to comment
Share on other sites

Moin Thorsten,

also das dauert jetzt n bisschen, in die Tiefe zu gehen, aber vorab als Info:

das klingt interessant! Gibt es unter Windows so etwas wie /var/log/messages unter Unix, also ein systemweites Logfile, in dem solche Ereignisse hinterlegt werden?

Ich bekomme den Fehler nur über die Windows API "GetLastError()" heraus. Das wird leider nicht geloggt. Error 30 bedeutet soviel wie Gerät fehlerhaft oder so ähnlich (es gibt da auch ne Klartext-Funktion für...). Unter Windows98 äusserte es sich immer bei solchen Übertragungsfehlern, bei Win32 kam die Meldung trotz Fehlers nicht immer... warum weiss ich nicht.

GetLastError ist der Status des letzten Windows-API Aufrufs.

(Herkunft des Ganzen: http://www.hep.princeton.edu/~tziegler/electronics/microchip/_mpusbapi.cpp)

Das wuerde mich wundern, denn mit dem EZ-USB funktioniert diese Konfiguration problemlos.

Steht das irgendwo in der USB Spec?

Hmm, ich hab das in der Spec 1.1: http://www.usb.org/developers/docs/usbspec.zip

auf Seite 203 nach Tabelle 9-10 so verstanden, dass das durch ein Bit gekennzeichnet wird, ob es IN oder OUT ist am Endpunkt. Dieses Bit wird beim Control-Transfer ignoriert (so auch an EP0, da gibts keinen Deskriptor für). Die Deskriptoren werden ja nur einmal beim Anmelden des Gerätes ausgelesen... Allerdings ist das der "Standard"-Deskriptor, whatever... darüber bin ich nicht hinausgekommen. Bei "bulk" dürfte das also eigentlich nicht funktionieren?!?

Alles weitere hoffentlich später :)

Viele nachtschlafene Grüsse, Claudio

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...