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