Support Isochronous transfer additionally

Dependents:   USBHostC270_example_GR-PEACH USBHostDac_example USBHostDac_Audio_in_out

Fork of USBHost_custom by Renesas

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBIsochronous.h Source File

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