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:
Tue Dec 11 15:26:54 2012 +0000
Revision:
2:fe1e62051d88
Parent:
1:3b7bc4f87a61
Child:
3:ae77d63a1eda
bug fix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 2:fe1e62051d88 1 // BaseUsbHostIsoEp.cpp 2012/12/11
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 0:b7d6879637a8 49 void IsochronousEp::reset()
va009039 0:b7d6879637a8 50 {
va009039 0:b7d6879637a8 51 m_FrameNumber = LPC_USB->HcFmNumber + 100; // 100msec
va009039 0:b7d6879637a8 52 }
va009039 0:b7d6879637a8 53
va009039 0:b7d6879637a8 54 void IsochronousEp::irqWdhHandler(HCTD* td)
va009039 0:b7d6879637a8 55 {
va009039 0:b7d6879637a8 56 osStatus st = m_queue.put(td);
va009039 0:b7d6879637a8 57 if (st != osOK) {
va009039 0:b7d6879637a8 58 //led4_error = 1;
va009039 0:b7d6879637a8 59 }
va009039 0:b7d6879637a8 60 //led2 = !led2;
va009039 0:b7d6879637a8 61 }
va009039 0:b7d6879637a8 62
va009039 0:b7d6879637a8 63 HCITD* IsochronousEp::new_HCITD()
va009039 0:b7d6879637a8 64 {
va009039 0:b7d6879637a8 65 HCITD* itd;
va009039 0:b7d6879637a8 66 int r = posix_memalign(reinterpret_cast<void**>(&itd), 32, sizeof(HCITD)+m_PacketSize*m_FrameCount);
va009039 0:b7d6879637a8 67 if (r != 0) {
va009039 0:b7d6879637a8 68 return NULL;
va009039 0:b7d6879637a8 69 }
va009039 0:b7d6879637a8 70 int di = 0; //DelayInterrupt
va009039 0:b7d6879637a8 71 itd->Control = 0xe0000000 | // CC ConditionCode NOT ACCESSED
va009039 0:b7d6879637a8 72 ((m_FrameCount-1) << 24)| // FC FrameCount
va009039 0:b7d6879637a8 73 TD_DELAY_INT(di) | // DI DelayInterrupt
va009039 0:b7d6879637a8 74 m_FrameNumber; // SF StartingFrame
va009039 0:b7d6879637a8 75 itd->BufferPage0 = const_cast<uint8_t*>(itd->buf);
va009039 0:b7d6879637a8 76 itd->BufferEnd = const_cast<uint8_t*>(itd->buf) + m_PacketSize * m_FrameCount - 1;
va009039 0:b7d6879637a8 77 itd->Next = NULL;
va009039 0:b7d6879637a8 78 itd->ep = this;
va009039 0:b7d6879637a8 79 uint32_t addr = reinterpret_cast<uint32_t>(itd->buf);
va009039 0:b7d6879637a8 80 for(int i = 0; i < m_FrameCount; i++) {
va009039 0:b7d6879637a8 81 uint16_t offset = addr & 0x0fff;
va009039 0:b7d6879637a8 82 if ((addr&0xfffff000) == (reinterpret_cast<uint32_t>(itd->BufferEnd)&0xfffff000)) {
va009039 0:b7d6879637a8 83 offset |= 0x1000;
va009039 0:b7d6879637a8 84 }
va009039 0:b7d6879637a8 85 itd->OffsetPSW[i] = 0xe000|offset;
va009039 0:b7d6879637a8 86 addr += m_PacketSize;
va009039 0:b7d6879637a8 87 }
va009039 0:b7d6879637a8 88 m_FrameNumber += m_FrameCount;
va009039 0:b7d6879637a8 89 return itd;
va009039 0:b7d6879637a8 90 }
va009039 0:b7d6879637a8 91
va009039 0:b7d6879637a8 92
va009039 2:fe1e62051d88 93 HCITD* IsochronousEp::isochronousReveive(int millisec)
va009039 0:b7d6879637a8 94 {
va009039 0:b7d6879637a8 95 TEST_ASSERT(m_itd_queue_count >= 0);
va009039 2:fe1e62051d88 96 while(m_itd_queue_count < 3 && m_itd_queue_count < HCTD_QUEUE_SIZE) {
va009039 0:b7d6879637a8 97 HCITD* itd = reinterpret_cast<HCITD*>(m_pED->TailTd);
va009039 0:b7d6879637a8 98 TEST_ASSERT(itd);
va009039 2:fe1e62051d88 99 if (itd == NULL) {
va009039 2:fe1e62051d88 100 return NULL;
va009039 2:fe1e62051d88 101 }
va009039 0:b7d6879637a8 102 HCITD* blank_itd = new_HCITD();
va009039 0:b7d6879637a8 103 TEST_ASSERT(blank_itd);
va009039 2:fe1e62051d88 104 if (blank_itd == NULL) {
va009039 2:fe1e62051d88 105 return NULL;
va009039 2:fe1e62051d88 106 }
va009039 0:b7d6879637a8 107 itd->Next = reinterpret_cast<uint32_t>(blank_itd);
va009039 0:b7d6879637a8 108 m_pED->TailTd = reinterpret_cast<HCTD*>(blank_itd);
va009039 0:b7d6879637a8 109 m_itd_queue_count++;
va009039 0:b7d6879637a8 110 //DBG_IED(m_pED);
va009039 0:b7d6879637a8 111 LPC_USB->HcControl |= OR_CONTROL_PLE; // Enable Periodic
va009039 0:b7d6879637a8 112 }
va009039 0:b7d6879637a8 113
va009039 2:fe1e62051d88 114 HCITD* itd = get_queue_HCITD(millisec);
va009039 0:b7d6879637a8 115 if (itd) {
va009039 0:b7d6879637a8 116 m_itd_queue_count--;
va009039 0:b7d6879637a8 117 }
va009039 0:b7d6879637a8 118 return itd;
va009039 0:b7d6879637a8 119 }
va009039 0:b7d6879637a8 120
va009039 2:fe1e62051d88 121 HCITD* IsochronousEp::get_queue_HCITD(int millisec)
va009039 0:b7d6879637a8 122 {
va009039 0:b7d6879637a8 123 for(int i = 0; i < 16; i++) {
va009039 0:b7d6879637a8 124 osEvent evt = m_queue.get(millisec);
va009039 0:b7d6879637a8 125 if (evt.status == osEventMessage) {
va009039 0:b7d6879637a8 126 HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p);
va009039 0:b7d6879637a8 127 TEST_ASSERT(itd);
va009039 2:fe1e62051d88 128 if (itd == NULL) {
va009039 2:fe1e62051d88 129 return NULL;
va009039 2:fe1e62051d88 130 }
va009039 0:b7d6879637a8 131 uint8_t cc = itd->Control>>28;
va009039 0:b7d6879637a8 132 if (cc != 0) {
va009039 0:b7d6879637a8 133 m_ConditionCode = cc;
va009039 0:b7d6879637a8 134 }
va009039 0:b7d6879637a8 135 return itd;
va009039 0:b7d6879637a8 136 } else if (evt.status == osOK) {
va009039 0:b7d6879637a8 137 continue;
va009039 0:b7d6879637a8 138 } else if (evt.status == osEventTimeout) {
va009039 0:b7d6879637a8 139 return NULL;
va009039 0:b7d6879637a8 140 } else {
va009039 0:b7d6879637a8 141 DBG("evt.status: %02x\n", evt.status);
va009039 0:b7d6879637a8 142 TEST_ASSERT(evt.status == osEventMessage);
va009039 2:fe1e62051d88 143 return NULL;
va009039 0:b7d6879637a8 144 }
va009039 0:b7d6879637a8 145 }
va009039 0:b7d6879637a8 146 return NULL;
va009039 0:b7d6879637a8 147 }