LogitechC270 webcam class driver alpha version

Dependencies:   USBHost mbed

Fork of USBHostMSD_HelloWorld by Samuel Mokrani

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBIsochronous.h Source File

USBIsochronous.h

00001 // USBIsochronous.h
00002 #pragma once
00003 
00004 class IsochronousEp;
00005 struct HCITD {    // HostController Isochronous Transfer Descriptor
00006     __IO uint32_t Control;      // +0 Transfer descriptor control
00007     uint8_t*  BufferPage0;      // +4 Buffer Page 0
00008     HCITD* Next;                // +8 Physical pointer to next Isochronous Transfer Descriptor
00009     uint8_t*  BufferEnd;        // +12 buffer End
00010     __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW
00011     IsochronousEp* ep;          // +32 endpoint object
00012     __IO uint8_t buf[0];        // +36 buffer
00013                                 // +36
00014     HCITD(IsochronousEp* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize);
00015     inline void* operator new(size_t size, int buf_size) {
00016         void* p;
00017         if (posix_memalign(&p, 32, size+buf_size) == 0) {
00018             return p;
00019         }
00020         return NULL;
00021     }
00022 
00023     inline void operator delete(void* p) {
00024         free(p);
00025     }
00026 
00027     inline uint16_t StartingFrame() {
00028         return Control & 0xffff;
00029     }
00030 
00031     inline uint8_t FrameCount() {
00032         return ((Control>>24)&7)+1;
00033     }    
00034 
00035     inline uint8_t ConditionCode() {
00036         return Control>>28;
00037     }
00038 };
00039 
00040 struct _HCED {    // HostController EndPoint Descriptor
00041     __IO uint32_t Control; // +0 Endpoint descriptor control
00042     HCTD* TailTd;          // +4 Physical address of tail in Transfer descriptor list
00043     __IO HCTD* HeadTd;     // +8 Physcial address of head in Transfer descriptor list
00044     _HCED* Next;           // +12 Physical address of next Endpoint descriptor
00045                            // +16
00046     _HCED(int addr, uint8_t ep, uint16_t size, int lowSpeed = 0) {
00047         Control =  addr            | /* USB address */
00048         ((ep & 0x7F) << 7)         | /* Endpoint address */
00049         (ep!=0?(((ep&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */
00050         ((lowSpeed?1:0) << 13)     | /* speed full=0 low=1 */
00051         (size << 16);                /* MaxPkt Size */
00052         Next = NULL;
00053     }
00054 
00055     inline void* operator new(size_t size) {
00056         void* p;
00057         if (posix_memalign(&p, 16, size) == 0) {
00058             return p;
00059         }
00060         return NULL;
00061     }
00062 
00063     inline void operator delete(void* p) {
00064         free(p);
00065     }
00066 
00067     inline uint8_t FunctionAddress() {
00068         return Control & 0x7f;
00069     }
00070 
00071     inline int Speed() {
00072         return (Control>>13)&1;
00073     }
00074 
00075     inline void setFunctionAddress(int addr) {
00076         Control &= ~0x7f;
00077         Control |= addr;
00078     }
00079 
00080     inline void setMaxPacketSize(uint16_t size) {
00081         Control &= ~0xffff0000;
00082         Control |= size<<16;
00083     }
00084 
00085     int Skip() {
00086         return (Control>>14) & 1;
00087     }
00088 
00089     void setSkip() {
00090         Control |= (1<<14);
00091     }
00092 
00093     void setFormat() {
00094         Control |= (1<<15);
00095     }
00096 
00097     template<typename T>
00098     inline bool enqueue(T* td) {
00099         if (td) {
00100             T* tail = reinterpret_cast<T*>(TailTd);
00101             if (tail) {
00102                 tail->Next = td;
00103                 TailTd = reinterpret_cast<HCTD*>(td);
00104                 return true;
00105             }
00106         }
00107         return false;
00108     }
00109 
00110     template<typename T>
00111     inline T* dequeue() {
00112         T* head = reinterpret_cast<T*>(reinterpret_cast<uint32_t>(HeadTd)&~3); // delete Halted and Toggle Carry bit
00113         T* tail = reinterpret_cast<T*>(TailTd);
00114         if (head == NULL || tail == NULL || head == tail) {
00115             return NULL;
00116         }
00117         HeadTd = reinterpret_cast<HCTD*>(head->Next);
00118         return head;
00119     }
00120     template<typename T>
00121     void init_queue(T* td) {
00122         TailTd = reinterpret_cast<HCTD*>(td);
00123         HeadTd = reinterpret_cast<HCTD*>(td); 
00124     }
00125 };
00126 
00127 struct _HCCA {    // Host Controller Communication Area
00128     _HCED* InterruptTable[32]; // +0 Interrupt Table
00129     __IO uint16_t FrameNumber;// +128 Frame Number
00130     __IO uint16_t Pad1;       // +130
00131     __IO HCTD* DoneHead;      // +132 Done Head
00132     uint8_t Reserved[116];    // +136 Reserved for future use
00133     uint8_t Unknown[4];       // +252 Unused
00134                               // +256
00135     inline void* operator new(size_t size) {
00136         void* p;
00137         if (posix_memalign(&p, 256, size) == 0) {
00138             return p;
00139         }
00140         return NULL;
00141     }
00142 
00143     inline void operator delete(void* p) {
00144         free(p);
00145     }
00146     
00147     inline void enqueue(_HCED* ed) {
00148         for(int i = 0; i < 32; i++) {
00149             if (InterruptTable[i] == NULL) {
00150                 InterruptTable[i] = ed;
00151             } else {
00152                 _HCED* nextEd = InterruptTable[i];
00153                 while(nextEd->Next && nextEd->Next != ed) {
00154                     nextEd = nextEd->Next;
00155                 }
00156                 nextEd->Next = ed;
00157             }
00158         }
00159     }
00160     
00161     inline void dequeue(_HCED* ed) {
00162          for(int i = 0; i < 32; i++) {
00163             if (InterruptTable[i] == ed) {
00164                 InterruptTable[i] = ed->Next;
00165             } else if (InterruptTable[i]) {
00166                 _HCED* nextEd = InterruptTable[i];
00167                 while(nextEd) {
00168                     if (nextEd->Next == ed) {
00169                         nextEd->Next = ed->Next;
00170                         break;
00171                     }
00172                     nextEd = nextEd->Next;
00173                 }
00174             }
00175          }
00176     }
00177 };
00178 
00179 #define HCITD_QUEUE_SIZE 3
00180 
00181 class IsochronousEp {
00182 public:
00183     void init(int addr, uint8_t ep, uint16_t size, uint8_t frameCount = 4, uint8_t queueLimit = HCITD_QUEUE_SIZE);
00184     void reset(int delay_ms = 100);
00185     HCITD* isochronousReceive(int timeout_ms);
00186     int isochronousSend(uint8_t* buf, int len, int timeout_ms);
00187     HCITD* get_queue_HCITD(int timeout_ms);
00188     uint16_t m_PacketSize;
00189     void disconnect();
00190     void irqWdhHandler(HCITD* itd) {m_queue.put(itd);} // WDH
00191 private:
00192     HCITD* new_HCITD(IsochronousEp* obj);
00193     Queue<HCITD, HCITD_QUEUE_SIZE> m_queue; // ITD done queue
00194     int m_itd_queue_count;
00195     int m_itd_queue_limit;
00196     uint16_t m_FrameNumber;
00197     int m_FrameCount; // 1-8
00198     void enable();
00199     _HCED* m_pED;
00200 };