mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
acm bug fix
This commit is contained in:
parent
389c6115e3
commit
702897bd5b
15 changed files with 105 additions and 79 deletions
3
Usb.cpp
3
Usb.cpp
|
@ -108,7 +108,8 @@ uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_l
|
|||
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--;
|
||||
|
||||
/*
|
||||
USBTRACE2("\r\nAddress: ", addr);
|
||||
USBTRACE2(" EP: ", ep);
|
||||
|
|
10
Usb.h
10
Usb.h
|
@ -47,16 +47,8 @@ e-mail : support@circuitsathome.com
|
|||
|
||||
/* shield pins. First parameter - SS pin, second parameter - INT pin */
|
||||
|
||||
#if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
#define BOARD_TEENSY_PLUS_PLUS
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_BLACK_WIDDOW
|
||||
typedef MAX3421e<P6, P3> MAX3421E; // Black Widow
|
||||
#elif defined(BOARD_TEENSY_PLUS_PLUS)
|
||||
typedef MAX3421e<P9, P8> MAX3421E; // Teensy++ 2.0 & 1.0
|
||||
#elif defined(BOARD_MEGA_ADK)
|
||||
typedef MAX3421e<P53, P54> MAX3421E; // Arduino Mega ADK
|
||||
#else
|
||||
typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega, 2560
|
||||
#endif
|
||||
|
@ -280,4 +272,4 @@ inline uint8_t USB::setConf( uint8_t addr, uint8_t ep, uint8_t conf_value )
|
|||
|
||||
#endif // defined(USB_METHODS_INLINE)
|
||||
|
||||
#endif //_usb_h_
|
||||
#endif //_usb_h_
|
33
adk.cpp
33
adk.cpp
|
@ -48,11 +48,12 @@ ADK::ADK(USB *p, const char* manufacturer,
|
|||
for(uint8_t i=0; i<ADK_MAX_ENDPOINTS; i++) {
|
||||
epInfo[i].epAddr = 0;
|
||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||
epInfo[i].epAttribs = 0;
|
||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||
//epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
||||
epInfo[i].epAttribs = ( 0xfc & ( USB_NAK_MAX_POWER<<2 ));
|
||||
}//for(uint8_t i=0; i<ADK_MAX_ENDPOINTS; i++...
|
||||
|
||||
//set bulk-IN EP naklimit to 1
|
||||
epInfo[epDataInIndex].epAttribs = ( 0xfc & ( USB_NAK_NOWAIT<<2 ));
|
||||
|
||||
// register in USB subsystem
|
||||
if (pUsb) {
|
||||
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
||||
|
@ -156,16 +157,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
|
||||
for (uint8_t i=0; i<num_of_conf; i++) {
|
||||
ConfigDescParser<0, 0, 0, 0> confDescrParser(this);
|
||||
delay(1);
|
||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||
#if defined(XOOM)
|
||||
//added by Jaylen Scott Vanorden
|
||||
if( rcode ) {
|
||||
USBTRACE2("\r\nGot 1st bad code for config: ", rcode);
|
||||
// Try once more
|
||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||
}
|
||||
#endif
|
||||
if( rcode ) {
|
||||
goto FailGetConfDescr;
|
||||
}
|
||||
|
@ -181,7 +173,9 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
goto FailSetDevTblEntry;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Set Configuration Value
|
||||
rcode = pUsb->setConf(bAddress, 0, bConfNum);
|
||||
if( rcode ){
|
||||
|
@ -207,22 +201,11 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
return 0; //successful configuration
|
||||
}//if( buf->idVendor == ADK_VID...
|
||||
|
||||
//delay(20); //testing compatibility w/Motorola Xoom
|
||||
|
||||
//probe device - get accessory protocol revision
|
||||
{
|
||||
uint16_t adkproto = -1;
|
||||
delay(1);
|
||||
rcode = getProto((uint8_t*)&adkproto );
|
||||
#if defined(XOOM)
|
||||
//added by Jaylen Scott Vanorden
|
||||
if( rcode ) {
|
||||
USBTRACE2("\r\nGot 1st bad code for proto: ", rcode);
|
||||
// Try once more
|
||||
rcode = getProto((uint8_t*)&adkproto );
|
||||
}
|
||||
#endif
|
||||
if( rcode ){
|
||||
if( rcode ){
|
||||
goto FailGetProto; //init fails
|
||||
}
|
||||
USBTRACE2("\r\nADK protocol rev. ", adkproto );
|
||||
|
|
6
adk.h
6
adk.h
|
@ -44,10 +44,6 @@ e-mail : support@circuitsathome.com
|
|||
#define ADK_PID 0x2D00
|
||||
#define ADB_PID 0x2D01
|
||||
|
||||
#define XOOM //enables repeating getProto() and getConf() attempts
|
||||
//necessary for slow devices such as Motorola XOOM
|
||||
//defined by default, can be commented out to save memory
|
||||
|
||||
/* requests */
|
||||
|
||||
#define ADK_GETPROTO 51 //check USB accessory protocol version
|
||||
|
@ -109,7 +105,7 @@ public:
|
|||
const char* uri,
|
||||
const char* serial);
|
||||
|
||||
// Methods for receiving and sending data
|
||||
// Methods for recieving and sending data
|
||||
uint8_t RcvData(uint16_t *nbytesptr, uint8_t *dataptr);
|
||||
uint8_t SndData(uint16_t nbytes, uint8_t *dataptr);
|
||||
|
||||
|
|
|
@ -20,9 +20,6 @@ e-mail : support@circuitsathome.com
|
|||
#ifndef _avrpins_h_
|
||||
#define _avrpins_h_
|
||||
|
||||
/* Uncomment the following if you have Arduino Mega ADK board with MAX3421e built-in */
|
||||
//#define BOARD_MEGA_ADK
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#ifdef PORTA
|
||||
|
@ -468,7 +465,6 @@ template<typename Tp_pin, typename Tc_bit>
|
|||
#define P51 Pb2
|
||||
#define P52 Pb1
|
||||
#define P53 Pb0
|
||||
#define P54 Pj2
|
||||
|
||||
#endif //"Mega" pin numbers
|
||||
|
||||
|
|
18
cdcacm.cpp
18
cdcacm.cpp
|
@ -28,18 +28,20 @@ ACM::ACM(USB *p, CDCAsyncOper *pasync) :
|
|||
bPollEnable(false),
|
||||
bControlIface(0),
|
||||
bDataIface(0),
|
||||
bNumEP(1)
|
||||
bNumEP(1),
|
||||
ready(false)
|
||||
{
|
||||
for(uint8_t i=0; i<ACM_MAX_ENDPOINTS; i++)
|
||||
{
|
||||
epInfo[i].epAddr = 0;
|
||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||
epInfo[i].epAttribs = 0;
|
||||
//epInfo[i].bmNakPower = USB_NAK_NOWAIT;
|
||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
||||
epInfo[i].bmNakPower = USB_NAK_NOWAIT;
|
||||
//epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
||||
|
||||
//if (!i)
|
||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
||||
if (!i)
|
||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
||||
|
||||
}
|
||||
if (pUsb)
|
||||
pUsb->RegisterDeviceClass(this);
|
||||
|
@ -172,6 +174,7 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
goto FailOnInit;
|
||||
|
||||
USBTRACE("ACM configured\r\n");
|
||||
ready = true;
|
||||
|
||||
//bPollEnable = true;
|
||||
|
||||
|
@ -226,7 +229,7 @@ void ACM::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto
|
|||
// Fill in the endpoint info structure
|
||||
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
|
||||
epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
|
||||
epInfo[index].epAttribs = 0;
|
||||
//epInfo[index].epAttribs = 0;
|
||||
|
||||
bNumEP ++;
|
||||
|
||||
|
@ -244,6 +247,7 @@ uint8_t ACM::Release()
|
|||
bAddress = 0;
|
||||
qNextPollTime = 0;
|
||||
bPollEnable = false;
|
||||
ready = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -254,7 +258,7 @@ uint8_t ACM::Poll()
|
|||
if (!bPollEnable)
|
||||
return 0;
|
||||
|
||||
uint32_t time_now = millis();
|
||||
//uint32_t time_now = millis();
|
||||
|
||||
//if (qNextPollTime <= time_now)
|
||||
//{
|
||||
|
|
2
cdcacm.h
2
cdcacm.h
|
@ -154,6 +154,7 @@ protected:
|
|||
uint8_t bNumEP; // total number of EP in the configuration
|
||||
uint32_t qNextPollTime; // next poll time
|
||||
bool bPollEnable; // poll enable flag
|
||||
bool ready; //device ready indicator
|
||||
|
||||
EpInfo epInfo[ACM_MAX_ENDPOINTS];
|
||||
|
||||
|
@ -179,6 +180,7 @@ public:
|
|||
virtual uint8_t Release();
|
||||
virtual uint8_t Poll();
|
||||
virtual uint8_t GetAddress() { return bAddress; };
|
||||
virtual bool isReady() { return ready; };
|
||||
|
||||
// UsbConfigXtracter implementation
|
||||
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
|
||||
|
|
|
@ -232,7 +232,7 @@ void FTDI::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t prot
|
|||
// Fill in the endpoint info structure
|
||||
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
|
||||
epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
|
||||
epInfo[index].epAttribs = 0;
|
||||
//epInfo[index].epAttribs = 0;
|
||||
|
||||
bNumEP ++;
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ e-mail : support@circuitsathome.com
|
|||
#include "cdcprolific.h"
|
||||
|
||||
PL2303::PL2303(USB *p, CDCAsyncOper *pasync) :
|
||||
ACM(p, pasync),
|
||||
wPLType(0)
|
||||
ACM(p, pasync)
|
||||
//wPLType(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,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();
|
||||
|
||||
|
@ -68,11 +69,24 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
if( rcode )
|
||||
goto FailGetDevDescr;
|
||||
|
||||
if (((USB_DEVICE_DESCRIPTOR*)buf)->idVendor != PL_VID && ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct != PL_PID )
|
||||
if (((USB_DEVICE_DESCRIPTOR*)buf)->idVendor != PL_VID && ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct != PL_PID ) {
|
||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||
|
||||
// Save type of PL chip
|
||||
wPLType = ((USB_DEVICE_DESCRIPTOR*)buf)->bcdDevice;
|
||||
}
|
||||
|
||||
/* determine chip variant */
|
||||
|
||||
if (((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass == 0x02 ) {
|
||||
pltype = type_0;
|
||||
}
|
||||
else if (((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0 == 0x40 ) {
|
||||
pltype = rev_HX;
|
||||
}
|
||||
else if (((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass == 0x00) {
|
||||
pltype = type_1;
|
||||
}
|
||||
else if (((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass == 0xff) {
|
||||
pltype = type_1;
|
||||
}
|
||||
|
||||
// Allocate new address according to device class
|
||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||
|
@ -116,7 +130,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
|
||||
USBTRACE2("NC:", num_of_conf);
|
||||
|
||||
for (uint8_t i=0; i<num_of_conf; i++)
|
||||
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);
|
||||
|
@ -128,11 +142,11 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
break;
|
||||
} // for
|
||||
|
||||
if (bNumEP < 2)
|
||||
if ( bNumEP < 2 )
|
||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||
|
||||
// Assign epInfo to epinfo pointer
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
||||
rcode = pUsb->setEpInfoEntry( bAddress, bNumEP, epInfo );
|
||||
|
||||
USBTRACE2("Conf:", bConfNum);
|
||||
|
||||
|
@ -142,6 +156,29 @@ 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)
|
||||
|
@ -149,7 +186,8 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
|
||||
USBTRACE("PL configured\r\n");
|
||||
|
||||
bPollEnable = true;
|
||||
//bPollEnable = true;
|
||||
ready = true;
|
||||
return 0;
|
||||
|
||||
FailGetDevDescr:
|
||||
|
|
|
@ -38,11 +38,11 @@ e-mail : support@circuitsathome.com
|
|||
#include "confdescparser.h"
|
||||
#include "cdcacm.h"
|
||||
|
||||
//#define PL2303_COMPAT //uncomment it if you have compatibility problems
|
||||
|
||||
#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
|
||||
|
@ -128,6 +128,7 @@ enum tXO_State
|
|||
enum pl2303_type
|
||||
{
|
||||
unknown,
|
||||
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 */
|
||||
|
@ -137,9 +138,13 @@ enum pl2303_type
|
|||
|
||||
#define PL_MAX_ENDPOINTS 4
|
||||
|
||||
//class PL2303;
|
||||
|
||||
class PL2303 : public ACM
|
||||
{
|
||||
uint16_t wPLType; // Type of chip
|
||||
|
||||
//uint16_t wPLType; // Type of chip
|
||||
|
||||
|
||||
public:
|
||||
PL2303(USB *pusb, CDCAsyncOper *pasync);
|
||||
|
@ -152,6 +157,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__
|
|
@ -110,7 +110,7 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
|
|||
dscrType = *((uint8_t*)theBuffer.pValue + 1);
|
||||
stateParseDescr = 2;
|
||||
case 2:
|
||||
// This is a sort of hack. Assuming that two bytes are already in the buffer
|
||||
// This is a sort of hack. Assuming that two bytes are allready in the buffer
|
||||
// the pointer is positioned two bytes ahead in order for the rest of descriptor
|
||||
// to be read right after the size and the type fields.
|
||||
// This should be used carefuly. varBuffer should be used directly to handle data
|
||||
|
|
|
@ -68,8 +68,7 @@ void loop()
|
|||
{
|
||||
Usb.Task();
|
||||
|
||||
if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
|
||||
{
|
||||
if( Acm.isReady()) {
|
||||
uint8_t rcode;
|
||||
|
||||
/* reading the keyboard */
|
||||
|
|
|
@ -76,9 +76,8 @@ uint8_t buf[64]; //serial buffer equals Max.packet size of bulk-IN endpoint
|
|||
uint16_t rcvd = 64;
|
||||
|
||||
Usb.Task();
|
||||
|
||||
if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
|
||||
{
|
||||
|
||||
if( Pl.isReady()) {
|
||||
/* reading the GPS */
|
||||
if( read_delay < millis() ){
|
||||
read_delay += READ_DELAY;
|
||||
|
|
|
@ -95,7 +95,7 @@ void loop()
|
|||
{
|
||||
Usb.Task();
|
||||
|
||||
if( Usb.getUsbTaskState() == USB_STATE_RUNNING ) {
|
||||
if( Pl.isReady()) {
|
||||
|
||||
bool newdata = false;
|
||||
unsigned long start = millis();
|
||||
|
@ -210,7 +210,7 @@ bool feedgps()
|
|||
rcode = false;
|
||||
if( rcvd ) { //more than zero bytes received
|
||||
for( uint16_t i=0; i < rcvd; i++ ) {
|
||||
if( gps.encode(buf[i])) { //feed a character to gps object
|
||||
if( gps.encode((char)buf[i])) { //feed a character to gps object
|
||||
rcode = true;
|
||||
}//if( gps.encode(buf[i]...
|
||||
}//for( uint16_t i=0; i < rcvd; i++...
|
||||
|
|
|
@ -87,12 +87,6 @@ MAX3421e< SS, INTR >::MAX3421e()
|
|||
spi::init();
|
||||
INTR::SetDirRead();
|
||||
|
||||
#ifdef BOARD_MEGA_ADK
|
||||
/* For Mega ADK, which has Max3421e on-board, set MAX_RESET to Output mode, and pull Reset to HIGH */
|
||||
DDRJ |= 0x04;
|
||||
PORTJ |= 0x04;
|
||||
#endif
|
||||
|
||||
/* MAX3421E - full-duplex SPI, level interrupt */
|
||||
regWr( rPINCTL,( bmFDUPSPI + bmINTLEVEL ));
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue