USB host library, support isochronous,bulk,interrupt and control.

Dependents:   BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example

Import programBaseUsbHost_example

BaseUsbHost example program

Committer:
va009039
Date:
Sun Jan 06 11:45:18 2013 +0000
Revision:
3:ae77d63a1eda
Parent:
2:fe1e62051d88
Child:
4:d931d24c2f81
change interface usbhub class

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 3:ae77d63a1eda 1 // BaseUsbHostIsoEp.cpp 2012/12/31
va009039 0:b7d6879637a8 2 #include "mbed.h"
va009039 0:b7d6879637a8 3 #include "rtos.h"
va009039 0:b7d6879637a8 4 #include "BaseUsbHost.h"
va009039 0:b7d6879637a8 5 #define DEBUG
va009039 0:b7d6879637a8 6 #include "BaseUsbHostDebug.h"
va009039 0:b7d6879637a8 7 #define TEST
va009039 0:b7d6879637a8 8 #include "BaseUsbHostTest.h"
va009039 0:b7d6879637a8 9
va009039 0:b7d6879637a8 10 IsochronousEp::IsochronousEp(int addr, uint8_t ep, uint16_t size):BaseEp(addr, ep, size)
va009039 0:b7d6879637a8 11 {
va009039 0:b7d6879637a8 12 DBG("%p FA:%d EP:%02X MPS:%d\n", this, addr, ep, size);
va009039 0:b7d6879637a8 13 TEST_ASSERT(m_pED);
va009039 0:b7d6879637a8 14
va009039 0:b7d6879637a8 15 m_pED->Control |= (1 << 15); // F Format ITD
va009039 0:b7d6879637a8 16
va009039 0:b7d6879637a8 17 TEST_ASSERT(size >= 128 && size <= 1023);
va009039 0:b7d6879637a8 18 m_PacketSize = size;
va009039 2:fe1e62051d88 19 m_FrameCount = 4; // 1-8
va009039 2:fe1e62051d88 20 TEST_ASSERT(m_FrameCount >= 1 && m_FrameCount <= 8);
va009039 0:b7d6879637a8 21 m_itd_queue_count = 0;
va009039 0:b7d6879637a8 22 reset();
va009039 0:b7d6879637a8 23 HCITD* itd = new_HCITD();
va009039 0:b7d6879637a8 24 m_pED->TailTd = reinterpret_cast<HCTD*>(itd);
va009039 0:b7d6879637a8 25 m_pED->HeadTd = reinterpret_cast<HCTD*>(itd);
va009039 2:fe1e62051d88 26 TEST_ASSERT(itd);
va009039 2:fe1e62051d88 27 if (itd == NULL) {
va009039 2:fe1e62051d88 28 return;
va009039 2:fe1e62051d88 29 }
va009039 0:b7d6879637a8 30 HCCA* hcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA);
va009039 0:b7d6879637a8 31 TEST_ASSERT(hcca);
va009039 2:fe1e62051d88 32 if (hcca == NULL) {
va009039 2:fe1e62051d88 33 return;
va009039 2:fe1e62051d88 34 }
va009039 0:b7d6879637a8 35 for(int i = 0; i < 32; i++) {
va009039 0:b7d6879637a8 36 if (hcca->InterruptTable[i] == 0) {
va009039 0:b7d6879637a8 37 hcca->InterruptTable[i] = reinterpret_cast<uint32_t>(m_pED);
va009039 0:b7d6879637a8 38 } else {
va009039 0:b7d6879637a8 39 HCED* nextEd = reinterpret_cast<HCED*>(hcca->InterruptTable[i]);
va009039 0:b7d6879637a8 40 while(nextEd->Next && nextEd->Next != reinterpret_cast<uint32_t>(m_pED)) {
va009039 0:b7d6879637a8 41 nextEd = reinterpret_cast<HCED*>(nextEd->Next);
va009039 0:b7d6879637a8 42 }
va009039 0:b7d6879637a8 43 nextEd->Next = reinterpret_cast<uint32_t>(m_pED);
va009039 0:b7d6879637a8 44 }
va009039 0:b7d6879637a8 45 }
va009039 0:b7d6879637a8 46 DBG_ED(m_pED);
va009039 0:b7d6879637a8 47 }
va009039 0:b7d6879637a8 48
va009039 3:ae77d63a1eda 49 void IsochronousEp::reset(int delay_ms)
va009039 0:b7d6879637a8 50 {
va009039 3:ae77d63a1eda 51 m_FrameNumber = LPC_USB->HcFmNumber + delay_ms;
va009039 0:b7d6879637a8 52 }
va009039 0:b7d6879637a8 53
va009039 0:b7d6879637a8 54 HCITD* IsochronousEp::new_HCITD()
va009039 0:b7d6879637a8 55 {
va009039 0:b7d6879637a8 56 HCITD* itd;
va009039 0:b7d6879637a8 57 int r = posix_memalign(reinterpret_cast<void**>(&itd), 32, sizeof(HCITD)+m_PacketSize*m_FrameCount);
va009039 0:b7d6879637a8 58 if (r != 0) {
va009039 0:b7d6879637a8 59 return NULL;
va009039 0:b7d6879637a8 60 }
va009039 0:b7d6879637a8 61 int di = 0; //DelayInterrupt
va009039 0:b7d6879637a8 62 itd->Control = 0xe0000000 | // CC ConditionCode NOT ACCESSED
va009039 0:b7d6879637a8 63 ((m_FrameCount-1) << 24)| // FC FrameCount
va009039 0:b7d6879637a8 64 TD_DELAY_INT(di) | // DI DelayInterrupt
va009039 0:b7d6879637a8 65 m_FrameNumber; // SF StartingFrame
va009039 0:b7d6879637a8 66 itd->BufferPage0 = const_cast<uint8_t*>(itd->buf);
va009039 0:b7d6879637a8 67 itd->BufferEnd = const_cast<uint8_t*>(itd->buf) + m_PacketSize * m_FrameCount - 1;
va009039 0:b7d6879637a8 68 itd->Next = NULL;
va009039 0:b7d6879637a8 69 itd->ep = this;
va009039 0:b7d6879637a8 70 uint32_t addr = reinterpret_cast<uint32_t>(itd->buf);
va009039 0:b7d6879637a8 71 for(int i = 0; i < m_FrameCount; i++) {
va009039 0:b7d6879637a8 72 uint16_t offset = addr & 0x0fff;
va009039 0:b7d6879637a8 73 if ((addr&0xfffff000) == (reinterpret_cast<uint32_t>(itd->BufferEnd)&0xfffff000)) {
va009039 0:b7d6879637a8 74 offset |= 0x1000;
va009039 0:b7d6879637a8 75 }
va009039 0:b7d6879637a8 76 itd->OffsetPSW[i] = 0xe000|offset;
va009039 0:b7d6879637a8 77 addr += m_PacketSize;
va009039 0:b7d6879637a8 78 }
va009039 0:b7d6879637a8 79 m_FrameNumber += m_FrameCount;
va009039 0:b7d6879637a8 80 return itd;
va009039 0:b7d6879637a8 81 }
va009039 0:b7d6879637a8 82
va009039 2:fe1e62051d88 83 HCITD* IsochronousEp::isochronousReveive(int millisec)
va009039 0:b7d6879637a8 84 {
va009039 0:b7d6879637a8 85 TEST_ASSERT(m_itd_queue_count >= 0);
va009039 2:fe1e62051d88 86 while(m_itd_queue_count < 3 && m_itd_queue_count < HCTD_QUEUE_SIZE) {
va009039 0:b7d6879637a8 87 HCITD* itd = reinterpret_cast<HCITD*>(m_pED->TailTd);
va009039 0:b7d6879637a8 88 TEST_ASSERT(itd);
va009039 2:fe1e62051d88 89 if (itd == NULL) {
va009039 2:fe1e62051d88 90 return NULL;
va009039 2:fe1e62051d88 91 }
va009039 0:b7d6879637a8 92 HCITD* blank_itd = new_HCITD();
va009039 0:b7d6879637a8 93 TEST_ASSERT(blank_itd);
va009039 2:fe1e62051d88 94 if (blank_itd == NULL) {
va009039 2:fe1e62051d88 95 return NULL;
va009039 2:fe1e62051d88 96 }
va009039 0:b7d6879637a8 97 itd->Next = reinterpret_cast<uint32_t>(blank_itd);
va009039 0:b7d6879637a8 98 m_pED->TailTd = reinterpret_cast<HCTD*>(blank_itd);
va009039 0:b7d6879637a8 99 m_itd_queue_count++;
va009039 0:b7d6879637a8 100 //DBG_IED(m_pED);
va009039 3:ae77d63a1eda 101 enable(); // Enable Periodic
va009039 0:b7d6879637a8 102 }
va009039 0:b7d6879637a8 103
va009039 2:fe1e62051d88 104 HCITD* itd = get_queue_HCITD(millisec);
va009039 0:b7d6879637a8 105 if (itd) {
va009039 0:b7d6879637a8 106 m_itd_queue_count--;
va009039 0:b7d6879637a8 107 }
va009039 0:b7d6879637a8 108 return itd;
va009039 0:b7d6879637a8 109 }
va009039 0:b7d6879637a8 110
va009039 2:fe1e62051d88 111 HCITD* IsochronousEp::get_queue_HCITD(int millisec)
va009039 0:b7d6879637a8 112 {
va009039 0:b7d6879637a8 113 for(int i = 0; i < 16; i++) {
va009039 0:b7d6879637a8 114 osEvent evt = m_queue.get(millisec);
va009039 0:b7d6879637a8 115 if (evt.status == osEventMessage) {
va009039 0:b7d6879637a8 116 HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p);
va009039 0:b7d6879637a8 117 TEST_ASSERT(itd);
va009039 2:fe1e62051d88 118 if (itd == NULL) {
va009039 2:fe1e62051d88 119 return NULL;
va009039 2:fe1e62051d88 120 }
va009039 0:b7d6879637a8 121 uint8_t cc = itd->Control>>28;
va009039 0:b7d6879637a8 122 if (cc != 0) {
va009039 0:b7d6879637a8 123 m_ConditionCode = cc;
va009039 0:b7d6879637a8 124 }
va009039 0:b7d6879637a8 125 return itd;
va009039 0:b7d6879637a8 126 } else if (evt.status == osOK) {
va009039 0:b7d6879637a8 127 continue;
va009039 0:b7d6879637a8 128 } else if (evt.status == osEventTimeout) {
va009039 0:b7d6879637a8 129 return NULL;
va009039 0:b7d6879637a8 130 } else {
va009039 0:b7d6879637a8 131 DBG("evt.status: %02x\n", evt.status);
va009039 0:b7d6879637a8 132 TEST_ASSERT(evt.status == osEventMessage);
va009039 2:fe1e62051d88 133 return NULL;
va009039 0:b7d6879637a8 134 }
va009039 0:b7d6879637a8 135 }
va009039 0:b7d6879637a8 136 return NULL;
va009039 0:b7d6879637a8 137 }
va009039 3:ae77d63a1eda 138
va009039 3:ae77d63a1eda 139 void IsochronousEp::enable()
va009039 3:ae77d63a1eda 140 {
va009039 3:ae77d63a1eda 141 LPC_USB->HcControl |= OR_CONTROL_PLE;
va009039 3:ae77d63a1eda 142 }