Hallo zusammen, ich hänge gerade an einem Problem fest und weiß ehrlich gesagt nicht mehr so recht, wie ich weiter komme. Ich verwende ein USBKEY-kompatibles Board mit AT90USB1287. Auf dem AVR läuft der Code aus der Atmel-Appnote "AVR280: USB Host CDC Demonstration on megaAVR with USB" als USB-UART-Bridge. Als CDC-Device hängt ein GPS-Empfänger mit PL2303HXD (v4.00)am AVR-USB. Das Ganze hat recht vielversprechend begonnen, die NMEA-Daten aus dem GPS-Empfänger sprudelten nach dem Einstecken gleich fröhlich aus dem UART-TX des AVRs. Ganz anders verhält sich die Gegenrichtung. Wenn ich versuche Daten an den GPS-Empfänger zu senden, kann ich diese bis zum Versenden über das USB-Datenregister verfolgen, doch die Daten kommen nicht aus dem PL2303HXD-TX am GPS-Empfänger. Ich habe noch einen USB/RS232-Konverter mit PL2303HX (v3.00). Mit dem funktionieren die Daten erstaunlicherweise in beide Richtungen problemlos. Mir scheint, die beiden PL2303 funktionieren ein klein wenig anders und der USB CDC-Host-Stack kann den neueren der beiden Chips nicht richtig bedienen. Hat jemand eine Idee, was das Problem sein könnte? Vielen Dank. Gruß, the bartman
Hallo zusammen, immer wieder schön ein Problem dann doch selbst zu lösen :-) Das Ganze hat mir einfach keine Ruhe gelassen und ich habe mal weiter geforscht. Mir schien, als ob sich der PL2303HXD ohne besondere Initialisierung im Supend-Modus befindet und damit die Ausgangstreiber (also auch der TXD) abgeschaltet sind. Die CDC-Spezifikation gab diesbezüglich nichts her, ein paar Versuche über irgend welche Requests den Chip zu wecken, schlugen fehl. Zudem stellte sich heraus, dass der vermeintliche PL2303HX v3.00 wohl eine noch ältere Variante (also z.B. ohne Postfix, oder H oder HA) zu sein schien, denn ein weiterer Adapter neuer als der zuvor verwendete, jedoch definitiv kein HXD, zeigte sich genauso TXD-stumm, wie der HXD-Typ. Also musste es irgend einen Weg geben, den CHip aus dem Suspend zu holen, denn die diversen Geräteteriber von Windows oder LINUX können den Chip ja schließlich auch bedienen. Die Lösung meines Problems war dann tatsächlich im Quellcode des Linux-Treibers für den PL2303 zu finden. Dort ist eine kryptische Initialisierungssequenz zu finden, die offenbar vor langer Zeit durch Reverse-Engineering und USB-Sniffen an einem Windows-Rechner zustande kam. Keiner weiß so genau was da passiert, aber es scheint bestens zu funktionieren. Ich habe die Sequenz dann für den AVR280-Quellcode aufbereitet. Das Ganze sieht dann folgendermaßen aus: In "host_cdc_task.c" des Quellcodes aus AVR280 ist unmittelbar vor
1 | // Open port (according cdc spec 1.1 chapter 6.2.14)
|
2 | usb_request.bmRequestType = USB_SETUP_SET_CLASS_INTER; |
3 | usb_request.bRequest = SETUP_CDC_SET_CONTROL_LINE_STATE; |
4 | usb_request.wValue.... |
folgender Code einzufügen:
1 | // PL2303 H/HA/HX/HXD setup sequence derived from the Linux Cross Reference
|
2 | // at http://lxr.free-electrons.com/source/drivers/usb/serial/pl2303.c
|
3 | U8 au8_buffer[10]; |
4 | |
5 | // pl2303_vendor_read(0x8484, 0, serial, buf);
|
6 | usb_request.bmRequestType = USB_SETUP_GET_VENDOR_DEVICE; |
7 | usb_request.bRequest = SETUP_GET_VENDOR_DEVICE; |
8 | usb_request.wValue = 0x8484; |
9 | usb_request.wIndex = 0; |
10 | usb_request.wLength = 1; |
11 | usb_request.uncomplete_read = FALSE; |
12 | host_send_control(au8_buffer); |
13 | |
14 | // pl2303_vendor_write(0x0404, 0, serial);
|
15 | usb_request.bmRequestType = USB_SETUP_SET_VENDOR_DEVICE; |
16 | usb_request.bRequest = SETUP_SET_VENDOR_DEVICE; |
17 | usb_request.wValue = 0x0404; |
18 | usb_request.wIndex = 0; |
19 | usb_request.wLength = 0; |
20 | usb_request.uncomplete_read = FALSE; |
21 | host_send_control(0); |
22 | |
23 | // pl2303_vendor_read(0x8484, 0, serial, buf);
|
24 | usb_request.bmRequestType = USB_SETUP_GET_VENDOR_DEVICE; |
25 | usb_request.bRequest = SETUP_GET_VENDOR_DEVICE; |
26 | usb_request.wValue = 0x8484; |
27 | usb_request.wIndex = 0; |
28 | usb_request.wLength = 1; |
29 | usb_request.uncomplete_read = FALSE; |
30 | host_send_control(au8_buffer); |
31 | |
32 | // pl2303_vendor_read(0x8383, 0, serial, buf);
|
33 | usb_request.bmRequestType = USB_SETUP_GET_VENDOR_DEVICE; |
34 | usb_request.bRequest = SETUP_GET_VENDOR_DEVICE; |
35 | usb_request.wValue = 0x8484; |
36 | usb_request.wIndex = 0; |
37 | usb_request.wLength = 1; |
38 | usb_request.uncomplete_read = FALSE; |
39 | host_send_control(au8_buffer); |
40 | |
41 | // pl2303_vendor_read(0x8484, 0, serial, buf);
|
42 | usb_request.bmRequestType = USB_SETUP_GET_VENDOR_DEVICE; |
43 | usb_request.bRequest = SETUP_GET_VENDOR_DEVICE; |
44 | usb_request.wValue = 0x8484; |
45 | usb_request.wIndex = 0; |
46 | usb_request.wLength = 1; |
47 | usb_request.uncomplete_read = FALSE; |
48 | host_send_control(au8_buffer); |
49 | |
50 | // pl2303_vendor_write(0x0404, 1, serial);
|
51 | usb_request.bmRequestType = USB_SETUP_SET_VENDOR_DEVICE; |
52 | usb_request.bRequest = SETUP_SET_VENDOR_DEVICE; |
53 | usb_request.wValue = 0x0404; |
54 | usb_request.wIndex = 1; |
55 | usb_request.wLength = 0; |
56 | usb_request.uncomplete_read = FALSE; |
57 | host_send_control(0); |
58 | |
59 | // pl2303_vendor_read(0x8484, 0, serial, buf);
|
60 | usb_request.bmRequestType = USB_SETUP_GET_VENDOR_DEVICE; |
61 | usb_request.bRequest = SETUP_GET_VENDOR_DEVICE; |
62 | usb_request.wValue = 0x8484; |
63 | usb_request.wIndex = 0; |
64 | usb_request.wLength = 1; |
65 | usb_request.uncomplete_read = FALSE; |
66 | host_send_control(au8_buffer); |
67 | |
68 | // pl2303_vendor_read(0x8383, 0, serial, buf);
|
69 | usb_request.bmRequestType = USB_SETUP_GET_VENDOR_DEVICE; |
70 | usb_request.bRequest = SETUP_GET_VENDOR_DEVICE; |
71 | usb_request.wValue = 0x8484; |
72 | usb_request.wIndex = 0; |
73 | usb_request.wLength = 1; |
74 | usb_request.uncomplete_read = FALSE; |
75 | host_send_control(au8_buffer); |
76 | |
77 | // pl2303_vendor_write(0, 1, serial);
|
78 | usb_request.bmRequestType = USB_SETUP_SET_VENDOR_DEVICE; |
79 | usb_request.bRequest = SETUP_SET_VENDOR_DEVICE; |
80 | usb_request.wValue = 0; |
81 | usb_request.wIndex = 1; |
82 | usb_request.wLength = 0; |
83 | usb_request.uncomplete_read = FALSE; |
84 | host_send_control(0); |
85 | |
86 | // pl2303_vendor_write(1, 0, serial);
|
87 | usb_request.bmRequestType = USB_SETUP_SET_VENDOR_DEVICE; |
88 | usb_request.bRequest = SETUP_SET_VENDOR_DEVICE; |
89 | usb_request.wValue = 1; |
90 | usb_request.wIndex = 0; |
91 | usb_request.wLength = 0; |
92 | usb_request.uncomplete_read = FALSE; |
93 | host_send_control(0); |
94 | |
95 | // Simplified determination, if the PL2303 is a HX or not:
|
96 | // If the PL2303 doesn't work properly, switch HWB to ON,
|
97 | // then the other request is sent.
|
98 | if ( Is_not_hwb() ) |
99 | {
|
100 | // pl2303_vendor_write(2, 0x44, serial); --> HX
|
101 | usb_request.bmRequestType = USB_SETUP_SET_VENDOR_DEVICE; |
102 | usb_request.bRequest = SETUP_SET_VENDOR_DEVICE; |
103 | usb_request.wValue = 2; |
104 | usb_request.wIndex = 0x44; |
105 | usb_request.wLength = 0; |
106 | usb_request.uncomplete_read = FALSE; |
107 | host_send_control(0); |
108 | }
|
109 | else
|
110 | {
|
111 | // pl2303_vendor_write(2, 0x24, serial); --> type0/type1
|
112 | usb_request.bmRequestType = USB_SETUP_SET_VENDOR_DEVICE; |
113 | usb_request.bRequest = SETUP_SET_VENDOR_DEVICE; |
114 | usb_request.wValue = 2; |
115 | usb_request.wIndex = 0x24; |
116 | usb_request.wLength = 0; |
117 | usb_request.uncomplete_read = FALSE; |
118 | host_send_control(0); |
119 | }
|
Zusätzlich sind in "usb_commun.h" im Abschnitt "Standard Requests (bRequest)" folgende Zeilen zu ergänzen:
1 | #define SETUP_GET_VENDOR_DEVICE 0x01
|
2 | #define SETUP_SET_VENDOR_DEVICE 0x01
|
Damit sollten sich nun am USBKEY im CDC-Hostmode sämtliche Derivate des PL2303 betreiben lassen... Gruß, the bartman
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.