testing n-Bed with a Logitech C270 camera
Fork of USBHostC270_example by
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 };
Generated on Mon Jul 18 2022 19:52:39 by 1.7.2