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_EPINFO_IS_NULL 0xD6
|
||||||
#define USB_ERROR_INVALID_ARGUMENT 0xD7
|
#define USB_ERROR_INVALID_ARGUMENT 0xD7
|
||||||
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD8
|
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD8
|
||||||
|
#define USB_ERROR_INVALID_MAX_PKT_SIZE 0xD9
|
||||||
//class USBDeviceConfig
|
#define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDA
|
||||||
//{
|
|
||||||
//public:
|
|
||||||
// virtual uint8_t Init(uint8_t addr) = 0;
|
|
||||||
// virtual uint8_t Release(uint8_t addr) = 0;
|
|
||||||
// virtual uint8_t Poll() = 0;
|
|
||||||
//};
|
|
||||||
|
|
||||||
class USBDeviceConfig
|
class USBDeviceConfig
|
||||||
{
|
{
|
||||||
public:
|
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 Release() = 0;
|
||||||
virtual uint8_t Poll() = 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_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_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_RETRY_LIMIT 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_NAK_NOWAIT 1 //used in Richard's PS2/Wiimote code
|
#define USB_NAK_NOWAIT 1 //used in Richard's PS2/Wiimote code
|
||||||
|
|
||||||
#define USB_NUMDEVICES 6 //number of USB devices
|
#define USB_NUMDEVICES 64 //number of USB devices
|
||||||
#define HUB_MAX_HUBS 5 // maximum number of hubs that can be attached to the host controller
|
#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
|
#define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms
|
||||||
|
|
||||||
/* USB state machine states */
|
/* USB state machine states */
|
||||||
|
@ -208,12 +202,12 @@ typedef struct {
|
||||||
unsigned int wLength; // 6 Depends on bRequest
|
unsigned int wLength; // 6 Depends on bRequest
|
||||||
} SETUP_PKT, *PSETUP_PKT;
|
} SETUP_PKT, *PSETUP_PKT;
|
||||||
|
|
||||||
/* device record structure */
|
///* device record structure */
|
||||||
typedef struct
|
//typedef struct
|
||||||
{
|
//{
|
||||||
EP_RECORD *epinfo; //device endpoint information
|
// EpInfo *epinfo; //device endpoint information
|
||||||
uint8_t devclass; //device class
|
// uint8_t devclass; //device class
|
||||||
} DEV_RECORD;
|
//} DEV_RECORD;
|
||||||
|
|
||||||
|
|
||||||
struct HubDescriptor
|
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<P6, P3> MAX3421E; // Black Widdow
|
||||||
typedef MAX3421e<P10, P9> MAX3421E; // Duemielanove
|
typedef MAX3421e<P10, P9> MAX3421E; // Duemielanove
|
||||||
|
|
||||||
class USB : public MAX3421E
|
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;
|
AddressPoolImpl<USB_NUMDEVICES> addrPool;
|
||||||
USBDeviceConfig* devConfig[USB_NUMDEVICES];
|
USBDeviceConfig* devConfig[USB_NUMDEVICES];
|
||||||
uint8_t devConfigIndex;
|
uint8_t devConfigIndex;
|
||||||
|
uint8_t bmHubPre;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
USB( void );
|
USB( void );
|
||||||
|
|
||||||
|
void SetHubPreMask() { bmHubPre |= bmHUBPRE; };
|
||||||
|
void ResetHubPreMask() { bmHubPre &= (~bmHUBPRE); };
|
||||||
|
|
||||||
AddressPool& GetAddressPool()
|
AddressPool& GetAddressPool()
|
||||||
{
|
{
|
||||||
return (AddressPool&)addrPool;
|
return (AddressPool&)addrPool;
|
||||||
|
@ -284,163 +278,156 @@ class USB : public MAX3421E
|
||||||
uint8_t getUsbTaskState( void );
|
uint8_t getUsbTaskState( void );
|
||||||
void setUsbTaskState( uint8_t state );
|
void setUsbTaskState( uint8_t state );
|
||||||
|
|
||||||
EP_RECORD* getDevTableEntry( uint8_t addr, uint8_t ep );
|
EpInfo* getEpInfoEntry( uint8_t addr, uint8_t ep );
|
||||||
uint8_t setDevTableEntry( uint8_t addr, EP_RECORD* eprecord_ptr );
|
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 */
|
/* 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 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, 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 );
|
||||||
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 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, unsigned int nak_limit = USB_NAK_LIMIT );
|
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, unsigned int nak_limit = USB_NAK_LIMIT );
|
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 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, unsigned int nak_limit = USB_NAK_LIMIT );
|
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, unsigned int nak_limit = USB_NAK_LIMIT );
|
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, 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 );
|
||||||
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 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, 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 );
|
||||||
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 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 ctrlData( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, boolean direction );
|
||||||
uint8_t ctrlStatus( uint8_t ep, boolean direction, unsigned int nak_limit = USB_NAK_LIMIT );
|
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, unsigned int nak_limit = USB_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, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t outTransfer( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* data );
|
||||||
uint8_t dispatchPkt( uint8_t token, uint8_t ep, unsigned int nak_limit = USB_NAK_LIMIT );
|
uint8_t dispatchPkt( uint8_t token, uint8_t ep, uint16_t nak_limit );
|
||||||
|
|
||||||
// Hub Methods
|
// Hub Methods
|
||||||
uint8_t ClearHubFeature( uint8_t addr, uint8_t ep, uint8_t fid, 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, 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 );
|
||||||
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 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, unsigned int nak_limit = USB_NAK_LIMIT );
|
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, 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 );
|
||||||
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 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, unsigned int nak_limit = USB_NAK_LIMIT );
|
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, 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 );
|
||||||
|
|
||||||
uint8_t HubPortPowerOn(uint8_t addr, uint8_t port);
|
uint8_t HubPortPowerOn(uint8_t addr, uint8_t port);
|
||||||
uint8_t HubPortReset(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 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 PrintHubStatus(/*USB *usbptr,*/ uint8_t addr);
|
||||||
|
|
||||||
void Task( void );
|
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:
|
private:
|
||||||
void init();
|
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
|
//get device descriptor
|
||||||
inline uint8_t USB::getDevDescr( uint8_t addr, uint8_t ep, unsigned int nbytes, uint8_t* dataptr, unsigned int 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, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr ));
|
||||||
}
|
}
|
||||||
//get configuration descriptor
|
//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 ) {
|
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, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr ));
|
||||||
}
|
}
|
||||||
//get string descriptor
|
//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 ) {
|
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, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr ));
|
||||||
}
|
}
|
||||||
//set address
|
//set address
|
||||||
inline uint8_t USB::setAddr( uint8_t oldaddr, uint8_t ep, uint8_t newaddr, unsigned int 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, nak_limit ));
|
return( ctrlReq( oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL ));
|
||||||
}
|
}
|
||||||
//set configuration
|
//set configuration
|
||||||
inline uint8_t USB::setConf( uint8_t addr, uint8_t ep, uint8_t conf_value, unsigned int 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, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL ));
|
||||||
}
|
}
|
||||||
//class requests
|
//class requests
|
||||||
inline uint8_t USB::setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol, unsigned int 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, nak_limit ));
|
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 ) {
|
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, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_PROTOCOL, 0x00, 0x00, interface, 0x0001, dataptr ));
|
||||||
}
|
}
|
||||||
//get HID report descriptor
|
//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 ) {
|
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, nak_limit ));
|
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 ) {
|
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, nak_limit ));
|
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
|
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, nak_limit ));
|
return( ctrlReq( addr, ep, bmREQ_HIDIN, HID_REQUEST_GET_REPORT, report_id, report_type, interface, nbytes, dataptr ));
|
||||||
}
|
}
|
||||||
/* returns one byte of data in 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 ) {
|
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, nak_limit ));
|
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 ) {
|
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, nak_limit ));
|
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
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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 ));
|
||||||
return( ctrlReq( addr, ep, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, dataptr, nak_limit ));
|
|
||||||
}
|
}
|
||||||
// Set Hub Descriptor
|
// 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
|
// 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
|
// 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_
|
#endif //_usb_h_
|
89
address.h
89
address.h
|
@ -4,19 +4,25 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "max3421e.h"
|
#include "max3421e.h"
|
||||||
|
|
||||||
/* Endpoint information structure */
|
#define USB_NAK_MAX_POWER 15 //NAK binary order maximum value
|
||||||
/* bToggle of endpoint 0 initialized to 0xff */
|
|
||||||
/* during enumeration bToggle is set to 00 */
|
struct EpInfo
|
||||||
typedef struct
|
|
||||||
{
|
{
|
||||||
uint8_t epAddr; //copy from endpoint descriptor. Bit 7 indicates direction ( ignored for control endpoints )
|
uint8_t epAddr; // Endpoint address
|
||||||
uint8_t Attr; // Endpoint transfer type.
|
uint8_t maxPktSize; // Maximum packet size
|
||||||
unsigned int MaxPktSize; // Maximum packet size.
|
|
||||||
uint8_t Interval; // Polling interval in frames.
|
union
|
||||||
uint8_t sndToggle; //last toggle value, bitmask for HCTL toggle bits
|
{
|
||||||
uint8_t rcvToggle; //last toggle value, bitmask for HCTL toggle bits
|
uint8_t epAttribs;
|
||||||
/* not sure if both are necessary */
|
|
||||||
} EP_RECORD;
|
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
|
// 7 6 5 4 3 2 1 0
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
|
@ -48,10 +54,11 @@ struct UsbDeviceAddress
|
||||||
|
|
||||||
struct UsbDevice
|
struct UsbDevice
|
||||||
{
|
{
|
||||||
EP_RECORD *epinfo; // endpoint info pointer
|
EpInfo *epinfo; // endpoint info pointer
|
||||||
uint8_t address; // address
|
uint8_t address; // address
|
||||||
|
uint8_t epcount; // number of endpoints
|
||||||
bool lowspeed; // indicates if a device is the low speed one
|
bool lowspeed; // indicates if a device is the low speed one
|
||||||
uint8_t devclass; // device class
|
// uint8_t devclass; // device class
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddressPool
|
class AddressPool
|
||||||
|
@ -70,7 +77,7 @@ typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev);
|
||||||
template <const uint8_t MAX_DEVICES_ALLOWED>
|
template <const uint8_t MAX_DEVICES_ALLOWED>
|
||||||
class AddressPoolImpl : public AddressPool
|
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
|
uint8_t hubCounter; // hub counter is kept
|
||||||
// in order to avoid hub address duplication
|
// in order to avoid hub address duplication
|
||||||
|
@ -81,6 +88,7 @@ class AddressPoolImpl : public AddressPool
|
||||||
void InitEntry(uint8_t index)
|
void InitEntry(uint8_t index)
|
||||||
{
|
{
|
||||||
thePool[index].address = 0;
|
thePool[index].address = 0;
|
||||||
|
thePool[index].epcount = 1;
|
||||||
thePool[index].lowspeed = 0;
|
thePool[index].lowspeed = 0;
|
||||||
thePool[index].epinfo = &dev0ep;
|
thePool[index].epinfo = &dev0ep;
|
||||||
};
|
};
|
||||||
|
@ -141,9 +149,9 @@ public:
|
||||||
thePool[0].address = 0;
|
thePool[0].address = 0;
|
||||||
thePool[0].epinfo = &dev0ep;
|
thePool[0].epinfo = &dev0ep;
|
||||||
dev0ep.epAddr = 0;
|
dev0ep.epAddr = 0;
|
||||||
dev0ep.MaxPktSize = 8;
|
dev0ep.maxPktSize = 8;
|
||||||
dev0ep.sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
dev0ep.epAttribs = 0; //set DATA0/1 toggles to 0
|
||||||
dev0ep.rcvToggle = bmRCVTOG0;
|
dev0ep.bmNakPower = USB_NAK_MAX_POWER;
|
||||||
|
|
||||||
InitAllAddresses();
|
InitAllAddresses();
|
||||||
};
|
};
|
||||||
|
@ -171,20 +179,28 @@ public:
|
||||||
// Allocates new address
|
// Allocates new address
|
||||||
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0)
|
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)
|
if (parent > 127 || port > 7)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// finds first empty address entry starting from one
|
// finds first empty address entry starting from one
|
||||||
uint8_t index = FindAddressIndex(0);
|
uint8_t index = FindAddressIndex(0);
|
||||||
|
|
||||||
Serial.println(index, DEC);
|
|
||||||
|
|
||||||
if (!index) // if empty entry is not found
|
if (!index) // if empty entry is not found
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (parent == 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;
|
return thePool[index].address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +220,13 @@ public:
|
||||||
}
|
}
|
||||||
thePool[index].address = *((uint8_t*)&addr);
|
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;
|
return thePool[index].address;
|
||||||
};
|
};
|
||||||
// Empties pool entry
|
// Empties pool entry
|
||||||
|
@ -220,20 +243,20 @@ public:
|
||||||
};
|
};
|
||||||
// Returns number of hubs attached
|
// 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.
|
// It can be rather helpfull to find out if there are hubs attached than getting the exact number of hubs.
|
||||||
uint8_t GetNumHubs()
|
//uint8_t GetNumHubs()
|
||||||
{
|
//{
|
||||||
return hubCounter;
|
// return hubCounter;
|
||||||
};
|
//};
|
||||||
uint8_t GetNumDevices()
|
//uint8_t GetNumDevices()
|
||||||
{
|
//{
|
||||||
uint8_t counter = 0;
|
// uint8_t counter = 0;
|
||||||
|
|
||||||
for (uint8_t i=1; i<MAX_DEVICES_ALLOWED; i++)
|
// for (uint8_t i=1; i<MAX_DEVICES_ALLOWED; i++)
|
||||||
if (thePool[i].address != 0);
|
// if (thePool[i].address != 0);
|
||||||
counter ++;
|
// counter ++;
|
||||||
|
|
||||||
return counter;
|
// return counter;
|
||||||
};
|
//};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __ADDRESS_H__
|
#endif // __ADDRESS_H__
|
|
@ -9,8 +9,8 @@
|
||||||
/* pin numbers to port numbers */
|
/* pin numbers to port numbers */
|
||||||
|
|
||||||
//#define MAX_SS 10
|
//#define MAX_SS 10
|
||||||
//#define MAX_INT 3 // Black Widdow
|
#define MAX_INT 3 // Black Widdow
|
||||||
#define MAX_INT 9 // Duemielanove
|
//#define MAX_INT 9 // Duemielanove
|
||||||
|
|
||||||
#define MAX_GPX 8
|
#define MAX_GPX 8
|
||||||
//#define MAX_RESET 7
|
//#define MAX_RESET 7
|
||||||
|
|
|
@ -249,7 +249,7 @@ uint8_t MAX3421e< SS, INTR >::Task( void )
|
||||||
uint8_t pinvalue;
|
uint8_t pinvalue;
|
||||||
//Serial.print("Vbus state: ");
|
//Serial.print("Vbus state: ");
|
||||||
//Serial.println( vbusState, HEX );
|
//Serial.println( vbusState, HEX );
|
||||||
pinvalue = INTR::Read();
|
pinvalue = INTR::IsSet(); //Read();
|
||||||
//pinvalue = digitalRead( MAX_INT );
|
//pinvalue = digitalRead( MAX_INT );
|
||||||
if( pinvalue == LOW ) {
|
if( pinvalue == LOW ) {
|
||||||
rcode = IntHandler();
|
rcode = IntHandler();
|
||||||
|
|
204
usbhub.cpp
204
usbhub.cpp
|
@ -1,35 +1,34 @@
|
||||||
#include "usbhub.h"
|
#include "usbhub.h"
|
||||||
|
|
||||||
|
bool USBHub::bResetInitiated = false;
|
||||||
|
|
||||||
USBHub::USBHub(USB *p) :
|
USBHub::USBHub(USB *p) :
|
||||||
pUsb(p),
|
pUsb(p),
|
||||||
bAddress(0),
|
bAddress(0),
|
||||||
bNbrPorts(0),
|
bNbrPorts(0),
|
||||||
bInitState(0),
|
bInitState(0),
|
||||||
// bPortResetCounter(1),
|
|
||||||
qNextPollTime(0),
|
qNextPollTime(0),
|
||||||
bPollEnable(false)
|
bPollEnable(false)
|
||||||
{
|
{
|
||||||
epInfo[0].epAddr = 0;
|
epInfo[0].epAddr = 0;
|
||||||
epInfo[0].MaxPktSize = 8;
|
epInfo[0].maxPktSize = 8;
|
||||||
epInfo[0].sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
epInfo[0].epAttribs = 0;
|
||||||
epInfo[0].rcvToggle = bmRCVTOG0;
|
epInfo[0].bmNakPower = USB_NAK_MAX_POWER;
|
||||||
|
|
||||||
epInfo[1].epAddr = 1;
|
epInfo[1].epAddr = 1;
|
||||||
epInfo[1].MaxPktSize = 1;
|
epInfo[1].maxPktSize = 1;
|
||||||
epInfo[1].Interval = 0xff;
|
epInfo[1].epAttribs = 0;
|
||||||
epInfo[1].sndToggle = bmSNDTOG0; //set DATA0/1 toggles to 0
|
|
||||||
epInfo[1].rcvToggle = bmRCVTOG0;
|
|
||||||
|
|
||||||
if (pUsb)
|
if (pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
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 buf[32];
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
UsbDevice *p = NULL;
|
UsbDevice *p = NULL;
|
||||||
EP_RECORD *oldep_ptr = NULL;
|
EpInfo *oldep_ptr = NULL;
|
||||||
uint8_t len = 0;
|
uint8_t len = 0;
|
||||||
uint16_t cd_len = 0;
|
uint16_t cd_len = 0;
|
||||||
|
|
||||||
|
@ -38,8 +37,6 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
switch (bInitState)
|
switch (bInitState)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
Serial.println("Init");
|
|
||||||
|
|
||||||
if (bAddress)
|
if (bAddress)
|
||||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
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;
|
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||||
|
|
||||||
if (!p->epinfo)
|
if (!p->epinfo)
|
||||||
{
|
|
||||||
Serial.println("epinfo");
|
|
||||||
return USB_ERROR_EPINFO_IS_NULL;
|
return USB_ERROR_EPINFO_IS_NULL;
|
||||||
}
|
|
||||||
|
|
||||||
// Save old pointer to EP_RECORD of address 0
|
// Save old pointer to EP_RECORD of address 0
|
||||||
oldep_ptr = p->epinfo;
|
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
|
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
||||||
p->epinfo = epInfo;
|
p->epinfo = epInfo;
|
||||||
|
|
||||||
|
p->lowspeed = lowspeed;
|
||||||
|
|
||||||
// Get device descriptor
|
// Get device descriptor
|
||||||
rcode = pUsb->getDevDescr( 0, 0, 8, (uint8_t*)buf );
|
rcode = pUsb->getDevDescr( 0, 0, 8, (uint8_t*)buf );
|
||||||
|
|
||||||
|
p->lowspeed = false;
|
||||||
|
|
||||||
if (!rcode)
|
if (!rcode)
|
||||||
len = (buf[0] > 32) ? 32 : buf[0];
|
len = (buf[0] > 32) ? 32 : buf[0];
|
||||||
|
|
||||||
|
@ -71,8 +69,6 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
{
|
{
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
Serial.println("getDevDesc:");
|
|
||||||
return rcode;
|
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;
|
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||||
|
|
||||||
// Extract Max Packet Size from the device descriptor
|
// 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
|
// Assign new address to the device
|
||||||
rcode = pUsb->setAddr( 0, 0, bAddress );
|
rcode = pUsb->setAddr( 0, 0, bAddress );
|
||||||
|
@ -99,14 +95,9 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
addrPool.FreeAddress(bAddress);
|
addrPool.FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
Serial.print("setAddr:");
|
|
||||||
Serial.println(rcode, HEX);
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.print("Addr:");
|
|
||||||
Serial.println(bAddress, HEX);
|
|
||||||
|
|
||||||
// Restore p->epinfo
|
// Restore p->epinfo
|
||||||
p->epinfo = oldep_ptr;
|
p->epinfo = oldep_ptr;
|
||||||
|
|
||||||
|
@ -117,7 +108,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
goto FailGetDevDescr;
|
goto FailGetDevDescr;
|
||||||
|
|
||||||
// Assign epInfo to epinfo pointer
|
// Assign epInfo to epinfo pointer
|
||||||
rcode = pUsb->setDevTableEntry(bAddress, epInfo);
|
rcode = pUsb->setEpInfoEntry(bAddress, 2, epInfo);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
@ -159,17 +150,12 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
goto FailGetConfDescr;
|
goto FailGetConfDescr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.print("Conf val:");
|
|
||||||
Serial.println(buf[5], HEX);
|
|
||||||
|
|
||||||
// Set Configuration Value
|
// Set Configuration Value
|
||||||
rcode = pUsb->setConf(bAddress, 0, buf[5]);
|
rcode = pUsb->setConf(bAddress, 0, buf[5]);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
Serial.println("Hub configured");
|
|
||||||
|
|
||||||
bInitState = 3;
|
bInitState = 3;
|
||||||
|
|
||||||
case 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++)
|
for (uint8_t j=1; j<=bNbrPorts; j++)
|
||||||
pUsb->HubPortPowerOn(bAddress, j);
|
pUsb->HubPortPowerOn(bAddress, j);
|
||||||
|
|
||||||
Serial.println("Ports powered");
|
pUsb->SetHubPreMask();
|
||||||
|
|
||||||
bPollEnable = true;
|
bPollEnable = true;
|
||||||
bInitState = 0;
|
bInitState = 0;
|
||||||
}
|
}
|
||||||
|
@ -186,31 +171,24 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FailGetDevDescr:
|
FailGetDevDescr:
|
||||||
Serial.print("getDevDescr:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailSetDevTblEntry:
|
FailSetDevTblEntry:
|
||||||
Serial.print("setDevTblEn:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailGetHubDescr:
|
FailGetHubDescr:
|
||||||
Serial.print("getHub:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailGetConfDescr:
|
FailGetConfDescr:
|
||||||
Serial.print("getConf:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
Serial.print("setConf:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
FailGetPortStatus:
|
FailGetPortStatus:
|
||||||
Serial.print("GetPortStatus:");
|
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
Serial.println(rcode, HEX);
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,9 +196,11 @@ uint8_t USBHub::Release()
|
||||||
{
|
{
|
||||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||||
|
|
||||||
|
if (bAddress == 0x41)
|
||||||
|
pUsb->SetHubPreMask();
|
||||||
|
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
bNbrPorts = 0;
|
bNbrPorts = 0;
|
||||||
// bPortResetCounter = 0;
|
|
||||||
qNextPollTime = 0;
|
qNextPollTime = 0;
|
||||||
bPollEnable = false;
|
bPollEnable = false;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -235,51 +215,27 @@ uint8_t USBHub::Poll()
|
||||||
|
|
||||||
if (qNextPollTime <= millis())
|
if (qNextPollTime <= millis())
|
||||||
{
|
{
|
||||||
Serial.print("Poll:");
|
|
||||||
Serial.println(bAddress, HEX);
|
Serial.println(bAddress, HEX);
|
||||||
|
|
||||||
rcode = GetHubStatus(bAddress);
|
rcode = GetHubStatus(bAddress);
|
||||||
if (rcode)
|
|
||||||
{
|
|
||||||
Serial.print("HubStatus:");
|
|
||||||
Serial.println(rcode,HEX);
|
|
||||||
}
|
|
||||||
qNextPollTime = millis() + 100;
|
qNextPollTime = millis() + 100;
|
||||||
}
|
}
|
||||||
return rcode;
|
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 USBHub::GetHubStatus(uint8_t addr)
|
||||||
{
|
{
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
uint8_t buf[8];
|
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 );
|
rcode = pUsb->inTransfer(addr, 1, 1, buf);
|
||||||
//Serial.println(devtable[1].epinfo->epAddr, HEX);
|
|
||||||
|
|
||||||
rcode = pUsb->inTransfer(addr, 1, 1, buf, 1);
|
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
{
|
|
||||||
Serial.print("inTransfer:");
|
|
||||||
Serial.println(rcode, HEX);
|
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
|
||||||
Serial.print("Int:");
|
|
||||||
Serial.println(buf[0],HEX);
|
|
||||||
|
|
||||||
//return 0;
|
|
||||||
|
|
||||||
if (buf[0] & 0x01) // Hub Status Change
|
if (buf[0] & 0x01) // Hub Status Change
|
||||||
{
|
{
|
||||||
pUsb->PrintHubStatus(addr);
|
//pUsb->PrintHubStatus(addr);
|
||||||
//rcode = GetHubStatus(1, 0, 1, 4, buf);
|
//rcode = GetHubStatus(1, 0, 1, 4, buf);
|
||||||
//if (rcode)
|
//if (rcode)
|
||||||
//{
|
//{
|
||||||
|
@ -298,91 +254,91 @@ uint8_t USBHub::GetHubStatus(uint8_t addr)
|
||||||
rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff);
|
rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff);
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
{
|
|
||||||
Serial.print("GetPortStatus err:");
|
|
||||||
Serial.println(rcode, HEX);
|
|
||||||
Serial.print("on port:");
|
|
||||||
Serial.println(port, DEC);
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
rcode = HubPortStatusChange(addr, port, evt);
|
||||||
|
|
||||||
|
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (rcode)
|
||||||
|
return rcode;
|
||||||
}
|
}
|
||||||
HubPortStatusChange(addr, port, evt);
|
} // 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
|
} // for
|
||||||
return 0;
|
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)
|
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
|
// Device connected event
|
||||||
case bmHUB_PORT_EVENT_CONNECT:
|
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_ENABLE);
|
||||||
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_CONNECTION);
|
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_CONNECTION);
|
||||||
pUsb->HubPortReset(addr, port);
|
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
|
// Reset complete event
|
||||||
case bmHUB_PORT_EVENT_RESET_COMPLETE:
|
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);
|
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_RESET | HUB_FEATURE_C_PORT_CONNECTION);
|
||||||
|
|
||||||
// Check if device is a low-speed device
|
delay(20);
|
||||||
if (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED)
|
|
||||||
{
|
|
||||||
UsbDevice *p = pUsb->GetAddressPool().GetUsbDevicePtr(addr);
|
|
||||||
|
|
||||||
if (p)
|
a.devAddress = addr;
|
||||||
p->lowspeed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(50);
|
pUsb->Configuring(a.bmAddress, port, (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED) );
|
||||||
|
bResetInitiated = false;
|
||||||
pUsb->Configuring(addr, port);
|
|
||||||
break;
|
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)
|
} // switch (evt.bmEvent)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes)
|
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes)
|
||||||
{
|
{
|
||||||
uint8_t rcode = 0;
|
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_RESETTING 0xb5
|
||||||
#define USB_STATE_HUB_PORT_ENABLED 0xb6
|
#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
|
// 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)
|
#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
|
// Hub Port States
|
||||||
//#define bmHUB_PORT_STATE_POWERED ((0UL | bmHUB_PORT_STATUS_PORT_POWER) << 16)
|
#define bmHUB_PORT_STATE_DISABLED (0x0000 | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION)
|
||||||
#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)
|
|
||||||
|
|
||||||
// Hub Port Events
|
// 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_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
|
struct HubEvent
|
||||||
{
|
{
|
||||||
|
@ -56,50 +58,30 @@ struct HubEvent
|
||||||
|
|
||||||
class USBHub : USBDeviceConfig
|
class USBHub : USBDeviceConfig
|
||||||
{
|
{
|
||||||
|
static bool bResetInitiated; // True when reset is triggered
|
||||||
|
|
||||||
USB *pUsb; // USB class instance pointer
|
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 bAddress; // address
|
||||||
uint8_t bNbrPorts; // number of ports
|
uint8_t bNbrPorts; // number of ports
|
||||||
uint8_t bInitState; // initialization state variable
|
uint8_t bInitState; // initialization state variable
|
||||||
// uint8_t bPortResetCounter; // number of ports reset
|
|
||||||
uint32_t qNextPollTime; // next poll time
|
uint32_t qNextPollTime; // next poll time
|
||||||
bool bPollEnable; // poll enable flag
|
bool bPollEnable; // poll enable flag
|
||||||
|
|
||||||
uint8_t GetHubStatus(uint8_t addr);
|
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:
|
public:
|
||||||
USBHub(USB *p);
|
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 Release();
|
||||||
virtual uint8_t Poll();
|
virtual uint8_t Poll();
|
||||||
|
virtual uint8_t GetAddress() { return bAddress; };
|
||||||
};
|
};
|
||||||
|
|
||||||
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes = false);
|
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__
|
#endif // __USBHUB_H__
|
Loading…
Reference in a new issue