USB host library, support isochronous,bulk,interrupt and control.

Dependents:   BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example

Import programBaseUsbHost_example

BaseUsbHost example program

Revision:
4:d931d24c2f81
Parent:
3:ae77d63a1eda
Child:
5:8a2d056e9b38
--- 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);