diff options
Diffstat (limited to 'lib/usbhost/USB_Host_Shield_2.0/cdcprolific.cpp')
-rw-r--r-- | lib/usbhost/USB_Host_Shield_2.0/cdcprolific.cpp | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/lib/usbhost/USB_Host_Shield_2.0/cdcprolific.cpp b/lib/usbhost/USB_Host_Shield_2.0/cdcprolific.cpp new file mode 100644 index 000000000..eceb1df9f --- /dev/null +++ b/lib/usbhost/USB_Host_Shield_2.0/cdcprolific.cpp | |||
@@ -0,0 +1,247 @@ | |||
1 | /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved. | ||
2 | |||
3 | This software may be distributed and modified under the terms of the GNU | ||
4 | General Public License version 2 (GPL2) as published by the Free Software | ||
5 | Foundation and appearing in the file GPL2.TXT included in the packaging of | ||
6 | this file. Please note that GPL2 Section 2[b] requires that all works based | ||
7 | on this software must also be made publicly available under the terms of | ||
8 | the GPL2 ("Copyleft"). | ||
9 | |||
10 | Contact information | ||
11 | ------------------- | ||
12 | |||
13 | Circuits At Home, LTD | ||
14 | Web : http://www.circuitsathome.com | ||
15 | e-mail : support@circuitsathome.com | ||
16 | */ | ||
17 | #include "cdcprolific.h" | ||
18 | |||
19 | PL2303::PL2303(USB *p, CDCAsyncOper *pasync) : | ||
20 | ACM(p, pasync), | ||
21 | wPLType(0) { | ||
22 | } | ||
23 | |||
24 | uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) { | ||
25 | const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); | ||
26 | |||
27 | uint8_t buf[constBufSize]; | ||
28 | USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf); | ||
29 | uint8_t rcode; | ||
30 | UsbDevice *p = NULL; | ||
31 | EpInfo *oldep_ptr = NULL; | ||
32 | uint8_t num_of_conf; // number of configurations | ||
33 | #ifdef PL2303_COMPAT | ||
34 | enum pl2303_type pltype = unknown; | ||
35 | #endif | ||
36 | |||
37 | AddressPool &addrPool = pUsb->GetAddressPool(); | ||
38 | |||
39 | USBTRACE("PL Init\r\n"); | ||
40 | |||
41 | if(bAddress) | ||
42 | return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; | ||
43 | |||
44 | // Get pointer to pseudo device with address 0 assigned | ||
45 | p = addrPool.GetUsbDevicePtr(0); | ||
46 | |||
47 | if(!p) | ||
48 | return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; | ||
49 | |||
50 | if(!p->epinfo) { | ||
51 | USBTRACE("epinfo\r\n"); | ||
52 | return USB_ERROR_EPINFO_IS_NULL; | ||
53 | } | ||
54 | |||
55 | // Save old pointer to EP_RECORD of address 0 | ||
56 | oldep_ptr = p->epinfo; | ||
57 | |||
58 | // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence | ||
59 | p->epinfo = epInfo; | ||
60 | |||
61 | p->lowspeed = lowspeed; | ||
62 | |||
63 | // Get device descriptor | ||
64 | rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); | ||
65 | |||
66 | // Restore p->epinfo | ||
67 | p->epinfo = oldep_ptr; | ||
68 | |||
69 | if(rcode) | ||
70 | goto FailGetDevDescr; | ||
71 | |||
72 | if(udd->idVendor != PL_VID && CHECK_PID(udd->idProduct)) | ||
73 | return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; | ||
74 | |||
75 | /* determine chip variant */ | ||
76 | #ifdef PL2303_COMPAT | ||
77 | if(udd->bDeviceClass == 0x02 ) | ||
78 | pltype = type_0; | ||
79 | else if(udd->bMaxPacketSize0 == 0x40 ) | ||
80 | pltype = rev_HX; | ||
81 | else if(udd->bDeviceClass == 0x00) | ||
82 | pltype = type_1; | ||
83 | else if(udd->bDeviceClass == 0xff) | ||
84 | pltype = type_1; | ||
85 | #endif | ||
86 | |||
87 | // Save type of PL chip | ||
88 | wPLType = udd->bcdDevice; | ||
89 | |||
90 | // Allocate new address according to device class | ||
91 | bAddress = addrPool.AllocAddress(parent, false, port); | ||
92 | |||
93 | if(!bAddress) | ||
94 | return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; | ||
95 | |||
96 | // Extract Max Packet Size from the device descriptor | ||
97 | epInfo[0].maxPktSize = udd->bMaxPacketSize0; | ||
98 | |||
99 | // Assign new address to the device | ||
100 | rcode = pUsb->setAddr(0, 0, bAddress); | ||
101 | |||
102 | if(rcode) { | ||
103 | p->lowspeed = false; | ||
104 | addrPool.FreeAddress(bAddress); | ||
105 | bAddress = 0; | ||
106 | USBTRACE2("setAddr:", rcode); | ||
107 | return rcode; | ||
108 | } | ||
109 | |||
110 | USBTRACE2("Addr:", bAddress); | ||
111 | |||
112 | p->lowspeed = false; | ||
113 | |||
114 | p = addrPool.GetUsbDevicePtr(bAddress); | ||
115 | |||
116 | if(!p) | ||
117 | return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; | ||
118 | |||
119 | p->lowspeed = lowspeed; | ||
120 | |||
121 | num_of_conf = udd->bNumConfigurations; | ||
122 | |||
123 | // Assign epInfo to epinfo pointer | ||
124 | rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); | ||
125 | |||
126 | if(rcode) | ||
127 | goto FailSetDevTblEntry; | ||
128 | |||
129 | USBTRACE2("NC:", num_of_conf); | ||
130 | |||
131 | for(uint8_t i = 0; i < num_of_conf; i++) { | ||
132 | HexDumper<USBReadParser, uint16_t, uint16_t> HexDump; | ||
133 | ConfigDescParser < 0xFF, 0, 0, CP_MASK_COMPARE_CLASS> confDescrParser(this); | ||
134 | |||
135 | rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump); | ||
136 | |||
137 | if(rcode) | ||
138 | goto FailGetConfDescr; | ||
139 | |||
140 | rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); | ||
141 | |||
142 | if(rcode) | ||
143 | goto FailGetConfDescr; | ||
144 | |||
145 | if(bNumEP > 1) | ||
146 | break; | ||
147 | } // for | ||
148 | |||
149 | if(bNumEP < 2) | ||
150 | return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; | ||
151 | |||
152 | // Assign epInfo to epinfo pointer | ||
153 | rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); | ||
154 | |||
155 | USBTRACE2("Conf:", bConfNum); | ||
156 | |||
157 | // Set Configuration Value | ||
158 | rcode = pUsb->setConf(bAddress, 0, bConfNum); | ||
159 | |||
160 | if(rcode) | ||
161 | goto FailSetConfDescr; | ||
162 | |||
163 | #ifdef PL2303_COMPAT | ||
164 | /* Shamanic dance - sending Prolific init data as-is */ | ||
165 | vendorRead( 0x84, 0x84, 0, buf ); | ||
166 | vendorWrite( 0x04, 0x04, 0 ); | ||
167 | vendorRead( 0x84, 0x84, 0, buf ); | ||
168 | vendorRead( 0x83, 0x83, 0, buf ); | ||
169 | vendorRead( 0x84, 0x84, 0, buf ); | ||
170 | vendorWrite( 0x04, 0x04, 1 ); | ||
171 | vendorRead( 0x84, 0x84, 0, buf); | ||
172 | vendorRead( 0x83, 0x83, 0, buf); | ||
173 | vendorWrite( 0, 0, 1 ); | ||
174 | vendorWrite( 1, 0, 0 ); | ||
175 | if( pltype == rev_HX ) { | ||
176 | vendorWrite( 2, 0, 0x44 ); | ||
177 | vendorWrite( 0x06, 0x06, 0 ); // From W7 init | ||
178 | } | ||
179 | else { | ||
180 | vendorWrite( 2, 0, 0x24 ); | ||
181 | } | ||
182 | /* Shamanic dance end */ | ||
183 | #endif | ||
184 | /* Calling post-init callback */ | ||
185 | rcode = pAsync->OnInit(this); | ||
186 | |||
187 | if(rcode) | ||
188 | goto FailOnInit; | ||
189 | |||
190 | USBTRACE("PL configured\r\n"); | ||
191 | |||
192 | //bPollEnable = true; | ||
193 | ready = true; | ||
194 | return 0; | ||
195 | |||
196 | FailGetDevDescr: | ||
197 | #ifdef DEBUG_USB_HOST | ||
198 | NotifyFailGetDevDescr(); | ||
199 | goto Fail; | ||
200 | #endif | ||
201 | |||
202 | FailSetDevTblEntry: | ||
203 | #ifdef DEBUG_USB_HOST | ||
204 | NotifyFailSetDevTblEntry(); | ||
205 | goto Fail; | ||
206 | #endif | ||
207 | |||
208 | FailGetConfDescr: | ||
209 | #ifdef DEBUG_USB_HOST | ||
210 | NotifyFailGetConfDescr(); | ||
211 | goto Fail; | ||
212 | #endif | ||
213 | |||
214 | FailSetConfDescr: | ||
215 | #ifdef DEBUG_USB_HOST | ||
216 | NotifyFailSetConfDescr(); | ||
217 | goto Fail; | ||
218 | #endif | ||
219 | |||
220 | FailOnInit: | ||
221 | #ifdef DEBUG_USB_HOST | ||
222 | USBTRACE("OnInit:"); | ||
223 | #endif | ||
224 | |||
225 | #ifdef DEBUG_USB_HOST | ||
226 | Fail: | ||
227 | NotifyFail(rcode); | ||
228 | #endif | ||
229 | Release(); | ||
230 | return rcode; | ||
231 | } | ||
232 | |||
233 | //uint8_t PL::Poll() | ||
234 | //{ | ||
235 | // uint8_t rcode = 0; | ||
236 | // | ||
237 | // //if (!bPollEnable) | ||
238 | // // return 0; | ||
239 | // | ||
240 | // //if (qNextPollTime <= millis()) | ||
241 | // //{ | ||
242 | // // USB_HOST_SERIAL.println(bAddress, HEX); | ||
243 | // | ||
244 | // // qNextPollTime = millis() + 100; | ||
245 | // //} | ||
246 | // return rcode; | ||
247 | //} | ||