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.
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 00025 // warning 00026 // #define _usb_h_ 00027 // #define MBED_H 00028 00029 #if !defined(_usb_h_) || defined(USBCORE_H) 00030 #error "Never include UsbCore.h directly; include Usb.h instead" 00031 #else 00032 #define USBCORE_H 00033 00034 // Not used anymore? If anyone uses this, please let us know so that this may be 00035 // moved to the proper place, settings.h. 00036 //#define USB_METHODS_INLINE 00037 00038 00039 /* Common setup data constant combinations */ 00040 #define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE //get descriptor request type 00041 #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' 00042 #define bmREQ_CL_GET_INTF USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE //get interface request type 00043 00044 // D7 data transfer direction (0 - host-to-device, 1 - device-to-host) 00045 // D6-5 Type (0- standard, 1 - class, 2 - vendor, 3 - reserved) 00046 // D4-0 Recipient (0 - device, 1 - interface, 2 - endpoint, 3 - other, 4..31 - reserved) 00047 00048 // USB Device Classes 00049 #define USB_CLASS_USE_CLASS_INFO 0x00 // Use Class Info in the Interface Descriptors 00050 #define USB_CLASS_AUDIO 0x01 // Audio 00051 #define USB_CLASS_COM_AND_CDC_CTRL 0x02 // Communications and CDC Control 00052 #define USB_CLASS_HID 0x03 // HID 00053 #define USB_CLASS_PHYSICAL 0x05 // Physical 00054 #define USB_CLASS_IMAGE 0x06 // Image 00055 #define USB_CLASS_PRINTER 0x07 // Printer 00056 #define USB_CLASS_MASS_STORAGE 0x08 // Mass Storage 00057 #define USB_CLASS_HUB 0x09 // Hub 00058 #define USB_CLASS_CDC_DATA 0x0a // CDC-Data 00059 #define USB_CLASS_SMART_CARD 0x0b // Smart-Card 00060 #define USB_CLASS_CONTENT_SECURITY 0x0d // Content Security 00061 #define USB_CLASS_VIDEO 0x0e // Video 00062 #define USB_CLASS_PERSONAL_HEALTH 0x0f // Personal Healthcare 00063 #define USB_CLASS_DIAGNOSTIC_DEVICE 0xdc // Diagnostic Device 00064 #define USB_CLASS_WIRELESS_CTRL 0xe0 // Wireless Controller 00065 #define USB_CLASS_MISC 0xef // Miscellaneous 00066 #define USB_CLASS_APP_SPECIFIC 0xfe // Application Specific 00067 #define USB_CLASS_VENDOR_SPECIFIC 0xff // Vendor Specific 00068 00069 // Additional Error Codes 00070 #define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED 0xD1 00071 #define USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE 0xD2 00072 #define USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS 0xD3 00073 #define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL 0xD4 00074 #define USB_ERROR_HUB_ADDRESS_OVERFLOW 0xD5 00075 #define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL 0xD6 00076 #define USB_ERROR_EPINFO_IS_NULL 0xD7 00077 #define USB_ERROR_INVALID_ARGUMENT 0xD8 00078 #define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD9 00079 #define USB_ERROR_INVALID_MAX_PKT_SIZE 0xDA 00080 #define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDB 00081 #define USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET 0xE0 00082 #define USB_ERROR_FailGetDevDescr 0xE1 00083 #define USB_ERROR_FailSetDevTblEntry 0xE2 00084 #define USB_ERROR_FailGetConfDescr 0xE3 00085 #define USB_ERROR_TRANSFER_TIMEOUT 0xFF 00086 00087 #define USB_XFER_TIMEOUT 5000 // (5000) USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec 00088 //#define USB_NAK_LIMIT 32000 // NAK limit for a transfer. 0 means NAKs are not counted 00089 #define USB_RETRY_LIMIT 3 // 3 retry limit for a transfer 00090 #define USB_SETTLE_DELAY 200 // settle delay in milliseconds 00091 00092 #define USB_NUMDEVICES 16 //number of USB devices 00093 //#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller 00094 #define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms 00095 00096 /* USB state machine states */ 00097 #define USB_STATE_MASK 0xf0 00098 00099 #define USB_STATE_DETACHED 0x10 00100 #define USB_DETACHED_SUBSTATE_INITIALIZE 0x11 00101 #define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE 0x12 00102 #define USB_DETACHED_SUBSTATE_ILLEGAL 0x13 00103 #define USB_ATTACHED_SUBSTATE_SETTLE 0x20 00104 #define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30 00105 #define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE 0x40 00106 #define USB_ATTACHED_SUBSTATE_WAIT_SOF 0x50 00107 #define USB_ATTACHED_SUBSTATE_WAIT_RESET 0x51 00108 #define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE 0x60 00109 #define USB_STATE_ADDRESSING 0x70 00110 #define USB_STATE_CONFIGURING 0x80 00111 #define USB_STATE_RUNNING 0x90 00112 #define USB_STATE_ERROR 0xa0 00113 00114 class USBDeviceConfig 00115 { 00116 public: 00117 virtual uint8_t Init(uint8_t parent __attribute__((unused)), uint8_t port __attribute__((unused)), bool lowspeed __attribute__((unused))) 00118 { 00119 return 0; 00120 } 00121 00122 virtual uint8_t ConfigureDevice(uint8_t parent __attribute__((unused)), uint8_t port __attribute__((unused)), bool lowspeed __attribute__((unused))) 00123 { 00124 return 0; 00125 } 00126 00127 virtual uint8_t Release() 00128 { 00129 return 0; 00130 } 00131 00132 virtual uint8_t Poll() 00133 { 00134 return 0; 00135 } 00136 00137 virtual uint8_t GetAddress() 00138 { 00139 return 0; 00140 } 00141 00142 virtual void ResetHubPort(uint8_t port __attribute__((unused))) 00143 { 00144 return; 00145 } // Note used for hubs only! 00146 00147 virtual bool VIDPIDOK(uint16_t vid __attribute__((unused)), uint16_t pid __attribute__((unused))) 00148 { 00149 return false; 00150 } 00151 00152 virtual bool DEVCLASSOK(uint8_t klass __attribute__((unused))) 00153 { 00154 return false; 00155 } 00156 00157 virtual bool DEVSUBCLASSOK(uint8_t subklass __attribute__((unused))) 00158 { 00159 return true; 00160 } 00161 }; 00162 00163 /* USB Setup Packet Structure */ 00164 typedef struct 00165 { 00166 00167 union { // offset description 00168 uint8_t bmRequestType; // 0 Bit-map of request type 00169 00170 struct 00171 { 00172 uint8_t recipient : 5; // Recipient of the request 00173 uint8_t type : 2; // Type of request 00174 uint8_t direction : 1; // Direction of data X-fer 00175 } __attribute__((packed)); 00176 } ReqType_u; 00177 uint8_t bRequest; // 1 Request 00178 00179 union { 00180 uint16_t wValue; // 2 Depends on bRequest 00181 00182 struct 00183 { 00184 uint8_t wValueLo; 00185 uint8_t wValueHi; 00186 } __attribute__((packed)); 00187 } wVal_u; 00188 uint16_t wIndex; // 4 Depends on bRequest 00189 uint16_t wLength; // 6 Depends on bRequest 00190 } __attribute__((packed)) SETUP_PKT, *PSETUP_PKT; 00191 00192 // Base class for incoming data parser 00193 00194 class USBReadParser 00195 { 00196 public: 00197 virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset) = 0; 00198 }; 00199 00200 class USB : public MAX3421E 00201 { 00202 AddressPoolImpl<USB_NUMDEVICES> addrPool; 00203 USBDeviceConfig *devConfig[USB_NUMDEVICES]; 00204 uint8_t bmHubPre; 00205 00206 private: 00207 static Timer arduinoTimer; // for millis() & micros() function in Arduino 00208 public: 00209 static uint32_t read_ms() { return arduinoTimer.read_ms(); } 00210 static uint32_t read_us() { return arduinoTimer.read_us(); } 00211 00212 public: 00213 USB(PinName mosi, PinName miso, PinName sclk, PinName ssel, PinName intr); 00214 00215 void SetHubPreMask() 00216 { 00217 bmHubPre |= bmHUBPRE; 00218 }; 00219 00220 void ResetHubPreMask() 00221 { 00222 bmHubPre &= (~bmHUBPRE); 00223 }; 00224 00225 AddressPool &GetAddressPool() 00226 { 00227 return (AddressPool &)addrPool; 00228 }; 00229 00230 uint8_t RegisterDeviceClass(USBDeviceConfig *pdev) 00231 { 00232 for (uint8_t i = 0; i < USB_NUMDEVICES; i++) 00233 { 00234 if (!devConfig[i]) 00235 { 00236 devConfig[i] = pdev; 00237 return 0; 00238 } 00239 } 00240 return USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS; 00241 }; 00242 00243 void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) 00244 { 00245 addrPool.ForEachUsbDevice(pfunc); 00246 }; 00247 uint8_t getUsbTaskState(void); 00248 void setUsbTaskState(uint8_t state); 00249 00250 EpInfo *getEpInfoEntry(uint8_t addr, uint8_t ep); 00251 uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo *eprecord_ptr); 00252 00253 /* Control requests */ 00254 uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr); 00255 uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr); 00256 00257 uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p); 00258 00259 uint8_t getStrDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t index, uint16_t langid, uint8_t *dataptr); 00260 uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr); 00261 uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value); 00262 /**/ 00263 uint8_t ctrlData(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr, bool direction); 00264 uint8_t ctrlStatus(uint8_t ep, bool direction, uint16_t nak_limit); 00265 uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval = 0); 00266 uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data); 00267 uint8_t dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit); 00268 00269 void Task(void); 00270 00271 uint8_t DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed); 00272 uint8_t Configuring(uint8_t parent, uint8_t port, bool lowspeed); 00273 uint8_t ReleaseDevice(uint8_t addr); 00274 00275 uint8_t ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, 00276 uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t *dataptr, USBReadParser *p); 00277 00278 private: 00279 void init(); 00280 uint8_t SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_limit); 00281 uint8_t OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data); 00282 uint8_t InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval = 0); 00283 uint8_t AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed); 00284 }; 00285 00286 #if 0 //defined(USB_METHODS_INLINE) 00287 //get device descriptor 00288 00289 inline uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) { 00290 return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr)); 00291 } 00292 //get configuration descriptor 00293 00294 inline uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) { 00295 return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr)); 00296 } 00297 //get string descriptor 00298 00299 inline uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t nuint8_ts, uint8_t index, uint16_t langid, uint8_t* dataptr) { 00300 return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr)); 00301 } 00302 //set address 00303 00304 inline uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) { 00305 return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL)); 00306 } 00307 //set configuration 00308 00309 inline uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) { 00310 return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL)); 00311 } 00312 00313 //Timer USB::arduinoTimer; 00314 00315 #endif // defined(USB_METHODS_INLINE) 00316 00317 #endif /* USBCORE_H */
Generated on Thu Jul 14 2022 08:33:41 by
1.7.2