You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

cdcprolific.cpp 6.5KB

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