mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
next big change
This commit is contained in:
parent
d3a52a7616
commit
2be575ffc0
8 changed files with 1071 additions and 1384 deletions
225
Usb.h
225
Usb.h
|
@ -138,32 +138,26 @@
|
|||
#define USB_ERROR_EPINFO_IS_NULL 0xD6
|
||||
#define USB_ERROR_INVALID_ARGUMENT 0xD7
|
||||
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD8
|
||||
|
||||
//class USBDeviceConfig
|
||||
//{
|
||||
//public:
|
||||
// virtual uint8_t Init(uint8_t addr) = 0;
|
||||
// virtual uint8_t Release(uint8_t addr) = 0;
|
||||
// virtual uint8_t Poll() = 0;
|
||||
//};
|
||||
#define USB_ERROR_INVALID_MAX_PKT_SIZE 0xD9
|
||||
#define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDA
|
||||
|
||||
class USBDeviceConfig
|
||||
{
|
||||
public:
|
||||
virtual uint8_t Init(uint8_t parent, uint8_t port) = 0;
|
||||
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed) = 0;
|
||||
virtual uint8_t Release() = 0;
|
||||
virtual uint8_t Poll() = 0;
|
||||
virtual uint8_t GetAddress() = 0;
|
||||
};
|
||||
|
||||
|
||||
#define USB_XFER_TIMEOUT 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. o meand NAKs are not counted
|
||||
#define USB_RETRY_LIMIT 3 //retry limit for a transfer
|
||||
#define USB_SETTLE_DELAY 200 //settle delay in milliseconds
|
||||
#define USB_NAK_NOWAIT 1 //used in Richard's PS2/Wiimote code
|
||||
|
||||
#define USB_NUMDEVICES 6 //number of USB devices
|
||||
#define HUB_MAX_HUBS 5 // maximum number of hubs that can be attached to the host controller
|
||||
#define USB_NUMDEVICES 64 //number of USB devices
|
||||
#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller
|
||||
#define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms
|
||||
|
||||
/* USB state machine states */
|
||||
|
@ -208,12 +202,12 @@ typedef struct {
|
|||
unsigned int wLength; // 6 Depends on bRequest
|
||||
} SETUP_PKT, *PSETUP_PKT;
|
||||
|
||||
/* device record structure */
|
||||
typedef struct
|
||||
{
|
||||
EP_RECORD *epinfo; //device endpoint information
|
||||
uint8_t devclass; //device class
|
||||
} DEV_RECORD;
|
||||
///* device record structure */
|
||||
//typedef struct
|
||||
//{
|
||||
// EpInfo *epinfo; //device endpoint information
|
||||
// uint8_t devclass; //device class
|
||||
//} DEV_RECORD;
|
||||
|
||||
|
||||
struct HubDescriptor
|
||||
|
@ -237,30 +231,30 @@ struct HubDescriptor
|
|||
};
|
||||
|
||||
|
||||
// Base class for incomming data parser
|
||||
class UsbReadParser
|
||||
{
|
||||
public:
|
||||
virtual void Parse(const uint8_t len, const uint8_t *pbuf, const uint16_t &offset) = 0;
|
||||
};
|
||||
|
||||
|
||||
//typedef MAX3421e<P6, P3> MAX3421E; // Black Widdow
|
||||
typedef MAX3421e<P10, P9> MAX3421E; // Duemielanove
|
||||
|
||||
class USB : public MAX3421E
|
||||
{
|
||||
//data structures
|
||||
/* device table. Filled during enumeration */
|
||||
/* index corresponds to device address */
|
||||
/* each entry contains pointer to endpoint structure */
|
||||
/* and device class to use in various places */
|
||||
//DEV_RECORD devtable[ USB_NUMDEVICES + 1 ];
|
||||
//EP_RECORD dev0ep; //Endpoint data structure used during enumeration for uninitialized device
|
||||
|
||||
//byte usb_task_state;
|
||||
|
||||
|
||||
AddressPoolImpl<USB_NUMDEVICES> addrPool;
|
||||
USBDeviceConfig* devConfig[USB_NUMDEVICES];
|
||||
uint8_t devConfigIndex;
|
||||
uint8_t bmHubPre;
|
||||
|
||||
public:
|
||||
USB( void );
|
||||
|
||||
void SetHubPreMask() { bmHubPre |= bmHUBPRE; };
|
||||
void ResetHubPreMask() { bmHubPre &= (~bmHUBPRE); };
|
||||
|
||||
AddressPool& GetAddressPool()
|
||||
{
|
||||
return (AddressPool&)addrPool;
|
||||
|
@ -284,163 +278,156 @@ class USB : public MAX3421E
|
|||
uint8_t getUsbTaskState( void );
|
||||
void setUsbTaskState( uint8_t state );
|
||||
|
||||
EP_RECORD* getDevTableEntry( uint8_t addr, uint8_t ep );
|
||||
uint8_t setDevTableEntry( uint8_t addr, EP_RECORD* eprecord_ptr );
|
||||
EpInfo* getEpInfoEntry( uint8_t addr, uint8_t ep );
|
||||
uint8_t setEpInfoEntry( uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr );
|
||||
|
||||
uint8_t ctrlReq( uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, unsigned int wInd, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t ctrlReq( uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, unsigned int wInd, unsigned int nbytes, uint8_t* dataptr);
|
||||
|
||||
/* Control requests */
|
||||
uint8_t getDevDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t getConfDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t conf, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t getStrDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t index, unsigned int langid, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t setAddr( uint8_t oldaddr, uint8_t ep, uint8_t newaddr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t setConf( uint8_t addr, uint8_t ep, uint8_t conf_value, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t getDevDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr );
|
||||
uint8_t getConfDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t conf, uint8_t* dataptr );
|
||||
uint8_t getStrDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t index, unsigned int langid, uint8_t* dataptr );
|
||||
uint8_t setAddr( uint8_t oldaddr, uint8_t ep, uint8_t newaddr );
|
||||
uint8_t setConf( uint8_t addr, uint8_t ep, uint8_t conf_value );
|
||||
/**/
|
||||
uint8_t setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t getProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t getReportDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t setReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t getReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t getIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t setIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t duration, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol );
|
||||
uint8_t getProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t* dataptr );
|
||||
uint8_t getReportDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr );
|
||||
uint8_t setReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr );
|
||||
uint8_t getReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr );
|
||||
uint8_t getIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr );
|
||||
uint8_t setIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t duration );
|
||||
/**/
|
||||
uint8_t ctrlData( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t ctrlStatus( uint8_t ep, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t inTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t outTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t dispatchPkt( uint8_t token, uint8_t ep, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t ctrlData( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, boolean direction );
|
||||
uint8_t ctrlStatus( uint8_t ep, boolean direction, uint16_t nak_limit );
|
||||
uint8_t inTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data );
|
||||
uint8_t outTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data );
|
||||
uint8_t dispatchPkt( uint8_t token, uint8_t ep, uint16_t nak_limit );
|
||||
|
||||
// Hub Methods
|
||||
uint8_t ClearHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t ClearPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel = 0, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t GetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t index, uint16_t nbytes, uint8_t *dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t GetHubStatus( uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t GetPortStatus( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t SetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t SetHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t SetPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel = 0, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
uint8_t ClearHubFeature( uint8_t addr, uint8_t ep, uint8_t fid );
|
||||
uint8_t ClearPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel = 0 );
|
||||
uint8_t GetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t index, uint16_t nbytes, uint8_t *dataptr );
|
||||
uint8_t GetHubStatus( uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr );
|
||||
uint8_t GetPortStatus( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr );
|
||||
uint8_t SetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr );
|
||||
uint8_t SetHubFeature( uint8_t addr, uint8_t ep, uint8_t fid );
|
||||
uint8_t SetPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel = 0 );
|
||||
|
||||
uint8_t HubPortPowerOn(uint8_t addr, uint8_t port);
|
||||
uint8_t HubPortReset(uint8_t addr, uint8_t port);
|
||||
uint8_t HubClearPortFeatures(uint8_t addr, uint8_t port, uint8_t bm_features);
|
||||
|
||||
uint8_t GetNumDevices();
|
||||
uint8_t GetNumHubs();
|
||||
|
||||
uint8_t PollHubs();
|
||||
uint8_t PollHub();
|
||||
|
||||
void PrintHubStatus(/*USB *usbptr,*/ uint8_t addr);
|
||||
|
||||
void Task( void );
|
||||
|
||||
uint8_t DefaultAddressing();
|
||||
uint8_t DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed);
|
||||
uint8_t Configuring(uint8_t parent, uint8_t port, bool lowspeed);
|
||||
uint8_t ReleaseDevice(uint8_t addr);
|
||||
|
||||
uint8_t Configuring(uint8_t parent, uint8_t port);
|
||||
//typedef void (*USBREADCALLBACK)(uint16_t nbytes, uint8_t *data, uint16_t offset);
|
||||
|
||||
//uint8_t ctrlReq( uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
|
||||
// uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBREADCALLBACK pf);
|
||||
|
||||
uint8_t ctrlReq( uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
|
||||
uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, UsbReadParser *p);
|
||||
|
||||
private:
|
||||
void init();
|
||||
uint8_t SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t &nak_limit);
|
||||
uint8_t OutTransfer(EpInfo *pep, uint16_t nak_limit, unsigned int nbytes, uint8_t *data);
|
||||
uint8_t InTransfer (EpInfo *pep, uint16_t nak_limit, unsigned int nbytes, uint8_t* data);
|
||||
};
|
||||
|
||||
#if defined(USB_METHODS_INLINE)
|
||||
//#if defined(USB_METHODS_INLINE)
|
||||
//get device descriptor
|
||||
inline uint8_t USB::getDevDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr, nak_limit ));
|
||||
inline uint8_t USB::getDevDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr ));
|
||||
}
|
||||
//get configuration descriptor
|
||||
inline uint8_t USB::getConfDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t conf, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr, nak_limit ));
|
||||
inline uint8_t USB::getConfDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t conf, uint8_t* dataptr ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr ));
|
||||
}
|
||||
//get string descriptor
|
||||
inline uint8_t USB::getStrDescr( uint8_t addr, uint8_t ep, unsigned int nuint8_ts, uint8_t index, unsigned int langid, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr, nak_limit ));
|
||||
inline uint8_t USB::getStrDescr( uint8_t addr, uint8_t ep, unsigned int nuint8_ts, uint8_t index, unsigned int langid, uint8_t* dataptr ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr ));
|
||||
}
|
||||
//set address
|
||||
inline uint8_t USB::setAddr( uint8_t oldaddr, uint8_t ep, uint8_t newaddr, unsigned int nak_limit ) {
|
||||
return( ctrlReq( oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL, nak_limit ));
|
||||
inline uint8_t USB::setAddr( uint8_t oldaddr, uint8_t ep, uint8_t newaddr ) {
|
||||
return( ctrlReq( oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL ));
|
||||
}
|
||||
//set configuration
|
||||
inline uint8_t USB::setConf( uint8_t addr, uint8_t ep, uint8_t conf_value, unsigned int nak_limit ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL, nak_limit ));
|
||||
inline uint8_t USB::setConf( uint8_t addr, uint8_t ep, uint8_t conf_value ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL ));
|
||||
}
|
||||
//class requests
|
||||
inline uint8_t USB::setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol, unsigned int nak_limit ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, interface, 0x0000, NULL, nak_limit ));
|
||||
inline uint8_t USB::setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_PROTOCOL, protocol, 0x00, interface, 0x0000, NULL ));
|
||||
}
|
||||
inline uint8_t USB::getProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, interface, 0x0001, dataptr, nak_limit ));
|
||||
inline uint8_t USB::getProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t* dataptr ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, interface, 0x0001, dataptr ));
|
||||
}
|
||||
//get HID report descriptor
|
||||
inline uint8_t USB::getReportDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, dataptr, nak_limit ));
|
||||
inline uint8_t USB::getReportDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, HID_DESCRIPTOR_REPORT, 0x0000, nbytes, dataptr ));
|
||||
}
|
||||
inline uint8_t USB::setReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit ));
|
||||
inline uint8_t USB::setReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, report_id, report_type, interface, nbytes, dataptr ));
|
||||
}
|
||||
inline uint8_t USB::getReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr, unsigned int nak_limit ) { // ** RI 04/11/09
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, dataptr, nak_limit ));
|
||||
inline uint8_t USB::getReport( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t interface, uint8_t report_type, uint8_t report_id, uint8_t* dataptr ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, dataptr ));
|
||||
}
|
||||
/* returns one byte of data in dataptr */
|
||||
inline uint8_t USB::getIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr, unsigned int nak_limit ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, reportID, 0, interface, 0x0001, dataptr, nak_limit ));
|
||||
inline uint8_t USB::getIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t* dataptr ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_IDLE, reportID, 0, interface, 0x0001, dataptr ));
|
||||
}
|
||||
inline uint8_t USB::setIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t duration, unsigned int nak_limit ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, interface, 0x0000, NULL, nak_limit ));
|
||||
inline uint8_t USB::setIdle( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t reportID, uint8_t duration ) {
|
||||
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, interface, 0x0000, NULL ));
|
||||
}
|
||||
|
||||
// uint8_t ctrlReq(
|
||||
//uint8_t addr,
|
||||
//uint8_t ep,
|
||||
//uint8_t bmReqType,
|
||||
//uint8_t bRequest,
|
||||
//uint8_t wValLo,
|
||||
//uint8_t wValHi,
|
||||
//unsigned int wInd,
|
||||
//unsigned int nbytes,
|
||||
//uint8_t* dataptr,
|
||||
//unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
|
||||
// Clear Hub Feature
|
||||
inline uint8_t USB::ClearHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, unsigned int nak_limit )
|
||||
inline uint8_t USB::ClearHubFeature( uint8_t addr, uint8_t ep, uint8_t fid )
|
||||
{
|
||||
return( ctrlReq( addr, ep, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, NULL, nak_limit ));
|
||||
return( ctrlReq( addr, ep, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, NULL ));
|
||||
}
|
||||
// Clear Port Feature
|
||||
inline uint8_t USB::ClearPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel, unsigned int nak_limit )
|
||||
inline uint8_t USB::ClearPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel )
|
||||
{
|
||||
return( ctrlReq( addr, ep, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000|port)|(sel<<8)), 0, NULL, nak_limit ));
|
||||
return( ctrlReq( addr, ep, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000|port)|(sel<<8)), 0, NULL ));
|
||||
}
|
||||
// Get Hub Descriptor
|
||||
inline uint8_t USB::GetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t index, uint16_t nbytes, uint8_t *dataptr, unsigned int nak_limit )
|
||||
inline uint8_t USB::GetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t index, uint16_t nbytes, uint8_t *dataptr )
|
||||
{
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, dataptr, nak_limit ));
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, dataptr ));
|
||||
}
|
||||
// Get Hub Status
|
||||
inline uint8_t USB::GetHubStatus( uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit )
|
||||
inline uint8_t USB::GetHubStatus( uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr )
|
||||
{
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, dataptr, nak_limit ));
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, dataptr ));
|
||||
}
|
||||
// Get Port Status
|
||||
inline uint8_t USB::GetPortStatus( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit )
|
||||
inline uint8_t USB::GetPortStatus( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr )
|
||||
{
|
||||
//Serial.println(bmREQ_GET_PORT_STATUS, BIN);
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, dataptr, nak_limit ));
|
||||
return( ctrlReq( addr, ep, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, dataptr ));
|
||||
}
|
||||
// Set Hub Descriptor
|
||||
inline uint8_t USB::SetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr, unsigned int nak_limit )
|
||||
inline uint8_t USB::SetHubDescriptor( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr )
|
||||
{
|
||||
return( ctrlReq( addr, ep, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, dataptr, nak_limit ));
|
||||
return( ctrlReq( addr, ep, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, dataptr ));
|
||||
}
|
||||
// Set Hub Feature
|
||||
inline uint8_t USB::SetHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, unsigned int nak_limit )
|
||||
inline uint8_t USB::SetHubFeature( uint8_t addr, uint8_t ep, uint8_t fid )
|
||||
{
|
||||
return( ctrlReq( addr, ep, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, NULL, nak_limit ));
|
||||
return( ctrlReq( addr, ep, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, NULL ));
|
||||
}
|
||||
// Set Port Feature
|
||||
inline uint8_t USB::SetPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel, unsigned int nak_limit )
|
||||
inline uint8_t USB::SetPortFeature( uint8_t addr, uint8_t ep, uint8_t fid, uint8_t port, uint8_t sel )
|
||||
{
|
||||
return( ctrlReq( addr, ep, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000|sel)<<8)|port), 0, NULL, nak_limit ));
|
||||
return( ctrlReq( addr, ep, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000|sel)<<8)|port), 0, NULL ));
|
||||
}
|
||||
#endif // defined(USB_METHODS_INLINE)
|
||||
//#endif // defined(USB_METHODS_INLINE)
|
||||
|
||||
#endif //_usb_h_
|
89
address.h
89
address.h
|
@ -4,19 +4,25 @@
|
|||
#include <inttypes.h>
|
||||
#include "max3421e.h"
|
||||
|
||||
/* Endpoint information structure */
|
||||
/* bToggle of endpoint 0 initialized to 0xff */
|
||||
/* during enumeration bToggle is set to 00 */
|
||||
typedef struct
|
||||
#define USB_NAK_MAX_POWER 15 //NAK binary order maximum value
|
||||
|
||||
struct EpInfo
|
||||
{
|
||||
uint8_t epAddr; //copy from endpoint descriptor. Bit 7 indicates direction ( ignored for control endpoints )
|
||||
uint8_t Attr; // Endpoint transfer type.
|
||||
unsigned int MaxPktSize; // Maximum packet size.
|
||||
uint8_t Interval; // Polling interval in frames.
|
||||
uint8_t sndToggle; //last toggle value, bitmask for HCTL toggle bits
|
||||
uint8_t rcvToggle; //last toggle value, bitmask for HCTL toggle bits
|
||||
/* not sure if both are necessary */
|
||||
} EP_RECORD;
|
||||
uint8_t epAddr; // Endpoint address
|
||||
uint8_t maxPktSize; // Maximum packet size
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t epAttribs;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t bmSndToggle : 1; // Send toggle, when zerro bmSNDTOG0, bmSNDTOG1 otherwise
|
||||
uint8_t bmRcvToggle : 1; // Send toggle, when zerro bmRCVTOG0, bmRCVTOG1 otherwise
|
||||
uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// ---------------------------------
|
||||
|
@ -48,10 +54,11 @@ struct UsbDeviceAddress
|
|||
|
||||
struct UsbDevice
|
||||
{
|
||||
EP_RECORD *epinfo; // endpoint info pointer
|
||||
EpInfo *epinfo; // endpoint info pointer
|
||||
uint8_t address; // address
|
||||
uint8_t epcount; // number of endpoints
|
||||
bool lowspeed; // indicates if a device is the low speed one
|
||||
uint8_t devclass; // device class
|
||||
// uint8_t devclass; // device class
|
||||
};
|
||||
|
||||
class AddressPool
|
||||
|
@ -70,7 +77,7 @@ typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev);
|
|||
template <const uint8_t MAX_DEVICES_ALLOWED>
|
||||
class AddressPoolImpl : public AddressPool
|
||||
{
|
||||
EP_RECORD dev0ep; //Endpoint data structure used during enumeration for uninitialized device
|
||||
EpInfo dev0ep; //Endpoint data structure used during enumeration for uninitialized device
|
||||
|
||||
uint8_t hubCounter; // hub counter is kept
|
||||
// in order to avoid hub address duplication
|
||||
|
@ -81,6 +88,7 @@ class AddressPoolImpl : public AddressPool
|
|||
void InitEntry(uint8_t index)
|
||||
{
|
||||
thePool[index].address = 0;
|
||||
thePool[index].epcount = 1;
|
||||
thePool[index].lowspeed = 0;
|
||||
thePool[index].epinfo = &dev0ep;
|
||||
};
|
||||
|
@ -141,9 +149,9 @@ public:
|
|||
thePool[0].address = 0;
|
||||
thePool[0].epinfo = &dev0ep;
|
||||
dev0ep.epAddr = 0;
|
||||
dev0ep.MaxPktSize = 8;
|
||||
dev0ep.sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
||||
dev0ep.rcvToggle = bmRCVTOG0;
|
||||
dev0ep.maxPktSize = 8;
|
||||
dev0ep.epAttribs = 0; //set DATA0/1 toggles to 0
|
||||
dev0ep.bmNakPower = USB_NAK_MAX_POWER;
|
||||
|
||||
InitAllAddresses();
|
||||
};
|
||||
|
@ -171,20 +179,28 @@ public:
|
|||
// Allocates new address
|
||||
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0)
|
||||
{
|
||||
if (parent != 0 && port == 0)
|
||||
Serial.println("PRT:0");
|
||||
|
||||
if (parent > 127 || port > 7)
|
||||
return 0;
|
||||
|
||||
// finds first empty address entry starting from one
|
||||
uint8_t index = FindAddressIndex(0);
|
||||
|
||||
Serial.println(index, DEC);
|
||||
|
||||
if (!index) // if empty entry is not found
|
||||
return 0;
|
||||
|
||||
if (parent == 0)
|
||||
{
|
||||
thePool[index].address = (is_hub) ? 0x41 : 1;
|
||||
if (is_hub)
|
||||
{
|
||||
thePool[index].address = 0x41;
|
||||
hubCounter ++;
|
||||
}
|
||||
else
|
||||
thePool[index].address = 1;
|
||||
|
||||
return thePool[index].address;
|
||||
}
|
||||
|
||||
|
@ -204,6 +220,13 @@ public:
|
|||
}
|
||||
thePool[index].address = *((uint8_t*)&addr);
|
||||
|
||||
Serial.print("Addr:");
|
||||
Serial.print(addr.bmHub, HEX);
|
||||
Serial.print(".");
|
||||
Serial.print(addr.bmParent, HEX);
|
||||
Serial.print(".");
|
||||
Serial.println(addr.bmAddress, HEX);
|
||||
|
||||
return thePool[index].address;
|
||||
};
|
||||
// Empties pool entry
|
||||
|
@ -220,20 +243,20 @@ public:
|
|||
};
|
||||
// Returns number of hubs attached
|
||||
// It can be rather helpfull to find out if there are hubs attached than getting the exact number of hubs.
|
||||
uint8_t GetNumHubs()
|
||||
{
|
||||
return hubCounter;
|
||||
};
|
||||
uint8_t GetNumDevices()
|
||||
{
|
||||
uint8_t counter = 0;
|
||||
//uint8_t GetNumHubs()
|
||||
//{
|
||||
// return hubCounter;
|
||||
//};
|
||||
//uint8_t GetNumDevices()
|
||||
//{
|
||||
// uint8_t counter = 0;
|
||||
|
||||
for (uint8_t i=1; i<MAX_DEVICES_ALLOWED; i++)
|
||||
if (thePool[i].address != 0);
|
||||
counter ++;
|
||||
// for (uint8_t i=1; i<MAX_DEVICES_ALLOWED; i++)
|
||||
// if (thePool[i].address != 0);
|
||||
// counter ++;
|
||||
|
||||
return counter;
|
||||
};
|
||||
// return counter;
|
||||
//};
|
||||
};
|
||||
|
||||
#endif // __ADDRESS_H__
|
|
@ -9,8 +9,8 @@
|
|||
/* pin numbers to port numbers */
|
||||
|
||||
//#define MAX_SS 10
|
||||
//#define MAX_INT 3 // Black Widdow
|
||||
#define MAX_INT 9 // Duemielanove
|
||||
#define MAX_INT 3 // Black Widdow
|
||||
//#define MAX_INT 9 // Duemielanove
|
||||
|
||||
#define MAX_GPX 8
|
||||
//#define MAX_RESET 7
|
||||
|
|
|
@ -249,7 +249,7 @@ uint8_t MAX3421e< SS, INTR >::Task( void )
|
|||
uint8_t pinvalue;
|
||||
//Serial.print("Vbus state: ");
|
||||
//Serial.println( vbusState, HEX );
|
||||
pinvalue = INTR::Read();
|
||||
pinvalue = INTR::IsSet(); //Read();
|
||||
//pinvalue = digitalRead( MAX_INT );
|
||||
if( pinvalue == LOW ) {
|
||||
rcode = IntHandler();
|
||||
|
|
204
usbhub.cpp
204
usbhub.cpp
|
@ -1,35 +1,34 @@
|
|||
#include "usbhub.h"
|
||||
|
||||
bool USBHub::bResetInitiated = false;
|
||||
|
||||
USBHub::USBHub(USB *p) :
|
||||
pUsb(p),
|
||||
bAddress(0),
|
||||
bNbrPorts(0),
|
||||
bInitState(0),
|
||||
// bPortResetCounter(1),
|
||||
qNextPollTime(0),
|
||||
bPollEnable(false)
|
||||
{
|
||||
epInfo[0].epAddr = 0;
|
||||
epInfo[0].MaxPktSize = 8;
|
||||
epInfo[0].sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
||||
epInfo[0].rcvToggle = bmRCVTOG0;
|
||||
epInfo[0].maxPktSize = 8;
|
||||
epInfo[0].epAttribs = 0;
|
||||
epInfo[0].bmNakPower = USB_NAK_MAX_POWER;
|
||||
|
||||
epInfo[1].epAddr = 1;
|
||||
epInfo[1].MaxPktSize = 1;
|
||||
epInfo[1].Interval = 0xff;
|
||||
epInfo[1].sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
||||
epInfo[1].rcvToggle = bmRCVTOG0;
|
||||
epInfo[1].maxPktSize = 1;
|
||||
epInfo[1].epAttribs = 0;
|
||||
|
||||
if (pUsb)
|
||||
pUsb->RegisterDeviceClass(this);
|
||||
}
|
||||
|
||||
uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||
uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
uint8_t rcode;
|
||||
UsbDevice *p = NULL;
|
||||
EP_RECORD *oldep_ptr = NULL;
|
||||
EpInfo *oldep_ptr = NULL;
|
||||
uint8_t len = 0;
|
||||
uint16_t cd_len = 0;
|
||||
|
||||
|
@ -38,8 +37,6 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
|||
switch (bInitState)
|
||||
{
|
||||
case 0:
|
||||
Serial.println("Init");
|
||||
|
||||
if (bAddress)
|
||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||
|
||||
|
@ -50,10 +47,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
|||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
|
||||
if (!p->epinfo)
|
||||
{
|
||||
Serial.println("epinfo");
|
||||
return USB_ERROR_EPINFO_IS_NULL;
|
||||
}
|
||||
|
||||
// Save old pointer to EP_RECORD of address 0
|
||||
oldep_ptr = p->epinfo;
|
||||
|
@ -61,9 +55,13 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
|||
// 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, 8, (uint8_t*)buf );
|
||||
|
||||
p->lowspeed = false;
|
||||
|
||||
if (!rcode)
|
||||
len = (buf[0] > 32) ? 32 : buf[0];
|
||||
|
||||
|
@ -71,8 +69,6 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
|||
{
|
||||
// Restore p->epinfo
|
||||
p->epinfo = oldep_ptr;
|
||||
|
||||
Serial.println("getDevDesc:");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
|
@ -88,7 +84,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
|||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||
|
||||
// Extract Max Packet Size from the device descriptor
|
||||
epInfo[0].MaxPktSize = ((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
||||
epInfo[0].maxPktSize = ((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
||||
|
||||
// Assign new address to the device
|
||||
rcode = pUsb->setAddr( 0, 0, bAddress );
|
||||
|
@ -99,14 +95,9 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
|||
p->epinfo = oldep_ptr;
|
||||
addrPool.FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
Serial.print("setAddr:");
|
||||
Serial.println(rcode, HEX);
|
||||
return rcode;
|
||||
}
|
||||
|
||||
Serial.print("Addr:");
|
||||
Serial.println(bAddress, HEX);
|
||||
|
||||
// Restore p->epinfo
|
||||
p->epinfo = oldep_ptr;
|
||||
|
||||
|
@ -117,7 +108,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
|||
goto FailGetDevDescr;
|
||||
|
||||
// Assign epInfo to epinfo pointer
|
||||
rcode = pUsb->setDevTableEntry(bAddress, epInfo);
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, 2, epInfo);
|
||||
|
||||
if (rcode)
|
||||
goto FailSetDevTblEntry;
|
||||
|
@ -159,17 +150,12 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
|||
goto FailGetConfDescr;
|
||||
}
|
||||
|
||||
Serial.print("Conf val:");
|
||||
Serial.println(buf[5], HEX);
|
||||
|
||||
// Set Configuration Value
|
||||
rcode = pUsb->setConf(bAddress, 0, buf[5]);
|
||||
|
||||
if (rcode)
|
||||
goto FailSetConfDescr;
|
||||
|
||||
Serial.println("Hub configured");
|
||||
|
||||
bInitState = 3;
|
||||
|
||||
case 3:
|
||||
|
@ -177,8 +163,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
|||
for (uint8_t j=1; j<=bNbrPorts; j++)
|
||||
pUsb->HubPortPowerOn(bAddress, j);
|
||||
|
||||
Serial.println("Ports powered");
|
||||
|
||||
pUsb->SetHubPreMask();
|
||||
bPollEnable = true;
|
||||
bInitState = 0;
|
||||
}
|
||||
|
@ -186,31 +171,24 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
|||
return 0;
|
||||
|
||||
FailGetDevDescr:
|
||||
Serial.print("getDevDescr:");
|
||||
goto Fail;
|
||||
|
||||
FailSetDevTblEntry:
|
||||
Serial.print("setDevTblEn:");
|
||||
goto Fail;
|
||||
|
||||
FailGetHubDescr:
|
||||
Serial.print("getHub:");
|
||||
goto Fail;
|
||||
|
||||
FailGetConfDescr:
|
||||
Serial.print("getConf:");
|
||||
goto Fail;
|
||||
|
||||
FailSetConfDescr:
|
||||
Serial.print("setConf:");
|
||||
goto Fail;
|
||||
|
||||
FailGetPortStatus:
|
||||
Serial.print("GetPortStatus:");
|
||||
goto Fail;
|
||||
|
||||
Fail:
|
||||
Serial.println(rcode, HEX);
|
||||
return rcode;
|
||||
}
|
||||
|
||||
|
@ -218,9 +196,11 @@ uint8_t USBHub::Release()
|
|||
{
|
||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||
|
||||
if (bAddress == 0x41)
|
||||
pUsb->SetHubPreMask();
|
||||
|
||||
bAddress = 0;
|
||||
bNbrPorts = 0;
|
||||
// bPortResetCounter = 0;
|
||||
qNextPollTime = 0;
|
||||
bPollEnable = false;
|
||||
return 0;
|
||||
|
@ -235,51 +215,27 @@ uint8_t USBHub::Poll()
|
|||
|
||||
if (qNextPollTime <= millis())
|
||||
{
|
||||
Serial.print("Poll:");
|
||||
Serial.println(bAddress, HEX);
|
||||
|
||||
rcode = GetHubStatus(bAddress);
|
||||
if (rcode)
|
||||
{
|
||||
Serial.print("HubStatus:");
|
||||
Serial.println(rcode,HEX);
|
||||
}
|
||||
qNextPollTime = millis() + 100;
|
||||
}
|
||||
return rcode;
|
||||
}
|
||||
|
||||
|
||||
//bmHUB_PORT_STATUS_C_PORT_CONNECTION
|
||||
//bmHUB_PORT_STATUS_C_PORT_ENABLE
|
||||
//bmHUB_PORT_STATUS_C_PORT_SUSPEND
|
||||
//bmHUB_PORT_STATUS_C_PORT_OVER_CURRENT
|
||||
//bmHUB_PORT_STATUS_C_PORT_RESET
|
||||
|
||||
uint8_t USBHub::GetHubStatus(uint8_t addr)
|
||||
{
|
||||
uint8_t rcode;
|
||||
uint8_t buf[8];
|
||||
|
||||
// uint8_t inTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data, unsigned int nak_limit = USB_NAK_LIMIT );
|
||||
//Serial.println(devtable[1].epinfo->epAddr, HEX);
|
||||
|
||||
rcode = pUsb->inTransfer(addr, 1, 1, buf, 1);
|
||||
rcode = pUsb->inTransfer(addr, 1, 1, buf);
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
Serial.print("inTransfer:");
|
||||
Serial.println(rcode, HEX);
|
||||
return rcode;
|
||||
}
|
||||
Serial.print("Int:");
|
||||
Serial.println(buf[0],HEX);
|
||||
|
||||
//return 0;
|
||||
|
||||
if (buf[0] & 0x01) // Hub Status Change
|
||||
{
|
||||
pUsb->PrintHubStatus(addr);
|
||||
//pUsb->PrintHubStatus(addr);
|
||||
//rcode = GetHubStatus(1, 0, 1, 4, buf);
|
||||
//if (rcode)
|
||||
//{
|
||||
|
@ -298,91 +254,91 @@ uint8_t USBHub::GetHubStatus(uint8_t addr)
|
|||
rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff);
|
||||
|
||||
if (rcode)
|
||||
{
|
||||
Serial.print("GetPortStatus err:");
|
||||
Serial.println(rcode, HEX);
|
||||
Serial.print("on port:");
|
||||
Serial.println(port, DEC);
|
||||
continue;
|
||||
}
|
||||
HubPortStatusChange(addr, port, evt);
|
||||
|
||||
rcode = HubPortStatusChange(addr, port, evt);
|
||||
|
||||
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
||||
return 0;
|
||||
|
||||
if (rcode)
|
||||
return rcode;
|
||||
}
|
||||
} // for
|
||||
|
||||
for (uint8_t port=1; port<=bNbrPorts; port++)
|
||||
{
|
||||
HubEvent evt;
|
||||
evt.bmEvent = 0;
|
||||
|
||||
rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff);
|
||||
|
||||
if (rcode)
|
||||
continue;
|
||||
|
||||
if ((evt.bmStatus & bmHUB_PORT_STATE_CHECK_DISABLED) != bmHUB_PORT_STATE_DISABLED)
|
||||
continue;
|
||||
|
||||
// Emulate connection event for the port
|
||||
evt.bmChange |= bmHUB_PORT_STATUS_C_PORT_CONNECTION;
|
||||
|
||||
rcode = HubPortStatusChange(addr, port, evt);
|
||||
|
||||
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
||||
return 0;
|
||||
|
||||
if (rcode)
|
||||
return rcode;
|
||||
} // for
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
|
||||
uint8_t USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
|
||||
{
|
||||
Serial.print("Prt:");
|
||||
Serial.print(port,HEX);
|
||||
|
||||
Serial.print("\tEvt:");
|
||||
Serial.println(evt.bmEvent,HEX);
|
||||
Serial.print("\tSt:");
|
||||
Serial.println(evt.bmStatus,HEX);
|
||||
Serial.print("\tCh:");
|
||||
Serial.println(evt.bmChange,HEX);
|
||||
|
||||
|
||||
//Serial.print("Con:");
|
||||
//Serial.println(bmHUB_PORT_EVENT_CONNECT, HEX);
|
||||
|
||||
//Serial.print("Rc:");
|
||||
//Serial.println(bmHUB_PORT_EVENT_RESET_COMPLETE, HEX);
|
||||
|
||||
PrintHubPortStatus(pUsb, addr, port, true);
|
||||
|
||||
switch (evt.bmEvent)
|
||||
{
|
||||
//case (bmHUB_PORT_STATE_DISABLED | bmHUB_PORT_STATUS_C_PORT_CONNECTION | bmHUB_PORT_STATUS_C_PORT_SUSPEND):
|
||||
// Serial.println("DIS");
|
||||
// pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_PORT_ENABLE | HUB_FEATURE_C_PORT_CONNECTION);
|
||||
// pUsb->HubPortReset(addr, port);
|
||||
// break;
|
||||
|
||||
// Device connected event
|
||||
case bmHUB_PORT_EVENT_CONNECT:
|
||||
Serial.println("CON");
|
||||
case bmHUB_PORT_EVENT_LS_CONNECT:
|
||||
if (bResetInitiated)
|
||||
return 0;
|
||||
|
||||
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_ENABLE);
|
||||
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_CONNECTION);
|
||||
pUsb->HubPortReset(addr, port);
|
||||
break;
|
||||
bResetInitiated = true;
|
||||
return HUB_ERROR_PORT_HAS_BEEN_RESET;
|
||||
|
||||
// Device disconnected event
|
||||
case bmHUB_PORT_EVENT_DISCONNECT:
|
||||
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_ENABLE);
|
||||
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_CONNECTION);
|
||||
bResetInitiated = false;
|
||||
|
||||
UsbDeviceAddress a;
|
||||
a.bmHub = 0;
|
||||
a.bmParent = addr;
|
||||
a.bmAddress = port;
|
||||
pUsb->ReleaseDevice(a.devAddress);
|
||||
return 0;
|
||||
|
||||
// Reset complete event
|
||||
case bmHUB_PORT_EVENT_RESET_COMPLETE:
|
||||
Serial.println("RCMPL");
|
||||
case bmHUB_PORT_EVENT_LS_RESET_COMPLETE:
|
||||
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_RESET | HUB_FEATURE_C_PORT_CONNECTION);
|
||||
|
||||
// Check if device is a low-speed device
|
||||
if (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED)
|
||||
{
|
||||
UsbDevice *p = pUsb->GetAddressPool().GetUsbDevicePtr(addr);
|
||||
delay(20);
|
||||
|
||||
if (p)
|
||||
p->lowspeed = true;
|
||||
}
|
||||
a.devAddress = addr;
|
||||
|
||||
delay(50);
|
||||
|
||||
pUsb->Configuring(addr, port);
|
||||
pUsb->Configuring(a.bmAddress, port, (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED) );
|
||||
bResetInitiated = false;
|
||||
break;
|
||||
|
||||
// Suspended or resuming state
|
||||
case bmHUB_PORT_STATE_SUSPENDED:
|
||||
Serial.println("SUSP");
|
||||
break;
|
||||
|
||||
// Resume complete event
|
||||
case (bmHUB_PORT_STATE_ENABLED | HUB_FEATURE_C_PORT_SUSPEND):
|
||||
break;
|
||||
|
||||
//case bmHUB_PORT_STATE_RESUMING:
|
||||
// break;
|
||||
|
||||
} // switch (evt.bmEvent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes)
|
||||
{
|
||||
uint8_t rcode = 0;
|
||||
|
|
54
usbhub.h
54
usbhub.h
|
@ -19,25 +19,27 @@
|
|||
#define USB_STATE_HUB_PORT_RESETTING 0xb5
|
||||
#define USB_STATE_HUB_PORT_ENABLED 0xb6
|
||||
|
||||
// Additional Error Codes
|
||||
#define HUB_ERROR_PORT_HAS_BEEN_RESET 0xb1
|
||||
|
||||
|
||||
// The bit mask to check for all necessary state bits
|
||||
#define bmHUB_PORT_STATUS_ALL_MAIN ((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION | bmHUB_PORT_STATUS_C_PORT_ENABLE | bmHUB_PORT_STATUS_C_PORT_SUSPEND | bmHUB_PORT_STATUS_C_PORT_RESET) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_SUSPEND)
|
||||
|
||||
// Bit mask to check for DISABLED state in HubEvent::bmStatus field
|
||||
#define bmHUB_PORT_STATE_CHECK_DISABLED (0x0000 | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_SUSPEND)
|
||||
|
||||
// Hub Port States
|
||||
//#define bmHUB_PORT_STATE_POWERED ((0UL | bmHUB_PORT_STATUS_PORT_POWER) << 16)
|
||||
#define bmHUB_PORT_STATE_DISCONNECTED ((0UL | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE) << 16)
|
||||
|
||||
#define bmHUB_PORT_STATE_DISABLED ((0UL | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION))
|
||||
|
||||
#define bmHUB_PORT_STATE_RESETTING ((0UL | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_RESET) << 16)
|
||||
#define bmHUB_PORT_STATE_ENABLED ((0UL | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE) << 16)
|
||||
#define bmHUB_PORT_STATE_SUSPENDED ((0UL | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_SUSPEND) << 16)
|
||||
#define bmHUB_PORT_STATE_DISABLED (0x0000 | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
||||
|
||||
// Hub Port Events
|
||||
#define bmHUB_PORT_EVENT_CONNECT (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION) << 16) | bmHUB_PORT_STATE_DISABLED)
|
||||
#define bmHUB_PORT_EVENT_CONNECT (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
||||
#define bmHUB_PORT_EVENT_DISCONNECT (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION) << 16) | bmHUB_PORT_STATUS_PORT_POWER)
|
||||
#define bmHUB_PORT_EVENT_RESET_COMPLETE (((0UL | bmHUB_PORT_STATUS_C_PORT_RESET) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
||||
|
||||
#define bmHUB_PORT_EVENT_PORT_ENABLED (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION | bmHUB_PORT_STATUS_C_PORT_ENABLE) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
||||
#define bmHUB_PORT_EVENT_LS_CONNECT (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_LOW_SPEED)
|
||||
#define bmHUB_PORT_EVENT_LS_RESET_COMPLETE (((0UL | bmHUB_PORT_STATUS_C_PORT_RESET) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_LOW_SPEED)
|
||||
#define bmHUB_PORT_EVENT_LS_PORT_ENABLED (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION | bmHUB_PORT_STATUS_C_PORT_ENABLE) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_ENABLE | bmHUB_PORT_STATUS_PORT_CONNECTION | bmHUB_PORT_STATUS_PORT_LOW_SPEED)
|
||||
|
||||
struct HubEvent
|
||||
{
|
||||
|
@ -56,50 +58,30 @@ struct HubEvent
|
|||
|
||||
class USBHub : USBDeviceConfig
|
||||
{
|
||||
static bool bResetInitiated; // True when reset is triggered
|
||||
|
||||
USB *pUsb; // USB class instance pointer
|
||||
|
||||
EP_RECORD epInfo[2]; // interrupt endpoint info structure
|
||||
EpInfo epInfo[2]; // interrupt endpoint info structure
|
||||
|
||||
uint8_t bAddress; // address
|
||||
uint8_t bNbrPorts; // number of ports
|
||||
uint8_t bInitState; // initialization state variable
|
||||
// uint8_t bPortResetCounter; // number of ports reset
|
||||
uint32_t qNextPollTime; // next poll time
|
||||
bool bPollEnable; // poll enable flag
|
||||
|
||||
uint8_t GetHubStatus(uint8_t addr);
|
||||
void HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt);
|
||||
uint8_t HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt);
|
||||
|
||||
public:
|
||||
USBHub(USB *p);
|
||||
|
||||
virtual uint8_t Init(uint8_t parent, uint8_t port);
|
||||
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; };
|
||||
};
|
||||
|
||||
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes = false);
|
||||
|
||||
|
||||
// ---------------------------------
|
||||
// | H | H | H | P | P | P | S | S |
|
||||
// ---------------------------------
|
||||
// H - hub ID
|
||||
// P - port number
|
||||
// S - port state
|
||||
|
||||
struct UsbHubPortState
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t bmState : 2;
|
||||
uint8_t bmPort : 3;
|
||||
uint8_t bmHub : 3;
|
||||
};
|
||||
uint8_t portState;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // __USBHUB_H__
|
Loading…
Reference in a new issue