Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FATFileSystem mbed-rtos
Dependents: Peach_AudioChannelDividerAndCompensator
USBIsochronous.h
00001 // USBIsochronous.h 00002 #pragma once 00003 #if !defined (__CC_ARM) && (!defined (_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L)) 00004 #include <malloc.h> 00005 #endif 00006 00007 class IsochronousEp; 00008 struct HCITD { // HostController Isochronous Transfer Descriptor 00009 __IO uint32_t Control; // +0 Transfer descriptor control 00010 uint8_t* BufferPage0; // +4 Buffer Page 0 00011 HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor 00012 uint8_t* BufferEnd; // +12 buffer End 00013 __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW 00014 IsochronousEp* ep; // +32 endpoint object 00015 __IO uint8_t buf[0]; // +36 buffer 00016 // +36 00017 HCITD(IsochronousEp* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize); 00018 00019 inline void* operator new(size_t size, int buf_size) { 00020 void* p; 00021 // uint32_t addr; 00022 #if !defined (__CC_ARM) && (!defined (_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L)) 00023 // バッファ先頭アドレスは、下位12ビットが0となっていると好都合 00024 // アイソクロナスパケットが小さい間は問題が無いが、大きくなると、異常を生じる様子。 00025 // 獲得されるメモリアドレスは時によるので、運がよければ動作するが、12ビットアラインにすれば、確実に動くように思われる 00026 //p = memalign(32, size+buf_size);というオリジナルの記述では下位4ビットしか0になってない。 00027 p = memalign(0x1000, size+buf_size); 00028 return p; 00029 #else 00030 // バッファ先頭アドレスは、下位12ビットが0となっていると好都合 00031 //p = posix_memalign(&p, 32, size+buf_size);というオリジナルの記述では下位4ビットしか0になってない。 00032 if (posix_memalign(&p, 0x1000, size+buf_size) == 0) { 00033 //if (posix_memalign(&p, 32, size+buf_size) == 0) { 00034 return p; 00035 } 00036 return NULL; 00037 #endif 00038 } 00039 00040 // inline void* operator new(size_t size, int buf_size) { 00041 // void* p; 00042 //#if !defined (__CC_ARM) && (!defined (_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L)) 00043 // p = memalign(32, size+buf_size); 00044 // return p; 00045 //#else 00046 // if (posix_memalign(&p, 32, size+buf_size) == 0) { 00047 // return p; 00048 // } 00049 // return NULL; 00050 //#endif 00051 // } 00052 00053 inline void operator delete(void* p) { 00054 free(p); 00055 } 00056 00057 inline uint16_t StartingFrame() { 00058 return Control & 0xffff; 00059 } 00060 00061 inline void SetStartingFrame(uint16_t FrameNumber) { 00062 Control = (Control & 0xffff0000) | FrameNumber; 00063 } 00064 00065 inline uint8_t FrameCount() { 00066 return ((Control>>24)&7)+1; 00067 } 00068 00069 inline uint8_t ConditionCode() { 00070 return Control>>28; 00071 } 00072 }; 00073 00074 struct _HCED { // HostController EndPoint Descriptor 00075 __IO uint32_t Control; // +0 Endpoint descriptor control 00076 HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list 00077 __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list 00078 _HCED* Next; // +12 Physical address of next Endpoint descriptor 00079 // +16 00080 _HCED(int addr, uint8_t ep, uint16_t size, int lowSpeed = 0) { 00081 Control = addr | /* USB address */ 00082 ((ep & 0x7F) << 7) | /* Endpoint address */ 00083 (ep!=0?(((ep&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */ 00084 ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */ 00085 (size << 16); /* MaxPkt Size */ 00086 Next = NULL; 00087 } 00088 00089 inline void* operator new(size_t size) { 00090 void* p; 00091 #if !defined (__CC_ARM) && (!defined (_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L)) 00092 p = memalign(16, size); 00093 return p; 00094 #else 00095 if (posix_memalign(&p, 16, size) == 0) { 00096 return p; 00097 } 00098 return NULL; 00099 #endif 00100 } 00101 00102 inline void operator delete(void* p) { 00103 free(p); 00104 } 00105 00106 inline uint8_t FunctionAddress() { 00107 return Control & 0x7f; 00108 } 00109 00110 inline int Speed() { 00111 return (Control>>13)&1; 00112 } 00113 00114 inline void setFunctionAddress(int addr) { 00115 Control &= ~0x7f; 00116 Control |= addr; 00117 } 00118 00119 inline void setMaxPacketSize(uint16_t size) { 00120 Control &= ~0xffff0000; 00121 Control |= size<<16; 00122 } 00123 00124 int Skip() { 00125 return (Control>>14) & 1; 00126 } 00127 00128 void setSkip() { 00129 Control |= (1<<14); 00130 } 00131 00132 void setFormat() { 00133 Control |= (1<<15); 00134 } 00135 00136 template<typename T> 00137 inline bool enqueue(T* td) { 00138 if (td) { 00139 T* tail = reinterpret_cast<T*>(TailTd); 00140 if (tail) { 00141 tail->Next = td; 00142 TailTd = reinterpret_cast<HCTD*>(td); 00143 return true; 00144 } 00145 } 00146 return false; 00147 } 00148 00149 template<typename T> 00150 inline T* dequeue() { 00151 T* head = reinterpret_cast<T*>(reinterpret_cast<uint32_t>(HeadTd)&~3); // delete Halted and Toggle Carry bit 00152 T* tail = reinterpret_cast<T*>(TailTd); 00153 if (head == NULL || tail == NULL || head == tail) { 00154 return NULL; 00155 } 00156 HeadTd = reinterpret_cast<HCTD*>(head->Next); 00157 return head; 00158 } 00159 template<typename T> 00160 void init_queue(T* td) { 00161 TailTd = reinterpret_cast<HCTD*>(td); 00162 HeadTd = reinterpret_cast<HCTD*>(td); 00163 } 00164 }; 00165 00166 struct _HCCA { // Host Controller Communication Area 00167 _HCED* InterruptTable[32]; // +0 Interrupt Table 00168 __IO uint16_t FrameNumber;// +128 Frame Number 00169 __IO uint16_t Pad1; // +130 00170 __IO HCTD* DoneHead; // +132 Done Head 00171 uint8_t Reserved[116]; // +136 Reserved for future use 00172 uint8_t Unknown[4]; // +252 Unused 00173 // +256 00174 inline void* operator new(size_t size) { 00175 void* p; 00176 #if !defined (__CC_ARM) && (!defined (_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L)) 00177 p = memalign(256, size); 00178 return p; 00179 #else 00180 if (posix_memalign(&p, 256, size) == 0) { 00181 return p; 00182 } 00183 return NULL; 00184 #endif 00185 } 00186 00187 inline void operator delete(void* p) { 00188 free(p); 00189 } 00190 00191 inline void enqueue(_HCED* ed) { 00192 for(int i = 0; i < 32; i++) { 00193 if (InterruptTable[i] == NULL) { 00194 InterruptTable[i] = ed; 00195 } else { 00196 _HCED* nextEd = InterruptTable[i]; 00197 while(nextEd->Next && nextEd->Next != ed) { 00198 nextEd = nextEd->Next; 00199 } 00200 nextEd->Next = ed; 00201 } 00202 } 00203 } 00204 00205 inline void dequeue(_HCED* ed) { 00206 for(int i = 0; i < 32; i++) { 00207 if (InterruptTable[i] == ed) { 00208 InterruptTable[i] = ed->Next; 00209 } else if (InterruptTable[i]) { 00210 _HCED* nextEd = InterruptTable[i]; 00211 while(nextEd) { 00212 if (nextEd->Next == ed) { 00213 nextEd->Next = ed->Next; 00214 break; 00215 } 00216 nextEd = nextEd->Next; 00217 } 00218 } 00219 } 00220 } 00221 }; 00222 00223 //doku #define HCITD_QUEUE_SIZE 3 00224 #define HCITD_QUEUE_SIZE 11 00225 00226 class IsochronousEp { 00227 public: 00228 void init(int addr, uint8_t ep, uint16_t size, uint8_t frameCount = 4, uint8_t queueLimit = HCITD_QUEUE_SIZE); 00229 void reset(int delay_ms = 100); 00230 HCITD* isochronousReceive(int timeout_ms); 00231 int isochronousSend(uint8_t* buf, int len, int timeout_ms); 00232 HCITD* get_queue_HCITD(int timeout_ms); 00233 uint16_t m_PacketSize; 00234 void disconnect(); 00235 void irqWdhHandler(HCITD* itd) {m_queue.put(itd);} // WDH 00236 int getQueueNum() {return m_itd_queue_count;} 00237 private: 00238 HCITD* new_HCITD(IsochronousEp* obj); 00239 Queue<HCITD, HCITD_QUEUE_SIZE> m_queue; // ITD done queue 00240 int m_itd_queue_count; 00241 int m_itd_queue_limit; 00242 uint16_t m_FrameNumber; 00243 int m_FrameCount; // 1-8 00244 void enable(); 00245 _HCED* m_pED; 00246 };
Generated on Wed Jul 13 2022 02:38:57 by
1.7.2