Apr.11 update

This commit is contained in:
Oleg Mazurov 2011-04-18 10:27:11 -06:00
parent aa6fc58bc4
commit 1f42c51bd2
4 changed files with 191 additions and 242 deletions

22
Usb.cpp
View file

@ -618,26 +618,4 @@ uint8_t USB::ReleaseDevice(uint8_t addr)
return devConfig[i]->Release(); return devConfig[i]->Release();
} }
uint8_t USB::HubPortPowerOn(uint8_t addr, uint8_t port)
{
return SetPortFeature(addr, 0, HUB_FEATURE_PORT_POWER, port, 0);
}
uint8_t USB::HubPortReset(uint8_t addr, uint8_t port)
{
return SetPortFeature(addr, 0, HUB_FEATURE_PORT_RESET, port, 0);
}
uint8_t USB::HubClearPortFeatures(uint8_t addr, uint8_t port, uint8_t bm_features)
{
return ClearPortFeature(addr, 0, bm_features, port, 0);
}
//void USB::PrintHubStatus(/*USB *usbptr,*/ uint8_t addr)
//{
// uint8_t buf[4];
//
// return /*usbptr->*/GetHubStatus(addr, 0, 4, (uint8_t*)&buf);
//
//}

212
Usb.h
View file

@ -50,85 +50,6 @@
#define USB_CLASS_APP_SPECIFIC 0xfe // Application Specific #define USB_CLASS_APP_SPECIFIC 0xfe // Application Specific
#define USB_CLASS_VENDOR_SPECIFIC 0xff // Vendor Specific #define USB_CLASS_VENDOR_SPECIFIC 0xff // Vendor Specific
// Hub Requests
#define bmREQ_CLEAR_HUB_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
#define bmREQ_CLEAR_PORT_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_CLEAR_TT_BUFFER USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_GET_HUB_DESCRIPTOR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
#define bmREQ_GET_HUB_STATUS USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
#define bmREQ_GET_PORT_STATUS USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_RESET_TT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_SET_HUB_DESCRIPTOR USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
#define bmREQ_SET_HUB_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
#define bmREQ_SET_PORT_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_GET_TT_STATE USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_STOP_TT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
// Hub Class Requests
#define HUB_REQUEST_CLEAR_TT_BUFFER 8
#define HUB_REQUEST_RESET_TT 9
#define HUB_REQUEST_GET_TT_STATE 10
#define HUB_REQUEST_STOP_TT 11
// Hub Features
#define HUB_FEATURE_C_HUB_LOCAL_POWER 0
#define HUB_FEATURE_C_HUB_OVER_CURRENT 1
#define HUB_FEATURE_PORT_CONNECTION 0
#define HUB_FEATURE_PORT_ENABLE 1
#define HUB_FEATURE_PORT_SUSPEND 2
#define HUB_FEATURE_PORT_OVER_CURRENT 3
#define HUB_FEATURE_PORT_RESET 4
#define HUB_FEATURE_PORT_POWER 8
#define HUB_FEATURE_PORT_LOW_SPEED 9
#define HUB_FEATURE_C_PORT_CONNECTION 16
#define HUB_FEATURE_C_PORT_ENABLE 17
#define HUB_FEATURE_C_PORT_SUSPEND 18
#define HUB_FEATURE_C_PORT_OVER_CURRENT 19
#define HUB_FEATURE_C_PORT_RESET 20
#define HUB_FEATURE_PORT_TEST 21
#define HUB_FEATURE_PORT_INDICATOR 22
// Hub Port Test Modes
#define HUB_PORT_TEST_MODE_J 1
#define HUB_PORT_TEST_MODE_K 2
#define HUB_PORT_TEST_MODE_SE0_NAK 3
#define HUB_PORT_TEST_MODE_PACKET 4
#define HUB_PORT_TEST_MODE_FORCE_ENABLE 5
// Hub Port Indicator Color
#define HUB_PORT_INDICATOR_AUTO 0
#define HUB_PORT_INDICATOR_AMBER 1
#define HUB_PORT_INDICATOR_GREEN 2
#define HUB_PORT_INDICATOR_OFF 3
// Hub Port Status Bitmasks
#define bmHUB_PORT_STATUS_PORT_CONNECTION 0x0001
#define bmHUB_PORT_STATUS_PORT_ENABLE 0x0002
#define bmHUB_PORT_STATUS_PORT_SUSPEND 0x0004
#define bmHUB_PORT_STATUS_PORT_OVER_CURRENT 0x0008
#define bmHUB_PORT_STATUS_PORT_RESET 0x0010
#define bmHUB_PORT_STATUS_PORT_POWER 0x0100
#define bmHUB_PORT_STATUS_PORT_LOW_SPEED 0x0200
#define bmHUB_PORT_STATUS_PORT_HIGH_SPEED 0x0400
#define bmHUB_PORT_STATUS_PORT_TEST 0x0800
#define bmHUB_PORT_STATUS_PORT_INDICATOR 0x1000
// Hub Port Status Change Bitmasks (used one byte instead of two)
#define bmHUB_PORT_STATUS_C_PORT_CONNECTION 0x0001
#define bmHUB_PORT_STATUS_C_PORT_ENABLE 0x0002
#define bmHUB_PORT_STATUS_C_PORT_SUSPEND 0x0004
#define bmHUB_PORT_STATUS_C_PORT_OVER_CURRENT 0x0008
#define bmHUB_PORT_STATUS_C_PORT_RESET 0x0010
// Hub Status Bitmasks (used one byte instead of two)
#define bmHUB_STATUS_LOCAL_POWER_SOURCE 0x01
#define bmHUB_STATUS_OVER_CURRENT 0x12
// Hub Status Change Bitmasks (used one byte instead of two)
#define bmHUB_STATUS_C_LOCAL_POWER_SOURCE 0x01
#define bmHUB_STATUS_C_OVER_CURRENT 0x12
// Additional Error Codes // Additional Error Codes
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED 0xD1 #define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED 0xD1
#define USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE 0xD2 #define USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE 0xD2
@ -158,7 +79,7 @@ public:
#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 16 //number of USB devices #define USB_NUMDEVICES 16 //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 */
@ -203,33 +124,6 @@ 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 */
//typedef struct
//{
// EpInfo *epinfo; //device endpoint information
// uint8_t devclass; //device class
//} DEV_RECORD;
struct HubDescriptor
{
uint8_t bDescLength; // descriptor length
uint8_t bDescriptorType; // descriptor type
uint8_t bNbrPorts; // number of ports a hub equiped with
struct
{
uint16_t LogPwrSwitchMode : 2;
uint16_t CompoundDevice : 1;
uint16_t OverCurrentProtectMode : 2;
uint16_t TTThinkTime : 2;
uint16_t PortIndicatorsSupported : 1;
uint16_t Reserved : 8;
};
uint8_t bPwrOn2PwrGood;
uint8_t bHubContrCurrent;
};
// Base class for incomming data parser // Base class for incomming data parser
@ -240,8 +134,8 @@ public:
}; };
//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
{ {
@ -293,11 +187,6 @@ class USB : public MAX3421E
/**/ /**/
uint8_t setProto( uint8_t addr, uint8_t ep, uint8_t interface, uint8_t protocol ); 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 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 ); 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 ctrlStatus( uint8_t ep, boolean direction, uint16_t nak_limit );
@ -305,22 +194,6 @@ class USB : public MAX3421E
uint8_t outTransfer( 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 ); 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 );
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);
void PrintHubStatus(/*USB *usbptr,*/ uint8_t addr);
void Task( void ); void Task( void );
uint8_t DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed); uint8_t DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed);
@ -344,91 +217,40 @@ class USB : public MAX3421E
//#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 ) { 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 )); 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 ) { 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 )); 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 ) { 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 )); 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 ) { 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 )); 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 ) { 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 )); 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 ) { 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 )); 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 ) { 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 )); 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 ) {
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 ) {
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 ) {
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 ) {
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 ) {
return( ctrlReq( addr, ep, bmREQ_HIDOUT, HID_REQUEST_SET_IDLE, reportID, duration, interface, 0x0000, NULL ));
}
// Clear Hub Feature
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 ));
}
// Clear Port Feature
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 ));
}
// Get Hub Descriptor
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 ));
}
// Get Hub Status
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 ));
}
// Get Port Status
inline uint8_t USB::GetPortStatus( uint8_t addr, uint8_t ep, uint8_t port, uint16_t nbytes, uint8_t* dataptr )
{
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 )
{
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 )
{
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 )
{
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_

View file

@ -117,7 +117,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed)
case 1: case 1:
// Get hub descriptor // Get hub descriptor
rcode = pUsb->GetHubDescriptor(bAddress, 0, 0, 8, buf); rcode = GetHubDescriptor(0, 8, buf);
if (rcode) if (rcode)
goto FailGetHubDescr; goto FailGetHubDescr;
@ -161,7 +161,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed)
case 3: case 3:
// Power on all ports // Power on all ports
for (uint8_t j=1; j<=bNbrPorts; j++) for (uint8_t j=1; j<=bNbrPorts; j++)
pUsb->HubPortPowerOn(bAddress, j); SetPortFeature(HUB_FEATURE_PORT_POWER, j, 0); //HubPortPowerOn(j);
pUsb->SetHubPreMask(); pUsb->SetHubPreMask();
bPollEnable = true; bPollEnable = true;
@ -215,20 +215,18 @@ uint8_t USBHub::Poll()
if (qNextPollTime <= millis()) if (qNextPollTime <= millis())
{ {
Serial.println(bAddress, HEX); rcode = CheckHubStatus();
rcode = GetHubStatus(bAddress);
qNextPollTime = millis() + 100; qNextPollTime = millis() + 100;
} }
return rcode; return rcode;
} }
uint8_t USBHub::GetHubStatus(uint8_t addr) uint8_t USBHub::CheckHubStatus()
{ {
uint8_t rcode; uint8_t rcode;
uint8_t buf[8]; uint8_t buf[8];
rcode = pUsb->inTransfer(addr, 1, 1, buf); rcode = pUsb->inTransfer(bAddress, 1, 1, buf);
if (rcode) if (rcode)
return rcode; return rcode;
@ -251,12 +249,12 @@ uint8_t USBHub::GetHubStatus(uint8_t addr)
HubEvent evt; HubEvent evt;
evt.bmEvent = 0; evt.bmEvent = 0;
rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff); rcode = GetPortStatus(port, 4, evt.evtBuff);
if (rcode) if (rcode)
continue; continue;
rcode = HubPortStatusChange(addr, port, evt); rcode = PortStatusChange(port, evt);
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET) if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
return 0; return 0;
@ -271,7 +269,7 @@ uint8_t USBHub::GetHubStatus(uint8_t addr)
HubEvent evt; HubEvent evt;
evt.bmEvent = 0; evt.bmEvent = 0;
rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff); rcode = GetPortStatus(port, 4, evt.evtBuff);
if (rcode) if (rcode)
continue; continue;
@ -282,7 +280,7 @@ uint8_t USBHub::GetHubStatus(uint8_t addr)
// Emulate connection event for the port // Emulate connection event for the port
evt.bmChange |= bmHUB_PORT_STATUS_C_PORT_CONNECTION; evt.bmChange |= bmHUB_PORT_STATUS_C_PORT_CONNECTION;
rcode = HubPortStatusChange(addr, port, evt); rcode = PortStatusChange(port, evt);
if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET) if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET)
return 0; return 0;
@ -293,7 +291,7 @@ uint8_t USBHub::GetHubStatus(uint8_t addr)
return 0; return 0;
} }
uint8_t USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt) uint8_t USBHub::PortStatusChange(uint8_t port, HubEvent &evt)
{ {
switch (evt.bmEvent) switch (evt.bmEvent)
{ {
@ -303,21 +301,21 @@ uint8_t USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
if (bResetInitiated) if (bResetInitiated)
return 0; return 0;
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_ENABLE); ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 0);
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_CONNECTION); ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0);
pUsb->HubPortReset(addr, port); SetPortFeature(HUB_FEATURE_PORT_RESET, port, 0);
bResetInitiated = true; bResetInitiated = true;
return HUB_ERROR_PORT_HAS_BEEN_RESET; return HUB_ERROR_PORT_HAS_BEEN_RESET;
// Device disconnected event // Device disconnected event
case bmHUB_PORT_EVENT_DISCONNECT: case bmHUB_PORT_EVENT_DISCONNECT:
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_ENABLE); ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 0);
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_CONNECTION); ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0);
bResetInitiated = false; bResetInitiated = false;
UsbDeviceAddress a; UsbDeviceAddress a;
a.bmHub = 0; a.bmHub = 0;
a.bmParent = addr; a.bmParent = bAddress;
a.bmAddress = port; a.bmAddress = port;
pUsb->ReleaseDevice(a.devAddress); pUsb->ReleaseDevice(a.devAddress);
return 0; return 0;
@ -325,11 +323,12 @@ uint8_t USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
// Reset complete event // Reset complete event
case bmHUB_PORT_EVENT_RESET_COMPLETE: case bmHUB_PORT_EVENT_RESET_COMPLETE:
case bmHUB_PORT_EVENT_LS_RESET_COMPLETE: case bmHUB_PORT_EVENT_LS_RESET_COMPLETE:
pUsb->HubClearPortFeatures(addr, port, HUB_FEATURE_C_PORT_RESET | HUB_FEATURE_C_PORT_CONNECTION); ClearPortFeature(HUB_FEATURE_C_PORT_RESET, port, 0);
ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0);
delay(20); delay(20);
a.devAddress = addr; a.devAddress = bAddress;
pUsb->Configuring(a.bmAddress, port, (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED) ); pUsb->Configuring(a.bmAddress, port, (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED) );
bResetInitiated = false; bResetInitiated = false;
@ -339,12 +338,12 @@ uint8_t USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt)
return 0; return 0;
} }
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes) void PrintHubPortStatus(USBHub *hubptr, uint8_t addr, uint8_t port, bool print_changes)
{ {
uint8_t rcode = 0; uint8_t rcode = 0;
HubEvent evt; HubEvent evt;
rcode = usbptr->GetPortStatus(addr, 0, port, 4, evt.evtBuff); rcode = hubptr->GetPortStatus(port, 4, evt.evtBuff);
if (rcode) if (rcode)
{ {

156
usbhub.h
View file

@ -10,6 +10,85 @@
#include "Usb.h" #include "Usb.h"
#include <WProgram.h> #include <WProgram.h>
// Hub Requests
#define bmREQ_CLEAR_HUB_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
#define bmREQ_CLEAR_PORT_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_CLEAR_TT_BUFFER USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_GET_HUB_DESCRIPTOR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
#define bmREQ_GET_HUB_STATUS USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
#define bmREQ_GET_PORT_STATUS USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_RESET_TT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_SET_HUB_DESCRIPTOR USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
#define bmREQ_SET_HUB_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
#define bmREQ_SET_PORT_FEATURE USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_GET_TT_STATE USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
#define bmREQ_STOP_TT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
// Hub Class Requests
#define HUB_REQUEST_CLEAR_TT_BUFFER 8
#define HUB_REQUEST_RESET_TT 9
#define HUB_REQUEST_GET_TT_STATE 10
#define HUB_REQUEST_STOP_TT 11
// Hub Features
#define HUB_FEATURE_C_HUB_LOCAL_POWER 0
#define HUB_FEATURE_C_HUB_OVER_CURRENT 1
#define HUB_FEATURE_PORT_CONNECTION 0
#define HUB_FEATURE_PORT_ENABLE 1
#define HUB_FEATURE_PORT_SUSPEND 2
#define HUB_FEATURE_PORT_OVER_CURRENT 3
#define HUB_FEATURE_PORT_RESET 4
#define HUB_FEATURE_PORT_POWER 8
#define HUB_FEATURE_PORT_LOW_SPEED 9
#define HUB_FEATURE_C_PORT_CONNECTION 16
#define HUB_FEATURE_C_PORT_ENABLE 17
#define HUB_FEATURE_C_PORT_SUSPEND 18
#define HUB_FEATURE_C_PORT_OVER_CURRENT 19
#define HUB_FEATURE_C_PORT_RESET 20
#define HUB_FEATURE_PORT_TEST 21
#define HUB_FEATURE_PORT_INDICATOR 22
// Hub Port Test Modes
#define HUB_PORT_TEST_MODE_J 1
#define HUB_PORT_TEST_MODE_K 2
#define HUB_PORT_TEST_MODE_SE0_NAK 3
#define HUB_PORT_TEST_MODE_PACKET 4
#define HUB_PORT_TEST_MODE_FORCE_ENABLE 5
// Hub Port Indicator Color
#define HUB_PORT_INDICATOR_AUTO 0
#define HUB_PORT_INDICATOR_AMBER 1
#define HUB_PORT_INDICATOR_GREEN 2
#define HUB_PORT_INDICATOR_OFF 3
// Hub Port Status Bitmasks
#define bmHUB_PORT_STATUS_PORT_CONNECTION 0x0001
#define bmHUB_PORT_STATUS_PORT_ENABLE 0x0002
#define bmHUB_PORT_STATUS_PORT_SUSPEND 0x0004
#define bmHUB_PORT_STATUS_PORT_OVER_CURRENT 0x0008
#define bmHUB_PORT_STATUS_PORT_RESET 0x0010
#define bmHUB_PORT_STATUS_PORT_POWER 0x0100
#define bmHUB_PORT_STATUS_PORT_LOW_SPEED 0x0200
#define bmHUB_PORT_STATUS_PORT_HIGH_SPEED 0x0400
#define bmHUB_PORT_STATUS_PORT_TEST 0x0800
#define bmHUB_PORT_STATUS_PORT_INDICATOR 0x1000
// Hub Port Status Change Bitmasks (used one byte instead of two)
#define bmHUB_PORT_STATUS_C_PORT_CONNECTION 0x0001
#define bmHUB_PORT_STATUS_C_PORT_ENABLE 0x0002
#define bmHUB_PORT_STATUS_C_PORT_SUSPEND 0x0004
#define bmHUB_PORT_STATUS_C_PORT_OVER_CURRENT 0x0008
#define bmHUB_PORT_STATUS_C_PORT_RESET 0x0010
// Hub Status Bitmasks (used one byte instead of two)
#define bmHUB_STATUS_LOCAL_POWER_SOURCE 0x01
#define bmHUB_STATUS_OVER_CURRENT 0x12
// Hub Status Change Bitmasks (used one byte instead of two)
#define bmHUB_STATUS_C_LOCAL_POWER_SOURCE 0x01
#define bmHUB_STATUS_C_OVER_CURRENT 0x12
// Hub Port Configuring Substates // Hub Port Configuring Substates
#define USB_STATE_HUB_PORT_CONFIGURING 0xb0 #define USB_STATE_HUB_PORT_CONFIGURING 0xb0
#define USB_STATE_HUB_PORT_POWERED_OFF 0xb1 #define USB_STATE_HUB_PORT_POWERED_OFF 0xb1
@ -22,7 +101,6 @@
// Additional Error Codes // Additional Error Codes
#define HUB_ERROR_PORT_HAS_BEEN_RESET 0xb1 #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)
@ -41,6 +119,26 @@
#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_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) #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 HubDescriptor
{
uint8_t bDescLength; // descriptor length
uint8_t bDescriptorType; // descriptor type
uint8_t bNbrPorts; // number of ports a hub equiped with
struct
{
uint16_t LogPwrSwitchMode : 2;
uint16_t CompoundDevice : 1;
uint16_t OverCurrentProtectMode : 2;
uint16_t TTThinkTime : 2;
uint16_t PortIndicatorsSupported : 1;
uint16_t Reserved : 8;
};
uint8_t bPwrOn2PwrGood;
uint8_t bHubContrCurrent;
};
struct HubEvent struct HubEvent
{ {
union union
@ -70,18 +168,70 @@ class USBHub : USBDeviceConfig
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 CheckHubStatus();
uint8_t HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt); uint8_t PortStatusChange(uint8_t port, HubEvent &evt);
public: public:
USBHub(USB *p); USBHub(USB *p);
uint8_t ClearHubFeature( uint8_t fid );
uint8_t ClearPortFeature( uint8_t fid, uint8_t port, uint8_t sel = 0 );
uint8_t GetHubDescriptor( uint8_t index, uint16_t nbytes, uint8_t *dataptr );
uint8_t GetHubStatus( uint16_t nbytes, uint8_t* dataptr );
uint8_t GetPortStatus( uint8_t port, uint16_t nbytes, uint8_t* dataptr );
uint8_t SetHubDescriptor( uint8_t port, uint16_t nbytes, uint8_t* dataptr );
uint8_t SetHubFeature( uint8_t fid );
uint8_t SetPortFeature( uint8_t fid, uint8_t port, uint8_t sel = 0 );
void PrintHubStatus();
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed); 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; }; virtual uint8_t GetAddress() { return bAddress; };
}; };
// Clear Hub Feature
inline uint8_t USBHub::ClearHubFeature( uint8_t fid )
{
return( pUsb->ctrlReq( bAddress, 0, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, NULL ));
}
// Clear Port Feature
inline uint8_t USBHub::ClearPortFeature( uint8_t fid, uint8_t port, uint8_t sel )
{
return( pUsb->ctrlReq( bAddress, 0, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000|port)|(sel<<8)), 0, NULL ));
}
// Get Hub Descriptor
inline uint8_t USBHub::GetHubDescriptor( uint8_t index, uint16_t nbytes, uint8_t *dataptr )
{
return( pUsb->ctrlReq( bAddress, 0, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, dataptr ));
}
// Get Hub Status
inline uint8_t USBHub::GetHubStatus( uint16_t nbytes, uint8_t* dataptr )
{
return( pUsb->ctrlReq( bAddress, 0, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, dataptr ));
}
// Get Port Status
inline uint8_t USBHub::GetPortStatus( uint8_t port, uint16_t nbytes, uint8_t* dataptr )
{
return( pUsb->ctrlReq( bAddress, 0, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, dataptr ));
}
// Set Hub Descriptor
inline uint8_t USBHub::SetHubDescriptor( uint8_t port, uint16_t nbytes, uint8_t* dataptr )
{
return( pUsb->ctrlReq( bAddress, 0, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, dataptr ));
}
// Set Hub Feature
inline uint8_t USBHub::SetHubFeature( uint8_t fid )
{
return( pUsb->ctrlReq( bAddress, 0, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, NULL ));
}
// Set Port Feature
inline uint8_t USBHub::SetPortFeature( uint8_t fid, uint8_t port, uint8_t sel )
{
return( pUsb->ctrlReq( bAddress, 0, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000|sel)<<8)|port), 0, NULL ));
}
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);
#endif // __USBHUB_H__ #endif // __USBHUB_H__