USB host library, support isochronous,bulk,interrupt and control.
Dependents: BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example
BaseUsbHost.h
00001 // BaseUsbHost.h 2013/2/11 00002 #pragma once 00003 #include <vector> 00004 #include <string> 00005 00006 #define USB_OK 0 00007 #define USB_PROCESSING -1 00008 #define USB_ERROR -2 00009 #define USB_ERROR_MEMORY -3 00010 #define USB_ERROR_STALL -4 00011 #define USB_ERROR_DEVICE_NOT_RESPONDING -5 00012 00013 // USB STANDARD REQUEST DEFINITIONS 00014 #define USB_DESCRIPTOR_TYPE_DEVICE 1 00015 #define USB_DESCRIPTOR_TYPE_CONFIGURATION 2 00016 #define USB_DESCRIPTOR_TYPE_STRING 3 00017 #define USB_DESCRIPTOR_TYPE_INTERFACE 4 00018 #define USB_DESCRIPTOR_TYPE_ENDPOINT 5 00019 #define USB_DESCRIPTOR_TYPE_HUB 0x29 00020 // ----------- Control RequestType Fields ----------- 00021 #define USB_DEVICE_TO_HOST 0x80 00022 #define USB_HOST_TO_DEVICE 0x00 00023 #define USB_REQUEST_TYPE_CLASS 0x20 00024 #define USB_RECIPIENT_DEVICE 0x00 00025 #define USB_RECIPIENT_INTERFACE 0x01 00026 #define USB_RECIPIENT_OTHER 0x03 00027 // -------------- USB Standard Requests -------------- 00028 #define GET_STATUS 0 00029 #define CLEAR_FEATURE 1 00030 #define SET_FEATURE 3 00031 #define SET_ADDRESS 5 00032 #define GET_DESCRIPTOR 6 00033 #define SET_CONFIGURATION 9 00034 #define SET_INTERFACE 11 00035 00036 #pragma pack(push,1) 00037 struct StandardDeviceDescriptor {// offset 00038 uint8_t bLength; // +0 00039 uint8_t bDescriptorType; // +1 00040 uint16_t bcdUSB; // +2 00041 uint8_t bDeviceClass; // +4 00042 uint8_t bDeviceSubClass; // +5 00043 uint8_t bDeviceProtocol; // +6 00044 uint8_t bMaxPacketSize; // +7 00045 uint16_t idVendor; // +8 00046 uint16_t idProduct; // +10 00047 uint16_t bcdDevice; // +12 00048 uint8_t iManufacturer; // +14 00049 uint8_t iProduct; // +15 00050 uint8_t iSerialNumber; // +16 00051 uint8_t bNumConfigurations; // +17 00052 }; // +18 00053 00054 struct StandardConfigurationDescriptor {// offset 00055 uint8_t bLength; // +0 00056 uint8_t bDescriptorType; // +1 00057 uint16_t wTotalLength; // +2 00058 uint8_t bNumInterfaces; // +4 00059 uint8_t bConfigurationValue; // +5 00060 uint8_t iConfiguration; // +6 00061 uint8_t bmAttributes; // +7 00062 uint8_t bMaxPower; // +8 00063 }; // +9 00064 00065 struct StandardInterfaceDescriptor {// offset 00066 uint8_t bLength; // +0 00067 uint8_t bDescriptorType; // +1 00068 uint8_t bInterfaceNumber; // +2 00069 uint8_t bAlternateSetting; // +3 00070 uint8_t bNumEndpoints; // +4 00071 uint8_t bInterfaceClass; // +5 00072 uint8_t bInterfaceSubClass;// +6 00073 uint8_t bInterfaceProtocol;// +7 00074 uint8_t iInterface; // +8 00075 }; // +9 00076 00077 struct StandardEndpointDescriptor {// offset 00078 uint8_t bLength; // +0 00079 uint8_t bDescriptorType; // +1 00080 uint8_t bEndpointAddress; // +2 00081 uint8_t bmAttributes; // +3 00082 uint16_t wMaxPacketSize; // +4 00083 uint8_t bInterval; // +6 00084 }; // +7 00085 00086 struct StandardStringDescriptor {// offset 00087 uint8_t bLength; // +0 00088 uint8_t bDescriptorType; // +1 00089 char bString[0]; // +2 00090 }; // +3 00091 00092 struct HubDescriptor { // offset 00093 uint8_t bDescLength; // +0 00094 uint8_t bDescriptorType; // +1 00095 uint8_t bNbrPorts; // +2 00096 uint16_t wHubCharacteristics;// +3 00097 uint8_t bPwrOn2PwrGood; // +5 00098 uint8_t bHubContrCurrent; // +6 00099 uint8_t DeviceRemovable; // +7 00100 uint8_t PortPweCtrlMak; // +8 00101 }; // +9 00102 #pragma pack(pop) 00103 00104 // ------------------ HcControl Register --------------------- 00105 #define OR_CONTROL_PLE 0x00000004 00106 #define OR_CONTROL_IE 0x00000008 00107 #define OR_CONTROL_CLE 0x00000010 00108 #define OR_CONTROL_BLE 0x00000020 00109 #define OR_CONTROL_HCFS 0x000000C0 00110 #define OR_CONTROL_HC_OPER 0x00000080 00111 // ----------------- HcCommandStatus Register ----------------- 00112 #define OR_CMD_STATUS_HCR 0x00000001 00113 #define OR_CMD_STATUS_CLF 0x00000002 00114 #define OR_CMD_STATUS_BLF 0x00000004 00115 // --------------- HcInterruptStatus Register ----------------- 00116 #define OR_INTR_STATUS_WDH 0x00000002 00117 #define OR_INTR_STATUS_UE 0x00000010 00118 #define OR_INTR_STATUS_FNO 0x00000020 00119 #define OR_INTR_STATUS_RHSC 0x00000040 00120 // --------------- HcInterruptEnable Register ----------------- 00121 #define OR_INTR_ENABLE_WDH 0x00000002 00122 #define OR_INTR_ENABLE_FNO 0x00000020 00123 #define OR_INTR_ENABLE_RHSC 0x00000040 00124 #define OR_INTR_ENABLE_MIE 0x80000000 00125 // ---------------- HcRhDescriptorA Register ------------------ 00126 #define OR_RH_STATUS_LPSC 0x00010000 00127 #define OR_RH_STATUS_DRWE 0x00008000 00128 // -------------- HcRhPortStatus[1:NDP] Register -------------- 00129 #define OR_RH_PORT_CCS 0x00000001 00130 #define OR_RH_PORT_PRS 0x00000010 00131 #define OR_RH_PORT_CSC 0x00010000 00132 #define OR_RH_PORT_PRSC 0x00100000 00133 00134 // TRANSFER DESCRIPTOR CONTROL FIELDS 00135 #define TD_ROUNDING (uint32_t)(0x00040000) /* Buffer Rounding */ 00136 #define TD_SETUP (uint32_t)(0x00000000) /* Direction of Setup Packet */ 00137 #define TD_IN (uint32_t)(0x00100000) /* Direction In */ 00138 #define TD_OUT (uint32_t)(0x00080000) /* Direction Out */ 00139 #define TD_DELAY_INT(x) (uint32_t)((x) << 21) /* Delay Interrupt */ 00140 #define TD_DI (uint32_t)(7<<21) /* desable interrupt */ 00141 #define TD_TOGGLE_0 (uint32_t)(0x02000000) /* Toggle 0 */ 00142 #define TD_TOGGLE_1 (uint32_t)(0x03000000) /* Toggle 1 */ 00143 #define TD_CC (uint32_t)(0xF0000000) /* Completion Code */ 00144 00145 class BaseEp; 00146 struct HCTD { // HostController Transfer Descriptor 00147 __IO uint32_t Control; // +0 Transfer descriptor control 00148 __IO uint8_t* CurrBufPtr; // +4 Physical address of current buffer pointer 00149 HCTD* Next; // +8 Physical pointer to next Transfer Descriptor 00150 uint8_t* BufEnd; // +12 Physical address of end of buffer 00151 uint8_t* buf_top; // +16 Buffer start address 00152 uint16_t buf_size; // +20 buffer size size 00153 uint8_t _dummy[10]; // +22 dummy 00154 BaseEp* ep; // +32 endpoint object 00155 // +36 00156 HCTD(BaseEp* obj); 00157 inline void* operator new(size_t size) { 00158 void* p; 00159 if (posix_memalign(&p, 16, size) == 0) { 00160 return p; 00161 } 00162 return NULL; 00163 } 00164 00165 inline void operator delete(void* p) { 00166 free(p); 00167 } 00168 00169 inline void transfer(uint8_t* data, int len) { 00170 CurrBufPtr = data; 00171 buf_top = data; 00172 buf_size = len; 00173 BufEnd = const_cast<uint8_t*>(data)+len-1; 00174 } 00175 00176 inline int status() { 00177 if (CurrBufPtr) { 00178 return CurrBufPtr - buf_top; 00179 } 00180 return buf_size; 00181 } 00182 00183 inline uint8_t ConditionCode() { 00184 return Control>>28; 00185 } 00186 }; 00187 00188 struct HCITD { // HostController Isochronous Transfer Descriptor 00189 __IO uint32_t Control; // +0 Transfer descriptor control 00190 uint8_t* BufferPage0; // +4 Buffer Page 0 00191 HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor 00192 uint8_t* BufferEnd; // +12 buffer End 00193 __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW 00194 BaseEp* ep; // +32 endpoint object 00195 __IO uint8_t buf[0]; // +36 buffer 00196 // +36 00197 HCITD(BaseEp* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize); 00198 inline void* operator new(size_t size, int buf_size) { 00199 void* p; 00200 if (posix_memalign(&p, 32, size+buf_size) == 0) { 00201 return p; 00202 } 00203 return NULL; 00204 } 00205 00206 inline void operator delete(void* p) { 00207 free(p); 00208 } 00209 00210 inline uint16_t StartingFrame() { 00211 return Control & 0xffff; 00212 } 00213 00214 inline uint8_t FrameCount() { 00215 return ((Control>>24)&7)+1; 00216 } 00217 00218 inline uint8_t ConditionCode() { 00219 return Control>>28; 00220 } 00221 }; 00222 00223 struct HCED { // HostController EndPoint Descriptor 00224 __IO uint32_t Control; // +0 Endpoint descriptor control 00225 HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list 00226 __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list 00227 HCED* Next; // +12 Physical address of next Endpoint descriptor 00228 // +16 00229 HCED(int addr, uint8_t ep, uint16_t size, int lowSpeed) { 00230 Control = addr | /* USB address */ 00231 ((ep & 0x7F) << 7) | /* Endpoint address */ 00232 (ep!=0?(((ep&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */ 00233 ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */ 00234 (size << 16); /* MaxPkt Size */ 00235 Next = NULL; 00236 } 00237 00238 inline void* operator new(size_t size) { 00239 void* p; 00240 if (posix_memalign(&p, 16, size) == 0) { 00241 return p; 00242 } 00243 return NULL; 00244 } 00245 00246 inline void operator delete(void* p) { 00247 free(p); 00248 } 00249 00250 inline uint8_t FunctionAddress() { 00251 return Control & 0x7f; 00252 } 00253 00254 inline int Speed() { 00255 return (Control>>13)&1; 00256 } 00257 00258 inline void setFunctionAddress(int addr) { 00259 Control &= ~0x7f; 00260 Control |= addr; 00261 } 00262 00263 inline void setMaxPacketSize(uint16_t size) { 00264 Control &= ~0xffff0000; 00265 Control |= size<<16; 00266 } 00267 }; 00268 00269 struct HCCA { // Host Controller Communication Area 00270 HCED* InterruptTable[32]; // +0 Interrupt Table 00271 __IO uint16_t FrameNumber;// +128 Frame Number 00272 __IO uint16_t Pad1; // +130 00273 __IO HCTD* DoneHead; // +132 Done Head 00274 uint8_t Reserved[116]; // +136 Reserved for future use 00275 uint8_t Unknown[4]; // +252 Unused 00276 // +256 00277 inline void* operator new(size_t size) { 00278 void* p; 00279 if (posix_memalign(&p, 256, size) == 0) { 00280 return p; 00281 } 00282 return NULL; 00283 } 00284 00285 inline void operator delete(void* p) { 00286 free(p); 00287 } 00288 }; 00289 00290 class BaseUsbHost { 00291 public: 00292 BaseUsbHost(); 00293 void irqHandler(); 00294 // report 00295 uint32_t m_report_irq; 00296 uint32_t m_report_RHSC; 00297 uint32_t m_report_FNO; 00298 uint32_t m_report_WDH; 00299 uint32_t m_report_sp; 00300 private: 00301 void init_hw_ohci(HCCA* pHcca); 00302 void ResetRootHub(); 00303 HCCA* m_pHcca; 00304 }; 00305 00306 #define HCTD_QUEUE_SIZE 3 00307 00308 class BaseEp { // endpoint 00309 public: 00310 BaseEp(int addr, uint8_t ep = 0, uint16_t size = 8, int lowSpeed = 0); 00311 int GetAddr(); 00312 int GetLowSpeed(); 00313 void update_FunctionAddress(int addr); 00314 void update_MaxPacketSize(uint16_t size); 00315 int transfer(uint8_t* buf, int len); 00316 int status(uint32_t millisec=osWaitForever); 00317 // 00318 virtual void enable() = 0; 00319 virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} // WDH 00320 int wait_queue_HCTD(HCTD* wait_td, uint32_t millisec=osWaitForever); 00321 // report 00322 uint8_t m_ConditionCode; 00323 int m_report_queue_error; 00324 protected: 00325 int send_receive(uint8_t* buf, int len, int millisec); 00326 HCTD* get_queue_HCTD(uint32_t millisec=osWaitForever); 00327 HCED* m_pED; 00328 Queue<HCTD, HCTD_QUEUE_SIZE> m_queue; // TD done queue 00329 int m_td_queue_count; 00330 }; 00331 00332 class ControlEp : public BaseEp { 00333 public: 00334 ControlEp(int lowSpeed = 0); 00335 int GetDescriptor(int descType, int descIndex, uint8_t* data, int length); 00336 int SetAddress(int addr); // device address 00337 int SetConfiguration(int config); 00338 int GetConfiguration(int *config); 00339 int SetInterfaceAlternate(int interface, int alternate); 00340 int GetInterface(int interface, int *alternate); 00341 int controlSend(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, const uint8_t* data=NULL, int length=0); 00342 int controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t* data, int length); 00343 string GetStringDescriptor(int index); 00344 private: 00345 int open(int addr); 00346 virtual void enable(){}; 00347 }; 00348 00349 class BulkEp : public BaseEp { 00350 public: 00351 BulkEp(int addr, uint8_t ep, uint16_t size); 00352 int bulkSend(const uint8_t* buf, int len, int millisec=osWaitForever); 00353 int bulkReceive(uint8_t* buf, int len, int millisec=osWaitForever); 00354 private: 00355 virtual void enable(); 00356 }; 00357 00358 class InterruptEp : public BaseEp { 00359 public: 00360 InterruptEp(int addr, uint8_t ep, uint16_t size, int lowSpeed=0); 00361 int interruptReceive(uint8_t* buf, int len, int millisec=osWaitForever); 00362 private: 00363 virtual void enable(); 00364 }; 00365 00366 class IsochronousEp : public BaseEp { 00367 public: 00368 IsochronousEp(int addr, uint8_t ep, uint16_t size); 00369 void reset(int delay_ms = 100); 00370 HCITD* isochronousReveive(int millisec=osWaitForever); 00371 int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever); 00372 HCITD* get_queue_HCITD(int millisec); 00373 uint16_t m_PacketSize; 00374 private: 00375 HCITD* new_HCITD(BaseEp* obj); 00376 int m_itd_queue_count; 00377 uint16_t m_FrameNumber; 00378 int m_FrameCount; // 1-8 00379 virtual void enable(); 00380 }; 00381 00382 // --- HUB -------------------------------------------------- 00383 class UsbHub { 00384 public: 00385 UsbHub(ControlEp* ctlEp = NULL); 00386 static bool check(ControlEp* ctlEp); 00387 int SetPortPower(int port); 00388 int ClearPortPower(int port); 00389 vector<ControlEp*> PortEp; 00390 template<class T> ControlEp* search(int skip = 0) { 00391 for(vector<ControlEp*>::iterator it = PortEp.begin(); it != PortEp.end(); ++it) { 00392 if (T::check(*it)) { 00393 if (skip-- <= 0) { 00394 return *it; 00395 } 00396 } 00397 } 00398 return NULL; 00399 } 00400 template<class T> ControlEp* assign(int port) { 00401 if (port >= 0 && port < PortEp.size()) { 00402 return PortEp[port]; 00403 } 00404 return NULL; 00405 } 00406 private: 00407 int PortReset(int port); 00408 int SetPortFeature(int feature, int index); 00409 int ClearPortFeature(int feature, int index); 00410 int SetPortReset(int port); 00411 int GetPortStatus(int port, uint32_t* status); 00412 ControlEp* m_ctlEp; 00413 }; 00414 00415 // --- UVC -------------------------------------------------- 00416 #define _30FPS 333333 00417 #define _25FPS 400000 00418 #define _20FPS 500000 00419 #define _15FPS 666666 00420 #define _10FPS 1000000 00421 #define _5FPS 2000000 00422 #define _1FPS 10000000 00423 00424 #define SET_CUR 0x01 00425 #define GET_CUR 0x81 00426 #define GET_MIN 0x82 00427 #define GET_MAX 0x83 00428 #define GET_RES 0x84 00429 #define GET_LEN 0x85 00430 #define GET_INFO 0x86 00431 #define GET_DEF 0x87 00432 00433 #define VS_PROBE_CONTROL 0x01 00434 #define VS_COMMIT_CONTROL 0x02 00435 00436 class BaseUvc { 00437 public: 00438 void poll(int millisec=osWaitForever); 00439 int Control(int req, int cs, int index, uint8_t* buf, int size); 00440 ControlEp* m_ctlEp; 00441 IsochronousEp* m_isoEp; 00442 uint32_t report_cc_count[16]; // ConditionCode 00443 uint32_t report_ps_cc_count[16]; // Packt Status ConditionCode 00444 // callback 00445 void onResult(uint16_t frame, uint8_t* buf, int len); 00446 void setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ); 00447 class CDummy; 00448 template<class T> 00449 void setOnResult( T* pItem, void (T::*pMethod)(uint16_t, uint8_t*, int) ) 00450 { 00451 m_pCb = NULL; 00452 m_pCbItem = (CDummy*) pItem; 00453 m_pCbMeth = (void (CDummy::*)(uint16_t, uint8_t*, int)) pMethod; 00454 } 00455 void clearOnResult(); 00456 CDummy* m_pCbItem; 00457 void (CDummy::*m_pCbMeth)(uint16_t, uint8_t*, int); 00458 void (*m_pCb)(uint16_t, uint8_t*, int); 00459 };
Generated on Fri Jul 15 2022 19:56:09 by 1.7.2