Zoltan Hudak / UsbHostMAX3421E

Dependents:   UsbHostMAX3421E_Hello

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbhub.h Source File

usbhub.h

00001 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
00002 
00003 This software may be distributed and modified under the terms of the GNU
00004 General Public License version 2 (GPL2) as published by the Free Software
00005 Foundation and appearing in the file GPL2.TXT included in the packaging of
00006 this file. Please note that GPL2 Section 2[b] requires that all works based
00007 on this software must also be made publicly available under the terms of
00008 the GPL2 ("Copyleft").
00009 
00010 Contact information
00011 -------------------
00012 
00013 Circuits At Home, LTD
00014 Web      :  http://www.circuitsathome.com
00015 e-mail   :  support@circuitsathome.com
00016  */
00017 #if !defined(__USBHUB_H__)
00018 #define __USBHUB_H__
00019 
00020 #include "Usb.h"
00021 
00022 #define USB_DESCRIPTOR_HUB                      0x09 // Hub descriptor type
00023 
00024 // Hub Requests
00025 #define bmREQ_CLEAR_HUB_FEATURE                 USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
00026 #define bmREQ_CLEAR_PORT_FEATURE                USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
00027 #define bmREQ_CLEAR_TT_BUFFER                   USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
00028 #define bmREQ_GET_HUB_DESCRIPTOR                USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
00029 #define bmREQ_GET_HUB_STATUS                    USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
00030 #define bmREQ_GET_PORT_STATUS                   USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
00031 #define bmREQ_RESET_TT                          USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
00032 #define bmREQ_SET_HUB_DESCRIPTOR                USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
00033 #define bmREQ_SET_HUB_FEATURE                   USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
00034 #define bmREQ_SET_PORT_FEATURE                  USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
00035 #define bmREQ_GET_TT_STATE                      USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
00036 #define bmREQ_STOP_TT                           USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_OTHER
00037 
00038 // Hub Class Requests
00039 #define HUB_REQUEST_CLEAR_TT_BUFFER             8
00040 #define HUB_REQUEST_RESET_TT                    9
00041 #define HUB_REQUEST_GET_TT_STATE                10
00042 #define HUB_REQUEST_STOP_TT                     11
00043 
00044 // Hub Features
00045 #define HUB_FEATURE_C_HUB_LOCAL_POWER           0
00046 #define HUB_FEATURE_C_HUB_OVER_CURRENT          1
00047 #define HUB_FEATURE_PORT_CONNECTION             0
00048 #define HUB_FEATURE_PORT_ENABLE                 1
00049 #define HUB_FEATURE_PORT_SUSPEND                2
00050 #define HUB_FEATURE_PORT_OVER_CURRENT           3
00051 #define HUB_FEATURE_PORT_RESET                  4
00052 #define HUB_FEATURE_PORT_POWER                  8
00053 #define HUB_FEATURE_PORT_LOW_SPEED              9
00054 #define HUB_FEATURE_C_PORT_CONNECTION           16
00055 #define HUB_FEATURE_C_PORT_ENABLE               17
00056 #define HUB_FEATURE_C_PORT_SUSPEND              18
00057 #define HUB_FEATURE_C_PORT_OVER_CURRENT         19
00058 #define HUB_FEATURE_C_PORT_RESET                20
00059 #define HUB_FEATURE_PORT_TEST                   21
00060 #define HUB_FEATURE_PORT_INDICATOR              22
00061 
00062 // Hub Port Test Modes
00063 #define HUB_PORT_TEST_MODE_J                    1
00064 #define HUB_PORT_TEST_MODE_K                    2
00065 #define HUB_PORT_TEST_MODE_SE0_NAK              3
00066 #define HUB_PORT_TEST_MODE_PACKET               4
00067 #define HUB_PORT_TEST_MODE_FORCE_ENABLE         5
00068 
00069 // Hub Port Indicator Color
00070 #define HUB_PORT_INDICATOR_AUTO                 0
00071 #define HUB_PORT_INDICATOR_AMBER                1
00072 #define HUB_PORT_INDICATOR_GREEN                2
00073 #define HUB_PORT_INDICATOR_OFF                  3
00074 
00075 // Hub Port Status Bitmasks
00076 #define bmHUB_PORT_STATUS_PORT_CONNECTION       0x0001
00077 #define bmHUB_PORT_STATUS_PORT_ENABLE           0x0002
00078 #define bmHUB_PORT_STATUS_PORT_SUSPEND          0x0004
00079 #define bmHUB_PORT_STATUS_PORT_OVER_CURRENT     0x0008
00080 #define bmHUB_PORT_STATUS_PORT_RESET            0x0010
00081 #define bmHUB_PORT_STATUS_PORT_POWER            0x0100
00082 #define bmHUB_PORT_STATUS_PORT_LOW_SPEED        0x0200
00083 #define bmHUB_PORT_STATUS_PORT_HIGH_SPEED       0x0400
00084 #define bmHUB_PORT_STATUS_PORT_TEST             0x0800
00085 #define bmHUB_PORT_STATUS_PORT_INDICATOR        0x1000
00086 
00087 // Hub Port Status Change Bitmasks (used one byte instead of two)
00088 #define bmHUB_PORT_STATUS_C_PORT_CONNECTION     0x0001
00089 #define bmHUB_PORT_STATUS_C_PORT_ENABLE         0x0002
00090 #define bmHUB_PORT_STATUS_C_PORT_SUSPEND        0x0004
00091 #define bmHUB_PORT_STATUS_C_PORT_OVER_CURRENT   0x0008
00092 #define bmHUB_PORT_STATUS_C_PORT_RESET          0x0010
00093 
00094 // Hub Status Bitmasks (used one byte instead of two)
00095 #define bmHUB_STATUS_LOCAL_POWER_SOURCE         0x01
00096 #define bmHUB_STATUS_OVER_CURRENT               0x12
00097 
00098 // Hub Status Change Bitmasks (used one byte instead of two)
00099 #define bmHUB_STATUS_C_LOCAL_POWER_SOURCE       0x01
00100 #define bmHUB_STATUS_C_OVER_CURRENT             0x12
00101 
00102 
00103 // Hub Port Configuring Substates
00104 #define USB_STATE_HUB_PORT_CONFIGURING          0xb0
00105 #define USB_STATE_HUB_PORT_POWERED_OFF          0xb1
00106 #define USB_STATE_HUB_PORT_WAIT_FOR_POWER_GOOD  0xb2
00107 #define USB_STATE_HUB_PORT_DISCONNECTED         0xb3
00108 #define USB_STATE_HUB_PORT_DISABLED             0xb4
00109 #define USB_STATE_HUB_PORT_RESETTING            0xb5
00110 #define USB_STATE_HUB_PORT_ENABLED              0xb6
00111 
00112 // Additional Error Codes
00113 #define HUB_ERROR_PORT_HAS_BEEN_RESET           0xb1
00114 
00115 // The bit mask to check for all necessary state bits
00116 #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)
00117 
00118 // Bit mask to check for DISABLED state in HubEvent::bmStatus field
00119 #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)
00120 
00121 // Hub Port States
00122 #define bmHUB_PORT_STATE_DISABLED               (0x0000 | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION)
00123 
00124 // Hub Port Events
00125 #define bmHUB_PORT_EVENT_CONNECT                (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION) << 16) | bmHUB_PORT_STATUS_PORT_POWER | bmHUB_PORT_STATUS_PORT_CONNECTION)
00126 #define bmHUB_PORT_EVENT_DISCONNECT             (((0UL | bmHUB_PORT_STATUS_C_PORT_CONNECTION) << 16) | bmHUB_PORT_STATUS_PORT_POWER)
00127 #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)
00128 
00129 #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)
00130 #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)
00131 #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)
00132 
00133 struct HubDescriptor {
00134         uint8_t bDescLength; // descriptor length
00135         uint8_t bDescriptorType; // descriptor type
00136         uint8_t bNbrPorts; // number of ports a hub equiped with
00137 
00138         struct {
00139                 uint16_t LogPwrSwitchMode : 2;
00140                 uint16_t CompoundDevice : 1;
00141                 uint16_t OverCurrentProtectMode : 2;
00142                 uint16_t TTThinkTime : 2;
00143                 uint16_t PortIndicatorsSupported : 1;
00144                 uint16_t Reserved : 8;
00145         } __attribute__((packed));
00146 
00147         uint8_t bPwrOn2PwrGood;
00148         uint8_t bHubContrCurrent;
00149 } __attribute__((packed));
00150 
00151 struct HubEvent {
00152 
00153         union {
00154 
00155                 struct {
00156                         uint16_t bmStatus; // port status bits
00157                         uint16_t bmChange; // port status change bits
00158                 } __attribute__((packed));
00159                 uint32_t bmEvent;
00160                 uint8_t evtBuff[4];
00161         };
00162 } __attribute__((packed));
00163 
00164 class USBHub : USBDeviceConfig {
00165         static bool bResetInitiated; // True when reset is triggered
00166 
00167         Usb *pUsb; // USB class instance pointer
00168 
00169         EpInfo epInfo[2]; // interrupt endpoint info structure
00170 
00171         uint8_t bAddress; // address
00172         uint8_t bNbrPorts; // number of ports
00173         //        uint8_t bInitState; // initialization state variable
00174         uint32_t qNextPollTime; // next poll time
00175         bool bPollEnable; // poll enable flag
00176 
00177         uint8_t CheckHubStatus();
00178         uint8_t PortStatusChange(uint8_t port, HubEvent &evt);
00179 
00180 public:
00181         USBHub(Usb *p);
00182 
00183         uint8_t ClearHubFeature(uint8_t fid);
00184         uint8_t ClearPortFeature(uint8_t fid, uint8_t port, uint8_t sel = 0);
00185         uint8_t GetHubDescriptor(uint8_t index, uint16_t nbytes, uint8_t *dataptr);
00186         uint8_t GetHubStatus(uint16_t nbytes, uint8_t* dataptr);
00187         uint8_t GetPortStatus(uint8_t port, uint16_t nbytes, uint8_t* dataptr);
00188         uint8_t SetHubDescriptor(uint8_t port, uint16_t nbytes, uint8_t* dataptr);
00189         uint8_t SetHubFeature(uint8_t fid);
00190         uint8_t SetPortFeature(uint8_t fid, uint8_t port, uint8_t sel = 0);
00191 
00192         void PrintHubStatus();
00193 
00194         uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
00195         uint8_t Release();
00196         uint8_t Poll();
00197         void ResetHubPort(uint8_t port);
00198 
00199         virtual uint8_t GetAddress() {
00200                 return bAddress;
00201         };
00202 
00203         virtual bool DEVCLASSOK(uint8_t klass) {
00204                 return (klass == 0x09);
00205         }
00206 
00207 };
00208 
00209 // Clear Hub Feature
00210 
00211 inline uint8_t USBHub::ClearHubFeature(uint8_t fid) {
00212         return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, 0, NULL, NULL));
00213 }
00214 // Clear Port Feature
00215 
00216 inline uint8_t USBHub::ClearPortFeature(uint8_t fid, uint8_t port, uint8_t sel) {
00217         return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000 | port) | (sel << 8)), 0, 0, NULL, NULL));
00218 }
00219 // Get Hub Descriptor
00220 
00221 inline uint8_t USBHub::GetHubDescriptor(uint8_t index, uint16_t nbytes, uint8_t *dataptr) {
00222         return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, nbytes, dataptr, NULL));
00223 }
00224 // Get Hub Status
00225 
00226 inline uint8_t USBHub::GetHubStatus(uint16_t nbytes, uint8_t* dataptr) {
00227         return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, nbytes, dataptr, NULL));
00228 }
00229 // Get Port Status
00230 
00231 inline uint8_t USBHub::GetPortStatus(uint8_t port, uint16_t nbytes, uint8_t* dataptr) {
00232         return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, nbytes, dataptr, NULL));
00233 }
00234 // Set Hub Descriptor
00235 
00236 inline uint8_t USBHub::SetHubDescriptor(uint8_t port, uint16_t nbytes, uint8_t* dataptr) {
00237         return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, nbytes, dataptr, NULL));
00238 }
00239 // Set Hub Feature
00240 
00241 inline uint8_t USBHub::SetHubFeature(uint8_t fid) {
00242         return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, 0, NULL, NULL));
00243 }
00244 // Set Port Feature
00245 
00246 inline uint8_t USBHub::SetPortFeature(uint8_t fid, uint8_t port, uint8_t sel) {
00247         return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000 | sel) << 8) | port), 0, 0, NULL, NULL));
00248 }
00249 
00250 void PrintHubPortStatus(Usb *usbptr, uint8_t addr, uint8_t port, bool print_changes = false);
00251 
00252 #endif // __USBHUB_H__