supported GR-PEACH original: http://developer.mbed.org/users/va009039/code/USBHostC270_example/ The function of Isochronous has moved to USBHost_AddIso library.
Dependencies: USBHost_custom_Addiso
Fork of USBHostC270_example_GR-PEACH by
Diff: USBHostC270/USBisochronous/USBIsochronous.h
- Revision:
- 12:ea4badc78215
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBHostC270/USBisochronous/USBIsochronous.h Wed Mar 20 14:28:39 2013 +0000
@@ -0,0 +1,200 @@
+// USBIsochronous.h
+#pragma once
+
+class IsochronousEp;
+struct HCITD { // HostController Isochronous Transfer Descriptor
+ __IO uint32_t Control; // +0 Transfer descriptor control
+ uint8_t* BufferPage0; // +4 Buffer Page 0
+ HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor
+ uint8_t* BufferEnd; // +12 buffer End
+ __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW
+ IsochronousEp* ep; // +32 endpoint object
+ __IO uint8_t buf[0]; // +36 buffer
+ // +36
+ HCITD(IsochronousEp* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize);
+ inline void* operator new(size_t size, int buf_size) {
+ void* p;
+ if (posix_memalign(&p, 32, size+buf_size) == 0) {
+ return p;
+ }
+ return NULL;
+ }
+
+ inline void operator delete(void* p) {
+ free(p);
+ }
+
+ inline uint16_t StartingFrame() {
+ return Control & 0xffff;
+ }
+
+ inline uint8_t FrameCount() {
+ return ((Control>>24)&7)+1;
+ }
+
+ inline uint8_t ConditionCode() {
+ return Control>>28;
+ }
+};
+
+struct _HCED { // HostController EndPoint Descriptor
+ __IO uint32_t Control; // +0 Endpoint descriptor control
+ HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list
+ __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list
+ _HCED* Next; // +12 Physical address of next Endpoint descriptor
+ // +16
+ _HCED(int addr, uint8_t ep, uint16_t size, int lowSpeed = 0) {
+ Control = addr | /* USB address */
+ ((ep & 0x7F) << 7) | /* Endpoint address */
+ (ep!=0?(((ep&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */
+ ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */
+ (size << 16); /* MaxPkt Size */
+ Next = NULL;
+ }
+
+ inline void* operator new(size_t size) {
+ void* p;
+ if (posix_memalign(&p, 16, size) == 0) {
+ return p;
+ }
+ return NULL;
+ }
+
+ inline void operator delete(void* p) {
+ free(p);
+ }
+
+ inline uint8_t FunctionAddress() {
+ return Control & 0x7f;
+ }
+
+ inline int Speed() {
+ return (Control>>13)&1;
+ }
+
+ inline void setFunctionAddress(int addr) {
+ Control &= ~0x7f;
+ Control |= addr;
+ }
+
+ inline void setMaxPacketSize(uint16_t size) {
+ Control &= ~0xffff0000;
+ Control |= size<<16;
+ }
+
+ int Skip() {
+ return (Control>>14) & 1;
+ }
+
+ void setSkip() {
+ Control |= (1<<14);
+ }
+
+ void setFormat() {
+ Control |= (1<<15);
+ }
+
+ template<typename T>
+ inline bool enqueue(T* td) {
+ if (td) {
+ T* tail = reinterpret_cast<T*>(TailTd);
+ if (tail) {
+ tail->Next = td;
+ TailTd = reinterpret_cast<HCTD*>(td);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ template<typename T>
+ inline T* dequeue() {
+ T* head = reinterpret_cast<T*>(reinterpret_cast<uint32_t>(HeadTd)&~3); // delete Halted and Toggle Carry bit
+ T* tail = reinterpret_cast<T*>(TailTd);
+ if (head == NULL || tail == NULL || head == tail) {
+ return NULL;
+ }
+ HeadTd = reinterpret_cast<HCTD*>(head->Next);
+ return head;
+ }
+ template<typename T>
+ void init_queue(T* td) {
+ TailTd = reinterpret_cast<HCTD*>(td);
+ HeadTd = reinterpret_cast<HCTD*>(td);
+ }
+};
+
+struct _HCCA { // Host Controller Communication Area
+ _HCED* InterruptTable[32]; // +0 Interrupt Table
+ __IO uint16_t FrameNumber;// +128 Frame Number
+ __IO uint16_t Pad1; // +130
+ __IO HCTD* DoneHead; // +132 Done Head
+ uint8_t Reserved[116]; // +136 Reserved for future use
+ uint8_t Unknown[4]; // +252 Unused
+ // +256
+ inline void* operator new(size_t size) {
+ void* p;
+ if (posix_memalign(&p, 256, size) == 0) {
+ return p;
+ }
+ return NULL;
+ }
+
+ inline void operator delete(void* p) {
+ free(p);
+ }
+
+ inline void enqueue(_HCED* ed) {
+ for(int i = 0; i < 32; i++) {
+ if (InterruptTable[i] == NULL) {
+ InterruptTable[i] = ed;
+ } else {
+ _HCED* nextEd = InterruptTable[i];
+ while(nextEd->Next && nextEd->Next != ed) {
+ nextEd = nextEd->Next;
+ }
+ nextEd->Next = ed;
+ }
+ }
+ }
+
+ inline void dequeue(_HCED* ed) {
+ for(int i = 0; i < 32; i++) {
+ if (InterruptTable[i] == ed) {
+ InterruptTable[i] = ed->Next;
+ } else if (InterruptTable[i]) {
+ _HCED* nextEd = InterruptTable[i];
+ while(nextEd) {
+ if (nextEd->Next == ed) {
+ nextEd->Next = ed->Next;
+ break;
+ }
+ nextEd = nextEd->Next;
+ }
+ }
+ }
+ }
+};
+
+#define HCITD_QUEUE_SIZE 3
+
+class IsochronousEp {
+public:
+ void init(int addr, uint8_t ep, uint16_t size, uint8_t frameCount = 4, uint8_t queueLimit = HCITD_QUEUE_SIZE);
+ void reset(int delay_ms = 100);
+ HCITD* isochronousReceive(int timeout_ms);
+ int isochronousSend(uint8_t* buf, int len, int timeout_ms);
+ HCITD* get_queue_HCITD(int timeout_ms);
+ uint16_t m_PacketSize;
+ void disconnect();
+ void irqWdhHandler(HCITD* itd) {m_queue.put(itd);} // WDH
+private:
+ HCITD* new_HCITD(IsochronousEp* obj);
+ Queue<HCITD, HCITD_QUEUE_SIZE> m_queue; // ITD done queue
+ int m_itd_queue_count;
+ int m_itd_queue_limit;
+ uint16_t m_FrameNumber;
+ int m_FrameCount; // 1-8
+ void enable();
+ _HCED* m_pED;
+};
