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
This commit is contained in:
v173k 2014-11-18 18:56:28 -06:00
parent d5e900f833
commit 9fb4cb1847
2 changed files with 61 additions and 2 deletions

View file

@ -30,6 +30,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
UsbDevice *p = NULL; UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL; EpInfo *oldep_ptr = NULL;
uint8_t num_of_conf; // number of configurations uint8_t num_of_conf; // number of configurations
enum pl2303_type pltype = unknown;
AddressPool &addrPool = pUsb->GetAddressPool(); 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) if(udd->idVendor != PL_VID && udd->idProduct != PL_PID)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; 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 // Save type of PL chip
wPLType = udd->bcdDevice; wPLType = udd->bcdDevice;
@ -144,7 +160,30 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
if(rcode) if(rcode)
goto FailSetConfDescr; 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); rcode = pAsync->OnInit(this);
if(rcode) if(rcode)

View file

@ -19,6 +19,8 @@ e-mail : support@circuitsathome.com
#include "cdcacm.h" #include "cdcacm.h"
#define PL2303_COMPAT //uncomment it if you have compatibility problems
#define PL_VID 0x067B #define PL_VID 0x067B
#define PL_PID ( 0x2303 || 0x0609 ) #define PL_PID ( 0x2303 || 0x0609 )
@ -106,7 +108,8 @@ enum tXO_State {
enum pl2303_type { enum pl2303_type {
unknown, 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_X, /* type 1, until someone from prolific tells us... */
rev_HX, /* HX version of the pl2303 chip */ rev_HX, /* HX version of the pl2303 chip */
rev_H rev_H
@ -129,6 +132,23 @@ public:
//// UsbConfigXtracter implementation //// UsbConfigXtracter implementation
//virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); //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__ #endif // __CDCPROLIFIC_H__