From da03f22741bdea657dfcfb51df4c17c8f7d1cd2e Mon Sep 17 00:00:00 2001 From: "Andrew J. Kroll" Date: Wed, 18 Mar 2015 05:35:44 -0400 Subject: [PATCH] fix pointer screwup that has been around for ages. --- Usb.cpp | 12 +-- UsbCore.h | 8 +- cdc_XR21B1411.cpp | 210 ++++++++++++++++++++++++++++++++++++++++++++++ cdc_XR21B1411.h | 135 +++++++++++++++++++++++++++++ 4 files changed, 355 insertions(+), 10 deletions(-) create mode 100644 cdc_XR21B1411.cpp create mode 100644 cdc_XR21B1411.h diff --git a/Usb.cpp b/Usb.cpp index d7df9646..3e07149a 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -77,7 +77,7 @@ uint8_t USB::setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr) return 0; } -uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_limit) { +uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_limit) { UsbDevice *p = addrPool.GetUsbDevicePtr(addr); if(!p) @@ -91,8 +91,8 @@ uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_l if(!*ppep) return USB_ERROR_EP_NOT_FOUND_IN_TBL; - nak_limit = (0x0001UL << (((*ppep)->bmNakPower > USB_NAK_MAX_POWER) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower)); - nak_limit--; + *nak_limit = (0x0001UL << (((*ppep)->bmNakPower > USB_NAK_MAX_POWER) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower)); + *nak_limit--; /* USBTRACE2("\r\nAddress: ", addr); USBTRACE2(" EP: ", ep); @@ -132,7 +132,7 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque EpInfo *pep = NULL; uint16_t nak_limit = 0; - rcode = SetAddress(addr, ep, &pep, nak_limit); + rcode = SetAddress(addr, ep, &pep, &nak_limit); if(rcode) return rcode; @@ -207,7 +207,7 @@ uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* EpInfo *pep = NULL; uint16_t nak_limit = 0; - uint8_t rcode = SetAddress(addr, ep, &pep, nak_limit); + uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit); if(rcode) { USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81); @@ -293,7 +293,7 @@ uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dat EpInfo *pep = NULL; uint16_t nak_limit = 0; - uint8_t rcode = SetAddress(addr, ep, &pep, nak_limit); + uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit); if(rcode) return rcode; diff --git a/UsbCore.h b/UsbCore.h index a7399702..aad62afd 100644 --- a/UsbCore.h +++ b/UsbCore.h @@ -89,10 +89,10 @@ typedef MAX3421e MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega #define USB_ERROR_FailGetConfDescr 0xE3 #define USB_ERROR_TRANSFER_TIMEOUT 0xFF -#define USB_XFER_TIMEOUT 10000 //30000 // (5000) USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec -//#define USB_NAK_LIMIT 32000 //NAK limit for a transfer. 0 means NAKs are not counted +#define USB_XFER_TIMEOUT 5000 // (5000) USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec +//#define USB_NAK_LIMIT 32000 // NAK limit for a transfer. 0 means NAKs are not counted #define USB_RETRY_LIMIT 3 // 3 retry limit for a transfer -#define USB_SETTLE_DELAY 200 //settle delay in milliseconds +#define USB_SETTLE_DELAY 200 // settle delay in milliseconds #define USB_NUMDEVICES 16 //number of USB devices //#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller @@ -258,7 +258,7 @@ public: private: void init(); - uint8_t SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_limit); + uint8_t SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_limit); uint8_t OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data); uint8_t InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t *data); uint8_t AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed); diff --git a/cdc_XR21B1411.cpp b/cdc_XR21B1411.cpp new file mode 100644 index 00000000..6490c40e --- /dev/null +++ b/cdc_XR21B1411.cpp @@ -0,0 +1,210 @@ +/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved. + +This software may be distributed and modified under the terms of the GNU +General Public License version 2 (GPL2) as published by the Free Software +Foundation and appearing in the file GPL2.TXT included in the packaging of +this file. Please note that GPL2 Section 2[b] requires that all works based +on this software must also be made publicly available under the terms of +the GPL2 ("Copyleft"). + +Contact information +------------------- + +Circuits At Home, LTD +Web : http://www.circuitsathome.com +e-mail : support@circuitsathome.com + */ +#include "cdcprolific.h" + +PL2303::PL2303(USB *p, CDCAsyncOper *pasync) : +ACM(p, pasync), +wPLType(0) { +} + +uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) { + const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); + + uint8_t buf[constBufSize]; + USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf); + uint8_t rcode; + UsbDevice *p = NULL; + EpInfo *oldep_ptr = NULL; + uint8_t num_of_conf; // number of configurations + + AddressPool &addrPool = pUsb->GetAddressPool(); + + USBTRACE("PL Init\r\n"); + + if(bAddress) + return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; + + // Get pointer to pseudo device with address 0 assigned + p = addrPool.GetUsbDevicePtr(0); + + if(!p) + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + + if(!p->epinfo) { + USBTRACE("epinfo\r\n"); + return USB_ERROR_EPINFO_IS_NULL; + } + + // Save old pointer to EP_RECORD of address 0 + oldep_ptr = p->epinfo; + + // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence + p->epinfo = epInfo; + + p->lowspeed = lowspeed; + + // Get device descriptor + rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); + + // Restore p->epinfo + p->epinfo = oldep_ptr; + + if(rcode) + goto FailGetDevDescr; + + if(udd->idVendor != PL_VID && udd->idProduct != PL_PID) + return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; + + // Save type of PL chip + wPLType = udd->bcdDevice; + + // Allocate new address according to device class + bAddress = addrPool.AllocAddress(parent, false, port); + + if(!bAddress) + return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; + + // Extract Max Packet Size from the device descriptor + epInfo[0].maxPktSize = udd->bMaxPacketSize0; + + // Assign new address to the device + rcode = pUsb->setAddr(0, 0, bAddress); + + if(rcode) { + p->lowspeed = false; + addrPool.FreeAddress(bAddress); + bAddress = 0; + USBTRACE2("setAddr:", rcode); + return rcode; + } + + USBTRACE2("Addr:", bAddress); + + p->lowspeed = false; + + p = addrPool.GetUsbDevicePtr(bAddress); + + if(!p) + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + + p->lowspeed = lowspeed; + + num_of_conf = udd->bNumConfigurations; + + // Assign epInfo to epinfo pointer + rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); + + if(rcode) + goto FailSetDevTblEntry; + + USBTRACE2("NC:", num_of_conf); + + for(uint8_t i = 0; i < num_of_conf; i++) { + HexDumper HexDump; + ConfigDescParser < 0xFF, 0, 0, CP_MASK_COMPARE_CLASS> confDescrParser(this); + + rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump); + + if(rcode) + goto FailGetConfDescr; + + rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); + + if(rcode) + goto FailGetConfDescr; + + if(bNumEP > 1) + break; + } // for + + if(bNumEP < 2) + return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; + + // Assign epInfo to epinfo pointer + rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); + + USBTRACE2("Conf:", bConfNum); + + // Set Configuration Value + rcode = pUsb->setConf(bAddress, 0, bConfNum); + + if(rcode) + goto FailSetConfDescr; + + rcode = pAsync->OnInit(this); + + if(rcode) + goto FailOnInit; + + USBTRACE("PL configured\r\n"); + + //bPollEnable = true; + ready = true; + return 0; + +FailGetDevDescr: +#ifdef DEBUG_USB_HOST + NotifyFailGetDevDescr(); + goto Fail; +#endif + +FailSetDevTblEntry: +#ifdef DEBUG_USB_HOST + NotifyFailSetDevTblEntry(); + goto Fail; +#endif + +FailGetConfDescr: +#ifdef DEBUG_USB_HOST + NotifyFailGetConfDescr(); + goto Fail; +#endif + +FailSetConfDescr: +#ifdef DEBUG_USB_HOST + NotifyFailSetConfDescr(); + goto Fail; +#endif + +FailOnInit: +#ifdef DEBUG_USB_HOST + USBTRACE("OnInit:"); +#endif + +#ifdef DEBUG_USB_HOST +Fail: + NotifyFail(rcode); +#endif + Release(); + return rcode; +} + +//uint8_t PL::Poll() +//{ +// uint8_t rcode = 0; +// +// //if (!bPollEnable) +// // return 0; +// +// //if (qNextPollTime <= millis()) +// //{ +// // USB_HOST_SERIAL.println(bAddress, HEX); +// +// // qNextPollTime = millis() + 100; +// //} +// return rcode; +//} diff --git a/cdc_XR21B1411.h b/cdc_XR21B1411.h new file mode 100644 index 00000000..32566585 --- /dev/null +++ b/cdc_XR21B1411.h @@ -0,0 +1,135 @@ +/* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved. + +This software may be distributed and modified under the terms of the GNU +General Public License version 2 (GPL2) as published by the Free Software +Foundation and appearing in the file GPL2.TXT included in the packaging of +this file. Please note that GPL2 Section 2[b] requires that all works based +on this software must also be made publicly available under the terms of +the GPL2 ("Copyleft"). + +Contact information +------------------- + +Circuits At Home, LTD +Web : http://www.circuitsathome.com +e-mail : support@circuitsathome.com + */ +#if !defined(__CDCPROLIFIC_H__) +#define __CDCPROLIFIC_H__ + +#include "cdcacm.h" + +#define PL_VID 0x067B +#define PL_PID ( 0x2303 || 0x0609 ) + +//#define PL_PID 0x0609 + +#define PROLIFIC_REV_H 0x0202 +#define PROLIFIC_REV_X 0x0300 +#define PROLIFIC_REV_HX_CHIP_D 0x0400 +#define PROLIFIC_REV_1 0x0001 + +#define kXOnChar '\x11' +#define kXOffChar '\x13' + +#define SPECIAL_SHIFT (5) +#define SPECIAL_MASK ((1<