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:
Mon Feb 11 12:00:47 2013 +0000
Revision:
5:8a2d056e9b38
Parent:
4:d931d24c2f81
add GetStringDescriptor()

Who changed what in which revision?

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