fix pointer screwup that has been around for ages.

This commit is contained in:
Andrew J. Kroll 2015-03-18 05:35:44 -04:00
parent 46dc4e6fec
commit da03f22741
4 changed files with 355 additions and 10 deletions

12
Usb.cpp
View file

@ -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;

View file

@ -89,7 +89,7 @@ typedef MAX3421e<P10, P9> 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_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
@ -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);

210
cdc_XR21B1411.cpp Normal file
View file

@ -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<USB_DEVICE_DESCRIPTOR*>(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<USBReadParser, uint16_t, uint16_t> 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;
//}

135
cdc_XR21B1411.h Normal file
View file

@ -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<<SPECIAL_SHIFT) - 1)
#define STATE_ALL ( PD_RS232_S_MASK | PD_S_MASK )
#define FLOW_RX_AUTO ( PD_RS232_A_RFR | PD_RS232_A_DTR | PD_RS232_A_RXO )
#define FLOW_TX_AUTO ( PD_RS232_A_CTS | PD_RS232_A_DSR | PD_RS232_A_TXO | PD_RS232_A_DCD )
#define CAN_BE_AUTO ( FLOW_RX_AUTO | FLOW_TX_AUTO )
#define CAN_NOTIFY ( PD_RS232_N_MASK )
#define EXTERNAL_MASK ( PD_S_MASK | (PD_RS232_S_MASK & ~PD_RS232_S_LOOP) )
#define INTERNAL_DELAY ( PD_RS232_S_LOOP )
#define DEFAULT_AUTO ( PD_RS232_A_DTR | PD_RS232_A_RFR | PD_RS232_A_CTS | PD_RS232_A_DSR )
#define DEFAULT_NOTIFY 0x00
#define DEFAULT_STATE ( PD_S_TX_ENABLE | PD_S_RX_ENABLE | PD_RS232_A_TXO | PD_RS232_A_RXO )
#define CONTINUE_SEND 1
#define PAUSE_SEND 2
#define kRxAutoFlow ((UInt32)( PD_RS232_A_RFR | PD_RS232_A_DTR | PD_RS232_A_RXO ))
#define kTxAutoFlow ((UInt32)( PD_RS232_A_CTS | PD_RS232_A_DSR | PD_RS232_A_TXO | PD_RS232_A_DCD ))
#define kControl_StateMask ((UInt32)( PD_RS232_S_CTS | PD_RS232_S_DSR | PD_RS232_S_CAR | PD_RS232_S_RI ))
#define kRxQueueState ((UInt32)( PD_S_RXQ_EMPTY | PD_S_RXQ_LOW_WATER | PD_S_RXQ_HIGH_WATER | PD_S_RXQ_FULL ))
#define kTxQueueState ((UInt32)( PD_S_TXQ_EMPTY | PD_S_TXQ_LOW_WATER | PD_S_TXQ_HIGH_WATER | PD_S_TXQ_FULL ))
#define kCONTROL_DTR 0x01
#define kCONTROL_RTS 0x02
#define kStateTransientMask 0x74
#define kBreakError 0x04
#define kFrameError 0x10
#define kParityError 0x20
#define kOverrunError 0x40
#define kCTS 0x80
#define kDSR 0x02
#define kRI 0x08
#define kDCD 0x01
#define kHandshakeInMask ((UInt32)( PD_RS232_S_CTS | PD_RS232_S_DSR | PD_RS232_S_CAR | PD_RS232_S_RI ))
#define VENDOR_WRITE_REQUEST_TYPE 0x40
#define VENDOR_WRITE_REQUEST 0x01
#define VENDOR_READ_REQUEST_TYPE 0xc0
#define VENDOR_READ_REQUEST 0x01
// Device Configuration Registers (DCR0, DCR1, DCR2)
#define SET_DCR0 0x00
#define GET_DCR0 0x80
#define DCR0_INIT 0x01
#define DCR0_INIT_H 0x41
#define DCR0_INIT_X 0x61
#define SET_DCR1 0x01
#define GET_DCR1 0x81
#define DCR1_INIT_H 0x80
#define DCR1_INIT_X 0x00
#define SET_DCR2 0x02
#define GET_DCR2 0x82
#define DCR2_INIT_H 0x24
#define DCR2_INIT_X 0x44
// On-chip Data Buffers:
#define RESET_DOWNSTREAM_DATA_PIPE 0x08
#define RESET_UPSTREAM_DATA_PIPE 0x09
#define PL_MAX_ENDPOINTS 4
enum tXO_State {
kXOnSent = -2,
kXOffSent = -1,
kXO_Idle = 0,
kXOffNeeded = 1,
kXOnNeeded = 2
};
enum pl2303_type {
unknown,
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
};
class PL2303 : public ACM {
uint16_t wPLType; // Type of chip
public:
PL2303(USB *pusb, CDCAsyncOper *pasync);
// USBDeviceConfig implementation
uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
//virtual uint8_t Release();
//virtual uint8_t Poll();
//virtual uint8_t GetAddress() { return bAddress; };
//// UsbConfigXtracter implementation
//virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
};
#endif // __CDCPROLIFIC_H__