mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
FTDI fixed
This commit is contained in:
parent
b30f62d931
commit
cf1611cb48
11 changed files with 3298 additions and 51 deletions
2
README
2
README
|
@ -1,5 +1,5 @@
|
|||
This is Rev.2.0 of MAX3421E-based USB Host Library for Arduino. At the moment, this repo contains current development copy
|
||||
of the code facilitating developer's exchange. For those not involved in the project, the code in its current state doesn't bear any value.
|
||||
of the code facilitating developer's exchange. For those not involved in the project, the code in its' current state doesn't bear any value.
|
||||
In other words, nothing works yet.
|
||||
|
||||
The code uses slightly modified Konstantin Chizhov's AVR pin templates, see the original here -> https://github.com/KonstantinChizhov/AvrProjects
|
8
Usb.cpp
8
Usb.cpp
|
@ -153,7 +153,7 @@ uint8_t USB::ctrlReq( uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequ
|
|||
|
||||
rcode = InTransfer( pep, nak_limit, &read, dataptr );
|
||||
|
||||
if (rcode)
|
||||
if (rcode /*&& rcode != hrSTALL*/)
|
||||
return rcode;
|
||||
|
||||
// Invoke callback function if inTransfer completed successfuly and callback function pointer is specified
|
||||
|
@ -194,7 +194,7 @@ uint8_t USB::inTransfer( uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t*
|
|||
|
||||
uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t* data)
|
||||
{
|
||||
uint8_t rcode;
|
||||
uint8_t rcode = 0;
|
||||
uint8_t pktsize;
|
||||
|
||||
uint16_t nbytes = *nbytesptr;
|
||||
|
@ -212,9 +212,9 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
|
|||
|
||||
/* check for RCVDAVIRQ and generate error if not present */
|
||||
/* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */
|
||||
if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 ) {
|
||||
if(( regRd( rHIRQ ) & bmRCVDAVIRQ ) == 0 )
|
||||
return ( 0xf0 ); //receive error
|
||||
}
|
||||
|
||||
pktsize = regRd( rRCVBC ); //number of received bytes
|
||||
|
||||
int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
|
||||
|
|
40
cdcacm.cpp
40
cdcacm.cpp
|
@ -238,31 +238,31 @@ uint8_t ACM::Poll()
|
|||
|
||||
uint32_t time_now = millis();
|
||||
|
||||
if (qNextPollTime <= time_now)
|
||||
{
|
||||
qNextPollTime = time_now + 100;
|
||||
//if (qNextPollTime <= time_now)
|
||||
//{
|
||||
// qNextPollTime = time_now + 100;
|
||||
|
||||
uint8_t rcode;
|
||||
const uint8_t constBufSize = 16;
|
||||
uint8_t buf[constBufSize];
|
||||
// uint8_t rcode;
|
||||
// const uint8_t constBufSize = 16;
|
||||
// uint8_t buf[constBufSize];
|
||||
|
||||
for (uint8_t i=0; i<constBufSize; i++)
|
||||
buf[i] = 0;
|
||||
// for (uint8_t i=0; i<constBufSize; i++)
|
||||
// buf[i] = 0;
|
||||
|
||||
uint16_t read = (constBufSize > epInfo[epInterruptInIndex].maxPktSize)
|
||||
? epInfo[epInterruptInIndex].maxPktSize : constBufSize;
|
||||
rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, &read, buf);
|
||||
// uint16_t read = (constBufSize > epInfo[epInterruptInIndex].maxPktSize)
|
||||
// ? epInfo[epInterruptInIndex].maxPktSize : constBufSize;
|
||||
// rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, &read, buf);
|
||||
|
||||
if (rcode)
|
||||
return rcode;
|
||||
// if (rcode)
|
||||
// return rcode;
|
||||
|
||||
for (uint8_t i=0; i<read; i++)
|
||||
{
|
||||
PrintHex<uint8_t>(buf[i]);
|
||||
Serial.print(" ");
|
||||
}
|
||||
USBTRACE("\r\n");
|
||||
}
|
||||
// for (uint8_t i=0; i<read; i++)
|
||||
// {
|
||||
// PrintHex<uint8_t>(buf[i]);
|
||||
// Serial.print(" ");
|
||||
// }
|
||||
// USBTRACE("\r\n");
|
||||
//}
|
||||
return rcode;
|
||||
}
|
||||
|
||||
|
|
22
cdcftdi.cpp
22
cdcftdi.cpp
|
@ -4,9 +4,11 @@ const uint8_t FTDI::epDataInIndex = 1;
|
|||
const uint8_t FTDI::epDataOutIndex = 2;
|
||||
const uint8_t FTDI::epInterruptInIndex = 3;
|
||||
|
||||
FTDI::FTDI(USB *p) :
|
||||
FTDI::FTDI(USB *p, FTDIAsyncOper *pasync) :
|
||||
pAsync(pasync),
|
||||
pUsb(p),
|
||||
bAddress(0),
|
||||
bNumEP(1),
|
||||
wFTDIType(0)
|
||||
{
|
||||
for(uint8_t i=0; i<FTDI_MAX_ENDPOINTS; i++)
|
||||
|
@ -135,6 +137,8 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
if (bNumEP < 2)
|
||||
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
|
||||
|
||||
USBTRACE2("NumEP:", bNumEP);
|
||||
|
||||
// Assign epInfo to epinfo pointer
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
||||
|
||||
|
@ -146,17 +150,10 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
if (rcode)
|
||||
goto FailSetConfDescr;
|
||||
|
||||
rcode = SetBaudRate(115200);
|
||||
rcode = pAsync->OnInit(this);
|
||||
|
||||
if (rcode)
|
||||
goto FailSetBaudRate;
|
||||
|
||||
rcode = SetFlowControl(FTDI_SIO_DISABLE_FLOW_CTRL);
|
||||
//rcode = SetFlowControl(FTDI_SIO_SET_DTR_HIGH);
|
||||
|
||||
if (rcode)
|
||||
goto FailSetFlowControl;
|
||||
|
||||
goto FailOnInit;
|
||||
|
||||
USBTRACE("FTDI configured\r\n");
|
||||
|
||||
|
@ -187,6 +184,10 @@ FailSetFlowControl:
|
|||
USBTRACE("SetFlowControl:");
|
||||
goto Fail;
|
||||
|
||||
FailOnInit:
|
||||
USBTRACE("OnInit:");
|
||||
goto Fail;
|
||||
|
||||
Fail:
|
||||
Serial.println(rcode, HEX);
|
||||
Release();
|
||||
|
@ -227,6 +228,7 @@ uint8_t FTDI::Release()
|
|||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||
|
||||
bAddress = 0;
|
||||
bNumEP = 1;
|
||||
qNextPollTime = 0;
|
||||
bPollEnable = false;
|
||||
return 0;
|
||||
|
|
12
cdcftdi.h
12
cdcftdi.h
|
@ -71,6 +71,15 @@
|
|||
#define FTDI_SIO_RI_MASK 0x40
|
||||
#define FTDI_SIO_RLSD_MASK 0x80
|
||||
|
||||
class FTDI;
|
||||
|
||||
class FTDIAsyncOper
|
||||
{
|
||||
public:
|
||||
virtual uint8_t OnInit(FTDI *pftdi) = 0;
|
||||
};
|
||||
|
||||
|
||||
// Only single port chips are currently supported by the library,
|
||||
// so only three endpoints are allocated.
|
||||
#define FTDI_MAX_ENDPOINTS 3
|
||||
|
@ -81,6 +90,7 @@ class FTDI : public USBDeviceConfig, public UsbConfigXtracter
|
|||
static const uint8_t epDataOutIndex; // DataOUT endpoint index
|
||||
static const uint8_t epInterruptInIndex; // InterruptIN endpoint index
|
||||
|
||||
FTDIAsyncOper *pAsync;
|
||||
USB *pUsb;
|
||||
uint8_t bAddress;
|
||||
uint8_t bConfNum; // configuration number
|
||||
|
@ -95,7 +105,7 @@ class FTDI : public USBDeviceConfig, public UsbConfigXtracter
|
|||
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
||||
|
||||
public:
|
||||
FTDI(USB *pusb);
|
||||
FTDI(USB *pusb, FTDIAsyncOper *pasync);
|
||||
|
||||
uint8_t SetBaudRate(uint32_t baud);
|
||||
uint8_t SetModemControl(uint16_t control);
|
||||
|
|
|
@ -4,6 +4,13 @@
|
|||
#include <inttypes.h>
|
||||
#include "..\ParseTools\parsetools.h"
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include "..\DebugTools\printhex.h"
|
||||
#include "..\DebugTools\hexdump.h"
|
||||
#include "..\DebugTools\message.h"
|
||||
|
||||
//#include "hid.h"
|
||||
|
||||
class UsbConfigXtracter
|
||||
{
|
||||
public:
|
||||
|
@ -25,7 +32,7 @@ class ConfigDescParser : public USBReadParser
|
|||
MultiValueBuffer theBuffer;
|
||||
MultiByteValueParser valParser;
|
||||
ByteSkipper theSkipper;
|
||||
uint8_t varBuffer[sizeof(USB_CONFIGURATION_DESCRIPTOR)];
|
||||
uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/];
|
||||
|
||||
uint8_t stateParseDescr; // ParseDescriptor state
|
||||
|
||||
|
@ -40,6 +47,8 @@ class ConfigDescParser : public USBReadParser
|
|||
|
||||
bool ParseDescriptor(uint8_t **pp, uint16_t *pcntdn);
|
||||
|
||||
void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
|
||||
|
||||
public:
|
||||
ConfigDescParser(UsbConfigXtracter *xtractor);
|
||||
virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset);
|
||||
|
@ -102,6 +111,9 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
|
|||
case USB_DESCRIPTOR_ENDPOINT:
|
||||
theBuffer.valueSize = sizeof(USB_ENDPOINT_DESCRIPTOR) - 2;
|
||||
break;
|
||||
case HID_DESCRIPTOR_HID:
|
||||
theBuffer.valueSize = dscrLen - 2;
|
||||
break;
|
||||
}
|
||||
valParser.Initialize(&theBuffer);
|
||||
stateParseDescr = 4;
|
||||
|
@ -135,6 +147,11 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
|
|||
if (theXtractor)
|
||||
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
|
||||
break;
|
||||
case HID_DESCRIPTOR_HID:
|
||||
if (!valParser.Parse(pp, pcntdn))
|
||||
return false;
|
||||
PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
|
||||
break;
|
||||
default:
|
||||
if (!theSkipper.Skip(pp, pcntdn, dscrLen-2))
|
||||
return false;
|
||||
|
@ -145,4 +162,43 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
|
|||
return true;
|
||||
}
|
||||
|
||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
||||
void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc)
|
||||
{
|
||||
Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"));
|
||||
Notify(PSTR("bDescLength:\t\t"));
|
||||
PrintHex<uint8_t>(pDesc->bLength);
|
||||
|
||||
Notify(PSTR("\r\nbDescriptorType:\t"));
|
||||
PrintHex<uint8_t>(pDesc->bDescriptorType);
|
||||
|
||||
Notify(PSTR("\r\nbcdHID:\t\t\t"));
|
||||
PrintHex<uint16_t>(pDesc->bcdHID);
|
||||
|
||||
Notify(PSTR("\r\nbCountryCode:\t\t"));
|
||||
PrintHex<uint8_t>(pDesc->bCountryCode);
|
||||
|
||||
Notify(PSTR("\r\nbNumDescriptors:\t"));
|
||||
PrintHex<uint8_t>(pDesc->bNumDescriptors);
|
||||
|
||||
//Notify(PSTR("\r\nbDescrType:\t\t"));
|
||||
//PrintHex<uint8_t>(pDesc->bDescrType);
|
||||
//
|
||||
//Notify(PSTR("\r\nwDescriptorLength:\t"));
|
||||
//PrintHex<uint16_t>(pDesc->wDescriptorLength);
|
||||
|
||||
for (uint8_t i=0; i<pDesc->bNumDescriptors; i++)
|
||||
{
|
||||
HID_CLASS_DESCRIPTOR_LEN_AND_TYPE *pLT = (HID_CLASS_DESCRIPTOR_LEN_AND_TYPE*)&(pDesc->bDescrType);
|
||||
|
||||
Notify(PSTR("\r\nbDescrType:\t\t"));
|
||||
PrintHex<uint8_t>(pLT[i].bDescrType);
|
||||
|
||||
Notify(PSTR("\r\nwDescriptorLength:\t"));
|
||||
PrintHex<uint16_t>(pLT[i].wDescriptorLength);
|
||||
}
|
||||
Notify(PSTR("\r\n"));
|
||||
}
|
||||
|
||||
|
||||
#endif // __CONFDESCPARSER_H__
|
97
masstorage.h
Normal file
97
masstorage.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
#if !defined(__MASSTORAGE_H__)
|
||||
#define __MASSTORAGE_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "avrpins.h"
|
||||
#include "max3421e.h"
|
||||
#include "usbhost.h"
|
||||
#include "usb_ch9.h"
|
||||
#include "Usb.h"
|
||||
#include <WProgram.h>
|
||||
|
||||
#include "..\DebugTools\printhex.h"
|
||||
#include "..\DebugTools\hexdump.h"
|
||||
#include "..\DebugTools\message.h"
|
||||
|
||||
#include "confdescparser.h"
|
||||
|
||||
//#define bmREQ_CDCOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
//#define bmREQ_CDCIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
|
||||
// Mass Storage Subclass Constants
|
||||
#define MASS_SUBCLASS_SCSI_NOT_REPORTED 0x00 // De facto use
|
||||
#define MASS_SUBCLASS_RBC 0x01
|
||||
#define MASS_SUBCLASS_ATAPI 0x02 // MMC-5 (ATAPI)
|
||||
#define MASS_SUBCLASS_OBSOLETE1 0x03 // Was QIC-157
|
||||
#define MASS_SUBCLASS_UFI 0x04 // Specifies how to interface Floppy Disk Drives to USB
|
||||
#define MASS_SUBCLASS_OBSOLETE2 0x05 // Was SFF-8070i
|
||||
#define MASS_SUBCLASS_SCSI 0x06 // SCSI Transparent Command Set
|
||||
#define MASS_SUBCLASS_LSDFS 0x07 // Specifies how host has to negotiate access before trying SCSI
|
||||
#define MASS_SUBCLASS_IEEE1667 0x08
|
||||
|
||||
// Mass Storage Class Protocols
|
||||
#define MASS_PROTO_CBI 0x00 // CBI (with command completion interrupt)
|
||||
#define MASS_PROTO_CBI_NO_INT 0x01 // CBI (without command completion interrupt)
|
||||
#define MASS_PROTO_OBSOLETE 0x02
|
||||
#define MASS_PROTO_BBB 0x50 // Bulk Only Transport
|
||||
#define MASS_PROTO_UAS 0x62
|
||||
|
||||
// Request Codes
|
||||
#define MASS_REQ_ADSC 0x00
|
||||
#define MASS_REQ_GET 0xFC
|
||||
#define MASS_REQ_PUT 0xFD
|
||||
#define MASS_REQ_GET_MAX_LUN 0xFE
|
||||
#define MASS_REQ_BOMSR 0xFF // Bulk-Only Mass Storage Reset
|
||||
|
||||
#define MASS_CBW_SIGNATURE 0x43425355
|
||||
#define MASS_CBS_SIGNATURE 0x53425355
|
||||
|
||||
struct CommandBlockWrapper
|
||||
{
|
||||
uint32_t dCBWSignature;
|
||||
uint32_t dCBWTag;
|
||||
uint32_t dCBWDataTransferLength;
|
||||
uint8_t bmCBWFlags;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t bCBWLUN : 4;
|
||||
uint8_r bReserved1 : 4;
|
||||
};
|
||||
struct
|
||||
{
|
||||
uint8_t bCBWCBLength : 4;
|
||||
uint8_t bReserved2 : 4;
|
||||
};
|
||||
|
||||
uint8_t CBWCB[16];
|
||||
};
|
||||
|
||||
struct CommandStatusWrapper
|
||||
{
|
||||
uint32_t dCSWSignature;
|
||||
uint32_t dCSWTag;
|
||||
uint32_t dCSWDataResidue;
|
||||
uint8_t bCSWStatus;
|
||||
};
|
||||
|
||||
class BulkOnly : public USBDeviceConfig, public UsbConfigXtracter
|
||||
{
|
||||
public:
|
||||
uint8_t Reset();
|
||||
uint8_t GetMaxLun(uint8_t *max_lun);
|
||||
|
||||
uint8_t ResetRecovery();
|
||||
|
||||
// USBDeviceConfig implementation
|
||||
virtual 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 // __MASSTORAGE_H__
|
23
usb_ch9.h
23
usb_ch9.h
|
@ -52,6 +52,10 @@
|
|||
#define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // bDescriptorType for Interface Power.
|
||||
#define USB_DESCRIPTOR_OTG 0x09 // bDescriptorType for an OTG Descriptor.
|
||||
|
||||
#define HID_DESCRIPTOR_HID 0x21
|
||||
|
||||
|
||||
|
||||
/* OTG SET FEATURE Constants */
|
||||
#define OTG_FEATURE_B_HNP_ENABLE 3 // SET FEATURE OTG - Enable B device to perform HNP
|
||||
#define OTG_FEATURE_A_HNP_SUPPORT 4 // SET FEATURE OTG - A device supports HNP
|
||||
|
@ -128,4 +132,23 @@ typedef struct
|
|||
uint8_t bInterval; // Polling interval in frames.
|
||||
} USB_ENDPOINT_DESCRIPTOR;
|
||||
|
||||
|
||||
/* HID descriptor */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID; // HID class specification release
|
||||
uint8_t bCountryCode;
|
||||
uint8_t bNumDescriptors; // Number of additional class specific descriptors
|
||||
uint8_t bDescrType; // Type of class descriptor
|
||||
uint16_t wDescriptorLength; // Total size of the Report descriptor
|
||||
} USB_HID_DESCRIPTOR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bDescrType; // Type of class descriptor
|
||||
uint16_t wDescriptorLength; // Total size of the Report descriptor
|
||||
} HID_CLASS_DESCRIPTOR_LEN_AND_TYPE;
|
||||
|
||||
#endif // _ch9_h_
|
||||
|
|
Loading…
Reference in a new issue