From 1f42c51bd25e25134e5bccfc0d495f6b7070b423 Mon Sep 17 00:00:00 2001 From: Oleg Mazurov Date: Mon, 18 Apr 2011 10:27:11 -0600 Subject: [PATCH] Apr.11 update --- Usb.cpp | 22 ------ Usb.h | 212 +++++------------------------------------------------ usbhub.cpp | 43 ++++++----- usbhub.h | 156 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 191 insertions(+), 242 deletions(-) diff --git a/Usb.cpp b/Usb.cpp index 8aee8144..653a4334 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -618,26 +618,4 @@ uint8_t USB::ReleaseDevice(uint8_t addr) 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); -// -//} diff --git a/Usb.h b/Usb.h index 7d96216d..049d499d 100644 --- a/Usb.h +++ b/Usb.h @@ -50,85 +50,6 @@ #define USB_CLASS_APP_SPECIFIC 0xfe // Application 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 #define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED 0xD1 #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_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 /* USB state machine states */ @@ -203,33 +124,6 @@ typedef struct { unsigned int wLength; // 6 Depends on bRequest } 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 @@ -240,8 +134,8 @@ public: }; -//typedef MAX3421e MAX3421E; // Black Widdow -typedef MAX3421e MAX3421E; // Duemielanove +typedef MAX3421e MAX3421E; // Black Widdow +//typedef MAX3421e MAX3421E; // Duemielanove 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 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 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 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 ); uint8_t DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed); @@ -344,91 +217,40 @@ class USB : public MAX3421E //#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 ) { +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 ) { +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 ) { +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 ) { +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 ) { +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 ) { +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 ) { +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 ) { - 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 //_usb_h_ \ No newline at end of file diff --git a/usbhub.cpp b/usbhub.cpp index 0b99fea3..64efaafc 100644 --- a/usbhub.cpp +++ b/usbhub.cpp @@ -117,7 +117,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) case 1: // Get hub descriptor - rcode = pUsb->GetHubDescriptor(bAddress, 0, 0, 8, buf); + rcode = GetHubDescriptor(0, 8, buf); if (rcode) goto FailGetHubDescr; @@ -161,7 +161,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) case 3: // Power on all ports for (uint8_t j=1; j<=bNbrPorts; j++) - pUsb->HubPortPowerOn(bAddress, j); + SetPortFeature(HUB_FEATURE_PORT_POWER, j, 0); //HubPortPowerOn(j); pUsb->SetHubPreMask(); bPollEnable = true; @@ -215,20 +215,18 @@ uint8_t USBHub::Poll() if (qNextPollTime <= millis()) { - Serial.println(bAddress, HEX); - - rcode = GetHubStatus(bAddress); + rcode = CheckHubStatus(); qNextPollTime = millis() + 100; } return rcode; } -uint8_t USBHub::GetHubStatus(uint8_t addr) +uint8_t USBHub::CheckHubStatus() { uint8_t rcode; uint8_t buf[8]; - rcode = pUsb->inTransfer(addr, 1, 1, buf); + rcode = pUsb->inTransfer(bAddress, 1, 1, buf); if (rcode) return rcode; @@ -251,12 +249,12 @@ uint8_t USBHub::GetHubStatus(uint8_t addr) HubEvent evt; evt.bmEvent = 0; - rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff); + rcode = GetPortStatus(port, 4, evt.evtBuff); if (rcode) continue; - rcode = HubPortStatusChange(addr, port, evt); + rcode = PortStatusChange(port, evt); if (rcode == HUB_ERROR_PORT_HAS_BEEN_RESET) return 0; @@ -271,7 +269,7 @@ uint8_t USBHub::GetHubStatus(uint8_t addr) HubEvent evt; evt.bmEvent = 0; - rcode = pUsb->GetPortStatus(addr, 0, port, 4, evt.evtBuff); + rcode = GetPortStatus(port, 4, evt.evtBuff); if (rcode) continue; @@ -282,7 +280,7 @@ uint8_t USBHub::GetHubStatus(uint8_t addr) // Emulate connection event for the port 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) return 0; @@ -293,7 +291,7 @@ uint8_t USBHub::GetHubStatus(uint8_t addr) 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) { @@ -303,21 +301,21 @@ uint8_t USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt) 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); + ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 0); + ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0); + SetPortFeature(HUB_FEATURE_PORT_RESET, port, 0); 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); + ClearPortFeature(HUB_FEATURE_C_PORT_ENABLE, port, 0); + ClearPortFeature(HUB_FEATURE_C_PORT_CONNECTION, port, 0); bResetInitiated = false; UsbDeviceAddress a; a.bmHub = 0; - a.bmParent = addr; + a.bmParent = bAddress; a.bmAddress = port; pUsb->ReleaseDevice(a.devAddress); return 0; @@ -325,11 +323,12 @@ uint8_t USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt) // Reset complete event case bmHUB_PORT_EVENT_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); - a.devAddress = addr; + a.devAddress = bAddress; pUsb->Configuring(a.bmAddress, port, (evt.bmStatus & bmHUB_PORT_STATUS_PORT_LOW_SPEED) ); bResetInitiated = false; @@ -339,12 +338,12 @@ uint8_t USBHub::HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt) 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; HubEvent evt; - rcode = usbptr->GetPortStatus(addr, 0, port, 4, evt.evtBuff); + rcode = hubptr->GetPortStatus(port, 4, evt.evtBuff); if (rcode) { diff --git a/usbhub.h b/usbhub.h index 1a9de648..cb03f228 100644 --- a/usbhub.h +++ b/usbhub.h @@ -10,6 +10,85 @@ #include "Usb.h" #include +// 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 #define USB_STATE_HUB_PORT_CONFIGURING 0xb0 #define USB_STATE_HUB_PORT_POWERED_OFF 0xb1 @@ -22,7 +101,6 @@ // 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) @@ -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_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 { union @@ -70,18 +168,70 @@ class USBHub : USBDeviceConfig uint32_t qNextPollTime; // next poll time bool bPollEnable; // poll enable flag - uint8_t GetHubStatus(uint8_t addr); - uint8_t HubPortStatusChange(uint8_t addr, uint8_t port, HubEvent &evt); + uint8_t CheckHubStatus(); + uint8_t PortStatusChange(uint8_t port, HubEvent &evt); public: 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 Release(); virtual uint8_t Poll(); 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); #endif // __USBHUB_H__ \ No newline at end of file