From 9fb4cb18472084f483a7b3a6fe18bbe85f6a1089 Mon Sep 17 00:00:00 2001 From: v173k Date: Tue, 18 Nov 2014 18:56:28 -0600 Subject: [PATCH] Fix for PL2303HX chips so that PL2303::SndData() works. Details: This was worked earlier by uncommenting "#define PL2303_COMPAT" from cdcprolific.h I just re-added code by Oleg Mazurov which for some reason was lost during a later merge/pull request. Also see: http://www.circuitsathome.com/mcu/major-acmprolific-bug-fix-posted-on-github --- cdcprolific.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- cdcprolific.h | 22 +++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/cdcprolific.cpp b/cdcprolific.cpp index d629ad55..8a06c388 100644 --- a/cdcprolific.cpp +++ b/cdcprolific.cpp @@ -30,6 +30,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) { UsbDevice *p = NULL; EpInfo *oldep_ptr = NULL; uint8_t num_of_conf; // number of configurations + enum pl2303_type pltype = unknown; AddressPool &addrPool = pUsb->GetAddressPool(); @@ -69,6 +70,21 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) { if(udd->idVendor != PL_VID && udd->idProduct != PL_PID) return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; + /* determine chip variant */ + + if (udd->bDeviceClass == 0x02 ) { + pltype = type_0; + } + else if (udd->bMaxPacketSize0 == 0x40 ) { + pltype = rev_HX; + } + else if (udd->bDeviceClass == 0x00) { + pltype = type_1; + } + else if (udd->bDeviceClass == 0xff) { + pltype = type_1; + } + // Save type of PL chip wPLType = udd->bcdDevice; @@ -144,7 +160,30 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) { if(rcode) goto FailSetConfDescr; - + + #if defined(PL2303_COMPAT) + /* shamanic dance - sending Prolific init data as-is */ + vendorRead( 0x84, 0x84, 0, buf ); + vendorWrite( 0x04, 0x04, 0 ); + vendorRead( 0x84, 0x84, 0, buf ); + vendorRead( 0x83, 0x83, 0, buf ); + vendorRead( 0x84, 0x84, 0, buf ); + vendorWrite( 0x04, 0x04, 1 ); + vendorRead( 0x84, 0x84, 0, buf); + vendorRead( 0x83, 0x83, 0, buf); + vendorWrite( 0, 0, 1 ); + vendorWrite( 1, 0, 0 ); + if ( pltype == rev_HX ) { + vendorWrite( 2, 0, 0x44 ); + vendorWrite( 0x06, 0x06, 0 ); //from W7 init + } + else { + vendorWrite( 2, 0, 0x24 ); + } + /* shamanic dance end */ + #endif + + /* calling post-init callback */ rcode = pAsync->OnInit(this); if(rcode) diff --git a/cdcprolific.h b/cdcprolific.h index bfa92fe3..7b964ca7 100644 --- a/cdcprolific.h +++ b/cdcprolific.h @@ -19,6 +19,8 @@ e-mail : support@circuitsathome.com #include "cdcacm.h" +#define PL2303_COMPAT //uncomment it if you have compatibility problems + #define PL_VID 0x067B #define PL_PID ( 0x2303 || 0x0609 ) @@ -106,7 +108,8 @@ enum tXO_State { enum pl2303_type { unknown, - type_1, /* don't know the difference between type 0 and */ + type_0, + type_1, /* don't know the difference between type 0 and */ rev_X, /* type 1, until someone from prolific tells us... */ rev_HX, /* HX version of the pl2303 chip */ rev_H @@ -129,6 +132,23 @@ public: //// UsbConfigXtracter implementation //virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); + +private: + /* Prolific proprietary requests */ + uint8_t vendorRead( uint8_t val_lo, uint8_t val_hi, uint16_t index, uint8_t* buf ); + uint8_t vendorWrite( uint8_t val_lo, uint8_t val_hi, uint8_t index ); }; +/* vendor read request */ +inline uint8_t PL2303::vendorRead( uint8_t val_lo, uint8_t val_hi, uint16_t index, uint8_t* buf ) +{ + return( pUsb->ctrlReq(bAddress, 0, VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, val_lo, val_hi, index, 1, 1, buf, NULL )); +} + +/* vendor write request */ +inline uint8_t PL2303::vendorWrite( uint8_t val_lo, uint8_t val_hi, uint8_t index ) +{ + return( pUsb->ctrlReq(bAddress, 0, VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, val_lo, val_hi, index, 0, 0, NULL, NULL )); +} + #endif // __CDCPROLIFIC_H__