Hallo, ich arbeite mich grade in den USB ein. Dazu verwende ich den PDIUSBD12 und Mega8. Die ersten Schritte der Enumeration macht der D12 bereits: BusReset GetDescriptor BusReset SetAddress Soweit sollte eigentlich alles stimmen. Aber danach macht mein D12 wieder ein BusReset anstatt mit der neuen Adresse den Deskriptor anzufordern. Hat einer eine Idee was da los ist? Kann ja eigentlich nur am Deskriptor selber liegen oder? Außerdem ist das eine Qual mit dem Debuggen. Ich sende mir die Daten über RS232 an den PC und schau sie mir dann da an. Aber irgendwie kommt da nicht immer alles an. Wie debuggt ihr eigentlich? Über LCD? Gruß Ralf
Welches Betriebssystem? Schreibst Du den Enumeration-Code selbst, oder benutzt Du fremden Code? Gruß Stefan Salewski
Hallo Stefan, ich nutze Windows 2000. Der Code läuft auf dem ATmega8 von Atmel und steuert einen PDIUSBD12. Die Software orientiert sich an dem Buch von J. Axelson bzw. dem Code von BeyondLogic.org (USB in a Nutshell) für einen PDIUSBD11. Bislang bin ich noch dabei die Firmware des Mikrocontrollers zum Laufen zu bringen. Unter Windows habe ich noch nichts programmiert. Soweit ich weiss kümmert sich der Host standardmäßig selber um die Kommunikation mit den Geräten - jedenfalls bis zur erfolgreichen Enumeration. Und genau da haperts. Gruß Ralf
Das ist das std. Verhalten wenn dein D12 gar nichts sendet. Win probiert dann alles mögliche um das Device doch noch irgendwie anzusprechen. Vermutlich geht schon dein erster GetDeskriptor(Device) nicht. Poste doch mal deinen Code. Thomas
hi, wärs möglich das du mir dein code schicken kannst? weil ich experementiere auch mit dem PDIUSBD12 und hab extreme problem den irgendwie zum laufen zu bekommen, das er überhaupt irgend etwas macht MFG Tom
Ich weiss leider nicht, wie ich hier Code hochladen kann (vlt. kann mir das ja jemand sagen), deshalb habe ich die Dateien auf meiner Seite hochgeladen: http://rahand.oyla12.de. Hier dann bitte unter 'Downloads' nachschauen. Ein Debug-Protokoll mit Anmerkungen von mir ist auch dabei. Die Dateien sind z.T. im .doc-Format. Das liegt an meinem Provider. Gruß Ralf
>Soweit ich weiss >kümmert sich der Host standardmäßig selber um die Kommunikation mit den >Geräten - jedenfalls bis zur erfolgreichen Enumeration. Ich kenne den PDIUSBD12 zwar nicht so genau, aber er ist doch wohl dem USBN9604 sehr ähnlich, den Benedikt Sauter für sein usbn2mc-Projekt eingesetzt hat. Bei dem USBN9604 und bei dem von mir verwendeten AT90USB geht praktisch nichts automatisch. Nach dem ersten Bus-Reset muss das Device gleich den Device-Descriptor schicken, dann kommt ein weiterer Bus-Reset und dann geht es munter weiter mit dem Senden der Descriptors. Wenn man da Unsinn oder gar nichts sendet macht der Host wieder einen Reset. Ich arbeite aber nur unter Linux, aber bei Windows ist das wohl ähnlich. USB Complete habe ich auch, ich finde aber das Buch von H.J.Kelm etwas übersichtlicher. Warum hast Du Dich gerade für den PDIUSBD12 entschieden? Kennst Du das Projekt von B. Sauter? Der hat mit dem USBN9604 ja schon sehr viel gemacht, teilweise auch unter Windows. Und mein Projekt mit dem AT90USB funktioniert (unter Linux) auch schon ganz gut, die Dokumentation ist nun auch fast fertig. Ach ja, Du hattest nach Debugging gefragt: Das mache ich auch über die serielle Schnittstelle. Auf meiner Platine habe ich einen Max232, und ich sende Debuggingausgaben dann an ein Terminalprogramm (minicon). Geht wunderbar. Beispiel Enumeration. Ich gebe den Standard-Request aus (8 Byte) der vom Host gesendet wird, und dann den Descriptor, den meine Firmware als Antwort sendet. So sieht man sofort, wenn etwas aufgrund eines Programmierfehlers schief läuft. Gruß Stefan Salewski
es ist eine schlechte idee 16bit Werte direkt in die Deskriptoren einzutragen. Je nach Compiler und Proz geht das schief. sizeof() funktioniert auch nicht immer. Diese Teile musst du in jedem Fall anhand des LST files prüfen. Thomas
@ Stefan: Das mit dem 'automatisch' war nicht so gemeint, dass ich den Controller anstöpsel und das wars dann. Es ist mir schon klar, dass In- und Out-Requests zu beantworten sind. Was ich meinte war, dass ich PC-seitig noch nichts programmiert habe. Bis zum Ende der Enumeration sollte dies meines Wissens auch nicht notwendig sein. @ Thomas: Das mit den 8- und 16-Bit-Werten muß ich mir im Einzelnen mal genau anschaun. Was mich nur wundert ist, dass laut meinem Protokoll der PC meinem Controller eine ID zuweißt. Und nach dem Setzen derselbigen wieder ein Reset kommt. Wenn ich also eine ID vom PC erhalte dann kann doch bis dahin nicht viel falsch sein, sonst würde er doch keine ID senden? Und sobald ich dann die ID setze kann doch kein Reset kommen, sondern dann folgt doch erstmal wieder das Einlesen der Deskriptoren, oder? Gruß Ralf
Schuß ins Blaue: Du darfst die zugewiesene Adresse nicht zu früh aktivieren. Die Status-Stage für den SET_ADDRESS Request muß noch auf Adresse 0 erfolgen. Erst nach Beendigung der Status-Stage darfst Du die Adresse aktivieren. Hast Du das bedacht?
>Wenn ich also eine ID vom PC erhalte dann kann doch bis dahin nicht viel >falsch sein, sonst würde er doch keine ID senden? Und sobald ich dann >die ID setze kann doch kein Reset kommen, sondern dann folgt doch >erstmal wieder das Einlesen der Deskriptoren, oder? Mit ID meinst du die neue Device-Adresse? Wenn Du die erhälst ist das schon mal gut. Ist Dir bewußt, dass du bestätigen musst, dass Du die neue Adresse erhalten hast, und dass Du erst nachdem dieses Bestätigungs-Handshake beendet ist die neue Adresse für Dein Gerät setzen darfst?
nein eine Device Addresse erhalten erst mal auch kaputte Geräte. Win wird die jedem Gerät erst mal zuzuweisen. Der Grund für dieses Verhalten liegt farin begründet, das zu Anfang oft kaputte Geräte am Markt waren. MS versuchte eben auch diese zu enumerieren. Erst wenn das Device auf der neuen Adresse nicht antwortet kommt der nächste Busreset und das ganze beginnt von vorne. Nach 3 Mal ist dann Schluss. Also nochmal: 1. die Deskriptoren sind im off 2. D12 sendet nichts 3. Die Status Stage für SetAddress ist falsch (Spec genau lesen!) Der erste GetDescriptor(Device) Request kommt mit wLenght 64! Der D12 hat glaube ich im ControlEP nur 8 oder 16 bytes Fifo. Auch wenn der Host 64 Bytes anfragt darf in der Data Stage nur max Fif0 Size bytes auf einmal gesendet werden. Thomas
Ich habe diese Ding mal zum laufen gebracht. Leider funktionierte die Initialisiereung nur unter Linux 2.4, später unter Windows oder Linux 2.6 nicht mehr. Wieso es nur unter Linux 2.4 funktionierte habe ich nicht weiter untersucht. Setzen der Adresse: // Adresse setzen usbWriteCommand(0xD0); // Set Address/Enable usbWriteData(Address | 0x80); // Adresse setzen // Packet mit der Länge 0 senden usbWriteCommand(0x01); // Endpoint wählen usbWriteCommand(0xF0); // Write usbWriteData(0); // Reserve usbWriteData(0); // Length usbWriteCommand(0xFA); // Validate
>Ich habe diese Ding mal zum laufen gebracht.
Für mich sieht das gerade falsch herum aus.
Wie René König ein paar Sekunden vor mir schrieb:
Die Status-Stage für den SET_ADDRESS Request muß noch auf
Adresse 0 erfolgen. Erst nach Beendigung der Status-Stage darfst Du die
Adresse aktivieren.
Hallo, es ist bei mir exakt so, wie Thomas sagt: 1. Setup-Token: es werden 64 Bytes angefragt -> gesendet werden 8. 2. In-Token: Es werden 10 Bytes angefragt (8+10 = 18 Größe des kompletten Deskriptors) -> gesendet werden 8. 3. Nun erfolgt der Reset. 4. Setup-Token: SetAddress wird angefordert -> ich schreibe Null-Byte und setze Flag. 5. In-Token: Da nun die Flag gesetzt ist -> zugewiesene Adresse setzen. Ab nun sollte er eigentlich über die neue Adresse den Deskriptor wieder anfragen (falls ich das richtig verstanden habe). Stattdessen kommt ein Reset und alles fängt von vorne an. Nach 3 mal ist Schluß. Im übrigen frage ich immer den LastTransactionStatus ab. Und der zeigt mir an, das die Packete immer angekommen sind ... mit einer Ausnahme: Bei dem In-Token unter Punkt 2 (der erste In-Token nach einem Reset) bekomme ich den Status, daß nichts angekommen ist. Aber ich denke, da es der erste In-Token ist, kann ja zuvor auch garnichts empfangen worden sein. Der Status (nichts empfangen) ist also richtig in dem Fall. Naja wie gesagt, das wird dann 3 mal durchlaufen und dann ist Schluß. Also ich werde jetzt, wie Thomas vorschlägt, nochmal die Spezifikation durchlesen. Falls jemand einen konkreten Vorschlag hat, um etwas gezielter nach dem Fehler zu suchen, dann immer her damit. Schönes Wochende, Gruß Ralf
Ich hab mir jetzt alles noch einmal angesehn und finde einfach keinen Fehler. Der Deskriptor ist ok. Die unsigned short Werte werden [LOW][HIGH]-Byte geschrieben. Wie ich allerdings feststellen soll, ob der D12 überhaupt etwas sendet ist mir schleierhaft. Die gelesenen Daten vom Host sind richtig. Nach dem Schreiben der ersten 8 Bytes des Deskriptors erhalte ich einen IN-Token. Die 8 Bytes werden also an den Host gesendet. Danach erfolgt ein Reset, was laut Spezifikation auch richtig ist. Wie soll ich nun feststellen, ob der Host tatsächlich die 8 Bytes gelesen hat oder ob er nur Schema-F durchläuft? Beim auslesen der LastTransactionStatus-Register werden auch keine Fehler angezeigt. Also ist die Übertragung erfolgreich abgeschlossen worden. Hat jemand noch eine Idee? Gruß Ralf
>Hat jemand noch eine Idee? USB ist eben nicht ganz einfach -- ich musste in den vergangenen Monaten auch manchmal kämpfen. Insbesondere bei Fehlern oder Ungenauigkeiten im Datenblatt wird es unangenehm. Aber meine freie USB-Firmware für den AT90USB ist jetzt inklusive Beispielprogramm und etwas Dokumentation online. Falls Du mit dem PDIUSBD12 nicht weiter kommst wäre das vielleicht eine Alternative. Beitrag "Freie USB-Firmware für AT90USB verfügbar" http://www.ssalewski.de/Misc.html.de Gruß Stefan Salewski
ich suche heute abend mal meine Implementation raus. Vieleicht bringt das ja was. sizeof() hast du überprüft? Wenn ich mich richtig errinnere ist da was beim SetAddress() was beim D12 anders funktioniert als normal. Thomas
Danke für Deine Links Stefan, aber noch bin ich mit dem D12 nicht fertig. Thomas, ist echt nett von Dir. Du kannst mir das Ganze auch gerne per eMail schicken: ralf.handrich@gmx.de. Hier nochmal das neueste Debug-Protokoll: Initialization ---------------- SetAddressEnable = 80 // Resets und Suspend Change SetEndpointEnable = 01 SetMode (config,clock) = 16 , 0B ReadInterruptRegister = 40 , 00 SetAddressEnable = 80 SetEndpointEnable = 01 SetMode (config,clock) = 16 , 0B ReadInterruptRegister = 80 , 00 SetEndpointStatus (ep, status)= 00 , 00 SetEndpointStatus (ep, status)= 01 , 00 ReadInterruptRegister = C0 , 00 SetAddressEnable = 80 SetEndpointEnable = 01 SetMode (config,clock) = 16 , 0B SetEndpointStatus (ep, status)= 00 , 00 SetEndpointStatus (ep, status)= 01 , 00 ReadInterruptRegister = 80 , 00 SetEndpointStatus (ep, status)= 00 , 00 SetEndpointStatus (ep, status)= 01 , 00 ReadInterruptRegister = C0 , 00 SetAddressEnable = 80 SetEndpointEnable = 01 SetMode (config,clock) = 16 , 0B SetEndpointStatus (ep, status)= 00 , 00 SetEndpointStatus (ep, status)= 01 , 00 // HIER GEHTS LOS ReadInterruptRegister = 01 , 00 // SETUP-TOKEN ProcessIRQ_EP0OUT ReadLastTransactionStatus = 21 - SetupPacket - ReadEndpoint = 80 06 00 01 00 00 40 00 AcknowledgeEndpoint = 00 AcknowledgeEndpoint = 01 GetDescriptor Write2Endpoint = 12 01 00 02 00 00 00 08 ReadInterruptRegister = 03 , 00 // IN-TOKEN + OUT-TOKEN ? ProcessIRQ_EP0IN ReadLastTransactionStatus = 00 // DATA0 - warum? PROGRESS_IDLE Write2Endpoint = 25 09 34 12 00 01 01 00 ProcessIRQ_EP0OUT ReadLastTransactionStatus = 00 - Out-Token - // OUT-TOKEN - warum? nBytes = 00 ReadInterruptRegister = 40 , 00 // RESET SetAddressEnable = 80 SetEndpointEnable = 01 SetMode (config,clock) = 16 , 0B ReadInterruptRegister = 01 , 00 // SETUP-TOKEN mit Adresse ProcessIRQ_EP0OUT ReadLastTransactionStatus = 21 - SetupPacket - ReadEndpoint = 00 05 03 00 00 00 00 00 // Die Adresse AcknowledgeEndpoint = 00 AcknowledgeEndpoint = 01 Write2Endpoint = ReadInterruptRegister = 02 , 00 // IN-TOKEN: // neue Adresse setzen ProcessIRQ_EP0IN ReadLastTransactionStatus = 41 PROGRESS_ADDRESS SetAddressEnable = 83 ReadInterruptRegister = 40 , 00 // Reset und von vorne, weil // irgendwo ein Fehler war SetAddressEnable = 80 SetEndpointEnable = 01 SetMode (config,clock) = 16 , 0B Nach dem GetDescriptor() erhalte ich einen Interrupt mit IN- und OUT-Token. Das ist schon sehr komisch. Ich nehme mal an, daß da der Fehler liegt. Was ja Thomas auch schon vermutet hat. Ich frage mich nur, was an meinem Code falsch sein soll: 8 Bytes werden gelesen - Acknowledge geht raus - die ersten 8 Bytes des Deskriptors werden geschrieben.
Ich habe den Fehler gefunden. Das Setzen der Adresse muß direkt nach Erhalt der Selbigen erfolgen und nicht erst beim Eintreffen des nächsten In-Tokens, wie das bei 'USB in a Nutshell' beschrieben wird. Allerdings arbeiten die auch mit einem D11. Danke an Alle, die mir geholfen haben. Gruß Ralf
>Das Setzen der Adresse muß direkt nach Erhalt der Selbigen erfolgen
Das ist erstaunlich -- nach USB-Spezifikation soll, wie weiter oben von
einigen anderen auch erwähnt, die Transaktion mit Adresse 0
abgeschlossen werden. Erst ganz am Ende soll die neue Adresse gesetzt
werden.
Da wäre ich nicht drauf gekommen -- steht davon irgendwas im Datenblatt?
Der Beitrag von Datum: 30.03.2007 19:55
geht ja wohl auch in diese Richtung.
Gruß
Stefan Salewski
Der D12 setzt die Adresse nicht direkt nach dem SetAddress()-Befehl, sondern er wartet intern damit, bis das nächste IN-Token mit Adresse 0 beantwortet wurde. Schau dazu mal bei: http://www.robmeerman.co.uk/project/usb/code/hid-mouse Gruß Ralf
Hi, ich weiß der Thread ist schon länger tot, aber ich wollte kein neues Thema anreißen. Hab nur eine kurze Frage für USB-Spezialisten: Wenn der Setuprequest "GetDescriptor (Configuration)", soll dann grundsätzlich immer die gesamte Konfiguration geschickt werden, d.h. mit sämtlichen Interface- und Endpointdescriptoren oder soll ich mich vorerst mal an den Wert, der im Feld wLength angegeben ist halten, bis 0x00FF Bytes angefordert werden? Gruß, Johnsn
Du hälst Dich an wLength, solange dieser Wert kleiner ist als ConfigDescriptor.wTotalLength. Ansonsten gilt der letztere Wert (wTotalLength).
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.