Support Isochronous transfer additionally

Dependents:   USBHostC270_example_GR-PEACH USBHostDac_example USBHostDac_Audio_in_out

Fork of USBHost_custom by Renesas

Committer:
HinoNaka
Date:
Fri Apr 21 07:23:33 2017 +0000
Revision:
41:5c3ebf7372ee
Support Isochronous transfer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
HinoNaka 41:5c3ebf7372ee 1 // USBIsochronous.h
HinoNaka 41:5c3ebf7372ee 2 #pragma once
HinoNaka 41:5c3ebf7372ee 3 #if !defined (__CC_ARM) && (!defined (_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L))
HinoNaka 41:5c3ebf7372ee 4 #if defined(__ICCARM__)
HinoNaka 41:5c3ebf7372ee 5 #include <iar_dlmalloc.h>
HinoNaka 41:5c3ebf7372ee 6 #define memalign __iar_dlmemalign
HinoNaka 41:5c3ebf7372ee 7 #else
HinoNaka 41:5c3ebf7372ee 8 #include <malloc.h>
HinoNaka 41:5c3ebf7372ee 9 #endif
HinoNaka 41:5c3ebf7372ee 10 #endif
HinoNaka 41:5c3ebf7372ee 11
HinoNaka 41:5c3ebf7372ee 12 class IsochronousEp;
HinoNaka 41:5c3ebf7372ee 13 struct HCITD { // HostController Isochronous Transfer Descriptor
HinoNaka 41:5c3ebf7372ee 14 __IO uint32_t Control; // +0 Transfer descriptor control
HinoNaka 41:5c3ebf7372ee 15 uint8_t* BufferPage0; // +4 Buffer Page 0
HinoNaka 41:5c3ebf7372ee 16 HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor
HinoNaka 41:5c3ebf7372ee 17 uint8_t* BufferEnd; // +12 buffer End
HinoNaka 41:5c3ebf7372ee 18 __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW
HinoNaka 41:5c3ebf7372ee 19 IsochronousEp* ep; // +32 endpoint object
HinoNaka 41:5c3ebf7372ee 20 uint8_t* buf; // +36 buffer
HinoNaka 41:5c3ebf7372ee 21 // +40
HinoNaka 41:5c3ebf7372ee 22 HCITD(IsochronousEp* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize);
HinoNaka 41:5c3ebf7372ee 23 inline void* operator new(size_t size, int buf_size) {
HinoNaka 41:5c3ebf7372ee 24 void* p;
HinoNaka 41:5c3ebf7372ee 25 struct HCITD * wk_hcitd;
HinoNaka 41:5c3ebf7372ee 26 void* q;
HinoNaka 41:5c3ebf7372ee 27 #if !defined (__CC_ARM) && (!defined (_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L))
HinoNaka 41:5c3ebf7372ee 28 p = memalign(0x20, size);
HinoNaka 41:5c3ebf7372ee 29 if (p != NULL) {
HinoNaka 41:5c3ebf7372ee 30 q = memalign(0x1000, buf_size);
HinoNaka 41:5c3ebf7372ee 31 if (q != NULL) {
HinoNaka 41:5c3ebf7372ee 32 wk_hcitd = (struct HCITD *)p;
HinoNaka 41:5c3ebf7372ee 33 wk_hcitd->buf = (uint8_t*)q;
HinoNaka 41:5c3ebf7372ee 34 } else {
HinoNaka 41:5c3ebf7372ee 35 free(p);
HinoNaka 41:5c3ebf7372ee 36 p = NULL;
HinoNaka 41:5c3ebf7372ee 37 }
HinoNaka 41:5c3ebf7372ee 38 }
HinoNaka 41:5c3ebf7372ee 39 return p;
HinoNaka 41:5c3ebf7372ee 40 #else
HinoNaka 41:5c3ebf7372ee 41 if (posix_memalign(&p, 0x20, size) == 0) {
HinoNaka 41:5c3ebf7372ee 42 if (posix_memalign(&q, 0x1000, buf_size) == 0) {
HinoNaka 41:5c3ebf7372ee 43 wk_hcitd = (struct HCITD *)p;
HinoNaka 41:5c3ebf7372ee 44 wk_hcitd->buf = (uint8_t*)q;
HinoNaka 41:5c3ebf7372ee 45 } else {
HinoNaka 41:5c3ebf7372ee 46 free(p);
HinoNaka 41:5c3ebf7372ee 47 p = NULL;
HinoNaka 41:5c3ebf7372ee 48 }
HinoNaka 41:5c3ebf7372ee 49 return p;
HinoNaka 41:5c3ebf7372ee 50 }
HinoNaka 41:5c3ebf7372ee 51 return NULL;
HinoNaka 41:5c3ebf7372ee 52 #endif
HinoNaka 41:5c3ebf7372ee 53 }
HinoNaka 41:5c3ebf7372ee 54
HinoNaka 41:5c3ebf7372ee 55 inline void operator delete(void* p) {
HinoNaka 41:5c3ebf7372ee 56 struct HCITD * wk_hcitd = (struct HCITD *)p;
HinoNaka 41:5c3ebf7372ee 57 free((void *)wk_hcitd->buf);
HinoNaka 41:5c3ebf7372ee 58 free(p);
HinoNaka 41:5c3ebf7372ee 59 }
HinoNaka 41:5c3ebf7372ee 60
HinoNaka 41:5c3ebf7372ee 61 inline uint16_t StartingFrame() {
HinoNaka 41:5c3ebf7372ee 62 return Control & 0xffff;
HinoNaka 41:5c3ebf7372ee 63 }
HinoNaka 41:5c3ebf7372ee 64
HinoNaka 41:5c3ebf7372ee 65 inline void SetStartingFrame(uint16_t FrameNumber) {
HinoNaka 41:5c3ebf7372ee 66 Control = (Control & 0xffff0000) | FrameNumber;
HinoNaka 41:5c3ebf7372ee 67 }
HinoNaka 41:5c3ebf7372ee 68
HinoNaka 41:5c3ebf7372ee 69 inline uint8_t FrameCount() {
HinoNaka 41:5c3ebf7372ee 70 return ((Control>>24)&7)+1;
HinoNaka 41:5c3ebf7372ee 71 }
HinoNaka 41:5c3ebf7372ee 72
HinoNaka 41:5c3ebf7372ee 73 inline uint8_t ConditionCode() {
HinoNaka 41:5c3ebf7372ee 74 return Control>>28;
HinoNaka 41:5c3ebf7372ee 75 }
HinoNaka 41:5c3ebf7372ee 76 };
HinoNaka 41:5c3ebf7372ee 77
HinoNaka 41:5c3ebf7372ee 78 struct _HCED { // HostController EndPoint Descriptor
HinoNaka 41:5c3ebf7372ee 79 __IO uint32_t Control; // +0 Endpoint descriptor control
HinoNaka 41:5c3ebf7372ee 80 HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list
HinoNaka 41:5c3ebf7372ee 81 __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list
HinoNaka 41:5c3ebf7372ee 82 _HCED* Next; // +12 Physical address of next Endpoint descriptor
HinoNaka 41:5c3ebf7372ee 83 // +16
HinoNaka 41:5c3ebf7372ee 84 _HCED(int addr, uint8_t ep, uint16_t size, int lowSpeed = 0) {
HinoNaka 41:5c3ebf7372ee 85 Control = addr | /* USB address */
HinoNaka 41:5c3ebf7372ee 86 ((ep & 0x7F) << 7) | /* Endpoint address */
HinoNaka 41:5c3ebf7372ee 87 (ep!=0?(((ep&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */
HinoNaka 41:5c3ebf7372ee 88 ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */
HinoNaka 41:5c3ebf7372ee 89 (size << 16); /* MaxPkt Size */
HinoNaka 41:5c3ebf7372ee 90 Next = NULL;
HinoNaka 41:5c3ebf7372ee 91 }
HinoNaka 41:5c3ebf7372ee 92
HinoNaka 41:5c3ebf7372ee 93 inline void* operator new(size_t size) {
HinoNaka 41:5c3ebf7372ee 94 void* p;
HinoNaka 41:5c3ebf7372ee 95 #if !defined (__CC_ARM) && (!defined (_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L))
HinoNaka 41:5c3ebf7372ee 96 p = memalign(16, size);
HinoNaka 41:5c3ebf7372ee 97 return p;
HinoNaka 41:5c3ebf7372ee 98 #else
HinoNaka 41:5c3ebf7372ee 99 if (posix_memalign(&p, 16, size) == 0) {
HinoNaka 41:5c3ebf7372ee 100 return p;
HinoNaka 41:5c3ebf7372ee 101 }
HinoNaka 41:5c3ebf7372ee 102 return NULL;
HinoNaka 41:5c3ebf7372ee 103 #endif
HinoNaka 41:5c3ebf7372ee 104 }
HinoNaka 41:5c3ebf7372ee 105
HinoNaka 41:5c3ebf7372ee 106 inline void operator delete(void* p) {
HinoNaka 41:5c3ebf7372ee 107 free(p);
HinoNaka 41:5c3ebf7372ee 108 }
HinoNaka 41:5c3ebf7372ee 109
HinoNaka 41:5c3ebf7372ee 110 inline uint8_t FunctionAddress() {
HinoNaka 41:5c3ebf7372ee 111 return Control & 0x7f;
HinoNaka 41:5c3ebf7372ee 112 }
HinoNaka 41:5c3ebf7372ee 113
HinoNaka 41:5c3ebf7372ee 114 inline int Speed() {
HinoNaka 41:5c3ebf7372ee 115 return (Control>>13)&1;
HinoNaka 41:5c3ebf7372ee 116 }
HinoNaka 41:5c3ebf7372ee 117
HinoNaka 41:5c3ebf7372ee 118 inline void setFunctionAddress(int addr) {
HinoNaka 41:5c3ebf7372ee 119 Control &= ~0x7f;
HinoNaka 41:5c3ebf7372ee 120 Control |= addr;
HinoNaka 41:5c3ebf7372ee 121 }
HinoNaka 41:5c3ebf7372ee 122
HinoNaka 41:5c3ebf7372ee 123 inline void setMaxPacketSize(uint16_t size) {
HinoNaka 41:5c3ebf7372ee 124 Control &= ~0xffff0000;
HinoNaka 41:5c3ebf7372ee 125 Control |= size<<16;
HinoNaka 41:5c3ebf7372ee 126 }
HinoNaka 41:5c3ebf7372ee 127
HinoNaka 41:5c3ebf7372ee 128 int Skip() {
HinoNaka 41:5c3ebf7372ee 129 return (Control>>14) & 1;
HinoNaka 41:5c3ebf7372ee 130 }
HinoNaka 41:5c3ebf7372ee 131
HinoNaka 41:5c3ebf7372ee 132 void setSkip() {
HinoNaka 41:5c3ebf7372ee 133 Control |= (1<<14);
HinoNaka 41:5c3ebf7372ee 134 }
HinoNaka 41:5c3ebf7372ee 135
HinoNaka 41:5c3ebf7372ee 136 void setFormat() {
HinoNaka 41:5c3ebf7372ee 137 Control |= (1<<15);
HinoNaka 41:5c3ebf7372ee 138 }
HinoNaka 41:5c3ebf7372ee 139
HinoNaka 41:5c3ebf7372ee 140 template<typename T>
HinoNaka 41:5c3ebf7372ee 141 inline bool enqueue(T* td) {
HinoNaka 41:5c3ebf7372ee 142 if (td) {
HinoNaka 41:5c3ebf7372ee 143 T* tail = reinterpret_cast<T*>(TailTd);
HinoNaka 41:5c3ebf7372ee 144 if (tail) {
HinoNaka 41:5c3ebf7372ee 145 tail->Next = td;
HinoNaka 41:5c3ebf7372ee 146 TailTd = reinterpret_cast<HCTD*>(td);
HinoNaka 41:5c3ebf7372ee 147 return true;
HinoNaka 41:5c3ebf7372ee 148 }
HinoNaka 41:5c3ebf7372ee 149 }
HinoNaka 41:5c3ebf7372ee 150 return false;
HinoNaka 41:5c3ebf7372ee 151 }
HinoNaka 41:5c3ebf7372ee 152
HinoNaka 41:5c3ebf7372ee 153 template<typename T>
HinoNaka 41:5c3ebf7372ee 154 inline T* dequeue() {
HinoNaka 41:5c3ebf7372ee 155 T* head = reinterpret_cast<T*>(reinterpret_cast<uint32_t>(HeadTd)&~3); // delete Halted and Toggle Carry bit
HinoNaka 41:5c3ebf7372ee 156 T* tail = reinterpret_cast<T*>(TailTd);
HinoNaka 41:5c3ebf7372ee 157 if (head == NULL || tail == NULL || head == tail) {
HinoNaka 41:5c3ebf7372ee 158 return NULL;
HinoNaka 41:5c3ebf7372ee 159 }
HinoNaka 41:5c3ebf7372ee 160 HeadTd = reinterpret_cast<HCTD*>(head->Next);
HinoNaka 41:5c3ebf7372ee 161 return head;
HinoNaka 41:5c3ebf7372ee 162 }
HinoNaka 41:5c3ebf7372ee 163 template<typename T>
HinoNaka 41:5c3ebf7372ee 164 void init_queue(T* td) {
HinoNaka 41:5c3ebf7372ee 165 TailTd = reinterpret_cast<HCTD*>(td);
HinoNaka 41:5c3ebf7372ee 166 HeadTd = reinterpret_cast<HCTD*>(td);
HinoNaka 41:5c3ebf7372ee 167 }
HinoNaka 41:5c3ebf7372ee 168 };
HinoNaka 41:5c3ebf7372ee 169
HinoNaka 41:5c3ebf7372ee 170 struct _HCCA { // Host Controller Communication Area
HinoNaka 41:5c3ebf7372ee 171 _HCED* InterruptTable[32]; // +0 Interrupt Table
HinoNaka 41:5c3ebf7372ee 172 __IO uint16_t FrameNumber;// +128 Frame Number
HinoNaka 41:5c3ebf7372ee 173 __IO uint16_t Pad1; // +130
HinoNaka 41:5c3ebf7372ee 174 __IO HCTD* DoneHead; // +132 Done Head
HinoNaka 41:5c3ebf7372ee 175 uint8_t Reserved[116]; // +136 Reserved for future use
HinoNaka 41:5c3ebf7372ee 176 uint8_t Unknown[4]; // +252 Unused
HinoNaka 41:5c3ebf7372ee 177 // +256
HinoNaka 41:5c3ebf7372ee 178 inline void* operator new(size_t size) {
HinoNaka 41:5c3ebf7372ee 179 void* p;
HinoNaka 41:5c3ebf7372ee 180 #if !defined (__CC_ARM) && (!defined (_POSIX_C_SOURCE) || (_POSIX_C_SOURCE < 200112L))
HinoNaka 41:5c3ebf7372ee 181 p = memalign(256, size);
HinoNaka 41:5c3ebf7372ee 182 return p;
HinoNaka 41:5c3ebf7372ee 183 #else
HinoNaka 41:5c3ebf7372ee 184 if (posix_memalign(&p, 256, size) == 0) {
HinoNaka 41:5c3ebf7372ee 185 return p;
HinoNaka 41:5c3ebf7372ee 186 }
HinoNaka 41:5c3ebf7372ee 187 return NULL;
HinoNaka 41:5c3ebf7372ee 188 #endif
HinoNaka 41:5c3ebf7372ee 189 }
HinoNaka 41:5c3ebf7372ee 190
HinoNaka 41:5c3ebf7372ee 191 inline void operator delete(void* p) {
HinoNaka 41:5c3ebf7372ee 192 free(p);
HinoNaka 41:5c3ebf7372ee 193 }
HinoNaka 41:5c3ebf7372ee 194
HinoNaka 41:5c3ebf7372ee 195 inline void enqueue(_HCED* ed) {
HinoNaka 41:5c3ebf7372ee 196 for(int i = 0; i < 32; i++) {
HinoNaka 41:5c3ebf7372ee 197 if (InterruptTable[i] == NULL) {
HinoNaka 41:5c3ebf7372ee 198 InterruptTable[i] = ed;
HinoNaka 41:5c3ebf7372ee 199 } else {
HinoNaka 41:5c3ebf7372ee 200 _HCED* nextEd = InterruptTable[i];
HinoNaka 41:5c3ebf7372ee 201 while(nextEd->Next && nextEd->Next != ed) {
HinoNaka 41:5c3ebf7372ee 202 nextEd = nextEd->Next;
HinoNaka 41:5c3ebf7372ee 203 }
HinoNaka 41:5c3ebf7372ee 204 nextEd->Next = ed;
HinoNaka 41:5c3ebf7372ee 205 }
HinoNaka 41:5c3ebf7372ee 206 }
HinoNaka 41:5c3ebf7372ee 207 }
HinoNaka 41:5c3ebf7372ee 208
HinoNaka 41:5c3ebf7372ee 209 inline void dequeue(_HCED* ed) {
HinoNaka 41:5c3ebf7372ee 210 for(int i = 0; i < 32; i++) {
HinoNaka 41:5c3ebf7372ee 211 if (InterruptTable[i] == ed) {
HinoNaka 41:5c3ebf7372ee 212 InterruptTable[i] = ed->Next;
HinoNaka 41:5c3ebf7372ee 213 } else if (InterruptTable[i]) {
HinoNaka 41:5c3ebf7372ee 214 _HCED* nextEd = InterruptTable[i];
HinoNaka 41:5c3ebf7372ee 215 while(nextEd) {
HinoNaka 41:5c3ebf7372ee 216 if (nextEd->Next == ed) {
HinoNaka 41:5c3ebf7372ee 217 nextEd->Next = ed->Next;
HinoNaka 41:5c3ebf7372ee 218 break;
HinoNaka 41:5c3ebf7372ee 219 }
HinoNaka 41:5c3ebf7372ee 220 nextEd = nextEd->Next;
HinoNaka 41:5c3ebf7372ee 221 }
HinoNaka 41:5c3ebf7372ee 222 }
HinoNaka 41:5c3ebf7372ee 223 }
HinoNaka 41:5c3ebf7372ee 224 }
HinoNaka 41:5c3ebf7372ee 225 };
HinoNaka 41:5c3ebf7372ee 226
HinoNaka 41:5c3ebf7372ee 227 #define HCITD_QUEUE_SIZE 24
HinoNaka 41:5c3ebf7372ee 228
HinoNaka 41:5c3ebf7372ee 229 class IsochronousEp {
HinoNaka 41:5c3ebf7372ee 230 public:
HinoNaka 41:5c3ebf7372ee 231 void init(int addr, uint8_t ep, uint16_t size, uint8_t frameCount = 4, uint8_t queueLimit = 3);
HinoNaka 41:5c3ebf7372ee 232 void reset(int delay_ms = 100);
HinoNaka 41:5c3ebf7372ee 233 HCITD* isochronousReceive(int timeout_ms);
HinoNaka 41:5c3ebf7372ee 234 int isochronousSend(uint8_t* buf, int len, int timeout_ms);
HinoNaka 41:5c3ebf7372ee 235 HCITD* get_queue_HCITD(int timeout_ms);
HinoNaka 41:5c3ebf7372ee 236 uint16_t m_PacketSize;
HinoNaka 41:5c3ebf7372ee 237 void disconnect();
HinoNaka 41:5c3ebf7372ee 238 void irqWdhHandler(HCITD* itd) {m_queue.put(itd);} // WDH
HinoNaka 41:5c3ebf7372ee 239 int getQueueNum() {return m_itd_queue_count;}
HinoNaka 41:5c3ebf7372ee 240 private:
HinoNaka 41:5c3ebf7372ee 241 HCITD* new_HCITD(IsochronousEp* obj);
HinoNaka 41:5c3ebf7372ee 242 Queue<HCITD, HCITD_QUEUE_SIZE> m_queue; // ITD done queue
HinoNaka 41:5c3ebf7372ee 243 int m_itd_queue_count;
HinoNaka 41:5c3ebf7372ee 244 int m_itd_queue_limit;
HinoNaka 41:5c3ebf7372ee 245 uint16_t m_FrameNumber;
HinoNaka 41:5c3ebf7372ee 246 int m_FrameCount; // 1-8
HinoNaka 41:5c3ebf7372ee 247 void enable();
HinoNaka 41:5c3ebf7372ee 248 _HCED* m_pED;
HinoNaka 41:5c3ebf7372ee 249 };
HinoNaka 41:5c3ebf7372ee 250