USB host library, support isochronous,bulk,interrupt and control.
Dependents: BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example
Import programBaseUsbHost_example
BaseUsbHost example program
Diff: BaseUsbHost.h
- Revision:
- 4:d931d24c2f81
- Parent:
- 3:ae77d63a1eda
- Child:
- 5:8a2d056e9b38
diff -r ae77d63a1eda -r d931d24c2f81 BaseUsbHost.h --- a/BaseUsbHost.h Sun Jan 06 11:45:18 2013 +0000 +++ b/BaseUsbHost.h Fri Jan 25 14:51:33 2013 +0000 @@ -1,4 +1,4 @@ -// BaseUsbHost.h 2013/1/5 +// BaseUsbHost.h 2013/1/24 #pragma once #include <vector> @@ -33,7 +33,7 @@ #define SET_INTERFACE 11 #pragma pack(push,1) -typedef struct { // offset +struct StandardDeviceDescriptor {// offset uint8_t bLength; // +0 uint8_t bDescriptorType; // +1 uint16_t bcdUSB; // +2 @@ -48,9 +48,9 @@ uint8_t iProduct; // +15 uint8_t iSerialNumber; // +16 uint8_t bNumConfigurations; // +17 -} StandardDeviceDescriptor; // +18 +}; // +18 -typedef struct { // offset +struct StandardConfigurationDescriptor {// offset uint8_t bLength; // +0 uint8_t bDescriptorType; // +1 uint16_t wTotalLength; // +2 @@ -59,9 +59,9 @@ uint8_t iConfiguration; // +6 uint8_t bmAttributes; // +7 uint8_t bMaxPower; // +8 -} StandardConfigurationDescriptor; // +9 +}; // +9 -typedef struct { // offset +struct StandardInterfaceDescriptor {// offset uint8_t bLength; // +0 uint8_t bDescriptorType; // +1 uint8_t bInterfaceNumber; // +2 @@ -71,18 +71,18 @@ uint8_t bInterfaceSubClass;// +6 uint8_t bInterfaceProtocol;// +7 uint8_t iInterface; // +8 -} StandardInterfaceDescriptor; // +9 +}; // +9 -typedef struct { // offset +struct StandardEndpointDescriptor {// offset uint8_t bLength; // +0 uint8_t bDescriptorType; // +1 uint8_t bEndpointAddress; // +2 uint8_t bmAttributes; // +3 uint16_t wMaxPacketSize; // +4 uint8_t bInterval; // +6 -} StandardEndpointDescriptor; // +7 +}; // +7 -typedef struct { // offset +struct HubDescriptor { // offset uint8_t bDescLength; // +0 uint8_t bDescriptorType; // +1 uint8_t bNbrPorts; // +2 @@ -91,7 +91,7 @@ uint8_t bHubContrCurrent; // +6 uint8_t DeviceRemovable; // +7 uint8_t PortPweCtrlMak; // +8 -} HubDescriptor; // +9 +}; // +9 #pragma pack(pop) // ------------------ HcControl Register --------------------- @@ -135,44 +135,150 @@ #define TD_TOGGLE_1 (uint32_t)(0x03000000) /* Toggle 1 */ #define TD_CC (uint32_t)(0xF0000000) /* Completion Code */ -typedef struct { // Host Controller Communication Area - uint32_t InterruptTable[32]; // Interrupt Table - __IO uint16_t FrameNumber; // Frame Number - __IO uint16_t Pad1; - __IO uint32_t DoneHead; // Done Head - uint8_t Reserved[116]; // Reserved for future use - uint8_t Unknown[4]; // Unused -} HCCA; +class BaseEp; +struct HCTD { // HostController Transfer Descriptor + __IO uint32_t Control; // +0 Transfer descriptor control + __IO uint8_t* CurrBufPtr; // +4 Physical address of current buffer pointer + HCTD* Next; // +8 Physical pointer to next Transfer Descriptor + uint8_t* BufEnd; // +12 Physical address of end of buffer + uint8_t* buf_top; // +16 Buffer start address + uint16_t buf_size; // +20 buffer size size + uint8_t _dummy[10]; // +22 dummy + BaseEp* ep; // +32 endpoint object + // +36 + HCTD(BaseEp* obj); + inline void* operator new(size_t size) { + void* p; + if (posix_memalign(&p, 16, size) == 0) { + return p; + } + return NULL; + } -typedef struct { // HostController Transfer Descriptor - __IO uint32_t Control; // +0 Transfer descriptor control - __IO uint8_t* CurrBufPtr; // +4 Physical address of current buffer pointer - __IO uint32_t Next; // +8 Physical pointer to next Transfer Descriptor - uint8_t* BufEnd; // +12 Physical address of end of buffer - uint8_t* buf_top; // +16 Buffer start address - uint16_t buf_size; // +20 buffer size size - uint8_t setup[8]; // +22 setup cmd area - uint8_t _dummy[2]; // +30 dummy - void *ep; // +32 endpoint object - __IO uint8_t buf[0]; // +36 buffer -} HCTD; // +36 + inline void operator delete(void* p) { + free(p); + } + + inline void transfer(uint8_t* data, int len) { + CurrBufPtr = data; + buf_top = data; + buf_size = len; + BufEnd = const_cast<uint8_t*>(data)+len-1; + } -typedef struct { // HostController Isochronous Transfer Descriptor + inline int status() { + if (CurrBufPtr) { + return CurrBufPtr - buf_top; + } + return buf_size; + } + + inline uint8_t ConditionCode() { + return Control>>28; + } +}; + +struct HCITD { // HostController Isochronous Transfer Descriptor __IO uint32_t Control; // +0 Transfer descriptor control uint8_t* BufferPage0; // +4 Buffer Page 0 - __IO uint32_t Next; // +8 Physical pointer to next Transfer Descriptor + HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor uint8_t* BufferEnd; // +12 buffer End __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW - void *ep; // +32 endpoint object + BaseEp* ep; // +32 endpoint object __IO uint8_t buf[0]; // +36 buffer -} HCITD; // +36 + // +36 + HCITD(BaseEp* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize); + inline void* operator new(size_t size, int buf_size) { + void* p; + if (posix_memalign(&p, 32, size+buf_size) == 0) { + return p; + } + return NULL; + } + + inline void operator delete(void* p) { + free(p); + } -typedef struct { // HostController EndPoint Descriptor + inline uint16_t StartingFrame() { + return Control & 0xffff; + } + + inline uint8_t FrameCount() { + return ((Control>>24)&7)+1; + } + + inline uint8_t ConditionCode() { + return Control>>28; + } +}; + +struct HCED { // HostController EndPoint Descriptor __IO uint32_t Control; // +0 Endpoint descriptor control HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list - uint32_t Next; // +12 Physical address of next Endpoint descriptor -} HCED; + HCED* Next; // +12 Physical address of next Endpoint descriptor + // +16 + HCED(int addr, uint8_t ep, uint16_t size, int lowSpeed) { + Control = addr | /* USB address */ + ((ep & 0x7F) << 7) | /* Endpoint address */ + (ep!=0?(((ep&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */ + ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */ + (size << 16); /* MaxPkt Size */ + Next = NULL; + } + + inline void* operator new(size_t size) { + void* p; + if (posix_memalign(&p, 16, size) == 0) { + return p; + } + return NULL; + } + + inline void operator delete(void* p) { + free(p); + } + + inline uint8_t FunctionAddress() { + return Control & 0x7f; + } + + inline int Speed() { + return (Control>>13)&1; + } + + inline void setFunctionAddress(int addr) { + Control &= ~0x7f; + Control |= addr; + } + + inline void setMaxPacketSize(uint16_t size) { + Control &= ~0xffff0000; + Control |= size<<16; + } +}; + +struct HCCA { // Host Controller Communication Area + HCED* InterruptTable[32]; // +0 Interrupt Table + __IO uint16_t FrameNumber;// +128 Frame Number + __IO uint16_t Pad1; // +130 + __IO HCTD* DoneHead; // +132 Done Head + uint8_t Reserved[116]; // +136 Reserved for future use + uint8_t Unknown[4]; // +252 Unused + // +256 + inline void* operator new(size_t size) { + void* p; + if (posix_memalign(&p, 256, size) == 0) { + return p; + } + return NULL; + } + + inline void operator delete(void* p) { + free(p); + } +}; class BaseUsbHost { public: @@ -203,8 +309,6 @@ int status(uint32_t millisec=osWaitForever); // virtual void enable() = 0; - HCTD* new_HCTD(int buf_size=0); - void delete_HCTD(HCTD* p); virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} // WDH int wait_queue_HCTD(HCTD* wait_td, uint32_t millisec=osWaitForever); // report @@ -231,7 +335,6 @@ int controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t* data, int length); private: int open(int addr); - void setup(HCTD* td, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, uint16_t wLength=0); virtual void enable(){}; }; @@ -259,9 +362,9 @@ HCITD* isochronousReveive(int millisec=osWaitForever); int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever); HCITD* get_queue_HCITD(int millisec); - int m_PacketSize; // 128,192 + uint16_t m_PacketSize; private: - HCITD* new_HCITD(); + HCITD* new_HCITD(BaseEp* obj); int m_itd_queue_count; uint16_t m_FrameNumber; int m_FrameCount; // 1-8 @@ -276,6 +379,22 @@ int SetPortPower(int port); int ClearPortPower(int port); vector<ControlEp*> PortEp; + template<class T> ControlEp* search(int skip = 0) { + for(vector<ControlEp*>::iterator it = PortEp.begin(); it != PortEp.end(); ++it) { + if (T::check(*it)) { + if (skip-- <= 0) { + return *it; + } + } + } + return NULL; + } + template<class T> ControlEp* assign(int port) { + if (port >= 0 && port < PortEp.size()) { + return PortEp[port]; + } + return NULL; + } private: int PortReset(int port); int SetPortFeature(int feature, int index);