Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: UsbHostMAX3421E_Hello
UsbCore.h
00001 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved. 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00016 00017 Contact information 00018 ------------------- 00019 00020 Circuits At Home, LTD 00021 Web : http://www.circuitsathome.com 00022 e-mail : support@circuitsathome.com 00023 */ 00024 #ifndef USBCORE_H 00025 #define USBCORE_H 00026 00027 #include "MAX3421E.h" 00028 #include "address.h" 00029 00030 //#define USB_METHODS_INLINE 00031 /* Common setup data constant combinations */ 00032 #define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE //get descriptor request type 00033 #define bmREQ_SET USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE //set request type for all but 'set feature' and 'set interface' 00034 #define bmREQ_CL_GET_INTF USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE //get interface request type 00035 // D7 data transfer direction (0 - host-to-device, 1 - device-to-host) 00036 // D6-5 Type (0- standard, 1 - class, 2 - vendor, 3 - reserved) 00037 // D4-0 Recipient (0 - device, 1 - interface, 2 - endpoint, 3 - other, 4..31 - reserved) 00038 // USB Device Classes 00039 #define USB_CLASS_USE_CLASS_INFO 0x00 // Use Class Info in the Interface Descriptors 00040 #define USB_CLASS_AUDIO 0x01 // Audio 00041 #define USB_CLASS_COM_AND_CDC_CTRL 0x02 // Communications and CDC Control 00042 #define USB_CLASS_HID 0x03 // HID 00043 #define USB_CLASS_PHYSICAL 0x05 // Physical 00044 #define USB_CLASS_IMAGE 0x06 // Image 00045 #define USB_CLASS_PRINTER 0x07 // Printer 00046 #define USB_CLASS_MASS_STORAGE 0x08 // Mass Storage 00047 #define USB_CLASS_HUB 0x09 // Hub 00048 #define USB_CLASS_CDC_DATA 0x0a // CDC-Data 00049 #define USB_CLASS_SMART_CARD 0x0b // Smart-Card 00050 #define USB_CLASS_CONTENT_SECURITY 0x0d // Content Security 00051 #define USB_CLASS_VIDEO 0x0e // Video 00052 #define USB_CLASS_PERSONAL_HEALTH 0x0f // Personal Healthcare 00053 #define USB_CLASS_DIAGNOSTIC_DEVICE 0xdc // Diagnostic Device 00054 #define USB_CLASS_WIRELESS_CTRL 0xe0 // Wireless Controller 00055 #define USB_CLASS_MISC 0xef // Miscellaneous 00056 #define USB_CLASS_APP_SPECIFIC 0xfe // Application Specific 00057 #define USB_CLASS_VENDOR_SPECIFIC 0xff // Vendor Specific 00058 00059 // Additional Error Codes 00060 #define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED 0xD1 00061 #define USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE 0xD2 00062 #define USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS 0xD3 00063 #define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL 0xD4 00064 #define USB_ERROR_HUB_ADDRESS_OVERFLOW 0xD5 00065 #define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL 0xD6 00066 #define USB_ERROR_EPINFO_IS_NULL 0xD7 00067 #define USB_ERROR_INVALID_ARGUMENT 0xD8 00068 #define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD9 00069 #define USB_ERROR_INVALID_MAX_PKT_SIZE 0xDA 00070 #define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDB 00071 #define USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET 0xE0 00072 #define USB_ERROR_FailGetDevDescr 0xE1 00073 #define USB_ERROR_FailSetDevTblEntry 0xE2 00074 #define USB_ERROR_FailGetConfDescr 0xE3 00075 #define USB_ERROR_TRANSFER_TIMEOUT 0xFF 00076 00077 #define USB_XFER_TIMEOUT 5000 // (5000) USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec 00078 #define USB_RETRY_LIMIT 3 // 3 retry limit for a transfer 00079 #define USB_SETTLE_DELAY 200 // settle delay in milliseconds 00080 #define USB_NUMDEVICES 16 //number of USB devices 00081 #define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms 00082 //#define USB_NAK_LIMIT 32000 // NAK limit for a transfer. 0 means NAKs are not counted 00083 //#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller 00084 /* USB state machine states */ 00085 #define USB_STATE_MASK 0xf0 00086 #define USB_STATE_DETACHED 0x10 00087 #define USB_DETACHED_SUBSTATE_INITIALIZE 0x11 00088 #define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE 0x12 00089 #define USB_DETACHED_SUBSTATE_ILLEGAL 0x13 00090 #define USB_ATTACHED_SUBSTATE_SETTLE 0x20 00091 #define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30 00092 #define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE 0x40 00093 #define USB_ATTACHED_SUBSTATE_WAIT_SOF 0x50 00094 #define USB_ATTACHED_SUBSTATE_WAIT_RESET 0x51 00095 #define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE 0x60 00096 #define USB_STATE_ADDRESSING 0x70 00097 #define USB_STATE_CONFIGURING 0x80 00098 #define USB_STATE_RUNNING 0x90 00099 #define USB_STATE_ERROR 0xa0 00100 00101 00102 class USBDeviceConfig 00103 { 00104 public: 00105 virtual uint8_t Init 00106 ( 00107 uint8_t parent __attribute__((unused)), 00108 uint8_t port __attribute__((unused)), 00109 bool lowspeed __attribute__((unused)) 00110 ) 00111 { 00112 return 0; 00113 } 00114 00115 virtual uint8_t ConfigureDevice 00116 ( 00117 uint8_t parent __attribute__((unused)), 00118 uint8_t port __attribute__((unused)), 00119 bool lowspeed __attribute__((unused)) 00120 ) 00121 { 00122 return 0; 00123 } 00124 00125 virtual uint8_t Release() { return 0; } 00126 virtual uint8_t Poll() { return 0; } 00127 virtual uint8_t GetAddress() { return 0; } 00128 virtual void ResetHubPort(uint8_t port __attribute__((unused))) { return; } 00129 00130 // Note used for hubs only! 00131 virtual bool VIDPIDOK(uint16_t vid __attribute__((unused)), uint16_t pid __attribute__((unused))) { return false; } 00132 virtual bool DEVCLASSOK(uint8_t klass __attribute__((unused))) { return false; } 00133 virtual bool DEVSUBCLASSOK(uint8_t subklass __attribute__((unused))) { return true; } 00134 }; 00135 00136 /* USB Setup Packet Structure */ 00137 typedef struct 00138 { 00139 union 00140 { // offset description 00141 uint8_t bmRequestType; // 0 Bit-map of request type 00142 00143 struct 00144 { 00145 uint8_t recipient : 5; // Recipient of the request 00146 uint8_t type : 2; // Type of request 00147 uint8_t direction : 1; // Direction of data X-fer 00148 } __attribute__((packed)); 00149 } 00150 ReqType_u; 00151 uint8_t bRequest; // 1 Request 00152 00153 union 00154 { 00155 uint16_t wValue; // 2 Depends on bRequest 00156 00157 struct 00158 { 00159 uint8_t wValueLo; 00160 uint8_t wValueHi; 00161 } __attribute__((packed)); 00162 } 00163 wVal_u; 00164 uint16_t wIndex; // 4 Depends on bRequest 00165 uint16_t wLength; // 6 Depends on bRequest 00166 } 00167 __attribute__((packed)) 00168 SETUP_PKT, *PSETUP_PKT; 00169 00170 // Base class for incoming data parser 00171 class USBReadParser 00172 { 00173 public: 00174 virtual void Parse(const uint16_t len, const uint8_t* pbuf, const uint16_t& offset) = 0; 00175 }; 00176 00177 class Usb : public MAX3421E 00178 { 00179 AddressPoolImpl<USB_NUMDEVICES> addrPool; 00180 USBDeviceConfig* devConfig[USB_NUMDEVICES]; 00181 uint8_t bmHubPre; 00182 public: 00183 Usb(PinName mosi, PinName miso, PinName sck, PinName ss, PinName intr); 00184 int8_t init(); 00185 void SetHubPreMask() { bmHubPre |= bmHUBPRE; } 00186 void ResetHubPreMask() { bmHubPre &= (~bmHUBPRE); } 00187 AddressPool& GetAddressPool() { return (AddressPool&)addrPool; } 00188 uint8_t RegisterDeviceClass(USBDeviceConfig* pdev) 00189 { 00190 for (uint8_t i = 0; i < USB_NUMDEVICES; i++) { 00191 if (!devConfig[i]) { 00192 devConfig[i] = pdev; 00193 return 0; 00194 } 00195 } 00196 00197 return USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS; 00198 } 00199 00200 void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) { addrPool.ForEachUsbDevice(pfunc); } 00201 uint8_t getUsbTaskState(void); 00202 void setUsbTaskState(uint8_t state); 00203 00204 EpInfo* getEpInfoEntry(uint8_t addr, uint8_t ep); 00205 uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr); 00206 00207 /* Control requests */ 00208 uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr); 00209 uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr); 00210 00211 uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser* p); 00212 00213 uint8_t getStrDescr 00214 ( 00215 uint8_t addr, 00216 uint8_t ep, 00217 uint16_t nbytes, 00218 uint8_t index, 00219 uint16_t langid, 00220 uint8_t* dataptr 00221 ); 00222 uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr); 00223 uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value); 00224 /**/ 00225 uint8_t ctrlData(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr, bool direction); 00226 uint8_t ctrlStatus(uint8_t ep, bool direction, uint16_t nak_limit); 00227 uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t* nbytesptr, uint8_t* data, uint8_t bInterval = 0); 00228 uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data); 00229 uint8_t dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit); 00230 00231 void task(void); 00232 00233 uint8_t defaultAddressing(uint8_t parent, uint8_t port, bool lowspeed); 00234 uint8_t configuring(uint8_t parent, uint8_t port, bool lowspeed); 00235 uint8_t releaseDevice(uint8_t addr); 00236 00237 uint8_t ctrlReq 00238 ( 00239 uint8_t addr, 00240 uint8_t ep, 00241 uint8_t bmReqType, 00242 uint8_t bRequest, 00243 uint8_t wValLo, 00244 uint8_t wValHi, 00245 uint16_t wInd, 00246 uint16_t total, 00247 uint16_t nbytes, 00248 uint8_t* dataptr, 00249 USBReadParser* p 00250 ); 00251 private: 00252 uint8_t setAddress(uint8_t addr, uint8_t ep, EpInfo ** ppep, uint16_t* nak_limit); 00253 uint8_t outTransfer(EpInfo* pep, uint16_t nak_limit, uint16_t nbytes, uint8_t* data); 00254 uint8_t inTransfer(EpInfo* pep, uint16_t nak_limit, uint16_t* nbytesptr, uint8_t* data, uint8_t bInterval = 0); 00255 uint8_t attemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed); 00256 }; 00257 00258 #if 0 //defined(USB_METHODS_INLINE) 00259 00260 //get device descriptor 00261 inline uint8_t Usb::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) 00262 { 00263 return 00264 ( 00265 ctrlReq 00266 ( 00267 addr, 00268 ep, 00269 bmREQ_GET_DESCR, 00270 USB_REQUEST_GET_DESCRIPTOR, 00271 0x00, 00272 USB_DESCRIPTOR_DEVICE, 00273 0x0000, 00274 nbytes, 00275 dataptr 00276 ) 00277 ); 00278 } 00279 00280 //get configuration descriptor 00281 inline uint8_t Usb::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) 00282 { 00283 return 00284 ( 00285 ctrlReq 00286 ( 00287 addr, 00288 ep, 00289 bmREQ_GET_DESCR, 00290 USB_REQUEST_GET_DESCRIPTOR, 00291 conf, 00292 USB_DESCRIPTOR_CONFIGURATION, 00293 0x0000, 00294 nbytes, 00295 dataptr 00296 ) 00297 ); 00298 } 00299 00300 //get string descriptor 00301 inline uint8_t Usb::getStrDescr 00302 ( 00303 uint8_t addr, 00304 uint8_t ep, 00305 uint16_t nuint8_ts, 00306 uint8_t index, 00307 uint16_t langid, 00308 uint8_t* dataptr 00309 ) 00310 { 00311 return 00312 ( 00313 ctrlReq 00314 ( 00315 addr, 00316 ep, 00317 bmREQ_GET_DESCR, 00318 USB_REQUEST_GET_DESCRIPTOR, 00319 index, 00320 USB_DESCRIPTOR_STRING, 00321 langid, 00322 nuint8_ts, 00323 dataptr 00324 ) 00325 ); 00326 } 00327 00328 //set address 00329 inline uint8_t Usb::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) 00330 { 00331 return(ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL)); 00332 } 00333 00334 //set configuration 00335 inline uint8_t Usb::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) 00336 { 00337 return(ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL)); 00338 } 00339 #endif // defined(USB_METHODS_INLINE) 00340 #endif /* USBCORE_H */
Generated on Tue Jul 12 2022 18:12:05 by
1.7.2