doku newon / DokuUSBHostWithIso

Dependencies:   FATFileSystem mbed-rtos

Dependents:   Peach_AudioChannelDividerAndCompensator

Committer:
dkato
Date:
Wed Apr 01 05:36:16 2015 +0000
Revision:
30:2851a9b2bbfb
Child:
31:271fcfd7cfc2
supported Isochronous

Who changed what in which revision?

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