Forum: Mikrocontroller und Digitale Elektronik Problem mit PL2303HXD an AT90USB1287 als CDC-Host.


von the_bartman (Gast)


Lesenswert?

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

von the_bartman (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.